Commit Graph

13 Commits

Author SHA1 Message Date
Manfred Riem
bf33980426 feat(cli): embed core pack in wheel for offline/air-gapped deployment (#1803)
* feat(cli): embed core pack in wheel + offline-first init (#1711, #1752)

Bundle templates, commands, and scripts inside the specify-cli wheel so
that `specify init` works without any network access by default.

Changes:
- pyproject.toml: add hatchling force-include for core_pack assets; bump
  version to 0.2.1
- __init__.py: add _locate_core_pack(), _generate_agent_commands() (Python
  port of generate_commands() shell function), and scaffold_from_core_pack();
  modify init() to scaffold from bundled assets by default; add --from-github
  flag to opt back in to the GitHub download path
- release.yml: build wheel during CI release job
- create-github-release.sh: attach .whl as a release asset
- docs/installation.md: add Enterprise/Air-Gapped Installation section
- README.md: add Option 3 enterprise install with accurate offline story

Closes #1711
Addresses #1752

* fix(tests): update kiro alias test for offline-first scaffold path

* feat(cli): invoke bundled release script at runtime for offline scaffold

- Embed release scripts (bash + PowerShell) in wheel via pyproject.toml
- Replace Python _generate_agent_commands() with subprocess invocation of
  the canonical create-release-packages.sh, guaranteeing byte-for-byte
  parity between 'specify init --offline' and GitHub release ZIPs
- Fix macOS bash 3.2 compat in release script: replace cp --parents,
  local -n (nameref), and mapfile with POSIX-safe alternatives
- Fix _TOML_AGENTS: remove qwen (uses markdown per release script)
- Rename --from-github to --offline (opt-in to bundled assets)
- Add _locate_release_script() for cross-platform script discovery
- Update tests: remove bash 4+/GNU coreutils requirements, handle
  Kimi directory-per-skill layout, 576 tests passing
- Update CHANGELOG and docs/installation.md

* Potential fix for pull request finding

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

* fix(offline): error out if --offline fails instead of falling back to network

- _locate_core_pack() docstring now accurately describes that it only
  finds wheel-bundled core_pack/; source-checkout fallback lives in callers
- init() --offline + no bundled assets now exits with a clear error
  (previously printed a warning and silently fell back to GitHub download)
- init() scaffold failure under --offline now exits with an error
  instead of retrying via download_and_extract_template

Addresses reviewer comment: https://github.com/github/spec-kit/pull/1803

* fix(offline): address PR review comments

- fix(shell): harden validate_subset against glob injection in case patterns
- fix(shell): make GENRELEASES_DIR overridable via env var for test isolation
- fix(cli): probe pwsh then powershell on Windows instead of hardcoding pwsh
- fix(cli): remove unreachable fallback branch when --offline fails
- fix(cli): improve --offline error message with common failure causes
- fix(release): move wheel build step after create-release-packages.sh
- fix(docs): add --offline to installation.md air-gapped example
- fix(tests): remove unused genreleases_dir param from _run_release_script
- fix(tests): rewrite parity test to run one agent at a time with isolated
  temp dirs, preventing cross-agent interference from rm -rf

* fix(offline): address second round of review comments

- fix(shell): replace case-pattern membership with explicit loop + == check
  for unambiguous glob-safety in validate_subset()
- fix(cli): require pwsh (PowerShell 7) only; drop powershell (PS5) fallback
  since the bundled script uses #requires -Version 7.0
- fix(cli): add bash and zip preflight checks in scaffold_from_core_pack()
  with clear error messages if either is missing
- fix(build): list individual template files in pyproject.toml force-include
  to avoid duplicating templates/commands/ in the wheel

* fix(offline): address third round of review comments

- Add 120s timeout to subprocess.run in scaffold_from_core_pack to prevent
  indefinite hangs during offline scaffolding
- Add test_pyproject_force_include_covers_all_templates to catch missing
  template files in wheel bundling
- Tighten kiro alias test to assert specific scaffold path (download vs offline)

* fix(offline): address Copilot review round 4

- fix(offline): use handle_vscode_settings() merge for --here --offline
  to prevent data loss on existing .vscode/settings.json
- fix(release): glob wheel filename in create-github-release.sh instead
  of hardcoding version, preventing upload failures on version mismatch
- docs(release): add comment noting pyproject.toml version is synced by
  release-trigger.yml before the tag is pushed

* fix(offline): address review round 5 + offline bundle ZIP

- fix(offline): pwsh-only, no powershell.exe fallback; clarify error message
- fix(offline): tighten _has_bundled to check scripts dir for source checkouts
- feat(release): build specify-bundle-v*.zip with all deps at release time
- feat(release): attach offline bundle ZIP to GitHub release assets
- docs: simplify air-gapped install to single ZIP download from releases
- docs: add Windows PowerShell 7+ (pwsh) requirement note

* fix(tests): session-scoped scaffold cache + timeout + dead code removal

- Add timeout=300 and returncode check to _run_release_script() to fail
  fast with clear output on script hangs or failures
- Remove unused import specify_cli, _SOURCE_TEMPLATES, bundled_project fixture
- Add session-scoped scaffolded_sh/scaffolded_ps fixtures that scaffold
  once per agent and reuse the output directory across all invariant tests
- Reduces test_core_pack_scaffold runtime from ~175s to ~51s (3.4x faster)
- Parity tests still scaffold independently for isolation

* fix(offline): remove wheel from release, update air-gapped docs to use pip download

* fix(tests): handle codex skills layout and iflow agent in scaffold tests

Codex now uses create_skills() with hyphenated separator (speckit-plan/SKILL.md)
instead of generate_commands(). Update _SKILL_AGENTS, _expected_ext, and
_list_command_files to handle both codex ('-') and kimi ('.') skill agents.
Also picks up iflow as a new testable agent automatically via AGENT_CONFIG.

* fix(offline): require wheel core_pack for --offline, remove source-checkout fallback

--offline now strictly requires _locate_core_pack() to find the wheel's
bundled core_pack/ directory. Source-checkout fallbacks are no longer
accepted at the init() level — if core_pack/ is missing, the CLI errors
out with a clear message pointing to the installation docs.

scaffold_from_core_pack() retains its internal source-checkout fallbacks
so parity tests can call it directly from a source checkout.

* fix(offline): remove stale [Unreleased] CHANGELOG section, scope httpx.Client to download path

- Remove entire [Unreleased] section — CHANGELOG is auto-generated at release
- Move httpx.Client into use_github branch with context manager so --offline
  path doesn't allocate an unused network client

* fix(offline): remove dead --from-github flag, fix typer.Exit handling, add page templates validation

- Remove unused --from-github CLI option and docstring example
- Add (typer.Exit, SystemExit) re-raise before broad except Exception
  to prevent duplicate error panel on offline scaffold failure
- Validate page templates directory exists in scaffold_from_core_pack()
  to fail fast on incomplete wheel installs
- Fix ruff lint: remove unused shutil import, remove f-prefix on
  strings without placeholders in test_core_pack_scaffold.py

* docs(offline): add v0.6.0 deprecation notice with rationale

- Help text: note bundled assets become default in v0.6.0
- Docstring: explain why GitHub download is being retired (no network
  dependency, no proxy/firewall issues, guaranteed version match)
- Runtime nudge: when bundled assets are available but user takes the
  GitHub download path, suggest --offline with rationale
- docs/installation.md: add deprecation notice with full rationale

* fix(offline): allow --offline in source checkouts, fix CHANGELOG truncation

- Simplify use_github logic: use_github = not offline (let
  scaffold_from_core_pack handle fallback to source-checkout paths)
- Remove hard-fail when core_pack/ is absent — scaffold_from_core_pack
  already falls back to repo-root templates/scripts/commands
- Fix truncated 'skill…' → 'skills' in CHANGELOG.md

* fix(offline): sandbox GENRELEASES_DIR and clean up on failure

- Pin GENRELEASES_DIR to temp dir in scaffold_from_core_pack() so a
  user-exported value cannot redirect output or cause rm -rf outside
  the sandbox
- Clean up partial project directory on --offline scaffold failure
  (same behavior as the GitHub-download failure path)

* fix(tests): use shutil.which for bash discovery, add ps parity tests

- _find_bash() now tries shutil.which('bash') first so non-standard
  install locations (Nix, custom CI images) are found
- Parametrize parity test over both 'sh' and 'ps' script types to
  ensure PowerShell variant stays byte-for-byte identical to release
  script output (353 scaffold tests, 810 total)

* fix(tests): parse pyproject.toml with tomllib, remove unused fixture

- Use tomllib to parse force-include keys from the actual TOML table
  instead of raw substring search (avoids false positives)
- Remove unused source_template_stems fixture from
  test_scaffold_command_dir_location

* fix: guard GENRELEASES_DIR against unsafe values, update docstring

- Add safety check in create-release-packages.sh: reject empty, '/',
  '.', '..' values for GENRELEASES_DIR before rm -rf
- Strip trailing slash to avoid path surprises
- Update scaffold_from_core_pack() docstring to accurately describe
  all failure modes (not just 'assets not found')

* fix: harden GENRELEASES_DIR guard, cache parity tests, safe iterdir

- Reject '..' path segments in GENRELEASES_DIR to prevent traversal
- Session-cache both scaffold and release-script results in parity
  tests — runtime drops from ~74s to ~45s (40% faster)
- Guard cmd_dir.iterdir() in assertion message against missing dirs

* fix(tests): exclude YAML frontmatter source metadata from path rewrite check

The codex and kimi SKILL.md files have 'source: templates/commands/...'
in their YAML frontmatter — this is provenance metadata, not a runtime
path that needs rewriting. Strip frontmatter before checking for bare
scripts/ and templates/ paths.

* fix(offline): surface scaffold failure detail in error output

When --offline scaffold fails, look up the tracker's 'scaffold' step
detail and print it alongside the generic error message so users see
the specific root cause (e.g. missing zip/pwsh, script stderr).

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-20 14:46:48 -05:00
Hamilton Snow
c8af730b14 feat: migrate Codex/agy init to native skills workflow (#1906)
* feat: migrate codex and agy to native skills flow

* fix: harden codex skill frontmatter and script fallback

* fix: clarify skills separator default expansion

* fix: rewrite agent_scripts paths for codex skills

* fix: align kimi guidance and platform-aware codex fallback
2026-03-19 09:00:41 -05:00
Greazly
1a21bdef01 Feature/spec kit add pi coding agent pullrequest (#1853)
* feat(ai): add native support for Pi coding agent by pi+gpt 5.4

* docs(pi): document MCP limitations for Pi agent

* fix: unitended kimi agent mention added to update-agent-context.ps1

* fix: address reviewer feedback

* Apply suggestions from code review

Changes in AGENTS.md weren't part of my PR, but the Copilot feedback seems to be correct is correct. I've doublechecked it with contents of test_agent_config_consistency.py and create-release-packages scripts

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-17 14:50:18 -05:00
darkglow-net
6644f69a96 fix(ai-skills): exclude non-speckit copilot agent markdown from skill… (#1867)
* fix(ai-skills): exclude non-speckit copilot agent markdown from skill generation

* Potential fix for pull request finding

Fix missing `.agent` filename suffix

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

* Fix test assertion speckit.plan.md to speckit.plan.agent


Fix test assertion speckit.plan.md to speckit.plan.agent

* Fix filter glob based on review suggestions

fix(ai-skills): normalize Copilot .agent template names and align template fallback filtering

* Add template glob for fallback directory

* GH Copilot Suggestions

Clarify comment regarding Copilot's use of templates in tests.
Add extra test assertion

* fix(ai-skills): normalize Copilot .agent templates and preserve fallback behavior

fix(ai-skills): handle Copilot .agent templates and fallback filtering

Normalize Copilot command template names by stripping the .agent suffix
when deriving skill names and metadata sources, so files like
speckit.plan.agent.md produce speckit-plan and map to plan.md metadata.

Also align Copilot template discovery with speckit.* filtering while
preserving fallback to templates/commands/ when .github/agents contains
only user-authored markdown files, and add regression coverage for both
non-speckit agent exclusion and fallback behavior.

* fix(ai-skills): ignore non-speckit markdown commands

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-17 10:25:18 -05:00
fuyongde
7562664fd1 fix: migrate Qwen Code CLI from TOML to Markdown format (#1589) (#1730)
* fix: migrate Qwen Code CLI from TOML to Markdown format (#1589)

Qwen Code CLI v0.10.0 deprecated TOML format and fully switched to
Markdown as the core format for configuration and interaction files.

- Update create-release-packages.sh: generate .md files with $ARGUMENTS
  instead of .toml files with {{args}} for qwen agent
- Update create-release-packages.ps1: same change for PowerShell script
- Update AGENTS.md: reflect Qwen's new Markdown format in docs and
  remove Qwen from TOML format section
- Update tests/test_ai_skills.py: add commands_dir_qwen fixture and
  tests covering Markdown-format skills installation for Qwen

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

* fix: update CommandRegistrar qwen config to Markdown format

extensions.py CommandRegistrar.AGENT_CONFIGS['qwen'] was still set to
TOML format, causing `specify extension` to write .toml files into
.qwen/commands, conflicting with Qwen Code CLI v0.10.0+ expectations.

- Change qwen format from toml to markdown
- Change qwen args from {{args}} to $ARGUMENTS
- Change qwen extension from .toml to .md
- Add test to assert qwen config is Markdown format

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 07:43:14 -05:00
Dhilip
976c9981a4 fix(cli): deprecate explicit command support for agy (#1798) (#1808)
* fix(cli): deprecate explicit command support for agy (#1798)

* docs(cli): add tests and docs for agy deprecation (#1798)

* fix: address review comments for agy deprecation

* fix: address round 2 review comments for agy deprecation

* fix: address round 3 review comments for agy deprecation

* fix: address round 4 review comments for agy deprecation

* fix: address round 5 review comments for agy deprecation

* docs: add inline contextual comments to explain agy deprecation

* docs: clarify historical context in agy deprecation docstring

* fix: correct skills path in deprecation comment and make test mock fully deterministic
2026-03-13 07:35:30 -05:00
Fanch Daniel
e56d37db8c feat: add Kimi Code CLI agent support (#1790)
* feat: add Kimi Code (kimi) CLI agent support

- Register kimi in AGENT_CONFIG with folder `.kimi/`, markdown format, requires_cli=True
- Register kimi in CommandRegistrar.AGENT_CONFIGS
- Add kimi to supported agents table in AGENTS.md and README.md
- Add kimi to release packaging scripts (bash and PowerShell)
- Add kimi CLI installation to devcontainer post-create script
- Add kimi support to update-agent-context scripts (bash and PowerShell)
- Add 4 consistency tests covering all kimi integration surfaces
- Bump version to 0.1.14 and update CHANGELOG

* fix: include .specify/templates/ and real command files in release ZIPs

- Copy real command files from templates/commands/ (with speckit. prefix)
  instead of generating stubs, so slash commands have actual content
- Add .specify/templates/ to every ZIP so ensure_constitution_from_template
  can find constitution-template.md on init
- Add .vscode/settings.json to every ZIP
- Having 3 top-level dirs prevents the extraction flatten heuristic from
  incorrectly stripping the agent config folder (.kimi/, .claude/, etc.)
- Bump version to 0.1.14.1

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

* fix(kimi): use .kimi/skills/<name>/SKILL.md structure for Kimi Code CLI

Kimi Code CLI uses a skills system, not flat command files:
- Skills live in .kimi/skills/<name>/SKILL.md (project-level)
- Invoked with /skill:<name> (e.g. /skill:speckit.specify)
- Each skill is a directory containing SKILL.md with YAML frontmatter

Changes:
- AGENT_CONFIG["kimi"]["commands_subdir"] = "skills" (was "commands")
- create-release-packages.sh: new create_kimi_skills() function creates
  skill directories with SKILL.md from real template content
- Bump version to 0.1.14.2

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

* fix(test): align kimi commands_subdir assertion with skills structure

* fix: use forward slashes for tabnine path in create-release-packages.ps1

* fix: align kimi to .kimi/skills convention and fix ARGUMENTS unbound variable

* fix: address PR review comments for kimi agent support

  - Fix VERSION_NO_V undefined variable in create-github-release.sh
  - Restore version $1 argument handling in create-release-packages.sh
  - Fix tabnine/vibe/generic cases calling undefined generate_commands
  - Align roo path .roo/rules -> .roo/commands with AGENT_CONFIG
  - Fix kimi extension to use per-skill SKILL.md directory structure
  - Add parent mkdir before dest_file.write_text for nested paths
  - Restore devcontainer tools removed by regression + add Kimi CLI
  - Strengthen test_kimi_in_powershell_validate_set assertion

* fix: restore release scripts and address all PR review comments

  - Restore create-release-packages.sh to original with full generate_commands/
    rewrite_paths logic; add kimi case using create_kimi_skills function
  - Restore create-release-packages.ps1 to original with full Generate-Commands/
    Rewrite-Paths logic; add kimi case using New-KimiSkills function
  - Restore create-github-release.sh to original with proper $1 argument
    handling and VERSION_NO_V; add kimi zip entries
  - Add test_ai_help_includes_kimi for consistency with other agents
  - Strengthen test_kimi_in_powershell_validate_set to check ValidateSet

* fix: address second round of PR review comments

  - Add __AGENT__ and {AGENT_SCRIPT} substitutions in create_kimi_skills (bash)
  - Add __AGENT__ and {AGENT_SCRIPT} substitutions in New-KimiSkills (PowerShell)
  - Replace curl|bash Kimi installer with pipx install kimi-cli in post-create.sh

* fix: align kimi skill naming and add extension registrar test

  - Fix install_ai_skills() to use speckit.<cmd> naming for kimi (dot
    separator) instead of speckit-<cmd>, matching /skill:speckit.<cmd>
    invocation convention and packaging scripts
  - Add test_kimi_in_extension_registrar to verify CommandRegistrar.AGENT_CONFIGS
    includes kimi with correct dir and SKILL.md extension

* fix(test): align kimi skill name assertion with dot-separator convention

  test_skills_install_for_all_agents now expects speckit.specify (dot) for
  kimi and speckit-specify (hyphen) for all other agents, matching the
  install_ai_skills() implementation added in the previous commit.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 07:57:18 -05:00
Pavel-tabnine
1df24f1953 Pavel/add tabnine cli support (#1503)
* feat: add Tabnine CLI agent support

Tabnine CLI is a Gemini fork that uses TOML commands with the
.tabnine/agent/ directory structure and TABNINE.md context files.

Changes:
- Add 'tabnine' to AGENT_CONFIG in __init__.py
- Update release scripts (bash + PowerShell) for TOML command generation
- Update agent context scripts (bash + PowerShell)
- Add to GitHub release packages
- Update README.md and AGENTS.md documentation
- Bump version to 0.1.14
- Add 8 new tests for cross-file consistency

* fix: add missing generic to agent-context script usage string
2026-03-09 14:04:02 -05:00
Medhat Galal
32c6e7f40c feat: add kiro-cli and AGENT_CONFIG consistency coverage (#1690)
* feat: add kiro-cli and AGENT_CONFIG consistency coverage

* fix: address PR feedback for kiro-cli migration

* test: assert init invocation result in --here mode test

* test: capture init result in here-mode command test

* chore: save local unapproved work in progress

* fix: resolve remaining PR1690 review threads

* Update src/specify_cli/__init__.py

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

* test: reduce brittleness in ai help alias assertion

* fix: resolve PR1690 ruff syntax regression

---------

Co-authored-by: Manfred Riem <15701806+mnriem@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-03 12:04:46 -06:00
Manfred Riem
3040d33c31 Fix parameter ordering issues in CLI (#1669)
* chore: bump version to v0.0.6 [skip ci]

* Fix parameter ordering issues in CLI (#1641)

- Add validation to detect when option flags are consumed as values
- Provide clear error messages with helpful hints and examples
- Add 5 comprehensive tests to prevent regressions
- Update CODEOWNERS to @mnriem
- Bump version to 0.1.6 with changelog entry

Fixes: #1641

* Fix ruff linting errors: remove f-string prefix from strings without placeholders

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-23 13:17:08 -06:00
Manfred Riem
6150f1e317 Add generic agent support with customizable command directories (#1639)
- Add --ai generic option for unsupported AI agents (bring your own agent)
- Require --ai-commands-dir to specify where agent reads commands from
- Generate Markdown commands with $ARGUMENTS format (compatible with most agents)
- Rebuild CHANGELOG from GitHub releases (last 10 releases)
- Align version to 0.1.3

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-20 11:05:38 -06:00
Manfred Riem
24d76b5d92 Add pytest and Python linting (ruff) to CI (#1637)
* feat: add GitHub Actions workflow for testing and linting Python code

* fix: resolve ruff lint errors in specify_cli

- Remove extraneous f-string prefixes (F541)
- Split multi-statement lines (E701, E702)
- Remove unused variable assignments (F841)
- Remove ruff format check from CI workflow (format-only PR to follow)

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

* fix: strip ANSI codes in ai-skills help text test

The Rich/Typer CLI injects ANSI escape codes into option names in
--help output, causing plain string matching to fail.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-19 16:21:58 -06:00
Manfred Riem
9402ebd00a Feat/ai skills (#1632)
* implement ai-skills command line switch

* fix: address review comments, remove breaking change for existing projects, add tests

* fix: review comments

* fix: review comments

* fix: review comments

* fix: review comments

* fix: review comments, add test cases for all the agents

* fix: review comments

* fix: review comments

* chore: trigger CI

* chore: trigger CodeQL

* ci: add CodeQL workflow for code scanning

* ci: add actions language to CodeQL workflow, disable default setup

---------

Co-authored-by: dhilipkumars <s.dhilipkumar@gmail.com>
2026-02-19 13:24:41 -06:00