gsd-pi 2.32.0-dev.d792ba5 → 2.32.0-dev.f3d5d53
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/resource-loader.js +13 -3
- package/dist/resources/extensions/gsd/auto-prompts.ts +46 -44
- package/dist/resources/extensions/gsd/auto-start.ts +6 -5
- package/dist/resources/extensions/gsd/auto-timers.ts +3 -2
- package/dist/resources/extensions/gsd/auto-verification.ts +2 -1
- package/dist/resources/extensions/gsd/auto-worktree.ts +5 -4
- package/dist/resources/extensions/gsd/auto.ts +24 -23
- package/dist/resources/extensions/gsd/commands-inspect.ts +2 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.ts +2 -1
- package/dist/resources/extensions/gsd/error-utils.ts +6 -0
- package/dist/resources/extensions/gsd/export.ts +2 -1
- package/dist/resources/extensions/gsd/git-service.ts +3 -2
- package/dist/resources/extensions/gsd/guided-flow.ts +3 -2
- package/dist/resources/extensions/gsd/index.ts +6 -5
- package/dist/resources/extensions/gsd/key-manager.ts +2 -1
- package/dist/resources/extensions/gsd/marketplace-discovery.ts +4 -3
- package/dist/resources/extensions/gsd/migrate-external.ts +3 -2
- package/dist/resources/extensions/gsd/milestone-ids.ts +2 -1
- package/dist/resources/extensions/gsd/native-git-bridge.ts +2 -1
- package/dist/resources/extensions/gsd/parallel-merge.ts +2 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.ts +2 -1
- package/dist/resources/extensions/gsd/quick.ts +2 -1
- package/dist/resources/extensions/gsd/session-lock.ts +12 -1
- package/dist/resources/extensions/gsd/tests/context-compression.test.ts +1 -1
- package/dist/resources/extensions/gsd/worktree-command.ts +8 -7
- package/package.json +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +46 -44
- package/src/resources/extensions/gsd/auto-start.ts +6 -5
- package/src/resources/extensions/gsd/auto-timers.ts +3 -2
- package/src/resources/extensions/gsd/auto-verification.ts +2 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +5 -4
- package/src/resources/extensions/gsd/auto.ts +24 -23
- package/src/resources/extensions/gsd/commands-inspect.ts +2 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +2 -1
- package/src/resources/extensions/gsd/error-utils.ts +6 -0
- package/src/resources/extensions/gsd/export.ts +2 -1
- package/src/resources/extensions/gsd/git-service.ts +3 -2
- package/src/resources/extensions/gsd/guided-flow.ts +3 -2
- package/src/resources/extensions/gsd/index.ts +6 -5
- package/src/resources/extensions/gsd/key-manager.ts +2 -1
- package/src/resources/extensions/gsd/marketplace-discovery.ts +4 -3
- package/src/resources/extensions/gsd/migrate-external.ts +3 -2
- package/src/resources/extensions/gsd/milestone-ids.ts +2 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +2 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +2 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +2 -1
- package/src/resources/extensions/gsd/quick.ts +2 -1
- package/src/resources/extensions/gsd/session-lock.ts +12 -1
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +1 -1
- package/src/resources/extensions/gsd/worktree-command.ts +8 -7
|
@@ -16,6 +16,7 @@ import { getEnvApiKey } from "@gsd/pi-ai";
|
|
|
16
16
|
import { existsSync, statSync, chmodSync } from "node:fs";
|
|
17
17
|
import { join, dirname } from "node:path";
|
|
18
18
|
import { mkdirSync } from "node:fs";
|
|
19
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
19
20
|
|
|
20
21
|
// ─── Provider Registry ─────────────────────────────────────────────────────────
|
|
21
22
|
|
|
@@ -552,7 +553,7 @@ export async function testProviderKey(
|
|
|
552
553
|
return { provider, status: "error", message: `HTTP ${res.status}`, latencyMs };
|
|
553
554
|
} catch (err) {
|
|
554
555
|
const latencyMs = Date.now() - start;
|
|
555
|
-
const msg =
|
|
556
|
+
const msg = getErrorMessage(err);
|
|
556
557
|
if (msg.includes("timeout") || msg.includes("AbortError")) {
|
|
557
558
|
return { provider, status: "error", message: "timeout (15s)", latencyMs };
|
|
558
559
|
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import * as fs from 'node:fs';
|
|
18
18
|
import * as path from 'node:path';
|
|
19
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
19
20
|
|
|
20
21
|
// ============================================================================
|
|
21
22
|
// Type Definitions
|
|
@@ -194,7 +195,7 @@ export function parseMarketplaceJson(repoRoot: string):
|
|
|
194
195
|
} catch (err) {
|
|
195
196
|
return {
|
|
196
197
|
success: false,
|
|
197
|
-
error: `Failed to read marketplace.json: ${
|
|
198
|
+
error: `Failed to read marketplace.json: ${getErrorMessage(err)}`
|
|
198
199
|
};
|
|
199
200
|
}
|
|
200
201
|
|
|
@@ -204,7 +205,7 @@ export function parseMarketplaceJson(repoRoot: string):
|
|
|
204
205
|
} catch (err) {
|
|
205
206
|
return {
|
|
206
207
|
success: false,
|
|
207
|
-
error: `Failed to parse marketplace.json: ${
|
|
208
|
+
error: `Failed to parse marketplace.json: ${getErrorMessage(err)}`
|
|
208
209
|
};
|
|
209
210
|
}
|
|
210
211
|
|
|
@@ -293,7 +294,7 @@ export function inspectPlugin(
|
|
|
293
294
|
}
|
|
294
295
|
} catch (err) {
|
|
295
296
|
// Fall back to marketplace inline or derived
|
|
296
|
-
result.error = `Failed to parse plugin.json: ${
|
|
297
|
+
result.error = `Failed to parse plugin.json: ${getErrorMessage(err)}`;
|
|
297
298
|
}
|
|
298
299
|
}
|
|
299
300
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { existsSync, lstatSync, mkdirSync, readdirSync, renameSync, cpSync, rmSync, symlinkSync } from "node:fs";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { externalGsdRoot } from "./repo-identity.js";
|
|
12
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
12
13
|
|
|
13
14
|
export interface MigrationResult {
|
|
14
15
|
migrated: boolean;
|
|
@@ -47,7 +48,7 @@ export function migrateToExternalState(basePath: string): MigrationResult {
|
|
|
47
48
|
return { migrated: false, error: ".gsd exists but is not a directory or symlink" };
|
|
48
49
|
}
|
|
49
50
|
} catch (err) {
|
|
50
|
-
return { migrated: false, error: `Cannot stat .gsd: ${
|
|
51
|
+
return { migrated: false, error: `Cannot stat .gsd: ${getErrorMessage(err)}` };
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
const externalPath = externalGsdRoot(basePath);
|
|
@@ -114,7 +115,7 @@ export function migrateToExternalState(basePath: string): MigrationResult {
|
|
|
114
115
|
|
|
115
116
|
return {
|
|
116
117
|
migrated: false,
|
|
117
|
-
error: `Migration failed: ${
|
|
118
|
+
error: `Migration failed: ${getErrorMessage(err)}`,
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
}
|
|
@@ -9,6 +9,7 @@ import { randomInt } from "node:crypto";
|
|
|
9
9
|
import { readdirSync, existsSync } from "node:fs";
|
|
10
10
|
import { milestonesDir } from "./paths.js";
|
|
11
11
|
import { loadQueueOrder, sortByQueueOrder } from "./queue-order.js";
|
|
12
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
12
13
|
|
|
13
14
|
// ─── Regex ──────────────────────────────────────────────────────────────────
|
|
14
15
|
|
|
@@ -88,7 +89,7 @@ export function findMilestoneIds(basePath: string): string[] {
|
|
|
88
89
|
} catch (err) {
|
|
89
90
|
// Log why milestone scanning failed — silent [] here causes infinite loops (#456)
|
|
90
91
|
if (existsSync(dir)) {
|
|
91
|
-
console.error(`[gsd] findMilestoneIds: .gsd/milestones/ exists but readdirSync failed — ${
|
|
92
|
+
console.error(`[gsd] findMilestoneIds: .gsd/milestones/ exists but readdirSync failed — ${getErrorMessage(err)}`);
|
|
92
93
|
}
|
|
93
94
|
return [];
|
|
94
95
|
}
|
|
@@ -10,6 +10,7 @@ import { existsSync, readFileSync, unlinkSync, rmSync } from "node:fs";
|
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { GSDError, GSD_GIT_ERROR } from "./errors.js";
|
|
12
12
|
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
13
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
13
14
|
|
|
14
15
|
// Issue #453: keep auto-mode bookkeeping on the stable git CLI path unless a
|
|
15
16
|
// caller explicitly opts into the native helper.
|
|
@@ -716,7 +717,7 @@ export function nativeCommit(
|
|
|
716
717
|
try {
|
|
717
718
|
return native.gitCommit(basePath, message, options?.allowEmpty);
|
|
718
719
|
} catch (e) {
|
|
719
|
-
const msg =
|
|
720
|
+
const msg = getErrorMessage(e);
|
|
720
721
|
if (msg.includes("nothing to commit")) return null;
|
|
721
722
|
throw e;
|
|
722
723
|
}
|
|
@@ -11,6 +11,7 @@ import { mergeMilestoneToMain } from "./auto-worktree.js";
|
|
|
11
11
|
import { MergeConflictError } from "./git-service.js";
|
|
12
12
|
import { removeSessionStatus } from "./session-status-io.js";
|
|
13
13
|
import type { WorkerInfo } from "./parallel-orchestrator.js";
|
|
14
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
14
15
|
|
|
15
16
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
16
17
|
|
|
@@ -99,7 +100,7 @@ export async function mergeCompletedMilestone(
|
|
|
99
100
|
return {
|
|
100
101
|
milestoneId,
|
|
101
102
|
success: false,
|
|
102
|
-
error:
|
|
103
|
+
error: getErrorMessage(err),
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
106
|
}
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
analyzeParallelEligibility,
|
|
39
39
|
type ParallelCandidates,
|
|
40
40
|
} from "./parallel-eligibility.js";
|
|
41
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
41
42
|
|
|
42
43
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
43
44
|
|
|
@@ -363,7 +364,7 @@ export async function startParallel(
|
|
|
363
364
|
|
|
364
365
|
started.push(mid);
|
|
365
366
|
} catch (err) {
|
|
366
|
-
const message =
|
|
367
|
+
const message = getErrorMessage(err);
|
|
367
368
|
errors.push({ mid, error: message });
|
|
368
369
|
}
|
|
369
370
|
}
|
|
@@ -15,6 +15,7 @@ import { join } from "node:path";
|
|
|
15
15
|
import { loadPrompt } from "./prompt-loader.js";
|
|
16
16
|
import { gsdRoot } from "./paths.js";
|
|
17
17
|
import { createGitService, runGit } from "./git-service.js";
|
|
18
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
18
19
|
|
|
19
20
|
// ─── Quick Task Helpers ───────────────────────────────────────────────────────
|
|
20
21
|
|
|
@@ -122,7 +123,7 @@ export async function handleQuick(
|
|
|
122
123
|
}
|
|
123
124
|
} catch (err) {
|
|
124
125
|
// Branch creation failed — continue on current branch
|
|
125
|
-
const message =
|
|
126
|
+
const message = getErrorMessage(err);
|
|
126
127
|
ctx.ui.notify(`Could not create branch ${branchName}: ${message}. Working on current branch.`, "warning");
|
|
127
128
|
}
|
|
128
129
|
}
|
|
@@ -154,12 +154,23 @@ export function acquireSessionLock(basePath: string): SessionLockResult {
|
|
|
154
154
|
// Retry acquisition after cleanup
|
|
155
155
|
const release = lockfile.lockSync(gsdDir, {
|
|
156
156
|
realpath: false,
|
|
157
|
-
stale:
|
|
157
|
+
stale: 1_800_000, // 30 minutes — match primary lock settings
|
|
158
158
|
update: 10_000,
|
|
159
|
+
onCompromised: () => {
|
|
160
|
+
_lockCompromised = true;
|
|
161
|
+
},
|
|
159
162
|
});
|
|
160
163
|
_releaseFunction = release;
|
|
161
164
|
_lockedPath = basePath;
|
|
162
165
|
_lockPid = process.pid;
|
|
166
|
+
|
|
167
|
+
// Safety net for retry path too
|
|
168
|
+
const retryLockDir = join(gsdDir + ".lock");
|
|
169
|
+
process.once("exit", () => {
|
|
170
|
+
try { if (_releaseFunction) { _releaseFunction(); _releaseFunction = null; } } catch {}
|
|
171
|
+
try { if (existsSync(retryLockDir)) rmSync(retryLockDir, { recursive: true, force: true }); } catch {}
|
|
172
|
+
});
|
|
173
|
+
|
|
163
174
|
atomicWriteSync(lp, JSON.stringify(lockData, null, 2));
|
|
164
175
|
return { acquired: true };
|
|
165
176
|
} catch {
|
|
@@ -91,7 +91,7 @@ test("compression: buildPlanMilestonePrompt minimal drops project/requirements/d
|
|
|
91
91
|
// The plan-milestone builder should gate root file inlining on inlineLevel
|
|
92
92
|
assert.ok(
|
|
93
93
|
promptsSrc.includes('inlineLevel !== "minimal"') &&
|
|
94
|
-
promptsSrc.includes(
|
|
94
|
+
promptsSrc.includes("inlineProjectFromDb(base)"),
|
|
95
95
|
"plan-milestone should conditionally include project.md based on level",
|
|
96
96
|
);
|
|
97
97
|
});
|
|
@@ -34,6 +34,7 @@ import type { FileLineStat } from "./worktree-manager.js";
|
|
|
34
34
|
import { existsSync, realpathSync, readdirSync, rmSync, unlinkSync } from "node:fs";
|
|
35
35
|
import { nativeMergeAbort } from "./native-git-bridge.js";
|
|
36
36
|
import { join, sep } from "node:path";
|
|
37
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* Tracks the original project root so we can switch back.
|
|
@@ -370,7 +371,7 @@ async function handleCreate(
|
|
|
370
371
|
"info",
|
|
371
372
|
);
|
|
372
373
|
} catch (error) {
|
|
373
|
-
const msg =
|
|
374
|
+
const msg = getErrorMessage(error);
|
|
374
375
|
ctx.ui.notify(`Failed to create worktree: ${msg}`, "error");
|
|
375
376
|
}
|
|
376
377
|
}
|
|
@@ -418,7 +419,7 @@ async function handleSwitch(
|
|
|
418
419
|
"info",
|
|
419
420
|
);
|
|
420
421
|
} catch (error) {
|
|
421
|
-
const msg =
|
|
422
|
+
const msg = getErrorMessage(error);
|
|
422
423
|
ctx.ui.notify(`Failed to switch to worktree: ${msg}`, "error");
|
|
423
424
|
}
|
|
424
425
|
}
|
|
@@ -528,7 +529,7 @@ async function handleList(
|
|
|
528
529
|
|
|
529
530
|
ctx.ui.notify(lines.join("\n"), "info");
|
|
530
531
|
} catch (error) {
|
|
531
|
-
const msg =
|
|
532
|
+
const msg = getErrorMessage(error);
|
|
532
533
|
ctx.ui.notify(`Failed to list worktrees: ${msg}`, "error");
|
|
533
534
|
}
|
|
534
535
|
}
|
|
@@ -646,7 +647,7 @@ async function handleMerge(
|
|
|
646
647
|
);
|
|
647
648
|
return;
|
|
648
649
|
} catch (mergeErr) {
|
|
649
|
-
const mergeMsg =
|
|
650
|
+
const mergeMsg = getErrorMessage(mergeErr);
|
|
650
651
|
const isConflict = /conflict/i.test(mergeMsg);
|
|
651
652
|
|
|
652
653
|
if (isConflict) {
|
|
@@ -703,7 +704,7 @@ async function handleMerge(
|
|
|
703
704
|
"info",
|
|
704
705
|
);
|
|
705
706
|
} catch (error) {
|
|
706
|
-
const msg =
|
|
707
|
+
const msg = getErrorMessage(error);
|
|
707
708
|
ctx.ui.notify(`Failed to start merge: ${msg}`, "error");
|
|
708
709
|
}
|
|
709
710
|
}
|
|
@@ -746,7 +747,7 @@ async function handleRemove(
|
|
|
746
747
|
|
|
747
748
|
ctx.ui.notify(`${CLR.ok("✓")} Worktree ${CLR.name(name)} removed ${CLR.muted("(branch deleted)")}.`, "info");
|
|
748
749
|
} catch (error) {
|
|
749
|
-
const msg =
|
|
750
|
+
const msg = getErrorMessage(error);
|
|
750
751
|
ctx.ui.notify(`Failed to remove worktree: ${msg}`, "error");
|
|
751
752
|
}
|
|
752
753
|
}
|
|
@@ -800,7 +801,7 @@ async function handleRemoveAll(
|
|
|
800
801
|
if (failed.length > 0) lines.push(`${CLR.warn("✗")} Failed: ${failed.map(n => CLR.name(n)).join(", ")}`);
|
|
801
802
|
ctx.ui.notify(lines.join("\n"), failed.length > 0 ? "warning" : "info");
|
|
802
803
|
} catch (error) {
|
|
803
|
-
const msg =
|
|
804
|
+
const msg = getErrorMessage(error);
|
|
804
805
|
ctx.ui.notify(`Failed to remove worktrees: ${msg}`, "error");
|
|
805
806
|
}
|
|
806
807
|
}
|
package/package.json
CHANGED
|
@@ -189,30 +189,52 @@ export async function inlineGsdRootFile(
|
|
|
189
189
|
// ─── DB-Aware Inline Helpers ──────────────────────────────────────────────
|
|
190
190
|
|
|
191
191
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
192
|
+
* Shared DB-fallback pattern: attempt a DB query via the context-store, format
|
|
193
|
+
* the result, and fall back to the filesystem file when the DB is unavailable
|
|
194
|
+
* or the query yields no results.
|
|
195
|
+
*
|
|
196
|
+
* @param base Project root for filesystem fallback
|
|
197
|
+
* @param label Section heading (e.g. "Decisions")
|
|
198
|
+
* @param filename Filesystem fallback file (e.g. "decisions.md")
|
|
199
|
+
* @param queryDb Async callback receiving the dynamically-imported
|
|
200
|
+
* context-store module. Returns formatted markdown or null.
|
|
194
201
|
*/
|
|
195
|
-
|
|
196
|
-
base: string,
|
|
202
|
+
async function inlineFromDbOrFile(
|
|
203
|
+
base: string,
|
|
204
|
+
label: string,
|
|
205
|
+
filename: string,
|
|
206
|
+
queryDb: (cs: typeof import("./context-store.js")) => string | null,
|
|
197
207
|
): Promise<string | null> {
|
|
198
|
-
const inlineLevel = level ?? resolveInlineLevel();
|
|
199
208
|
try {
|
|
200
209
|
const { isDbAvailable } = await import("./gsd-db.js");
|
|
201
210
|
if (isDbAvailable()) {
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
const formatted = inlineLevel !== "full"
|
|
207
|
-
? formatDecisionsCompact(decisions)
|
|
208
|
-
: formatDecisionsForPrompt(decisions);
|
|
209
|
-
return `### Decisions\nSource: \`.gsd/DECISIONS.md\`\n\n${formatted}`;
|
|
211
|
+
const contextStore = await import("./context-store.js");
|
|
212
|
+
const content = queryDb(contextStore);
|
|
213
|
+
if (content) {
|
|
214
|
+
return `### ${label}\nSource: \`.gsd/${filename.toUpperCase().replace(/\.MD$/i, "")}.md\`\n\n${content}`;
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
217
|
} catch {
|
|
213
218
|
// DB not available — fall through to filesystem
|
|
214
219
|
}
|
|
215
|
-
return inlineGsdRootFile(base,
|
|
220
|
+
return inlineGsdRootFile(base, filename, label);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Inline decisions with optional milestone scoping from the DB.
|
|
225
|
+
* Falls back to filesystem via inlineGsdRootFile when DB unavailable or empty.
|
|
226
|
+
*/
|
|
227
|
+
export async function inlineDecisionsFromDb(
|
|
228
|
+
base: string, milestoneId?: string, scope?: string, level?: InlineLevel,
|
|
229
|
+
): Promise<string | null> {
|
|
230
|
+
const inlineLevel = level ?? resolveInlineLevel();
|
|
231
|
+
return inlineFromDbOrFile(base, "Decisions", "decisions.md", (cs) => {
|
|
232
|
+
const decisions = cs.queryDecisions({ milestoneId, scope });
|
|
233
|
+
if (decisions.length === 0) return null;
|
|
234
|
+
return inlineLevel !== "full"
|
|
235
|
+
? formatDecisionsCompact(decisions)
|
|
236
|
+
: cs.formatDecisionsForPrompt(decisions);
|
|
237
|
+
});
|
|
216
238
|
}
|
|
217
239
|
|
|
218
240
|
/**
|
|
@@ -223,23 +245,13 @@ export async function inlineRequirementsFromDb(
|
|
|
223
245
|
base: string, sliceId?: string, level?: InlineLevel,
|
|
224
246
|
): Promise<string | null> {
|
|
225
247
|
const inlineLevel = level ?? resolveInlineLevel();
|
|
226
|
-
|
|
227
|
-
const {
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const formatted = inlineLevel !== "full"
|
|
234
|
-
? formatRequirementsCompact(requirements)
|
|
235
|
-
: formatRequirementsForPrompt(requirements);
|
|
236
|
-
return `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${formatted}`;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
} catch {
|
|
240
|
-
// DB not available — fall through to filesystem
|
|
241
|
-
}
|
|
242
|
-
return inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
248
|
+
return inlineFromDbOrFile(base, "Requirements", "requirements.md", (cs) => {
|
|
249
|
+
const requirements = cs.queryRequirements({ sliceId });
|
|
250
|
+
if (requirements.length === 0) return null;
|
|
251
|
+
return inlineLevel !== "full"
|
|
252
|
+
? formatRequirementsCompact(requirements)
|
|
253
|
+
: cs.formatRequirementsForPrompt(requirements);
|
|
254
|
+
});
|
|
243
255
|
}
|
|
244
256
|
|
|
245
257
|
/**
|
|
@@ -249,19 +261,9 @@ export async function inlineRequirementsFromDb(
|
|
|
249
261
|
export async function inlineProjectFromDb(
|
|
250
262
|
base: string,
|
|
251
263
|
): Promise<string | null> {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const { queryProject } = await import("./context-store.js");
|
|
256
|
-
const content = queryProject();
|
|
257
|
-
if (content) {
|
|
258
|
-
return `### Project\nSource: \`.gsd/PROJECT.md\`\n\n${content}`;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
} catch {
|
|
262
|
-
// DB not available — fall through to filesystem
|
|
263
|
-
}
|
|
264
|
-
return inlineGsdRootFile(base, "project.md", "Project");
|
|
264
|
+
return inlineFromDbOrFile(base, "Project", "project.md", (cs) => {
|
|
265
|
+
return cs.queryProject();
|
|
266
|
+
});
|
|
265
267
|
}
|
|
266
268
|
|
|
267
269
|
// ─── Skill Discovery ──────────────────────────────────────────────────────
|
|
@@ -63,6 +63,7 @@ import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath } from "./debug-
|
|
|
63
63
|
import type { AutoSession } from "./auto/session.js";
|
|
64
64
|
import { existsSync, mkdirSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
65
65
|
import { join } from "node:path";
|
|
66
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
66
67
|
|
|
67
68
|
export interface BootstrapDeps {
|
|
68
69
|
shouldUseWorktreeIsolation: () => boolean;
|
|
@@ -201,11 +202,11 @@ export async function bootstrapAutoSession(
|
|
|
201
202
|
if (!midMatch) continue;
|
|
202
203
|
const mid = midMatch[1];
|
|
203
204
|
if (resolveMilestoneFile(base, mid, "SUMMARY")) {
|
|
204
|
-
try { unlinkSync(join(runtimeUnitsDir, file)); } catch (e) { debugLog("stale-unit-cleanup-failed", { file, error:
|
|
205
|
+
try { unlinkSync(join(runtimeUnitsDir, file)); } catch (e) { debugLog("stale-unit-cleanup-failed", { file, error: getErrorMessage(e) }); }
|
|
205
206
|
}
|
|
206
207
|
}
|
|
207
208
|
}
|
|
208
|
-
} catch (e) { debugLog("stale-unit-dir-cleanup-failed", { error:
|
|
209
|
+
} catch (e) { debugLog("stale-unit-dir-cleanup-failed", { error: getErrorMessage(e) }); }
|
|
209
210
|
|
|
210
211
|
let state = await deriveState(base);
|
|
211
212
|
|
|
@@ -343,7 +344,7 @@ export async function bootstrapAutoSession(
|
|
|
343
344
|
registerSigtermHandler(s.originalBasePath);
|
|
344
345
|
} catch (err) {
|
|
345
346
|
ctx.ui.notify(
|
|
346
|
-
`Auto-worktree setup failed: ${
|
|
347
|
+
`Auto-worktree setup failed: ${getErrorMessage(err)}. Continuing in project root.`,
|
|
347
348
|
"warning",
|
|
348
349
|
);
|
|
349
350
|
}
|
|
@@ -435,7 +436,7 @@ export async function bootstrapAutoSession(
|
|
|
435
436
|
}
|
|
436
437
|
} catch (err) {
|
|
437
438
|
ctx.ui.notify(
|
|
438
|
-
`Secrets check error: ${
|
|
439
|
+
`Secrets check error: ${getErrorMessage(err)}. Continuing without secrets.`,
|
|
439
440
|
"warning",
|
|
440
441
|
);
|
|
441
442
|
}
|
|
@@ -453,7 +454,7 @@ export async function bootstrapAutoSession(
|
|
|
453
454
|
ctx.ui.notify("Removed stale .git/index.lock from prior crash.", "info");
|
|
454
455
|
}
|
|
455
456
|
}
|
|
456
|
-
} catch (e) { debugLog("git-lock-cleanup-failed", { error:
|
|
457
|
+
} catch (e) { debugLog("git-lock-cleanup-failed", { error: getErrorMessage(e) }); }
|
|
457
458
|
|
|
458
459
|
// Pre-flight: validate milestone queue
|
|
459
460
|
try {
|
|
@@ -20,6 +20,7 @@ import { closeoutUnit, type CloseoutOptions } from "./auto-unit-closeout.js";
|
|
|
20
20
|
import { saveActivityLog } from "./activity-log.js";
|
|
21
21
|
import { recoverTimedOutUnit, type RecoveryContext } from "./auto-timeout-recovery.js";
|
|
22
22
|
import type { AutoSession } from "./auto/session.js";
|
|
23
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
23
24
|
|
|
24
25
|
export interface SupervisionContext {
|
|
25
26
|
s: AutoSession;
|
|
@@ -127,7 +128,7 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
127
128
|
);
|
|
128
129
|
await pauseAuto(ctx, pi);
|
|
129
130
|
} catch (err) {
|
|
130
|
-
const message =
|
|
131
|
+
const message = getErrorMessage(err);
|
|
131
132
|
console.error(`[idle-watchdog] Unhandled error: ${message}`);
|
|
132
133
|
try {
|
|
133
134
|
ctx.ui.notify(`Idle watchdog error: ${message}`, "warning");
|
|
@@ -159,7 +160,7 @@ export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
|
159
160
|
);
|
|
160
161
|
await pauseAuto(ctx, pi);
|
|
161
162
|
} catch (err) {
|
|
162
|
-
const message =
|
|
163
|
+
const message = getErrorMessage(err);
|
|
163
164
|
console.error(`[hard-timeout] Unhandled error: ${message}`);
|
|
164
165
|
try {
|
|
165
166
|
ctx.ui.notify(`Hard timeout error: ${message}`, "warning");
|
|
@@ -24,6 +24,7 @@ import { writeVerificationJSON } from "./verification-evidence.js";
|
|
|
24
24
|
import { removePersistedKey } from "./auto-recovery.js";
|
|
25
25
|
import type { AutoSession, PendingVerificationRetry } from "./auto/session.js";
|
|
26
26
|
import { join } from "node:path";
|
|
27
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
27
28
|
|
|
28
29
|
export interface VerificationContext {
|
|
29
30
|
s: AutoSession;
|
|
@@ -204,7 +205,7 @@ export async function runPostUnitVerification(
|
|
|
204
205
|
try {
|
|
205
206
|
await dispatchNextUnit(ctx, pi);
|
|
206
207
|
} catch (retryDispatchErr) {
|
|
207
|
-
const msg =
|
|
208
|
+
const msg = getErrorMessage(retryDispatchErr);
|
|
208
209
|
ctx.ui.notify(`Verification retry dispatch error: ${msg}`, "error");
|
|
209
210
|
startDispatchGapWatchdog(ctx, pi);
|
|
210
211
|
}
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
nativeBranchDelete,
|
|
39
39
|
nativeBranchExists,
|
|
40
40
|
} from "./native-git-bridge.js";
|
|
41
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
41
42
|
|
|
42
43
|
// ─── Module State ──────────────────────────────────────────────────────────
|
|
43
44
|
|
|
@@ -81,7 +82,7 @@ export function runWorktreePostCreateHook(sourceDir: string, worktreeDir: string
|
|
|
81
82
|
});
|
|
82
83
|
return null;
|
|
83
84
|
} catch (err) {
|
|
84
|
-
const msg =
|
|
85
|
+
const msg = getErrorMessage(err);
|
|
85
86
|
return `Worktree post-create hook failed: ${msg}`;
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -141,7 +142,7 @@ export function createAutoWorktree(basePath: string, milestoneId: string): strin
|
|
|
141
142
|
// Don't store originalBase -- caller can retry or clean up.
|
|
142
143
|
throw new GSDError(
|
|
143
144
|
GSD_IO_ERROR,
|
|
144
|
-
`Auto-worktree created at ${info.path} but chdir failed: ${
|
|
145
|
+
`Auto-worktree created at ${info.path} but chdir failed: ${getErrorMessage(err)}`,
|
|
145
146
|
);
|
|
146
147
|
}
|
|
147
148
|
|
|
@@ -168,7 +169,7 @@ export function teardownAutoWorktree(
|
|
|
168
169
|
} catch (err) {
|
|
169
170
|
throw new GSDError(
|
|
170
171
|
GSD_IO_ERROR,
|
|
171
|
-
`Failed to chdir back to ${originalBasePath} during teardown: ${
|
|
172
|
+
`Failed to chdir back to ${originalBasePath} during teardown: ${getErrorMessage(err)}`,
|
|
172
173
|
);
|
|
173
174
|
}
|
|
174
175
|
|
|
@@ -274,7 +275,7 @@ export function enterAutoWorktree(basePath: string, milestoneId: string): string
|
|
|
274
275
|
} catch (err) {
|
|
275
276
|
throw new GSDError(
|
|
276
277
|
GSD_IO_ERROR,
|
|
277
|
-
`Failed to enter auto-worktree at ${p}: ${
|
|
278
|
+
`Failed to enter auto-worktree at ${p}: ${getErrorMessage(err)}`,
|
|
278
279
|
);
|
|
279
280
|
}
|
|
280
281
|
|