gsd-pi 2.77.0-dev.c9c8932c6 → 2.77.0-dev.eaa4973bc
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/dist/cli-web-branch.d.ts +1 -0
- package/dist/cli-web-branch.js +3 -0
- package/dist/cli.js +24 -2
- package/dist/provider-migrations.d.ts +18 -0
- package/dist/provider-migrations.js +14 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +14 -10
- package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
- package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +24 -0
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +31 -0
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +58 -8
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +4 -2
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
- package/dist/resources/extensions/gsd/file-lock.js +49 -9
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
- package/dist/resources/extensions/gsd/journal.js +17 -2
- package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
- package/dist/resources/extensions/gsd/reports.js +5 -4
- package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
- package/dist/resources/extensions/gsd/uok/audit.js +18 -2
- package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -0
- package/dist/resources/extensions/mcp-client/auth.js +10 -1
- package/dist/resources/extensions/mcp-client/index.js +118 -9
- package/dist/resources/skills/create-skill/SKILL.md +2 -2
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- 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/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +13 -13
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-1832629448831fdc.js → webpack-2e68521d7c82f7c2.js} +1 -1
- package/package.json +3 -3
- package/packages/mcp-server/README.md +3 -3
- package/packages/mcp-server/dist/env-writer.d.ts +1 -0
- package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
- package/packages/mcp-server/dist/env-writer.js +74 -6
- package/packages/mcp-server/dist/env-writer.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +25 -2
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/src/env-writer.test.ts +79 -1
- package/packages/mcp-server/src/env-writer.ts +76 -6
- package/packages/mcp-server/src/server.ts +29 -2
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +21 -16
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +24 -17
- package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +19 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +20 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +25 -0
- package/packages/pi-tui/src/stdin-buffer.ts +26 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +14 -10
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +22 -16
- package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
- package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +16 -2
- package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -0
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +30 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +60 -5
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -2
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
- package/src/resources/extensions/gsd/file-lock.ts +84 -11
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
- package/src/resources/extensions/gsd/journal.ts +27 -2
- package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
- package/src/resources/extensions/gsd/reports.ts +5 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +39 -25
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +181 -0
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
- package/src/resources/extensions/gsd/uok/audit.ts +20 -2
- package/src/resources/extensions/gsd/workflow-logger.ts +22 -3
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -0
- package/src/resources/extensions/mcp-client/auth.ts +12 -1
- package/src/resources/extensions/mcp-client/index.ts +129 -10
- package/src/resources/skills/create-skill/SKILL.md +2 -2
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.js +0 -9
- /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → 5wbu35_C2_MQ3Jj1lEVDx}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → 5wbu35_C2_MQ3Jj1lEVDx}/_ssgManifest.js +0 -0
|
@@ -10,7 +10,16 @@
|
|
|
10
10
|
// ─── Env resolution ───────────────────────────────────────────────────────────
|
|
11
11
|
/** Resolve `${VAR}` references in a string against `process.env`. */
|
|
12
12
|
function resolveEnvValue(value) {
|
|
13
|
-
return value.replace(/\$\{([^}]+)\}/g, (_match, varName) =>
|
|
13
|
+
return value.replace(/\$\{([^}]+)\}/g, (_match, varName) => {
|
|
14
|
+
const resolved = process.env[varName];
|
|
15
|
+
if (resolved === undefined || resolved === "") {
|
|
16
|
+
// eslint-disable-next-line no-console
|
|
17
|
+
console.warn(`[mcp-client auth] Environment variable "${varName}" referenced in MCP server config is unset. ` +
|
|
18
|
+
`Requests will go out with a malformed header and the remote server will likely reject them with 401.`);
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
return resolved;
|
|
22
|
+
});
|
|
14
23
|
}
|
|
15
24
|
function resolveHeaders(raw) {
|
|
16
25
|
const resolved = {};
|
|
@@ -21,8 +21,38 @@ import { join } from "node:path";
|
|
|
21
21
|
import { buildHttpTransportOpts } from "./auth.js";
|
|
22
22
|
// ─── Connection Manager ───────────────────────────────────────────────────────
|
|
23
23
|
const connections = new Map();
|
|
24
|
+
const pendingConnections = new Map();
|
|
24
25
|
let configCache = null;
|
|
25
26
|
const toolCache = new Map();
|
|
27
|
+
const trustedStdioServers = new Set();
|
|
28
|
+
const CHILD_ENV_ALLOWLIST = new Set([
|
|
29
|
+
"PATH",
|
|
30
|
+
"Path",
|
|
31
|
+
"HOME",
|
|
32
|
+
"USER",
|
|
33
|
+
"USERNAME",
|
|
34
|
+
"USERPROFILE",
|
|
35
|
+
"SHELL",
|
|
36
|
+
"TMPDIR",
|
|
37
|
+
"TEMP",
|
|
38
|
+
"TMP",
|
|
39
|
+
"SystemRoot",
|
|
40
|
+
"WINDIR",
|
|
41
|
+
"APPDATA",
|
|
42
|
+
"LOCALAPPDATA",
|
|
43
|
+
"XDG_CONFIG_HOME",
|
|
44
|
+
"XDG_CACHE_HOME",
|
|
45
|
+
]);
|
|
46
|
+
function stdioTrustKey(config) {
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
name: config.name,
|
|
49
|
+
sourcePath: config.sourcePath,
|
|
50
|
+
command: config.command,
|
|
51
|
+
args: config.args ?? [],
|
|
52
|
+
cwd: config.cwd,
|
|
53
|
+
env: config.env ?? {},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
26
56
|
function readConfigs() {
|
|
27
57
|
if (configCache)
|
|
28
58
|
return configCache;
|
|
@@ -57,6 +87,7 @@ function readConfigs() {
|
|
|
57
87
|
servers.push({
|
|
58
88
|
name,
|
|
59
89
|
transport,
|
|
90
|
+
sourcePath: configPath,
|
|
60
91
|
...(hasCommand && {
|
|
61
92
|
command: config.command,
|
|
62
93
|
args: Array.isArray(config.args) ? config.args : undefined,
|
|
@@ -78,6 +109,42 @@ function readConfigs() {
|
|
|
78
109
|
configCache = servers;
|
|
79
110
|
return servers;
|
|
80
111
|
}
|
|
112
|
+
export function _buildMcpChildEnvForTest(configEnv) {
|
|
113
|
+
const childEnv = {};
|
|
114
|
+
for (const key of CHILD_ENV_ALLOWLIST) {
|
|
115
|
+
const value = process.env[key];
|
|
116
|
+
if (typeof value === "string")
|
|
117
|
+
childEnv[key] = value;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
...childEnv,
|
|
121
|
+
...(configEnv ? resolveEnv(configEnv) : {}),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function _buildMcpTrustConfirmOptionsForTest(signal) {
|
|
125
|
+
return signal ? { timeout: 120_000, signal } : { timeout: 120_000 };
|
|
126
|
+
}
|
|
127
|
+
async function assertTrustedStdioServer(config, ctx, signal) {
|
|
128
|
+
if (config.transport !== "stdio")
|
|
129
|
+
return undefined;
|
|
130
|
+
const trustKey = stdioTrustKey(config);
|
|
131
|
+
if (trustedStdioServers.has(trustKey))
|
|
132
|
+
return undefined;
|
|
133
|
+
if (!ctx?.hasUI) {
|
|
134
|
+
throw new Error(`MCP server "${config.name}" is a project-local stdio command from ${config.sourcePath}. ` +
|
|
135
|
+
"Run this from an interactive GSD session and approve the server before use.");
|
|
136
|
+
}
|
|
137
|
+
const commandLine = [config.command, ...(config.args ?? [])].filter(Boolean).join(" ");
|
|
138
|
+
const envKeys = Object.keys(config.env ?? {});
|
|
139
|
+
const envSummary = envKeys.length > 0
|
|
140
|
+
? `\n\nConfigured environment keys: ${envKeys.join(", ")}`
|
|
141
|
+
: "\n\nNo explicit environment keys configured.";
|
|
142
|
+
const approved = await ctx.ui.confirm(`Trust MCP server "${config.name}"?`, `Project config ${config.sourcePath} wants to start:\n\n${commandLine}${envSummary}\n\nOnly approve MCP servers you trust.`, _buildMcpTrustConfirmOptionsForTest(signal));
|
|
143
|
+
if (!approved) {
|
|
144
|
+
throw new Error(`MCP server "${config.name}" was not approved by the user.`);
|
|
145
|
+
}
|
|
146
|
+
return trustKey;
|
|
147
|
+
}
|
|
81
148
|
function getServerConfig(name) {
|
|
82
149
|
const trimmed = name.trim();
|
|
83
150
|
return readConfigs().find((s) => s.name === trimmed ||
|
|
@@ -96,7 +163,7 @@ function resolveEnv(env) {
|
|
|
96
163
|
}
|
|
97
164
|
return resolved;
|
|
98
165
|
}
|
|
99
|
-
async function getOrConnect(name, signal) {
|
|
166
|
+
async function getOrConnect(name, signal, ctx) {
|
|
100
167
|
const config = getServerConfig(name);
|
|
101
168
|
if (!config)
|
|
102
169
|
throw new Error(`Unknown MCP server: "${name}". Use mcp_servers to list available servers.`);
|
|
@@ -105,13 +172,28 @@ async function getOrConnect(name, signal) {
|
|
|
105
172
|
const existing = connections.get(config.name);
|
|
106
173
|
if (existing)
|
|
107
174
|
return existing.client;
|
|
175
|
+
const pending = pendingConnections.get(config.name);
|
|
176
|
+
if (pending)
|
|
177
|
+
return pending;
|
|
178
|
+
const connectionPromise = connectServer(config, signal, ctx);
|
|
179
|
+
pendingConnections.set(config.name, connectionPromise);
|
|
180
|
+
try {
|
|
181
|
+
return await connectionPromise;
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
pendingConnections.delete(config.name);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async function connectServer(config, signal, ctx) {
|
|
108
188
|
const client = new Client({ name: "gsd", version: "1.0.0" });
|
|
109
189
|
let transport;
|
|
190
|
+
let approvedTrustKey;
|
|
110
191
|
if (config.transport === "stdio" && config.command) {
|
|
192
|
+
approvedTrustKey = await assertTrustedStdioServer(config, ctx, signal);
|
|
111
193
|
transport = new StdioClientTransport({
|
|
112
194
|
command: config.command,
|
|
113
195
|
args: config.args,
|
|
114
|
-
env:
|
|
196
|
+
env: _buildMcpChildEnvForTest(config.env),
|
|
115
197
|
cwd: config.cwd,
|
|
116
198
|
stderr: "pipe",
|
|
117
199
|
});
|
|
@@ -127,9 +209,28 @@ async function getOrConnect(name, signal) {
|
|
|
127
209
|
else {
|
|
128
210
|
throw new Error(`Server "${config.name}" has unsupported transport: ${config.transport}`);
|
|
129
211
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
212
|
+
try {
|
|
213
|
+
await client.connect(transport, { signal, timeout: 30000 });
|
|
214
|
+
if (approvedTrustKey)
|
|
215
|
+
trustedStdioServers.add(approvedTrustKey);
|
|
216
|
+
connections.set(config.name, { client, transport });
|
|
217
|
+
return client;
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
try {
|
|
221
|
+
await transport.close();
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Best-effort cleanup after a failed or aborted connection attempt.
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
await client.close();
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// Best-effort cleanup after a failed or aborted connection attempt.
|
|
231
|
+
}
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
133
234
|
}
|
|
134
235
|
async function closeAll() {
|
|
135
236
|
const closing = Array.from(connections.entries()).map(async ([name, conn]) => {
|
|
@@ -139,9 +240,17 @@ async function closeAll() {
|
|
|
139
240
|
catch {
|
|
140
241
|
// Best-effort cleanup
|
|
141
242
|
}
|
|
243
|
+
try {
|
|
244
|
+
await conn.transport.close();
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
// Best-effort cleanup
|
|
248
|
+
}
|
|
142
249
|
connections.delete(name);
|
|
143
250
|
});
|
|
144
251
|
await Promise.allSettled(closing);
|
|
252
|
+
pendingConnections.clear();
|
|
253
|
+
trustedStdioServers.clear();
|
|
145
254
|
toolCache.clear();
|
|
146
255
|
}
|
|
147
256
|
// ─── Formatters ───────────────────────────────────────────────────────────────
|
|
@@ -249,7 +358,7 @@ export default function (pi) {
|
|
|
249
358
|
description: "MCP server name (from mcp_servers output), e.g. 'railway', 'twitter-mcp', 'linear'",
|
|
250
359
|
}),
|
|
251
360
|
}),
|
|
252
|
-
async execute(_id, params, signal) {
|
|
361
|
+
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
253
362
|
try {
|
|
254
363
|
// Return cached tools if available
|
|
255
364
|
const cached = toolCache.get(params.server);
|
|
@@ -265,7 +374,7 @@ export default function (pi) {
|
|
|
265
374
|
details: { server: params.server, toolCount: cached.length, cached: true },
|
|
266
375
|
};
|
|
267
376
|
}
|
|
268
|
-
const client = await getOrConnect(params.server, signal);
|
|
377
|
+
const client = await getOrConnect(params.server, signal, ctx);
|
|
269
378
|
const result = await client.listTools(undefined, { signal, timeout: 30000 });
|
|
270
379
|
const tools = (result.tools ?? []).map((t) => ({
|
|
271
380
|
name: t.name,
|
|
@@ -326,9 +435,9 @@ export default function (pi) {
|
|
|
326
435
|
description: "Tool arguments as key-value pairs matching the tool's input schema",
|
|
327
436
|
})),
|
|
328
437
|
}),
|
|
329
|
-
async execute(_id, params, signal) {
|
|
438
|
+
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
330
439
|
try {
|
|
331
|
-
const client = await getOrConnect(params.server, signal);
|
|
440
|
+
const client = await getOrConnect(params.server, signal, ctx);
|
|
332
441
|
const result = await client.callTool({ name: params.tool, arguments: params.args ?? {} }, undefined, { signal, timeout: 60000 });
|
|
333
442
|
// Serialize result content to text
|
|
334
443
|
const contentItems = result.content;
|
|
@@ -88,8 +88,8 @@ Then proceed directly to the workflow.
|
|
|
88
88
|
## Skill Structure Quick Reference
|
|
89
89
|
|
|
90
90
|
**Skill directories:**
|
|
91
|
-
- Global: `~/.
|
|
92
|
-
- Project-local: `.
|
|
91
|
+
- Global: `~/.agents/skills/{skill-name}/`
|
|
92
|
+
- Project-local: `.agents/skills/{skill-name}/`
|
|
93
93
|
|
|
94
94
|
**Simple skill (single file):**
|
|
95
95
|
```yaml
|
|
@@ -5,13 +5,13 @@ GSD-specific skill ecosystem details: directory conventions, discovery mechanics
|
|
|
5
5
|
<skill_directories>
|
|
6
6
|
GSD supports two skill directories, checked in order:
|
|
7
7
|
|
|
8
|
-
**User-scope (global):** `~/.
|
|
8
|
+
**User-scope (global):** `~/.agents/skills/`
|
|
9
9
|
- Available in every GSD session regardless of working directory
|
|
10
|
-
- Installed
|
|
10
|
+
- Installed via [skills.sh](https://skills.sh) or manually
|
|
11
11
|
|
|
12
|
-
**Project-scope (local):** `.
|
|
12
|
+
**Project-scope (local):** `.agents/skills/`
|
|
13
13
|
- Available only when GSD runs inside the project directory
|
|
14
|
-
-
|
|
14
|
+
- Committable to version control so team members share the same skill set
|
|
15
15
|
- Ideal for project-specific workflows, deploy scripts, or conventions
|
|
16
16
|
|
|
17
17
|
Skills in both directories follow the same SKILL.md format and router pattern conventions.
|
|
@@ -16,22 +16,22 @@
|
|
|
16
16
|
Enumerate skills from both directories:
|
|
17
17
|
```bash
|
|
18
18
|
echo "=== Global skills ==="
|
|
19
|
-
ls ~/.
|
|
19
|
+
ls ~/.agents/skills/ 2>/dev/null || echo "(none)"
|
|
20
20
|
|
|
21
21
|
echo "=== Project-local skills ==="
|
|
22
|
-
ls .
|
|
22
|
+
ls .agents/skills/ 2>/dev/null || echo "(none)"
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Present as:
|
|
26
26
|
```
|
|
27
27
|
Available skills:
|
|
28
28
|
|
|
29
|
-
Global (~/.
|
|
29
|
+
Global (~/.agents/skills/):
|
|
30
30
|
1. create-skill
|
|
31
31
|
2. manage-stripe
|
|
32
32
|
...
|
|
33
33
|
|
|
34
|
-
Project-local (.
|
|
34
|
+
Project-local (.agents/skills/):
|
|
35
35
|
3. project-deploy
|
|
36
36
|
...
|
|
37
37
|
```
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
**Ask the user:**
|
|
16
16
|
"Should this skill be global or project-local?"
|
|
17
17
|
|
|
18
|
-
1. **Global** (`~/.
|
|
19
|
-
2. **Project-local** (`.
|
|
18
|
+
1. **Global** (`~/.agents/skills/`) — Available in all GSD sessions
|
|
19
|
+
2. **Project-local** (`.agents/skills/`) — Available only in this project
|
|
20
20
|
|
|
21
21
|
## Step 2: Adaptive Requirements Gathering
|
|
22
22
|
|
|
@@ -99,11 +99,11 @@ See references/recommended-structure.md for templates.
|
|
|
99
99
|
## Step 5: Create Directory
|
|
100
100
|
|
|
101
101
|
Use the scope selected in Step 1 to determine the base path:
|
|
102
|
-
- **Global:** `~/.
|
|
103
|
-
- **Project-local:** `.
|
|
102
|
+
- **Global:** `~/.agents/skills/{skill-name}`
|
|
103
|
+
- **Project-local:** `.agents/skills/{skill-name}`
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
|
-
BASE_PATH="{selected-base}/
|
|
106
|
+
BASE_PATH="{selected-base}/skills/{skill-name}"
|
|
107
107
|
mkdir -p $BASE_PATH
|
|
108
108
|
# If complex:
|
|
109
109
|
mkdir -p $BASE_PATH/workflows
|