Commit Graph

20 Commits

Author SHA1 Message Date
김준호
ac2cb5daf5 feat(cli): implement specify self upgrade (#2475)
* feat(cli): implement specify self upgrade

* fix(cli): normalize self-upgrade prerelease tags

* fix(cli): tighten self-upgrade diagnostics

* fix(cli): harden self-upgrade verification parsing

* fix(cli): sanitize self-check fallback tags

* fix(cli): harden self-check release display

* fix(cli): validate resolved upgrade tags

* fix(cli): tolerate invalid install metadata

* test(cli): align upgrade network mocks

* fix(cli): respect relative installer paths

* fix(cli): tighten upgrade failure handling

* fix(cli): align installer path diagnostics

* fix(cli): validate release and version output

* fix(cli): clarify source checkout guidance

* fix(cli): harden upgrade detection helpers

* fix(cli): avoid echoing invalid release tags

* fix(cli): tolerate argv path resolve failures

* chore: remove self-upgrade formatting-only diffs

* fix: address self-upgrade review feedback

* fix: address self-upgrade review followups

* fix: address self-upgrade review edge cases

* fix: address self-upgrade review docs

* fix: refine self-upgrade review followups

* fix: address self-upgrade review cleanup

* fix: handle self-upgrade review edge cases

* fix: address self-upgrade review nits

* fix: address follow-up self-upgrade review

* fix: resolve self-upgrade review and Windows CI failures

- README: promote "Optional Commands" to ### so it is a sibling of
  "Core Commands" under "Available Slash Commands" (consistent heading
  levels; avoids the h2->h4 jump a revert would create).
- _version: allow --tag prerelease/dev and build-metadata suffixes to
  compose (e.g. v1.0.0-rc1+build.42), matching PEP 440 / semver; the
  Version() check still enforces canonical validity.
- tests: compare resolved argv0 as Path objects instead of POSIX strings
  so the assertion holds on Windows; skip the relative-installer-path
  executable-bit tests on Windows via a new requires_posix marker (they
  rely on chmod/X_OK semantics and chdir-into-tmp teardown that do not
  hold there). Add a combined prerelease+build-metadata tag test.

* fix: address second self-upgrade review round

- self_check: clarify that the "up to date" branch is reached only for
  parseable latest tags (the unparseable case returns earlier), so the
  InvalidVersion fallback assumption is not reintroduced.
- self_upgrade: compare target/current as Version instances directly
  instead of re-parsing the canonical strings through _is_newer; the
  empty-current case stays explicit via the not-None guard.
- tests: document the intentional broad GH_/GITHUB_ env scrub with a test
  asserting non-credential context vars (GH_HOST, GITHUB_REPOSITORY, …) are
  stripped from the installer subprocess env — a deliberate fail-safe that
  also catches credential-adjacent names without a recognized suffix.

* fix: address third self-upgrade review round

- self_upgrade: unify the no-op short-circuits on packaging Version
  equality instead of canonical-string equality. Version("1.0") equals
  Version("1.0.0") but their str() forms differ, so the old check could
  misreport an equal install as "already on latest release or newer".
  Both the unpinned and pinned branches now use Version comparison.
- self_upgrade: compare the verified version as a parsed Version against
  the target so a non-version verifier result is a mismatch (exit 2)
  rather than a coincidental canonical-string match.
- resolver: map HTTP 429 (Too Many Requests / secondary rate limit) to
  the rate-limited category so users get the same actionable token hint
  as 403.
- _is_github_credential_env_key: document the precise (intentionally
  broad) scrub matching contract in the docstring.
- tests: add a trailing-zero Version-equality regression test and a
  parametrized HTTP-status categorization test (429 -> rate limited;
  404/502 -> verbatim).

* fix: address fourth self-upgrade review round

- self_upgrade: label a pinned target older than the installed version as
  "Downgrading" rather than "Upgrading" so `--tag <older>` is not mistaken
  for a forward upgrade.
- resolver: drop the unused `typing.Optional` import and annotate the
  `--tag` option as `str | None`, consistent with the rest of the module
  (verified Typer resolves it on the supported Python versions).
- _is_github_credential_env_key: add `_PASSWORD` and `_CREDENTIALS` to the
  recognized credential suffixes and document that only these shapes are
  scrubbed (not blanket coverage).
- tests: assert the precise exit code (1) for the re-raised transient
  OSError path; skip the InvalidMetadataError test on Pythons where the
  real exception is absent instead of fabricating it; update the pinned
  downgrade test to expect the "Downgrading" label.

* fix: accept uppercase V prefix in --tag

Fold a leading uppercase `V` (a common paste) to the canonical lowercase
`v` before validating `--tag`. The remainder of the tag stays
case-sensitive on purpose: the validated value is used verbatim as a git
ref, which is case-sensitive on GitHub, so rewriting label/build-metadata
casing could point at a tag that does not exist. Adds a normalization test.
2026-06-03 12:04:54 -05:00
Jaimin
d116ce2b0a docs: fix broken pipx homepage URLs to point to pipx.pypa.io (#2670) 2026-05-27 07:10:38 -05:00
darion-yaphet
6322a4d429 docs: fix script name in directory tree examples (#2555)
* docs: fix script name in directory tree examples

Replace update-claude-md.sh with the actual filename setup-tasks.sh
in two directory tree examples (Steps 2 and 4 of the detailed walkthrough).

* docs: fix .specify/scripts layout to show bash/ and powershell/ subdirs

install_shared_infra() installs scripts under .specify/scripts/bash/
(script_type="sh") or .specify/scripts/powershell/ (script_type="ps"),
not directly under .specify/scripts/. Update docs/installation.md and
the _install_shared_infra docstring to reflect the actual on-disk layout.

* docs: update README tree examples to show scripts/bash/ subdirectory

Scripts are installed under .specify/scripts/bash/ (or powershell/)
not directly under .specify/scripts/. Fix both tree diagrams in the
Detailed Process walkthrough to match the actual on-disk layout.
2026-05-14 15:14:52 -05:00
Manfred Riem
707e929c2a docs: streamline install section and add community overview (#2561)
- Shorten README.md install section to single uv command + link to
  installation guide for alternatives and troubleshooting
- Add explicit 'Initialize a project' step to README Get Started
- Remove duplicate Troubleshooting section from README
- Reorder 'Make it your own' card on docs landing page so extensions
  and presets are explained before the stats
- Update Community nav-card to link to new community overview
- Create docs/community/overview.md landing page (aligned with
  reference/overview.md)
- Create dedicated install sub-pages: pipx, one-time (uvx), air-gapped
- Update docs/installation.md to lead with persistent uv install and
  link to sub-pages instead of duplicating content
- Update docs/toc.yml with new pages
- Remove stale EOF file
2026-05-14 10:14:32 -05:00
Copilot
38bb88bde1 docs: Add uv installation guide and inline callouts (#2465)
* Initial plan

* docs: Add uv installation guide and inline callouts

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/027c81a0-57f2-4f67-ab54-4c72f93eb254

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>

* docs: improve uv install guide PATH and Windows instructions

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/f56bcfb8-2cf5-44a5-b5e5-0fd6c3caa46f

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>

* docs: clarify uv note in README applies only to uv commands not pipx

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/a6ada1f7-522d-4a31-ac5b-880e763f9c97

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>

* docs: clarify uv note in installation.md applies only to uvx commands not pipx

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/4ec791dd-b048-4606-8db3-671bc8956b05

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>
2026-05-06 15:05:14 -05:00
Andrii Furmanets
2d5e63005d fix: default non-interactive init to copilot integration (#2414)
* fix: default non-interactive init integration

* chore: clarify non-interactive init default integration

* Address non-interactive init review feedback

* Fix interactive init test after fallback
2026-05-06 12:48:50 -05:00
Manfred Riem
171b65ac33 docs: replace deprecated --ai flag with --integration in all documentation (#2359)
* docs: replace deprecated --ai flag with --integration in all documentation

Replace all user-facing --ai, --ai-skills, and --ai-commands-dir references
with their modern equivalents:

- --ai <agent> → --integration <agent>
- --ai-skills → --integration-options="--skills"
- --ai-commands-dir <dir> → --integration generic --integration-options="--commands-dir <dir>"

Updated files:
- README.md (~17 occurrences)
- docs/installation.md (~8 occurrences)
- docs/upgrade.md (~11 occurrences)
- docs/local-development.md (~5 occurrences)
- CONTRIBUTING.md (1 occurrence)
- extensions/EXTENSION-USER-GUIDE.md (1 occurrence)
- src/specify_cli/__init__.py (docstring examples and error messages)

Left unchanged:
- CHANGELOG.md (historical record)
- Test files (intentionally exercise deprecated flag path)
- CLI flag implementation (backward compatibility)

Closes #2358

* docs: address review feedback on pre-existing issues

- Fix duplicate copilot example in README.md (replace with codex)
- Fix invalid gemini --integration-options="--skills" example (gemini
  does not support --skills)
- Update generic integration comment from 'Unsupported agent' to
  'Bring your own agent; requires --commands-dir'
- Clarify EXTENSION-USER-GUIDE.md: skills auto-register for
  skills-based integrations, not only with --integration-options

* docs: replace bare 'AI agent' / 'AI assistant' with 'coding agent' throughout

Full sweep across all documentation and user-facing CLI messages to
align terminology. Bare references like 'AI agent', 'AI assistant',
and 'AI Agent' are replaced with 'coding agent' or 'coding agent
integration' as appropriate.

Intentionally left unchanged:
- 'AI coding agent' (already correct expanded form)
- Deprecated --ai flag help text and error messages (describes the
  deprecated flag itself)
- Community extension descriptions (external project text)
- 'generated by an AI' in CONTRIBUTING.md (general AI, not agent)

* docs: address review — remove deprecated --offline, qualify --skills scope

- Remove --offline from docstring examples (deprecated no-op)
- Remove --offline from CONTRIBUTING.md testing example
- Replace --offline instructions in docs/installation.md with note that
  bundled assets are used by default
- Qualify --integration-options="--skills" in README.md to note it only
  applies to integrations that support skills mode
2026-04-24 16:04:04 -05:00
sha0dow
b278d66b2c docs(install): add pipx as alternative installation method (#2288)
* docs(install): add pipx as alternative installation method

- Add pipx commands to README.md installation section
- Add note about pipx compatibility to docs/installation.md
- Mention pipx persistent installation in docs/quickstart.md
- Add pipx upgrade instructions to docs/upgrade.md
- Clarify that project has no uv-specific dependencies

Refs: https://github.com/github/spec-kit/discussions/2255

* docs(install): address Copilot feedback - update prerequisites and upgrade references for pipx

* Update docs/quickstart.md

markdownlint’s MD012 (enabled in this repo) flags multiple consecutive blank lines

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

* Update docs/upgrade.md

In the Quick Reference table, the label “pipx upgrade” is misleading because the command shown is `pipx install --force ...` (a reinstall). by copilot.

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-23 08:12:17 -05:00
Michal Bachorik
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 4deb90f (fix: restore alias compatibility, #2110/#2125).

Only type and None-normalization checks remain for aliases. Pattern
enforcement continues for primary command names only.

Updated tests to verify free-form aliases pass through unchanged with
no warnings instead of being auto-corrected.

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

* fix(extensions): guard against non-dict command entries in _validate()

If provides.commands contains a non-mapping entry (e.g. an int or string),
'name' not in cmd raises TypeError instead of a user-facing ValidationError.
Added isinstance(cmd, dict) check at the top of the loop.

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

---------

Co-authored-by: iamaeroplane <michal.bachorik@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-15 07:35:49 -05:00
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
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
Benjamin Pahl
33a07969c3 feat(ci): add markdownlint-cli2 for consistent markdown formatting
Add automated markdown linting to ensure consistent formatting across
all markdown files in the repository.

Changes:
- Add .markdownlint-cli2.jsonc configuration
- Create .github/workflows/lint.yml for CI/CD integration
- Fix all 908 existing markdown errors across 27 files
- Enforce ATX-style headings and asterisk emphasis
- Set consistent 2-space list indentation

This prevents markdown errors after project initialization and
maintains high documentation quality standards.
2025-10-20 00:49:15 +02:00
Den Delimarsky
3b000fce4d Merge pull request #881 from github/localden/fixes
Updates to templates and scripts
2025-10-15 10:56:49 -07:00
root
0cca67fcd2 Update AI coding agent references in installation guide 2025-10-15 21:47:36 +08:00
den (work)
36ff7e6505 Update files 2025-10-14 11:52:26 -07:00
den (work)
15e5572a1d Update command reference 2025-10-06 22:16:48 -07:00
Bruno Borges
68eba52a40 feat: support 'specify init .' for current directory initialization
Adds '.' as shorthand equivalent to --here flag while maintaining
full backward compatibility. Updates documentation and bumps to v0.0.18.
2025-09-24 22:41:50 -07:00
Den Delimarsky 🌺
5787bb5537 Refactor with platform-specific constraints 2025-09-12 10:27:43 -07:00
Den Delimarsky 🌺
fd61b8742d Update docs and release 2025-09-08 23:21:12 -07:00
Den Delimarsky 🌺
4b98c20f5d Docs setup 2025-09-08 23:14:53 -07:00