Conversation
…ub#1758) * test(commands): create extension-commands LLM playground sandbox * update(tests): format LLM evaluation as an automated test runner * test(commands): map extension-commands python script with timestamps * test(commands): map extension-commands python script with timestamps * test(commands): update TESTING.md to evaluate discovery, lint, and deploy explicitly * test(commands): simplify execution expectations and add timestamp calculation * fix(tests): address copilot review comments on prompt formatting and relative paths * fix(tests): resolve copilot PR feedback regarding extension schema structure and argparse mutually exclusive groups * feat(extensions): add core selftest utility and migrate away from manual tests sandbox * fix(selftest): update command name array to match spec-kit validation schema * fix(selftest): wrap arguments in quotes to support multi-word extension names * update the command to be more meaningful * fix: if the extension is discovery only, it should not be installable * Address review comments for selftest documentation * address review comments * address review comments * Update extensions/selftest/commands/selftest.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ithub#1808) * fix(cli): deprecate explicit command support for agy (github#1798) * docs(cli): add tests and docs for agy deprecation (github#1798) * fix: address review comments for agy deprecation * fix: address round 2 review comments for agy deprecation * fix: address round 3 review comments for agy deprecation * fix: address round 4 review comments for agy deprecation * fix: address round 5 review comments for agy deprecation * docs: add inline contextual comments to explain agy deprecation * docs: clarify historical context in agy deprecation docstring * fix: correct skills path in deprecation comment and make test mock fully deterministic
…github#1730) * fix: migrate Qwen Code CLI from TOML to Markdown format (github#1589) Qwen Code CLI v0.10.0 deprecated TOML format and fully switched to Markdown as the core format for configuration and interaction files. - Update create-release-packages.sh: generate .md files with $ARGUMENTS instead of .toml files with {{args}} for qwen agent - Update create-release-packages.ps1: same change for PowerShell script - Update AGENTS.md: reflect Qwen's new Markdown format in docs and remove Qwen from TOML format section - Update tests/test_ai_skills.py: add commands_dir_qwen fixture and tests covering Markdown-format skills installation for Qwen Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: update CommandRegistrar qwen config to Markdown format extensions.py CommandRegistrar.AGENT_CONFIGS['qwen'] was still set to TOML format, causing `specify extension` to write .toml files into .qwen/commands, conflicting with Qwen Code CLI v0.10.0+ expectations. - Change qwen format from toml to markdown - Change qwen args from {{args}} to $ARGUMENTS - Change qwen extension from .toml to .md - Add test to assert qwen config is Markdown format Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: clean up command templates (specify, analyze)
- specify.md: fix self-referential step number (step 6c → proceed to step 7)
- specify.md: remove empty "General Guidelines" heading before "Quick Guidelines"
- analyze.md: deduplicate {ARGS} — already present in "User Input" section at top
* fix: restore ## Context heading in analyze template
Address PR review feedback from @dhilipkumars: keep the ## Context
markdown heading to preserve structural hierarchy for LLM parsing.
…ss (github#1809) - Replace eval of unquoted get_feature_paths output with safe pattern: capture into variable, check return code, then eval quoted result - Use printf '%q' in get_feature_paths to safely emit shell assignments, preventing injection via paths containing quotes or metacharacters - Add json_escape() helper for printf JSON fallback paths, handling backslash, double-quote, and control characters when jq is unavailable - Use jq -cn for safe JSON construction with proper escaping when available, with printf + json_escape() fallback - Replace declare -A (bash 4+) with indexed array for bash 3.2 compatibility (macOS default) - Use inline command -v jq check in create-new-feature.sh since it does not source common.sh - Guard trap cleanup against re-entrant invocation by disarming traps at entry - Use printf '%q' for shell-escaped branch names in user-facing output - Return failure instead of silently returning wrong path on ambiguous spec directory matches - Deduplicate agent file updates via realpath to prevent multiple writes to the same file (e.g. AGENTS.md aliased by multiple variables)
* Add specify doctor command for project health diagnostics * Add tests for specify doctor command * Document specify doctor command in README * Revert "Document specify doctor command in README" This reverts commit c1cfd06. * Revert "Add tests for specify doctor command" This reverts commit 65e12fb. * Revert "Add specify doctor command for project health diagnostics" This reverts commit d5bd932. * Add doctor extension to community catalog * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…hub#1836) The template outputs plain text `Last updated: [DATE]` but both update-agent-context scripts only matched `**Last updated**: [DATE]` (bold Markdown). Make the bold markers optional in the regex so the timestamp is refreshed regardless of formatting. Co-authored-by: easonysliu <easonysliu@tencent.com> Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
…ills propagation (github#1787) * Initial plan * feat(templates): add pluggable template system with packs, catalog, resolver, and CLI commands Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * test(templates): add comprehensive unit tests for template pack system Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * feat(presets): pluggable preset system with template/command overrides, catalog, and resolver - Rename 'template packs' to 'presets' to avoid naming collision with core templates - PresetManifest, PresetRegistry, PresetManager, PresetCatalog, PresetResolver in presets.py - Extract CommandRegistrar to agents.py as shared infrastructure - CLI: specify preset list/add/remove/search/resolve/info - CLI: specify preset catalog list/add/remove - --preset option on specify init - Priority-based preset stacking (--priority, lower = higher precedence) - Command overrides registered into all detected agent directories (17+ agents) - Extension command safety: skip registration if target extension not installed - Multi-catalog support: env var, project config, user config, built-in defaults - resolve_template() / Resolve-Template in bash/PowerShell scripts - Self-test preset: overrides all 6 core templates + 1 command - Scaffold with 4 examples: core/extension template and command overrides - Preset catalog (catalog.json, catalog.community.json) - Documentation: README.md, ARCHITECTURE.md, PUBLISHING.md - 110 preset tests, 253 total tests passing * feat(presets): propagate command overrides to skills via init-options - Add save_init_options() / load_init_options() helpers that persist CLI flags from 'specify init' to .specify/init-options.json - PresetManager._register_skills() overwrites SKILL.md files when --ai-skills was used during init and corresponding skill dirs exist - PresetManager._unregister_skills() restores core template content on preset removal - registered_skills stored in preset registry metadata - 8 new tests covering skill override, skip conditions, and restore * fix: address PR check failures (ruff F541, CodeQL URL substring) - Remove extraneous f-prefix from two f-strings without placeholders - Replace substring URL check in test with startswith/endswith assertions to satisfy CodeQL incomplete URL substring sanitization rule * fix: address Copilot PR review comments - Move save_init_options() before preset install so skills propagation works during 'specify init --preset --ai-skills' - Clean up downloaded ZIP after successful preset install during init - Validate --from URL scheme (require HTTPS, HTTP only for localhost) - Expose unregister_commands() on extensions.py CommandRegistrar wrapper instead of reaching into private _registrar field - Use _get_merged_packs() for search() and get_pack_info() so all active catalogs are searched, not just the highest-priority one - Fix fetch_catalog() cache to verify cached URL matches current URL - Fix PresetResolver: script resolution uses .sh extension, consistent file extensions throughout resolve(), and resolve_with_source() delegates to resolve() to honor template_type parameter - Fix bash common.sh: fall through to directory scan when python3 returns empty preset list - Fix PowerShell Resolve-Template: filter out dot-folders and sort extensions deterministically * fix: narrow empty except blocks and add explanatory comments * fix: address Copilot PR review comments (round 2) - Fix init --preset error masking: distinguish "not found" from real errors - Fix bash resolve_template: skip hidden dirs in extensions (match Python/PS) - Fix temp dir leaks in tests: use temp_dir fixture instead of mkdtemp - Fix self-test catalog entry: add note that it's local-only (no download_url) - Fix Windows path issue in resolve_with_source: use Path.relative_to() - Fix skill restore path: use project's .specify/templates/commands/ not source tree - Add encoding="utf-8" to all file read/write in agents.py - Update test to set up core command templates for skill restoration * fix: remove self-test from catalog.json (local-only preset) * fix: address Copilot PR review comments (round 3) - Fix PS Resolve-Template fallback to skip dot-prefixed dirs (.cache) - Rename _catalog to _catalog_name for consistency with extension system - Enforce install_allowed policy in CLI preset add and download_pack() - Fix shell injection: pass registry path via env var instead of string interpolation * fix: correct PresetError docstring from template to preset * Removed CHANGELOG requirement * Applying review recommendations * Applying review recommendations * Applying review recommendations * Applying review recommendations --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>
* chore: bump version to 0.3.0 * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…thub#1838) * feat: add DocGuard CDD enforcement extension to community catalog DocGuard is a Canonical-Driven Development enforcement tool that generates, validates, scores, and traces project documentation against 51 automated checks. Provides 6 commands: - guard: 51-check validation with quality labels - diagnose: AI-ready fix prompts - score: CDD maturity scoring (0-100) - trace: ISO 29119 traceability matrix - generate: Reverse-engineer docs from codebase - init: Initialize CDD with compliance profiles Features: - Zero dependencies (pure Node.js) - Config-aware traceability (respects .docguard.json) - Orphan file detection - Research-backed (AITPG/TRACE, IEEE TSE/TMLCN 2026) npm: https://www.npmjs.com/package/docguard-cli GitHub: https://github.com/raccioly/docguard * fix: use release asset URL for download_url The source archive URL nests files under a subdirectory, so the Spec Kit installer cannot find extension.yml at the archive root. Switch to a release asset ZIP built from the extension directory. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * docs: add DocGuard to community extensions README table * chore: update DocGuard entry to v0.8.0 (92 checks) * chore: update DocGuard description (51→92 checks) --------- Co-authored-by: Ricardo Accioly <ricardoaccioly@RAccioly-J0CWDQ4MXV.attlocal.net> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…atalog (github#1844) * feat(extensions): add reconcile and archive to community catalog * Update extension link text and add changelogs Normalize extension link text in extensions/README.md (replace `[@stn1slv]` with `spec-kit-archive` and `spec-kit-reconcile`) and add CHANGELOG URLs to the corresponding entries in extensions/catalog.community.json for the Archive and Reconcile extensions. --------- Co-authored-by: Stanislav Deviatov <stn1slv@users.noreply.github.com>
Display the extension ID below the name in `specify extension list` output. This allows users to easily copy the ID when disambiguation is needed. Fixes github#1832 Co-authored-by: iamaeroplane <michal.bachorik@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add specify status command with project info, agent detection, and feature detection * feat: add SDD artifacts check and task progress parsing to specify status * feat: add workflow phase detection and extensions summary to specify status * Revert "feat: add workflow phase detection and extensions summary to specify status" This reverts commit 1afe3c5. * Revert "feat: add SDD artifacts check and task progress parsing to specify status" This reverts commit 3be36f8. * Revert "feat: add specify status command with project info, agent detection, and feature detection" This reverts commit 681dc46. * feat: add spec-kit-status extension to community catalog * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Revert "Potential fix for pull request finding" This reverts commit 040447b. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com>
* chore: update DocGuard to v0.9.7 * docs: update DocGuard description in extensions table * chore: update DocGuard to v0.9.8 --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com>
- Extension ID: cognitive-squad - Version: 0.1.0 - Author: Testimonial - 19-function cognitive agent squad for autonomous pre-code analysis - 7 core agents, 7 specialists, 4 learning functions, feedback loop - Requires: spec-kit >=0.3.0, optionally understanding >=3.4.0 Repository: https://github.com/Testimonial/cognitive-squad Co-authored-by: Ladislav Bihari <ladislav.bihari@statsperform.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
github#1869) * fix(scripts): harden bash scripts with escape, compat, and cleanup fixes - common.sh: complete RFC 8259 JSON escape (\b, \f, strip control chars) - common.sh: distinguish python3 success-empty vs failure in resolve_template - check-prerequisites.sh: escape doc names through json_escape in fallback path - create-new-feature.sh: remove duplicate json_escape (already in common.sh) - create-new-feature.sh: warn on stderr when spec template is not found - update-agent-context.sh: move nested function to top-level for bash 3.2 compat * fix(scripts): explicit resolve_template return code and best-effort agent updates - common.sh: resolve_template now returns 1 when no template is found, making the "not found" case explicit instead of relying on empty stdout - setup-plan.sh, create-new-feature.sh: add || true to resolve_template calls so set -e does not abort on missing templates (non-fatal) - update-agent-context.sh: accumulate errors in update_all_existing_agents instead of silently discarding them — all agents are attempted and the composite result is returned, matching the PowerShell equivalent behavior * style(scripts): add clarifying comment in resolve_template preset branch * fix(scripts): wrap python3 call in if-condition to prevent set -e abort Move the python3 command substitution in resolve_template into an if-condition so that a non-zero exit (e.g. invalid .registry JSON) does not abort the function under set -e. The fallback directory scan now executes as intended regardless of caller errexit settings. * fix(scripts): track agent file existence before update and avoid top-level globals - _update_if_new now records the path and sets _found_agent before calling update_agent_file, so that failures do not cause duplicate attempts on aliased paths (AMP/KIRO/BOB -> AGENTS_FILE) or false "no agent files found" fallback triggers - Remove top-level initialisation of _updated_paths and _found_agent; they are now created exclusively inside update_all_existing_agents, keeping the script side-effect free when sourced
…github#1876) In multi-remote environments, `git fetch --all` outputs messages like "Fetching origin" to stdout. Since `check_existing_branches()` only redirected stderr (`2>/dev/null`), the stdout output was captured by the `$(...)` command substitution calling this function, contaminating the branch number return value and causing arithmetic errors like `$((10#Fetching...))`. Fix: redirect both stdout and stderr to /dev/null (`>/dev/null 2>&1`).
…hub#1855) * feat(extensions,presets): add priority-based resolution ordering Add priority field to extension and preset registries for deterministic template resolution when multiple sources provide the same template. Extensions: - Add `list_by_priority()` method to ExtensionRegistry - Add `--priority` option to `extension add` command - Add `extension set-priority` command - Show priority in `extension list` and `extension info` - Preserve priority during `extension update` - Update RFC documentation Presets: - Add `preset set-priority` command - Show priority in `preset info` output - Use priority ordering in PresetResolver for extensions Both systems: - Lower priority number = higher precedence (default: 10) - Backwards compatible with legacy entries (missing priority defaults to 10) - Comprehensive test coverage including backwards compatibility Closes github#1845 Closes github#1854 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address code review feedback - list_by_priority(): add secondary sort by ID for deterministic ordering, return deep copies to prevent mutation - install_from_directory/zip: validate priority >= 1 early - extension add CLI: validate --priority >= 1 before install - PresetRegistry.update(): preserve installed_at timestamp - Test assertions: use exact source string instead of substring match Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address additional review feedback - PresetResolver: add fallback to directory scanning when registry is empty/corrupted for robustness and backwards compatibility - PresetRegistry.update(): add guard to prevent injecting installed_at when absent in existing entry (mirrors ExtensionRegistry behavior) - RFC: update extension list example to match actual CLI output format Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: restore defensive code and RFC descriptions lost in rebase - Restore defensive code in list_by_priority() with .get() and isinstance check - Restore detailed --from URL and --dev option descriptions in RFC Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: add defensive code to presets list_by_priority() - Add .get() and isinstance check for corrupted/empty registry - Move copy import to module level (remove local import) - Matches defensive pattern used in extensions.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address reviewer feedback on priority resolution - Rename _normalize_priority to normalize_priority (public API) - Add comprehensive tests for normalize_priority function (9 tests) - Filter non-dict metadata entries in list_by_priority() methods - Fix extension priority resolution to merge registered and unregistered extensions into unified sorted list (unregistered get implicit priority 10) - Add tests for extension priority resolution ordering (4 tests) The key fix ensures unregistered extensions with implicit priority 10 correctly beat registered extensions with priority > 10, and vice versa. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: DRY refactor and strengthen test assertions - Extract _get_all_extensions_by_priority() helper in PresetResolver to eliminate duplicated extension list construction - Add priority=10 assertion to test_legacy_extension_without_priority_field - Add priority=10 assertion to test_legacy_preset_without_priority_field Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: add isinstance(dict) checks for corrupted registry entries Add defensive checks throughout CLI commands and manager methods to handle cases where registry entries may be corrupted (non-dict values). This prevents AttributeError when calling .get() on non-dict metadata. Locations fixed: - __init__.py: preset/extension info, set-priority, enable/disable, upgrade commands - extensions.py: list_installed() - presets.py: list_installed() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: normalize priority display to match resolution behavior Use normalize_priority() for all priority display in CLI commands to ensure displayed values match actual resolution behavior when registry data is corrupted/hand-edited. Locations fixed: - extensions.py: list_installed() - presets.py: list_installed(), PresetResolver - __init__.py: preset info, extension info, set-priority commands Also added GraphQL query for unresolved PR comments to CLAUDE.md. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: repair corrupted priority values in set-priority commands Changed set-priority commands to check if the raw stored value is already a valid int equal to the requested priority before skipping. This ensures corrupted values (e.g., "high") get repaired even when setting to the default priority (10). Also removed CLAUDE.md that was accidentally added to the repo. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: harden registry update methods against corrupted entries - Normalize priority when restoring during extension update to prevent propagating corrupted values (e.g., "high", 0, negative) - Add isinstance(dict) checks in ExtensionRegistry.update() and PresetRegistry.update() to handle corrupted entries (string/list) that would cause TypeError on merge Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: use safe fallback for version in list_installed() When registry entry is corrupted (non-dict), metadata becomes {} after the isinstance check. Use metadata.get("version", manifest.version) instead of metadata["version"] to avoid KeyError. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: iamaeroplane <michal.bachorik@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…hub#1874) * feat(cli): polite deep merge for settings.json with json5 and safe atomic write * fix(cli): prevent temp fd leak and align merge-policy docs
* feat: add Trae IDE support as a new agent Add Trae (https://www.trae.ai/) as a supported AI agent in spec-kit. Trae is an IDE-based agent that uses .trae/rules/ directory for project-level rules in Markdown format. Changes across 9 files: - src/specify_cli/__init__.py: Add trae to AGENT_CONFIG (IDE-based, .trae/ folder, rules subdir, no CLI required) - src/specify_cli/extensions.py: Add trae to CommandRegistrar.AGENT_CONFIGS (.trae/rules, markdown format, .md extension) - README.md: Add Trae to supported agents table, CLI examples, and --ai option description - .github/workflows/scripts/create-release-packages.sh: Add trae to ALL_AGENTS array and build case statement - .github/workflows/scripts/create-release-packages.ps1: Add trae to AllAgents array and switch statement - .github/workflows/scripts/create-github-release.sh: Add trae template zip files to release assets - scripts/bash/update-agent-context.sh: Add TRAE_FILE, trae case in update function, and auto-detect block - scripts/powershell/update-agent-context.ps1: Add TRAE_FILE, ValidateSet entry, switch case, and auto-detect block - tests/test_agent_config_consistency.py: Add 8 consistency tests for trae following established kimi/tabnine patterns * fix: correct Generate-Commands parameter names for trae in PowerShell release script Fix incorrect parameter names in the trae case of Build-Variant: - -Format -> -Extension - -ArgsToken -> -ArgFormat - -OutDir -> -OutputDir These now match the Generate-Commands function signature and all other agent entries in the script. Co-authored-by: Copilot <copilot@github.com> * Update release packaging scripts and agent docs * Update Agent.md * Restore format * Adjust order * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Unused * fix: add TRAE_FILE to update_all_existing_agents() for auto-detect support Add missing update_if_new call for TRAE_FILE in the bash update-agent-context.sh script's update_all_existing_agents() function, matching the PowerShell implementation. This ensures running the script without arguments will correctly auto-detect and update existing Trae agent files. * Add configuration for 'trae' in agents.py * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Refactor trae configuration test for clarity * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update update-agent-context.sh * Fix formatting in update-agent-context.sh --------- Co-authored-by: root <root@g340-cd52-700-60f9-5561-211-6c32.byted.org> Co-authored-by: root <root@g340-cd52-700-c3d1-c735-796-4b9e.byted.org> Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
github#1867) * fix(ai-skills): exclude non-speckit copilot agent markdown from skill generation * Potential fix for pull request finding Fix missing `.agent` filename suffix Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Fix test assertion speckit.plan.md to speckit.plan.agent Fix test assertion speckit.plan.md to speckit.plan.agent * Fix filter glob based on review suggestions fix(ai-skills): normalize Copilot .agent template names and align template fallback filtering * Add template glob for fallback directory * GH Copilot Suggestions Clarify comment regarding Copilot's use of templates in tests. Add extra test assertion * fix(ai-skills): normalize Copilot .agent templates and preserve fallback behavior fix(ai-skills): handle Copilot .agent templates and fallback filtering Normalize Copilot command template names by stripping the .agent suffix when deriving skill names and metadata sources, so files like speckit.plan.agent.md produce speckit-plan and map to plan.md metadata. Also align Copilot template discovery with speckit.* filtering while preserving fallback to templates/commands/ when .github/agents contains only user-authored markdown files, and add regression coverage for both non-speckit agent exclusion and fallback behavior. * fix(ai-skills): ignore non-speckit markdown commands --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* chore: bump version to 0.3.1 * fix: correct 0.3.1 CHANGELOG.md entries (github#1882) * Initial plan * fix: correct 0.3.1 CHANGELOG.md entries - fix truncated title and remove duplicates Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
* feat: register spec-kit-learn extension * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> resolve copilot review Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* feat(ai): add native support for Pi coding agent by pi+gpt 5.4 * docs(pi): document MCP limitations for Pi agent * fix: unitended kimi agent mention added to update-agent-context.ps1 * fix: address reviewer feedback * Apply suggestions from code review Changes in AGENTS.md weren't part of my PR, but the Copilot feedback seems to be correct is correct. I've doublechecked it with contents of test_agent_config_consistency.py and create-release-packages scripts Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
… stripping (github#1872) * fix(scripts): encode residual control chars as \uXXXX instead of stripping json_escape() was silently deleting control characters (U+0000-U+001F) that were not individually handled (\n, \t, \r, \b, \f). Per RFC 8259, these must be encoded as \uXXXX sequences to preserve data integrity. Replace the tr -d strip with a char-by-char loop that emits proper \uXXXX escapes for any remaining control characters. * fix(scripts): address Copilot review on json_escape control char loop - Set LC_ALL=C for the entire loop (not just printf) so that ${#s} and ${s:$i:1} operate on bytes deterministically across locales - Fix comment: U+0000 (NUL) cannot exist in bash strings, range is U+0001-U+001F; adjust code guard accordingly (code >= 1) - Emit directly to stdout instead of accumulating in a variable, avoiding quadratic string concatenation on longer inputs * perf(scripts): use printf -v to avoid subshell in json_escape loop Replace code=$(printf ...) with printf -v code to assign the character code without spawning a subshell on every byte, reducing overhead for longer inputs.
…w-feature params (github#1885) The $Number (Int32) parameter was implicitly receiving positional arguments intended for $FeatureDescription, causing a ParameterBindingArgumentTransformationException when AI agents called the script with positional strings. Add [Parameter(Position = 0)] to $FeatureDescription so it binds first, and mark $Number with [Parameter()] (no Position) so it only binds by name (-Number N). Fixes github#1879 Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: register spec-kit-iterate extension * fix: copilot review * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- Version: 1.0.0 → 1.1.0 - Commands: 1 → 3 (check, load, validate) - Hooks: 2 → 4 (before_plan, before_tasks, before_implement, after_implement) - Added: persistent constraints artifact, two-channel model, CVE detection, decision record fallback for greenfield projects, skip artifact persistence Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat(cli): add specify self check and self upgrade stub (github#2282) Introduce a new `specify self` Typer sub-app with two subcommands. `specify self check` performs a read-only lookup against the GitHub Releases API, compares the installed version to the latest tag with PEP 440 semantics, and prints one of four verdicts (newer-available, up-to-date, indeterminate, graceful-failure). When a newer stable release is available, the output includes a copy-pasteable `uv tool install --force --from git+...@<tag>` reinstall command. `GH_TOKEN` / `GITHUB_TOKEN` is attached as a bearer credential when set so users behind shared IPs escape the anonymous 60/hour rate limit. `specify self upgrade` is a documented non-destructive stub in this release: three-line guidance output, exit 0, no outbound call, no install-method detection. The real destructive implementation is planned as follow-up work. Failure categorization is a fixed three-entry enum (offline or timeout, rate limited, HTTP <code>). Anything outside those three categories propagates as a non-zero exit so bugs surface instead of being silently swallowed. No machine-readable output, no retries, no caching in this release — see issue github#2282 discussion. Tests mock `urllib.request.urlopen`; the suite performs zero real network calls. Full regression suite: 1586 passed. * fix(cli): disable Rich highlight for deterministic output Rich's default `highlight=True` applies ANSI color to detected patterns (integers, version strings, paths) whenever stdout is deemed a TTY. This caused intermittent failures in existing pytest assertions in tests/test_cli_version.py and tests/test_extensions.py::TestExtensionRemoveCLI that compare plain-text output without passing through `strip_ansi()`. Setting `Console(highlight=False)` globally makes all CLI output deterministic and fixes the flake without modifying the affected tests. The numeric cyan highlighting was not a documented part of the CLI visual contract. * fix: address copilot review feedback * fix: tighten self-check token handling * fix: align self-check helpers and script metadata * fix: harden self-check version handling * fix: guard self-check failure rendering
…ex/kimi (github#2313) * fix: resolve skill placeholders for all SKILL.md agents, not just codex/kimi * chore: remove unused NATIVE_SKILLS_AGENTS constant
* chore: bump version to 0.7.5 * chore: begin 0.7.6.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…ade (github#2320) * fix: --force now overwrites shared infra files during init and upgrade _install_shared_infra() previously skipped all existing files under .specify/scripts/ and .specify/templates/, regardless of --force. This meant users could never receive upstream fixes to shared scripts or templates after initial project setup. Changes: - Add force parameter to _install_shared_infra(); when True, existing files are overwritten with the latest bundled versions - Wire force=True through specify init --here --force and specify integration upgrade --force call sites - Replace hidden logging.warning with visible console output listing skipped files and suggesting --force - Fix contradictory upgrade docs that claimed --force updated shared infra (it didn't) and warned about overwrites (they didn't happen) - Add 6 tests: unit tests for skip/overwrite/warning behavior, plus end-to-end CLI tests for both --force and non-force paths Fixes github#2319 * fix: improve skip warning to suggest specific commands Address review feedback: the generic '--force' suggestion was misleading when _install_shared_infra is called from integration install/switch (which don't have a --force for shared infra). Now points users to the specific commands that can refresh shared infra: 'specify init --here --force' or 'specify integration upgrade --force'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs(install): add pipx as alternative installation method - Add pipx commands to README.md installation section - Add note about pipx compatibility to docs/installation.md - Mention pipx persistent installation in docs/quickstart.md - Add pipx upgrade instructions to docs/upgrade.md - Clarify that project has no uv-specific dependencies Refs: github#2255 * docs(install): address Copilot feedback - update prerequisites and upgrade references for pipx * Update docs/quickstart.md markdownlint’s MD012 (enabled in this repo) flags multiple consecutive blank lines Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/upgrade.md In the Quick Reference table, the label “pipx upgrade” is misleading because the command shown is `pipx install --force ...` (a reinstall). by copilot. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…based scaffolding (github#2324) * Initial plan * feat(copilot): add --skills flag for skills-based scaffolding Add --skills integration option to CopilotIntegration that scaffolds commands as speckit-<name>/SKILL.md under .github/skills/ instead of the default .agent.md + .prompt.md layout. - Add options() with --skills flag (default=False) - Branch setup() between default and skills modes - Add post_process_skill_content() for Copilot-specific mode: field - Adjust build_command_invocation() for skills mode (/speckit-<stem>) - Update dispatch_command() with skills mode detection - Parse --integration-options during init command - Add 22 new skills-mode tests - All 15 existing default-mode tests continue to pass Agent-Logs-Url: https://github.com/github/spec-kit/sessions/a4903fab-64ff-46c3-8eb8-a47f495a70c0 Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * docs(AGENTS.md): document Copilot --skills option Agent-Logs-Url: https://github.com/github/spec-kit/sessions/a4903fab-64ff-46c3-8eb8-a47f495a70c0 Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Potential fix for pull request finding 'Unused local variable' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * fix: address PR github#2324 review feedback - Reset _skills_mode at start of setup() to prevent singleton state leak - Tighten skills auto-detection to require speckit-*/SKILL.md (not any non-empty .github/skills/ directory) - Add copilot_skill_mode to init next-steps so skills mode renders /speckit-plan instead of /speckit.plan - Fix docstring quoting to match actual unquoted output - Add 4 tests covering singleton reset, auto-detection false positive, speckit layout detection, and next-steps skill syntax - Fix skipped test_invalid_metadata_error_returns_unknown by simulating InvalidMetadataError on Python versions that lack it * fix: inline skills prompt in dispatch_command auto-detection path build_command_invocation() reads self._skills_mode which stays False when skills mode is only auto-detected from the project layout. Inline the /speckit-<stem> prompt construction so dispatch_command() sends the correct prompt regardless of how skills mode was detected. Also strengthen test_dispatch_detects_speckit_skills_layout to assert the -p prompt contains /speckit-plan and the user args. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…plates, commands, and scripts (github#2133) * fix: rebase onto upstream/main, resolve conflicts with PR github#2189 upstream/main merged PR github#2189 (wrap-only strategy) which overlaps with our comprehensive composition strategies (prepend/append/wrap). Resolved conflicts keeping our implementation as source of truth: - README: keep our future considerations (composition is now fully implemented, not a future item) - presets.py: keep our composition architecture (_reconcile_composed_commands, collect_all_layers, resolve_content) while preserving github#2189's _substitute_core_template which is used by agents.py for skill generation - tests: keep both test sets (our composition tests + github#2189's wrap tests), removed TestReplayWrapsForCommand and TestInstallRemoveWrapLifecycle which test the superseded _replay_wraps_for_command API; our composition tests cover equivalent scenarios - Restored missing _unregister_commands call in remove() that was lost during github#2189 merge * fix: re-create skill directory in _reconcile_skills after removal After _unregister_skills removes a skill directory, _register_skills skips writing because the dir no longer passes the is_dir() check. Fix by ensuring the skill subdirectory exists before calling _register_skills so the next winning preset's content gets registered. Fixes the Claude E2E failure where removing a top-priority override preset left skill-based agents without any SKILL.md file. * fix: address twenty-third round of Copilot PR review feedback - Protect reconciliation in remove(): wrap _reconcile_composed_commands and _reconcile_skills in try/except so failures emit a warning instead of leaving the project in an inconsistent state - Protect reconciliation in install(): same pattern for post-install reconciliation so partial installs don't lack cleanup - Inherit scripts/agent_scripts from base frontmatter: when composing commands, merge scripts and agent_scripts keys from the base command's frontmatter into the top layer's frontmatter if missing, preventing composed commands from losing required script references - Add tier-5 bundled core fallback to collect_all_layers(): check the bundled core_pack (wheel) or repo-root templates (source checkout) when .specify/templates/ doesn't contain the core file, matching resolve()'s tier-5 fallback so composition can always find a base layer * fix: address twenty-fourth round of Copilot PR review feedback - Use yaml.safe_load for frontmatter parsing in resolve_content instead of CommandRegistrar.parse_frontmatter which uses naive find('---',3); strip strategy key from final frontmatter to prevent leaking internal composition directives into rendered agent command files - Filter _reconcile_skills to specific commands: use _FilteredManifest wrapper so only the commands being reconciled get their skills updated, preventing accidental overwrites of other commands' skills that may be owned by higher-priority presets * fix: address twenty-fifth round of Copilot PR review feedback - Support legacy command-frontmatter strategy: when preset.yml doesn't declare a strategy, check the command file's YAML frontmatter for strategy: wrap as a fallback so legacy wrap presets participate in composition and multi-preset chaining - Guard skill dir creation in _reconcile_skills: only re-create the skill directory if the skill was previously managed (listed in some preset's registered_skills), avoiding creation of new skill dirs that _register_skills would normally skip * fix: add explanatory comment to empty except in legacy frontmatter parsing * fix: address twenty-sixth round of Copilot PR review feedback - Unregister stale commands when composition fails: when resolve_content returns None during reconciliation (base layer removed), unregister the command from non-skill agents and emit a warning - Load extension aliases during reconciliation: _register_command_from_path now checks extension.yml for aliases when the winning layer is an extension, so alias files are restored after preset removal - Use line-based fence detection for legacy frontmatter strategy fallback: scan for --- on its own line instead of split('---',2) to avoid mis-parsing YAML values containing --- * fix: address twenty-seventh round of Copilot PR review feedback - Handle non-preset winners in _reconcile_skills: when the winning layer is core/extension/project-override, restore skills via _unregister_skills so skill-based agents stay consistent with the priority stack - Update base_frontmatter_text on replace layers: when a higher-priority replace layer occurs during composition, update both top and base frontmatter so scripts/agent_scripts inheritance reflects the effective base beneath the top composed layer * fix: address twenty-eighth round of Copilot PR review feedback - Parse only interior lines in _parse_fm_yaml: use lines[1:-1] instead of filtering all --- lines, preventing corruption when YAML values contain a line that is exactly --- - Omit empty frontmatter: skip re-rendering when top_fm is empty dict to avoid emitting ---/{}/--- for intentionally empty frontmatter - Update scaffold wrap comment: mention both {CORE_TEMPLATE} and $CORE_SCRIPT placeholders for templates/commands vs scripts - Clarify shell composition scope in ARCHITECTURE.md: note that bash/PS1 resolve_template_content only handles templates; command/script composition is handled by the Python resolver * fix: address twenty-ninth round of Copilot PR review feedback - Fix TestCollectAllLayers docstring: reference collect_all_layers() - Add default/unknown strategy handling in bash/PS1 composition: error on unrecognized strategy values instead of silently skipping - Fix comment: .composed/ is a persistent dir, not temporary - Fix comment: legacy fallback checks all valid strategies, not just wrap - Cache PresetRegistry in _reconcile_skills: build presets_by_priority once instead of constructing registry per-command * fix: address thirtieth round of Copilot PR review feedback - Guard legacy frontmatter fallback: only check command file frontmatter for strategy when the manifest entry doesn't explicitly include the strategy key, preventing override of manifest-declared strategies - Document rollback limitation: note that mid-registration failures may leave orphaned agent command files since partial progress isn't captured by the local vars * fix: handle project override skills and extension context in reconciliation * fix: add comment to empty except in extension registration fallback * fix: filter extension commands in reconciliation and fix type annotation * fix: filter extension commands from post-install reconciliation Apply the same extension-installed check used in _register_commands to the reconciliation command list, preventing reconciliation from registering commands for extensions that are not installed. * fix: skip convention fallback for explicit file paths and add stem fallback to tier-5 When a preset manifest provides an explicit file path that does not exist, skip the convention-based fallback to avoid masking typos. Also add speckit.<stem> to <stem>.md fallback in tier-5 bundled/source core lookup for consistency with tier-4. * fix: scan past non-replace layers to find base in resolve_content The base-finding scan now skips non-replace layers below a replace layer instead of stopping at the first non-replace. This fixes the case where a low-priority append/prepend layer sits below a replace that should serve as the base for composition. * fix: add context_note to non-skill agent registration for extensions Add context_note parameter to register_commands_for_non_skill_agents and pass extension name/id during reconciliation so rendered command files preserve the extension-specific context markers. * fix: Optional type, rollback safety, and override skill restoration - Fix context_note type to Optional[str] - Wrap shutil.rmtree in try/except during install rollback - Separate override-backed skills from core/extension in _reconcile_skills * fix: align bash/PS1 base-finding with Python resolver Rewrite bash and PowerShell composition loops to find the effective base replace layer first (scanning bottom-up, skipping non-replace layers below it), then compose only from the base upward. This prevents evaluation of irrelevant lower layers (e.g. a wrap with no placeholder below a replace) and matches resolve_content behavior. * fix: PS1 no-python warning, integration hook for override skills, alias cleanup - Warn when no Python 3 found in PS1 and presets use composition strategies - Apply post_process_skill_content integration hook when restoring override-backed skills so agent-specific flags are preserved - Unregister command aliases alongside primary name when composition fails to prevent orphaned alias files * fix: include aliases in removed_cmd_names during preset removal Read aliases from preset manifest before deleting pack_dir so alias command files are included in unregistration and reconciliation. * fix: add comment to empty except in alias extraction during removal * fix: scan top-down for effective base in all resolvers Change base-finding to scan from highest priority downward to find the nearest replace layer, then compose only layers above it. Prevents evaluation of irrelevant lower layers (e.g. a wrap without placeholder below a higher-priority replace) across Python, bash, and PowerShell. * fix: align CLI composition chain display with top-down base-finding Show only contributing layers (base and above) in preset resolve output, matching resolve_content top-down semantics. Layers below the effective base are omitted since they do not contribute. * fix: guard corrupted registry entries and make manifest authoritative - Add isinstance(meta, dict) guard in bash registry parsing so corrupted entries are skipped instead of breaking priority ordering - Only use convention-based file lookup when the manifest does not list the requested template, making preset.yml authoritative and preventing stray on-disk files from creating unintended layers * fix: align resolve() with manifest file paths and match extension context_note - Update resolve() preset tier to consult manifest file paths before convention-based lookup, matching collect_all_layers behavior - Use exact extension context_note format matching extensions.CommandRegistrar - Update test to declare template in manifest (authoritative manifest) * revert: restore resolve() convention-based behavior for backwards compatibility resolve() is the existing public API used by shell scripts and other callers. Changing it to manifest-authoritative breaks backward compat for presets that rely on convention-based file lookup. Only the new collect_all_layers/resolve_content path uses manifest-authoritative logic. * fix: only pre-compose when this preset is the top composing layer Skip composition in _register_commands when a higher-priority replace layer already wins for the command. Register the raw file instead and let reconciliation write the correct final content. * fix: deduplicate PyYAML warnings and use self.registry in reconciliation - Emit PyYAML-missing warning once per function call in bash/PS1 instead of per-preset to avoid spamming stderr - Use self.registry.list_by_priority() in reconciliation methods instead of constructing new PresetRegistry instances to avoid redundant I/O and potential consistency issues * fix: document strategy handling consistency between layers and registrar Composed output already strips strategy from frontmatter (resolve_content pops it). Raw file registration preserves legacy frontmatter strategy for backward compat; reconciliation corrects the final state. * fix: correct stale comments for alias tracking and base-finding algorithm * security: validate manifest file paths in bash/PowerShell resolvers Reject absolute paths and parent directory traversal (..) in the manifest-declared file field before joining with the preset directory. Matches the Python-side validation in PresetManifest._validate(). --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com>
* chore: bump version to 0.8.0 * chore: begin 0.8.1.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update preset-fiction-book-writing to community catalog - Preset ID: fiction-book-writing - Version: 1.5.0 - Author: Andreas Daumann - Description: Spec-Driven Development for novel and long-form fiction. Replaces software engineering terminology with storytelling craft: specs become story briefs, plans become story structures, and tasks become scene-by-scene writing tasks. Supports 8 POV modes, all major plot structure frameworks, 5 humanized-AI prose profiles, and exports to DOCX/EPUB/LaTeX via pandoc. V1.5.0: Support interactive, audiobooks, series, workflow corrections * Add screenwriting preset to community catalog - Preset ID: screenwriting - Version: 1.0.0 - Author: Andreas Daumann - Description: Spec-Driven Development for screenwriting/scriptwriting/tutorials: feature films, television (pilot, episode, limited series), and stage plays. Adapts the Speckit workflow to screenplay craft — slug lines, action lines, act breaks, beat sheets, and industry-standard pitch documents replace prose fiction conventions. Supports three-act, Save the Cat, TV pilot, network episode, cable/streaming episode, and stage-play structural frameworks. * Update presets/catalog.community.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update presets/catalog.community.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat: register jira preset in community catalog Adds luno/spec-kit-preset-jira — overrides speckit.taskstoissues to create Jira issues instead of GitHub Issues. See github#2223 for context on why this is a preset rather than an extension. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use immutable tag URL and sort jira preset alphabetically - Change download_url from heads/main to refs/tags/v1.0.0 for reproducible installs - Move jira entry to correct alphabetical position in presets object Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Ed Harrod <1381991+echarrod@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…thub#2351) xargs re-parses stdin as shell tokens, causing 'unterminated quote' errors when feature descriptions contain apostrophes, double quotes, or backslashes. Replace with sed-based whitespace trim that preserves input verbatim. Add regression tests for special characters in descriptions (core and extension scripts), plus a negative test for whitespace-only input. Fixes github#2339
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.0.0 to 8.1.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](astral-sh/setup-uv@cec2083...0880764) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 8.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Update product-forge to v1.5.0 in community catalog - Extension ID: product-forge - Version: 1.1.1 → 1.5.0 - Author: VaiYav - Description: updated to reflect v1.5 features (portfolio, lite mode, monorepo, optional V-Model) - Commands: 10 → 29 - Tags: refreshed to reflect current surface area - download_url pinned to v1.5.0 release tag - updated_at bumped to 2026-04-24 Release: https://github.com/VaiYav/speckit-product-forge/releases/tag/v1.5.0 * Bump product-forge to v1.5.1 (docs patch) Follow-up to v1.5.0 that surfaces the optional V-Model dependency (leocamello/spec-kit-v-model ≥ 0.5.0) in README Requirements, config-template.yml, and docs/config.md. Docs-only patch — no behavioural change. Release: https://github.com/VaiYav/speckit-product-forge/releases/tag/v1.5.1
…ithub#2354) * fix: resolve command references per integration type (dot vs hyphen) Replace hardcoded /speckit.<cmd> references in templates with __SPECKIT_COMMAND_<NAME>__ placeholders that are resolved at setup time based on the integration type: - Markdown/TOML/YAML agents: separator='.' → /speckit.plan - Skills agents: separator='-' → /speckit-plan Changes: - Add resolve_command_refs() static method to IntegrationBase - Add invoke_separator class attribute (. for base, - for skills) - Wire into process_template() as step 8 - Update _install_shared_infra() to process page templates - Replace /speckit.* in 5 command templates and 3 page templates - Add unit tests for resolve_command_refs (positive + negative) - Add integration tests verifying on-disk content for all agents - Add end-to-end CLI tests for Claude (skills) and Copilot (markdown) Fixes github#2347 * review: use effective_invoke_separator() for Copilot skills mode Address PR review feedback: instead of bleeding _skills_mode knowledge into the CLI layer, add effective_invoke_separator() method to IntegrationBase that accepts parsed_options. CopilotIntegration overrides it to return "-" when skills mode is requested. The CLI layer simply asks the integration for its separator — no hasattr or _skills_mode coupling. Also adds tests for the new method on both base and Copilot, plus an end-to-end test for 'specify init --integration copilot --integration-options --skills' verifying page templates get hyphen refs. * fix: build_command_invocation preserves full suffix for extension commands Previously rsplit('.', 1)[-1] on 'speckit.git.commit' yielded just 'commit', producing /speckit.commit instead of /speckit.git.commit (or /speckit-git-commit for skills). Fix: strip only the 'speckit.' prefix when present, then join remaining segments with the appropriate separator. Updated in IntegrationBase, SkillsIntegration, and CopilotIntegration. Added tests for extension commands in build_command_invocation across all three. * fix: Copilot dispatch_command() preserves full extension command suffix dispatch_command() had the same rsplit('.', 1)[-1] bug as build_command_invocation() — speckit.git.commit would dispatch as /speckit-commit instead of /speckit-git-commit in skills mode, or --agent speckit.commit instead of speckit.git.commit in default mode.
…thub#2340) * docs(presets): add lean preset README and enrich catalog metadata - Add README.md documenting the lean workflow preset, its commands, when to use it, and development instructions. - Add license, requires.speckit_version, and provides.commands fields to the lean preset catalog entry. - Add "core" tag to preset.yml for discoverability. * fix: bump catalog updated_at and add provides.templates for consistency Address PR review feedback: - Bump updated_at to reflect catalog modification time - Add provides.templates (0) to lean preset entry for consistency with catalog schema used in catalog.community.json
…ithub#2341) * docs: move community presets table to docs site, add missing entries - Move the full community presets table from README.md to the docs site at docs/community/presets.md, replacing the README section with a short link (matching the pattern used for Walkthroughs and Friends). - Add missing Jira Issue Tracking and Screenwriting rows to the docs table so it reflects all entries in catalog.community.json. * docs(presets): add docs site table step to publishing guide Add step to update docs/community/presets.md when submitting a community preset, and add corresponding PR checklist item. Matches the pattern used in the extensions publishing guide. * Clarify alphabetical sort key in presets publishing guide Specify that the docs table should be sorted by preset name (the first column), disambiguating from the catalog JSON which sorts by preset ID. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Address review: fix provides count, admonition style, example row - Add missing scripts count to Fiction Book Writing table row to match catalog - Switch README disclaimer to GitHub admonition format for consistency - Include optional scripts count in PUBLISHING.md example row * Fix Fiction Book Writing link text to match actual repo name --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…arkdownIntegration (github#2336) * feat(vibe): migrate to SkillsIntegration and inject user-invocable frontmatter Switches VibeIntegration from the old prompts-based MarkdownIntegration to SkillsIntegration, adopting the .vibe/skills/speckit-<name>/SKILL.md layout required by Mistral Vibe v2.0.0+. Post-processes each generated SKILL.md to inject `user-invocable: true` so skills are directly callable by users, not just by other agents. * test(vibe): assert user- invocable: true is present in all generated SKILL.md files * Update tests/integrations/test_integration_vibe.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… git branches (github#2305) (github#2349) * fix: allow plan setup to use feature metadata on custom branches * fix: harden feature metadata validation * fix: use portable feature metadata path Made-with: Cursor * fix: share feature.json parser and make path compare OS aware * test: isolate setup plan subprocess environment * fix: normalize feature metadata paths with pwd -P
Upstream is 321 commits ahead of fork (with fork 6 ahead for its own customizations). This merge accepts upstream for all template/script conflicts, shedding the fork's terse-templates customization. README replaced with upstream's current version. CLAUDE.md (fork identity) preserved. Terse-fork behavior (cut commands ~80%, strict line limits) can be reinstated in a follow-up PR on top of the modern CLI base if desired. The speckit-runner skill in pylot already enforces token-efficient usage at the caller level, so losing template-level trimming is lower-impact than it appears. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maxfindel
left a comment
There was a problem hiding this comment.
Review: sync: upstream spec-kit v0.8.1
Reviewer: tooling.cto | Date: 2026-04-24
Summary
Syncs the fork 321 commits to upstream v0.8.1, tagged v0.8.1-fellowship.1 and immediately usable via uvx. The Python package jumps from v0.1.0 → v0.8.1 with a real specify CLI, an extensions system, presets, integrations catalog, and cross-platform CI. CI is green across all Ubuntu matrix rows; Windows pytest still in-progress at time of review.
The PR is transparent about its main trade-off: all five core templates (specify, plan, tasks, implement, analyze) were replaced wholesale with upstream versions, shedding the fork's terse-template identity.
Strengths
- CI green: CodeQL, markdownlint, ruff, and all three Ubuntu pytest variants (
3.11,3.12,3.13) pass. - CLAUDE.md preserved: Fork context and drift policy intact.
- Honest scope declaration: PR body explicitly acknowledges the terse-template trade-off rather than burying it.
- Already tagged:
v0.8.1-fellowship.1is usable immediately viauvx --from git+https://github.com/fellowship-dev/spec-kit.git@v0.8.1-fellowship.1. - Extensions + presets: New modular architecture (hooks, catalog, git extension, selftest extension, lean/scaffold presets) is a meaningful capability jump.
Issues
MUST FIX
1. Fork identity shed — no follow-up issue exists
All five core templates expanded 4–6× from the fork's terse originals:
| Template | Before (main) | After (PR) | Factor |
|---|---|---|---|
specify.md |
56 lines | 327 lines | 5.8× |
plan.md |
38 lines | 152 lines | 4.0× |
tasks.md |
41 lines | 203 lines | 5.0× |
implement.md |
34 lines | 201 lines | 5.9× |
analyze.md |
38 lines | 252 lines | 6.6× |
The PR body commits to a follow-up ("a follow-up can reinstate terse-fork behavior") but no tracking issue exists. Consumer repos (booster-pack, rails-backend, inbox-angel-worker, mtg-lotr, Clapes repos) will receive verbose upstream templates on their next speckit sync. Before merging, open a follow-up issue documenting: (a) which templates need re-trimming, (b) the target line limits from CLAUDE.md (spec ≤50, plan ≤50, tasks ≤40), and (c) the consumer repos that need a re-sync once templates are trimmed.
2. CLAUDE.md now contains stale claims
CLAUDE.md still says:
"Commits behind upstream: 252+"— now 0"Do NOT auto-merge upstream — changes must be cherry-picked manually"— this PR contradicts that policy"Commands cut ~80%: original ~1,400 lines → this fork ~250 lines"— no longer true
The fork's operating policy document must be updated to reflect the new reality before merge. Leaving it as-is will confuse the drift-checker and future tooling workers.
NICE TO HAVE
3. Removed --require-plan flag in check-prerequisites.sh
The script consolidated and dropped --require-plan. The new templates don't use it (they use setup-plan.sh instead), so no in-tree breakage. However, any external scripts or custom extensions calling the old flag will silently fail (Unknown option exits 1). Consider a short deprecation note in the script's help text if this is a public API surface.
4. Windows pytest in-progress
Three Windows matrix jobs (windows-latest × 3.11/3.12/3.13) were still running at review time. Not blocking, but confirm they pass before merging.
Template Impact on Pylot Consumers
speckit-runner in pylot enforces terseness at the caller level (instructs the model to be concise), which partially mitigates the context expansion. However, each speckit invocation now ships 4–6× more template tokens into the context window. The cost and latency increase is real — budget for it, and prioritize the terse-template follow-up if speckit calls show cost spikes.
Verdict
Conditional approval — strong engineering work, good CI coverage, honest trade-off disclosure. Two blockers before merge:
- Open a tracking issue for the terse-template follow-up (with specific files and target line limits)
- Update
CLAUDE.mdto reflect the new fork status (synced, not behind; policy on future upstreams)
Once those two items are done this can merge.
- Remove stale 'Commits behind: 252+' claim (now 0) - Replace 'Do NOT auto-merge' with current policy (bulk syncs OK under CTO review) - Replace 'Commands cut ~80%' with accurate template line counts + re-trim tracker - Link fellowship-dev/pylot#239 as follow-up for terse-template re-trimming Addresses review finding from double-check of PR #2.
Double-Check Review: PR #2 — sync: upstream spec-kit v0.8.1Reviewer: tooling.cto (double-check pass 2) IntentSyncs the fellowship-dev fork 321 commits to upstream v0.8.1, immediately usable via `uvx`. Delivers. All five core templates are updated; fork CLAUDE.md and bash scripts are preserved. Implementation
Prior Review MUST FIX Status
CI Status (all green)
New Issues FoundNone. The one outstanding item (template verbosity) is now tracked in fellowship-dev/pylot#239 and documented in CLAUDE.md. Tests After Fixes
VerdictReady for merge. Both MUST FIX items from the prior review have been resolved: follow-up issue created, CLAUDE.md updated. CI is fully green. The terse-template re-trim is a known follow-up tracked in issue fellowship-dev/pylot#239, not a blocker. |
Summary
Syncs the fork with upstream
github/spec-kitat v0.8.1 (released 2026-04-24). Before this PR the fork was 321 commits behind, with 6 fork-only commits.What changed
scripts/bash/*andtemplates/commands/*andREADME.md. This sheds the terse-templates customization (the "cut commands ~80%, strict line limits" fork identity).CLAUDE.md(fork context/drift policy).scripts/bash/update-agent-context.sh(deleted upstream).specifyCLI (v0.8.1) installable viauvx. Verified locally withuvx --from git+<fork>@v0.8.1-fellowship.1 specify --version→specify 0.8.1.Why not resolve the terse customizations manually?
Upstream evolved templates/scripts heavily over 321 commits — new commands, new sections, refactors. Re-trimming on top of the new content is a judgment call per file (what to keep, what to trim). Doing that silently while nobody was watching felt wrong. This PR unblocks immediate use of the modern CLI; a follow-up can reinstate terse-fork behavior on top of v0.8.1 if still wanted.
Impact on
pylotconsumersThe
speckit-runnerskill in pylot enforces token-efficient behavior at the caller level (instructing the model to be terse), so the loss of template-level trimming is softer than the raw line counts suggest.Released as
Tag:
v0.8.1-fellowship.1(usable viauvx --from git+https://github.com/fellowship-dev/spec-kit.git@v0.8.1-fellowship.1).🤖 Generated with Claude Code