mirror of
https://github.com/Fission-AI/OpenSpec.git
synced 2026-10-24 06:53:28 +08:00
@fission-ai/openspec@1.12.0
21
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cb5ae2cd16 |
ci: bump changesets/action from 1.9.0 to 2.1.1 in the github-actions group (#1746)
* ci: bump changesets/action in the github-actions group Bumps the github-actions group with 1 update: [changesets/action](https://github.com/changesets/action). Updates `changesets/action` from 1.9.0 to 2.1.1 - [Release notes](https://github.com/changesets/action/releases) - [Changelog](https://github.com/changesets/action/blob/main/CHANGELOG.md) - [Commits](https://github.com/changesets/action/compare/a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d...8488615a623b1b9c987934bb89eae8af6a946ac1) --- updated-dependencies: - dependency-name: changesets/action dependency-version: 2.1.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] <support@github.com> * fix(ci): complete changesets action v2 migration * fix(nix): invalidate pnpm dependency hash * fix(nix): use calculated dependency hash * fix(nix): refresh pnpm dependency hash --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Clay Good <hi@claygood.com> |
||
|
|
c5c38a7aca |
chore(deps-dev): bump eslint from 10.8.1 to 10.9.0 in the development-dependencies group (#1745)
* chore(deps-dev): bump eslint in the development-dependencies group Bumps the development-dependencies group with 1 update: [eslint](https://github.com/eslint/eslint). Updates `eslint` from 10.8.1 to 10.9.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.8.1...v10.9.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.9.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * chore(nix): refresh dependency hash * fix(nix): use calculated dependency hash --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Clay Good <hi@claygood.com> |
||
|
|
dd7cea3ffe |
feat(show): diff delta requirements against the main specs (#980)
* Proposed feature: openspec show --diff to see changed requirements more clearly * Implementation of the --diff feature, which led to some spec changes during implementation. * Update the proposal to be clearer. Thanks coderabbit * Fix a bug identified by coderabbit with excessive trimming, and add a testcase for it. * fix(show): harden --diff for review feedback Keeps `openspec show <change>` without `--diff` a raw proposal passthrough, reports when a change has no delta specs instead of returning silently, preserves the Reason/Migration body of a REMOVED requirement, and resolves main specs through the command's root so `--store <id>` diffs against that store. Text mode and JSON mode now render from one shared collection pass, the CLI tests drive argv arrays from a mkdtemp project instead of interpolated shell strings, `--diff` is registered for shell completions, and the stray package-lock.json is gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * build(deps): declare the diff dependency and refresh the flake hash Adds the `diff` runtime dependency that requirement-diff.ts imports, updates pnpm-lock.yaml, and regenerates the flake's pnpmDeps hash so `nix build` matches the new lockfile. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(show): diff nested capabilities too collectSpecDiffs enumerated only top-level directories under the change's specs/, so a nested capability (specs/<area>/<id>/spec.md) was skipped: text mode printed nothing for it and its MODIFIED deltas came back from --json with no diff. It now uses the same discoverSpecFiles() helper ChangeParser uses, so the capability ids match the `spec` field of the JSON deltas. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(show): report header mismatches instead of hiding them Two cases where --diff quietly showed something misleading: A MODIFIED requirement whose capability has no main spec was rendered as all-additions, which reads like a new capability. It is an authoring error archive will reject, so it now prints the raw text with a warning naming the missing spec. A header that differs from the main spec only in case or interior spacing found no match at all under exact lookup, or matched under a lowercase-only comparison that let a real mismatch through silently. Lookup is now exact first, then the shared foldRequirementName fallback, and a folded match prints the diff the author meant alongside a warning that archive matches names exactly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor(show): name the main spec as such in collectSpecDiffs Comment and locals still called the main spec the "base" spec, and the no-main-spec comment described the old all-additions behavior. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * chore(deps-dev): bump the development-dependencies group with 2 updates Bumps the development-dependencies group with 2 updates: [smol-toml](https://github.com/squirrelchat/smol-toml) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint). Updates `smol-toml` from 1.7.1 to 1.8.0 - [Release notes](https://github.com/squirrelchat/smol-toml/releases) - [Commits](https://github.com/squirrelchat/smol-toml/compare/v1.7.1...v1.8.0) Updates `typescript-eslint` from 8.66.0 to 8.67.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.67.0/packages/typescript-eslint) --- updated-dependencies: - dependency-name: smol-toml dependency-version: 1.8.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies - dependency-name: typescript-eslint dependency-version: 8.67.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * chore(nix): invalidate pnpm dependency hash * fix(nix): update pnpm dependency hash * fix(show): harden requirement diff output * build(nix): pin combined dependency hash * test(show): assert proposal precedes diffs * docs(show): clarify JSON diff diagnostics * fix(show): retain unified diff hunk headers --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Clay Good <hi@claygood.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
c0c50f9a4c |
chore(deps-dev): bump the development-dependencies group with 2 updates (#1718)
* chore(deps-dev): bump the development-dependencies group with 2 updates Bumps the development-dependencies group with 2 updates: [smol-toml](https://github.com/squirrelchat/smol-toml) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint). Updates `smol-toml` from 1.7.1 to 1.8.0 - [Release notes](https://github.com/squirrelchat/smol-toml/releases) - [Commits](https://github.com/squirrelchat/smol-toml/compare/v1.7.1...v1.8.0) Updates `typescript-eslint` from 8.66.0 to 8.67.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.67.0/packages/typescript-eslint) --- updated-dependencies: - dependency-name: smol-toml dependency-version: 1.8.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies - dependency-name: typescript-eslint dependency-version: 8.67.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * chore(nix): invalidate pnpm dependency hash * fix(nix): update pnpm dependency hash --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Clay Good <hi@claygood.com> |
||
|
|
91813641cf |
chore(deps): migrate to @inquirer/prompts v8 + @inquirer/core v11 (#1667)
* chore(deps): migrate to @inquirer/prompts v8 + @inquirer/core v11 Bumps both packages together. The two Dependabot attempts each moved one half (#1450 prompts->8, #1422 core->11) and failed: prompts@8 pulls checkbox@5 -> core@^11, while package.json depends on core@^10 directly for two custom prompts, so a one-sided bump leaves two copies of @inquirer/core in the tree — custom prompts on v10 internals alongside bundled prompts on v11. Resolves the `instructions` removal in checkbox v5 by dropping the option: the built-in keys help tip now renders a superset of the hint that was being passed, so no theme override is needed. Closes #1458 * fix(nix): regenerate pnpmDeps hash for the inquirer v8 lockfile The pnpmDeps fixed-output hash is pinned to the contents of pnpm-lock.yaml, so the inquirer v8/core v11 migration invalidated it and Nix Flake Validation failed with 'pnpm failed to install dependencies'. Regenerated against this branch's lockfile and verified: nix build .#default completes (exit 0) through openspec-1.9.0.drv, not just past the fetch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Clay Good <hi@claygood.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3281f1f068 |
fix(deps): patch js-yaml and nanoid advisories via pnpm overrides (#1635)
Resolve all three open Dependabot alerts (all high severity): - GHSA-5p4m-2wfm-xmqj — js-yaml quadratic-CPU !!omap DoS (#96, #97). Root tree carried js-yaml 3.15.0 (via read-yaml-file) and 4.3.0 (via @changesets/parse). Dev-only; never in the published CLI, which uses `yaml`, not `js-yaml`. Pinned to >=3.15.1 / >=4.3.1. - GHSA-2v37-7h3g-55p8 / CVE-2026-67213 — nanoid size=0 infinite loop (#99). Present in both root (dev, via postcss<-vitest) and website (build-time, via postcss<-next) trees. Pinned to >=3.3.17 (resolves to 3.3.18). Overrides added to all four override surfaces (pnpm-workspace.yaml + package.json, root and website) to keep them in sync, each YAML entry annotated with its advisory id and removal condition. flake.nix pnpmDeps FOD hash regenerated for the root lockfile change (verified via nix build; hash-mismatch-count 0). dependabot.yml gains a note documenting the two surfaces Dependabot cannot manage (pnpm overrides + the Nix flake). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
4b114aade9 |
chore(deps-dev): bump development-dependencies group + refresh flake hash (#1633)
* chore(deps-dev): bump development-dependencies group + refresh flake pnpmDeps hash Supersedes #1630. Dependabot's PR bumps two dev dependencies within their existing package.json semver ranges (eslint 10.8.0 -> 10.8.1, typescript-eslint 8.65.0 -> 8.66.0), touching only pnpm-lock.yaml. That lockfile change invalidates the flake's fixed-output pnpmDeps.hash, so #1630 fails Nix Flake Validation ("pnpm failed to install dependencies"). Dependabot cannot update the Nix FOD hash, so this PR carries the same bump together with the refreshed hash. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(nix): set pnpmDeps hash for updated lockfile Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3e50944fb0 |
fix(build): allow esbuild install scripts (#1196)
* Add pnpm-workspace.yaml to allow esbuild build scripts pnpm 10+ blocks all dependency build scripts by default unless explicitly approved via allowBuilds or onlyBuiltDependencies in pnpm-workspace.yaml. esbuild (transitive dependency of vitest -> vite) has a postinstall script that downloads a platform-specific native binary. Without this config, pnpm install exits non-zero with [ERR_PNPM_IGNORED_BUILDS], breaking any downstream packaging (AUR, Nix, Docker) or local setup using pnpm >=10. Refs: #1195 * fix(build): declare pnpm workspace root * fix(build): harden pnpm workspace policies --------- Co-authored-by: Clay Good <hi@claygood.com> |
||
|
|
02b124e6b6 |
fix(security): patch fast-uri, postcss, and brace-expansion advisories (#1510)
* fix(security): patch fast-uri, postcss, and brace-expansion advisories Resolve the two open Dependabot alerts plus a third high-severity advisory the repo's own audit surfaces but Dependabot had not filed, all via version-ranged pnpm overrides (they lapse once the upstream tree moves past them): - fast-uri 3.1.4 -> 3.1.5 (website): GHSA-7p8r-x3mc-p8w7, high. Host confusion via backslash authority introducer. Pulled in transitively by ajv@8.18.0; bounded to ^3.1.5 so it stays on the 3.x line ajv expects. - postcss 8.5.22 -> 8.5.25 (root): GHSA-fxqj-rqcc-2cmp, moderate. Arbitrary .map file read via attacker-controlled sourceMappingURL. Pulled in by vite (dev/test tooling). - brace-expansion 5.0.8 -> 5.0.9 (website): GHSA-rgw5-rvv9-x895, high. DoS via unbounded recursion. The existing override capped at >=5.0.8, and 5.0.8 is itself vulnerable under this newer advisory; the root already resolved to 5.0.9. Root and website audits are clean at --audit-level high (and any-severity for the website). Full test suite: 3662 passing. * harden(security): bound overrides, scope release perms, add website lockfile drift check, document archive TOCTOU intent Hardening pass over the security fixes, from a parallel review of the dependency, CI, archive, and adjacent-code surfaces. Each item is low-risk and verified; resolved dependency versions are unchanged. - deps: bound the three security overrides to their current major (brace-expansion ">=5.0.9 <6", postcss ">=8.5.23 <9"). A bare ">=X" pin would take a future major on the next lockfile regen without review; the website already models the caret-bounded idiom. - ci: scope release-prepare.yml permissions per job. The top-level block dropped "pull-requests: write"; only the "prepare" job (which opens the Version Packages PR) now holds it. The "beta" job only tags/releases and publishes via OIDC, so it inherits the narrower default (least privilege). - ci: add a "Website Lockfile Drift" job to security.yml. The website keeps its own lockfile and is never installed in CI, so a website override that stops resolving would go unnoticed and `pnpm audit` would scan a stale graph. A `pnpm install --frozen-lockfile --ignore-scripts --dir website` fails fast on that drift (root drift is already caught in ci.yml). - archive: add intent comments at the 7 js/file-system-race sites in src/core/archive.ts. The stat->read->re-stat pattern is a deliberate concurrent-change detector; the comments record why, so no future refactor (human or scanner-driven) collapses it to fd I/O and blinds the guard. Verified: 3662 tests pass, build clean, website build clean, root+website audits clean at --audit-level high, and the new frozen-lockfile check passes locally. * chore(nix): refresh pnpmDeps hash for the lockfile change The root pnpm-lock.yaml changed (postcss + brace-expansion overrides), which stales the fixed-output pnpmDeps hash and fails Nix Flake Validation. Repin to the value CI computed from the new lockfile. |
||
|
|
23c2787789 |
chore(deps-dev): bump eslint from 10.7.0 to 10.8.0 in the development-dependencies group (#1494)
* chore(deps-dev): bump eslint in the development-dependencies group Bumps the development-dependencies group with 1 update: [eslint](https://github.com/eslint/eslint). Updates `eslint` from 10.7.0 to 10.8.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.7.0...v10.8.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.8.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * fix(nix): refresh pnpm dependency hash --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Clay Good <hi@claygood.com> |
||
|
|
87312900f5 |
fix(telemetry): send the usage event directly instead of via posthog-node (#1476)
* fix(telemetry): send the usage event directly instead of via posthog-node Installing OpenSpec shipped posthog-node's transitive tree (@posthog/core, @posthog/types) to every consumer. Those packages release several times a day, so any freshly resolved install tripped supply-chain age policies — pnpm's minimumReleaseAge failed with ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION on entries younger than the policy window (#1390). No pinning fixes this: exact-pinning posthog-node leaves its own ranges floating, npm overrides only apply at a consumer's root, pnpm ignores a dependency's npm-shrinkwrap, and bundledDependencies under a pnpm-managed node_modules packs the virtual-store layout and breaks module resolution (verified: the bundled CLI crashes on import). The SDK's only remaining job here was the wire format: the client was already configured to send one event immediately, time-bounded, with no retries, through an injected fetch that never throws. Post the same capture payload to the same /batch/ endpoint with that fetch directly. Same event name, properties, distinct id, and opt-out guards; shutdown still flushes in-flight events, each bounded by the request timeout. Verified end to end: the packed tarball contains zero posthog files, a pnpm consumer with minimumReleaseAge: 1440 installs cleanly with zero posthog lockfile entries, and the live endpoint answers 200 OK to the new payload. Regression tests pin the manifest and src free of posthog. Fixes #1390 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * build(nix): update the pnpm deps hash for the posthog-node removal Value taken from the CI mismatch report. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(telemetry): dispose the response body so no socket outlives shutdown undici keeps the connection occupied until the response body is consumed or canceled, and telemetry never reads it — on both the success and non-2xx paths the socket could linger after shutdown() returned. Cancel the body before the tracked promise resolves, with coverage for both paths (bodyUsed asserted after shutdown), and the live endpoint re-verified with disposal in place. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
17af60c66e |
fix(archive): make the scenario-drift check fence-aware, plus release-audit follow-ups (#1475)
* fix(archive): make the scenario-drift check fence-aware parseScenarioBlocks matched #### Scenario: headers on raw lines while the validator's countScenarios masks fenced code blocks (#1151). The drift check (#1391) inherited the raw scan, so a fenced scenario example in the current spec aborted an archive that validate had passed, and a fenced name in the MODIFIED block counted as keeping a scenario the block had actually dropped. Build the shared code-fence mask and skip masked lines in both the header scan and the block-end scan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(update): tear down the redirected request when the budget expires The overall request budget was armed inside the first send() and its callback closed over that hop's request. After a redirect the timer destroyed the already-dead first request, so a redirect target that trickled bytes kept resetting its idle timeout and held the socket open until the body-size cap. Track the in-flight request and have the budget timer destroy whichever one is open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(release): add changesets for user-facing changes missing from the 1.7.0 notes 18 feat/fix commits merged since v1.6.0 without a changeset, so the pending Version Packages PR would have released them silently: five tool integrations (ZCode, Hermes, CodeArts, Kimi Code rename, Codex skills-only), skills.sh distribution, symlinked schema dirs, nested spec discovery, drift multiplicity, checkbox markers, Windows welcome input, npx avoidance, doctor store drift, local dates, missing-core-workflows warning, store-aware main specs, open-questions guidance, and spec content guidance. Plus changesets for this branch's two fixes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(adapters): escape TOML-active characters in Gemini command files The gemini adapter interpolated the description into a TOML basic string and the body into a multiline basic string with no escaping. Every current template value happens to be safe; the first description with a double quote or backslash would silently produce invalid TOML for all Gemini command files. Escape both contexts (#1447 fixed the same class for the YAML adapters but scoped itself to YAML). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(update): harden install detection and redirect handling Three follow-ups from the release audit: - A path segment literally named volta (a user or project directory) classified the install as volta-managed and swallowed the upgrade offer. The undotted spelling now requires volta's own tools/image layout, matching how pnpm and yarn already demand corroboration. - The Windows npm-ownership fallback checked that the npm prefix exists, which is true of any X\node_modules\pkg tree, hand-copied ones included. Corroborate with the openspec.cmd shim npm actually writes. - A https registry redirecting to plain http was followed; a MITM on that reply controls the newer-version answer. Refuse the downgrade. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(cli): export zcodeAdapter from the barrel and sync a completion description zcode was registered but missing from the adapters barrel (its test imported the module directly), and the completion registry still carried the pre-#1062 description for the instructions command. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(parser): strip a UTF-8 BOM before parsing specs and deltas A BOM-prefixed delta spec (Windows editors, PowerShell Out-File) failed validate and archive with 'No delta sections found' because the first line never matched '## ADDED Requirements'. Strip the BOM in both normalizers, the same way tool detection already does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(cli): reject over-long change names with a validation message A 300-character change name surfaced two raw ENAMETOOLONG errno dumps from stat and mkdir. Bound the name at 200 characters in validateChangeName so the failure is a normal validation error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(archive): finish the early-sync no-op rules for MODIFIED and RENAMED Two asymmetries left over from the #1376/#1386/#1437 no-op work: - MODIFIED counted every delta as applied even when the block was byte-equal to the main spec, so a fully early-synced change rewrote the file (normalization churn), printed '~ N modified', and reported specsUpdated: true where its ADDED/REMOVED/RENAMED twins print 'Specs already in sync; no files changed.' Count only real replacements. - RENAMED's already-synced skip (source gone, target present) had no near-miss guard: a case/whitespace variant of the source still in the spec means a typo'd header, and REMOVED already hard-aborts on that signal. Apply the same guard, excluding the target itself so a case-only rename still no-ops. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(validate): stop reporting an unreadable specs dir as 'no deltas' The delta-validation loop swallowed every error as 'if no specs dir, treat as no deltas', so an EACCES capability folder produced the misleading 'Change must have at least one delta' while archive let the same error propagate. Tolerate only ENOENT and ENOTDIR (a stray specs file); anything else stays loud, matching discoverSpecFiles' documented fail-loud contract. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(update): say when commands-only delivery leaves a tool with nothing Under delivery: commands, update removed the skills of adapterless skills-only tools (Hermes, Kimi Code, Vibe, CodeArts, ForgeCode) without a word — leaving zero OpenSpec artifacts while the tool's detection dir kept re-suggesting an init that would also generate nothing. Print the same per-tool configuration correction init already prints, pointing at 'openspec config set delivery both'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(completion): honor $ZSH and $ZSH_CUSTOM for Oh My Zsh installs The installer used a set $ZSH only as an is-installed signal and then wrote to ~/.oh-my-zsh regardless, so a custom OMZ location got a freshly created ~/.oh-my-zsh tree that no shell ever loads — and isInstalled/uninstall looked in the same wrong place. Route every path through the $ZSH/$ZSH_CUSTOM-aware helpers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(init): make the static welcome screen wait for the Enter it asks for The static branch printed 'Press Enter to select tools...' and returned immediately, so the Enter landed in the tool picker and submitted the pre-selected set sight-unseen. #1462 routed reduced-motion, OPENSPEC_NO_ANIMATION, --no-animation, NO_COLOR, and narrow-terminal users onto this path. Wait in a TTY; drop the prompt line when there is no TTY to wait on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(feedback): keep the manual fallback on every gh failure Only missing-gh and unauthenticated flows showed the formatted feedback and pre-filled submission URL; issues-disabled, network, or rate-limit failures printed gh's stderr and discarded the path to submit what the user had already typed. Route those through the same manual fallback, preserving gh's exit code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(update): model the npm shim in the Windows prefix fixture The ownership corroboration now checks for the openspec.cmd shim npm writes beside node_modules; the Homebrew-prefix fixture built the layout without it, so the test failed on windows-pwsh. Write the shim in the fixture and pin the inverse: the same shape with nothing npm wrote (a hand-copied portable tree) is not an npm install. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(update): require volta's full tools/image layout for the undotted spelling The corroboration used has('tools', 'image'), which is some() — volta AND (tools OR image) — so /srv/volta/tools/apps/... still classified as a Volta install and swallowed the upgrade offer. Require both segments, matching the real %LOCALAPPDATA%\Volta\tools\image layout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(adapters): escape control characters in Gemini multiline prompts escapeTomlMultilineBasicString handled backslashes and quote-triples but not the C0 controls that are as invalid in a multiline basic string as in a single-line one. Reuse TOML_CONTROL_CHARS, applied last so the escapes it introduces are not re-doubled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(completion): finish the $ZSH_CUSTOM support and isolate it in tests The fpath verification advice still grepped the literal custom/completions, which a relocated $ZSH_CUSTOM need never contain — grep the actual directory instead. The installer tests cleared only $ZSH, so on a machine exporting $ZSH_CUSTOM they would have written into (and deleted from) the developer's real OMZ custom dir — the same leakage class #1400 fixed for $ZSH. Clear/restore both, and pin the custom-location paths with two new tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(release): correct the hermes and zcode changeset wording Hermes is skills-only (no command adapter), and zcode's namespaced commands register /opsx:<id>, not /opsx-* — the release notes must not reintroduce the invocation-spelling confusion #1471 removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(feedback): pin the manual fallback on a non-label gh failure The new reportGhFailure output (formatted feedback + pre-filled URL) had no coverage; the network-failure test now asserts it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(completion): match fpath entries as literal strings in the OMZ guidance The verification advice interpolated the completions dir into grep "<dir>" where regex metacharacters make the check unreliable and quotes could break the displayed command. Print one fpath entry per line and match with grep -F on a shell-quoted literal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(adapters): never emit a bare carriage return in Gemini TOML prompts A lone CR is illegal in a multiline basic string — Python 3.13 tomllib rejects the file — and the control-char pass deliberately skipped it on the assumption it only appears as CRLF. Normalize CRLF to LF and escape any remaining CR as \r. The escaping guarantee is now parser-backed: smol-toml (new devDependency) round-trips every hostile body in the regression matrix (lone CR, CRLF, CR before a quote run, NUL/VT/FF, trailing backslash, four- and five-quote runs), and the same outputs were verified against Python tomllib. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * build(nix): update the pnpm deps hash for the smol-toml devDependency The lockfile changed, so the fixed-output derivation hash moved; value taken from the CI mismatch report. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
05c701970a |
chore(security): override brace-expansion to fix the failing audit (#1461)
* chore(security): override brace-expansion to fix the failing audit A new advisory (GHSA-mh99-v99m-4gvg, high) flags brace-expansion <= 5.0.7 with the only patched release being 5.0.8. The scheduled Security workflow has failed on every run since 2026-07-27. pnpm audit --fix adds a scoped override in both the root and website packages; the lockfile diffs touch only brace-expansion and its subtree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(nix): blank pnpmDeps hash to surface the new lockfile hash Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(nix): pin pnpmDeps hash for the updated lockfile Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
abb422a04b |
chore(deps): consolidate dependabot bumps with flake hash update (#1457)
* chore(deps): consolidate dependabot bumps (typescript 6, @types/node 26, ora 9, commander, posthog-node) Replaces #1448, #1451, #1452 and #1453 with a single lockfile resolution. Each of those PRs changed pnpm-lock.yaml, so merging them serially would invalidate the flake.nix pnpmDeps hash four times over. - typescript 5.9.3 -> 6.0.3 (#1452) - @types/node 24.2.0 -> 26.x (#1451) - ora 8.2.0 -> 9.4.1 (#1453) - commander 14.0.0 -> 14.0.3, posthog-node 5.46.0 -> 5.46.1 (#1448, lockfile only) #1450 (@inquirer/prompts 8) is deliberately excluded: it needs a code migration, not a version bump. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(nix): update pnpmDeps hash for bumped lockfile Hash taken from this PR's first Nix Flake Validation run. Note it differs from the hash any individual dependabot PR would have produced -- the combined lockfile resolves to its own content hash. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(deps): align @types/node with the Node 20.19 runtime floor Addresses review feedback: compiling against Node 26 declarations lets the type checker admit APIs that are unavailable on the runtimes OpenSpec actually supports (engines: node >=20.19.0). Pins @types/node to ^20.19.43, the latest release in the line matching the declared floor. This also corrects a pre-existing drift -- main was on @types/node 24 against the same 20.19 floor, so the types were already ahead of the supported runtime before this PR. Verified: build clean, tsc --noEmit clean, eslint clean, 112 files / 2253 tests passing, dist/ emit byte-identical to origin/main, and no peer dependency warnings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore(nix): update pnpmDeps hash for the realigned lockfile The @types/node downgrade to the 20.19 line changed the dependency set again (it pulls undici-types 6.21.0), so the previous hash no longer matches. Value taken from a forced-mismatch Nix run on this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5406c8b3ff |
chore(deps): consolidate dependabot bumps with flake hash update (#1427)
* chore(deps): consolidate dependabot bumps (chalk, posthog-node, zod, changesets, typescript-eslint, eslint 10) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(nix): update pnpmDeps hash for bumped lockfile Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
e2f748c64f |
chore(security): add security policy, dependabot config, and config key guards (#1415)
* chore(security): add security policy, dependabot config, and config key guards Adds a SECURITY.md with a private disclosure path and an explicit threat model, a Dependabot configuration covering the CLI package, the docs site, and CI actions, and closes a prototype-pollution path in `config set`. `--allow-unknown` was meant to relax the known-key check but skipped every key check, so `openspec config set --allow-unknown __proto__.polluted x` reported success and assigned onto Object.prototype for the process lifetime. Unsafe segments are now rejected at the command layer regardless of `--allow-unknown`, and setNestedValue/deleteNestedValue refuse them for any caller. Also bumps the bundled yaml dependency from 2.8.2 to 2.9.0, the only advisory in this repo that affects code shipped in the npm package. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(nix): update pnpmDeps hash for the yaml bump fetchPnpmDeps pins a fixed-output hash over the whole dependency set, so changing pnpm-lock.yaml invalidates it. Recovered the new value from a hash-mismatch build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(security): clear dependency advisories and automate future checks Refreshes both lockfiles so every open advisory in the CLI package is resolved, replaces a quadratically-backtracking heading parser, and adds the automation to catch the next one. Dependency refresh (in-range, lockfile only): brace-expansion, flatted, js-yaml, minimatch, postcss, rollup, and vite all move to patched versions in the root lockfile; fast-uri and brace-expansion move in the website lockfile. Only @changesets/cli needed a declared floor bump, to reach a patched js-yaml. Production dependencies now report zero advisories. extractFirstPurposeLine parsed ATX headings with /\s+#+\s*$/, which backtracks quadratically on a whitespace-padded title. Replaced with a linear hand-rolled scan, verified identical to the old implementation across 303,000 generated inputs. Automation: a Security workflow runs dependency review on pull requests, blocks on advisories in published dependencies, and re-audits weekly; every GitHub Action is pinned to a commit SHA so a moved tag cannot change what CI executes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ci): drop the pnpm cache from the audit job Nothing is installed there, so setup-node's cache-save post step failed on the missing store path even though both audit steps passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(nix): repin pnpmDeps hash after the dependency refresh Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(security): apply opengrep findings and fix a dependency-review permission gap Ran opengrep against the repository to check the claims in #1414. Of 208 findings, 201 are one path-traversal rule firing on joins built from module constants, argv, or readdir entry names; 1 non-literal-regexp is fed only by LEGACY_SLASH_COMMAND_PATHS. Neither is reachable from untrusted input. The actionable results are applied here. - dependabot: add a cooldown so a freshly published version is not adopted immediately. Security updates ignore the cooldown, so this delays only routine bumps, long enough for a compromised release to be yanked. - getNestedValue now refuses prototype-reaching segments, matching the guards already on setNestedValue and deleteNestedValue. - dependency-review no longer asks to comment on the pull request. That needs `pull-requests: write`, which the workflow does not grant and a fork's token never gets, so a real finding would have failed on the comment instead of reporting the vulnerable dependency. - SECURITY.md: show the command that proves build tooling is absent from an installed copy, rather than asking readers to take it on trust. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(dependabot): drop semver cooldown keys unsupported by github-actions Dependabot rejected the whole config file, which would have silently disabled every version update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(security): make the audit advisory and document runtime behavior The published-dependency audit no longer fails the job. A newly published advisory should not block an unrelated pull request, and the step depends on registry availability; Dependabot alerts and dependency review remain the gates. SECURITY.md is corrected to match — it claimed the audit was blocking. Also documents what the CLI does on your machine, all verified rather than asserted: the install script prints one line and makes no network request or file write; every shell-invoking call uses a fixed literal while anything carrying user input uses an argument array with shell:false; telemetry sends a command name, a version, and a local random UUID, with IP capture disabled. Secret scanning is now listed, confirmed enabled by a repository admin. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ci): keep the production audit blocking off pull requests Making the step advisory on every event meant a newly published high-severity advisory in a shipped dependency could not fail any run unless a dependency changed. It stays advisory on pull requests, so an unrelated change is never blocked by an advisory published that morning, and blocks on the weekly schedule and on pushes to main, where a failure is the signal rather than a tax on someone else's work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9d40ae98f0 |
fix(nix): build with Node.js 22 now that nixpkgs marks Node 20 insecure (#1406)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
737518b36f |
[codex] Refresh security dependency locks (#1249)
* fix: refresh security dependency locks * fix: refresh nix pnpm dependency hash |
||
|
|
86d2e04cae |
chore(nix): improve flake with dynamic version and build optimization (#550)
* chore(nix): improve flake with dynamic version and source filtering - Read version dynamically from package.json instead of hardcoding - Add lib.fileset source filtering to exclude node_modules and build artifacts - Update update-flake.sh to support dynamic version pattern - Add hash change detection to skip unnecessary rebuilds - Improve error handling with automatic rollback on failure - Update specs to reflect dynamic version behavior * chore(ci): bump Nix actions to latest versions - nix-installer-action: v13 → v21 - magic-nix-cache-action: v8 → v13 - Update validation message for unchanged flake.nix * chore: add changeset for Nix improvements * fix(nix): make update-flake.sh portable to macOS - Fix grep pattern on line 37 to include opening parenthesis - Replace GNU grep -oP with portable sed alternatives (lines 53, 68, 70) - Ensures script works on both Linux and macOS (BSD sed/grep) * fix(nix): properly check build verification exit status Fix logic bug where build failures were incorrectly reported as success. The script now: - Captures build exit code and output separately - Fails fast if build returns non-zero exit code - Only checks for 'dirty tree' warning if build succeeded This addresses CodeRabbit review feedback on line 101-107. --------- Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com> |
||
|
|
ae83b4e16d |
feat(cli): add interactive UI for artifact experimental setup (#560)
* feat(cli): add interactive UI for artifact experimental setup Add animated welcome screen and searchable multi-select prompt when running `openspec artifact-experimental-setup` without the --tool flag in interactive mode. Users can now browse and select multiple tools for setup instead of requiring the --tool flag. - Add welcome screen with ASCII art animation - Add searchable multi-select prompt component - Support multi-tool setup in single command invocation * fix(nix): update flake version and reset hash for rebuild - Update version from 0.20.0 to 0.23.0 to match package.json - Set pnpmDeps hash to empty string to trigger rebuild - Fix update-flake.sh to work on macOS (use portable grep/sed) CI will fail with correct hash which we'll then apply. * fix(nix): set correct pnpmDeps hash * feat(cli): improve error handling for multi-tool setup - Continue setup for remaining tools when one fails - Collect and report all failures at the end - Only throw if all tools fail - Show partial success summary (configured vs failed) |
||
|
|
ed4d965208 |
feat: add nix flake support (sorry for this duplicate) (#459)
* add nix flake support * feat: add Nix flake maintenance automation * Add Nix Flake CI Validation * fix updatescript, update flake * make update-script compatible with macos --------- Co-authored-by: Tabish Bidiwale <30385142+TabishB@users.noreply.github.com> |