* fix: remove @gsd/* cross-deps that break npm install (#hotfix)
Workspace packages declared @gsd/* as dependencies in their own
package.json files. npm's bundleDependencies bundles packages into
node_modules/ but still tries to resolve sub-dependencies from the
registry — causing 404s for the unpublished @gsd/* scope.
- Remove @gsd/* from all dependencies (root and workspace packages)
- Add validate-pack.sh: tests tarball installability before publish
- Wire validate-pack into CI (every PR) and publish pipeline
- Bump to v2.10.10
- Update changelog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: drop bundleDependencies, use postinstall symlinks instead
bundleDependencies with workspace packages causes npm to resolve
@gsd/* from the registry during install — 404 since they're not
published. Replace with a postinstall script that creates
node_modules/@gsd/* symlinks pointing to packages/*.
- Remove @gsd/* from dependencies and bundleDependencies
- Add link-workspace-packages.cjs (CJS, runs before ESM postinstall)
- Update validate-pack to verify symlinks after install
- Include link script in files array
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: robust validate-pack + fallback workspace linking
- Keep @gsd/* in bundleDependencies (for npm pack bundling)
- Remove @gsd/* from root dependencies (prevents 404 registry lookups)
- Add link-workspace-packages.cjs fallback for when bundled symlinks
aren't created
- Simplified validate-pack with better error diagnostics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: remove bundleDependencies — use postinstall symlinks only
npm 10.x fetches packument metadata for ALL deps including bundled ones.
@gsd/* packages don't exist on npm → 404 → hard install failure.
bundleDependencies is fundamentally broken for unpublished workspace
packages. Replace with:
- packages/ shipped via files array (already was)
- link-workspace-packages.cjs creates node_modules/@gsd/* symlinks in
postinstall, pointing to packages/*
- No @gsd/* in dependencies or bundleDependencies at all
Tarball drops from 40M to 3M (no bundled node_modules).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add .npmignore to prevent .gitignore from excluding dist/
.gitignore contains /dist/ and packages/*/dist/ which are needed in
the published tarball. Without .npmignore, npm pack respects .gitignore
and excludes them — even though "files" in package.json should override.
An empty .npmignore causes npm to ignore .gitignore entirely, letting
the "files" field control what's packed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: avoid SIGPIPE in validate-pack on Linux
tar | grep -q causes SIGPIPE (exit 141) on Linux when grep closes the
pipe early. Write tar listing to a temp file and grep that instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: update changelog for v2.10.9
* 2.10.9
* fix(ci): retry smoke test with backoff for npm propagation delay
The post-publish smoke test was failing because npm registry propagation
can take 30-90s. Replaced the fixed 15s sleep with a retry loop (5
attempts, 30s backoff).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: normalize .ts import extensions to .js for Node 22.22+ compatibility
Node 22.22.0's --experimental-strip-types handles .ts import specifiers
differently, causing ERR_INVALID_TYPESCRIPT_SYNTAX in CI. The project
convention uses .js specifiers with a custom resolve hook that rewrites
them to .ts at test time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: replace better-sqlite3 with sql.js to eliminate native compilation failures
better-sqlite3 requires prebuilt binaries or node-gyp compilation, which
fails on newer Node versions (e.g. 25.x) that lack prebuilds. sql.js uses
WASM-compiled SQLite with zero native dependencies, making installation
reliable across all platforms and Node versions.
Closes#355
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Initial plan
* fix: detect and merge orphaned completed slice branches at startup to prevent infinite loop
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: add missing closing brace in mergeOrphanedSliceBranches
The for-loop body was missing its closing brace, causing a parse error
that broke all tests importing auto.ts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
Co-authored-by: TÂCHES <afromanguy@me.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Lex Christopherson <lex@glittercowboy.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Node 22.22.0's --experimental-strip-types handles .ts import specifiers
differently, causing ERR_INVALID_TYPESCRIPT_SYNTAX in CI. The project
convention uses .js specifiers with a custom resolve hook that rewrites
them to .ts at test time.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Initial plan
* Add adaptive reconciliation, concrete remediation steps, and xxHash32 JS fallback
- auto.ts: final reconciliation pass before halting on loop detection
(runs skipExecuteTask to write blocker artifacts and advance pipeline)
- auto.ts: adaptive retry on prevCount>=2: write stub summary when still
missing after two agent sessions, so the agent has a recovery context
- auto.ts: buildLoopRemediationSteps() helper with concrete manual steps
when automatic reconciliation cannot resolve the unit
- xxhash/index.ts: pure-JS xxHash32 fallback when native addon does not
export xxHash32 (prevents 'native.xxHash32 is not a function' crash)
- idle-recovery.test.ts: tests for buildLoopRemediationSteps and loop-recovery
path in skipExecuteTask
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
* Address code review feedback
- xxhash/index.ts: extract accumulate() helper to remove duplicate lane
processing lines in the 16-byte loop
- auto.ts: replace magic number 2 with named constant STUB_RECOVERY_THRESHOLD
- idle-recovery.test.ts: add comment explaining the 3 (== MAX_UNIT_DISPATCHES)
used in the loop-recovery test
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
* Address PR review: verify post-state, fix stub wording, fix checkbox syntax, add fallback test
- auto.ts (MAX branch): check verifyExpectedArtifact() after skipExecuteTask()
before advancing; annotate both conditions explaining what each validates
- auto.ts (self-repair branch): guard advance with verifyExpectedArtifact() so
regex mismatches in the slice plan don't silently re-dispatch
- auto.ts (stub-recovery): write stub summary directly with "PARTIAL RECOVERY"
wording instead of using skipExecuteTask (which would claim "exhausted N attempts")
- auto.ts (remediation): fix checkbox example to "- [x] **${tid}:" (no trailing **)
- xxhash/index.ts: export xxHash32Fallback so CI can test JS path independently
- native/src/index.ts: re-export xxHash32Fallback
- xxhash.test.mjs: add "xxHash32Fallback (pure-JS path)" describe block that
validates the JS implementation against the reference on all test cases
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
* chore: retrigger CI
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
Co-authored-by: CI Trigger <noreply@github.com>
* feat(M001/S01): ID generation and config plumbing
Tasks:
- chore(M001/S01/T02): auto-commit after execute-task
- chore(M001/S01): auto-commit after plan-slice
- docs(S01): add slice plan
Branch: gsd/M001/S01
* feat(M001/S02): Regex hardening and backwards compat
Tasks:
- chore(M001/S02/T02): auto-commit after execute-task
- chore(M001/S02/T01): auto-commit after execute-task
- chore: untrack .gsd/ runtime files from git index
- docs(S02): add slice plan
Branch: gsd/M001/S02
* docs(M001/S03): UX — wizard toggle and documentation
Tasks:
- chore(M001/S03/T01): auto-commit after execute-task
- docs(S03): add slice plan
Branch: gsd/M001/S03
* test(M001/S04): Integration tests and end-to-end verification
Tasks:
- chore(M001/S04/T02): auto-commit after execute-task
- chore(M001/S04/T01): auto-commit after execute-task
- docs(S04): add slice plan
Branch: gsd/M001/S04
* chore(M001): record integration branch
* chore(M002): record integration branch
* docs(M002/S01): Format swap — production code, tests, and docs
Tasks:
- chore(gsd/M002/S01): auto-commit after pre-switch
- chore(M002/S01/T01): auto-commit after execute-task
- chore: untrack .gsd/ runtime files from git index
- docs(S01): add slice plan
Branch: gsd/M002/S01
* chore(M002): auto-commit after complete-milestone
* Updated to document that we don't automatically always squash to main if you started on a different branch (like a dev or feature branch)
* fix: replace vitest import with node:test in regex-hardening test
The test imported from 'vitest' which isn't installed, causing
ERR_MODULE_NOT_FOUND and failing the CI unit test step. All other
test files use node:test. Swapped the import and removed the
vitest conditional wrapper.
* chore: untrack .gsd/ (already gitignored)
* docs: fix stale 'main' references in merge comments and prompts
The slice merge code correctly resolves to the integration branch
(which may be a feature branch, worktree branch, etc.), but comments,
JSDoc, and prompt templates still said 'main' as if it were always
the literal main branch.
Updated git-service.ts, worktree.ts, system.md, and
guided-complete-slice.md to say 'integration branch' with a clear
explanation of what that means.
* Fixed preferences.md case mismatch; Added fallback for backwards compat
* Updated preferences file example to show new unique_milestone_ids setting
* Updated readme to explain best practice for working in teams
---------
Co-authored-by: TÂCHES <afromanguy@me.com>
Two bugs that interact to silently kill auto-mode:
1. smartStage() uses `git add -A` which respects .gitignore. When .gsd/
is gitignored (common — GSD's own baseline patterns only ignore runtime
files, but many projects ignore all of .gsd/), new planning artifacts
(CONTEXT.md, SUMMARY.md, PLAN.md, UAT.md, DECISIONS.md) are never
staged. They exist on disk but not in git. Squash-merges then delete
them on main because they appear as "removed relative to main."
Fix: after `git add -A`, force-add `.gsd/milestones/` and root
planning files. Runtime paths are still excluded by the subsequent
`git reset HEAD` step.
2. handleAgentEnd() has no reentrancy guard. Background job notifications
(async_bash results) trigger additional agent_end events while the
first handler is still running (it yields at every await). Concurrent
dispatchNextUnit() calls race on newSession() — one cancels the other,
silently stopping auto-mode. Combined with bug #1, the second
dispatchNextUnit call may find the active milestone's CONTEXT.md
missing (never committed, lost during branch switch) and stop with
"No context or roadmap yet."
Fix: boolean guard prevents concurrent execution. Reset in stopAuto()
so restarts aren't blocked.
Fixes #TBD
Co-authored-by: TÂCHES <afromanguy@me.com>
After a crash where complete-slice wrote SUMMARY+UAT but didn't mark
the roadmap [x], the idempotency check incorrectly reported the unit
as "done" (artifacts exist), while the state machine kept returning
the same complete-slice unit (roadmap shows [ ]). This caused
dispatchNextUnit to recurse forever.
Fix: verifyExpectedArtifact for complete-slice now also checks that
the slice is marked [x] in the roadmap. If not, it returns false so
the stale completion key is evicted and the unit re-runs.
Lenient if roadmap file is missing or corrupt (returns true).
Co-authored-by: glittercowboy <186001655+glittercowboy@users.noreply.github.com>
Model variants like `claude-opus-4-6[1m]` use bracket suffixes to
differentiate context window configurations internally, but the
Anthropic API only accepts base model IDs (e.g. `claude-opus-4-6`).
Sending the full variant ID via OAuth (Claude Max/Pro) causes a 404:
{"type":"not_found_error","message":"model: claude-opus-4-6[1m]"}
Strip any `[...]` suffix from model.id for OAuth requests only.
API key auth is left unchanged since the behavior there is unverified.
verifyExpectedArtifact() returned true when resolveExpectedArtifactPath()
returned null, conflating "unit type has no artifact" with "slice directory
missing on disk". This caused /gsd auto to infinitely skip and re-dispatch
the same stale completed-unit entry until OOM.
Now only replan-slice (the sole type with no verifiable artifact) passes
on null; all other types return false, triggering the existing eviction
logic that removes the stale key and re-runs the unit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>