mirror of
https://github.com/github/spec-kit
synced 2026-06-21 13:51:39 +00:00
b78a3cdd88f3e43061f7e26800fe81dc5ac833bf
789 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b78a3cdd88 |
docs: merge TESTING.md into CONTRIBUTING.md, remove TESTING.md (#2228)
* docs: merge TESTING.md into CONTRIBUTING.md, remove TESTING.md Merge relevant testing content (automated checks, manual testing process, reporting template, test-selection prompt) into CONTRIBUTING.md. Remove obsolete content referencing deleted zip bundles and the non-existent test_core_pack_scaffold.py file. Update DEVELOPMENT.md to remove the TESTING.md entry. Closes #2226 * docs: address review — narrow automated checks intro, use cross-platform temp path |
||
|
|
2f5417f0ad |
Add agent-assign extension to community catalog (#2030)
* Add agent-assign extension to community catalog * Fix author name to xuyang in catalog entry * Update extensions/catalog.community.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update updated_at date in catalog.community.json * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: xuyang <xuyangxy@rd.netease.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
33a28ec8f7 |
fix: unofficial PyPI warning (#1982) and legacy extension command name auto-correction (#2017) (#2027)
* docs: warn about unofficial PyPI packages and recommend version verification (#1982)
Clarify that only packages from github/spec-kit are official, and add
`specify version` as a post-install verification step to help users
catch accidental installation of an unrelated package with the same name.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): auto-correct legacy command names instead of hard-failing (#2017)
Community extensions that predate the strict naming requirement use two
common legacy formats ('speckit.command' and 'extension.command').
Instead of rejecting them outright, auto-correct to the required
'speckit.{extension}.{command}' pattern and emit a compatibility warning
so authors know they need to update their manifest. Names that cannot be
safely corrected (e.g. single-segment names) still raise ValidationError.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(tests): isolate preset catalog search test from community catalog network calls
test_search_with_cached_data asserted exactly 2 results but was getting 4
because _get_merged_packs() queries the full built-in catalog stack
(default + community). The community catalog had no local cache and hit
the network, returning real presets. Writing a project-level
preset-catalogs.yml that pins the test to the default URL only makes
the count assertions deterministic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): extend auto-correction to aliases (#2017)
The upstream #1994 added alias validation in _collect_manifest_command_names,
which also rejected legacy 2-part alias names (e.g. 'speckit.verify').
Extend the same auto-correction logic from _validate() to cover aliases,
so both 'speckit.command' and 'extension.command' alias formats are
corrected to 'speckit.{ext_id}.{command}' with a compatibility warning
instead of hard-failing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): address PR review feedback (#2017)
- _try_correct_command_name: only correct 'X.Y' to 'speckit.ext_id.Y'
when X matches ext_id, preventing misleading warnings followed by
install failure due to namespace mismatch
- _validate: add aliases type/string guards matching _collect_manifest
_command_names defensive checks
- _validate: track command renames and rewrite any hook.*.command
references that pointed at a renamed command, emitting a warning
- test: fix test_command_name_autocorrect_no_speckit_prefix to use
ext_id matching the legacy namespace; add namespace-mismatch test
- test: replace redundant preset-catalogs.yml isolation with
monkeypatch.delenv("SPECKIT_PRESET_CATALOG_URL") so the env var
cannot bypass catalog restriction in CI environments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update docs/installation.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(extensions): warn when hook command refs are silently canonicalized; fix grammar
- Hook rewrites (alias-form or rename-map) now always emit a warning so
extension authors know to update their manifests. Previously only
rename-map rewrites produced a warning; pure alias-form lifts were
silent.
- Pluralize "command/commands" in the uninstall confirmation message so
single-command extensions no longer print "1 commands".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): raise ValidationError for non-dict hook entries
Silently skipping non-dict hook entries left them in manifest.hooks,
causing HookExecutor.register_hooks() to crash with AttributeError
when it called hook_config.get() on a non-mapping value.
Also updates PR description to accurately reflect the implementation
(no separate _try_correct_alias_name helper; aliases use the same
_try_correct_command_name path).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): derive remove cmd_count from registry, fix wording
Previously cmd_count used len(ext_manifest.commands) which only counted
primary commands and missed aliases. The registry's registered_commands
already tracks every command name (primaries + aliases) per agent, so
max(len(v) for v in registered_commands.values()) gives the correct
total.
Also changes "from AI agent" → "across AI agents" since remove()
unregisters commands from all detected agents.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): distinguish missing vs empty registered_commands in remove prompt
Using get() without a default lets us tell apart:
- key missing (legacy registry entry) → fall back to manifest count
- key present but empty dict (installed with no agent dirs) → show 0
Previously the truthiness check `if registered_commands and ...` treated
both cases the same, so an empty dict fell back to len(manifest.commands)
and overcounted commands that would actually be removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): clarify removal prompt wording to 'per agent'
'across AI agents' implied a total count, but cmd_count uses max()
across agents (per-agent count). Using sum() would double-count since
users think in logical commands, not per-agent files. 'per agent'
accurately describes what the number represents.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): clarify cmd_count comment — per-agent max, not total
The comment said 'covers all agents' implying a total, but cmd_count uses
max() across agents (per-agent count). Updated comment to explain the
max() choice and why sum() would double-count.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(extensions): add CLI tests for remove confirmation pluralization
Adds TestExtensionRemoveCLI with two CliRunner tests:
- singular: 1 registered command → '1 command per agent'
- plural: 2 registered commands → '2 commands per agent'
These prevent regressions on the cmd_count pluralization logic
and the 'per agent' wording introduced in this PR.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(agents): remove orphaned SKILL.md parent dirs on unregister
For SKILL.md-based agents (codex, kimi), each command lives in its own
subdirectory (e.g. .agents/skills/speckit-ext-cmd/SKILL.md). The previous
unregister_commands() only unlinked the file, leaving an empty parent dir.
Now attempts rmdir() on the parent when it differs from the agent commands
dir. OSError is silenced so non-empty dirs (e.g. user files) are safely left.
Adds test_unregister_skill_removes_parent_directory to cover this.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(extensions): drop alias pattern enforcement from _validate()
Aliases are intentionally free-form to preserve community extension
compatibility (e.g. 'speckit.verify' short aliases used by spec-kit-verify
and other existing extensions). This aligns _validate() with the intent of
upstream commit
|
||
|
|
f0886bd089 |
feat: register architect-preview in community catalog (#2214)
* Add Architect Impact Previewer to catalog Added a new architect impact previewer with metadata. * Fix description formatting in architect-preview * Add Architect Impact Previewer extension details * Update catalog.community.json * Add Architect Impact Previewer extension details Added 'Architect Impact Previewer' extension with details including name, description, author, version, and URLs. * Add Architect Impact Previewer extension to README |
||
|
|
39c7b04e5e |
chore: deprecate --ai flag in favor of --integration on specify init (#2218)
* chore: deprecate --ai flag in favor of --integration on specify init - Adds deprecation warning when --ai is used - Shows equivalent --integration command replacement - Handles generic integration with --commands-dir mapping - Adds comprehensive test coverage for deprecation behavior - Warning displays as prominent red panel above Next Steps - --ai flag continues to function (non-breaking change) Fixes #2169 * Address PR review feedback for issue #2169 - Use existing strip_ansi helper from conftest instead of duplicating ANSI escape pattern - Properly escape ai_commands_dir with shlex.quote() to handle paths with spaces - Add shlex import to support proper command-line argument escaping |
||
|
|
3467d26b1c |
chore: release 0.7.0, begin 0.7.1.dev0 development (#2217)
* chore: bump version to 0.7.0 * chore: begin 0.7.1.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
a00e679918 |
Add workflow engine with catalog system (#2158)
* Initial plan * Add workflow engine with step registry, expression engine, catalog system, and CLI commands Agent-Logs-Url: https://github.com/github/spec-kit/sessions/72a7bb5d-071f-4d67-a507-7e1abae2384d Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Add comprehensive tests for workflow engine (94 tests) Agent-Logs-Url: https://github.com/github/spec-kit/sessions/72a7bb5d-071f-4d67-a507-7e1abae2384d Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Address review feedback: do-while condition preservation and URL scheme validation Agent-Logs-Url: https://github.com/github/spec-kit/sessions/72a7bb5d-071f-4d67-a507-7e1abae2384d Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Address review feedback, add CLI dispatch, interactive gates, and docs Review comments (7/7): - Add explanatory comment to empty except block - Implement workflow catalog download with cleanup on failure - Add input type coercion for number/boolean/enum - Fix example workflow to remove non-existent output references - Fix while_loop and if_then condition defaults (string 'false' → bool False) - Fix resume step index tracking with step_offset parameter CLI dispatch: - Add build_exec_args() and dispatch_command() to IntegrationBase - Override for Claude (skills: /speckit-specify), Gemini (-m flag), Codex (codex exec), Copilot (--agent speckit.specify) - CommandStep invokes installed commands by name via integration CLI - Add PromptStep for arbitrary inline prompts (10th step type) - Stream CLI output live to terminal (no silent blocking) - Remove timeout when streaming (user can Ctrl+C) - Ctrl+C saves state as PAUSED for clean resume Interactive gates: - Gate steps prompt [1] approve [2] reject in TTY - Fall back to PAUSED in non-interactive environments - Resume re-executes the gate for interactive prompting Documentation: - workflows/README.md — user guide - workflows/ARCHITECTURE.md — internals with Mermaid diagrams - workflows/PUBLISHING.md — catalog submission guide Tests: 94 → 122 workflow tests, 1362 total (all passing) * Fix ruff lint errors: unused imports, f-string placeholders, undefined name * Address second review: registry-backed validation, shell failures, loop/fan-out execution, URL validation - VALID_STEP_TYPES now queries STEP_REGISTRY dynamically - Shell step returns FAILED on non-zero exit code - Persist workflow YAML in run directory for reliable resume - Resume loads from run copy, falls back to installed workflow - Engine iterates while/do-while loops up to max_iterations - Engine expands fan-out per item with context.item - HTTPS URL validation for catalog workflow installs (HTTP allowed for localhost) - Fix catalog merge priority docstring (lower number wins) - Fix dispatch_command docstring (no build_exec_args_for_command) - Gate on_reject=retry pauses for re-prompt on resume - Update docs to 10 step types, add prompt step to tables and README * Potential fix for pull request finding 'Empty except' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * Address third review: fan-out IDs, catalog guards, shell coercion, docs - Fan-out generates unique per-item step IDs and collects results - Catalog merge skips non-dict workflow entries (malformed data guard) - Shell step coerces run_cmd to str after expression evaluation - urlopen timeout=30 for catalog workflow installs - yaml.dump with sort_keys=False, allow_unicode=True for catalog configs - Document streaming timeout as intentionally unbounded (user Ctrl+C) - Document --allow-all-tools as required for non-interactive + future enhancement - Update test docstring and PUBLISHING.md to 10 step types with prompt * Validate final URL after redirects in catalog fetch urlopen follows redirects, so validate the response URL against the same HTTPS/localhost rules to prevent redirect-based downgrade attacks. * Address fourth review: filter arg eval, tags normalization, install redirect check - Filter arguments now evaluated via _evaluate_simple_expression() so default(42) returns int not string - Tags normalized: non-list/non-string values handled gracefully - Install URL redirect validation (same as catalog fetch) - Remove unused 'skipped' variable in catalog config parsing - Author 'github' → 'GitHub' in example workflow - Document nested step resume limitation (re-runs parent step) * Add explanatory comment to empty except ValueError block * Address fifth review: expression parsing, fan-out output, URL install, gate options - Move string literal parsing before operator detection in expressions so quoted strings with operators (e.g. 'a in b') are not mis-parsed - Fan-out: remove max_concurrency from persisted output, fix docstring to reflect sequential execution - workflow add: support URL sources with HTTPS/redirect validation, validate workflow ID is non-empty before writing files - Deduplicate local install logic via _validate_and_install_local() - Remove 'edit' gate option from speckit workflow (not implemented) * Add comments to empty except ValueError blocks in URL install * Address sixth review: operator precedence, fan_in cleanup, registry resilience, docs - Fix or/and operator precedence (or parsed first = lower precedence) - Restore context.fan_in after fan-in step completes - Catch JSONDecodeError in registry load for corrupted files - Replace print() with on_step_start callback (library-safe) - Gate validation warns when on_reject set but no reject option - Shell step: document shell=True security tradeoff - README: sdd-pipeline → speckit, parallel → sequential for fan-out - ARCHITECTURE.md: parallel → fan-out/fan-in in diagram * Address seventh review: string literal before pipe, type annotations, validate on install - Move string literal check above pipe filter parsing so 'a | b' works - Fix type annotations: input_values list[str] | None, run_id str | None - Run validate_workflow() before installing from local path/URL - Remove duplicate string literal check from expression parser * Address eighth review: fan-out namespaced IDs, early return, catalog validation - Fan-out per-item step IDs use _fanout_{step_id}_{base}_{idx} namespace to avoid collisions with user-defined step IDs - Early return after fan-out loop when state is paused/failed/aborted - Catalog installs parse + validate downloaded YAML before registering, using definition metadata instead of catalog entry for registry * Address ninth review: populate catalog, fix indentation, priority, README - Add speckit workflow entry to catalog.json so it's discoverable - Fix shell step output dict indentation - Catalog add_catalog priority derived from max existing + 1 - README Quick Start clarified with install + local file examples * Address tenth review: max_iterations validation, catalog config guard, version alignment - Validate max_iterations is int >= 1 in while and do-while steps - Guard add_catalog against corrupted config (non-dict/non-list) - Align speckit_version requirement to >=0.6.1 (current package version) - Fan-out template validation uses separate seen_ids set to avoid false duplication errors with user-defined step IDs * Address eleventh review: command step fails without CLI, ID mismatch warning, state persistence - Command step returns FAILED when CLI not installed (was silent COMPLETED) - Catalog install warns on workflow ID vs catalog key mismatch - Engine persists state.save() before returning on unknown step type - Update tests to expect FAILED for command steps without CLI - Integration tests use shell steps for CLI-independent execution * Address twelfth review: type annotations, version examples, streaming docs, requires - Fix workflow_search type annotations (str | None) - PUBLISHING.md: speckit_version >=0.15.0 → >=0.6.1 - Document that exit_code is captured and referenceable by later steps - Mark requires as declared-but-not-enforced (planned enhancement) - Note full stdout/stderr capture as planned enhancement * Enforce catalog key matches workflow ID (fail instead of warn) * Bundle speckit workflow: auto-install during specify init - Add workflows/speckit to pyproject.toml force-include for wheel builds - Add _locate_bundled_workflow() helper (mirrors _locate_bundled_extension) - Auto-install speckit workflow during specify init (after git extension) - Update all integration file inventory tests to expect workflow files * Address fourteenth review: prompt fails without CLI, resolved step data, fan-out normalization - PromptStep returns FAILED when CLI not installed (was silent COMPLETED) - Engine step_data prefers resolved values from step output - Fan-out normalizes output.results=[] for empty item lists - subprocess.run inherits stdout/stderr (no explicit sys.stdout) - Registry tests use issubset for extensibility * Address fifteenth review: fan_in docstring, gate defaults, validation guards, reserved prefix - FanInStep docstring: aggregate-only, no blocking semantics - FanInStep: guard output_config as dict, handle None - Gate validate: use same default options as execute - Validate inputs is dict and steps is list before iterating - Reserve _fanout_ prefix in step ID validation - PUBLISHING.md: remove unenforced checklist items, add _fanout_ note * Address sixteenth review: docs regex, fan_in try/finally, hyphenated dot-path keys - PUBLISHING.md: update ID regex docs to match implementation (single-char OK) - FanInStep: wrap expression evaluation in try/finally for context.fan_in - Expression dot-path: allow hyphens in keys before list index (e.g. run-tests[0]) * Make speckit workflow integration-agnostic, document Copilot CLI requirement - Workflow integration selectable via input (default: claude) - Each command step uses {{ inputs.integration }} instead of hardcoded copilot - Copilot docstring documents CLI requirement for workflow dispatch - Added install_url for Copilot CLI docs * Address seventeenth review: project checks, catalog robustness - Add .specify/ project check to workflow run/resume/status/search/info - remove_catalog validates config shape (dict + list) before indexing - _fetch_single_catalog validates response is a dict - _get_merged_workflows raises when all catalogs fail to fetch - add_catalog guards against non-dict catalog entries in config * Address eighteenth review: condition coercion, gate abort result, while default, cache guard, resume log - evaluate_condition treats plain 'false'/'true' strings as booleans - Gate abort returns StepResult(FAILED) instead of raising exception so step output is persisted in state for inspection - while_loop max_iterations optional (default 10), validation aligned - Catalog cache fallback catches invalid JSON gracefully - resume() appends workflow_finished log entry like execute() * Address nineteenth review: allow-all-tools opt-in, empty catalogs, abort dead code, while docstring - --allow-all-tools controlled by SPECKIT_ALLOW_ALL_TOOLS env var (default: 1) Set to 0 to disable automatic tool approval for Copilot CLI - Empty catalogs list falls back to built-in defaults (not an error) - Remove unreachable WorkflowAbortError catches from execute/resume (gate abort now returns StepResult(FAILED) instead of raising) - while_loop docstring updated: max_iterations is optional (default 10) * Address twentieth review: gate abort maps to ABORTED status, do-while max_iterations optional - Engine detects output.aborted from gate step and sets RunStatus.ABORTED (was unreachable — gate abort returned FAILED but status was always FAILED) - do-while max_iterations now optional (default 10), aligned with while_loop - do-while docstring and validation updated accordingly * Coerce default_options to dict, align bundled workflow ID regex with validator * Gate validates string options, prompt uses resolved integration, loop normalizes max_iterations * Use parentId:childId convention for nested step IDs - Fan-out per-item IDs use parentId:templateId:index (e.g. parallel:impl:0) - Reserve ':' in user step IDs (validation rejects) - Replaces _fanout_ prefix with cleaner namespacing - Expressions like {{ steps.parallel:impl:0.output.file }} work naturally * Validate workflow version is semantic versioning (X.Y.Z) * Schema version validation, strict semver, load_workflow docstring, preserve max_concurrency - Validate schema_version is '1.0' (reject unknown future schemas) - Strict semver regex: ^\d+\.\d+\.\d+$ (rejects 1.0.0beta etc.) - load_workflow docstring: 'parsed' not 'validated' - Keep max_concurrency in fan-out output (was dropped) - do_while docstring: engine re-evaluates step_config condition - ARCHITECTURE.md: document nested resume limitation * Path traversal prevention, loop step ID namespacing - RunState validates run_id is alphanumeric+hyphens (no path separators) - workflow_add validates catalog source doesn't escape workflows_dir - Loop iterations namespace nested step IDs as parentId:childId:iteration so multiple iterations don't overwrite each other in context/state --------- 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> |
||
|
|
c0152e4f3d |
docs(catalog): add claude-ask-questions to community preset catalog (#2191)
* feat: add claude-ask-questions preset for AskUserQuestion rendering
Delivers the /speckit.clarify and /speckit.checklist AskUserQuestion
integration as a stackable preset under presets/claude-ask-questions/
instead of modifying core templates or ClaudeIntegration.
- presets/claude-ask-questions/preset.yml registers command overrides
for speckit.clarify and speckit.checklist following the same pattern
as the bundled lean preset.
- Override commands replace the Markdown-table question-rendering
blocks with AskUserQuestion instructions. Option | Description maps
to {label, description} for clarify; Option | Candidate | Why It
Matters maps to {label: Candidate, description: Why It Matters} for
checklist. Recommended option is placed first with a
"Recommended — <reasoning>" prefix; a final "Custom"/"Short" option
preserves the free-form ≤5-word escape hatch.
- Registered in presets/catalog.json as a bundled preset.
Core templates, ClaudeIntegration, and the existing test suite are
left untouched, so non-Claude agents and users who do not install
this preset see no behavior change.
Closes github/spec-kit#2181
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: move claude-ask-questions preset to external repo
Per maintainer feedback on #2191, presets should be hosted on the
author's own GitHub repository and registered in catalog.community.json
rather than bundled in spec-kit. Removes the bundled preset directory
and its entry from the official catalog, and adds a community catalog
entry pointing at the external repository and release archive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(catalog): sync claude-ask-questions description with upstream preset
* revert: keep presets/catalog.json updated_at unchanged
No entries in the official catalog changed in this PR, so the timestamp
bump was spurious. Addresses Copilot review feedback on #2191.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||
|
|
03a9163633 |
Add SFSpeckit — Salesforce SDD Extension (#2208)
* Add SFSpeckit — Salesforce SDD Extension * chore: update catalog updated_at timestamp |
||
|
|
4687c33b0f |
feat(scripts): optional single-segment branch prefix for gitflow (#2202)
* feat(scripts): optional single-segment branch prefix for gitflow - Add spec_kit_effective_branch_name / Get-SpecKitEffectiveBranchName: when branch matches prefix/rest with exactly one slash, validate and resolve specs/ using only the rest (e.g. feat/001-my-feature). - Wire into check_feature_branch, find_feature_dir_by_prefix (bash) and Test-FeatureBranch, Find-FeatureDirByPrefix + Get-FeaturePathsEnv (PS). - Align git extension git-common with core validation; remove unused get_feature_dir / Get-FeatureDir helpers. - Extend tests in test_timestamp_branches.py and test_git_extension.py. Made-with: Cursor * Update scripts/powershell/common.ps1 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(ps): align feature-dir resolution errors with bash (no throw under Stop) Find-FeatureDirByPrefix: on ambiguous prefix matches, write errors to stderr and return $null instead of throwing, matching find_feature_dir_by_prefix. Get-FeaturePathsEnv: narrow try/catch to ConvertFrom-Json only; add Get-FeatureDirFromBranchPrefixOrExit to mirror bash get_feature_paths (stderr + exit 1) when prefix lookup fails, avoiding unhandled terminating errors under $ErrorActionPreference = 'Stop' in check-prerequisites, setup-plan, and update-agent-context. Made-with: Cursor * Update tests/test_timestamp_branches.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update extensions/git/scripts/powershell/git-common.ps1 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update scripts/powershell/common.ps1 Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
de93528fad |
chore: release 0.6.2, begin 0.6.3.dev0 development (#2205)
* chore: bump version to 0.6.2 * chore: begin 0.6.3.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
bb7da09b65 |
Add Worktrees extension to community catalog (#2207)
- Extension ID: worktrees - Version: 1.0.0 - Author: dango85 - Description: Default-on worktree isolation for parallel agents Made-with: Cursor Co-authored-by: Abishek Yadav <abiyadav@publicisgroupe.net> |
||
|
|
fe75a45627 |
feat: Update catalog.community.json for preset-fiction-book-writing (#2199)
* feat: Update catalog.community.json for preset-fiction-book-writing * Add fiction-book-writing preset to community catalog - Preset ID: fiction-book-writing - Version: 1.3.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. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * doc: added fiction-book-writing preset link in README.md * 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> Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com> |
||
|
|
aa85b2f166 |
feat: Register "What-if Analysis" community extension (#2182)
* feat: implement read-only what-if analysis command * chore: polish what-if analysis (Claude hints + optional tasks) * refactor: deliver what-if analysis as a standalone extension * Move What-if extension to standalone repo and update community catalog * Fix: Reorder whatif extension alphabetically in community catalog |
||
|
|
e27896e681 |
feat: add GitHub Issues Integration to community catalog (#2188)
* feat: add GitHub Issues Integration to community catalog Add GitHub Issues Integration extension to the community catalog and README. Extension provides: - /speckit.github-issues.import - Import GitHub Issue and generate spec.md - /speckit.github-issues.sync - Keep specs updated with issue changes - /speckit.github-issues.link - Add bidirectional traceability Resolves #2175 * Modify created_at and updated_at timestamps Updated timestamps for created_at and updated_at fields. * Update updated_at date in catalog.community.json |
||
|
|
b67b2856b1 |
feat(agents): add Goose AI agent support (#2015)
* feat(integrations): add YamlIntegration base class for YAML recipe agents Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * feat(integrations): add Goose integration subpackage with YAML recipe support Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * feat(integrations): register GooseIntegration in the integration registry Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * feat(agents): add YAML format support to CommandRegistrar for extension/preset commands Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * feat(scripts): add goose agent type to bash update-agent-context script Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * feat(scripts): add goose agent type to PowerShell update-agent-context script Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * docs(agents): add Goose to supported agents table and integration notes Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * docs(readme): add Goose to supported agents table Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * test(integrations): add YamlIntegrationTests base mixin for YAML agent testing Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * test(integrations): add Goose integration tests Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * test(consistency): add Goose consistency checks for config, registrar, and scripts Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * docs(agents): move Goose to YAML Format section in Command File Formats Goose uses YAML recipes, not Markdown. Remove it from the Markdown Format list and add a dedicated YAML Format subsection with a representative recipe example showing prompt: | and {{args}} placeholders. * refactor(agents): delegate render_yaml_command to YamlIntegration Remove the duplicate header dict, yaml.safe_dump call, body indentation, and _human_title logic from CommandRegistrar.render_yaml_command(). Delegate to YamlIntegration._render_yaml() and _human_title() so YAML recipe output stays consistent across the init-time generation and command-registration code paths. * fix(agents): guard alias output path against directory traversal Validate that alias_file resolves within commands_dir before writing. Uses the same resolve().relative_to() pattern already established in extensions.py for ZIP path containment checks. * docs(agents): add Goose to Multi-Agent Support comment list in update-agent-context.sh * fix(agents): add goose to print_summary Usage line in bash context script The print_summary() function listed all supported agents in its Usage output but omitted goose, making it inconsistent with the header docs and the error message in update_specific_agent(). Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(agents): add goose to Print-Summary Usage line in PowerShell context script The Print-Summary function listed all supported agents in its Usage output but omitted goose, making it inconsistent with the ValidateSet and the header documentation. Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(agents): normalize description and title types in YamlIntegration.setup() YAML frontmatter can contain non-string types (null, list, int). Add isinstance checks matching TomlIntegration._extract_description() to ensure Goose recipes always receive valid string fields. Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(agents): validate shared script exists before exec in Goose bash wrapper Add Forge-style check that the shared update-agent-context.sh is present and executable, producing a clear error instead of a cryptic shell exec failure when the shared script is missing. Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(agents): validate shared script exists before invoke in Goose PowerShell wrapper Add Forge-style Test-Path check that the shared update-agent-context.ps1 exists, producing a clear error instead of a cryptic PowerShell failure when the shared script is missing. Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(agents): normalize title and description types in render_yaml_command() Extension/preset frontmatter can contain non-string types. Add isinstance checks matching the normalization in YamlIntegration.setup() so both code paths produce valid Goose recipe fields. Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(agents): replace $ARGUMENTS with arg_placeholder in process_template() Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * test(agents): assert $ARGUMENTS absent from generated YAML recipes Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * test(agents): assert $ARGUMENTS absent from generated TOML commands Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> * fix(tests): rewrite docstring to avoid embedded triple-quote in TOML test Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> --------- Signed-off-by: Furkan Köykıran <furkankoykiran@gmail.com> |
||
|
|
52ed84d723 |
Update ralph extension to v1.0.1 in community catalog (#2192)
- Extension ID: ralph - Version: 1.0.0 → 1.0.1 - Author: Rubiss - Changes: Fixed bash task count bug, removed hardcoded model, added regression tests, CI workflow, and release pipeline. - Release: https://github.com/Rubiss/spec-kit-ralph/releases/tag/v1.0.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
cdbea09e1a |
fix: skip docs deployment workflow on forks (#2171)
Add repository check to build and deploy jobs so they skip with success on forks, avoiding failed Pages deployments for contributors. |
||
|
|
1cb794e516 |
chore: release 0.6.1, begin 0.6.2.dev0 development (#2162)
* chore: bump version to 0.6.1 * chore: begin 0.6.2.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
43cb0fa7ab |
feat: add bundled lean preset with minimal workflow commands (#2161)
* feat: add bundled lean preset with minimal workflow commands Add a lean preset that overrides the 5 core workflow commands (specify, plan, tasks, implement, constitution) with minimal prompts that produce exactly one artifact each — no extension hooks, no scripts, no git branching, no templates. Bundled preset infrastructure: - Add _locate_bundled_preset() mirroring _locate_bundled_extension() - Update 'specify init --preset' to try bundled -> catalog fallback - Update 'specify preset add' to try bundled -> catalog fallback - Add bundled guard in download_pack() for presets without download URLs - Add lean to presets/catalog.json with 'bundled: true' marker - Add lean to pyproject.toml force-include for wheel packaging - Align error messages with bundled extension error pattern Tests: 15 new tests (TestLeanPreset + TestBundledPresetLocator) * refactor: address review — clean up unused imports, strengthen test assertions - Remove unused MagicMock import and cache_dir setup in download test - Assert 'bundled' and 'reinstall' in CLI error output (not just exit code) - Mock catalog in missing-locally test for deterministic bundled error path - Fix test versions to satisfy updated speckit_version >=0.6.0 requirement * refactor: address review — fix constitution paths, add REINSTALL_COMMAND to presets.py - Fix constitution path to .specify/memory/constitution.md in plan, tasks, implement commands (matching core command convention) - Include REINSTALL_COMMAND in download_pack() bundled guard for consistent recovery instructions across bundled extensions and presets * refactor: address review — explicit feature_directory paths, ZIP cleanup in finally - Prefix spec.md/plan.md/tasks.md with <feature_directory>/ in plan, tasks, and implement commands so the agent doesn't operate on repo root by mistake - Move ZIP unlink into finally block in init --preset path so cleanup runs even when install_from_zip raises (matching preset_add pattern) * refactor: address review — replace Unicode em dashes with ASCII, fix grammar - Replace all Unicode em dashes with ASCII hyphens in preset.yml and catalog.json to avoid decode errors on non-UTF-8 environments - Fix grammar: 'store it in tasks.md' -> 'store them in tasks.md' * refactor: address review - align task format between tasks and implement - Remove undefined [P] marker from implement (lean uses sequential execution) - Clarify checkbox update: 'change - [ ] to - [x]' instead of ambiguous '[X]' - Simplify implement to execute tasks in order without parallel complexity * refactor: address review - parse frontmatter instead of raw substring search - Use CommandRegistrar.parse_frontmatter() to check for scripts/agent_scripts keys in YAML frontmatter instead of brittle 'scripts:' substring search |
||
|
|
74e3f45aa9 |
Add Brownfield Bootstrap extension to community catalog (#2145)
- 4 commands: scan, bootstrap, validate, migrate for existing codebases - 1 hook: after_init for auto-scanning project after spec-kit initialization - Addresses community request in issue #1436 (30+ reactions) |
||
|
|
97ea7cf6a0 |
Add CI Guard extension to community catalog (#2157)
* Add CI Guard extension to community catalog Adds spec-kit-ci-guard: spec compliance gates for CI/CD pipelines. 5 commands: - /speckit.ci.check — run all compliance checks with pass/fail - /speckit.ci.report — generate requirement traceability matrix - /speckit.ci.gate — configure merge gate rules and thresholds - /speckit.ci.drift — detect bidirectional spec-to-code drift - /speckit.ci.badge — generate spec compliance badges 2 hooks: before_implement, after_implement Bridges the gap between SDD workflow and CI/CD enforcement. * Fix updated_at to monotonically increase per Copilot review Set to 2026-04-10T15:00:00Z (later than previous 2026-04-10T12:34:56Z). |
||
|
|
f43b85096c |
Add SpecTest extension to community catalog (#2159)
* Add SpecTest extension to community catalog Adds spec-kit-spectest: auto-generate test scaffolds from spec criteria. 4 commands: - /speckit.test.generate — generate framework-native test scaffolds - /speckit.test.coverage — map spec requirements to test coverage - /speckit.test.gaps — find untested requirements with suggestions - /speckit.test.plan — generate structured test plan documents 1 hook: after_implement (gap detection) Bridges the spec-to-test gap in the SDD workflow. * Update extensions/catalog.community.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix spectest created_at/updated_at to use current timestamp per Copilot review Set both to 2026-04-10T16:00:00Z instead of midnight. --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
d1b95c2f59 |
fix: bundled extensions should not have download URLs (#2155)
* fix: bundled extensions should not have download URLs (#2151) - Remove selftest from default catalog (not a published extension) - Replace download_url with 'bundled: true' flag for git extension - Add bundled check in extension add flow with clear error message when bundled extension is missing from installed package - Add bundled check in download_extension() with specific error - Direct users to reinstall via uv with full GitHub URL - Add 3 regression tests for bundled extension handling * refactor: address review - move bundled check up-front, extract reinstall constant - Move bundled check before download_url inspection in download_extension() so bundled extensions can never be downloaded even with a URL present - Extract REINSTALL_COMMAND constant to avoid duplicated install strings * fix: allow bundled extensions with download_url to be updated Bundled extensions should only be blocked from download when they have no download_url. If a newer version is published to the catalog with a URL, users should be able to install it to get bug fixes. Add test for bundled-with-URL download path. |
||
|
|
8bb08ae1a0 |
Add PR Bridge extension to community catalog (#2148)
- 3 commands: generate PR descriptions, reviewer checklists, and change summaries - 1 hook: after_implement for auto-generating PR description - Closes the SDD workflow loop: specify → plan → tasks → implement → PR |
||
|
|
5732de60d0 |
feat(cursor-agent): migrate from .cursor/commands to .cursor/skills (#2156)
Use SkillsIntegration so workflows ship as speckit-*/SKILL.md. Update init next-steps, extension hook invocation, docs, and tests. Made-with: Cursor |
||
|
|
b6e19b49ec |
Add TinySpec extension to community catalog (#2147)
* Add TinySpec extension to community catalog - 3 commands: tinyspec, implement, classify for lightweight single-file workflow - 1 hook: before_specify for auto-classifying task complexity - Addresses community request in issue #1174 (22+ reactions) * 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> |
||
|
|
7f1e38491f |
chore: bump spec-kit-verify to 1.0.3 and spec-kit-review to 1.0.1 (#2146)
* chore: bump spec-kit-verify to 1.0.3 and spec-kit-review to 1.0.1 * Removed invalid aliases * Change updated at |
||
|
|
bc0288832e |
Add Status Report extension to community catalog (#2123)
- Extension ID: status-report - Version: 1.2.5 - Author: Open-Agent-Tools - Description: Project status, feature progress, and next-action recommendations for spec-driven workflows Co-authored-by: Unserious AI <121459476+unseriousAI@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e70495c2b8 |
chore: release 0.6.0, begin 0.6.1.dev0 development (#2144)
* chore: bump version to 0.6.0 * chore: begin 0.6.1.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
674a66449a |
Add Bugfix Workflow community extension to catalog and README (#2135)
* Add Bugfix Workflow community extension to catalog and README Adds the spec-kit-bugfix extension (3 commands, 1 hook) that provides a structured bugfix workflow — capture bugs, trace to spec artifacts, and surgically patch specs without regenerating from scratch. Addresses community request in issue #619 (25+ upvotes, maintainer-approved). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Bump catalog updated_at to 2026-04-09 to match new entry date Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
efeb5489c3 |
Add Worktree Isolation extension to community catalog (#2143)
- 3 commands: create, list, clean worktrees for parallel feature development - 1 hook: after_specify for auto-worktree creation - Addresses community request in issue #61 (36+ upvotes) |
||
|
|
8013d0b57e |
Add multi-repo-branching preset to community catalog (#2139)
* Add nested-repos to community catalog - Preset ID: nested-repos - Version: 1.0.0 - Author: sakitA - Description: Multi-module nested repository support for independent repos and git submodules Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update presets/catalog.community.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Bump catalog updated_at timestamp Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update nested-repos preset: commands-only, 0 templates Removed template overrides to reduce core content duplication. Commands instruct AI to add nested-repo sections dynamically. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename preset: nested-repos -> multi-repo-branching Updated preset ID, name, description, and all URLs to reflect the new repository name and clearer preset identity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove templates: 0 from catalog provides section Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove accidentally committed .claude folder Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review: restore templates key and add README entry - Add templates: 0 back to provides for catalog consistency - Add multi-repo-branching to Community Presets table in README.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
0a121b073c |
Readme clarity (#2013)
* Specify CLI Reference formatting Improves formatting of Specify CLI Reference * Available Slash Commands clarity Improve "Available Slash Commands" clarity in README.md. * Add extension/preset commands to cli reference * Extensions & Presets section clarity Improves Extensions & Presets section clarity in README.md * Removes `$` from Agent Skill * Reverts Supported AI Agents Table * Added missing Agent Skill column * Trailing whitespaces Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Adds missing code block language Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Revised wording Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Revised specify synopsis * Update specify command reference table Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Removes extra (duplicate) slashes * Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Removed old section * missing /speckit.taskstoissues * integration command 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> * 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> |
||
|
|
6af2e64e88 |
Rewrite AGENTS.md for integration architecture (#2119)
* Rewrite AGENTS.md for integration subpackage architecture Replaces the old AGENT_CONFIG dict-based 7-step process with documentation reflecting the integration subpackage architecture shipped in #1924. Removed: Supported Agents table, old step-by-step guide referencing AGENT_CONFIG/release scripts/case statements, Agent Categories lists, Directory Conventions section, Important Design Decisions section. Kept: About Spec Kit and Specify, Command File Formats, Argument Patterns, Devcontainer section. Added: Architecture overview, decision tree for base class selection, configure/register/scripts/test/override steps with real code examples from existing integrations (Windsurf, Gemini, Codex, Copilot). Agent-Logs-Url: https://github.com/github/spec-kit/sessions/71b25c53-7d0c-492a-9503-f40a437d5ece Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Fix JSONC comment syntax in devcontainer example Agent-Logs-Url: https://github.com/github/spec-kit/sessions/71b25c53-7d0c-492a-9503-f40a437d5ece Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * docs(AGENTS.md): address Copilot PR review comments - Clarify that integrations are registered by _register_builtins() in __init__.py, not self-registered at import time - Scope the key-must-match-executable rule to CLI-based integrations (requires_cli: True); IDE-based integrations use canonical identifiers - Replace <commands_dir> placeholder in test snippet with a concrete example path (.windsurf/workflows/) - Document that hyphens in keys become underscores in test filenames (e.g. cursor-agent -> test_integration_cursor_agent.py) - Note that the argument placeholder is integration-specific (registrar_config["args"]); add Forge's {{parameters}} as an example - Apply consistency fixes to Required fields table, Key design rule callout, and Common Pitfalls #1 * docs(AGENTS.md): clarify scripts path uses Python-safe package_dir not key The scripts step previously referenced src/specify_cli/integrations/<key>/scripts/ but for hyphenated keys the actual directory is underscored (e.g. kiro-cli -> kiro_cli/). Rename the placeholder to <package_dir> and add a note explaining: - <package_dir> matches <key> for non-hyphenated keys - <package_dir> uses underscores for hyphenated keys (e.g. kiro-cli -> kiro_cli/) - IntegrationBase.key always retains the original hyphenated value Addresses: https://github.com/github/spec-kit/pull/2119#discussion_r3054946896 * docs(AGENTS.md): use <key_with_underscores> in pytest example command The pytest command previously used <key> as a placeholder, but test filenames always use underscores even for hyphenated keys. This was internally inconsistent since the preceding sentence already explained the hyphen→underscore mapping. Switch to <key_with_underscores> to match the actual filename on disk. Addresses: https://github.com/github/spec-kit/pull/2119#discussion_r3054962863 * docs(AGENTS.md): use <package_dir> in step 2 subpackage path The path src/specify_cli/integrations/<key>/__init__.py was inaccurate for hyphenated keys (e.g. kiro-cli lives in kiro_cli/, not kiro-cli/). Rename the placeholder to <package_dir>, define it inline (hyphens become underscores), and note that IntegrationBase.key always retains the original hyphenated value. Addresses: https://github.com/github/spec-kit/pull/2119#discussion_r3058050583 * docs(AGENTS.md): qualify 'single source of truth' to Python metadata only The registry is only authoritative for Python integration metadata. Context-update dispatcher scripts (bash + PowerShell) still require explicit per-agent cases and maintain their own supported-agent lists until they are migrated to registry-based dispatch. Tighten the claim to avoid misleading contributors into skipping the script updates. Addresses: https://github.com/github/spec-kit/pull/2119#pullrequestreview-4083090261 * docs(AGENTS.md): mention ValidateSet update in PowerShell dispatcher step The update-agent-context.ps1 script has a [ValidateSet(...)] on the AgentType parameter. Without adding the new key to that list, the script rejects the argument before reaching Update-SpecificAgent. Add this as an explicit step alongside the switch case and Update-AllExistingAgents. Addresses: https://github.com/github/spec-kit/pull/2119#pullrequestreview-4083217694 * fix(integrations): sort codebuddy before codex in _register_builtins() Both the import list and the _register() call list had codex before codebuddy, violating the alphabetical ordering that AGENTS.md documents. Swap them so the file matches the documented convention. Addresses: https://github.com/github/spec-kit/pull/2119#pullrequestreview-4083341590 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> |
||
|
|
66125a80a9 |
docs: add SpecKit Companion to Community Friends section (#2140)
Add SpecKit Companion VS Code extension to the Community Friends listing alongside existing community projects. |
||
|
|
55515093a2 |
feat: add memorylint extension to community catalog (#2138)
* feat: add memorylint extension to community catalog * chore: update speckit_version requirement to >=0.5.1 for memorylint extension * docs: register memorylint extension in README and update requirements |
||
|
|
aa2282ea04 |
chore: release 0.5.1, begin 0.5.2.dev0 development (#2137)
* chore: bump version to 0.5.1 * chore: begin 0.5.2.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
1c41aacbac |
fix: pin typer>=0.24.0 and click>=8.2.1 to fix import crash (#2136)
typer <0.24.0 under-constrains its click dependency (click>=8.0.0), allowing resolvers to pick click <8.2 which lacks __class_getitem__ on click.Choice. This causes 'TypeError: type Choice is not subscriptable' at import time on any Python version. Pin typer>=0.24.0 (which correctly requires click>=8.2.1) and click>=8.2.1 to prevent incompatible combinations. Fixes #2134 |
||
|
|
cb0d9612ef | feat: update fleet extension to v1.1.0 (#2029) | ||
|
|
71143598be |
fix(forge): use hyphen notation in frontmatter name field (#2075)
* fix(forge): use hyphen notation in frontmatter name field
- Changed injected name field from 'speckit.{command}' to 'speckit-{command}'
- Keeps standard filename format 'speckit.{command}.md'
- Aligns with Forge's command naming convention requirements
- All tests pass
* feat(forge): centralize name formatting to fix extension/preset command names
Address PR feedback by centralizing Forge command name formatting to ensure
consistent hyphenated names across both core template setup and
extension/preset command registration.
Changes:
- Add format_forge_command_name() utility function in forge integration
- Update ForgeIntegration._apply_forge_transformations() to use centralized formatter
- Add _format_name_for_agent() helper in CommandRegistrar to apply agent-specific formatting
- Update CommandRegistrar.register_commands() to format names for Forge (both primary commands and aliases)
- Add comprehensive test coverage for the formatter and registrar behavior
Impact:
- Extension commands installed for Forge now use 'name: speckit-my-extension-example'
instead of 'name: speckit.my-extension.example'
- Fixes ZSH/shell compatibility issues with dot notation in command names
- Maintains backward compatibility for all other agents (they continue using dot notation)
- Eliminates duplication between integration setup and registrar paths
Example transformation:
Before: name: speckit.jira.sync-status (breaks in ZSH/Forge)
After: name: speckit-jira-sync-status (works everywhere)
Fixes inconsistency where core templates used hyphens but extension/preset
commands preserved dots, breaking Forge's naming requirements.
* refactor(forge): move name formatting logic to integration module
Move _format_name_for_agent function logic into Forge integration's
registrar_config as a 'format_name' callback, improving separation of
concerns and keeping Forge-specific logic within its integration module.
Changes:
- Remove _format_name_for_agent() from agents.py (shared module)
- Add 'format_name' callback to Forge's registrar_config pointing to format_forge_command_name
- Update CommandRegistrar to use format_name callback when available
- Maintains same behavior: Forge commands use hyphenated names, others use dot notation
Benefits:
- Better encapsulation: Forge-specific logic lives in forge integration
- More extensible: Other integrations can provide custom formatters via registrar_config
- Cleaner separation: agents.py doesn't need to know about specific agent requirements
* fix(forge): make format_forge_command_name idempotent
Handle already-hyphenated names (speckit-foo) to prevent double-prefixing
(speckit-speckit-foo). The function now returns already-formatted names
unchanged, making it safe to call multiple times.
Changes:
- Add early return for names starting with 'speckit-'
- Update docstring to clarify accepted input formats
- Add examples showing idempotent behavior
- Add test coverage for idempotent behavior
Examples:
format_forge_command_name('speckit-plan') -> 'speckit-plan' (unchanged)
format_forge_command_name('speckit.plan') -> 'speckit-plan' (converted)
format_forge_command_name('plan') -> 'speckit-plan' (prefixed)
* test(forge): strengthen name field assertions and clarify comments
Improve test_name_field_uses_hyphenated_format to fail loudly when
the name field is missing instead of silently passing.
Changes:
- Add explicit assertion that name_match is not None before validating value
- Ensures test fails if regex doesn't match (e.g., frontmatter rendering changes)
- Clarify Claude comment: it doesn't use inject_name path but SKILL.md
frontmatter still includes hyphenated name via build_skill_frontmatter()
Before: Test would silently pass if 'name:' field was missing from frontmatter
After: Test explicitly asserts field presence before validating format
* docs(forge): clarify frontmatter name requirement and improve test isolation
Fix misleading docstring and improve test to properly validate that the
format_name callback is Forge-specific.
Changes to src/specify_cli/integrations/forge/__init__.py:
- Reword module docstring to clarify the requirement is specifically for
the frontmatter 'name' field value, not command files or invocation
- Before: 'Requires hyphenated command names ... instead of dot notation'
(implied dot notation unsupported overall)
- After: 'Uses a hyphenated frontmatter name value ... for shell compatibility'
(clarifies it's the frontmatter field, and Forge still supports dot filenames)
Changes to tests/integrations/test_integration_forge.py:
- Replace Claude with Windsurf in test_registrar_does_not_affect_other_agents
- Claude uses build_skill_frontmatter() which always includes hyphenated names,
so testing it didn't validate that format_name callback is Forge-only
- Windsurf is a standard markdown agent without inject_name
- Now asserts NO 'name:' field is present, proving format_name isn't invoked
- This properly validates the callback mechanism is isolated to Forge
* test(forge): use parse_frontmatter for precise YAML validation
Replace regex and string searches with CommandRegistrar.parse_frontmatter()
to validate only YAML frontmatter, not entire file content. Prevents false
positives if command body contains 'name:' lines.
Changes:
- test_forge_specific_transformations: Parse frontmatter dict instead of string search
- test_name_field_uses_hyphenated_format: Replace regex with frontmatter parsing
- test_registrar_formats_extension_command_names_for_forge: Use dict validation
- test_registrar_formats_alias_names_for_forge: Use dict validation
Benefits: More precise, robust against body content, better error messages,
consistent with existing codebase utilities.
---------
Co-authored-by: ericnoam <eric.rodriguez@leovegas.com>
|
||
|
|
9c73e68528 |
fix(bash): sed replacement escaping, BSD portability, dead cleanup in update-agent-context.sh (#2090)
* fix(bash): sed replacement escaping, BSD portability, dead cleanup code
Three bugs in update-agent-context.sh:
1. **sed escaping targets wrong side** (line 318-320): The escaping
function escapes regex pattern characters (`[`, `.`, `*`, `^`, `$`,
`+`, `{`, `}`, `|`) but these variables are used as sed
*replacement* strings, not patterns. Only `&` (insert matched text),
`\` (escape char), and `|` (our sed delimiter) are special in the
replacement context. Also adds escaping for `project_name` which
was used unescaped.
2. **BSD sed newline insertion fails on macOS** (line 364-366): Uses
bash variable expansion to insert a literal newline into a sed
replacement string. This works on GNU sed (Linux) but fails silently
on BSD sed (macOS). Replaced with portable awk approach that works
on both platforms.
3. **cleanup() removes non-existent files** (line 125-126): The
cleanup trap attempts `rm -f /tmp/agent_update_*_$$` and
`rm -f /tmp/manual_additions_$$` but the script never creates files
matching these patterns — all temp files use `mktemp`. The wildcard
with `$$` (PID) in /tmp could theoretically match unrelated files.
Fixes #154 (macOS sed failure)
Fixes #293 (sed expression errors)
Related: #338 (shellcheck findings)
* fix: restore forge case and revert copilot path change
Address PR review feedback:
- Restore forge) case in update_specific_agent since
src/specify_cli/integrations/forge/__init__.py still exists
- Revert COPILOT_FILE path from .github/agents/ back to .github/
to stay consistent with Python integration and tests
- Restore FORGE_FILE variable, comments, and usage strings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: extract repeated sed escaping into _esc_sed helper
Address Gemini review feedback — the inline sed escaping pattern
appeared 7 times in create_new_agent_file(). Extract to a single
helper function for maintainability and readability.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: restore combined AGENTS_FILE label in update_all_existing_agents
Gemini correctly identified that splitting AGENTS_FILE updates into
individual calls is redundant — _update_if_new deduplicates by
realpath, so only the first call logs. Restore the combined label
and add back missing Pi reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove pre-escaped && in JS/TS commands now that _esc_sed handles it
The old code manually pre-escaped & as \& in get_commands_for_language
because the broken escaping function didn't handle &. Now that _esc_sed
properly escapes replacement-side specials, the pre-escaping causes
double-escaping: && becomes \&\& in generated files.
Found by blind audit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: split awk && mv to let set -e catch awk failures
Under set -e, the left side of && does not trigger errexit on failure.
Split into two statements so awk failures are fatal instead of silent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: guard empty _CLEANUP_FILES array for Bash 3.2 compatibility
On Bash 3.2, the ${arr[@]+"${arr[@]}"} pattern expands to a single
empty string when the array is empty, causing rm to target .bak and
.tmp in the current directory. Use explicit length check instead,
which also avoids the word-splitting risk of unquoted expansion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Bo Bobson <bo@noneofyourbusiness.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
8472e44215 |
Add Spec Diagram community extension to catalog and README (#2129)
Adds the spec-kit-diagram extension (3 commands, 1 hook) that auto-generates Mermaid diagrams for SDD workflow visualization, feature progress tracking, and task dependency graphs. Addresses community request in issue #467 (50+ upvotes). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
2972dec85c |
feat: Git extension stage 2 — GIT_BRANCH_NAME override, --force for existing dirs, auto-install tests (#1940) (#2117)
* feat: Git extension stage 2 — GIT_BRANCH_NAME override, --force for existing dirs, auto-install tests (#1940) - Add GIT_BRANCH_NAME env var override to create-new-feature.sh/.ps1 for exact branch naming (bypasses all prefix/suffix generation) - Fix --force flag for 'specify init <dir>' into existing directories - Add TestGitExtensionAutoInstall tests (auto-install, --no-git skip, commands registered) - Add TestFeatureDirectoryResolution tests (env var, feature.json, priority, branch fallback) - Document GIT_BRANCH_NAME in speckit.git.feature.md and specify.md * fix: remove unused Tuple import (ruff F401) * fix: address Copilot review feedback (#2117) - Fix timestamp regex ordering: check YYYYMMDD-HHMMSS before generic numeric prefix in both bash and PowerShell - Set BRANCH_SUFFIX in GIT_BRANCH_NAME override path so 244-byte truncation logic works correctly - Add 244-byte length check for GIT_BRANCH_NAME in PowerShell - Use existing_items for non-empty dir warning with --force - Skip git extension install if already installed (idempotent --force) - Wrap PowerShell feature.json parsing in try/catch for malformed JSON - Fix PS comment: 'prefix lookup' -> 'exact mapping via Get-FeatureDir' - Remove non-functional SPECIFY_SPEC_DIRECTORY from specify.md template * fix: address second round of Copilot review feedback (#2117) - Guard shutil.rmtree on init failure: skip cleanup when --force merged into a pre-existing directory (prevents data loss) - Bash: error on GIT_BRANCH_NAME >244 bytes instead of broken truncation - Fix malformed numbered list in specify.md (restore missing step 1) - Add claude_skills.exists() assert before iterdir() in test * fix: use UTF-8 byte count for 244-byte branch name limit (#2117) - Bash: use LC_ALL=C wc -c for byte length instead of ${#VAR} - PowerShell: use [System.Text.Encoding]::UTF8.GetByteCount() instead of .Length (UTF-16 code units) * fix: address third round of review feedback (#2117) - Update --dry-run help text in bash and PowerShell (branch name only) - Fix specify.md JSON example: use concrete path, not literal variable - Add TestForceExistingDirectory tests (merge + error without --force) - Add PowerShell Get-FeaturePathsEnv tests (env var + feature.json) * fix: normalize relative paths and fix Test-HasGit compat (#2117) - Bash common.sh: normalize SPECIFY_FEATURE_DIRECTORY and feature.json relative paths to absolute under repo root - PowerShell common.ps1: same normalization using IsPathRooted + Join-Path - PowerShell create-new-feature.ps1: call Test-HasGit without -RepoRoot for compatibility with core common.ps1 (no param) and git-common.ps1 (optional param with default) * test: add GIT_BRANCH_NAME automated tests for bash and PowerShell (#2117) - TestGitBranchNameOverrideBash: 5 tests (exact name, sequential prefix, timestamp prefix, overlong rejection, dry-run) - TestGitBranchNameOverridePowerShell: 4 tests (exact name, sequential prefix, timestamp prefix, overlong rejection) - Tests use extension scripts (not core) via new ext_git_repo and ext_ps_git_repo fixtures * fix: restore git init during specify init + review fixes (#2117) - Restore is_git_repo() and init_git_repo() functions removed in stage 2 - specify init now runs git init AND installs git extension (not just extension install alone) - Add is_dir() guard for non-here path to prevent uncontrolled error when target exists but is a file - Add python3 JSON fallback in common.sh for multi-line feature.json (grep pipeline fails on pretty-printed JSON without jq) * fix: use init_git_repo error_msg in failure output (#2117) * fix: ensure_executable_scripts also covers .specify/extensions/ (#2117) Extension .sh scripts (e.g. create-new-feature.sh, initialize-repo.sh) may lack execute bits after install. Scan both .specify/scripts/ and .specify/extensions/ for permission fixing. * fix: move chmod after extension install + sanitize error_msg (#2117) - ensure_executable_scripts() now runs after git extension install so extension .sh files get execute bits in the same init run - Sanitize init_git_repo error_msg to single line (replace newlines, truncate to 120 chars) to prevent garbled StepTracker output * fix: use tracker.error for git init/extension failures (#2117) Git init failure and extension install failure were reported as tracker.complete (showing green) even on error. Now track a git_has_error flag and call tracker.error when any step fails, so the UI correctly reflects the failure state. * fix: sanitize ext_err in git step tracker for consistent rendering (#2117) |
||
|
|
838bd0fedc | fix(git): surface checkout errors for existing branches (#2122) | ||
|
|
3028a00b6e |
Add Branch Convention community extension to catalog and README (#2128)
Adds the spec-kit-branch-convention extension (3 commands, 1 hook) that enables configurable branch and folder naming with built-in presets for GitFlow, ticket-based, date-based, and custom patterns. Addresses community request in issue #407 (39+ upvotes). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
ac6714de31 |
docs: lighten March 2026 newsletter for readability (#2127)
- Remove PR/issue number references throughout - Shorten summary table cells - Break version wall-of-text into shorter per-version paragraphs - Trim blog post summaries to key insights - Condense community tools and industry coverage sections - Merge competitive landscape subsections |
||
|
|
4deb90f4f5 |
fix: restore alias compatibility for community extensions (#2110) (#2125)
Relax alias validation in _collect_manifest_command_names() to only
enforce the 3-part speckit.{ext}.{cmd} pattern on primary command
names. Aliases retain type and duplicate checking but are otherwise
free-form, restoring pre-#1994 behavior.
This unblocks community extensions (e.g. spec-kit-verify) that use
2-part aliases like 'speckit.verify'.
Fixes #2110
|
||
|
|
4d58ee945c |
Added March 2026 newsletter (#2124)
* Added March 2026 newsletter * Use ASCII hyphen in newsletter title for consistency |
||
|
|
feb839103d |
Add Spec Refine community extension to catalog and README (#2118)
* Add Spec Refine community extension to catalog and README Adds the spec-kit-refine extension (4 commands, 2 hooks) that enables iterative specification refinement — update specs in-place, propagate changes to plan and tasks, diff impact, and track sync status. Addresses community request in issue #1191 (101+ upvotes). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix alphabetical ordering of S-entries in Community Extensions table Reorders Ship Release, Spec Critique, Spec Refine, Spec Sync, Staff Review, and Superpowers Bridge into correct alphabetical order per publishing guide. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |