Problem
Auto-mode crashes on resume with:
Extension "command:gsd" error: Cannot find module 'gsd-pi/package.json'
Require stack:
- ~/.gsd/agent/extensions/gsd/auto.js
This happens every time auto-mode tries to resume (e.g. after a pause or restart), making auto-mode unable to recover gracefully. The error is thrown before the resume path completes, so state is left inconsistent.
Root Cause
auto.ts line 1342 uses createRequire(import.meta.url) to resolve gsd-pi/package.json, but gsd-pi is not findable from the extension's deployed location at ~/.gsd/agent/extensions/gsd/auto.js.
// auto.ts:1341–1343
const _req = createRequire(import.meta.url);
const pkgRoot = dirname(_req.resolve("gsd-pi/package.json")); // ← THROWS
const { initResources } = await import(join(pkgRoot, "dist", "resource-loader.js"));
Why this fails:
loader.js sets NODE_PATH to gsd-pi/node_modules (its own deps, for playwright etc.):
// loader.js:103–107
const gsdNodeModules = join(gsdRoot, 'node_modules');
process.env.NODE_PATH = [gsdNodeModules, process.env.NODE_PATH]
.filter(Boolean)
.join(delimiter);
resource-loader.js creates a symlink ~/.gsd/agent/node_modules → gsd-pi/node_modules for ESM resolution.
When createRequire resolves from ~/.gsd/agent/extensions/gsd/auto.js, it walks up:
~/.gsd/agent/extensions/gsd/node_modules/gsd-pi — absent
~/.gsd/agent/extensions/node_modules/gsd-pi — absent
~/.gsd/agent/node_modules/gsd-pi — symlink resolves to gsd-pi/node_modules/gsd-pi — absent (gsd-pi is not a dependency of itself)
NODE_PATH entry gsd-pi/node_modules/gsd-pi — absent
gsd-pi is only installed at the global node_modules level, which is NOT in NODE_PATH or any ancestor of the extension path.
The inline comment claims this approach "works in both source and deployed" — this is incorrect for deployments where gsd-pi is installed globally and not self-referencing.
The regression test resource-loader-import-path.test.ts only checks that the resolve("gsd-pi/package.json") pattern exists in source; it does not test that the resolution actually succeeds at runtime.
Expected Behavior
auto.ts should derive pkgRoot using a mechanism that works from the deployed extension path. Two viable options:
Option A (recommended) — use GSD_WORKFLOW_PATH (already set by loader.js):
// GSD_WORKFLOW_PATH = {gsdRoot}/dist/resources/GSD-WORKFLOW.md
// so dirname twice gives us gsdRoot
const pkgRoot = resolve(dirname(process.env.GSD_WORKFLOW_PATH!), '..', '..');
const { initResources } = await import(join(pkgRoot, "dist", "resource-loader.js"));
Option B — expose GSD_PKG_ROOT from loader.js:
// loader.js — add after existing env var assignments
process.env.GSD_PKG_ROOT = gsdRoot; // gsdRoot is already computed at line 10
// auto.ts — use it directly
const pkgRoot = process.env.GSD_PKG_ROOT ?? dirname(_req.resolve("gsd-pi/package.json"));
Option A requires no change to loader.js; Option B is more explicit and self-documenting.
Environment
- GSD version: 2.69.0
- Model: claude-sonnet-4-6
- Failing in: auto-mode resume path (
auto.ts handleResume / resumeAuto)
Reproduction Context
Occurs on any auto-mode resume after a pause or restart when gsd-pi is installed via npm/npx globally (the standard installation method). The code path at auto.ts:1342 is only reached during resume, not during initial start.
Forensic Evidence
- Error message:
Cannot find module 'gsd-pi/package.json' from auto.js
NODE_PATH observed in process env: {gsd-pi}/node_modules (not the parent directory containing gsd-pi)
~/.gsd/agent/node_modules symlink confirms it points to gsd-pi/node_modules, not the directory containing gsd-pi
GSD_WORKFLOW_PATH is reliably set and resolves to {pkgRoot}/dist/resources/GSD-WORKFLOW.md, making it a suitable anchor
- Downstream effect: resume-time
initResources is never called, so bundled extension files are not re-synced; stuck-loop anomalies in forensics may be partially attributable to stale extension state after resume
Auto-generated by /gsd forensics
Problem
Auto-mode crashes on resume with:
This happens every time auto-mode tries to resume (e.g. after a pause or restart), making auto-mode unable to recover gracefully. The error is thrown before the resume path completes, so state is left inconsistent.
Root Cause
auto.tsline 1342 usescreateRequire(import.meta.url)to resolvegsd-pi/package.json, butgsd-piis not findable from the extension's deployed location at~/.gsd/agent/extensions/gsd/auto.js.Why this fails:
loader.jssetsNODE_PATHtogsd-pi/node_modules(its own deps, for playwright etc.):resource-loader.jscreates a symlink~/.gsd/agent/node_modules → gsd-pi/node_modulesfor ESM resolution.When
createRequireresolves from~/.gsd/agent/extensions/gsd/auto.js, it walks up:~/.gsd/agent/extensions/gsd/node_modules/gsd-pi— absent~/.gsd/agent/extensions/node_modules/gsd-pi— absent~/.gsd/agent/node_modules/gsd-pi— symlink resolves togsd-pi/node_modules/gsd-pi— absent (gsd-pi is not a dependency of itself)NODE_PATHentrygsd-pi/node_modules/gsd-pi— absentgsd-piis only installed at the global node_modules level, which is NOT inNODE_PATHor any ancestor of the extension path.The inline comment claims this approach "works in both source and deployed" — this is incorrect for deployments where
gsd-piis installed globally and not self-referencing.The regression test
resource-loader-import-path.test.tsonly checks that theresolve("gsd-pi/package.json")pattern exists in source; it does not test that the resolution actually succeeds at runtime.Expected Behavior
auto.tsshould derivepkgRootusing a mechanism that works from the deployed extension path. Two viable options:Option A (recommended) — use
GSD_WORKFLOW_PATH(already set byloader.js):Option B — expose
GSD_PKG_ROOTfromloader.js:Option A requires no change to
loader.js; Option B is more explicit and self-documenting.Environment
auto.tshandleResume/resumeAuto)Reproduction Context
Occurs on any auto-mode resume after a pause or restart when
gsd-piis installed via npm/npx globally (the standard installation method). The code path atauto.ts:1342is only reached during resume, not during initial start.Forensic Evidence
Cannot find module 'gsd-pi/package.json'fromauto.jsNODE_PATHobserved in process env:{gsd-pi}/node_modules(not the parent directory containinggsd-pi)~/.gsd/agent/node_modulessymlink confirms it points togsd-pi/node_modules, not the directory containinggsd-piGSD_WORKFLOW_PATHis reliably set and resolves to{pkgRoot}/dist/resources/GSD-WORKFLOW.md, making it a suitable anchorinitResourcesis never called, so bundled extension files are not re-synced; stuck-loop anomalies in forensics may be partially attributable to stale extension state after resumeAuto-generated by
/gsd forensics