710 Commits

Author SHA1 Message Date
github-actions[bot]
4fafe71bf5 chore: bump version to 0.4.5 v0.4.5 2026-04-02 17:35:32 +00:00
Manfred Riem
b1832c9477 Stage 6: Complete migration — remove legacy scaffold path (#1924) (#2063)
* Stage 6: Complete migration — remove legacy scaffold path (#1924)

Remove the legacy GitHub download and offline scaffold code paths.
All 26 agents now use the integration system exclusively.

Code removal (~1073 lines from __init__.py):
- download_template_from_github(), download_and_extract_template()
- scaffold_from_core_pack(), _locate_release_script()
- install_ai_skills(), _get_skills_dir (restored slim version for presets)
- _has_bundled_skills(), _migrate_legacy_kimi_dotted_skills()
- AGENT_SKILLS_MIGRATIONS, _handle_agent_skills_migration()
- _parse_rate_limit_headers(), _format_rate_limit_error()
- Three-way branch in init() collapsed to integration-only

Config derivation (single source of truth):
- AGENT_CONFIG derived from INTEGRATION_REGISTRY (replaced 180-line dict)
- CommandRegistrar.AGENT_CONFIGS derived from INTEGRATION_REGISTRY (replaced 160-line dict)
- Backward-compat constants kept for presets/extensions: SKILL_DESCRIPTIONS,
  NATIVE_SKILLS_AGENTS, DEFAULT_SKILLS_DIR

Release pipeline cleanup:
- Deleted create-release-packages.sh/.ps1 (948 lines of ZIP packaging)
- Deleted create-github-release.sh, generate-release-notes.sh
- Deleted simulate-release.sh, get-next-version.sh, update-version.sh
- Removed .github/workflows/scripts/ directory entirely
- release.yml is now self-contained: check, notes, release all inlined
- Install instructions use uv tool install with version tag

Test cleanup:
- Deleted test_ai_skills.py (tested removed functions)
- Deleted test_core_pack_scaffold.py (tested removed scaffold)
- Cleaned test_agent_config_consistency.py (removed 19 release-script tests)
- Fixed test_branch_numbering.py (removed dead monkeypatches)
- Updated auto-promote tests (verify files created, not tip messages)

1089 tests pass, 0 failures, ruff clean.

* fix: resolve merge conflicts with #2051 (claude as skills)

- Fix circular import: move CommandRegistrar import in claude
  integration to inside method bodies (was at module level)
- Lazy-populate AGENT_CONFIGS via _ensure_configs() to avoid
  circular import at class definition time
- Set claude registrar_config to .claude/commands (extension/preset
  target) since the integration handles .claude/skills in setup()
- Update tests from #2051 to match: registrar_config assertions,
  remove --integration tip assertions, remove install_ai_skills mocks

1086 tests pass.

* fix: properly preserve claude skills migration from #2051

Restore ClaudeIntegration.registrar_config to .claude/skills (not
.claude/commands) so extension/preset registrations write to the
correct skills directory.

Update tests that simulate claude setup to use .claude/skills and
check for SKILL.md layout. Some tests still need updating for the
full skills path — 10 remaining failures from the #2051 test
expectations around the extension/preset skill registration flow.

WIP: 1076/1086 pass.

* fix: properly handle SKILL.md paths in extension update rollback and tests

Fix extension update rollback using _compute_output_name() for SKILL.md
agents (converts dots to hyphens in skill directory names). Previously
the backup and cleanup code constructed paths with raw command names
(e.g. speckit.test-ext.hello/SKILL.md) instead of the correct computed
names (speckit-test-ext-hello/SKILL.md).

Test fixes for claude skills migration:
- Update claude tests to use .claude/skills paths and SKILL.md layout
- Use qwen (not claude) for skills-guard tests since claude's agent dir
  IS the skills dir — creating it triggers command registration
- Fix test_extension_command_registered_when_extension_present to check
  skills path format

1086 tests pass, 0 failures, ruff clean.

* fix: address PR review — lazy init, assertions, deprecated flags

- _ensure_configs(): catch ImportError (not Exception), don't set
  _configs_loaded on failure so retries work
- Move _ensure_configs() before unregister loop (not inside it)
- Module-level try/except catches ImportError specifically
- Remove tautology assertion (or True) in test_extensions.py
- Strengthen preset provenance assertion to check source: field
- Mark --offline, --skip-tls, --debug, --github-token as hidden
  deprecated no-ops in init()

1086 tests pass.

* fix: remove deleted release scripts from pyproject.toml force-include

Removes force-include entries for create-release-packages.sh/.ps1
which were deleted but still referenced in [tool.hatch.build].
2026-04-02 12:34:34 -05:00
Andrii Furmanets
a858c1d6da Install Claude Code as native skills and align preset/integration flows (#2051)
* Use Claude skills for generated commands

* Fix Claude integration and preset skill flows

* Group Claude tests in integration suite

* Align Claude skill frontmatter across generators

* Fix native skill preset cleanup

* Keep legacy AI skills test on legacy path

* Move Claude here-mode test to CLI suite
2026-04-02 09:44:48 -05:00
liuyiyu
d9ce7c1fc0 Add repoindex 0402 (#2062)
* Add repoindex to community catalog, -Extension ID: repoindex -Version 1.0.0 - Author: Yiyu Liu - Description: Generate repo index

* udpate sort order for repoindex

* Add repoindex to community catalog, -Extension ID: repoindex -Version 1.0.0 - Author: Yiyu Liu - Description: Generate repo index

* udpate sort order for repoindex

* Update main README adding repoindex intro

* fix display issue

* Update extensions/catalog.community.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-02 08:47:39 -05:00
Manfred Riem
4f9d966beb Stage 5: Skills, Generic & Option-Driven Integrations (#1924) (#2052)
* Stage 5: Skills, Generic & Option-Driven Integrations (#1924)

Add SkillsIntegration base class and migrate codex, kimi, agy, and
generic to the integration system.

Integrations:
- SkillsIntegration(IntegrationBase) in base.py — creates
  speckit-<name>/SKILL.md layout matching release ZIP output byte-for-byte
- CodexIntegration — .agents/skills/, --skills default=True
- KimiIntegration — .kimi/skills/, --skills + --migrate-legacy options,
  dotted→hyphenated skill directory migration
- AgyIntegration — .agent/skills/, skills-only (commands deprecated v1.20.5)
- GenericIntegration — user-specified --commands-dir, MarkdownIntegration
- All four have update-context.sh/.ps1 scripts
- All four registered in INTEGRATION_REGISTRY

CLI changes:
- --ai <agent> auto-promotes to integration path for all registered agents
- Interactive agent selection also auto-promotes (bug fix)
- --ai-skills and --ai-commands-dir show deprecation notices on integration path
- Next-steps display shows correct skill invocation syntax for skills integrations
- agy added to CommandRegistrar.AGENT_CONFIGS

Tests:
- test_integration_base_skills.py — reusable mixin with setup, frontmatter,
  directory structure, scripts, CLI auto-promote, and complete file inventory
  (sh+ps) tests
- Per-agent test files: test_integration_{codex,kimi,agy,generic}.py
- Kimi legacy migration tests, generic --commands-dir validation
- Registry updated with Stage 5 keys
- Removed 9 dead-mock tests, moved 4 integration tests to proper locations
- Fixed all bare project-name tests to use tmp_path
- Fixed 6 pre-existing ANSI escape code test failures in test_extensions.py
  and test_presets.py

1524 tests pass, 0 failures.

* fix: remove unused variable flagged by ruff (F841)

* fix: address PR review — integration-type-aware deprecation messages and early generic validation

- --ai-skills deprecation message now distinguishes SkillsIntegration
  ("skills are the default") from command-based integrations ("has no effect")
- --ai-commands-dir validation for generic runs even when auto-promoted,
  giving clear CLI error instead of late ValueError from setup()
- Resolves review comments from #2052

* fix: address PR review round 2

- Remove unused SKILL_DESCRIPTIONS dict from base.py (dead code after
  switching to template descriptions for ZIP parity)
- Narrow YAML parse catch from Exception to yaml.YAMLError
- Remove unused shutil import from test_integration_kimi.py
- Remove unused _REGISTRAR_EXEMPT class attr from test_registry.py
- Reword --ai-commands-dir deprecation to be actionable
- Update generic validation error to mention both --ai and --integration

* fix: address PR review round 3

- Clarify parsed_options forwarding is intentional (all options passed,
  integrations decide what to use)
- Extract _strip_ansi() helper in test_extensions.py and test_presets.py
- Remove unused pytest import (test_cli.py), unused locals (test_integration_base_skills.py)
- Reword --ai-commands-dir deprecation to be actionable without referencing
  the not-yet-implemented --integration-options

* fix: address PR review round 4

- Reorder kimi migration: run super().setup() first so hyphenated
  targets exist, then migrate dotted dirs (prevents user content loss)
- Move _strip_ansi() to shared tests/conftest.py, import from there
  in test_extensions.py, test_presets.py, test_ai_skills.py
- Remove now-unused re imports from all three test files

* fix: address PR review round 5

- Use write_bytes() for LF-only newlines (no CRLF on Windows)
- Add --integration-options CLI parameter — raw string passed through
  to the integration via opts['raw_options']; the integration owns
  parsing of its own options
- GenericIntegration.setup() reads --commands-dir from raw_options
  when not in parsed_options (supports --integration-options="...")
- Skip early --ai-commands-dir validation when --integration-options
  is provided (integration validates in its own setup())
- Remove parse_integration_options from core — integrations parse
  their own options

* fix: address PR review round 6

- GenericIntegration is now stateless: removed self._commands_dir
  instance state, overrides setup() directly to compute destination
  from parsed_options/raw_options on the stack
- commands_dest() raises by design (stateless singleton)
- _quote() in SkillsIntegration now escapes backslashes and double
  quotes to produce valid YAML even with special characters

* fix: address PR review round 7

- Support --commands-dir=value form in raw_options parsing (not just
  --commands-dir value with space separator)
- Normalize CRLF to LF in write_file_and_record() before encoding
- Persist ai_skills=True in init-options.json when using a
  SkillsIntegration, so extensions/presets emit SKILL.md overrides
  correctly even without explicit --ai-skills flag
2026-04-02 08:00:12 -05:00
Roland Huß
b44ffc0101 feat(scripts): add --dry-run flag to create-new-feature (#1998)
* feat(scripts): add --dry-run flag to create-new-feature scripts

Add a --dry-run / -DryRun flag to both bash and PowerShell
create-new-feature scripts that computes the next branch name,
spec file path, and feature number without creating any branches,
directories, or files. This enables external tools to query the
next available name before running the full specify workflow.

When combined with --json, the output includes a DRY_RUN field.
Without --dry-run, behavior is completely unchanged.

Closes #1931

Assisted-By: 🤖 Claude Code

* fix(scripts): gate specs/ dir creation behind dry-run check

Dry-run was unconditionally creating the root specs/ directory via
mkdir -p / New-Item before the dry-run guard. This violated the
documented contract of zero side effects. Also adds returncode
assertion on git branch --list in tests and adds PowerShell dry-run
test coverage (skipped when pwsh unavailable).

Addresses review comments on #1998.

Assisted-By: 🤖 Claude Code

* fix: address PR review feedback

- Gate `mkdir -p $SPECS_DIR` behind DRY_RUN check (bash + PowerShell)
  so dry-run creates zero directories
- Add returncode assertion on `git branch --list` in test
- Strengthen spec dir test to verify root `specs/` is not created
- Add PowerShell dry-run test class (5 tests, skipped without pwsh)
- Fix run_ps_script to use temp repo copy instead of project root

Assisted-By: 🤖 Claude Code

* fix: use git ls-remote for remote-aware dry-run numbering

Dry-run now queries remote branches via `git ls-remote --heads`
(read-only, no fetch) to account for remote-only branches when
computing the next sequential number. This prevents dry-run from
returning a number that already exists on a remote.

Added test verifying dry-run sees remote-only higher-numbered
branches and adjusts numbering accordingly.

Assisted-By: 🤖 Claude Code

* fix(scripts): deduplicate number extraction and branch scanning logic

Extract shared _extract_highest_number helper (bash) and
Get-HighestNumberFromNames (PowerShell) to eliminate duplicated
number extraction patterns between local branch and remote ref
scanning.

Add SkipFetch/skip_fetch parameter to check_existing_branches /
Get-NextBranchNumber so dry-run reuses the same function instead
of inlining duplicate max-of-branches-and-specs logic.

Assisted-By: 🤖 Claude Code

* fix(tests): use isolated paths for remote branch test

Move remote.git and second_clone directories under git_repo
instead of git_repo.parent to prevent path collisions with
parallel test workers.

Assisted-By: 🤖 Claude Code

* fix: address PR review feedback

- Set GIT_TERMINAL_PROMPT=0 for git ls-remote calls to prevent
  credential prompts from blocking dry-run in automation scenarios
- Add returncode assertion to test_dry_run_with_timestamp git
  branch --list check

Assisted-By: 🤖 Claude Code
2026-04-02 07:52:21 -05:00
Sakoda, Taro (cub)
8e14ab1935 fix: support feature branch numbers with 4+ digits (#2040)
* fix: support feature branch numbers with 4+ digits in common.sh and common.ps1

The sequential feature number pattern was hardcoded to exactly 3 digits
(`{3}`), causing branches like `1234-feature-name` to be rejected.
Changed to `{3,}` (3 or more digits) to support growing projects.
Also added a guard to exclude malformed timestamp patterns from being
accepted as sequential prefixes.

Closes #344

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: narrow timestamp guard and use [long] to prevent overflow

- Change [int] to [long] in PowerShell Get-CurrentBranch to avoid
  overflow for large feature numbers (>2,147,483,647)
- Narrow malformed-timestamp exclusion from ^[0-9]+-[0-9]{6}- to
  ^[0-9]{7}-[0-9]{6}- so valid sequential branches like
  004-123456-fix-bug are not rejected

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: add regression tests for 4+ digit feature branch support

Cover check_feature_branch and find_feature_dir_by_prefix with 4-digit
sequential prefixes, as requested in PR review #2040.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: reject timestamp-like branches without trailing slug

Branches like "20260319-143022" (no "-<name>" suffix) were incorrectly
accepted as sequential prefixes. Add explicit rejection for 7-or-8
digit date + 6-digit time patterns with no trailing slug, in both
common.sh and common.ps1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 07:44:26 -05:00
Manfred Riem
0945df9ec8 Add community content disclaimers (#2058)
* Add community content disclaimers

Add notes clarifying that community extensions, presets, walkthroughs,
and community friends are independently created and maintained by their
respective authors and are not reviewed, nor endorsed, nor supported
by GitHub.

Disclaimers added to:
- README.md: Community Extensions, Community Presets, Community
  Walkthroughs, and Community Friends sections
- extensions/README.md: Community Reference Catalog and Available
  Community Extensions sections
- presets/README.md: Catalog Management section

* Refine community disclaimers per PR review feedback

- Clarify that GitHub/maintainers may review catalog PRs for formatting
  and policy compliance, but do not review, audit, endorse, or support
  the extension/preset code itself (avoids contradiction with submission
  process that mentions PR reviews)
- Add missing 'use at your own discretion' guidance to Community
  Walkthroughs and Community Friends sections for consistency
2026-04-01 19:41:18 -05:00
Ismael
ea60efe2fa docs: add community extensions website link to README and extensions docs (#2014) 2026-04-01 16:26:25 -05:00
Manfred Riem
97b9f0f00d docs: remove dead Cognitive Squad and Understanding extension links and from extensions/catalog.community.json (#2057)
* docs: remove dead Cognitive Squad and Understanding extension links

Both repos (Testimonial/cognitive-squad and Testimonial/understanding)
have been deleted by their author. No forks or relocations exist.

* chore: remove dead extensions from community catalog

Remove cognitive-squad and understanding entries whose repos
have been deleted by their author.
2026-04-01 16:22:48 -05:00
Quratulain-bilal
4df6d963dc Add fix-findings extension to community catalog (#2039)
- Extension ID: fix-findings
- Version: 1.0.0
- Author: Quratulain-bilal
- Description: Automated analyze-fix-reanalyze loop that resolves spec findings until clean
- Addresses #2011

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 12:51:06 -05:00
Manfred Riem
682ffbfc0d Stage 4: TOML integrations — gemini and tabnine migrated to plugin architecture (#2050)
Add TomlIntegration base class in base.py that mirrors MarkdownIntegration:
- Overrides command_filename() for .toml extension
- Extracts description from YAML frontmatter for top-level TOML key
- Renders prompt body in TOML multiline basic strings with escaped backslashes
- Keeps full processed template (including frontmatter) as prompt body
- Byte-for-byte parity with v0.4.4 release ZIP output

Create integrations/gemini/ and integrations/tabnine/ subpackages:
- Config-only __init__.py subclassing TomlIntegration
- Integration-specific update-context scripts (sh + ps1)

Add TomlIntegrationTests mixin with TOML-specific validations:
- Valid TOML parsing, description/prompt keys, {{args}} placeholder
- Setup/teardown, manifest tracking, install/uninstall round-trips
- CLI auto-promote (--ai) and --integration flag tests
- Complete file inventory tests (sh + ps)

Register both in INTEGRATION_REGISTRY; --ai auto-promote works automatically.
2026-04-01 10:26:48 -05:00
Arun_18
b606b38512 feat: add 5 lifecycle extensions to community catalog (#2049)
* feat: add 5 gstack-inspired lifecycle commands (critique, review, qa, ship, retro)

Add 5 new core command templates inspired by Garry Tan's GStack to complete
the spec-driven development lifecycle:

- /speckit.critique: Dual-lens product + engineering review before implementation
- /speckit.review: Staff-level code review (correctness, security, performance)
- /speckit.qa: Systematic QA testing (browser-driven and CLI modes)
- /speckit.ship: Release automation (pre-flight, changelog, CI, PR creation)
- /speckit.retro: Sprint retrospective with metrics and improvement suggestions

Each command includes:
- Command template in templates/commands/
- Output report template in templates/
- Extension hook support (before_*/after_*)
- YAML frontmatter with prerequisite scripts

Updated README.md workflow from 6 to 11 steps and added CHANGELOG entry.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Revert "feat: add 5 gstack-inspired lifecycle commands (critique, review, qa, ship, retro)"

This reverts commit 6eb15a7a3e.

* feat: add 5 lifecycle extensions to community catalog

Add the following community extensions:
- staff-review: Staff-engineer-level code review
- qa: Systematic QA testing with browser/CLI validation
- ship: Release engineering automation
- retro: Sprint retrospective with metrics
- critique: Dual-lens spec and plan critique

Each extension is hosted in its own repository under arunt14/
with v1.0.0 releases available.

* fix: resolve mojibake encoding, sort keys, rename retro extension

- Fix double-encoded em dashes and arrows in catalog.community.json
- Sort extension entries alphabetically by key
- Rename 'Retrospective Extension' to 'Retro Extension' to avoid
  name collision with existing 'retrospective' extension

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-01 09:57:31 -05:00
Manfred Riem
255371d367 Stage 3: Standard markdown integrations — 19 agents migrated to plugin architecture (#2038)
* Stage 3: Standard markdown integrations — 19 agents migrated to plugin architecture

Migrate all standard markdown integrations to self-contained subpackages
under integrations/. Each subclasses MarkdownIntegration with config-only
overrides (~10 lines per __init__.py).

Integrations migrated (19):
claude, qwen, opencode, junie, kilocode, auggie, roo, codebuddy,
qodercli, amp, shai, bob, trae, pi, iflow, kiro-cli, windsurf,
vibe, cursor-agent

Changes:
- Create integrations/<key>/ subpackage with __init__.py and scripts/
  (update-context.sh, update-context.ps1) for each integration
- Register all 19 in INTEGRATION_REGISTRY (20 total with copilot)
- MarkdownIntegration.setup() processes templates (replaces {SCRIPT},
  {ARGS}, __AGENT__; strips frontmatter blocks; rewrites paths)
- Extract install_scripts() to IntegrationBase; refactor copilot to use it
- Generalize --ai auto-promote from copilot-only to registry-driven:
  any integration registered in INTEGRATION_REGISTRY auto-promotes.
  Unregistered agents (gemini, tabnine, codex, kimi, agy, generic)
  continue through the legacy --ai path unchanged.
- Fix cursor/cursor-agent key mismatch in CommandRegistrar.AGENT_CONFIGS
- Add missing vibe entry to CommandRegistrar.AGENT_CONFIGS
- Update kiro alias test to reflect auto-promote behavior

Testing:
- Per-agent test files (test_integration_<agent>.py) with shared mixin
- 1316 tests passing, 0 failures
- Complete file inventory tests for both sh and ps variants
- Byte-for-byte validated against v0.4.3 release packages (684 files)

* Address PR review: fix repo root detection and no-op test

- Fix repo root fallback in all 20 update-context.sh scripts: walk up
  from script location to find .specify/ instead of falling back to pwd
- Fix repo root fallback in all 20 update-context.ps1 scripts: walk up
  from script location to find .specify/ instead of falling back to $PWD
- Add assertions to test_setup_writes_to_correct_directory: verify
  expected_dir exists and all command files reside under it

* Fix REPO_ROOT priority: prefer .specify walk-up over git root

In monorepos the git toplevel may differ from the project root that
contains .specify/. The previous fix still preferred git rev-parse
over the walk-up result.

Bash scripts (20): prefer the discovered _root when it contains
.specify/; only accept git root if it also contains .specify/.

PowerShell scripts (20): validate git root contains .specify/ before
using it; fall back to walking up from script directory otherwise.

* Guard git call with try/catch in PowerShell scripts

With $ErrorActionPreference = 'Stop', an unguarded git rev-parse
throws a terminating CommandNotFoundException when git is not
installed, preventing the .specify walk-up fallback from running.

Wrap the git call in try/catch across all 20 update-context.ps1
scripts so the fallback works reliably without git.

* Rename hyphenated package dirs to valid Python identifiers

Rename kiro-cli → kiro_cli and cursor-agent → cursor_agent so the
packages can be imported with normal Python syntax instead of
importlib.  The user-facing integration key (IntegrationBase.key)
stays hyphenated to match the actual CLI tool / binary name.

Also reorganize _register_builtins(): imports and registrations
are now grouped alphabetically with clear section comments.

* Reuse CommandRegistrar path rewriting in process_template()

Replace the duplicated regex-based path rewriting in
MarkdownIntegration.process_template() with a call to the shared
CommandRegistrar._rewrite_project_relative_paths() implementation.

This ensures extension-local paths are preserved and boundary rules
stay consistent across the codebase.

* Promote _rewrite_project_relative_paths to public API

Rename CommandRegistrar._rewrite_project_relative_paths() to
rewrite_project_relative_paths() (drop leading underscore) so
integrations can call it without reaching into a private method
across subsystem boundaries.

Addresses PR review feedback:
https://github.com/github/spec-kit/pull/2038#discussion_r3022105627

* Broaden TestRegistrarKeyAlignment to cover all integration keys

Parametrize across ALL_INTEGRATION_KEYS instead of only checking
cursor-agent and vibe.  Keeps a separate negative test for the
stale 'cursor' shorthand.

Addresses PR review feedback:
https://github.com/github/spec-kit/pull/2038#discussion_r3022269032
2026-04-01 09:17:21 -05:00
Manfred Riem
3113b72d6f chore: release 0.4.4, begin 0.4.5.dev0 development (#2048)
* chore: bump version to 0.4.4

* chore: begin 0.4.5.dev0 development

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-01 08:58:36 -05:00
Manfred Riem
3899dcc0d4 Stage 2: Copilot integration — proof of concept with shared template primitives (#2035)
* feat: Stage 2a — CopilotIntegration with shared template primitives

- base.py: added granular primitives (shared_commands_dir,
  shared_templates_dir, list_command_templates, command_filename,
  commands_dest, copy_command_to_directory, record_file_in_manifest,
  write_file_and_record, process_template)
- CopilotIntegration: uses primitives to produce .agent.md commands,
  companion .prompt.md files, and .vscode/settings.json
- Verified byte-for-byte parity with old release script output
- Copilot auto-registered in INTEGRATION_REGISTRY
- 70 tests (22 new: base primitives + copilot integration)

Part of #1924

* feat: Stage 2b — --integration flag, routing, agent.json, shared infra

- Added --integration flag to init() (mutually exclusive with --ai)
- --ai copilot auto-promotes to integration path with migration nudge
- Integration setup writes .specify/agent.json with integration key
- _install_shared_infra() copies scripts and templates to .specify/
- init-options.json records 'integration' key when used
- 4 new CLI tests: mutual exclusivity, unknown rejection, copilot
  end-to-end, auto-promote (74 total integration tests)

Part of #1924

* feat: Stage 2 completion — integration scripts, integration.json, shared manifest

- Added copilot/scripts/update-context.sh and .ps1 (thin wrappers
  that delegate to the shared update-agent-context script)
- CopilotIntegration.setup() installs integration scripts to
  .specify/integrations/copilot/scripts/
- Renamed agent.json → integration.json with script paths
- _install_shared_infra() now tracks files in
  integration-shared.manifest.json
- Updated tests: scripts installed, integration.json has script paths,
  shared manifest recorded (74 tests)

Part of #1924

* refactor: rename shared manifest to speckit.manifest.json

Cleaner naming — the shared infrastructure (scripts, templates)
belongs to spec-kit itself, not to any specific integration.

* fix: copilot update-context scripts reflect target architecture

Scripts now source shared functions (via SPECKIT_SOURCE_ONLY=1) and
call update_agent_file directly with .github/copilot-instructions.md,
rather than delegating back to the shared case statement.

* fix: simplify copilot scripts — dispatcher sources common functions

Integration scripts now contain only copilot-specific logic (target
path + agent name). The dispatcher is responsible for sourcing shared
functions before calling the integration script.

* fix: copilot update-context scripts are self-contained implementations

These scripts ARE the implementation — the dispatcher calls them.
They source common.sh + update-agent-context functions, gather
feature/plan data, then call update_agent_file with the copilot
target path (.github/copilot-instructions.md).

* docs: add Stage 7 activation note to copilot update-context scripts

* test: add complete file inventory test for copilot integration

Validates every single file (37 total) produced by
specify init --integration copilot --script sh --no-git.

* test: add PowerShell file inventory test for copilot integration

Validates all 37 files produced by --script ps variant, including
.specify/scripts/powershell/ instead of bash.

* refactor: split test_integrations.py into tests/integrations/ directory

- test_base.py: IntegrationOption, IntegrationBase, MarkdownIntegration, primitives
- test_manifest.py: IntegrationManifest, path traversal, persistence, validation
- test_registry.py: INTEGRATION_REGISTRY
- test_copilot.py: CopilotIntegration unit tests
- test_cli.py: --integration flag, auto-promote, file inventories (sh + ps)
- conftest.py: shared StubIntegration helper

76 integration tests + 48 consistency tests = 124 total, all passing.

* refactor: move file inventory tests from test_cli to test_copilot

File inventories are copilot-specific. test_cli.py now only tests
CLI flag mechanics (mutual exclusivity, unknown rejection, auto-promote).

* fix: skip JSONC merge to preserve user settings, fix docstring

- _merge_vscode_settings() now returns early (skips merge) when
  existing settings.json can't be parsed (e.g. JSONC with comments),
  instead of overwriting with empty settings
- Updated _install_shared_infra() docstring to match implementation
  (scripts + templates, speckit.manifest.json)

* fix: warn user when JSONC settings merge is skipped

* fix: show template content when JSONC merge is skipped

User now sees the exact settings they should add manually.

* fix: document process_template requirement, merge scripts without rmtree

- base.py setup() docstring now explicitly states raw copy behavior
  and directs to CopilotIntegration for process_template example
- _install_shared_infra() uses merge/overwrite instead of rmtree to
  preserve user-added files under .specify/scripts/

* fix: don't overwrite pre-existing shared scripts or templates

Only write files that don't already exist — preserves any user
modifications to shared scripts (common.sh etc.) and templates.

* fix: warn user about skipped pre-existing shared files

Lists all shared scripts and templates that were not copied because
they already existed in the project.

* test: add test for shared infra skip behavior on pre-existing files

Verifies that _install_shared_infra() preserves user-modified scripts
and templates while still installing missing ones.

* fix: address review — containment check, deterministic prompts, manifest accuracy

- CopilotIntegration.setup() adds dest containment check (relative_to)
- Companion prompts generated from templates list, not directory glob
- _install_shared_infra() only records files actually copied (not pre-existing)
- VS Code settings tests made unconditional (assert template exists)
- Inventory tests use .as_posix() for cross-platform paths

* fix: correct PS1 function names, document SPECKIT_SOURCE_ONLY prerequisite

- Fixed Get-FeaturePaths → Get-FeaturePathsEnv, Read-PlanData → Parse-PlanData
- Documented that shared scripts must guard Main with SPECKIT_SOURCE_ONLY
  before these integration scripts can be activated (Stage 7)

* fix: add dict type check for settings merge, simplify PS1 to subprocess

- _merge_vscode_settings() skips merge with warning if parsed JSON
  is not a dict (array, null, etc.)
- PS1 update-context.ps1 uses & invocation instead of dot-sourcing
  since the shared script runs Main unconditionally

* fix: skip-write on no-op merge, bash subprocess, dynamic integration list

- _merge_vscode_settings() only writes when keys were actually added
- update-context.sh uses exec subprocess like PS1 version
- Unknown integration error lists available integrations dynamically

* fix: align path rewriting with release script, add .specify/.specify/ fix

Path rewrite regex matches the release script's rewrite_paths()
exactly (verified byte-identical output). Added .specify/.specify/
double-prefix fix for additional safety.
2026-03-31 17:40:32 -05:00
Quratulain-bilal
b8335a532c docs: sync AGENTS.md with AGENT_CONFIG for missing agents (#2025)
* docs: sync AGENTS.md with AGENT_CONFIG for missing agents

Add Antigravity (agy) and Mistral Vibe (vibe) to the supported agents
table — both exist in AGENT_CONFIG but were missing from documentation.

Fix Agent Categories section:
- Move Cursor from CLI-Based to IDE-Based (requires_cli is False)
- Add missing CLI agents: Codex, Auggie, iFlow
- Add missing IDE agents: Kilo Code, Roo Code, Trae, Antigravity

Update Command File Formats and Directory Conventions sections to
include all agents that were previously undocumented.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: address Copilot review feedback on AGENTS.md

- Fix Cursor table entry: CLI Tool → N/A (IDE-based), matches requires_cli=False in AGENT_CONFIG
- Fix Antigravity directory: .agent/commands/ → .agent/skills/ (skills-based per AGENT_SKILLS_MIGRATIONS)
- Add opencode singular command exception to Directory Conventions (.opencode/command/)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add --ai key hint for Cursor in AGENTS.md

Cursor's AGENT_CONFIG key is cursor-agent but the CLI Tool column
shows N/A (IDE-based). Adding the --ai flag reference in the
Description column so readers know the correct key to use with
specify init --ai cursor-agent.

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add --ai key hint for Antigravity in AGENTS.md

Antigravity's AGENT_CONFIG key is 'agy' and requires --ai-skills flag,
but the table only showed N/A (IDE-based). Adding the --ai flag reference
so readers know to use: specify init --ai agy --ai-skills

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: clarify Antigravity directory convention for both modes

AGENT_CONFIG generates .agent/commands/ by default, but --ai-skills
uses .agent/skills/. Document both paths in Directory Conventions.

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add Tabnine nested path exception to Directory Conventions

Tabnine uses .tabnine/agent/commands/ which has an extra path segment
compared to the usual .<agent-name>/commands/ convention.

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add Copilot to Markdown list, fix Antigravity dir convention

- Add GitHub Copilot to the Markdown format "Used by" list (it uses
  markdown with .agent.md extension and chat mode frontmatter)
- Clarify Antigravity uses .agent/skills/ (requires --ai-skills);
  .agent/commands/ is deprecated/legacy

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add missing IDE agents to Directory Conventions

Add Roo Code and IBM Bob to the IDE agents list in Directory
Conventions so all IDE-based agents are documented.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: document Codex --ai-skills requirement in all sections

Codex CLI requires --ai-skills when explicitly selected via
specify init --ai codex (exits with migration error otherwise).
Updated table, CLI-Based Agents list, and Directory Conventions.

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: fix Antigravity dir to match AGENT_CONFIG, add Amp shared folder

- Antigravity table row: .agent/skills/ → .agent/commands/ (matches
  AGENT_CONFIG folder + commands_subdir; skills mode via --ai-skills)
- Add shared .agents/ folder exception for Amp and Codex
- Move Codex from Skills-based to Shared folder section (it shares
  .agents/ with Amp)

Addresses Copilot review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: clarify Antigravity skills path is required, not optional

Reword to make clear .agent/skills/ is the effective path and
.agent/commands/ is deprecated, since CLI enforces --ai-skills.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 16:07:09 -05:00
Hamilton Snow
cb16412f88 docs: ensure manual tests use local specify (#2020)
* docs: ensure manual tests use local specify

* docs: mention venv activation before editable install

* docs: clarify Windows venv activation commands
2026-03-31 11:52:36 -05:00
Copilot
804cd10c71 Stage 1: Integration foundation — base classes, manifest system, and registry (#1925)
* feat: Stage 1 — integration foundation (base classes, manifest, registry)

Add the integrations package with:
- IntegrationBase ABC and MarkdownIntegration base class
- IntegrationOption dataclass for per-integration CLI options
- IntegrationManifest with SHA-256 hash-tracked install/uninstall
- INTEGRATION_REGISTRY (empty, populated in later stages)
- 34 tests at 98% coverage

Purely additive — no existing code modified.

Part of #1924

* fix: normalize manifest keys to POSIX, type manifest parameter

- Store manifest file keys using as_posix() after resolving relative
  to project root, ensuring cross-platform portable manifests
- Type the manifest parameter as IntegrationManifest (via TYPE_CHECKING
  import) instead of Any in IntegrationBase methods

* fix: symlink safety in uninstall/setup, handle invalid JSON in load

- uninstall() now uses non-resolved path for deletion so symlinks
  themselves are removed, not their targets; resolve only for
  containment validation
- setup() keeps unresolved dst_file for copy; resolves separately
  for project-root validation
- load() catches json.JSONDecodeError and re-raises as ValueError
  with the manifest path for clearer diagnostics
- Added test for invalid JSON manifest loading

* fix: lexical symlink containment, assert project_root consistency

- uninstall() now uses os.path.normpath for lexical containment check
  instead of resolve(), so in-project symlinks pointing outside are
  still properly removed
- setup() asserts manifest.project_root matches the passed project_root
  to prevent path mismatches between file operations and manifest
  recording

* fix: handle non-files in check_modified/uninstall, validate manifest key

- check_modified() treats non-regular-files (dirs, symlinks) as modified
  instead of crashing with IsADirectoryError
- uninstall() skips directories (adds to skipped list), only unlinks
  files and symlinks
- load() validates stored integration key matches the requested key

* fix: safe symlink handling in uninstall

- Broken symlinks now removable (lexists check via is_symlink fallback)
- Symlinks never hashed (avoids following to external targets)
- Symlinks only removed with force=True, otherwise skipped

* fix: robust unlink, fail-fast config validation, symlink tests

- uninstall() wraps path.unlink() in try/except OSError to avoid
  partial cleanup on race conditions or permission errors
- setup() raises ValueError on missing config or folder instead of
  silently returning empty
- Added 3 tests: symlink in check_modified, symlink skip/force in
  uninstall (47 total)

* fix: check_modified uses lexical containment, explicit is_symlink check

- check_modified() no longer calls _validate_rel_path (which resolves
  symlinks); uses lexical checks (is_absolute, '..' in parts) instead
- is_symlink() checked before is_file() so symlinks to files are still
  treated as modified
- Fixed templates_dir() docstring to match actual behavior

---------

Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com>
2026-03-31 10:37:00 -05:00
dagecko
4dff63a84e fix: harden GitHub Actions workflows (#2021) 2026-03-31 10:12:12 -05:00
Manfred Riem
40ecd44ada chore: use PEP 440 .dev0 versions on main after releases (#2032)
* chore: use PEP 440 .dev0 versions on main after releases

- Release-trigger workflow now adds a dev bump commit (X.Y.(Z+1).dev0)
  on the release branch after tagging, so main gets the dev version
  when the PR merges. The tag still points at the release commit.
- Set current pyproject.toml to 0.4.4.dev0.
- Replace broken release workflow badge with shields.io release badge.

* Update .github/workflows/release-trigger.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-31 09:51:47 -05:00
Hamilton Snow
b19a7eedfa feat: add superpowers bridge extension to community catalog (#2023)
* docs: correct specify extension add syntax to require extension name

The specify extension add command requires the extension name as a positional argument. Many documentation files incorrectly demonstrated using the --from flag without specifying the extension name first.

* feat: add superb extension to community catalog

Orchestrates obra/superpowers skills within the spec-kit SDD workflow.

* fix: link superb extension docs
2026-03-31 06:25:11 -05:00
Valentin
9cb3f3d1ad feat: add product-forge extension to community catalog (#2012)
Product Forge — Full product lifecycle SpecKit extension by VaiYav.
Covers 9 phases: research → product-spec → revalidation → bridge →
plan → implement → verify → test-plan → test-run.

10 commands, MIT license, v1.1.0
https://github.com/VaiYav/speckit-product-forge

Co-authored-by: Valentyn Yakovliev <your-verified-email@example.com>
2026-03-30 11:42:23 -05:00
Roland Huß
f8da535d71 feat(scripts): add --allow-existing-branch flag to create-new-feature (#1999)
* feat(scripts): add --allow-existing-branch flag to create-new-feature

Add an --allow-existing-branch / -AllowExistingBranch flag to both
bash and PowerShell create-new-feature scripts. When the target branch
already exists, the script switches to it instead of failing. The spec
directory and template are still created if missing, but existing
spec.md files are not overwritten (prevents data loss on re-runs).

The flag is opt-in, so existing behavior is completely unchanged
without it. This enables worktree-based workflows and CI/CD pipelines
that create branches externally before running speckit.specify.

Relates to #1931. Also addresses #1680, #841, #1921.

Assisted-By: 🤖 Claude Code

* fix: address PR review feedback for allow-existing-branch

- Make checkout failure fatal instead of suppressing with || true (bash)
- Check $LASTEXITCODE after git checkout in PowerShell
- Use Test-Path -PathType Leaf for spec file existence check (PS)
- Add PowerShell static assertion test for -AllowExistingBranch flag

Assisted-By: 🤖 Claude Code
2026-03-27 14:04:14 -05:00
Alexander Rampp
edaa5a7ff1 fix(scripts): add correct path for copilot-instructions.md (#1997) 2026-03-27 11:43:57 -05:00
PChemGuy
5be705e414 Update README.md (#1995)
Thank you!
2026-03-27 11:14:11 -05:00
Andrii Furmanets
796b4f47c4 fix: prevent extension command shadowing (#1994)
* fix: prevent extension command shadowing

* Validate extension command namespaces

* Reuse extension command name pattern
2026-03-27 10:55:26 -05:00
Kash
6b1f45c50c Fix Claude Code CLI detection for npm-local installs (#1978)
* Fix Claude Code CLI detection for npm-local installs

`specify check` reports "Claude Code CLI (not found)" for users who
installed Claude Code via npm-local (the default installer path, common
with nvm). The binary lives at ~/.claude/local/node_modules/.bin/claude
which was not checked. Add CLAUDE_NPM_LOCAL_PATH as a second well-known
location alongside the existing migrate-installer path.

Fixes https://github.com/github/spec-kit/issues/550

* Address Copilot review feedback

- Remove unused pytest import from test_check_tool.py
- Use tmp_path instead of hardcoded /nonexistent/claude for hermetic tests
- Simplify redundant exists() + is_file() to just is_file()

AI-assisted: Changes applied with Claude Code.

* Update tests/test_check_tool.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/test_check_tool.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-27 10:50:43 -05:00
AK
8778c26dcf fix(scripts): honor PowerShell agent and script filters (#1969)
Rename the Normalize-List parameter in create-release-packages.ps1 to avoid conflicting with PowerShell's automatic $input variable. This fixes Windows offline scaffolding when -Agents and -Scripts are passed.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-27 10:48:11 -05:00
Daniel Badde
41d1f4b0ac feat: add MAQA extension suite (7 extensions) to community catalog (#1981)
* feat: add MAQA extension suite to community catalog and README

Adds 7 extensions forming the MAQA (Multi-Agent & Quality Assurance)
suite to catalog.community.json in correct alphabetical order (after
'learn', before 'onboard') and to the README community extensions table:

- maqa           — coordinator/feature/QA workflow, board auto-detection
- maqa-azure-devops — Azure DevOps Boards integration
- maqa-ci           — CI/CD gate (GitHub Actions/CircleCI/GitLab/Bitbucket)
- maqa-github-projects — GitHub Projects v2 integration
- maqa-jira         — Jira integration
- maqa-linear       — Linear integration
- maqa-trello       — Trello integration

All entries placed alphabetically. maqa v0.1.3 bumped to reflect
multi-board auto-detection added in this release.

* fix: set catalog updated_at to match latest entry timestamp

Top-level updated_at was 00:00:00Z while plan-review-gate entries
had 08:22:30Z, making metadata inconsistent for freshness consumers.
Updated to 2026-03-27T08:22:30Z (>= all entry timestamps).
2026-03-27 10:45:19 -05:00
Rafael Sales
9c2481fd67 feat: add spec-kit-onboard extension to community catalog (#1991)
Adds the onboard extension (v2.1.0) — contextual onboarding and
progressive growth for developers new to spec-kit projects.

- 7 commands: start, explain, trail, quiz, badge, mentor, team
- 3 hooks: after-implement, before-implement, after-explain
- Repository: https://github.com/dmux/spec-kit-onboard
2026-03-27 09:58:43 -05:00
Ed Harrod
8520241dfe Add plan-review-gate to community catalog (#1993)
- Extension ID: plan-review-gate
- Version: 1.0.0
- Author: luno
- Catalog entries sorted alphabetically by ID
- README table row inserted alphabetically by name

Co-authored-by: Ed Harrod <your-real-email@luno.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 08:23:01 -05:00
dependabot[bot]
362868a342 chore(deps): bump actions/deploy-pages from 4 to 5 (#1990)
Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 08:03:34 -05:00
dependabot[bot]
d7206126e0 chore(deps): bump DavidAnson/markdownlint-cli2-action from 19 to 23 (#1989)
Bumps [DavidAnson/markdownlint-cli2-action](https://github.com/davidanson/markdownlint-cli2-action) from 19 to 23.
- [Release notes](https://github.com/davidanson/markdownlint-cli2-action/releases)
- [Commits](https://github.com/davidanson/markdownlint-cli2-action/compare/v19...v23)

---
updated-dependencies:
- dependency-name: DavidAnson/markdownlint-cli2-action
  dependency-version: '23'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 08:02:40 -05:00
Manfred Riem
b22f381c0d chore: bump version to 0.4.3 (#1986)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-26 16:04:09 -05:00
Hamilton Snow
ccc44dd00a Unify Kimi/Codex skill naming and migrate legacy dotted Kimi dirs (#1971)
* fix: unify hyphenated skills and migrate legacy kimi dotted dirs

* fix: preserve legacy kimi dotted preset skill overrides

* fix: migrate kimi legacy dotted skills without ai-skills flag

* fix: harden kimi migration and cache hook init options

* fix: apply kimi preset skill overrides without ai-skills flag

* fix: keep sequential branch numbering beyond 999

* test: align kimi scaffold skill path with hyphen naming

* chore: align hook typing and preset skill comment

* fix: restore AGENT_SKILLS_DIR_OVERRIDES compatibility export

* refactor: remove AGENT_SKILLS_DIR_OVERRIDES and update callers

* fix(ps1): support sequential branch numbers above 999

* fix: resolve preset skill placeholders for skills agents

* Fix legacy kimi migration safety and preset skill dir checks

* Harden TOML rendering and consolidate preset skill restore parsing

* Fix PowerShell overflow and hook message fallback for empty invocations

* Restore preset skills from extensions

* Refine preset skill restore helpers

* Harden skill path and preset checks

* Guard non-dict init options

* Avoid deleting unmanaged preset skill dirs

* Unify extension skill naming with hooks

* Harden extension native skill registration

* Normalize preset skill titles
2026-03-26 10:53:30 -05:00
Manfred Riem
2c2fea8783 fix(ps1): replace null-conditional operator for PowerShell 5.1 compatibility (#1975)
The `?.` (null-conditional member access) operator requires PowerShell 7.1+,
but Windows ships with PowerShell 5.1 by default. When AI agents invoke .ps1
scripts on Windows, they typically use the system-associated handler (5.1),
causing a ParseException: Unexpected token '?.Path'.

Replace the single `?.` usage with a 5.1-compatible two-step pattern that
preserves the same null-safety behavior.

Fixes #1972
2026-03-25 12:54:49 -05:00
Manfred Riem
4b4bd735a3 chore: bump version to 0.4.2 (#1973)
* chore: bump version to 0.4.2

* chore: clean up CHANGELOG and fix release workflow

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-25 12:28:29 -05:00
Dhilip
36019ebf1b feat: Auto-register ai-skills for extensions whenever applicable (#1840)
* feat: Auto-register ai-skills for extensions whenever applicable

* fix: failing test

* fix: address copilot review comments – path traversal guard and use short_name in title

* fix: address remaining copilot review comments – is_file guard, skills type-validation, and exact extension ownership check on fallback rmtree

* fix: address copilot round-3 comments – align skill naming with presets.py convention, safe rmdir on fail, require SKILL.md for fallback rmtree, normalize skill_count in CLI

* fix: is_dir() guard in fast-path rmtree and fix ghost-skill assertion naming

* fix: path-traversal guard on skill_name in both rmtree paths of _unregister_extension_skills

* fix: add SKILL.md ownership check to fast-path rmtree and alias shadowed _get_skills_dir import
2026-03-25 07:48:36 -05:00
Manfred Riem
fb152eb824 docs: add manual testing guide for slash command validation (#1955)
* docs: add manual testing guide for slash command validation

Adds a top-level TESTING.md that describes the manual test process PR
submitters must follow when their changes affect slash commands.

Includes:
- Process overview (identify affected commands, setup, run, report)
- Local setup instructions using editable install
- Reporting template for PR submissions
- Agent prompt that analyzes changed files and determines which
  commands need testing, including transitive script dependencies
  and extension hook mappings

* Update TESTING.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update TESTING.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-24 14:22:36 -05:00
Manfred Riem
00e5dc1f91 Add AIDE, Extensify, and Presetify to community extensions (#1961)
* Add AIDE, Extensify, and Presetify to community extensions

Add three extensions from the mnriem/spec-kit-extensions repository:

- AI-Driven Engineering (AIDE): structured 7-step workflow for building
  new projects from scratch with AI assistants
- Extensify: create and validate extensions and extension catalogs
- Presetify: create and validate presets and preset catalogs

Updates both the README community extensions table and
catalog.community.json with entries in alphabetical order.

* fix(tests): isolate preset search test from community catalog growth

Mock get_active_catalogs to return only the default catalog entry so
the test uses only its own cached data and won't break as the
community preset catalog grows.
2026-03-24 13:18:30 -05:00
Manfred Riem
eeda669c19 docs: add community presets section to main README (#1960)
- Add 🎨 Community Presets section between Community Extensions and Community Walkthroughs
- Add ToC entry for the new section
- Populate presets/catalog.community.json with pirate and aide-in-place presets
- Entries alphabetized: catalog by id, README table by name
2026-03-24 12:56:36 -05:00
Manfred Riem
ebc61067e8 docs: move community extensions table to main README for discoverability (#1959)
- Add 🧩 Community Extensions section to README.md before Community Walkthroughs
- Add table of contents entry for the new section
- Replace extensions/README.md table with a link back to the main README
- Update EXTENSION-PUBLISHING-GUIDE.md references to point to README.md
- Update EXTENSION-DEVELOPMENT-GUIDE.md references to point to README.md
2026-03-24 12:34:32 -05:00
Manfred Riem
2c2936022c docs(readme): consolidate Community Friends sections and fix ToC anchors (#1958)
* docs(readme): consolidate Community Friends sections and fix ToC anchors

- Merge duplicate 🤝 Community Friends section (table format near bottom) into
  the existing 🛠️ Community Friends section (bullet list)
- Add cc-sdd entry alongside Spec Kit Assistant
- Update intro text to 'Community projects that extend, visualize, or build on Spec Kit'
- Fix ToC anchors for Video Overview and Community Friends (remove variation selector from fragment)

* docs(readme): remove stale ToC entry for deleted Community Friends section
2026-03-24 12:05:43 -05:00
Ismael
816c1160e9 fix(commands): rename NFR references to success criteria in analyze and clarify (#1935)
* fix(commands): rename NFR references to success criteria in analyze and clarify

* fix(analyze): align Success Criteria description and inventory keys with spec template

- Reword "non-functional targets" to "measurable outcomes" to match the spec template's broader scope (performance, user success, business impact)
- Use explicit FR-/SC- identifiers as primary stable keys in the requirements inventory instead of derived slugs alone
2026-03-24 11:37:54 -05:00
Roland Huß
bc766c3101 Add Community Friends section to README (#1956)
* Add Community Friends section with cc-sdd

Adds a new "Community Friends" section to the README for projects that
extend or build on Spec Kit. Starts with cc-sdd, a Claude Code plugin
that layers composable traits (quality gates, worktree isolation, agent
teams) on top of Spec Kit's core workflow.

Suggested by @mnriem in discussion #1889.

Assisted-By: 🤖 Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update cc-sdd repo URL after rename

Assisted-By: 🤖 Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Mention Superpowers explicitly in cc-sdd description

Assisted-By: 🤖 Claude Code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:36:47 -05:00
Rafael Sales
f132f748e3 docs: add Community Friends section with Spec Kit Assistant VS Code extension (#1944)
* docs: add Community Tools section to README.md

* Update README.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* docs: rename "Community Tools" section to "Community Friends" in README.md

* docs: rename "Community Tools" section to "Community Friends" in README.md

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-24 11:17:51 -05:00
Manfred Riem
ee65758e2b chore: bump version to 0.4.1 (#1953)
* chore: bump version to 0.4.1

* fix(changelog): correct 0.4.1 section ordering and version reference (#1954)

* Initial plan

* fix(changelog): correct 0.4.1 section ordering and version reference

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/spec-kit/sessions/98bc10bc-f444-4833-bd3a-ab8ea0f5e192

---------

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>
2026-03-24 10:53:19 -05:00
Aaron Sun
a01180955d Add checkpoint extension (#1947)
Co-authored-by: Aaron Sun <aaronsun@mac.lan>
2026-03-24 08:59:43 -05:00
Michal Bachorik
b1ba972978 fix(scripts): prioritize .specify over git for repo root detection (#1933)
* fix(scripts): prioritize .specify over git for repo root detection

When spec-kit is initialized in a subdirectory that doesn't have its
own .git, but a parent directory does, spec-kit was incorrectly using
the parent's git repository root. This caused specs to be created in
the wrong location.

The fix changes repo root detection to prioritize .specify directory
over git rev-parse, ensuring spec-kit respects its own initialization
boundary rather than inheriting a parent git repo.

Fixes #1932

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address code review feedback

- Normalize paths in find_specify_root to prevent infinite loop with relative paths
- Use -PathType Container in PowerShell to only match .specify directories
- Improve has_git/Test-HasGit to check git command availability and validate work tree
- Handle git worktrees/submodules where .git can be a file
- Remove dead fallback code in create-new-feature scripts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: check .specify before termination in find_specify_root

Fixes edge case where project root is at filesystem root (common in
containers). The loop now checks for .specify before checking the
termination condition.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: scope git operations to spec-kit root & remove unused helpers

- get_current_branch now uses has_git check and runs git with -C to
  prevent using parent git repo branch names in .specify-only projects
- Same fix applied to PowerShell Get-CurrentBranch
- Removed unused find_repo_root() from create-new-feature.sh
- Removed unused Find-RepositoryRoot from create-new-feature.ps1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use cd -- to handle paths starting with dash

Prevents cd from interpreting directory names like -P or -L as options.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: check git command exists before calling get_repo_root in has_git

Avoids unnecessary work when git isn't installed since get_repo_root
may internally call git rev-parse.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(powershell): use LiteralPath and check git before Get-RepoRoot

- Use -LiteralPath in Find-SpecifyRoot to handle paths with wildcard
  characters ([, ], *, ?)
- Check Get-Command git before calling Get-RepoRoot in Test-HasGit to
  avoid unnecessary work when git isn't installed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(powershell): use LiteralPath for .git check in Test-HasGit

Prevents Test-Path from treating wildcard characters in paths as globs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(powershell): use LiteralPath in Get-RepoRoot fallback

Prevents Resolve-Path from treating wildcard characters as patterns.

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>
2026-03-24 08:55:21 -05:00