@opengsd/gsd-pi 1.0.2-dev.d456457 → 1.0.2-dev.dbfb371
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 +5 -0
- package/dist/resource-loader.js +24 -8
- package/dist/resources/.managed-resources-content-hash +1 -1
- 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-worktree.js +2 -54
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -15
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
- package/dist/resources/extensions/gsd/worktree-post-create-hook.js +117 -0
- 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/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/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 +42 -23
- package/packages/pi-ai/dist/models.generated.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/gsd/auto/loop.ts +22 -0
- package/src/resources/extensions/gsd/auto/phases.ts +1 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +2 -56
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -15
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +141 -1
- package/src/resources/extensions/gsd/worktree-post-create-hook.ts +127 -0
- package/src/resources/shared/package-manager-detection.ts +39 -0
- package/dist/tsconfig.extensions.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{4NVKiVx4C-8FUT9A7DZdq → BVrLsL82ynrLee5zxeihC}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{4NVKiVx4C-8FUT9A7DZdq → BVrLsL82ynrLee5zxeihC}/_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
|
/**
|
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))
|
|
@@ -627,7 +643,7 @@ function cleanupBundledSkillsFromEcosystemDir() {
|
|
|
627
643
|
makeTreeWritable(targetPath);
|
|
628
644
|
rmSync(targetPath, { recursive: true, force: true });
|
|
629
645
|
}
|
|
630
|
-
else {
|
|
646
|
+
else if (process.env.GSD_RESOURCE_LOADER_DEBUG === '1') {
|
|
631
647
|
console.warn(`[GSD] Leaving ambiguous skill collision in ${targetPath}; ` +
|
|
632
648
|
`the bundled copy will be used from ~/.gsd/agent/skills/${entry.name}.`);
|
|
633
649
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
9d6ff59a3cc348a6
|
|
@@ -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 ──
|
|
@@ -23,6 +23,7 @@ import { debugLog } from "./debug-logger.js";
|
|
|
23
23
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
24
24
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
25
25
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
26
|
+
import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
26
27
|
import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchForceReset, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, nativeWorktreeList, nativeLsFiles, } from "./native-git-bridge.js";
|
|
27
28
|
import { gsdHome } from "./gsd-home.js";
|
|
28
29
|
import { createWorkspace } from "./workspace.js";
|
|
@@ -796,60 +797,7 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
|
|
|
796
797
|
export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
|
|
797
798
|
return _finalizeProjectionForMergeImpl(mainBasePath, worktreePath, milestoneId);
|
|
798
799
|
}
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* Run the user-configured post-create hook script after worktree creation.
|
|
802
|
-
* The script receives SOURCE_DIR and WORKTREE_DIR as environment variables.
|
|
803
|
-
* Failure is non-fatal — returns the error message or null on success.
|
|
804
|
-
*
|
|
805
|
-
* Reads the hook path from git.worktree_post_create in preferences.
|
|
806
|
-
* Pass hookPath directly to bypass preference loading (useful for testing).
|
|
807
|
-
*/
|
|
808
|
-
export function runWorktreePostCreateHook(sourceDir, worktreeDir, hookPath) {
|
|
809
|
-
if (hookPath === undefined) {
|
|
810
|
-
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
811
|
-
hookPath = prefs?.worktree_post_create;
|
|
812
|
-
}
|
|
813
|
-
if (!hookPath)
|
|
814
|
-
return null;
|
|
815
|
-
// Resolve relative paths against the source project root.
|
|
816
|
-
// On Windows, convert 8.3 short paths (e.g. RUNNER~1) to long paths
|
|
817
|
-
// so execFileSync can locate the file correctly.
|
|
818
|
-
let resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
|
|
819
|
-
if (!existsSync(resolved)) {
|
|
820
|
-
return `Worktree post-create hook not found: ${resolved}`;
|
|
821
|
-
}
|
|
822
|
-
if (process.platform === "win32") {
|
|
823
|
-
try {
|
|
824
|
-
resolved = realpathSync.native(resolved);
|
|
825
|
-
}
|
|
826
|
-
catch (err) { /* keep original */
|
|
827
|
-
logWarning("worktree", `realpath failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
try {
|
|
831
|
-
// .bat/.cmd files on Windows require shell mode — execFileSync cannot
|
|
832
|
-
// spawn them directly (EINVAL).
|
|
833
|
-
const needsShell = process.platform === "win32" && /\.(bat|cmd)$/i.test(resolved);
|
|
834
|
-
execFileSync(resolved, [], {
|
|
835
|
-
cwd: worktreeDir,
|
|
836
|
-
env: {
|
|
837
|
-
...process.env,
|
|
838
|
-
SOURCE_DIR: sourceDir,
|
|
839
|
-
WORKTREE_DIR: worktreeDir,
|
|
840
|
-
},
|
|
841
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
842
|
-
encoding: "utf-8",
|
|
843
|
-
timeout: 30_000, // 30 second timeout
|
|
844
|
-
shell: needsShell,
|
|
845
|
-
});
|
|
846
|
-
return null;
|
|
847
|
-
}
|
|
848
|
-
catch (err) {
|
|
849
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
850
|
-
return `Worktree post-create hook failed: ${msg}`;
|
|
851
|
-
}
|
|
852
|
-
}
|
|
800
|
+
export { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
853
801
|
// ─── Auto-Worktree Branch Naming ───────────────────────────────────────────
|
|
854
802
|
/** Returns the git branch name for a milestone worktree (`milestone/<MID>`). */
|
|
855
803
|
export function autoWorktreeBranch(milestoneId) {
|
|
@@ -418,6 +418,17 @@ function initSessionNotifications(ctx) {
|
|
|
418
418
|
installNotifyInterceptor(ctx);
|
|
419
419
|
initNotificationWidget(ctx);
|
|
420
420
|
}
|
|
421
|
+
async function prepareWorkflowMcpForHookContext(ctx, basePath) {
|
|
422
|
+
// Skip MCP auto-prep when running inside an auto-worktree. The worktree
|
|
423
|
+
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
424
|
+
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
425
|
+
// CLI path resolution), dirtying the tree and breaking the milestone merge.
|
|
426
|
+
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
427
|
+
if (isInAutoWorktree(basePath))
|
|
428
|
+
return;
|
|
429
|
+
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
430
|
+
prepareWorkflowMcpForProject(ctx, basePath);
|
|
431
|
+
}
|
|
421
432
|
export function registerHooks(pi, ecosystemHandlers) {
|
|
422
433
|
// ADR-005 Phase 3b: surface pi-ai ProviderSwitchReport via audit, notification, and counter.
|
|
423
434
|
// Idempotent — only the first registerHooks call installs.
|
|
@@ -438,12 +449,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
438
449
|
await syncServiceTierStatus(ctx);
|
|
439
450
|
await applyDisabledModelProviderPolicy(ctx);
|
|
440
451
|
await applyCompactionThresholdOverride(ctx);
|
|
441
|
-
|
|
442
|
-
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
443
|
-
if (!isInAutoWorktree(basePath)) {
|
|
444
|
-
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
445
|
-
prepareWorkflowMcpForProject(ctx, basePath);
|
|
446
|
-
}
|
|
452
|
+
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
447
453
|
// Apply show_token_cost preference (#1515)
|
|
448
454
|
try {
|
|
449
455
|
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
@@ -468,15 +474,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
468
474
|
await syncServiceTierStatus(ctx);
|
|
469
475
|
await applyDisabledModelProviderPolicy(ctx);
|
|
470
476
|
await applyCompactionThresholdOverride(ctx);
|
|
471
|
-
|
|
472
|
-
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
473
|
-
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
474
|
-
// CLI path resolution), dirtying the tree and breaking the milestone merge.
|
|
475
|
-
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
476
|
-
if (!isInAutoWorktree(basePath)) {
|
|
477
|
-
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
478
|
-
prepareWorkflowMcpForProject(ctx, basePath);
|
|
479
|
-
}
|
|
477
|
+
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
480
478
|
await loadToolApiKeysForSession();
|
|
481
479
|
if (!isAutoActive()) {
|
|
482
480
|
ctx.ui.setWidget("gsd-progress", undefined);
|
|
@@ -511,6 +509,10 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
511
509
|
}
|
|
512
510
|
}
|
|
513
511
|
clearDeferredApprovalGate(beforeAgentBasePath);
|
|
512
|
+
// session_start can fire before the active provider has settled. By
|
|
513
|
+
// before_agent_start, Claude Code CLI sessions should get the same
|
|
514
|
+
// project MCP config that /gsd mcp init would write.
|
|
515
|
+
await prepareWorkflowMcpForHookContext(ctx, beforeAgentBasePath);
|
|
514
516
|
// GSD's own context injection (existing behavior — unchanged).
|
|
515
517
|
const { buildBeforeAgentStartResult } = await import("./system-context.js");
|
|
516
518
|
const gsdResult = await buildBeforeAgentStartResult(event, ctx);
|
|
@@ -17,6 +17,7 @@ import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
|
|
|
17
17
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
18
18
|
import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
|
|
19
19
|
import { loadPrompt } from "./prompt-loader.js";
|
|
20
|
+
import { isPnpmInstall } from "../../shared/package-manager-detection.js";
|
|
20
21
|
import { buildDoctorHealIssuePayload, buildDoctorHealSummary, buildWorkflowDispatchContent, } from "./workflow-protocol.js";
|
|
21
22
|
import { restoreGsdWorkflowTools, scopeGsdWorkflowToolsForDispatch, } from "./bootstrap/register-hooks.js";
|
|
22
23
|
const UPDATE_REGISTRY_URL = "https://registry.npmjs.org/@opengsd%2fgsd-pi/latest";
|
|
@@ -42,6 +43,8 @@ function isBunInstall(argv1 = process.argv[1]) {
|
|
|
42
43
|
function resolveInstallCommand(pkg) {
|
|
43
44
|
if (isBunInstall())
|
|
44
45
|
return `bun add -g ${pkg}`;
|
|
46
|
+
if (isPnpmInstall())
|
|
47
|
+
return `pnpm add -g ${pkg}`;
|
|
45
48
|
return `npm install -g ${pkg}`;
|
|
46
49
|
}
|
|
47
50
|
async function fetchLatestVersionForCommand() {
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Lightweight worktree post-create hook runner.
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { isAbsolute, join } from "node:path";
|
|
7
|
+
import { parse as parseYaml } from "yaml";
|
|
8
|
+
import { gsdHome } from "./gsd-home.js";
|
|
9
|
+
import { gsdRoot } from "./paths.js";
|
|
10
|
+
function readPreferencesObject(path) {
|
|
11
|
+
if (!existsSync(path))
|
|
12
|
+
return null;
|
|
13
|
+
const content = readFileSync(path, "utf-8");
|
|
14
|
+
try {
|
|
15
|
+
const startMarker = content.startsWith("---\r\n") ? "---\r\n" : "---\n";
|
|
16
|
+
if (content.startsWith(startMarker)) {
|
|
17
|
+
const searchStart = startMarker.length;
|
|
18
|
+
const endIdx = content.indexOf("\n---", searchStart);
|
|
19
|
+
if (endIdx === -1)
|
|
20
|
+
return null;
|
|
21
|
+
const parsed = parseYaml(content.slice(searchStart, endIdx).replace(/\r/g, ""));
|
|
22
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
23
|
+
? parsed
|
|
24
|
+
: null;
|
|
25
|
+
}
|
|
26
|
+
const gitLines = [];
|
|
27
|
+
let inGitSection = false;
|
|
28
|
+
for (const rawLine of content.split("\n")) {
|
|
29
|
+
const line = rawLine.replace(/\r$/, "");
|
|
30
|
+
const heading = line.match(/^##\s+(.+)$/);
|
|
31
|
+
if (heading) {
|
|
32
|
+
inGitSection = heading[1].trim().toLowerCase().replace(/\s+/g, "_") === "git";
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (inGitSection && line.trim() && !line.trimStart().startsWith("#")) {
|
|
36
|
+
gitLines.push(line.replace(/^\s*-\s*/, ""));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (gitLines.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
const parsed = parseYaml(gitLines.join("\n"));
|
|
42
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
43
|
+
? { git: parsed }
|
|
44
|
+
: null;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function extractHookPath(preferences) {
|
|
51
|
+
const git = preferences?.git;
|
|
52
|
+
if (!git || typeof git !== "object" || Array.isArray(git))
|
|
53
|
+
return null;
|
|
54
|
+
const hookPath = git.worktree_post_create;
|
|
55
|
+
return typeof hookPath === "string" && hookPath.trim() ? hookPath : null;
|
|
56
|
+
}
|
|
57
|
+
function resolveConfiguredHookPath(sourceDir) {
|
|
58
|
+
const paths = [
|
|
59
|
+
join(homedir(), ".pi", "agent", "gsd-preferences.md"),
|
|
60
|
+
join(gsdHome(), "preferences.md"),
|
|
61
|
+
join(gsdHome(), "PREFERENCES.md"),
|
|
62
|
+
join(gsdRoot(sourceDir), "preferences.md"),
|
|
63
|
+
join(gsdRoot(sourceDir), "PREFERENCES.md"),
|
|
64
|
+
];
|
|
65
|
+
let hookPath = null;
|
|
66
|
+
for (const path of paths) {
|
|
67
|
+
hookPath = extractHookPath(readPreferencesObject(path)) ?? hookPath;
|
|
68
|
+
}
|
|
69
|
+
return hookPath;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Run the user-configured post-create hook script after worktree creation.
|
|
73
|
+
* The script receives SOURCE_DIR and WORKTREE_DIR as environment variables.
|
|
74
|
+
* Failure is non-fatal -- returns the error message or null on success.
|
|
75
|
+
*
|
|
76
|
+
* Reads git.worktree_post_create from effective global/project preferences
|
|
77
|
+
* unless hookPath is provided directly.
|
|
78
|
+
*/
|
|
79
|
+
export function runWorktreePostCreateHook(sourceDir, worktreeDir, hookPath) {
|
|
80
|
+
if (hookPath === undefined) {
|
|
81
|
+
hookPath = resolveConfiguredHookPath(sourceDir) ?? undefined;
|
|
82
|
+
}
|
|
83
|
+
if (!hookPath)
|
|
84
|
+
return null;
|
|
85
|
+
let resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
|
|
86
|
+
if (!existsSync(resolved)) {
|
|
87
|
+
return `Worktree post-create hook not found: ${resolved}`;
|
|
88
|
+
}
|
|
89
|
+
if (process.platform === "win32") {
|
|
90
|
+
try {
|
|
91
|
+
resolved = realpathSync.native(resolved);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Keep the original path; the exec error below will include the failure.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const needsShell = process.platform === "win32" && /\.(bat|cmd)$/i.test(resolved);
|
|
99
|
+
execFileSync(resolved, [], {
|
|
100
|
+
cwd: worktreeDir,
|
|
101
|
+
env: {
|
|
102
|
+
...process.env,
|
|
103
|
+
SOURCE_DIR: sourceDir,
|
|
104
|
+
WORKTREE_DIR: worktreeDir,
|
|
105
|
+
},
|
|
106
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
107
|
+
encoding: "utf-8",
|
|
108
|
+
timeout: 30_000,
|
|
109
|
+
shell: needsShell,
|
|
110
|
+
});
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
115
|
+
return `Worktree post-create hook failed: ${msg}`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join, resolve as resolvePath, sep } from 'node:path';
|
|
3
|
+
function hasPnpmPath(value) {
|
|
4
|
+
if (!value)
|
|
5
|
+
return false;
|
|
6
|
+
const normalized = value.replace(/\\/g, '/').toLowerCase();
|
|
7
|
+
return (normalized.includes('/.pnpm/') ||
|
|
8
|
+
normalized.endsWith('/pnpm') ||
|
|
9
|
+
normalized.endsWith('/pnpm.cjs') ||
|
|
10
|
+
normalized.endsWith('/pnpm.js'));
|
|
11
|
+
}
|
|
12
|
+
function pathStartsWith(pathValue, dir) {
|
|
13
|
+
if (!pathValue)
|
|
14
|
+
return false;
|
|
15
|
+
const resolvedPath = resolvePath(pathValue);
|
|
16
|
+
const resolvedDir = resolvePath(dir);
|
|
17
|
+
return resolvedPath === resolvedDir || resolvedPath.startsWith(resolvedDir + sep);
|
|
18
|
+
}
|
|
19
|
+
// Shared by update-check.ts and gsd command handlers. The JS installer keeps a
|
|
20
|
+
// parallel copy because it runs before TypeScript output exists.
|
|
21
|
+
export function isPnpmInstall(argv1 = process.argv[1], env = process.env) {
|
|
22
|
+
if (env.npm_config_user_agent?.startsWith('pnpm/'))
|
|
23
|
+
return true;
|
|
24
|
+
if (hasPnpmPath(env.npm_execpath))
|
|
25
|
+
return true;
|
|
26
|
+
if (hasPnpmPath(argv1))
|
|
27
|
+
return true;
|
|
28
|
+
if (!argv1)
|
|
29
|
+
return false;
|
|
30
|
+
const pnpmBinDirs = [];
|
|
31
|
+
if (env.PNPM_HOME)
|
|
32
|
+
pnpmBinDirs.push(env.PNPM_HOME);
|
|
33
|
+
pnpmBinDirs.push(join(homedir(), 'Library', 'pnpm'));
|
|
34
|
+
pnpmBinDirs.push(join(homedir(), '.local', 'share', 'pnpm'));
|
|
35
|
+
return pnpmBinDirs.some((dir) => pathStartsWith(argv1, dir) || pathStartsWith(env.npm_execpath, dir));
|
|
36
|
+
}
|
package/dist/update-check.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isPnpmInstall } from './resources/shared/package-manager-detection.js';
|
|
2
|
+
export { isPnpmInstall };
|
|
1
3
|
interface UpdateCheckCache {
|
|
2
4
|
lastCheck: number;
|
|
3
5
|
latestVersion: string;
|
|
@@ -22,7 +24,10 @@ export declare function fetchLatestVersionFromRegistry(registryUrl?: string, fet
|
|
|
22
24
|
* (PR #4147) misses this path. Inspect the unresolved invocation path instead.
|
|
23
25
|
*/
|
|
24
26
|
export declare function isBunInstall(argv1?: string | undefined): boolean;
|
|
25
|
-
export declare function resolveInstallCommand(pkg: string
|
|
27
|
+
export declare function resolveInstallCommand(pkg: string, options?: {
|
|
28
|
+
argv1?: string;
|
|
29
|
+
env?: NodeJS.ProcessEnv;
|
|
30
|
+
}): string;
|
|
26
31
|
export interface UpdateCheckOptions {
|
|
27
32
|
currentVersion?: string;
|
|
28
33
|
cachePath?: string;
|
|
@@ -45,4 +50,3 @@ export declare function checkForUpdates(options?: UpdateCheckOptions): Promise<v
|
|
|
45
50
|
* Returns true if an update was performed, false otherwise.
|
|
46
51
|
*/
|
|
47
52
|
export declare function checkAndPromptForUpdates(options?: UpdateCheckOptions): Promise<boolean>;
|
|
48
|
-
export {};
|
package/dist/update-check.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
2
3
|
import { dirname, join, resolve as resolvePath, sep } from 'node:path';
|
|
3
4
|
import { homedir } from 'node:os';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
import { appRoot } from './app-paths.js';
|
|
6
|
-
import {
|
|
7
|
+
import { isPnpmInstall } from './resources/shared/package-manager-detection.js';
|
|
8
|
+
export { isPnpmInstall };
|
|
7
9
|
const CACHE_FILE = join(appRoot, '.update-check');
|
|
8
10
|
const NPM_PACKAGE_NAME = '@opengsd/gsd-pi';
|
|
9
11
|
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
@@ -91,9 +93,11 @@ export function isBunInstall(argv1 = process.argv[1]) {
|
|
|
91
93
|
const resolved = resolvePath(argv1);
|
|
92
94
|
return bunBinDirs.some((dir) => resolved.startsWith(resolvePath(dir) + sep));
|
|
93
95
|
}
|
|
94
|
-
export function resolveInstallCommand(pkg) {
|
|
95
|
-
if (isBunInstall())
|
|
96
|
+
export function resolveInstallCommand(pkg, options = {}) {
|
|
97
|
+
if (isBunInstall(options.argv1))
|
|
96
98
|
return `bun add -g ${pkg}`;
|
|
99
|
+
if (isPnpmInstall(options.argv1, options.env))
|
|
100
|
+
return `pnpm add -g ${pkg}`;
|
|
97
101
|
return `npm install -g ${pkg}`;
|
|
98
102
|
}
|
|
99
103
|
function printUpdateBanner(current, latest) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
BVrLsL82ynrLee5zxeihC
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"/_not-found/page": "/_not-found",
|
|
3
3
|
"/_global-error/page": "/_global-error",
|
|
4
4
|
"/api/boot/route": "/api/boot",
|
|
5
|
+
"/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
|
|
5
6
|
"/api/bridge-terminal/resize/route": "/api/bridge-terminal/resize",
|
|
6
7
|
"/api/bridge-terminal/stream/route": "/api/bridge-terminal/stream",
|
|
8
|
+
"/api/browse-directories/route": "/api/browse-directories",
|
|
9
|
+
"/api/dev-mode/route": "/api/dev-mode",
|
|
7
10
|
"/api/cleanup/route": "/api/cleanup",
|
|
8
11
|
"/api/captures/route": "/api/captures",
|
|
9
|
-
"/api/dev-mode/route": "/api/dev-mode",
|
|
10
|
-
"/api/browse-directories/route": "/api/browse-directories",
|
|
11
|
-
"/api/bridge-terminal/input/route": "/api/bridge-terminal/input",
|
|
12
12
|
"/api/doctor/route": "/api/doctor",
|
|
13
13
|
"/api/export-data/route": "/api/export-data",
|
|
14
14
|
"/api/experimental/route": "/api/experimental",
|
|
@@ -18,23 +18,23 @@
|
|
|
18
18
|
"/api/hooks/route": "/api/hooks",
|
|
19
19
|
"/api/inspect/route": "/api/inspect",
|
|
20
20
|
"/api/knowledge/route": "/api/knowledge",
|
|
21
|
+
"/api/files/route": "/api/files",
|
|
21
22
|
"/api/live-state/route": "/api/live-state",
|
|
22
23
|
"/api/mcp-connections/route": "/api/mcp-connections",
|
|
23
24
|
"/api/notifications/route": "/api/notifications",
|
|
24
|
-
"/api/files/route": "/api/files",
|
|
25
|
-
"/api/preferences/route": "/api/preferences",
|
|
26
25
|
"/api/onboarding/route": "/api/onboarding",
|
|
26
|
+
"/api/preferences/route": "/api/preferences",
|
|
27
27
|
"/api/recovery/route": "/api/recovery",
|
|
28
28
|
"/api/projects/route": "/api/projects",
|
|
29
29
|
"/api/session/browser/route": "/api/session/browser",
|
|
30
30
|
"/api/session/command/route": "/api/session/command",
|
|
31
31
|
"/api/session/events/route": "/api/session/events",
|
|
32
|
-
"/api/settings-data/route": "/api/settings-data",
|
|
33
32
|
"/api/session/manage/route": "/api/session/manage",
|
|
33
|
+
"/api/settings-data/route": "/api/settings-data",
|
|
34
34
|
"/api/shutdown/route": "/api/shutdown",
|
|
35
|
-
"/api/remote-questions/route": "/api/remote-questions",
|
|
36
35
|
"/api/skill-health/route": "/api/skill-health",
|
|
37
36
|
"/api/steer/route": "/api/steer",
|
|
37
|
+
"/api/remote-questions/route": "/api/remote-questions",
|
|
38
38
|
"/api/terminal/input/route": "/api/terminal/input",
|
|
39
39
|
"/api/switch-root/route": "/api/switch-root",
|
|
40
40
|
"/api/terminal/resize/route": "/api/terminal/resize",
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
7
|
+
"static/BVrLsL82ynrLee5zxeihC/_buildManifest.js",
|
|
8
|
+
"static/BVrLsL82ynrLee5zxeihC/_ssgManifest.js"
|
|
9
9
|
],
|
|
10
10
|
"rootMainFiles": [
|
|
11
11
|
"static/chunks/webpack-41a6d3c17ba63b62.js",
|