gsd-pi 2.37.1-dev.d3ace49 → 2.38.0-dev.29edcdc
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/app-paths.js +1 -1
- package/dist/cli.js +9 -0
- package/dist/extension-discovery.d.ts +5 -3
- package/dist/extension-discovery.js +14 -9
- package/dist/extension-registry.js +2 -2
- package/dist/remote-questions-config.js +2 -2
- package/dist/resource-loader.js +34 -1
- package/dist/resources/extensions/browser-tools/package.json +3 -1
- package/dist/resources/extensions/cmux/index.js +55 -1
- package/dist/resources/extensions/context7/package.json +1 -1
- package/dist/resources/extensions/env-utils.js +29 -0
- package/dist/resources/extensions/get-secrets-from-user.js +5 -24
- package/dist/resources/extensions/github-sync/cli.js +284 -0
- package/dist/resources/extensions/github-sync/index.js +73 -0
- package/dist/resources/extensions/github-sync/mapping.js +67 -0
- package/dist/resources/extensions/github-sync/sync.js +424 -0
- package/dist/resources/extensions/github-sync/templates.js +118 -0
- package/dist/resources/extensions/github-sync/types.js +7 -0
- package/dist/resources/extensions/google-search/package.json +3 -1
- package/dist/resources/extensions/gsd/auto/session.js +6 -23
- package/dist/resources/extensions/gsd/auto-dispatch.js +8 -9
- package/dist/resources/extensions/gsd/auto-loop.js +597 -588
- package/dist/resources/extensions/gsd/auto-post-unit.js +99 -70
- package/dist/resources/extensions/gsd/auto-prompts.js +23 -43
- package/dist/resources/extensions/gsd/auto-start.js +13 -2
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +13 -5
- package/dist/resources/extensions/gsd/auto-worktree.js +3 -3
- package/dist/resources/extensions/gsd/auto.js +143 -96
- package/dist/resources/extensions/gsd/captures.js +9 -1
- package/dist/resources/extensions/gsd/commands-extensions.js +3 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +16 -3
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
- package/dist/resources/extensions/gsd/commands.js +24 -3
- package/dist/resources/extensions/gsd/context-budget.js +2 -10
- package/dist/resources/extensions/gsd/detection.js +1 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +0 -2
- package/dist/resources/extensions/gsd/doctor-checks.js +82 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +78 -0
- package/dist/resources/extensions/gsd/doctor-format.js +15 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +27 -11
- package/dist/resources/extensions/gsd/doctor.js +204 -12
- package/dist/resources/extensions/gsd/exit-command.js +2 -1
- package/dist/resources/extensions/gsd/export.js +1 -1
- package/dist/resources/extensions/gsd/files.js +6 -2
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-service.js +15 -12
- package/dist/resources/extensions/gsd/guided-flow.js +82 -32
- package/dist/resources/extensions/gsd/index.js +24 -20
- package/dist/resources/extensions/gsd/migrate/parsers.js +1 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +37 -0
- package/dist/resources/extensions/gsd/package.json +1 -1
- package/dist/resources/extensions/gsd/preferences-models.js +0 -12
- package/dist/resources/extensions/gsd/preferences-types.js +1 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +59 -11
- package/dist/resources/extensions/gsd/preferences.js +8 -5
- package/dist/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -8
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +11 -8
- package/dist/resources/extensions/gsd/prompts/run-uat.md +27 -10
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/dist/resources/extensions/gsd/repo-identity.js +21 -4
- package/dist/resources/extensions/gsd/resource-version.js +2 -1
- package/dist/resources/extensions/gsd/roadmap-mutations.js +24 -0
- package/dist/resources/extensions/gsd/state.js +1 -1
- package/dist/resources/extensions/gsd/visualizer-data.js +1 -1
- package/dist/resources/extensions/gsd/worktree.js +35 -16
- package/dist/resources/extensions/mcp-client/index.js +14 -1
- package/dist/resources/extensions/remote-questions/status.js +2 -1
- package/dist/resources/extensions/remote-questions/store.js +2 -1
- package/dist/resources/extensions/search-the-web/provider.js +2 -1
- package/dist/resources/extensions/subagent/index.js +12 -3
- package/dist/resources/extensions/subagent/isolation.js +2 -1
- package/dist/resources/extensions/ttsr/rule-loader.js +2 -1
- package/dist/resources/extensions/universal-config/package.json +1 -1
- package/dist/welcome-screen.d.ts +12 -0
- package/dist/welcome-screen.js +53 -0
- package/package.json +1 -1
- package/packages/pi-ai/dist/utils/oauth/anthropic.js +2 -2
- package/packages/pi-ai/dist/utils/oauth/anthropic.js.map +1 -1
- package/packages/pi-ai/src/utils/oauth/anthropic.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +205 -7
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +8 -4
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +223 -7
- package/packages/pi-coding-agent/src/core/package-manager.ts +8 -4
- package/pkg/package.json +1 -1
- package/src/resources/extensions/cmux/index.ts +57 -1
- package/src/resources/extensions/env-utils.ts +31 -0
- package/src/resources/extensions/get-secrets-from-user.ts +5 -24
- package/src/resources/extensions/github-sync/cli.ts +364 -0
- package/src/resources/extensions/github-sync/index.ts +93 -0
- package/src/resources/extensions/github-sync/mapping.ts +81 -0
- package/src/resources/extensions/github-sync/sync.ts +556 -0
- package/src/resources/extensions/github-sync/templates.ts +183 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +20 -0
- package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +39 -0
- package/src/resources/extensions/github-sync/tests/mapping.test.ts +104 -0
- package/src/resources/extensions/github-sync/tests/templates.test.ts +110 -0
- package/src/resources/extensions/github-sync/types.ts +47 -0
- package/src/resources/extensions/gsd/auto/session.ts +7 -25
- package/src/resources/extensions/gsd/auto-dispatch.ts +7 -9
- package/src/resources/extensions/gsd/auto-loop.ts +484 -546
- package/src/resources/extensions/gsd/auto-post-unit.ts +80 -44
- package/src/resources/extensions/gsd/auto-prompts.ts +25 -45
- package/src/resources/extensions/gsd/auto-start.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +15 -4
- package/src/resources/extensions/gsd/auto-worktree.ts +3 -3
- package/src/resources/extensions/gsd/auto.ts +139 -101
- package/src/resources/extensions/gsd/captures.ts +10 -1
- package/src/resources/extensions/gsd/commands-extensions.ts +4 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +17 -2
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
- package/src/resources/extensions/gsd/commands.ts +26 -4
- package/src/resources/extensions/gsd/context-budget.ts +2 -12
- package/src/resources/extensions/gsd/detection.ts +2 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +0 -2
- package/src/resources/extensions/gsd/doctor-checks.ts +75 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +82 -1
- package/src/resources/extensions/gsd/doctor-format.ts +20 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +26 -9
- package/src/resources/extensions/gsd/doctor-types.ts +16 -1
- package/src/resources/extensions/gsd/doctor.ts +199 -14
- package/src/resources/extensions/gsd/exit-command.ts +2 -2
- package/src/resources/extensions/gsd/export.ts +1 -1
- package/src/resources/extensions/gsd/files.ts +5 -3
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-service.ts +20 -10
- package/src/resources/extensions/gsd/guided-flow.ts +110 -38
- package/src/resources/extensions/gsd/index.ts +24 -17
- package/src/resources/extensions/gsd/migrate/parsers.ts +1 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +37 -0
- package/src/resources/extensions/gsd/preferences-models.ts +0 -12
- package/src/resources/extensions/gsd/preferences-types.ts +4 -4
- package/src/resources/extensions/gsd/preferences-validation.ts +51 -11
- package/src/resources/extensions/gsd/preferences.ts +8 -5
- package/src/resources/extensions/gsd/prompts/discuss.md +11 -14
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +11 -12
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -10
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +4 -8
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +11 -8
- package/src/resources/extensions/gsd/prompts/run-uat.md +27 -10
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -2
- package/src/resources/extensions/gsd/repo-identity.ts +23 -4
- package/src/resources/extensions/gsd/resource-version.ts +3 -1
- package/src/resources/extensions/gsd/roadmap-mutations.ts +29 -0
- package/src/resources/extensions/gsd/state.ts +1 -1
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +21 -18
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +122 -68
- package/src/resources/extensions/gsd/tests/cmux.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +266 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +86 -3
- package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -7
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +11 -3
- package/src/resources/extensions/gsd/tests/worktree.test.ts +47 -0
- package/src/resources/extensions/gsd/types.ts +0 -1
- package/src/resources/extensions/gsd/visualizer-data.ts +1 -1
- package/src/resources/extensions/gsd/worktree.ts +35 -15
- package/src/resources/extensions/mcp-client/index.ts +17 -1
- package/src/resources/extensions/remote-questions/status.ts +3 -1
- package/src/resources/extensions/remote-questions/store.ts +3 -1
- package/src/resources/extensions/search-the-web/provider.ts +2 -1
- package/src/resources/extensions/subagent/index.ts +12 -3
- package/src/resources/extensions/subagent/isolation.ts +3 -1
- package/src/resources/extensions/ttsr/rule-loader.ts +3 -1
- package/dist/resources/extensions/gsd/prompt-compressor.js +0 -393
- package/dist/resources/extensions/gsd/semantic-chunker.js +0 -254
- package/dist/resources/extensions/gsd/summary-distiller.js +0 -212
- package/src/resources/extensions/gsd/prompt-compressor.ts +0 -508
- package/src/resources/extensions/gsd/semantic-chunker.ts +0 -336
- package/src/resources/extensions/gsd/summary-distiller.ts +0 -258
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +0 -193
- package/src/resources/extensions/gsd/tests/prompt-compressor.test.ts +0 -529
- package/src/resources/extensions/gsd/tests/semantic-chunker.test.ts +0 -426
- package/src/resources/extensions/gsd/tests/summary-distiller.test.ts +0 -323
- package/src/resources/extensions/gsd/tests/token-optimization-benchmark.test.ts +0 -1272
- package/src/resources/extensions/gsd/tests/token-optimization-prefs.test.ts +0 -164
|
@@ -33,7 +33,6 @@ import { writeUnitRuntimeRecord, clearUnitRuntimeRecord } from "./unit-runtime.j
|
|
|
33
33
|
import { runGSDDoctor, rebuildState, summarizeDoctorIssues } from "./doctor.js";
|
|
34
34
|
import { recordHealthSnapshot, checkHealEscalation } from "./doctor-proactive.js";
|
|
35
35
|
import { syncStateToProjectRoot } from "./auto-worktree-sync.js";
|
|
36
|
-
import { resetRewriteCircuitBreaker } from "./auto-dispatch.js";
|
|
37
36
|
import { isDbAvailable } from "./gsd-db.js";
|
|
38
37
|
import { consumeSignal } from "./session-status-io.js";
|
|
39
38
|
import {
|
|
@@ -56,6 +55,13 @@ import { join } from "node:path";
|
|
|
56
55
|
/** Throttle STATE.md rebuilds — at most once per 30 seconds */
|
|
57
56
|
const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
|
|
58
57
|
|
|
58
|
+
export interface PreVerificationOpts {
|
|
59
|
+
skipSettleDelay?: boolean;
|
|
60
|
+
skipDoctor?: boolean;
|
|
61
|
+
skipStateRebuild?: boolean;
|
|
62
|
+
skipWorktreeSync?: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
59
65
|
export interface PostUnitContext {
|
|
60
66
|
s: AutoSession;
|
|
61
67
|
ctx: ExtensionContext;
|
|
@@ -73,7 +79,7 @@ export interface PostUnitContext {
|
|
|
73
79
|
*
|
|
74
80
|
* Returns "dispatched" if a signal caused stop/pause, "continue" to proceed.
|
|
75
81
|
*/
|
|
76
|
-
export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"dispatched" | "continue"> {
|
|
82
|
+
export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreVerificationOpts): Promise<"dispatched" | "continue"> {
|
|
77
83
|
const { s, ctx, pi, buildSnapshotOpts, stopAuto, pauseAuto } = pctx;
|
|
78
84
|
|
|
79
85
|
// ── Parallel worker signal check ──
|
|
@@ -95,8 +101,10 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
95
101
|
// Invalidate all caches
|
|
96
102
|
invalidateAllCaches();
|
|
97
103
|
|
|
98
|
-
// Small delay to let files settle
|
|
99
|
-
|
|
104
|
+
// Small delay to let files settle (skipped for sidecars where latency matters more)
|
|
105
|
+
if (!opts?.skipSettleDelay) {
|
|
106
|
+
await new Promise(r => setTimeout(r, 100));
|
|
107
|
+
}
|
|
100
108
|
|
|
101
109
|
// Auto-commit
|
|
102
110
|
if (s.currentUnit) {
|
|
@@ -113,15 +121,25 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
113
121
|
const summaryContent = await loadFile(summaryPath);
|
|
114
122
|
if (summaryContent) {
|
|
115
123
|
const summary = parseSummary(summaryContent);
|
|
124
|
+
// Look up GitHub issue number for commit linking
|
|
125
|
+
let ghIssueNumber: number | undefined;
|
|
126
|
+
try {
|
|
127
|
+
const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
|
|
128
|
+
ghIssueNumber = getTaskIssueNumberForCommit(s.basePath, mid, sid, tid) ?? undefined;
|
|
129
|
+
} catch {
|
|
130
|
+
// GitHub sync not available — skip
|
|
131
|
+
}
|
|
132
|
+
|
|
116
133
|
taskContext = {
|
|
117
134
|
taskId: `${sid}/${tid}`,
|
|
118
135
|
taskTitle: summary.title?.replace(/^T\d+:\s*/, "") || tid,
|
|
119
136
|
oneLiner: summary.oneLiner || undefined,
|
|
120
137
|
keyFiles: summary.frontmatter.key_files?.filter(f => !f.includes("{{")) || undefined,
|
|
138
|
+
issueNumber: ghIssueNumber,
|
|
121
139
|
};
|
|
122
140
|
}
|
|
123
|
-
} catch {
|
|
124
|
-
|
|
141
|
+
} catch (e) {
|
|
142
|
+
debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
|
|
125
143
|
}
|
|
126
144
|
}
|
|
127
145
|
}
|
|
@@ -131,12 +149,20 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
131
149
|
if (commitMsg) {
|
|
132
150
|
ctx.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
|
|
133
151
|
}
|
|
134
|
-
} catch {
|
|
135
|
-
|
|
152
|
+
} catch (e) {
|
|
153
|
+
debugLog("postUnit", { phase: "auto-commit", error: String(e) });
|
|
136
154
|
}
|
|
137
155
|
|
|
138
|
-
//
|
|
156
|
+
// GitHub sync (non-blocking, opt-in)
|
|
139
157
|
try {
|
|
158
|
+
const { runGitHubSync } = await import("../github-sync/sync.js");
|
|
159
|
+
await runGitHubSync(s.basePath, s.currentUnit.type, s.currentUnit.id);
|
|
160
|
+
} catch (e) {
|
|
161
|
+
debugLog("postUnit", { phase: "github-sync", error: String(e) });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Doctor: fix mechanical bookkeeping (skipped for lightweight sidecars)
|
|
165
|
+
if (!opts?.skipDoctor) try {
|
|
140
166
|
const scopeParts = s.currentUnit.id.split("/").slice(0, 2);
|
|
141
167
|
const doctorScope = scopeParts.join("/");
|
|
142
168
|
const sliceTerminalUnits = new Set(["complete-slice", "run-uat"]);
|
|
@@ -146,13 +172,20 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
146
172
|
ctx.ui.notify(`Post-hook: applied ${report.fixesApplied.length} fix(es).`, "info");
|
|
147
173
|
}
|
|
148
174
|
|
|
149
|
-
// Proactive health tracking
|
|
150
|
-
|
|
175
|
+
// Proactive health tracking — filter to current milestone to avoid
|
|
176
|
+
// cross-milestone stale errors inflating the escalation counter
|
|
177
|
+
const currentMilestoneId = s.currentUnit.id.split("/")[0];
|
|
178
|
+
const milestoneIssues = currentMilestoneId
|
|
179
|
+
? report.issues.filter(i =>
|
|
180
|
+
i.unitId === currentMilestoneId ||
|
|
181
|
+
i.unitId.startsWith(`${currentMilestoneId}/`))
|
|
182
|
+
: report.issues;
|
|
183
|
+
const summary = summarizeDoctorIssues(milestoneIssues);
|
|
151
184
|
recordHealthSnapshot(summary.errors, summary.warnings, report.fixesApplied.length);
|
|
152
185
|
|
|
153
186
|
// Check if we should escalate to LLM-assisted heal
|
|
154
187
|
if (summary.errors > 0) {
|
|
155
|
-
const unresolvedErrors =
|
|
188
|
+
const unresolvedErrors = milestoneIssues
|
|
156
189
|
.filter(i => i.severity === "error" && !i.fixable)
|
|
157
190
|
.map(i => ({ code: i.code, message: i.message, unitId: i.unitId }));
|
|
158
191
|
const escalation = checkHealEscalation(summary.errors, unresolvedErrors);
|
|
@@ -168,24 +201,27 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
168
201
|
const reportText = formatDoctorReport(report, { scope: doctorScope, includeWarnings: true });
|
|
169
202
|
const structuredIssues = formatDoctorIssuesForPrompt(actionable);
|
|
170
203
|
dispatchDoctorHeal(pi, doctorScope, reportText, structuredIssues);
|
|
171
|
-
|
|
172
|
-
|
|
204
|
+
return "dispatched";
|
|
205
|
+
} catch (e) {
|
|
206
|
+
debugLog("postUnit", { phase: "doctor-heal-dispatch", error: String(e) });
|
|
173
207
|
}
|
|
174
208
|
}
|
|
175
209
|
}
|
|
176
|
-
} catch {
|
|
177
|
-
|
|
210
|
+
} catch (e) {
|
|
211
|
+
debugLog("postUnit", { phase: "doctor", error: String(e) });
|
|
178
212
|
}
|
|
179
213
|
|
|
180
|
-
// Throttled STATE.md rebuild
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
214
|
+
// Throttled STATE.md rebuild (skipped for lightweight sidecars)
|
|
215
|
+
if (!opts?.skipStateRebuild) {
|
|
216
|
+
const now = Date.now();
|
|
217
|
+
if (now - s.lastStateRebuildAt >= STATE_REBUILD_MIN_INTERVAL_MS) {
|
|
218
|
+
try {
|
|
219
|
+
await rebuildState(s.basePath);
|
|
220
|
+
s.lastStateRebuildAt = now;
|
|
221
|
+
autoCommitCurrentBranch(s.basePath, "state-rebuild", s.currentUnit.id);
|
|
222
|
+
} catch (e) {
|
|
223
|
+
debugLog("postUnit", { phase: "state-rebuild", error: String(e) });
|
|
224
|
+
}
|
|
189
225
|
}
|
|
190
226
|
}
|
|
191
227
|
|
|
@@ -193,16 +229,16 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
193
229
|
try {
|
|
194
230
|
const { pruneDeadProcesses } = await import("../bg-shell/process-manager.js");
|
|
195
231
|
pruneDeadProcesses();
|
|
196
|
-
} catch {
|
|
197
|
-
|
|
232
|
+
} catch (e) {
|
|
233
|
+
debugLog("postUnit", { phase: "prune-bg-shell", error: String(e) });
|
|
198
234
|
}
|
|
199
235
|
|
|
200
|
-
// Sync worktree state back to project root
|
|
201
|
-
if (s.originalBasePath && s.originalBasePath !== s.basePath) {
|
|
236
|
+
// Sync worktree state back to project root (skipped for lightweight sidecars)
|
|
237
|
+
if (!opts?.skipWorktreeSync && s.originalBasePath && s.originalBasePath !== s.basePath) {
|
|
202
238
|
try {
|
|
203
239
|
syncStateToProjectRoot(s.basePath, s.originalBasePath, s.currentMilestoneId);
|
|
204
|
-
} catch {
|
|
205
|
-
|
|
240
|
+
} catch (e) {
|
|
241
|
+
debugLog("postUnit", { phase: "worktree-sync", error: String(e) });
|
|
206
242
|
}
|
|
207
243
|
}
|
|
208
244
|
|
|
@@ -210,10 +246,10 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
210
246
|
if (s.currentUnit.type === "rewrite-docs") {
|
|
211
247
|
try {
|
|
212
248
|
await resolveAllOverrides(s.basePath);
|
|
213
|
-
|
|
249
|
+
s.rewriteAttemptCount = 0;
|
|
214
250
|
ctx.ui.notify("Override(s) resolved — rewrite-docs completed.", "info");
|
|
215
|
-
} catch {
|
|
216
|
-
|
|
251
|
+
} catch (e) {
|
|
252
|
+
debugLog("postUnit", { phase: "rewrite-docs-resolve", error: String(e) });
|
|
217
253
|
}
|
|
218
254
|
}
|
|
219
255
|
|
|
@@ -226,8 +262,8 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
226
262
|
const { clearReactiveState } = await import("./reactive-graph.js");
|
|
227
263
|
clearReactiveState(s.basePath, mid, sid);
|
|
228
264
|
}
|
|
229
|
-
} catch {
|
|
230
|
-
|
|
265
|
+
} catch (e) {
|
|
266
|
+
debugLog("postUnit", { phase: "reactive-state-cleanup", error: String(e) });
|
|
231
267
|
}
|
|
232
268
|
}
|
|
233
269
|
|
|
@@ -280,8 +316,8 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
280
316
|
if (triggerArtifactVerified) {
|
|
281
317
|
invalidateAllCaches();
|
|
282
318
|
}
|
|
283
|
-
} catch {
|
|
284
|
-
|
|
319
|
+
} catch (e) {
|
|
320
|
+
debugLog("postUnit", { phase: "artifact-verify", error: String(e) });
|
|
285
321
|
}
|
|
286
322
|
} else {
|
|
287
323
|
// Hook unit completed — finalize its runtime record
|
|
@@ -292,8 +328,8 @@ export async function postUnitPreVerification(pctx: PostUnitContext): Promise<"d
|
|
|
292
328
|
lastProgressKind: "hook-completed",
|
|
293
329
|
});
|
|
294
330
|
clearUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id);
|
|
295
|
-
} catch {
|
|
296
|
-
|
|
331
|
+
} catch (e) {
|
|
332
|
+
debugLog("postUnit", { phase: "hook-finalize", error: String(e) });
|
|
297
333
|
}
|
|
298
334
|
}
|
|
299
335
|
}
|
|
@@ -429,8 +465,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
429
465
|
}
|
|
430
466
|
}
|
|
431
467
|
}
|
|
432
|
-
} catch {
|
|
433
|
-
|
|
468
|
+
} catch (e) {
|
|
469
|
+
debugLog("postUnit", { phase: "triage-check", error: String(e) });
|
|
434
470
|
}
|
|
435
471
|
}
|
|
436
472
|
|
|
@@ -475,8 +511,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
475
511
|
);
|
|
476
512
|
|
|
477
513
|
return "continue";
|
|
478
|
-
} catch {
|
|
479
|
-
|
|
514
|
+
} catch (e) {
|
|
515
|
+
debugLog("postUnit", { phase: "quick-task-dispatch", error: String(e) });
|
|
480
516
|
}
|
|
481
517
|
}
|
|
482
518
|
|
|
@@ -20,11 +20,17 @@ import type { GSDState, InlineLevel } from "./types.js";
|
|
|
20
20
|
import type { GSDPreferences } from "./preferences.js";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import { existsSync } from "node:fs";
|
|
23
|
-
import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
|
|
24
|
-
import { compressToTarget } from "./prompt-compressor.js";
|
|
25
|
-
import { distillSummaries } from "./summary-distiller.js";
|
|
23
|
+
import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary } from "./context-budget.js";
|
|
26
24
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
27
|
-
|
|
25
|
+
|
|
26
|
+
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
const MAX_PREAMBLE_CHARS = 30_000;
|
|
29
|
+
|
|
30
|
+
function capPreamble(preamble: string): string {
|
|
31
|
+
if (preamble.length <= MAX_PREAMBLE_CHARS) return preamble;
|
|
32
|
+
return truncateAtSectionBoundary(preamble, MAX_PREAMBLE_CHARS).content;
|
|
33
|
+
}
|
|
28
34
|
|
|
29
35
|
// ─── Executor Constraints ─────────────────────────────────────────────────────
|
|
30
36
|
|
|
@@ -159,16 +165,9 @@ export async function inlineFileSmart(
|
|
|
159
165
|
return `### ${label}\nSource: \`${relPath}\`\n\n${content.trim()}`;
|
|
160
166
|
}
|
|
161
167
|
|
|
162
|
-
//
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
// If chunking didn't save much (< 20%), just include full content
|
|
166
|
-
if (result.savingsPercent < 20) {
|
|
167
|
-
return `### ${label}\nSource: \`${relPath}\`\n\n${content.trim()}`;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const formatted = formatChunks(result, relPath);
|
|
171
|
-
return `### ${label} (${result.omittedChunks} sections omitted for relevance)\nSource: \`${relPath}\`\n\n${formatted}`;
|
|
168
|
+
// For large files, truncate at section boundary
|
|
169
|
+
const truncated = truncateAtSectionBoundary(content, threshold).content;
|
|
170
|
+
return `### ${label}\nSource: \`${relPath}\`\n\n${truncated}`;
|
|
172
171
|
}
|
|
173
172
|
|
|
174
173
|
/**
|
|
@@ -202,21 +201,6 @@ export async function inlineDependencySummaries(
|
|
|
202
201
|
|
|
203
202
|
const result = sections.join("\n\n");
|
|
204
203
|
if (budgetChars !== undefined && result.length > budgetChars) {
|
|
205
|
-
// For 3+ summaries, try distillation first (preserves more information)
|
|
206
|
-
if (sections.length >= 3) {
|
|
207
|
-
const rawSummaries = sections.map(s => {
|
|
208
|
-
// Extract content after the header line
|
|
209
|
-
const lines = s.split("\n");
|
|
210
|
-
const contentStart = lines.findIndex(l => l.startsWith("Source:"));
|
|
211
|
-
return contentStart >= 0 ? lines.slice(contentStart + 1).join("\n").trim() : s;
|
|
212
|
-
});
|
|
213
|
-
const distilled = distillSummaries(rawSummaries, budgetChars);
|
|
214
|
-
if (distilled.content.length <= budgetChars) {
|
|
215
|
-
return distilled.content;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
// Fall back to section-boundary truncation
|
|
219
|
-
const { truncateAtSectionBoundary } = await import("./context-budget.js");
|
|
220
204
|
return truncateAtSectionBoundary(result, budgetChars).content;
|
|
221
205
|
}
|
|
222
206
|
return result;
|
|
@@ -634,7 +618,7 @@ export async function buildResearchMilestonePrompt(mid: string, midTitle: string
|
|
|
634
618
|
if (knowledgeInlineRM) inlined.push(knowledgeInlineRM);
|
|
635
619
|
inlined.push(inlineTemplate("research", "Research"));
|
|
636
620
|
|
|
637
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
621
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
638
622
|
|
|
639
623
|
const outputRelPath = relMilestoneFile(base, mid, "RESEARCH");
|
|
640
624
|
return loadPrompt("research-milestone", {
|
|
@@ -684,7 +668,7 @@ export async function buildPlanMilestonePrompt(mid: string, midTitle: string, ba
|
|
|
684
668
|
inlined.push(inlineTemplate("task-plan", "Task Plan"));
|
|
685
669
|
}
|
|
686
670
|
|
|
687
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
671
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
688
672
|
|
|
689
673
|
const outputRelPath = relMilestoneFile(base, mid, "ROADMAP");
|
|
690
674
|
const researchOutputPath = join(base, relMilestoneFile(base, mid, "RESEARCH"));
|
|
@@ -733,7 +717,7 @@ export async function buildResearchSlicePrompt(
|
|
|
733
717
|
const overridesInline = formatOverridesSection(activeOverrides);
|
|
734
718
|
if (overridesInline) inlined.unshift(overridesInline);
|
|
735
719
|
|
|
736
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
720
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
737
721
|
|
|
738
722
|
const outputRelPath = relSliceFile(base, mid, sid, "RESEARCH");
|
|
739
723
|
return loadPrompt("research-slice", {
|
|
@@ -781,7 +765,7 @@ export async function buildPlanSlicePrompt(
|
|
|
781
765
|
const planOverridesInline = formatOverridesSection(planActiveOverrides);
|
|
782
766
|
if (planOverridesInline) inlined.unshift(planOverridesInline);
|
|
783
767
|
|
|
784
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
768
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
785
769
|
|
|
786
770
|
// Build executor context constraints from the budget engine
|
|
787
771
|
const executorContextConstraints = formatExecutorConstraints();
|
|
@@ -900,15 +884,11 @@ export async function buildExecuteTaskPrompt(
|
|
|
900
884
|
const budgets = computeBudgets(contextWindow);
|
|
901
885
|
const verificationBudget = `~${Math.round(budgets.verificationBudgetChars / 1000)}K chars`;
|
|
902
886
|
|
|
903
|
-
//
|
|
904
|
-
// Only compress when compression_strategy is "compress" (budget/balanced profiles).
|
|
887
|
+
// Truncate carry-forward section when it exceeds 40% of inline context budget.
|
|
905
888
|
const carryForwardBudget = Math.floor(budgets.inlineContextBudgetChars * 0.4);
|
|
906
889
|
let finalCarryForward = carryForwardSection;
|
|
907
890
|
if (carryForwardSection.length > carryForwardBudget) {
|
|
908
|
-
|
|
909
|
-
if (resolveCompressionStrategy() === "compress") {
|
|
910
|
-
finalCarryForward = compressToTarget(carryForwardSection, carryForwardBudget).content;
|
|
911
|
-
}
|
|
891
|
+
finalCarryForward = truncateAtSectionBoundary(carryForwardSection, carryForwardBudget).content;
|
|
912
892
|
}
|
|
913
893
|
|
|
914
894
|
return loadPrompt("execute-task", {
|
|
@@ -971,7 +951,7 @@ export async function buildCompleteSlicePrompt(
|
|
|
971
951
|
const completeOverridesInline = formatOverridesSection(completeActiveOverrides);
|
|
972
952
|
if (completeOverridesInline) inlined.unshift(completeOverridesInline);
|
|
973
953
|
|
|
974
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
954
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
975
955
|
|
|
976
956
|
const sliceRel = relSlicePath(base, mid, sid);
|
|
977
957
|
const sliceSummaryPath = join(base, `${sliceRel}/${sid}-SUMMARY.md`);
|
|
@@ -1030,7 +1010,7 @@ export async function buildCompleteMilestonePrompt(
|
|
|
1030
1010
|
if (contextInline) inlined.push(contextInline);
|
|
1031
1011
|
inlined.push(inlineTemplate("milestone-summary", "Milestone Summary"));
|
|
1032
1012
|
|
|
1033
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
1013
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1034
1014
|
|
|
1035
1015
|
const milestoneSummaryPath = join(base, `${relMilestonePath(base, mid)}/${mid}-SUMMARY.md`);
|
|
1036
1016
|
|
|
@@ -1101,7 +1081,7 @@ export async function buildValidateMilestonePrompt(
|
|
|
1101
1081
|
const contextInline = await inlineFileOptional(contextPath, contextRel, "Milestone Context");
|
|
1102
1082
|
if (contextInline) inlined.push(contextInline);
|
|
1103
1083
|
|
|
1104
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
1084
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1105
1085
|
|
|
1106
1086
|
const validationOutputPath = join(base, `${relMilestonePath(base, mid)}/${mid}-VALIDATION.md`);
|
|
1107
1087
|
const roadmapOutputPath = `${relMilestonePath(base, mid)}/${mid}-ROADMAP.md`;
|
|
@@ -1155,7 +1135,7 @@ export async function buildReplanSlicePrompt(
|
|
|
1155
1135
|
const replanOverridesInline = formatOverridesSection(replanActiveOverrides);
|
|
1156
1136
|
if (replanOverridesInline) inlined.unshift(replanOverridesInline);
|
|
1157
1137
|
|
|
1158
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
1138
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1159
1139
|
|
|
1160
1140
|
const replanPath = join(base, `${relSlicePath(base, mid, sid)}/${sid}-REPLAN.md`);
|
|
1161
1141
|
|
|
@@ -1203,7 +1183,7 @@ export async function buildRunUatPrompt(
|
|
|
1203
1183
|
const projectInline = await inlineProjectFromDb(base);
|
|
1204
1184
|
if (projectInline) inlined.push(projectInline);
|
|
1205
1185
|
|
|
1206
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
1186
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1207
1187
|
|
|
1208
1188
|
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "UAT-RESULT"));
|
|
1209
1189
|
const uatType = extractUatType(uatContent) ?? "human-experience";
|
|
@@ -1242,7 +1222,7 @@ export async function buildReassessRoadmapPrompt(
|
|
|
1242
1222
|
const knowledgeInlineRA = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
1243
1223
|
if (knowledgeInlineRA) inlined.push(knowledgeInlineRA);
|
|
1244
1224
|
|
|
1245
|
-
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}
|
|
1225
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1246
1226
|
|
|
1247
1227
|
const assessmentPath = join(base, relSliceFile(base, mid, completedSliceId, "ASSESSMENT"));
|
|
1248
1228
|
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
resolveSkillDiscoveryMode,
|
|
21
21
|
getIsolationMode,
|
|
22
22
|
} from "./preferences.js";
|
|
23
|
-
import { ensureGsdSymlink } from "./repo-identity.js";
|
|
23
|
+
import { ensureGsdSymlink, validateProjectId } from "./repo-identity.js";
|
|
24
24
|
import { migrateToExternalState, recoverFailedMigration } from "./migrate-external.js";
|
|
25
25
|
import { collectSecretsFromManifest } from "../get-secrets-from-user.js";
|
|
26
26
|
import { gsdRoot, resolveMilestoneFile, milestonesDir } from "./paths.js";
|
|
@@ -130,6 +130,16 @@ export async function bootstrapAutoSession(
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
try {
|
|
133
|
+
// Validate GSD_PROJECT_ID early so the user gets immediate feedback
|
|
134
|
+
const customProjectId = process.env.GSD_PROJECT_ID;
|
|
135
|
+
if (customProjectId && !validateProjectId(customProjectId)) {
|
|
136
|
+
ctx.ui.notify(
|
|
137
|
+
`GSD_PROJECT_ID must contain only alphanumeric characters, hyphens, and underscores. Got: "${customProjectId}"`,
|
|
138
|
+
"error",
|
|
139
|
+
);
|
|
140
|
+
return releaseLockAndReturn();
|
|
141
|
+
}
|
|
142
|
+
|
|
133
143
|
// Ensure git repo exists
|
|
134
144
|
if (!nativeIsRepo(base)) {
|
|
135
145
|
const mainBranch =
|
|
@@ -429,10 +439,16 @@ export async function bootstrapAutoSession(
|
|
|
429
439
|
s.originalBasePath = base;
|
|
430
440
|
|
|
431
441
|
const isUnderGsdWorktrees = (p: string): boolean => {
|
|
442
|
+
// Direct layout: /.gsd/worktrees/
|
|
432
443
|
const marker = `${pathSep}.gsd${pathSep}worktrees${pathSep}`;
|
|
433
444
|
if (p.includes(marker)) return true;
|
|
434
445
|
const worktreesSuffix = `${pathSep}.gsd${pathSep}worktrees`;
|
|
435
|
-
|
|
446
|
+
if (p.endsWith(worktreesSuffix)) return true;
|
|
447
|
+
// Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/
|
|
448
|
+
const symlinkRe = new RegExp(
|
|
449
|
+
`\\${pathSep}\\.gsd\\${pathSep}projects\\${pathSep}[a-f0-9]+\\${pathSep}worktrees(?:\\${pathSep}|$)`,
|
|
450
|
+
);
|
|
451
|
+
return symlinkRe.test(p);
|
|
436
452
|
};
|
|
437
453
|
|
|
438
454
|
if (
|
|
@@ -22,6 +22,8 @@ import { join, sep as pathSep } from "node:path";
|
|
|
22
22
|
import { homedir } from "node:os";
|
|
23
23
|
import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
|
|
24
24
|
|
|
25
|
+
const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
|
|
26
|
+
|
|
25
27
|
// ─── Project Root → Worktree Sync ─────────────────────────────────────────
|
|
26
28
|
|
|
27
29
|
/**
|
|
@@ -111,7 +113,7 @@ export function syncStateToProjectRoot(
|
|
|
111
113
|
*/
|
|
112
114
|
export function readResourceVersion(): string | null {
|
|
113
115
|
const agentDir =
|
|
114
|
-
process.env.GSD_CODING_AGENT_DIR || join(
|
|
116
|
+
process.env.GSD_CODING_AGENT_DIR || join(gsdHome, "agent");
|
|
115
117
|
const manifestPath = join(agentDir, "managed-resources.json");
|
|
116
118
|
try {
|
|
117
119
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
@@ -153,9 +155,18 @@ export function checkResourcesStale(
|
|
|
153
155
|
* Returns the corrected base path.
|
|
154
156
|
*/
|
|
155
157
|
export function escapeStaleWorktree(base: string): string {
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
158
|
+
// Direct layout: /.gsd/worktrees/
|
|
159
|
+
const directMarker = `${pathSep}.gsd${pathSep}worktrees${pathSep}`;
|
|
160
|
+
let idx = base.indexOf(directMarker);
|
|
161
|
+
if (idx === -1) {
|
|
162
|
+
// Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/
|
|
163
|
+
const symlinkRe = new RegExp(
|
|
164
|
+
`\\${pathSep}\\.gsd\\${pathSep}projects\\${pathSep}[a-f0-9]+\\${pathSep}worktrees\\${pathSep}`,
|
|
165
|
+
);
|
|
166
|
+
const match = base.match(symlinkRe);
|
|
167
|
+
if (!match || match.index === undefined) return base;
|
|
168
|
+
idx = match.index;
|
|
169
|
+
}
|
|
159
170
|
|
|
160
171
|
// base is inside .gsd/worktrees/<something> — extract the project root
|
|
161
172
|
const projectRoot = base.slice(0, idx);
|
|
@@ -37,13 +37,13 @@ import {
|
|
|
37
37
|
resolveGitHeadPath,
|
|
38
38
|
nudgeGitBranchCache,
|
|
39
39
|
} from "./worktree.js";
|
|
40
|
-
import { MergeConflictError, readIntegrationBranch } from "./git-service.js";
|
|
40
|
+
import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
|
|
41
41
|
import { parseRoadmap } from "./files.js";
|
|
42
42
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
43
43
|
import {
|
|
44
44
|
nativeGetCurrentBranch,
|
|
45
45
|
nativeWorkingTreeStatus,
|
|
46
|
-
|
|
46
|
+
nativeAddAllWithExclusions,
|
|
47
47
|
nativeCommit,
|
|
48
48
|
nativeCheckoutBranch,
|
|
49
49
|
nativeMergeSquash,
|
|
@@ -768,7 +768,7 @@ function autoCommitDirtyState(cwd: string): boolean {
|
|
|
768
768
|
try {
|
|
769
769
|
const status = nativeWorkingTreeStatus(cwd);
|
|
770
770
|
if (!status) return false;
|
|
771
|
-
|
|
771
|
+
nativeAddAllWithExclusions(cwd, RUNTIME_EXCLUSION_PATHS);
|
|
772
772
|
const result = nativeCommit(
|
|
773
773
|
cwd,
|
|
774
774
|
"chore: auto-commit before milestone merge",
|