gsd-pi 2.51.0-dev.7d435fe → 2.51.0-dev.859cedb
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/resources/extensions/async-jobs/job-manager.js +4 -1
- package/dist/resources/extensions/gsd/auto/phases.js +6 -0
- package/dist/resources/extensions/gsd/auto.js +4 -2
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +11 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +23 -23
- 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 +2 -2
- 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/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 +23 -23
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/README.md +202 -0
- package/packages/mcp-server/package.json +36 -0
- package/packages/mcp-server/src/cli.ts +68 -0
- package/packages/mcp-server/src/index.ts +14 -0
- package/packages/mcp-server/src/mcp-server.test.ts +628 -0
- package/packages/mcp-server/src/server.ts +278 -0
- package/packages/mcp-server/src/session-manager.ts +328 -0
- package/packages/mcp-server/src/types.ts +107 -0
- package/packages/mcp-server/tsconfig.json +24 -0
- package/packages/rpc-client/package.json +20 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +4 -1
- package/src/resources/extensions/gsd/auto/phases.ts +6 -0
- package/src/resources/extensions/gsd/auto.ts +5 -2
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +11 -2
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -1
- /package/dist/web/standalone/.next/static/{RqOU-jOv9uZ1Q03P6L6nn → hFpSn70hOfLw7RhKUl_eK}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{RqOU-jOv9uZ1Q03P6L6nn → hFpSn70hOfLw7RhKUl_eK}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server types — session lifecycle and orchestration.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { RpcClient, SdkAgentEvent, RpcCostUpdateEvent, RpcExtensionUIRequest } from '@gsd/rpc-client';
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Session Status
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
export type SessionStatus = 'starting' | 'running' | 'blocked' | 'completed' | 'error' | 'cancelled';
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Managed Session
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
export interface ManagedSession {
|
|
18
|
+
/** Unique session ID returned from RpcClient.init() */
|
|
19
|
+
sessionId: string;
|
|
20
|
+
|
|
21
|
+
/** Absolute path to the project directory */
|
|
22
|
+
projectDir: string;
|
|
23
|
+
|
|
24
|
+
/** Current lifecycle status */
|
|
25
|
+
status: SessionStatus;
|
|
26
|
+
|
|
27
|
+
/** The RpcClient instance managing the agent process */
|
|
28
|
+
client: RpcClient;
|
|
29
|
+
|
|
30
|
+
/** Ring buffer of recent events (capped at MAX_EVENTS) */
|
|
31
|
+
events: SdkAgentEvent[];
|
|
32
|
+
|
|
33
|
+
/** Pending blocker requiring user response, if any */
|
|
34
|
+
pendingBlocker: PendingBlocker | null;
|
|
35
|
+
|
|
36
|
+
/** Cumulative cost tracking (max pattern per K004) */
|
|
37
|
+
cost: CostAccumulator;
|
|
38
|
+
|
|
39
|
+
/** Session start timestamp */
|
|
40
|
+
startTime: number;
|
|
41
|
+
|
|
42
|
+
/** Error message if status is 'error' */
|
|
43
|
+
error?: string;
|
|
44
|
+
|
|
45
|
+
/** Cleanup function to unsubscribe from events */
|
|
46
|
+
unsubscribe?: () => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Pending Blocker
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
export interface PendingBlocker {
|
|
54
|
+
/** The extension_ui_request id */
|
|
55
|
+
id: string;
|
|
56
|
+
|
|
57
|
+
/** The request method (e.g. 'select', 'confirm', 'input') */
|
|
58
|
+
method: string;
|
|
59
|
+
|
|
60
|
+
/** Human-readable message or title */
|
|
61
|
+
message: string;
|
|
62
|
+
|
|
63
|
+
/** Full event payload for inspection */
|
|
64
|
+
event: RpcExtensionUIRequest;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Cost Accumulator (K004 — cumulative-max)
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
export interface CostAccumulator {
|
|
72
|
+
totalCost: number;
|
|
73
|
+
tokens: {
|
|
74
|
+
input: number;
|
|
75
|
+
output: number;
|
|
76
|
+
cacheRead: number;
|
|
77
|
+
cacheWrite: number;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Execute Options
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
|
|
85
|
+
export interface ExecuteOptions {
|
|
86
|
+
/** Command to send after '/gsd auto' (default: none) */
|
|
87
|
+
command?: string;
|
|
88
|
+
|
|
89
|
+
/** Model ID override */
|
|
90
|
+
model?: string;
|
|
91
|
+
|
|
92
|
+
/** Run in bare mode (skip user config) */
|
|
93
|
+
bare?: boolean;
|
|
94
|
+
|
|
95
|
+
/** Path to CLI binary (overrides GSD_CLI_PATH and which resolution) */
|
|
96
|
+
cliPath?: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Constants
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
/** Maximum number of events kept in the ring buffer */
|
|
104
|
+
export const MAX_EVENTS = 50;
|
|
105
|
+
|
|
106
|
+
/** Timeout for RpcClient initialization (ms) */
|
|
107
|
+
export const INIT_TIMEOUT_MS = 30_000;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"module": "Node16",
|
|
5
|
+
"lib": ["ES2024"],
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"sourceMap": true,
|
|
13
|
+
"inlineSources": true,
|
|
14
|
+
"inlineSourceMap": false,
|
|
15
|
+
"moduleResolution": "Node16",
|
|
16
|
+
"resolveJsonModule": true,
|
|
17
|
+
"allowImportingTsExtensions": false,
|
|
18
|
+
"types": ["node"],
|
|
19
|
+
"outDir": "./dist",
|
|
20
|
+
"rootDir": "./src"
|
|
21
|
+
},
|
|
22
|
+
"include": ["src/**/*.ts"],
|
|
23
|
+
"exclude": ["node_modules", "dist", "**/*.d.ts", "src/**/*.d.ts"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gsd/rpc-client",
|
|
3
|
+
"version": "2.51.0",
|
|
4
|
+
"description": "Standalone RPC client SDK for GSD — zero internal dependencies",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -172,7 +172,10 @@ export class AsyncJobManager {
|
|
|
172
172
|
|
|
173
173
|
private deliverResult(job: Job): void {
|
|
174
174
|
if (!this.onJobComplete) return;
|
|
175
|
-
|
|
175
|
+
// Defer delivery by one microtask so await_job's .then() chain runs first
|
|
176
|
+
// and can set job.awaited = true before onJobComplete checks it (#2762).
|
|
177
|
+
const cb = this.onJobComplete;
|
|
178
|
+
queueMicrotask(() => cb(job));
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
private scheduleEviction(id: string): void {
|
|
@@ -1069,6 +1069,12 @@ export async function runUnitPhase(
|
|
|
1069
1069
|
}
|
|
1070
1070
|
|
|
1071
1071
|
if (unitResult.status === "cancelled") {
|
|
1072
|
+
// Provider-error pause: pauseAuto already handled cleanup and scheduled
|
|
1073
|
+
// recovery. Don't hard-stop — just break out of the loop (#2762).
|
|
1074
|
+
if (unitResult.errorContext?.category === "provider") {
|
|
1075
|
+
debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext.isTransient });
|
|
1076
|
+
return { action: "break", reason: "provider-pause" };
|
|
1077
|
+
}
|
|
1072
1078
|
ctx.ui.notify(
|
|
1073
1079
|
`Session creation timed out or was cancelled for ${unitType} ${unitId}. Will retry.`,
|
|
1074
1080
|
"warning",
|
|
@@ -186,7 +186,7 @@ import {
|
|
|
186
186
|
postUnitPostVerification,
|
|
187
187
|
} from "./auto-post-unit.js";
|
|
188
188
|
import { bootstrapAutoSession, type BootstrapDeps } from "./auto-start.js";
|
|
189
|
-
import { autoLoop, resolveAgentEnd, resolveAgentEndCancelled, _resetPendingResolve, isSessionSwitchInFlight, type LoopDeps } from "./auto-loop.js";
|
|
189
|
+
import { autoLoop, resolveAgentEnd, resolveAgentEndCancelled, _resetPendingResolve, isSessionSwitchInFlight, type LoopDeps, type ErrorContext } from "./auto-loop.js";
|
|
190
190
|
import {
|
|
191
191
|
WorktreeResolver,
|
|
192
192
|
type WorktreeResolverDeps,
|
|
@@ -800,11 +800,14 @@ export async function stopAuto(
|
|
|
800
800
|
export async function pauseAuto(
|
|
801
801
|
ctx?: ExtensionContext,
|
|
802
802
|
_pi?: ExtensionAPI,
|
|
803
|
+
_errorContext?: ErrorContext,
|
|
803
804
|
): Promise<void> {
|
|
804
805
|
if (!s.active) return;
|
|
805
806
|
clearUnitTimeout();
|
|
806
807
|
// Unblock any pending unit promise so the auto-loop is not orphaned.
|
|
807
|
-
|
|
808
|
+
// Pass errorContext so runUnitPhase can distinguish user-initiated pause
|
|
809
|
+
// from provider-error pause and avoid hard-stopping (#2762).
|
|
810
|
+
resolveAgentEndCancelled(_errorContext);
|
|
808
811
|
|
|
809
812
|
s.pausedSessionFile = ctx?.sessionManager?.getSessionFile() ?? null;
|
|
810
813
|
|
|
@@ -33,7 +33,12 @@ async function pauseTransientWithBackoff(
|
|
|
33
33
|
if (!allowAutoResume) {
|
|
34
34
|
ctx.ui.notify(`Transient provider errors persisted after ${MAX_TRANSIENT_AUTO_RESUMES} auto-resume attempts. Pausing for manual review.`, "warning");
|
|
35
35
|
}
|
|
36
|
-
await pauseAutoForProviderError(ctx.ui, errorDetail, () => pauseAuto(ctx, pi
|
|
36
|
+
await pauseAutoForProviderError(ctx.ui, errorDetail, () => pauseAuto(ctx, pi, {
|
|
37
|
+
message: `Provider error: ${errorDetail}`,
|
|
38
|
+
category: "provider",
|
|
39
|
+
isTransient: allowAutoResume,
|
|
40
|
+
retryAfterMs,
|
|
41
|
+
}), {
|
|
37
42
|
isRateLimit,
|
|
38
43
|
isTransient: allowAutoResume,
|
|
39
44
|
retryAfterMs,
|
|
@@ -161,7 +166,11 @@ export async function handleAgentEnd(
|
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
// --- Permanent / unknown: pause indefinitely ---
|
|
164
|
-
await pauseAutoForProviderError(ctx.ui, errorDetail, () => pauseAuto(ctx, pi
|
|
169
|
+
await pauseAutoForProviderError(ctx.ui, errorDetail, () => pauseAuto(ctx, pi, {
|
|
170
|
+
message: `Provider error: ${errorDetail}`,
|
|
171
|
+
category: "provider",
|
|
172
|
+
isTransient: false,
|
|
173
|
+
}), {
|
|
165
174
|
isRateLimit: false,
|
|
166
175
|
isTransient: false,
|
|
167
176
|
retryAfterMs: 0,
|
|
@@ -102,7 +102,7 @@ test("pauseAuto calls resolveAgentEndCancelled to unblock the loop", () => {
|
|
|
102
102
|
const fnBlock = source.slice(fnIdx, source.indexOf("\n/**\n * Build", fnIdx + 100));
|
|
103
103
|
|
|
104
104
|
assert.ok(
|
|
105
|
-
fnBlock.includes("resolveAgentEndCancelled(
|
|
105
|
+
fnBlock.includes("resolveAgentEndCancelled("),
|
|
106
106
|
"pauseAuto must call resolveAgentEndCancelled to unblock the auto-loop promise",
|
|
107
107
|
);
|
|
108
108
|
});
|
|
File without changes
|
|
File without changes
|