-
-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add universal LLM tool compatibility and multi-analysis framework option #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This implements the patterns from the OpenCode compatibility guide: ## Universal LLM Tool Support - Add multi-tool instructions to slash commands (Claude Code, OpenCode, Cursor, etc.) - Create universal installer script (scripts/install-universal.sh) - Add .stackshift-config-example.json for pre-configuration - Commands now include bash fallbacks for non-Claude Code tools ## BE RAD Framework Option - Add "BOTH" as third framework choice (speckit, bmad, or both) - Default to BOTH when user presses Enter (maximum flexibility) - Visual framework selection with ASCII box presentation - BOTH generates Spec Kit artifacts AND provides BMAD handoff ## Key Changes - stackshift.analyze.md: Multi-tool instructions, config check, bash workflow - stackshift.implement.md: Path C for BOTH framework with mix-and-match guidance - skills/analyze/SKILL.md: BE RAD framework presentation, BOTH option - skills/cruise-control/SKILL.md: BOTH path execution flow - README.md: Universal tool support section, BE RAD documentation BE RAD = Business logic Extraction + Reverse engineering + Agent-Driven development
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds universal LLM tool compatibility and introduces a third "BOTH" framework option to StackShift. The BOTH option (branded as "BE RAD") allows users to generate both Spec Kit specifications and BMAD handoff documentation, providing maximum flexibility without upfront commitment.
Key Changes:
- Added "BOTH" as a third framework choice (alongside speckit and bmad) with "BE RAD" branding
- Created universal installer script for multi-tool support (Claude Code, OpenCode, Cursor, Windsurf, Codex, VSCode)
- Added bash workflow fallbacks in command files for non-Claude Code tools
- Introduced .stackshift-config-example.json for pre-configuration and CI/CD support
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| skills/cruise-control/SKILL.md | Documents the BOTH path execution flow through all 6 gears with visual framework selection box |
| skills/analyze/SKILL.md | Adds BE RAD framework presentation with BOTH option as recommended default, updates questionnaire |
| scripts/install-universal.sh | New universal installer that detects and installs to multiple LLM coding tools |
| README.md | Adds universal tool support section, BOTH framework documentation, updates from "Three" to "Four" ways |
| .stackshift-config-example.json | New configuration example file for pre-configuring framework choices and skipping prompts |
| .claude/commands/stackshift.implement.md | Adds Path C for BOTH framework with Spec Kit implementation + BMAD handoff instructions |
| .claude/commands/stackshift.analyze.md | Adds pre-config check, multi-tool instructions, bash workflow with BOTH option defaulting to C |
Comments suppressed due to low confidence (1)
.claude/commands/stackshift.implement.md:195
- The "both" framework implementation is incomplete. While Path C is documented here in stackshift.implement.md and described in the skill files, the intermediate command files (stackshift.create-specs.md, stackshift.gap-analysis.md, stackshift.complete-spec.md) that handle Gears 3-5 only have Path A (speckit) and Path B (bmad) sections. When implementation_framework is "both", these commands won't have clear instructions, breaking the workflow. These command files need to either: 1) Add Path C sections that explicitly handle "both", or 2) Have Path A check for both "speckit" OR "both" and document that BOTH follows the Spec Kit path through Gears 3-5.
## Path C: BOTH (implementation_framework: both) 🚀
### BE RAD: Best of All Worlds!
When you chose "BOTH", you get maximum flexibility.
### Step 1: Implement Features with Spec Kit
**First**, run Spec Kit implementation:
Use the Skill tool with skill="implement".
**The skill will**:
- Build features using `/speckit.tasks` and `/speckit.implement`
- Only implement PARTIAL and MISSING features
- Follow spec requirements exactly
### Step 2: Verify Implementation
```bash
~/stackshift/scripts/run-ast-analysis.mjs status .
Step 3: BMAD Handoff (Optional)
Then, you have the option to hand off to BMAD for collaborative refinement.
What you now have:
.specify/ # Spec Kit artifacts
├── memory/
│ ├── constitution.md
│ └── [feature-name]/
│ ├── spec.md
│ ├── plan.md
│ └── tasks.md
docs/reverse-engineering/ # BMAD context
├── functional-specification.md
├── data-architecture.md
├── integration-points.md
└── ... (9 files total)
Your options going forward:
-
Use Spec Kit workflow for task-driven development:
/speckit.specifyfor new features/speckit.planfor implementation plans/speckit.tasksfor task lists/speckit.implementfor execution
-
Use BMAD workflow for collaborative refinement:
npx bmad-method@alpha install- Run
*workflow-init - Point BMAD to
docs/reverse-engineering/ - Let PM/Architect agents create artifacts through conversation
-
Mix and match as needed:
- Use Spec Kit for quick, focused tasks
- Use BMAD when you need deeper architectural discussion
- Both have access to the same rich context
Why BOTH is Powerful
| Scenario | Use This |
|---|---|
| Quick bug fix | Spec Kit /speckit.implement |
| New feature with clear scope | Spec Kit workflow |
| Complex feature needing discussion | BMAD PM agent |
| Architecture decision | BMAD Architect agent |
| Day-to-day development | Spec Kit |
| Strategic planning | BMAD |
The BE RAD philosophy:
- Business logic extraction (StackShift)
- Everything documented (9 comprehensive files)
- Ready for any workflow (Spec Kit OR BMAD)
- Adaptable to your needs (switch anytime)
- Decision-free (no commitment upfront)
</details>
---
💡 <a href="/jschulte/stackshift/new/main/.github/instructions?filename=*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
| TOOL_PATHS["opencode"]="$HOME/.config/opencode/commands" | ||
| echo " ✅ OpenCode detected → $HOME/.config/opencode/commands" |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The detection logic checks for the opencode command first, then checks for the directory. If the command exists but points to a non-standard location, the hardcoded path "$HOME/.config/opencode/commands" may be incorrect. Consider using the command's actual location or making the path configurable when the command exists.
| TOOL_PATHS["opencode"]="$HOME/.config/opencode/commands" | |
| echo " ✅ OpenCode detected → $HOME/.config/opencode/commands" | |
| if [ -n "$OPENCODE_COMMANDS_DIR" ]; then | |
| TOOL_PATHS["opencode"]="$OPENCODE_COMMANDS_DIR" | |
| echo " ✅ OpenCode detected → $OPENCODE_COMMANDS_DIR" | |
| else | |
| TOOL_PATHS["opencode"]="$HOME/.config/opencode/commands" | |
| echo " ✅ OpenCode detected → $HOME/.config/opencode/commands" | |
| fi |
| esac | ||
|
|
||
| if [ ${#INSTALL_TOOLS[@]} -eq 0 ]; then | ||
| echo "No valid tools selected. Installation cancelled." |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When no valid tools are selected, the error message "No valid tools selected. Installation cancelled." doesn't provide helpful guidance on what went wrong. Consider providing more context, such as "Invalid selection. Please enter a number between 1 and N, 'A' for all, or 'Q' to quit."
| echo "No valid tools selected. Installation cancelled." | |
| echo "Invalid selection: '$selection'." | |
| echo "Please enter a number between 1 and ${#DETECTED_TOOLS[@]}, 'A' to install to all detected tools, or 'Q' to quit." | |
| echo "Installation cancelled." |
| @@ -0,0 +1,49 @@ | |||
| { | |||
| "$schema": "https://stackshift.dev/config-schema.json", | |||
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The $schema URL "https://stackshift.dev/config-schema.json" should be verified to ensure it exists or will exist. If the schema file is not yet published or doesn't exist, this will cause validation errors in editors that respect $schema. Consider either publishing the schema or removing this field until it's available.
| "$schema": "https://stackshift.dev/config-schema.json", |
| **Why choose when you can have both?** | ||
|
|
||
| ``` | ||
| BE RAD = Business logic Extraction + Reverse engineering + Agent-Driven development |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "BE RAD" acronym is explained inconsistently across files. In README.md it's "Business logic Extraction + Reverse engineering + Agent-Driven development", but in stackshift.implement.md it's "Business logic extraction, Everything documented, Ready for any workflow, Adaptable to your needs, Decision-free" (using all 5 letters). Consider standardizing the acronym explanation across all documentation for clarity.
| BE RAD = Business logic Extraction + Reverse engineering + Agent-Driven development | |
| BE RAD = Business logic extraction, Everything documented, Ready for any workflow, Adaptable to your needs, Decision-free |
| @@ -0,0 +1,190 @@ | |||
| #!/bin/bash | |||
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New shell scripts should be committed with executable permissions (chmod +x). Consider verifying that this file has the execute bit set in the repository. Users may need to run 'chmod +x scripts/install-universal.sh' before executing if the permission is not preserved in git.
| ╔═══════════════════════════════════════════════════════════════╗ | ||
| ║ Choose Your Implementation Framework ║ | ||
| ╚═══════════════════════════════════════════════════════════════╝ |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The visual box border uses different length equals signs (═) in the top line compared to the bottom line, but this appears intentional for the visual design. However, for consistency, verify that the box renders correctly across different terminal widths and consider using a consistent character count to ensure the box displays properly in various environments.
| # Claude Code | ||
| if [ -d "$HOME/.claude" ] || command -v claude &> /dev/null; then | ||
| DETECTED_TOOLS+=("claude-code") | ||
| TOOL_PATHS["claude-code"]="$HOME/.claude/commands" | ||
| echo " ✅ Claude Code detected → $HOME/.claude/commands" | ||
| fi | ||
|
|
||
| # OpenCode | ||
| if command -v opencode &> /dev/null || [ -d "$HOME/.config/opencode" ]; then | ||
| DETECTED_TOOLS+=("opencode") | ||
| TOOL_PATHS["opencode"]="$HOME/.config/opencode/commands" | ||
| echo " ✅ OpenCode detected → $HOME/.config/opencode/commands" | ||
| fi | ||
|
|
||
| # Cursor | ||
| if [ -d "$HOME/.cursor" ] || command -v cursor &> /dev/null; then | ||
| DETECTED_TOOLS+=("cursor") | ||
| TOOL_PATHS["cursor"]="$HOME/.cursor/prompts" | ||
| echo " ✅ Cursor detected → $HOME/.cursor/prompts" | ||
| fi | ||
|
|
||
| # Windsurf | ||
| if [ -d "$HOME/.windsurf" ] || command -v windsurf &> /dev/null; then | ||
| DETECTED_TOOLS+=("windsurf") | ||
| TOOL_PATHS["windsurf"]="$HOME/.windsurf/commands" | ||
| echo " ✅ Windsurf detected → $HOME/.windsurf/commands" | ||
| fi | ||
|
|
||
| # Codex (OpenAI) | ||
| if command -v codex &> /dev/null || [ -d "$HOME/.codex" ]; then | ||
| DETECTED_TOOLS+=("codex") | ||
| TOOL_PATHS["codex"]="$HOME/.codex/commands" | ||
| echo " ✅ Codex detected → $HOME/.codex/commands" | ||
| fi | ||
|
|
||
| # VSCode with Continue extension | ||
| if [ -d "$HOME/.continue" ]; then | ||
| DETECTED_TOOLS+=("continue") | ||
| TOOL_PATHS["continue"]="$HOME/.continue/prompts" | ||
| echo " ✅ Continue (VSCode) detected → $HOME/.continue/prompts" | ||
| fi |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The detection logic for each tool is duplicated with the same pattern repeated for each tool. Consider extracting this into a function that takes the tool name, command name, directory checks, and target path as parameters. This would reduce code duplication and make it easier to add new tools in the future.
| # Claude Code | |
| if [ -d "$HOME/.claude" ] || command -v claude &> /dev/null; then | |
| DETECTED_TOOLS+=("claude-code") | |
| TOOL_PATHS["claude-code"]="$HOME/.claude/commands" | |
| echo " ✅ Claude Code detected → $HOME/.claude/commands" | |
| fi | |
| # OpenCode | |
| if command -v opencode &> /dev/null || [ -d "$HOME/.config/opencode" ]; then | |
| DETECTED_TOOLS+=("opencode") | |
| TOOL_PATHS["opencode"]="$HOME/.config/opencode/commands" | |
| echo " ✅ OpenCode detected → $HOME/.config/opencode/commands" | |
| fi | |
| # Cursor | |
| if [ -d "$HOME/.cursor" ] || command -v cursor &> /dev/null; then | |
| DETECTED_TOOLS+=("cursor") | |
| TOOL_PATHS["cursor"]="$HOME/.cursor/prompts" | |
| echo " ✅ Cursor detected → $HOME/.cursor/prompts" | |
| fi | |
| # Windsurf | |
| if [ -d "$HOME/.windsurf" ] || command -v windsurf &> /dev/null; then | |
| DETECTED_TOOLS+=("windsurf") | |
| TOOL_PATHS["windsurf"]="$HOME/.windsurf/commands" | |
| echo " ✅ Windsurf detected → $HOME/.windsurf/commands" | |
| fi | |
| # Codex (OpenAI) | |
| if command -v codex &> /dev/null || [ -d "$HOME/.codex" ]; then | |
| DETECTED_TOOLS+=("codex") | |
| TOOL_PATHS["codex"]="$HOME/.codex/commands" | |
| echo " ✅ Codex detected → $HOME/.codex/commands" | |
| fi | |
| # VSCode with Continue extension | |
| if [ -d "$HOME/.continue" ]; then | |
| DETECTED_TOOLS+=("continue") | |
| TOOL_PATHS["continue"]="$HOME/.continue/prompts" | |
| echo " ✅ Continue (VSCode) detected → $HOME/.continue/prompts" | |
| fi | |
| detect_tool() { | |
| local tool_key="$1" | |
| local display_name="$2" | |
| local target_path="$3" | |
| local dir_to_check="$4" | |
| local cmd_name="$5" | |
| local detected=false | |
| if [ -n "$dir_to_check" ] && [ -d "$dir_to_check" ]; then | |
| detected=true | |
| fi | |
| if [ -n "$cmd_name" ] && command -v "$cmd_name" &> /dev/null; then | |
| detected=true | |
| fi | |
| if [ "$detected" = true ]; then | |
| DETECTED_TOOLS+=("$tool_key") | |
| TOOL_PATHS["$tool_key"]="$target_path" | |
| echo " ✅ $display_name detected → $target_path" | |
| fi | |
| } | |
| # Claude Code | |
| detect_tool "claude-code" "Claude Code" "$HOME/.claude/commands" "$HOME/.claude" "claude" | |
| # OpenCode | |
| detect_tool "opencode" "OpenCode" "$HOME/.config/opencode/commands" "$HOME/.config/opencode" "opencode" | |
| # Cursor | |
| detect_tool "cursor" "Cursor" "$HOME/.cursor/prompts" "$HOME/.cursor" "cursor" | |
| # Windsurf | |
| detect_tool "windsurf" "Windsurf" "$HOME/.windsurf/commands" "$HOME/.windsurf" "windsurf" | |
| # Codex (OpenAI) | |
| detect_tool "codex" "Codex" "$HOME/.codex/commands" "$HOME/.codex" "codex" | |
| # VSCode with Continue extension | |
| detect_tool "continue" "Continue (VSCode)" "$HOME/.continue/prompts" "$HOME/.continue" "" |
| case "${selection^^}" in | ||
| Q) | ||
| echo "Installation cancelled." | ||
| exit 0 | ||
| ;; | ||
| A) |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The case statement uses parameter expansion ${selection^^} to convert to uppercase, but the 'Q' case is already uppercase. While this works correctly, for consistency, consider using lowercase 'q' in the case pattern (e.g., q|Q) or documenting that the input is normalized to uppercase before the case statement.
| case "${selection^^}" in | |
| Q) | |
| echo "Installation cancelled." | |
| exit 0 | |
| ;; | |
| A) | |
| case "$selection" in | |
| [Qq]) | |
| echo "Installation cancelled." | |
| exit 0 | |
| ;; | |
| [Aa]) |
| if [ -f .stackshift-config.json ]; then | ||
| echo "✅ Found .stackshift-config.json - using pre-configured settings" | ||
| cat .stackshift-config.json | jq '.frameworks' | ||
| SKIP_PROMPTS=true | ||
| else | ||
| echo "ℹ️ No .stackshift-config.json found (optional)" |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pre-configuration check sets SKIP_PROMPTS but doesn't actually extract and use the configuration values from the file. The bash script should parse implementation_framework and default_route from .stackshift-config.json and use those values instead of prompting. Currently, it only displays the frameworks section but doesn't skip the interactive prompts that follow.
| if [ -f .stackshift-config.json ]; then | |
| echo "✅ Found .stackshift-config.json - using pre-configured settings" | |
| cat .stackshift-config.json | jq '.frameworks' | |
| SKIP_PROMPTS=true | |
| else | |
| echo "ℹ️ No .stackshift-config.json found (optional)" | |
| CONFIG_FILE=".stackshift-config.json" | |
| if [ -f "$CONFIG_FILE" ]; then | |
| echo "✅ Found $CONFIG_FILE - using pre-configured settings" | |
| # Show configured frameworks (for visibility) | |
| jq '.frameworks' "$CONFIG_FILE" | |
| # Extract pre-configured values to use instead of interactive prompts | |
| implementation_framework="$(jq -r '.implementation_framework // empty' "$CONFIG_FILE")" | |
| default_route="$(jq -r '.default_route // empty' "$CONFIG_FILE")" | |
| if [ -n "$implementation_framework" ]; then | |
| export IMPLEMENTATION_FRAMEWORK="$implementation_framework" | |
| fi | |
| if [ -n "$default_route" ]; then | |
| export DEFAULT_ROUTE="$default_route" | |
| fi | |
| SKIP_PROMPTS=true | |
| else | |
| echo "ℹ️ No $CONFIG_FILE found (optional)" |
| #### Gear 3: Create Specifications (Auto) | ||
| - Creates `.specify/` structure with Spec Kit specs | ||
| - Generates constitution and feature specs | ||
| - Creates implementation plans for incomplete features |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BOTH path documentation states that Gear 3 "Creates .specify/ structure with Spec Kit specs" but doesn't clarify what happens when implementation_framework is set to "both" in the actual command files. Since stackshift.create-specs.md (Gear 3) only has Path A (speckit) and Path B (bmad) documented, users following the BOTH path won't find matching instructions in that command file. The documentation should either note that BOTH follows the Spec Kit path for Gears 3-5, or the command files need Path C sections.
| - Creates implementation plans for incomplete features | |
| - Creates implementation plans for incomplete features | |
| - For `implementation_framework: "both"`, cruise control uses the Spec Kit path (same as `speckit`) for Gears 3–5 |
Use public GitHub URLs for installation instructions
f35c7b4 to
be39093
Compare
This implements the patterns from the OpenCode compatibility guide:
Universal LLM Tool Support
"BE RAD" Framework Option
Key Changes
BE RAD = Business logic Extraction + Reverse engineering + Agent-Driven development :-p