The add-community-extension and add-community-preset agentic workflows
never ran for real submissions. Their issue templates auto-applied the
`extension-submission`/`preset-submission` label at creation, which lands
in the `opened` event (not `labeled`), and the external submitter fails
the team-membership activation gate.
Align both with the working bug-assess pattern:
- Add `names: [extension-submission]` / `[preset-submission]` so a
job-level condition gates activation on the specific label.
- Add `github: min-integrity: none` to allow reading external user issues.
- Remove the trigger label from the issue-template auto-labels so a
maintainer applies it during triage — emitting a real `labeled` event
from a team member, which passes activation.
- Recompile lock files with gh aw v0.79.8.
Co-authored-by: Manfred Riem <mnriem@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The committed lock file declared compiler v0.79.8 but contained a github
allow-only guard policy with `"repos": "${GITHUB_REPOSITORY}"`. MCP Gateway
v0.3.25 rejects repo-specific values ("allow-only.repos string must be 'all'
or 'public'"), so the agent job failed at "Start MCP Gateway":
failed to register guard for server "github": invalid server guard policy:
allow-only.repos string must be 'all' or 'public'
Recompiling bug-assess.md with gh-aw v0.79.8 deterministically emits
`"repos": "all"` (the gateway-accepted default when min-integrity is set
without an explicit repos scope), confirming the committed lock was stale.
This also reconciles the manifest setup-action SHA with the value already
used in the workflow body.
Co-authored-by: Manfred Riem <mnriem@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add bug-assess agentic workflow
Add a gh-aw agentic workflow that triggers when an issue is labeled
`bug-assess`. It assesses the report against the codebase (symptom, suspected
code paths, verdict, severity, remediation) and posts the full assessment.md as
an issue comment, led by a one-line valid?/priority summary. It also applies
severity / needs-reproduction / invalid triage labels.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: disable noop report-as-issue for bug-assess workflow
Set safe-outputs.noop.report-as-issue: false so noop runs on
failures/timeouts no longer create extra report issues, keeping
outputs limited to the issue comment and triage labels.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: clarify bug-assess label filtering is job-level
Reword the Triggering Conditions paragraph to reflect that the
issues:labeled trigger fires for any label and the bug-assess
filtering happens via a job-level condition, not at the trigger.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: tighten bug-assess prompt guardrails
- Add a 65,000-char comment-size limit instruction with explicit
truncation marking so large reports don't fail the safe-outputs
validator.
- Clarify the read-only guardrail: scratch files allowed under
$RUNNER_TEMP, never write into the working tree or commit/push.
- Align the one-line summary verdict vocabulary (Invalid) with the
canonical 'invalid' verdict and Step 8 label rules.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: align bug-assess severity wording and recompile with v0.78.1
- Use 'severity' instead of 'priority' in the Step 7 one-line summary to
match Step 5, the Severity header field, and the severity-* labels.
- Clarify the read-only guardrail: comment + labels are the intended
outputs on success, while the gh-aw harness may separately emit
failure-report artifacts/issues when a run errors or times out.
- Recompile with gh-aw v0.78.1 so the gh-aw-actions/setup pin matches
the repo's other workflow lock files and actions-lock.json.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Manfred Riem <mnriem@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: add category and effect as first-class fields in extension schema
Add `category` and `effect` as optional fields in the extension schema
(`extension.yml`) and community catalog (`catalog.community.json`).
Schema changes:
- Valid categories: docs, code, process, integration, visibility
- Valid effects: read-only, read-write
- Both fields are optional (backward-compatible with existing extensions)
- Validation raises ValidationError for invalid values when present
Propagation:
- Added `category` and `effect` to all 108 entries in catalog.community.json
(populated from the existing docs/community/extensions.md table)
- Updated extension template with commented category/effect fields
- Updated add-community-extension skill with new JSON template fields
- Updated `specify extension info` CLI output to display category/effect
- Added properties to ExtensionManifest class
Tests:
- test_valid_category: all 5 category values pass
- test_valid_effect: both effect values pass
- test_invalid_category: invalid value raises ValidationError
- test_invalid_effect: invalid value raises ValidationError
- test_category_and_effect_optional: omitting fields still works
Closes#2874
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: make category free-form, keep effect validated
Category is a free-form string (only validated as non-empty when present),
while effect remains restricted to 'read-only' or 'read-write'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: address PR review feedback
- Add type guard before 'in' check for effect to prevent TypeError on
unhashable YAML values (list/dict)
- Comment out category/effect in template so authors must opt in
- Use VALID_EFFECTS constant in test instead of hard-coded values
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: update category docstring to reflect free-form semantics
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* docs: clarify canonical extension effect values
---------
Co-authored-by: Manfred Riem <mnriem@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Add noop: report-as-issue: false to safe-outputs frontmatter in both
add-community-extension and add-community-preset workflows to prevent
them from posting noise comments to the [aw] No-Op Runs tracking issue.
Closes#2747
Both add-community-preset and add-community-extension workflows previously
triggered on issues opened, edited, and labeled events. This caused them to
fire on every new issue and post noisy bot comments explaining the issue
wasn't a submission (see #2739).
Changes:
- Narrow trigger from [opened, edited, labeled] to [labeled] only
- Update prompt instructions to stop silently on non-matching issues
instead of posting a comment
* Add agentic workflows for community catalog submissions
Add GitHub Agentic Workflows that automatically process community
extension and preset submission issues:
- add-community-extension.md: triggered by extension-submission issues,
validates the submission, updates extensions/catalog.community.json
and docs/community/extensions.md, then opens a draft PR
- add-community-preset.md: parallel workflow for preset-submission
issues, updates presets/catalog.community.json and
docs/community/presets.md
Both workflows:
- Trigger on opened, edited, or labeled events (maintainers can
retroactively label pre-existing issues)
- Validate ID format, semver, repo existence, required files, release,
and submission checklists
- Label issues with validation-passed or validation-failed
- Create draft PRs with Closes #N for maintainer review
Also includes gh-aw scaffolding (.github/aw/, .gitattributes lock file
rule, dependabot ignore for gh-aw-actions).
* Suppress whitespace checks on generated .lock.yml files
These files are auto-generated by gh aw compile and contain trailing
whitespace in the ASCII art header and indented YAML blocks that we
cannot control. Add -whitespace attribute to skip git whitespace
checks on them.
* Add Agent Governance extension to community catalog
Add agent-governance extension submitted by @bigsmartben to:
- extensions/catalog.community.json (alphabetical order)
- README.md community extensions table
Closes#2552
* Move community extensions table from README to docs site
- Create docs/community/extensions.md with full extensions table
- Replace ~120-line table in README.md with summary + link to docs site
- Add Extensions entry to docs/toc.yml under Community
- Update add-community-extension SKILL.md references
Simplify the community catalog submission flow to use issue templates
with manual maintainer review (no automation scripts or workflows).
- Add explicit CODEOWNERS entries for catalog.community.json files so
submissions are automatically assigned to a maintainer for review
- Improve preset submission template:
- Add 'Required Extensions' optional field
- Make 'Templates Provided' optional (supports command-only presets)
- Add 'Number of Scripts' optional field
The existing extension and preset issue templates already collect all
required catalog metadata. Maintainers review submissions and manually
update the catalog JSON files.
Closes#2400
* feat(integrations): add Devin for Terminal skills-based integration
- Register DevinIntegration as a SkillsIntegration with .devin/skills/ layout
- Add catalog entry, docs row, and supported-agents listing
- Display /speckit-<command> hyphen syntax in init "Next Steps" panel
(matches Claude/Cursor/Copilot skills mode, since Devin invokes skills
by directory name)
Closes#2346
* fix(devin): implement -p non-interactive dispatch; clarify skills comment
Addresses Copilot review on PR #2364:
- Override build_exec_args() in DevinIntegration to emit
'devin -p <prompt> [--model X]' for non-interactive text dispatch
(verified Devin CLI supports -p / --print). Returns None when
output_json=True since Devin has no structured-output flag, so
CommandStep workflows that require JSON cleanly raise
NotImplementedError instead of crashing on an unknown CLI flag.
requires_cli=True is retained for tool detection.
- Extend the skills-integrations enumeration comment in
specify_cli/__init__.py to include copilot and devin so the
comment matches the code below it.
* fix(devin): always return exec args; document plain-text stdout
Addresses third Copilot review comment on PR #2364.
Returning None from build_exec_args() when output_json=True
incorrectly used the codebase's IDE-only sentinel: workflow
CommandStep checks 'impl.build_exec_args("test") is None' to
detect non-dispatchable integrations (test_workflows.py exercises
this with WindsurfIntegration). The previous implementation made
Devin appear non-dispatchable to all command steps even though it
runs fine via 'devin -p'.
Always return the args list. When output_json is requested, Devin
is still dispatched and returns plain-text stdout instead of
structured JSON; the docstring documents this explicitly.
* docs(devin): include claude in skills-integrations enumeration comment
Addresses Copilot review on PR #2364: the comment listing skills
integrations omitted Claude, which is also a SkillsIntegration
subclass. Updated to keep the comment accurate for future readers.
* test(devin): add build_exec_args regression tests; bump catalog updated_at
Addresses Copilot review on PR #2364, per @mnriem's request to
'address the Copilot feedback, especially the testing ask':
- tests/integrations/test_integration_devin.py: add TestDevinBuildExecArgs
with three regression assertions:
* build_exec_args returns args (not the None IDE-only sentinel)
* --output-format is never emitted, regardless of output_json
* --model flag is passed through correctly
- integrations/catalog.json: bump top-level updated_at to reflect the
Devin entry addition so downstream catalog consumers can detect the
change reliably.
* ci: add windows-latest to test matrix
Add windows-latest to the pytest job OS matrix so tests run on both
Ubuntu and Windows for all Python versions.
Closes#2232
* test: skip bash-specific tests on Windows
Add sys.platform skip markers to all test classes and methods that
execute bash scripts via subprocess, so they are skipped on Windows
where bash is not available. Mixed classes with both bash and pwsh
tests have markers on individual bash methods only.
* test: fix 3 Windows-specific test failures
- test_manifest: use platform-appropriate absolute path (C:\ on Windows
vs /tmp on POSIX) since /tmp is not absolute on Windows
- test_extensions: add agent_scripts.ps entry and platform-conditional
assertions for codex skill fallback variant test
- test_timestamp_branches: use json.dumps() instead of f-string to
properly escape Windows backslash paths in feature.json
* test: extract requires_bash marker and fix PS test skip
Address PR review feedback:
- Define a reusable requires_bash marker in conftest.py and use it
across all 3 test files instead of repeating the skipif inline
- Move test_powershell_scanner_uses_long_tryparse_for_large_prefixes
into its own TestSequentialBranchPowerShell class so it is not
incorrectly skipped on Windows by the class-level bash marker
* test: use runtime bash check instead of platform check
Replace sys.platform == 'win32' with an actual bash invocation test
to handle environments where bash exists but is non-functional (e.g.,
WSL stub on Windows without an installed distro).
* test: reject WSL bash, accept only MSYS/MINGW on Windows
On Windows, verify uname -s reports MSYS, MINGW, or CYGWIN so the WSL
launcher (System32\bash.exe) is rejected — it cannot handle native
Windows paths used by test fixtures. Add SPECKIT_TEST_BASH=1 env var
escape hatch to force-enable bash tests in non-standard setups.
* ci: add comment explaining Windows bash test behavior
* test: early-reject WSL launcher, fix remaining f-string JSON
- Check resolved bash path for System32 before spawning any subprocess
to avoid WSL init prompts and timeout during test collection
- Convert remaining feature_json f-string writes to json.dumps() so
paths with backslashes produce valid JSON on Windows
* test: use bare 'bash' for detection to match test invocation
On Windows, subprocess.run(['bash', ...]) uses CreateProcess which
searches System32 before PATH — finding WSL bash even when
shutil.which('bash') returns Git-for-Windows. Probe with bare 'bash'
(same as test helpers) so the detection matches actual test behavior.
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.
* 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].
* chore: use PEP 440 .dev0 versions on main after releases
- Release-trigger workflow now adds a dev bump commit (X.Y.(Z+1).dev0)
on the release branch after tagging, so main gets the dev version
when the PR merges. The tag still points at the release commit.
- Set current pyproject.toml to 0.4.4.dev0.
- Replace broken release workflow badge with shields.io release badge.
* Update .github/workflows/release-trigger.yml
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* docs: correct specify extension add syntax to require extension name
The specify extension add command requires the extension name as a positional argument. Many documentation files incorrectly demonstrated using the --from flag without specifying the extension name first.
* feat: add superb extension to community catalog
Orchestrates obra/superpowers skills within the spec-kit SDD workflow.
* fix: link superb extension docs
Rename the Normalize-List parameter in create-release-packages.ps1 to avoid conflicting with PowerShell's automatic $input variable. This fixes Windows offline scaffolding when -Agents and -Scripts are passed.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
* chore: bump version to 0.4.2
* chore: clean up CHANGELOG and fix release workflow
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* 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>