From 73a9af70a4049c8480ba5a05eb1435274b41336a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87etinkaya?= Date: Thu, 11 Sep 2025 15:35:46 +0300 Subject: [PATCH 1/3] feat: add Qwen Code support to Spec Kit Add comprehensive Qwen Code integration following existing patterns: - Add Qwen as fourth AI assistant option in CLI - Update all documentation to include Qwen CLI references - Extend GitHub Actions workflow for Qwen template generation - Add Qwen support to shell scripts and templates - Maintain backward compatibility with existing assistants --- .github/workflows/release.yml | 20 ++++++++++++++++++-- CONTRIBUTING.md | 2 +- README.md | 5 +++-- scripts/update-agent-context.sh | 14 ++++++++++---- src/specify_cli/__init__.py | 21 +++++++++++++++++---- templates/plan-template.md | 4 ++-- 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c1ebfbc7..6d38d5a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -146,6 +146,16 @@ jobs: generate_commands "copilot" "prompt.md" "\$ARGUMENTS" "sdd-copilot-package/.github/prompts" echo "Created GitHub Copilot package" + # Create Qwen CLI package + mkdir -p sdd-qwen-package + cp -r sdd-package-base/* sdd-qwen-package/ + mkdir -p sdd-qwen-package/.qwen/commands + generate_commands "qwen" "md" "\$ARGUMENTS" "sdd-qwen-package/.qwen/commands" + if [ -f "agent_templates/qwen/QWEN.md" ]; then + cp agent_templates/qwen/QWEN.md sdd-qwen-package/QWEN.md + fi + echo "Created Qwen CLI package" + # Create archive files for each package cd sdd-claude-package && zip -r ../spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip . && cd .. @@ -153,6 +163,8 @@ jobs: cd sdd-copilot-package && zip -r ../spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip . && cd .. + cd sdd-qwen-package && zip -r ../spec-kit-template-qwen-${{ steps.get_tag.outputs.new_version }}.zip . && cd .. + # List contents for verification echo "Claude package contents:" unzip -l spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip | head -10 @@ -160,6 +172,8 @@ jobs: unzip -l spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip | head -10 echo "Copilot package contents:" unzip -l spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip | head -10 + echo "Qwen package contents:" + unzip -l spec-kit-template-qwen-${{ steps.get_tag.outputs.new_version }}.zip | head -10 - name: Generate release notes if: steps.check_release.outputs.exists == 'false' @@ -183,12 +197,13 @@ jobs: cat > release_notes.md << EOF Template release ${{ steps.get_tag.outputs.new_version }} - Updated specification-driven development templates for GitHub Copilot, Claude Code, and Gemini CLI. + Updated specification-driven development templates for GitHub Copilot, Claude Code, Gemini CLI, and Qwen Code. Download the template for your preferred AI assistant: - spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip - spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip - - spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip + - spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip + - spec-kit-template-qwen-${{ steps.get_tag.outputs.new_version }}.zip EOF echo "Generated release notes:" @@ -205,6 +220,7 @@ jobs: spec-kit-template-copilot-${{ steps.get_tag.outputs.new_version }}.zip \ spec-kit-template-claude-${{ steps.get_tag.outputs.new_version }}.zip \ spec-kit-template-gemini-${{ steps.get_tag.outputs.new_version }}.zip \ + spec-kit-template-qwen-${{ steps.get_tag.outputs.new_version }}.zip \ --title "Spec Kit Templates - $VERSION_NO_V" \ --notes-file release_notes.md env: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a7a75c2c..6d8441ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ These are one time installations required to be able to test your changes locall 1. Install [Python 3.11+](https://www.python.org/downloads/) 1. Install [uv](https://docs.astral.sh/uv/) for package management 1. Install [Git](https://git-scm.com/downloads) -1. Have an AI coding agent available: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), or [Gemini CLI](https://github.com/google-gemini/gemini-cli) +1. Have an AI coding agent available: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Qwen CLI](https://github.com/QwenLM/qwen-code) ## Submitting a pull request diff --git a/README.md b/README.md index ff768c53..b1ebcc8f 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Our research and experimentation focus on: ## 🔧 Prerequisites - **Linux/macOS** (or WSL2 on Windows) -- AI coding agent: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), or [Gemini CLI](https://github.com/google-gemini/gemini-cli) +- AI coding agent: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Qwen CLI](https://github.com/QwenLM/qwen-code) - [uv](https://docs.astral.sh/uv/) for package management - [Python 3.11+](https://www.python.org/downloads/) - [Git](https://git-scm.com/downloads) @@ -147,11 +147,12 @@ You will be prompted to select the AI agent you are using. You can also proactiv specify init --ai claude specify init --ai gemini specify init --ai copilot +specify init --ai qwen # Or in current directory: specify init --here --ai claude ``` -The CLI will check if you have Claude Code or Gemini CLI installed. If you do not, or you prefer to get the templates without checking for the right tools, use `--ignore-agent-tools` with your command: +The CLI will check if you have Claude Code, Gemini CLI, or Qwen CLI installed. If you do not, or you prefer to get the templates without checking for the right tools, use `--ignore-agent-tools` with your command: ```bash specify init --ai claude --ignore-agent-tools diff --git a/scripts/update-agent-context.sh b/scripts/update-agent-context.sh index 21b77aaa..c51ac7f9 100755 --- a/scripts/update-agent-context.sh +++ b/scripts/update-agent-context.sh @@ -14,6 +14,7 @@ NEW_PLAN="$FEATURE_DIR/plan.md" CLAUDE_FILE="$REPO_ROOT/CLAUDE.md" GEMINI_FILE="$REPO_ROOT/GEMINI.md" COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md" +QWEN_FILE="$REPO_ROOT/QWEN.md" # Allow override via argument AGENT_TYPE="$1" @@ -197,20 +198,24 @@ case "$AGENT_TYPE" in "copilot") update_agent_file "$COPILOT_FILE" "GitHub Copilot" ;; + "qwen") + update_agent_file "$QWEN_FILE" "Qwen Code" + ;; "") # Update all existing files [ -f "$CLAUDE_FILE" ] && update_agent_file "$CLAUDE_FILE" "Claude Code" [ -f "$GEMINI_FILE" ] && update_agent_file "$GEMINI_FILE" "Gemini CLI" [ -f "$COPILOT_FILE" ] && update_agent_file "$COPILOT_FILE" "GitHub Copilot" + [ -f "$QWEN_FILE" ] && update_agent_file "$QWEN_FILE" "Qwen Code" # If no files exist, create based on current directory or ask user - if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ]; then + if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ] && [ ! -f "$QWEN_FILE" ]; then echo "No agent context files found. Creating Claude Code context file by default." update_agent_file "$CLAUDE_FILE" "Claude Code" fi ;; *) - echo "ERROR: Unknown agent type '$AGENT_TYPE'. Use: claude, gemini, copilot, or leave empty for all." + echo "ERROR: Unknown agent type '$AGENT_TYPE'. Use: claude, gemini, copilot, qwen, or leave empty for all." exit 1 ;; esac @@ -227,8 +232,9 @@ if [ ! -z "$NEW_DB" ] && [ "$NEW_DB" != "N/A" ]; then fi echo "" -echo "Usage: $0 [claude|gemini|copilot]" +echo "Usage: $0 [claude|gemini|copilot|qwen]" echo " - No argument: Update all existing agent context files" echo " - claude: Update only CLAUDE.md" echo " - gemini: Update only GEMINI.md" -echo " - copilot: Update only .github/copilot-instructions.md" \ No newline at end of file +echo " - copilot: Update only .github/copilot-instructions.md" +echo " - qwen: Update only QWEN.md" \ No newline at end of file diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 94ac3dea..936fb738 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -51,7 +51,8 @@ import readchar AI_CHOICES = { "copilot": "GitHub Copilot", "claude": "Claude Code", - "gemini": "Gemini CLI" + "gemini": "Gemini CLI", + "qwen": "Qwen Code" } # ASCII Art Banner @@ -638,7 +639,7 @@ def download_and_extract_template(project_path: Path, ai_assistant: str, is_curr @app.command() def init( project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here)"), - ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, or copilot"), + ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, or qwen"), ignore_agent_tools: bool = typer.Option(False, "--ignore-agent-tools", help="Skip checks for AI agent tools like Claude Code"), no_git: bool = typer.Option(False, "--no-git", help="Skip git repository initialization"), here: bool = typer.Option(False, "--here", help="Initialize project in the current directory instead of creating a new one"), @@ -648,7 +649,7 @@ def init( This command will: 1. Check that required tools are installed (git is optional) - 2. Let you choose your AI assistant (Claude Code, Gemini CLI, or GitHub Copilot) + 2. Let you choose your AI assistant (Claude Code, Gemini CLI, GitHub Copilot, or Qwen Code) 3. Download the appropriate template from GitHub 4. Extract the template to a new project directory or current directory 5. Initialize a fresh git repository (if not --no-git and no existing repo) @@ -659,6 +660,7 @@ def init( specify init my-project --ai claude specify init my-project --ai gemini specify init my-project --ai copilot --no-git + specify init my-project --ai qwen specify init --ignore-agent-tools my-project specify init --here --ai claude specify init --here @@ -737,6 +739,10 @@ def init( if not check_tool("gemini", "Install from: https://github.com/google-gemini/gemini-cli"): console.print("[red]Error:[/red] Gemini CLI is required for Gemini projects") agent_tool_missing = True + elif selected_ai == "qwen": + if not check_tool("qwen", "Install from: https://github.com/QwenLM/qwen-code"): + console.print("[red]Error:[/red] Qwen CLI is required for Qwen Code projects") + agent_tool_missing = True # GitHub Copilot check is not needed as it's typically available in supported IDEs if agent_tool_missing: @@ -824,6 +830,12 @@ def init( steps_lines.append(" - See GEMINI.md for all available commands") elif selected_ai == "copilot": steps_lines.append(f"{step_num}. Open in Visual Studio Code and use [bold cyan]/specify[/], [bold cyan]/plan[/], [bold cyan]/tasks[/] commands with GitHub Copilot") + elif selected_ai == "qwen": + steps_lines.append(f"{step_num}. Use / commands with Qwen CLI") + steps_lines.append(" - Run qwen /specify to create specifications") + steps_lines.append(" - Run qwen /plan to create implementation plans") + steps_lines.append(" - Run qwen /tasks to generate tasks") + steps_lines.append(" - See QWEN.md for all available commands") step_num += 1 steps_lines.append(f"{step_num}. Update [bold magenta]CONSTITUTION.md[/bold magenta] with your project's non-negotiable principles") @@ -856,11 +868,12 @@ def check(): console.print("\n[cyan]Optional AI tools:[/cyan]") claude_ok = check_tool("claude", "Install from: https://docs.anthropic.com/en/docs/claude-code/setup") gemini_ok = check_tool("gemini", "Install from: https://github.com/google-gemini/gemini-cli") + qwen_ok = check_tool("qwen", "Install from: https://github.com/QwenLM/qwen-code") console.print("\n[green]✓ Specify CLI is ready to use![/green]") if not git_ok: console.print("[yellow]Consider installing git for repository management[/yellow]") - if not (claude_ok or gemini_ok): + if not (claude_ok or gemini_ok or qwen_ok): console.print("[yellow]Consider installing an AI assistant for the best experience[/yellow]") diff --git a/templates/plan-template.md b/templates/plan-template.md index f28a655d..2a648a3d 100644 --- a/templates/plan-template.md +++ b/templates/plan-template.md @@ -16,7 +16,7 @@ → Update Progress Tracking: Initial Constitution Check 4. Execute Phase 0 → research.md → If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns" -5. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, or `GEMINI.md` for Gemini CLI). +5. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, `GEMINI.md` for Gemini CLI, or `QWEN.md` for Qwen Code). 6. Re-evaluate Constitution Check section → If new violations: Refactor design, return to Phase 1 → Update Progress Tracking: Post-Design Constitution Check @@ -171,7 +171,7 @@ ios/ or android/ - Quickstart test = story validation steps 5. **Update agent file incrementally** (O(1) operation): - - Run `/scripts/update-agent-context.sh [claude|gemini|copilot]` for your AI assistant + - Run `/scripts/update-agent-context.sh [claude|gemini|copilot|qwen]` for your AI assistant - If exists: Add only NEW tech from current plan - Preserve manual additions between markers - Update recent changes (keep last 3) From c5e0c1840b4b9cdb7f899702a6e93889f0fbc749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87etinkaya?= Date: Mon, 15 Sep 2025 11:45:24 +0300 Subject: [PATCH 2/3] chore: address review feedback - remove comment and fix numbering --- .github/workflows/release.yml | 3 --- CONTRIBUTING.md | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7f66e66..bb29563b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -129,6 +129,3 @@ jobs: sed -i "s/version = \".*\"/version = \"$PYTHON_VERSION\"/" pyproject.toml echo "Updated pyproject.toml version to $PYTHON_VERSION (for release artifacts only)" fi - - # Note: No longer committing version changes back to main branch - # The version is only updated in the release artifacts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 888b8096..7916d973 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,9 +9,9 @@ Please note that this project is released with a [Contributor Code of Conduct](C These are one time installations required to be able to test your changes locally as part of the pull request (PR) submission process. 1. Install [Python 3.11+](https://www.python.org/downloads/) -2. Install [uv](https://docs.astral.sh/uv/) for package management -3. Install [Git](https://git-scm.com/downloads) -4. Have an AI coding agent available: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Qwen Code](https://github.com/QwenLM/qwen-code). We're working on adding support for other agents as well. +1. Install [uv](https://docs.astral.sh/uv/) for package management +1. Install [Git](https://git-scm.com/downloads) +1. Have an AI coding agent available: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Qwen Code](https://github.com/QwenLM/qwen-code). We're working on adding support for other agents as well. ## Submitting a pull request @@ -19,13 +19,13 @@ These are one time installations required to be able to test your changes locall >If your pull request introduces a large change that materially impacts the work of the CLI or the rest of the repository (e.g., you're introducing new templates, arguments, or otherwise major changes), make sure that it was **discussed and agreed upon** by the project maintainers. Pull requests with large changes that did not have a prior conversation and agreement will be closed. 1. Fork and clone the repository -2. Configure and install the dependencies: `uv sync` -3. Make sure the CLI works on your machine: `uv run specify --help` -4. Create a new branch: `git checkout -b my-branch-name` -5. Make your change, add tests, and make sure everything still works -6. Test the CLI functionality with a sample project if relevant -7. Push to your fork and submit a pull request -8. Wait for your pull request to be reviewed and merged. +1. Configure and install the dependencies: `uv sync` +1. Make sure the CLI works on your machine: `uv run specify --help` +1. Create a new branch: `git checkout -b my-branch-name` +1. Make your change, add tests, and make sure everything still works +1. Test the CLI functionality with a sample project if relevant +1. Push to your fork and submit a pull request +1. Wait for your pull request to be reviewed and merged. Here are a few things you can do that will increase the likelihood of your pull request being accepted: From 8b49d5d0fb676566ba8aba5ece35111610bd7086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87etinkaya?= Date: Wed, 17 Sep 2025 11:39:03 +0300 Subject: [PATCH 3/3] chore(release): bump version to 0.0.5 and update changelog Add entry for Qwen Code support as new AI assistant option --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91eb47a6..0722e520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.0.5] - 2025-09-17 + +### Added + +- Qwen Code support as additional AI assistant option + ## [0.0.4] - 2025-09-14 ### Added diff --git a/pyproject.toml b/pyproject.toml index 7eeeb52d..412c04ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "specify-cli" -version = "0.0.4" +version = "0.0.5" description = "Setup tool for Specify spec-driven development projects" requires-python = ">=3.11" dependencies = [