mirror of
https://github.com/github/spec-kit
synced 2026-06-21 13:51:39 +00:00
v0.5.1
752 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e3f0edd142 | chore: bump version to 0.5.1 v0.5.1 | ||
|
|
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> |
||
|
|
1c25b5af3b |
Add explicit-task-dependencies community preset to catalog and README (#2091)
Registers the explicit-task-dependencies preset in the community catalog and README. The preset adds (depends on T###) dependency declarations and an Execution Wave DAG to tasks.md. Preset repository: https://github.com/Quratulain-bilal/spec-kit-preset-explicit-task-dependencies Related to #1934 |
||
|
|
375b2fdb1d |
Add toc-navigation community preset to catalog and README (#2080)
* feat: add Table of Contents to generated markdown documents (#1970) * fix: address Copilot review - clarify TOC placement wording * fix: include TOC sections in structure templates * fix: include TOC in structure templates and fix tasks TOC placement wording * fix: correct TOC anchors to match headings with mandatory suffix * fix: include all ##-level headings in tasks-template TOC * fix: add missing TOC entries in tasks-template, remove leading blank line in * fix: move TOC after metadata block and include all ## headings in tasks-template * fix: use plain text for dynamic phase entries in tasks-template TOC * fix: remove hardcoded anchor links from template TOCs, use plain text exemplars * fix: remove HTML comments from template TOCs * fix: add missing Parallel Example heading to tasks-template TOC * revert: remove all core template changes, pivot to preset approach * feat: deliver TOC navigation as a preset (closes #1970) Pivots from core template changes to a preset approach per reviewer request. Adds presets/toc-navigation/ with 3 template overrides and 3 command overrides that add Table of Contents sections to generated spec.md, plan.md, and tasks.md documents. Addresses all 8 impact concerns from review: - Templates use anchor links (not plain text) matching command instructions - All 12 tasks-template headings accounted for (dynamic phases as plain text) - spec-template anchors include -mandatory suffix - TOC placed after Note paragraph in plan-template - Self-reference exclusion explicit in all commands - Clarify stale TOC instruction in specify command - Implement misparse warning in tasks command Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: publish toc-navigation preset to community catalog (#1970) Move preset to standalone repository per maintainer guidance: https://github.com/Quratulain-bilal/spec-kit-preset-toc-navigation - Remove presets/toc-navigation/ from core repo - Add toc-navigation entry to catalog.community.json Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Add toc-navigation preset to main README community presets table Adds Table of Contents Navigation entry (alphabetically between Pirate Speak and VS Code Ask Questions) to the community presets table in README.md as requested by maintainer. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
40fb276023 |
fix: prevent ambiguous TOML closing quotes when body ends with " (#2113) (#2115)
* fix: prevent ambiguous TOML closing quotes when body ends with `"` (#2113) _render_toml_string placed the closing `"""` inline with content, so a body ending with `"` produced `""""` (four consecutive quotes). While technically valid TOML 1.0, this breaks stricter parsers such as Gemini CLI v0.27.2. Insert a newline before the closing delimiter when the body ends with a quote character. Same treatment for the single-quote (`'''`) fallback. Adds both a positive test (body ending with `"` must not produce `""""`) and a negative test (safe bodies keep the inline delimiter). * fix: use line-ending backslash instead of newline for TOML closing delimiters Address PR review feedback: - Replace sep=newline with TOML line-ending backslash so the parsed value does not gain a trailing newline when body ends with a quote. - For literal string (''') fallback, skip to escaped basic string when value ends with single quote instead of inserting a newline. - Make test body multiline so it exercises the """ rendering path, and assert no trailing newline in parsed value. * test: cover escaped basic-string fallback when body has triple-quotes and ends with single-quote Addresses review feedback from PR #2115: adds test for the branch where the body contains '"""' and ends with "'", which forces _render_toml_string() through the escaped basic-string fallback instead of the '''...''' literal-string path (since '''' would produce the same ambiguous-closing-delimiter problem). |
||
|
|
6536bc4102 |
fix speckit issue for trae (#2112)
* 修改trea文件结构错误问题 * 修改trea文件结构错误问题 * 修复trae agent 文件结构错误问题 * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix trae's test case files * Update src/specify_cli/integrations/trae/__init__.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: jiakangning <jiakangning@bytedance.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
1a9e4d1d8d |
feat: Git extension stage 1 — bundled extensions/git with hooks on all core commands (#1941)
* feat: add git extension with hooks on all core commands - Create extensions/git/ with 5 commands: initialize, feature, validate, remote, commit - 18 hooks covering before/after for all 9 core commands - Scripts: create-new-feature, initialize-repo, auto-commit, git-common (bash + powershell) - Configurable: branch_numbering, init_commit_message, per-command auto-commit with custom messages - Add hooks to analyze, checklist, clarify, constitution, taskstoissues command templates - Allow hooks-only extensions (no commands required) - Bundle extension in wheel via pyproject.toml force-include - Resolve bundled extensions locally before catalog lookup - Remove planned-but-unimplemented before/after_commit hook refs - Update extension docs (API ref, dev guide, user guide) - 37 new tests covering manifest, install, all scripts (bash+pwsh), config reading, graceful degradation Stage 1: opt-in via 'specify extension add git'. No auto-install, no changes to specify.md or core git init code. Refs: #841, #1382, #1066, #1791, #1191 * fix: set git identity env vars in extension tests for CI runners * fix: address PR review comments - Fix commands property KeyError for hooks-only extensions - Fix has_git() operator precedence in git-common.sh - Align default commit message to '[Spec Kit] Initial commit' across config-template, extension.yml defaults, and both init scripts - Update README to reflect all 5 commands and 18 hooks * fix: address second round of PR review comments - Add type validation for provides.commands (must be list) and hooks (must be dict) in manifest _validate() - Tighten malformed timestamp detection in git-common.sh to catch 7-digit dates without trailing slug (e.g. 2026031-143022) - Pass REPO_ROOT to has_git/Test-HasGit in create-new-feature scripts - Fix initialize command docs: surface errors on git failures, only skip when git is not installed - Fix commit command docs: 'skips with a warning' not 'silently' - Add tests for commands:null and hooks:list rejection * fix: address third round of PR review comments - Remove scripts frontmatter from command files (CommandRegistrar rewrites ../../scripts/ to .specify/scripts/ which points at core scripts, not extension scripts) - Update speckit.git.commit command to derive event name from hook context rather than using a static example - Clarify that hook argument passthrough works via AI agent context (the agent carries conversation state including user's original feature description) * fix: address fourth round of PR review comments - Validate extension_id against ^[a-z0-9-]+$ in _locate_bundled_extension to prevent path traversal (security fix) - Move defaults under config.defaults in extension.yml to match ConfigManager._get_extension_defaults() schema - Ship git-config.yml in extension directory so it's copied during install (provides.config template isn't materialized by ExtensionManager) - Condition handling in hook templates: intentionally matches existing pattern from specify/plan/tasks/implement templates (not a new issue) * fix: add --allow-empty to git commit in initialize-repo scripts Ensures git init succeeds even on empty repos where nothing has been staged yet. * fix: resolve display names to bundled extensions before catalog download When 'specify extension add "Git Branching Workflow"' is used with a display name instead of the ID, the catalog resolver now runs first to map the name to an ID, then checks bundled extensions again with the resolved ID before falling back to network download. Also noted: EXECUTE_COMMAND_INVOCATION and condition handling match the existing pattern in specify/plan/tasks/implement templates (pre-existing, not introduced by this PR). * fix: handle before_/after_ prefixes in auto-commit message derivation - Strip both before_ and after_ prefixes when deriving command name (fixes misleading 'Auto-commit after before_plan' messages) - Include phase (before/after) in default commit messages - Clarify README config example is an override, not default behavior * fix: use portable grep -qw for word boundary in create-new-feature.sh BSD grep (macOS) doesn't support \b as a word boundary. Replace with grep -qw which is POSIX-portable. * fix: validate hook values, numeric --number, and PS warning routing - Validate each hook value is a dict with a 'command' field during manifest _validate() (prevents crash at install time) - Validate --number is a non-negative integer in bash create-new-feature (clear error instead of cryptic shell arithmetic failure) - Route PowerShell no-git warning to stderr in JSON mode so stdout stays valid JSON --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com> |
||
|
|
aad6f68ae5 |
Upgraded confluence extension to v.1.1.1 (#2109)
Co-authored-by: Aaron Sun <aaronsun@Mac.hsd1.wa.comcast.net> |
||
|
|
473a441720 |
Update V-Model Extension Pack to v0.5.0 (#2108)
- version: 0.4.0 → 0.5.0 - download_url: v0.4.0 tag → v0.5.0 tag - commands: 9 → 14 - updated_at: 2026-04-06 |
||
|
|
55ff148475 |
Add canon extension and canon-core preset. (#2022)
* Add canon extension and canon-core preset. * fix: correct branch and link references for spec-kit-canon catalog entries - Fix documentation/changelog URLs using `main` → `master` branch in extension and preset catalogs - Fix preset display link label from `spec-kit-canon-core` → `spec-kit-canon` in README * chore: refresh community catalog timestamps * chore: refresh canon extension command count * chore: point canon catalog entries to repo root instead of subdirectories --------- Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com> |
||
|
|
7f08f31286 |
[stage2] fix: serialize multiline descriptions in legacy TOML renderer (#2097)
* fix: preserve multiline descriptions in legacy toml renderer * refactor: reuse toml escape helper for prompt fallback |
||
|
|
8b099585c7 |
[stage1] fix: strip YAML frontmatter from TOML integration prompts (#2096)
* fix: correct toml integration frontmatter handling * refactor: reuse frontmatter split in toml integration * fix: preserve toml integration string semantics * docs: align toml integration renderer docstring |
||
|
|
9c0be46006 |
Add Confluence extension (#2028)
* Add Confluence extension * Updated latest available version to v.1.1.0 --------- Co-authored-by: Aaron Sun <aaronsun@mac.lan> |
||
|
|
f92e7e8096 |
fix: accept 4+ digit spec numbers in tests and docs (#2094)
Two test assertions in test_timestamp_branches.py used the regex
`\d{3}` (exactly 3 digits) instead of `\d{3,}` (3 or more digits).
While the underlying shell scripts already handle spec numbers ≥ 1000
correctly — printf "%03d" and PowerShell '{0:000}' both expand naturally
beyond 3 digits, and all detection regexes use {3,} — the overly-strict
test assertions would fail with a misleading error if a fixture ever
contained 1000+ spec directories.
Documentation in README.md, spec-driven.md, and the CLI --branch-numbering
help text implied that sequential spec numbers are always 3 digits, which
could lead users to believe a hard limit of 999 exists.
Changes:
- tests/test_timestamp_branches.py: change two \d{3} assertions to \d{3,}
- src/specify_cli/__init__.py: clarify help text to show numbers expand past 999
- README.md: update --branch-numbering docs to note numbers expand beyond 3 digits
- spec-driven.md: update feature numbering description to include 4-digit example
Fixes #2093
Co-authored-by: alex-zwingli <alex-zwingli@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
4178b61828 |
fix(scripts): improve git branch creation error handling (#2089)
* fix(scripts): improve git branch creation error handling - Capture git checkout -b stderr for meaningful error reporting - Skip redundant checkout when already on target branch - Surface actual git error messages instead of generic fallback Applies to both bash and PowerShell create-new-feature scripts. * fix(scripts): improve git branch creation error handling - Capture git checkout -b stderr for meaningful error reporting - Skip redundant checkout when already on target branch - Surface actual git error messages instead of generic fallback Applies to both bash and PowerShell create-new-feature scripts. * fix(scripts): use quiet mode for git checkout -b when capturing errors Ensures branch_create_error is empty on success, matching variable semantics. |
||
|
|
d9e63a51f1 |
Add optimize extension to community catalog (#2088)
- Extension ID: optimize - Version: 1.0.0 - Author: sakitA - Description: Audits and optimizes AI governance for context efficiency |
||
|
|
7dc493e613 |
feat: add "VS Code Ask Questions" preset (#2086)
* feat: add "VS Code Ask Questions" preset for enhanced interactive questioning * fix: address PR review feedback from Copilot |
||
|
|
5678ca7757 |
Add security-review v1.1.1 to community extensions catalog (#2073)
* Add security-review v1.1.0 to community catalog
* Format README and community catalog entries
* Set security-review author to DyanGalih
* Update extensions/catalog.community.json
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Bump security-review to v1.1.1
* 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>
* Fix linting: use asterisk emphasis, fix architecuture typo
* Revert "Format README and community catalog entries"
This reverts commit
|
||
|
|
94ba857b78 |
Add specify integration subcommand for post-init integration management (#2083)
* Initial plan * Add specify integration subcommand (list, install, uninstall, switch) Implements the `specify integration` subcommand group for managing integrations in existing projects after initial setup: - `specify integration list` — shows available integrations and installed status - `specify integration install <key>` — installs an integration into existing project - `specify integration uninstall [key]` — hash-safe removal preserving modified files - `specify integration switch <target>` — uninstalls current, installs target Follows the established `specify <noun> <verb>` CLI pattern used by extensions and presets. Shared infrastructure (scripts, templates) is preserved during uninstall and switch operations. Agent-Logs-Url: https://github.com/github/spec-kit/sessions/1cca6c84-3e12-465d-88b8-a646d3504f63 Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Address review feedback: extract helper, fix return type annotation - Extract _update_init_options_for_integration() to deduplicate init-options update logic between install and switch commands - Fix _parse_integration_options return type to dict[str, Any] | None Agent-Logs-Url: https://github.com/github/spec-kit/sessions/1cca6c84-3e12-465d-88b8-a646d3504f63 Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * Potential fix for pull request finding 'Unused import' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * Address review feedback: validate script type, handle --flag=value, fix metadata cleanup - Add _normalize_script_type() to validate script type against SCRIPT_TYPE_CHOICES - Handle --name=value syntax in _parse_integration_options() - Clear init-options.json keys in no-manifest uninstall early-return path - Clear stale metadata between switch teardown and install phases - Add 5 tests covering the new edge cases * Block --force with different integration, persist script type in init-options - --force on install now rejects overwriting a different integration; users must use 'specify integration switch' instead - _update_init_options_for_integration() now accepts and persists script_type - Fix misleading test docstring for switch metadata test - Add test_force_blocked_with_different_integration * Remove --force from integration install, ensure shared infra on install/switch - Remove --force parameter entirely from integration install; users must uninstall before reinstalling to prevent orphaned files - Auto-install shared infrastructure (.specify/scripts/, .specify/templates/) when missing during install or switch - Add test for shared infra creation on bare project install * Remove redundant installed_key != key check The == key case already returns above, so the != key guard is always true at this point. Simplify to just 'if installed_key:'. * Run shared infra unconditionally, defer metadata removal in switch - Call _install_shared_infra() unconditionally on install and switch since it merges without overwriting existing files - Remove premature metadata cleanup between switch phases; metadata is now only updated after successful Phase 2 install * Add install rollback, graceful manifest errors, clear switch metadata - Attempt teardown rollback on install/switch failure to avoid orphaned files - Catch ValueError/FileNotFoundError on IntegrationManifest.load() in uninstall with user-friendly recovery guidance - Clear metadata immediately after switch teardown so failed Phase 2 doesn't leave stale references to the removed integration * Log rollback failures instead of silently suppressing them * Handle corrupt manifest in switch, distinguish unknown vs missing manifest - Wrap IntegrationManifest.load() in switch with ValueError/FileNotFoundError handling, matching the pattern used in uninstall - Split else branch to report 'unknown integration' vs 'no manifest' separately * Clean up metadata on rollback, broaden init-options match in uninstall - Remove integration.json in install/switch rollback paths so failed installs don't leave stale metadata - Match on both 'integration' and 'ai' keys when clearing init-options.json during uninstall to handle partially-written metadata * Fix recovery guidance for unreadable manifests, fix type annotations - Recovery instructions now guide users through delete manifest → uninstall → reinstall workflow that actually works - Type annotations for optional CLI parameters changed from str to str | None * Allow manifest-only uninstall for unknown/removed integrations - Uninstall no longer requires the integration to be in the registry; falls back to manifest.uninstall() directly when get_integration() returns None - Switch Phase 1 similarly uses manifest-only uninstall for unknown integrations instead of skipping teardown, preventing orphaned files * Fail fast on corrupt integration.json, validate integration options - _read_integration_json() now exits with an actionable error when integration.json exists but is corrupt/unreadable - _parse_integration_options() rejects unknown options, validates flag usage, and requires values for non-flag options * Validate integration.json is a dict, fail fast on missing manifest in switch - _read_integration_json() validates parsed JSON is a dict, not a list/string - Switch fails fast with recovery guidance when manifest is missing instead of silently skipping teardown and risking co-existing integration files --------- 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> |
||
|
|
e1ab4f0486 |
Remove template version info from CLI, fix Claude user-invocable, cleanup dead code (#2081)
* Remove Template Version and Released from version output Templates are now bundled with the CLI, so showing them as separate artifacts with their own version and release date is no longer accurate. This also removes the GitHub API call that fetched the latest release, making the version command faster and eliminating a network dependency. * Remove unused datetime import * fix: inject user-invocable: true into Claude skill frontmatter The SkillsIntegration.setup() builds frontmatter manually without user-invocable. Add post-processing injection in ClaudeIntegration.setup(), matching the existing pattern for disable-model-invocation. * refactor: address review feedback - Factor _inject_user_invocable and _inject_disable_model_invocation into a shared _inject_frontmatter_flag(key, value) helper - Remove unused httpx, ssl, truststore imports and globals - Remove unused _github_token and _github_auth_headers helpers - Update setup() docstring to mention user-invocable * chore: remove httpx and truststore from dependencies Both are no longer used after removing the GitHub API call from the version command. Removes from PEP 723 script header and pyproject.toml. * fix: match EOL detection style in _inject_frontmatter_flag Handle \r\n, \n, and no-newline cases consistently with inject_argument_hint's pattern. |
||
|
|
535ddbe0d2 |
fix: add user-invocable: true to skill frontmatter (#2077)
Skills were missing this field, causing them to be treated as "managed" instead of user-invocable via /speckit-* commands. |
||
|
|
8353830f97 |
fix: add actions:write permission to stale workflow (#2079)
The actions/stale@v10 action uses GitHub Actions cache to persist state across runs. Without the actions:write permission, the action can write cache entries but cannot delete them (403 error on cache cleanup). This causes a vicious cycle: once an issue is processed and cached, the action skips it on every future run with 'issue skipped due being processed during the previous run' - so stale issues never reach the closing logic after being marked stale. Adding actions:write allows the action to properly manage its cache lifecycle, enabling stale issues to be closed after the configured 30-day close window. |
||
|
|
10be484868 |
feat: add argument-hint frontmatter to Claude Code commands (#1951) (#2059)
* feat: add argument-hint frontmatter to Claude Code commands (#1951) Inject argument-hint into YAML frontmatter for Claude agent only during release package generation. Templates remain agent-agnostic; hints are added on the fly in generate_commands() when agent is "claude". Closes #1951 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: scope argument-hint injection to YAML frontmatter only Addresses Copilot review: the awk/regex matched description: anywhere in the file. Now both bash and PowerShell track frontmatter boundaries (--- delimiters) and only inject argument-hint after the first description: inside the frontmatter block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add argument-hint to Claude integration + tests - Override setup() in ClaudeIntegration to inject argument-hint into YAML frontmatter after description: line, scoped to frontmatter only - Add ARGUMENT_HINTS mapping for all 9 commands - Add tests: hint presence, correct values, frontmatter scoping, ordering after description, and body-safety check Addresses maintainer feedback to cover the new integrations system in src/specify_cli/integrations/claude/__init__.py with tests in tests/integrations/test_integration_claude.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: address Copilot review feedback on Claude integration - Remove unused `import re` - Skip injection if argument-hint already exists in frontmatter - Add found_description assertion to test_hint_appears_after_description - Add test_inject_argument_hint_skips_if_already_present test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor: delegate to super().setup() and post-process for hints - Eliminates setup() duplication by calling super().setup() then post-processing command files to inject argument-hint - Fixes EOL preservation to correctly detect \r\n vs \n - No drift risk if MarkdownIntegration.setup() changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: use read_bytes/write_bytes for platform-stable EOL handling Address Copilot review: avoid platform newline translation by using read_bytes()/write_bytes() instead of read_text()/write_text() when post-processing SKILL.md files for argument-hint injection. * fix: re-record manifest hash after hint injection, quote hint values - Re-record file hash in manifest after writing argument-hint so check_modified()/uninstall stays in sync - Double-quote argument-hint values to match SKILL.md frontmatter style - Update tests to expect quoted hint values * fix: inject disable-model-invocation into Claude skill frontmatter --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
48b84cc941 | Update conduct extension to v1.0.1 (#2078) | ||
|
|
fac8e59c02 |
chore(deps): bump astral-sh/setup-uv from 7.6.0 to 8.0.0 (#2072)
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.6.0 to 8.0.0. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/37802adc94f370d6bfd71619e3f0bf239e1f3b78...cec208311dfd045dd5311c1add060b2062131d57) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 8.0.0 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> |
||
|
|
87c9e1ce75 |
chore(deps): bump actions/configure-pages from 5 to 6 (#2071)
Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 5 to 6. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-version: '6' 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> |
||
|
|
d40c9a6428 |
feat: add spec-kit-fixit extension to community catalog (#2024)
* feat: add spec-kit-fixit extension to community catalog * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix catalog format --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
cb508d7a36 |
chore: release 0.5.0, begin 0.5.1.dev0 development (#2070)
* chore: bump version to 0.5.0 * chore: begin 0.5.1.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
b8e7851234 |
feat: add Forgecode agent support (#2034)
* feat: add Forgecode (forge) agent support
- Add 'forgecode' to AGENT_CONFIGS in agents.py with .forge/commands
directory, markdown format, and {{parameters}} argument placeholder
- Add 'forgecode' to AGENT_CONFIG in __init__.py with .forge/ folder,
install URL, and requires_cli=True
- Add forgecode binary check in check_tool() mapping agent key
'forgecode' to the actual 'forge' CLI binary
- Add forgecode case to build_variant() in create-release-packages.sh
generating commands into .forge/commands/ with {{parameters}}
- Add forgecode to ALL_AGENTS in create-release-packages.sh
* fix: strip handoffs frontmatter and replace $ARGUMENTS for forgecode
The forgecode agent hangs when listing commands because the 'handoffs'
frontmatter field (a Claude Code-specific feature) contains 'send: true'
entries that forge tries to act on when indexing .forge/commands/ files.
Additionally, $ARGUMENTS in command bodies was never replaced with
{{parameters}}, so user input was not passed through to commands.
Python path (agents.py):
- Add strip_frontmatter_keys: [handoffs] to the forgecode AGENT_CONFIG
entry so register_commands drops the key before rendering
Bash path (create-release-packages.sh):
- Add extra_strip_key parameter to generate_commands; pass 'handoffs'
for the forgecode case in build_variant
- Use regex prefix match (~ "^"extra_key":") instead of exact
equality to handle trailing whitespace after the YAML key
- Add sed replacement of $ARGUMENTS -> $arg_format in the body
pipeline so {{parameters}} is substituted in forgecode command files
* feat: add name field injection for forgecode agent
Forgecode requires both 'name' and 'description' fields in command
frontmatter. This commit adds automatic injection of the 'name' field
during command generation for forgecode.
Changes:
- Python (agents.py): Add inject_name: True to forgecode config and
implement name injection logic in register_commands
- Bash (create-release-packages.sh): Add post-processing step to inject
name field into frontmatter after command generation
This complements the existing handoffs stripping fix (
|
||
|
|
08f69e3d3e |
Introduces DEVELOPMENT.md (#2069)
* Create DEVELOPMENT.md outline * AI-generated DEVELOPMENT.md draft * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Create Untitled 2.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Compact DEVELOPMENT.md * Create DEVELOPMENT.md outline * AI-generated DEVELOPMENT.md draft * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Create Untitled 2.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Update DEVELOPMENT.md * Compact DEVELOPMENT.md * Update DEVELOPMENT.md |
||
|
|
c8ccb0609d |
Update cc-sdd reference to cc-spex in Community Friends (#2007)
The cc-sdd project has been renamed to cc-spex (v3.0.0).
Assisted-By: 🤖 Claude Code
|
||
|
|
663d679f3b |
chore: release 0.4.5, begin 0.4.6.dev0 development (#2064)
* chore: bump version to 0.4.5 * chore: begin 0.4.6.dev0 development --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
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]. |
||
|
|
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 |
||
|
|
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> |
||
|
|
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 |
||
|
|
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 |
||
|
|
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>
|
||
|
|
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 |