@opengsd/gsd-pi 1.0.2-dev.235ebf3 → 1.0.2-dev.2c204d3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -12
- package/dist/resource-loader.d.ts +7 -0
- package/dist/resource-loader.js +42 -9
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/context7/index.js +12 -2
- package/dist/resources/extensions/gsd/auto/loop.js +19 -0
- package/dist/resources/extensions/gsd/auto/phases.js +1 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +232 -49
- package/dist/resources/extensions/gsd/auto-worktree.js +2 -54
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
- package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
- package/dist/resources/extensions/gsd/worktree-post-create-hook.js +117 -0
- package/dist/resources/extensions/search-the-web/native-search.js +57 -8
- package/dist/resources/shared/package-manager-detection.js +36 -0
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +7 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
- package/dist/web/standalone/.next/server/chunks/1834.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/package.json +0 -1
- package/dist/worktree-cli.d.ts +0 -2
- package/dist/worktree-cli.js +21 -9
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
- package/packages/cloud-mcp-gateway/package.json +4 -3
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/bin/gsd-mcp-server.js +14 -0
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +13 -13
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/bin/pi-ai.js +14 -0
- package/packages/pi-ai/dist/models.generated.d.ts +40 -17
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +49 -30
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +50 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +5 -3
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/package.json +8 -8
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/deps.js +10 -0
- package/scripts/install/detect-existing.js +17 -3
- package/scripts/install/npm-global.js +103 -33
- package/scripts/install.js +1 -0
- package/src/resources/extensions/context7/index.ts +15 -2
- package/src/resources/extensions/gsd/auto/loop.ts +22 -0
- package/src/resources/extensions/gsd/auto/phases.ts +1 -1
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-start.ts +307 -56
- package/src/resources/extensions/gsd/auto-worktree.ts +2 -56
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -15
- package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
- package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +141 -1
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +56 -4
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
- package/src/resources/extensions/gsd/worktree-post-create-hook.ts +127 -0
- package/src/resources/extensions/search-the-web/native-search.ts +60 -8
- package/src/resources/shared/package-manager-detection.ts +39 -0
- package/dist/tsconfig.extensions.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{-P554bKh56nzavKUmvFM2 → mijI90BL1BdUcMUnhC0HU}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{-P554bKh56nzavKUmvFM2 → mijI90BL1BdUcMUnhC0HU}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -13,6 +13,28 @@ GSD Pi is a local-first coding agent for planning, implementing, verifying, and
|
|
|
13
13
|
|
|
14
14
|
It combines a terminal agent, project workflow tools, worktree-aware Git automation, and optional UI integrations so a project can move from idea to reviewed implementation with less manual coordination.
|
|
15
15
|
|
|
16
|
+
## Screenshots
|
|
17
|
+
|
|
18
|
+
GSD runs as a terminal-first TUI with optional browser dashboard controls.
|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
## Feature Roll-Up
|
|
27
|
+
|
|
28
|
+
- **Guided terminal agent** — Start with `gsd`, configure providers, and run planned or quick coding sessions from your shell.
|
|
29
|
+
- **Autonomous project workflow** — Break work into milestones, slices, and tasks, then let auto mode plan, implement, verify, and advance.
|
|
30
|
+
- **Worktree-aware Git automation** — Keep implementation work isolated while preserving a reviewable main checkout.
|
|
31
|
+
- **Local project memory** — Store project requirements, decisions, runtime notes, generated plans, summaries, and validation evidence under `.gsd/`.
|
|
32
|
+
- **Multi-provider model routing** — Use the provider your team already has, with configurable defaults and per-phase model preferences.
|
|
33
|
+
- **Extension surface** — Add project-specific commands, tools, skills, and UI integrations through bundled or community extensions.
|
|
34
|
+
- **Terminal and web surfaces** — Use the TUI by default, or launch `gsd --web` when a visual control plane fits the work better than a terminal.
|
|
35
|
+
|
|
36
|
+
See [CHANGELOG.md](./CHANGELOG.md) for release-by-release fixes and [Legacy Release History](./docs/archive/legacy-release-history.md) for archived history before the `open-gsd/gsd-pi` baseline.
|
|
37
|
+
|
|
16
38
|
## Status
|
|
17
39
|
|
|
18
40
|
This repository is starting a new development baseline at version `1.0.0` under the `open-gsd/gsd-pi` project.
|
|
@@ -27,41 +49,63 @@ Recommended — guided installer:
|
|
|
27
49
|
npx @opengsd/gsd-pi@latest
|
|
28
50
|
```
|
|
29
51
|
|
|
30
|
-
|
|
52
|
+
For CI or scripted installs:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx @opengsd/gsd-pi@latest --yes
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Alternative — direct npm global install:
|
|
31
59
|
|
|
32
60
|
```bash
|
|
33
61
|
npm install -g @opengsd/gsd-pi@latest
|
|
34
62
|
```
|
|
35
63
|
|
|
36
|
-
|
|
64
|
+
If you want pnpm to own the global install, use pnpm's runner:
|
|
37
65
|
|
|
38
66
|
```bash
|
|
39
|
-
|
|
67
|
+
pnpm setup
|
|
68
|
+
exec $SHELL -l
|
|
69
|
+
pnpm dlx @opengsd/gsd-pi@latest
|
|
40
70
|
```
|
|
41
71
|
|
|
42
72
|
Source: [`open-gsd/gsd-pi`](https://github.com/open-gsd/gsd-pi).
|
|
43
73
|
|
|
44
74
|
## Migrate From Older Installs
|
|
45
75
|
|
|
46
|
-
GSD Pi now installs from the scoped
|
|
76
|
+
GSD Pi now installs from the scoped package `@opengsd/gsd-pi`. If you previously installed the older unscoped `gsd-pi` package, remove it first so the old global binary does not shadow the new package.
|
|
47
77
|
|
|
48
|
-
|
|
78
|
+
Recommended migration with the guided `npx` installer:
|
|
49
79
|
|
|
50
80
|
```bash
|
|
51
|
-
npm uninstall -g gsd-pi
|
|
81
|
+
npm uninstall -g gsd-pi @opengsd/gsd-pi
|
|
52
82
|
rm -f ~/.gsd/.update-check ~/.gsd/agent/managed-resources.json
|
|
53
|
-
|
|
54
|
-
|
|
83
|
+
npx @opengsd/gsd-pi@latest
|
|
84
|
+
command -v gsd
|
|
55
85
|
gsd --version
|
|
56
86
|
```
|
|
57
87
|
|
|
58
|
-
|
|
88
|
+
If the old package was installed with `sudo npm install -g`, use `sudo npm uninstall -g gsd-pi` for the old package removal.
|
|
89
|
+
|
|
90
|
+
To migrate from old npm globals to a pnpm-owned global install:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm uninstall -g gsd-pi @opengsd/gsd-pi
|
|
94
|
+
rm -f ~/.gsd/.update-check ~/.gsd/agent/managed-resources.json
|
|
95
|
+
pnpm setup
|
|
96
|
+
exec $SHELL -l
|
|
97
|
+
pnpm dlx @opengsd/gsd-pi@latest
|
|
98
|
+
command -v gsd
|
|
99
|
+
gsd --version
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Windows PowerShell with the guided `npx` installer:
|
|
59
103
|
|
|
60
104
|
```powershell
|
|
61
|
-
npm uninstall -g gsd-pi
|
|
105
|
+
npm uninstall -g gsd-pi @opengsd/gsd-pi
|
|
62
106
|
Remove-Item "$env:USERPROFILE\.gsd\.update-check" -Force -ErrorAction SilentlyContinue
|
|
63
107
|
Remove-Item "$env:USERPROFILE\.gsd\agent\managed-resources.json" -Force -ErrorAction SilentlyContinue
|
|
64
|
-
|
|
108
|
+
npx @opengsd/gsd-pi@latest
|
|
65
109
|
where.exe gsd
|
|
66
110
|
gsd --version
|
|
67
111
|
```
|
|
@@ -85,6 +129,14 @@ npm uninstall -g @opengsd/gsd-pi gsd-pi
|
|
|
85
129
|
rm -rf ~/.gsd
|
|
86
130
|
```
|
|
87
131
|
|
|
132
|
+
If you installed GSD with pnpm, use pnpm for the pnpm-owned package. If pnpm reports that its global bin directory is not on `PATH`, run `pnpm setup`, restart your shell, then retry.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pnpm remove -g @opengsd/gsd-pi
|
|
136
|
+
npm uninstall -g gsd-pi
|
|
137
|
+
rm -rf ~/.gsd
|
|
138
|
+
```
|
|
139
|
+
|
|
88
140
|
Windows PowerShell:
|
|
89
141
|
|
|
90
142
|
```powershell
|
|
@@ -139,7 +191,6 @@ Then use slash commands inside the GSD session:
|
|
|
139
191
|
| `native/` | Native engine packaging and platform binaries |
|
|
140
192
|
| `studio/` | Desktop studio app |
|
|
141
193
|
| `web/` | Web UI and API surface |
|
|
142
|
-
| `vscode-extension/` | VS Code integration |
|
|
143
194
|
| `docs/` | User and developer documentation |
|
|
144
195
|
| `scripts/` | Build, release, migration, and maintenance scripts |
|
|
145
196
|
|
|
@@ -33,6 +33,11 @@ export declare function getNewerManagedResourceVersion(agentDir: string, current
|
|
|
33
33
|
* 4. Makes the result writable for the next upgrade cycle.
|
|
34
34
|
*/
|
|
35
35
|
export declare function syncResourceDir(srcDir: string, destDir: string): void;
|
|
36
|
+
export declare function resolvePackageNodeModulesLayout(root: string): {
|
|
37
|
+
internalNodeModules: string;
|
|
38
|
+
hoistedNodeModules: string | null;
|
|
39
|
+
};
|
|
40
|
+
export declare function findNearestNodeModulesAncestor(startPath: string): string | null;
|
|
36
41
|
/** Check if any GSD workspace scopes exist in internal but not in hoisted node_modules */
|
|
37
42
|
export declare function hasMissingWorkspaceScopes(hoisted: string, internal: string): boolean;
|
|
38
43
|
/**
|
|
@@ -47,6 +52,7 @@ export declare function mergedFingerprint(hoisted: string, internal: string): st
|
|
|
47
52
|
* Syncs all bundled resources to agentDir (~/.gsd/agent/) on every launch.
|
|
48
53
|
*
|
|
49
54
|
* - extensions/ → ~/.gsd/agent/extensions/ (overwrite when version changes)
|
|
55
|
+
* - shared/ → ~/.gsd/agent/shared/ (overwrite when version changes)
|
|
50
56
|
* - agents/ → ~/.gsd/agent/agents/ (overwrite when version changes)
|
|
51
57
|
* - skills/ → ~/.gsd/agent/skills/ (overwrite when version changes)
|
|
52
58
|
* - GSD-WORKFLOW.md → ~/.gsd/agent/GSD-WORKFLOW.md (fallback for env var miss)
|
|
@@ -60,6 +66,7 @@ export declare function mergedFingerprint(hoisted: string, internal: string): st
|
|
|
60
66
|
*/
|
|
61
67
|
export declare function initResources(agentDir: string, skillsDir?: string): void;
|
|
62
68
|
export declare function hasStaleCompiledExtensionSiblings(extensionsDir: string, sourceDir?: string): boolean;
|
|
69
|
+
export declare function hasMissingBundledResourceFiles(destDir: string, sourceDir: string): boolean;
|
|
63
70
|
interface BuildResourceLoaderOptions {
|
|
64
71
|
additionalExtensionPaths?: string[];
|
|
65
72
|
}
|
package/dist/resource-loader.js
CHANGED
|
@@ -311,16 +311,15 @@ function copyDirRecursive(src, dest) {
|
|
|
311
311
|
* them without requiring every call site to use jiti.
|
|
312
312
|
*
|
|
313
313
|
* Layout differences by install method:
|
|
314
|
-
* - Source/monorepo: packageRoot/node_modules has everything
|
|
315
|
-
* - Global install (npm/bun/pnpm): merge
|
|
316
|
-
* packageRoot/node_modules so
|
|
314
|
+
* - Source/monorepo: packageRoot/node_modules has everything -> simple symlink
|
|
315
|
+
* - Global install (npm/bun/pnpm): merge the nearest ancestor node_modules
|
|
316
|
+
* with packageRoot/node_modules so both hoisted deps like yaml and
|
|
317
|
+
* package-local deps like @sinclair/typebox resolve (#3529, #3564).
|
|
317
318
|
*/
|
|
318
319
|
function ensureNodeModulesSymlink(agentDir) {
|
|
319
320
|
const agentNodeModules = join(agentDir, 'node_modules');
|
|
320
|
-
const internalNodeModules =
|
|
321
|
-
|
|
322
|
-
const isGlobalInstall = basename(hoistedNodeModules) === 'node_modules';
|
|
323
|
-
if (!isGlobalInstall) {
|
|
321
|
+
const { internalNodeModules, hoistedNodeModules } = resolvePackageNodeModulesLayout(packageRoot);
|
|
322
|
+
if (!hoistedNodeModules) {
|
|
324
323
|
// Source/monorepo: internal node_modules has everything
|
|
325
324
|
reconcileSymlink(agentNodeModules, internalNodeModules);
|
|
326
325
|
return;
|
|
@@ -330,6 +329,23 @@ function ensureNodeModulesSymlink(agentDir) {
|
|
|
330
329
|
// @gsd/* scopes are hoisted — a hoisted-only symlink breaks extension imports.
|
|
331
330
|
reconcileMergedNodeModules(agentNodeModules, hoistedNodeModules, internalNodeModules);
|
|
332
331
|
}
|
|
332
|
+
export function resolvePackageNodeModulesLayout(root) {
|
|
333
|
+
return {
|
|
334
|
+
internalNodeModules: join(root, 'node_modules'),
|
|
335
|
+
hoistedNodeModules: findNearestNodeModulesAncestor(root),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
export function findNearestNodeModulesAncestor(startPath) {
|
|
339
|
+
let current = resolve(startPath);
|
|
340
|
+
while (true) {
|
|
341
|
+
if (basename(current) === 'node_modules')
|
|
342
|
+
return current;
|
|
343
|
+
const parent = dirname(current);
|
|
344
|
+
if (parent === current)
|
|
345
|
+
return null;
|
|
346
|
+
current = parent;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
333
349
|
/** Check if any GSD workspace scopes exist in internal but not in hoisted node_modules */
|
|
334
350
|
export function hasMissingWorkspaceScopes(hoisted, internal) {
|
|
335
351
|
if (!existsSync(internal))
|
|
@@ -544,6 +560,7 @@ function pruneRemovedBundledExtensions(manifest, agentDir) {
|
|
|
544
560
|
* Syncs all bundled resources to agentDir (~/.gsd/agent/) on every launch.
|
|
545
561
|
*
|
|
546
562
|
* - extensions/ → ~/.gsd/agent/extensions/ (overwrite when version changes)
|
|
563
|
+
* - shared/ → ~/.gsd/agent/shared/ (overwrite when version changes)
|
|
547
564
|
* - agents/ → ~/.gsd/agent/agents/ (overwrite when version changes)
|
|
548
565
|
* - skills/ → ~/.gsd/agent/skills/ (overwrite when version changes)
|
|
549
566
|
* - GSD-WORKFLOW.md → ~/.gsd/agent/GSD-WORKFLOW.md (fallback for env var miss)
|
|
@@ -584,12 +601,17 @@ export function initResources(agentDir, skillsDir = join(agentDir, 'skills')) {
|
|
|
584
601
|
// Version matches — check content fingerprint for same-version staleness.
|
|
585
602
|
const currentHash = getCurrentResourceFingerprint();
|
|
586
603
|
const hasStaleExtensionFiles = hasStaleCompiledExtensionSiblings(extensionsDir, bundledExtensionsDir);
|
|
587
|
-
|
|
604
|
+
const hasMissingSharedFiles = hasMissingBundledResourceFiles(join(agentDir, 'shared'), join(resourcesDir, 'shared'));
|
|
605
|
+
if (manifest.contentHash &&
|
|
606
|
+
manifest.contentHash === currentHash &&
|
|
607
|
+
!hasStaleExtensionFiles &&
|
|
608
|
+
!hasMissingSharedFiles) {
|
|
588
609
|
return;
|
|
589
610
|
}
|
|
590
611
|
}
|
|
591
612
|
// Sync bundled resources — overwrite so updates land on next launch.
|
|
592
613
|
syncResourceDir(bundledExtensionsDir, join(agentDir, 'extensions'));
|
|
614
|
+
syncResourceDir(join(resourcesDir, 'shared'), join(agentDir, 'shared'));
|
|
593
615
|
syncResourceDir(join(resourcesDir, 'agents'), join(agentDir, 'agents'));
|
|
594
616
|
syncResourceDir(join(resourcesDir, 'skills'), skillsDir);
|
|
595
617
|
// Sync GSD-WORKFLOW.md to agentDir as a fallback for when GSD_WORKFLOW_PATH
|
|
@@ -627,7 +649,7 @@ function cleanupBundledSkillsFromEcosystemDir() {
|
|
|
627
649
|
makeTreeWritable(targetPath);
|
|
628
650
|
rmSync(targetPath, { recursive: true, force: true });
|
|
629
651
|
}
|
|
630
|
-
else {
|
|
652
|
+
else if (process.env.GSD_RESOURCE_LOADER_DEBUG === '1') {
|
|
631
653
|
console.warn(`[GSD] Leaving ambiguous skill collision in ${targetPath}; ` +
|
|
632
654
|
`the bundled copy will be used from ~/.gsd/agent/skills/${entry.name}.`);
|
|
633
655
|
}
|
|
@@ -675,6 +697,17 @@ export function hasStaleCompiledExtensionSiblings(extensionsDir, sourceDir = bun
|
|
|
675
697
|
}
|
|
676
698
|
return false;
|
|
677
699
|
}
|
|
700
|
+
export function hasMissingBundledResourceFiles(destDir, sourceDir) {
|
|
701
|
+
const sourceFiles = collectRelativeFiles(sourceDir);
|
|
702
|
+
if (sourceFiles.size === 0)
|
|
703
|
+
return false;
|
|
704
|
+
const installedFiles = collectRelativeFiles(destDir);
|
|
705
|
+
for (const relPath of sourceFiles) {
|
|
706
|
+
if (!installedFiles.has(relPath))
|
|
707
|
+
return true;
|
|
708
|
+
}
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
678
711
|
function collectRelativeFiles(rootDir) {
|
|
679
712
|
const files = new Set();
|
|
680
713
|
if (!existsSync(rootDir))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
e7fbf7aae3d3457c
|
|
@@ -92,6 +92,16 @@ function formatLibraryList(libs, query) {
|
|
|
92
92
|
lines.push("\nUse the ID (e.g. /websites/react_dev) with get_library_docs to fetch documentation.");
|
|
93
93
|
return lines.join("\n");
|
|
94
94
|
}
|
|
95
|
+
function getFirstTextContent(result) {
|
|
96
|
+
const content = result.content;
|
|
97
|
+
if (!Array.isArray(content))
|
|
98
|
+
return undefined;
|
|
99
|
+
const textBlock = content.find((block) => typeof block === "object" &&
|
|
100
|
+
block !== null &&
|
|
101
|
+
block.type === "text" &&
|
|
102
|
+
typeof block.text === "string");
|
|
103
|
+
return textBlock?.text.trim() || undefined;
|
|
104
|
+
}
|
|
95
105
|
// ─── Extension ───────────────────────────────────────────────────────────────
|
|
96
106
|
export default function (pi) {
|
|
97
107
|
// ── resolve_library ──────────────────────────────────────────────────────
|
|
@@ -164,7 +174,7 @@ export default function (pi) {
|
|
|
164
174
|
if (isPartial)
|
|
165
175
|
return new Text(theme.fg("warning", "Searching Context7..."), 0, 0);
|
|
166
176
|
if (result.isError || d?.error) {
|
|
167
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
177
|
+
return new Text(theme.fg("error", `Error: ${d?.error ?? getFirstTextContent(result) ?? "unknown"}`), 0, 0);
|
|
168
178
|
}
|
|
169
179
|
let text = theme.fg("success", `${d?.resultCount ?? 0} ${d?.resultCount === 1 ? "library" : "libraries"} found`);
|
|
170
180
|
if (d?.cached)
|
|
@@ -303,7 +313,7 @@ export default function (pi) {
|
|
|
303
313
|
if (isPartial)
|
|
304
314
|
return new Text(theme.fg("warning", "Fetching documentation..."), 0, 0);
|
|
305
315
|
if (result.isError || d?.error) {
|
|
306
|
-
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
|
316
|
+
return new Text(theme.fg("error", `Error: ${d?.error ?? getFirstTextContent(result) ?? "unknown"}`), 0, 0);
|
|
307
317
|
}
|
|
308
318
|
let text = theme.fg("success", `${(d?.charCount ?? 0).toLocaleString()} chars`);
|
|
309
319
|
text += theme.fg("dim", ` · ${d?.tokens ?? 5000} token budget`);
|
|
@@ -50,6 +50,7 @@ import { handleCustomEngineVerifyPause, handleCustomEngineVerifyRetryOutcome, }
|
|
|
50
50
|
import { handleCustomEngineReconcile } from "./workflow-custom-engine-reconcile.js";
|
|
51
51
|
import { handleCustomEngineReconcileOutcome } from "./workflow-custom-engine-reconcile-outcome.js";
|
|
52
52
|
import { formatLeaseConflictNotice } from "./lease-conflict-notice.js";
|
|
53
|
+
import { setAutoOutcomeWidget, unitVerb } from "../auto-dashboard.js";
|
|
53
54
|
/**
|
|
54
55
|
* Returns true if workerId is an active worker in this project whose OS
|
|
55
56
|
* process no longer exists. Used to detect dead lease holders before
|
|
@@ -690,6 +691,24 @@ export async function autoLoop(ctx, pi, s, deps, options) {
|
|
|
690
691
|
});
|
|
691
692
|
if (reconcileFlow.action === "break")
|
|
692
693
|
break;
|
|
694
|
+
if (s.stepMode) {
|
|
695
|
+
if (ctx.hasUI) {
|
|
696
|
+
ctx.ui.setWidget?.("gsd-progress", undefined);
|
|
697
|
+
setAutoOutcomeWidget(ctx, {
|
|
698
|
+
status: "step",
|
|
699
|
+
title: "Step complete",
|
|
700
|
+
detail: `Completed ${unitVerb(iterData.unitType)} ${iterData.unitId}.`,
|
|
701
|
+
unitLabel: `${unitVerb(iterData.unitType)} ${iterData.unitId}`,
|
|
702
|
+
nextAction: "Advance one step, or resume automatic mode.",
|
|
703
|
+
commands: ["/gsd next", "/gsd auto", "/gsd status for overview"],
|
|
704
|
+
startedAt: s.autoStartTime,
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
ctx.ui.setStatus("gsd-auto", "next");
|
|
708
|
+
ctx.ui.notify(`Step complete: ${unitVerb(iterData.unitType)} ${iterData.unitId}. Run /gsd next for the next step, or /gsd auto to continue automatically.`, "info");
|
|
709
|
+
s.preserveStepSurfaceAfterLoopExit = true;
|
|
710
|
+
break;
|
|
711
|
+
}
|
|
693
712
|
continue;
|
|
694
713
|
}
|
|
695
714
|
if (!sidecarItem) {
|
|
@@ -1568,7 +1568,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1568
1568
|
const dispatchKey = `${unitType}/${unitId}`;
|
|
1569
1569
|
const nextDispatchCount = (s.unitDispatchCount.get(dispatchKey) ?? 0) + 1;
|
|
1570
1570
|
// Status bar (widget + preconditions deferred until after model selection — see #2899)
|
|
1571
|
-
ctx.ui.setStatus("gsd-auto", "auto");
|
|
1571
|
+
ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
|
|
1572
1572
|
if (mid)
|
|
1573
1573
|
deps.updateSliceProgressCache(s.basePath, mid, state.activeSlice?.id);
|
|
1574
1574
|
// ── Safety harness: reset evidence + create checkpoint ──
|
|
@@ -132,6 +132,8 @@ export class AutoSession {
|
|
|
132
132
|
// ── Isolation degradation ────────────────────────────────────────────
|
|
133
133
|
/** Set to true when worktree creation fails; prevents merge of nonexistent branch. */
|
|
134
134
|
isolationDegraded = false;
|
|
135
|
+
/** Temporary recovery mode for stranded work adopted from physical git evidence. */
|
|
136
|
+
strandedRecoveryIsolationMode = null;
|
|
135
137
|
/** Project-root dirty snapshot captured before an isolated worktree unit runs. */
|
|
136
138
|
rootWriteBaseline = null;
|
|
137
139
|
// ── Merge guard ──────────────────────────────────────────────────────
|
|
@@ -285,6 +287,7 @@ export class AutoSession {
|
|
|
285
287
|
this.lastGitActionFailure = null;
|
|
286
288
|
this.lastGitActionStatus = null;
|
|
287
289
|
this.isolationDegraded = false;
|
|
290
|
+
this.strandedRecoveryIsolationMode = null;
|
|
288
291
|
this.rootWriteBaseline = null;
|
|
289
292
|
this.milestoneMergedInPhases = false;
|
|
290
293
|
this.milestoneStartShas = new Map();
|