@opengsd/gsd-pi 1.4.0-dev.5fc22c6f → 1.4.0-dev.c18009cd
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/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +58 -4
- package/dist/resources/extensions/gsd/artifact-verification.js +17 -5
- package/dist/resources/extensions/gsd/auto/closeout.js +45 -42
- package/dist/resources/extensions/gsd/auto/finalize.js +9 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +1 -1
- package/dist/resources/extensions/gsd/auto/run-unit.js +5 -2
- package/dist/resources/extensions/gsd/auto/schedule-wakeup.js +3 -0
- package/dist/resources/extensions/gsd/auto.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.js +58 -9
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +174 -16
- package/dist/resources/extensions/gsd/gsd-db.js +52 -0
- package/dist/resources/extensions/gsd/migrate-external.js +13 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +3 -3
- package/dist/resources/extensions/gsd/repo-identity.js +16 -0
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +4 -2
- package/dist/resources/extensions/gsd/unit-registry.js +27 -2
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +67 -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 +6 -6
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/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 +6 -6
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/integrations/hermes/CONTEXT.md +47 -0
- package/integrations/hermes/README.md +21 -0
- package/integrations/hermes/docs/issue-1162-grilling.md +197 -0
- package/integrations/hermes/docs/setup.md +4 -0
- package/integrations/hermes/open_gsd_hermes/commands.py +141 -0
- package/integrations/hermes/open_gsd_hermes/config.py +2 -0
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +594 -31
- package/integrations/hermes/open_gsd_hermes/notifications.py +10 -1
- package/integrations/hermes/plugin.yaml +4 -0
- package/integrations/hermes/tests/test_config.py +6 -0
- package/integrations/hermes/tests/test_gsd_client_cache.py +3 -0
- package/integrations/hermes/tests/test_gsd_client_execute.py +35 -0
- package/integrations/hermes/tests/test_gsd_client_process_cwd.py +22 -0
- package/integrations/hermes/tests/test_gsd_client_timeout.py +98 -0
- package/integrations/hermes/tests/test_milestone_client.py +447 -0
- package/integrations/hermes/tests/test_new_milestone_command.py +313 -0
- package/integrations/hermes/tests/test_supervisor_fsm.py +40 -0
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/session-manager.js +1 -1
- package/packages/daemon/dist/session-manager.js.map +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.js +4 -1
- package/packages/gsd-agent-core/dist/session/agent-session-navigation.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +18 -5
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +46 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +1 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +3 -0
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +64 -3
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +212 -39
- package/src/resources/extensions/gsd/artifact-verification.ts +16 -4
- package/src/resources/extensions/gsd/auto/closeout.ts +54 -56
- package/src/resources/extensions/gsd/auto/finalize.ts +8 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +1 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +5 -2
- package/src/resources/extensions/gsd/auto/schedule-wakeup.ts +8 -0
- package/src/resources/extensions/gsd/auto.ts +9 -3
- package/src/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.ts +80 -12
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +230 -21
- package/src/resources/extensions/gsd/gsd-db.ts +72 -0
- package/src/resources/extensions/gsd/migrate-external.ts +14 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +4 -4
- package/src/resources/extensions/gsd/repo-identity.ts +17 -0
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -5
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +335 -0
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +152 -22
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +50 -6
- package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +31 -9
- package/src/resources/extensions/gsd/tests/schedule-wakeup-tool.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +2 -2
- package/src/resources/extensions/gsd/unit-registry.ts +34 -2
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +135 -11
- /package/dist/web/standalone/.next/static/{kIEFsCryyGy6RzifULbJl → L2UMqXELiDH3oz-7yguXp}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{kIEFsCryyGy6RzifULbJl → L2UMqXELiDH3oz-7yguXp}/_ssgManifest.js +0 -0
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
//
|
|
21
21
|
// Not yet declared here (remaining ADR-033 steps): the manifest data
|
|
22
22
|
// (`UNIT_MANIFESTS` stays in unit-context-manifest.ts, already type-enforced
|
|
23
|
-
// against the registry's `UnitType`)
|
|
24
|
-
//
|
|
23
|
+
// against the registry's `UnitType`). Prompt-template association is declared
|
|
24
|
+
// for direct one-template units; conditional/composite prompt selection stays
|
|
25
|
+
// with the prompt builders until it has a richer registry shape.
|
|
25
26
|
|
|
26
27
|
import type { CanonicalWorkflowToolName } from "@opengsd/contracts";
|
|
27
28
|
import { BROWSER_CONTRACT_TOOL_NAMES } from "../shared/browser-contract.js";
|
|
@@ -61,6 +62,12 @@ export interface UnitDescriptor {
|
|
|
61
62
|
* resolves against session defaults).
|
|
62
63
|
*/
|
|
63
64
|
readonly phaseChain: readonly GSDModelPhaseKey[] | null;
|
|
65
|
+
/**
|
|
66
|
+
* Prompt template id passed to loadPrompt for units with a direct
|
|
67
|
+
* one-template builder. Omitted for conditional, composite, or not-yet
|
|
68
|
+
* verified prompt associations.
|
|
69
|
+
*/
|
|
70
|
+
readonly promptTemplate?: string;
|
|
64
71
|
/** `null` = the unit has no scoped gsd-tool contract. */
|
|
65
72
|
readonly toolContract: UnitToolSurfaceContract | null;
|
|
66
73
|
}
|
|
@@ -97,6 +104,7 @@ export const UNIT_REGISTRY = {
|
|
|
97
104
|
kind: "primary",
|
|
98
105
|
scopeClass: "standard",
|
|
99
106
|
phaseChain: ["research"],
|
|
107
|
+
promptTemplate: "research-milestone",
|
|
100
108
|
toolContract: {
|
|
101
109
|
allowedGsdTools: [
|
|
102
110
|
"gsd_summary_save",
|
|
@@ -112,6 +120,7 @@ export const UNIT_REGISTRY = {
|
|
|
112
120
|
kind: "primary",
|
|
113
121
|
scopeClass: "standard",
|
|
114
122
|
phaseChain: ["planning"],
|
|
123
|
+
promptTemplate: "plan-milestone",
|
|
115
124
|
toolContract: {
|
|
116
125
|
allowedGsdTools: [
|
|
117
126
|
"gsd_milestone_status",
|
|
@@ -160,6 +169,7 @@ export const UNIT_REGISTRY = {
|
|
|
160
169
|
kind: "primary",
|
|
161
170
|
scopeClass: "section-close",
|
|
162
171
|
phaseChain: ["validation", "planning"],
|
|
172
|
+
promptTemplate: "validate-milestone",
|
|
163
173
|
toolContract: {
|
|
164
174
|
allowedGsdTools: [
|
|
165
175
|
"gsd_milestone_status",
|
|
@@ -177,6 +187,7 @@ export const UNIT_REGISTRY = {
|
|
|
177
187
|
kind: "primary",
|
|
178
188
|
scopeClass: "standard",
|
|
179
189
|
phaseChain: ["completion"],
|
|
190
|
+
promptTemplate: "complete-milestone",
|
|
180
191
|
toolContract: {
|
|
181
192
|
allowedGsdTools: [
|
|
182
193
|
"gsd_milestone_status",
|
|
@@ -200,6 +211,7 @@ export const UNIT_REGISTRY = {
|
|
|
200
211
|
kind: "primary",
|
|
201
212
|
scopeClass: "standard",
|
|
202
213
|
phaseChain: ["research"],
|
|
214
|
+
promptTemplate: "research-slice",
|
|
203
215
|
toolContract: {
|
|
204
216
|
allowedGsdTools: [
|
|
205
217
|
"gsd_milestone_status",
|
|
@@ -216,6 +228,7 @@ export const UNIT_REGISTRY = {
|
|
|
216
228
|
kind: "primary",
|
|
217
229
|
scopeClass: "standard",
|
|
218
230
|
phaseChain: ["planning"],
|
|
231
|
+
promptTemplate: "plan-slice",
|
|
219
232
|
toolContract: {
|
|
220
233
|
allowedGsdTools: [
|
|
221
234
|
"gsd_milestone_status",
|
|
@@ -234,6 +247,7 @@ export const UNIT_REGISTRY = {
|
|
|
234
247
|
kind: "primary",
|
|
235
248
|
scopeClass: "standard",
|
|
236
249
|
phaseChain: ["planning"],
|
|
250
|
+
promptTemplate: "refine-slice",
|
|
237
251
|
toolContract: {
|
|
238
252
|
allowedGsdTools: [
|
|
239
253
|
"gsd_milestone_status",
|
|
@@ -250,6 +264,7 @@ export const UNIT_REGISTRY = {
|
|
|
250
264
|
kind: "primary",
|
|
251
265
|
scopeClass: "standard",
|
|
252
266
|
phaseChain: ["planning"],
|
|
267
|
+
promptTemplate: "replan-slice",
|
|
253
268
|
toolContract: {
|
|
254
269
|
allowedGsdTools: ["gsd_replan_slice", "gsd_decision_save"],
|
|
255
270
|
requiredWorkflowTools: ["gsd_replan_slice"],
|
|
@@ -259,6 +274,7 @@ export const UNIT_REGISTRY = {
|
|
|
259
274
|
kind: "primary",
|
|
260
275
|
scopeClass: "section-close",
|
|
261
276
|
phaseChain: ["completion"],
|
|
277
|
+
promptTemplate: "complete-slice",
|
|
262
278
|
toolContract: {
|
|
263
279
|
allowedGsdTools: [
|
|
264
280
|
"gsd_milestone_status",
|
|
@@ -293,6 +309,7 @@ export const UNIT_REGISTRY = {
|
|
|
293
309
|
kind: "primary",
|
|
294
310
|
scopeClass: "standard",
|
|
295
311
|
phaseChain: ["validation", "planning"],
|
|
312
|
+
promptTemplate: "reassess-roadmap",
|
|
296
313
|
toolContract: {
|
|
297
314
|
allowedGsdTools: ["gsd_milestone_status", "gsd_reassess_roadmap"],
|
|
298
315
|
requiredWorkflowTools: ["gsd_milestone_status", "gsd_reassess_roadmap"],
|
|
@@ -302,6 +319,7 @@ export const UNIT_REGISTRY = {
|
|
|
302
319
|
kind: "primary",
|
|
303
320
|
scopeClass: "execute-task",
|
|
304
321
|
phaseChain: ["execution"],
|
|
322
|
+
promptTemplate: "execute-task",
|
|
305
323
|
toolContract: {
|
|
306
324
|
allowedGsdTools: [
|
|
307
325
|
"gsd_task_complete",
|
|
@@ -346,6 +364,7 @@ export const UNIT_REGISTRY = {
|
|
|
346
364
|
kind: "primary",
|
|
347
365
|
scopeClass: "execute-task",
|
|
348
366
|
phaseChain: ["execution"],
|
|
367
|
+
promptTemplate: "reactive-execute",
|
|
349
368
|
toolContract: {
|
|
350
369
|
allowedGsdTools: [
|
|
351
370
|
"gsd_milestone_status",
|
|
@@ -361,6 +380,7 @@ export const UNIT_REGISTRY = {
|
|
|
361
380
|
kind: "primary",
|
|
362
381
|
scopeClass: "standard",
|
|
363
382
|
phaseChain: ["uat", "completion"],
|
|
383
|
+
promptTemplate: "run-uat",
|
|
364
384
|
toolContract: {
|
|
365
385
|
allowedGsdTools: [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent"],
|
|
366
386
|
requiredWorkflowTools: [...RUN_UAT_WORKFLOW_TOOL_NAMES],
|
|
@@ -375,6 +395,7 @@ export const UNIT_REGISTRY = {
|
|
|
375
395
|
kind: "primary",
|
|
376
396
|
scopeClass: "standard",
|
|
377
397
|
phaseChain: ["validation", "planning"],
|
|
398
|
+
promptTemplate: "gate-evaluate",
|
|
378
399
|
toolContract: {
|
|
379
400
|
allowedGsdTools: ["gsd_save_gate_result"],
|
|
380
401
|
requiredWorkflowTools: ["gsd_save_gate_result"],
|
|
@@ -384,6 +405,7 @@ export const UNIT_REGISTRY = {
|
|
|
384
405
|
kind: "primary",
|
|
385
406
|
scopeClass: "standard",
|
|
386
407
|
phaseChain: ["validation", "planning"],
|
|
408
|
+
promptTemplate: "rewrite-docs",
|
|
387
409
|
toolContract: {
|
|
388
410
|
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
|
|
389
411
|
requiredWorkflowTools: [],
|
|
@@ -408,6 +430,7 @@ export const UNIT_REGISTRY = {
|
|
|
408
430
|
kind: "primary",
|
|
409
431
|
scopeClass: "standard",
|
|
410
432
|
phaseChain: ["discuss", "planning"],
|
|
433
|
+
promptTemplate: "guided-workflow-preferences",
|
|
411
434
|
toolContract: {
|
|
412
435
|
allowedGsdTools: ["gsd_summary_save"],
|
|
413
436
|
requiredWorkflowTools: [],
|
|
@@ -417,6 +440,7 @@ export const UNIT_REGISTRY = {
|
|
|
417
440
|
kind: "primary",
|
|
418
441
|
scopeClass: "standard",
|
|
419
442
|
phaseChain: ["discuss", "planning"],
|
|
443
|
+
promptTemplate: "guided-discuss-project",
|
|
420
444
|
toolContract: {
|
|
421
445
|
allowedGsdTools: ["gsd_summary_save", "gsd_decision_save", "gsd_requirement_save"],
|
|
422
446
|
requiredWorkflowTools: ["ask_user_questions", "gsd_summary_save"],
|
|
@@ -426,6 +450,7 @@ export const UNIT_REGISTRY = {
|
|
|
426
450
|
kind: "primary",
|
|
427
451
|
scopeClass: "standard",
|
|
428
452
|
phaseChain: ["discuss", "planning"],
|
|
453
|
+
promptTemplate: "guided-discuss-requirements",
|
|
429
454
|
toolContract: {
|
|
430
455
|
allowedGsdTools: ["gsd_requirement_save", "gsd_summary_save"],
|
|
431
456
|
requiredWorkflowTools: ["ask_user_questions", "gsd_requirement_save", "gsd_summary_save"],
|
|
@@ -435,6 +460,7 @@ export const UNIT_REGISTRY = {
|
|
|
435
460
|
kind: "primary",
|
|
436
461
|
scopeClass: "standard",
|
|
437
462
|
phaseChain: ["discuss", "planning"],
|
|
463
|
+
promptTemplate: "guided-research-decision",
|
|
438
464
|
toolContract: {
|
|
439
465
|
allowedGsdTools: ["gsd_summary_save"],
|
|
440
466
|
requiredWorkflowTools: ["ask_user_questions"],
|
|
@@ -447,6 +473,7 @@ export const UNIT_REGISTRY = {
|
|
|
447
473
|
kind: "primary",
|
|
448
474
|
scopeClass: "standard",
|
|
449
475
|
phaseChain: ["research"],
|
|
476
|
+
promptTemplate: "guided-research-project",
|
|
450
477
|
toolContract: {
|
|
451
478
|
allowedGsdTools: [],
|
|
452
479
|
requiredWorkflowTools: [],
|
|
@@ -494,3 +521,8 @@ export function getUnitDescriptor(unitType: string): UnitDescriptor | undefined
|
|
|
494
521
|
export function getUnitPhaseChain(unitType: string): readonly GSDModelPhaseKey[] | null {
|
|
495
522
|
return getUnitDescriptor(unitType)?.phaseChain ?? null;
|
|
496
523
|
}
|
|
524
|
+
|
|
525
|
+
/** Prompt template id for units with a direct one-template builder. */
|
|
526
|
+
export function getUnitPromptTemplate(unitType: string): string | undefined {
|
|
527
|
+
return getUnitDescriptor(unitType)?.promptTemplate;
|
|
528
|
+
}
|
|
@@ -21,6 +21,8 @@ import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
|
21
21
|
import { randomUUID } from "node:crypto";
|
|
22
22
|
import { join } from "node:path";
|
|
23
23
|
|
|
24
|
+
import type { PreflightResult, PostflightResult } from "./clean-root-preflight.js";
|
|
25
|
+
|
|
24
26
|
import type { AutoSession } from "./auto/session.js";
|
|
25
27
|
import { debugLog } from "./debug-logger.js";
|
|
26
28
|
import { logWarning } from "./workflow-logger.js";
|
|
@@ -153,11 +155,11 @@ export interface WorktreeLifecycleDeps {
|
|
|
153
155
|
/**
|
|
154
156
|
* Milestone Merge Transaction Module runner.
|
|
155
157
|
*
|
|
156
|
-
* The field name
|
|
157
|
-
*
|
|
158
|
-
*
|
|
158
|
+
* The field name describes the lifecycle seam; production wiring supplies
|
|
159
|
+
* the named transaction wrapper rather than the raw legacy
|
|
160
|
+
* auto-worktree primitive directly.
|
|
159
161
|
*/
|
|
160
|
-
|
|
162
|
+
mergeMilestone: MilestoneMergeTransactionRunner;
|
|
161
163
|
|
|
162
164
|
// ADR-016 phase 2 / C1 + C2 + C3 + C4 inlined the following fields as
|
|
163
165
|
// direct imports — leaf primitives that did not vary across callers:
|
|
@@ -238,7 +240,106 @@ export interface StrandedMilestoneAdoptionOptions {
|
|
|
238
240
|
|
|
239
241
|
export type ExitResult =
|
|
240
242
|
| { ok: true; merged: boolean; codeFilesChanged: boolean }
|
|
241
|
-
| {
|
|
243
|
+
| {
|
|
244
|
+
ok: false;
|
|
245
|
+
reason:
|
|
246
|
+
| "merge-conflict"
|
|
247
|
+
| "teardown-failed"
|
|
248
|
+
| "preflight-dirty-overlap"
|
|
249
|
+
| "preflight-unmerged-conflicts"
|
|
250
|
+
| "merge-failed"
|
|
251
|
+
| "postflight-stash-restore-failed";
|
|
252
|
+
cause?: unknown;
|
|
253
|
+
postflight?: PostflightResult;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export interface GuardedMilestoneMergeDeps {
|
|
257
|
+
preflightCleanRoot: (
|
|
258
|
+
basePath: string,
|
|
259
|
+
milestoneId: string,
|
|
260
|
+
notify: NotifyCtx["notify"],
|
|
261
|
+
) => PreflightResult;
|
|
262
|
+
postflightPopStash: (
|
|
263
|
+
basePath: string,
|
|
264
|
+
milestoneId: string,
|
|
265
|
+
stashMarker: string | undefined,
|
|
266
|
+
notify: NotifyCtx["notify"],
|
|
267
|
+
) => PostflightResult;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Optional `exitMilestone(..., { merge: true, guardedMerge })` contract for callers
|
|
272
|
+
* that need root-clean preflight and postflight stash restoration around the
|
|
273
|
+
* lifecycle-owned merge attempt. `projectRoot` is the workspace root whose
|
|
274
|
+
* user changes are protected by the supplied guard functions.
|
|
275
|
+
*/
|
|
276
|
+
export interface GuardedMilestoneMergeOptions extends GuardedMilestoneMergeDeps {
|
|
277
|
+
projectRoot: string;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
type GuardedMilestoneMergeResult = ExitResult;
|
|
281
|
+
|
|
282
|
+
function preflightBlockedMergeReason(
|
|
283
|
+
blockedReason: PreflightResult["blockedReason"],
|
|
284
|
+
): Extract<ExitResult, { ok: false }>["reason"] {
|
|
285
|
+
if (blockedReason?.startsWith("unmerged-conflicts")) {
|
|
286
|
+
return "preflight-unmerged-conflicts";
|
|
287
|
+
}
|
|
288
|
+
return "preflight-dirty-overlap";
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Run a milestone merge behind the Worktree Lifecycle seam with the root-clean
|
|
293
|
+
* stash guard that protects user changes around merge.
|
|
294
|
+
*
|
|
295
|
+
* The helper owns the invariant ordering (preflight -> merge callback ->
|
|
296
|
+
* postflight on every attempted merge path) and returns the same typed result
|
|
297
|
+
* shape as `exitMilestone`. Auto closeout remains responsible for translating
|
|
298
|
+
* that result into loop policy (pause vs. stop, visible transcript
|
|
299
|
+
* preservation, projection rebuild).
|
|
300
|
+
*/
|
|
301
|
+
function runGuardedMilestoneMerge(request: {
|
|
302
|
+
merge: () => ExitResult;
|
|
303
|
+
guard: GuardedMilestoneMergeOptions;
|
|
304
|
+
milestoneId: string;
|
|
305
|
+
notify: NotifyCtx["notify"];
|
|
306
|
+
}): GuardedMilestoneMergeResult {
|
|
307
|
+
const { merge, guard, milestoneId, notify } = request;
|
|
308
|
+
const preflight = guard.preflightCleanRoot(guard.projectRoot, milestoneId, notify);
|
|
309
|
+
if (preflight.blocked) {
|
|
310
|
+
return {
|
|
311
|
+
ok: false,
|
|
312
|
+
reason: preflightBlockedMergeReason(preflight.blockedReason),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
let mergeError: unknown = null;
|
|
317
|
+
const exitResult = merge();
|
|
318
|
+
if (!exitResult.ok) {
|
|
319
|
+
mergeError = exitResult.cause ?? new Error(`exit ${exitResult.reason}`);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
let postflight: PostflightResult | undefined;
|
|
323
|
+
if (preflight.stashPushed) {
|
|
324
|
+
postflight = guard.postflightPopStash(
|
|
325
|
+
guard.projectRoot,
|
|
326
|
+
milestoneId,
|
|
327
|
+
preflight.stashMarker,
|
|
328
|
+
notify,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (mergeError instanceof MergeConflictError) {
|
|
333
|
+
return { ok: false, reason: "merge-conflict", cause: mergeError, postflight };
|
|
334
|
+
}
|
|
335
|
+
if (mergeError) {
|
|
336
|
+
return { ok: false, reason: "merge-failed", cause: mergeError, postflight };
|
|
337
|
+
}
|
|
338
|
+
if (postflight?.needsManualRecovery) {
|
|
339
|
+
return { ok: false, reason: "postflight-stash-restore-failed", postflight };
|
|
340
|
+
}
|
|
341
|
+
return exitResult;
|
|
342
|
+
}
|
|
242
343
|
|
|
243
344
|
/**
|
|
244
345
|
* Session-less merge entry context. Per ADR-016 phase 2 / A1 (#5616), the
|
|
@@ -1046,7 +1147,7 @@ function _mergeWorktreeModeImpl(
|
|
|
1046
1147
|
};
|
|
1047
1148
|
}
|
|
1048
1149
|
|
|
1049
|
-
const mergeResult = deps.
|
|
1150
|
+
const mergeResult = deps.mergeMilestone(
|
|
1050
1151
|
originalBasePath,
|
|
1051
1152
|
milestoneId,
|
|
1052
1153
|
roadmapResolution.content,
|
|
@@ -1213,7 +1314,7 @@ function _mergeBranchModeImpl(
|
|
|
1213
1314
|
};
|
|
1214
1315
|
}
|
|
1215
1316
|
|
|
1216
|
-
const mergeResult = deps.
|
|
1317
|
+
const mergeResult = deps.mergeMilestone(
|
|
1217
1318
|
worktreeBasePath,
|
|
1218
1319
|
milestoneId,
|
|
1219
1320
|
roadmapResolution.content,
|
|
@@ -1444,18 +1545,41 @@ export class WorktreeLifecycle {
|
|
|
1444
1545
|
* With `opts.merge === false`, runs auto-commit and teardown without
|
|
1445
1546
|
* merging to main.
|
|
1446
1547
|
*
|
|
1548
|
+
* When `opts.guardedMerge` is present with `opts.merge === true`, the
|
|
1549
|
+
* lifecycle verb also owns the root-clean guard around the merge: preflight
|
|
1550
|
+
* runs before the inner merge, postflight stash restore runs after every
|
|
1551
|
+
* attempted merge path, and guard failures are returned as typed
|
|
1552
|
+
* `ExitResult` reasons.
|
|
1553
|
+
*
|
|
1447
1554
|
* Returns a typed `ExitResult`. `MergeConflictError` is surfaced as
|
|
1448
1555
|
* `{ ok: false, reason: "merge-conflict", cause }` instead of thrown,
|
|
1449
|
-
* giving callers a typed branch for the expected failure path.
|
|
1450
|
-
*
|
|
1451
|
-
*
|
|
1556
|
+
* giving callers a typed branch for the expected failure path. Guarded merge
|
|
1557
|
+
* failures surface as `preflight-dirty-overlap`,
|
|
1558
|
+
* `preflight-unmerged-conflicts`, `merge-failed`, or
|
|
1559
|
+
* `postflight-stash-restore-failed`. Unexpected failures (filesystem, git
|
|
1560
|
+
* permissions, etc.) are wrapped as
|
|
1561
|
+
* `{ ok: false, reason: "teardown-failed", cause }` so callers always
|
|
1452
1562
|
* receive a discriminated union — no exceptions for any expected outcome.
|
|
1453
1563
|
*/
|
|
1454
1564
|
exitMilestone(
|
|
1455
1565
|
milestoneId: string,
|
|
1456
|
-
opts: {
|
|
1566
|
+
opts: {
|
|
1567
|
+
merge: boolean;
|
|
1568
|
+
preserveBranch?: boolean;
|
|
1569
|
+
preserveWorktree?: boolean;
|
|
1570
|
+
guardedMerge?: GuardedMilestoneMergeOptions;
|
|
1571
|
+
},
|
|
1457
1572
|
ctx: NotifyCtx,
|
|
1458
1573
|
): ExitResult {
|
|
1574
|
+
if (opts.merge && opts.guardedMerge) {
|
|
1575
|
+
return runGuardedMilestoneMerge({
|
|
1576
|
+
merge: () => this.exitMilestone(milestoneId, { merge: true }, ctx),
|
|
1577
|
+
guard: opts.guardedMerge,
|
|
1578
|
+
milestoneId,
|
|
1579
|
+
notify: ctx.notify,
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1459
1583
|
if (opts.merge) {
|
|
1460
1584
|
try {
|
|
1461
1585
|
const merged = this._mergeAndExit(milestoneId, ctx);
|
|
File without changes
|
|
File without changes
|