gsd-pi 2.82.0-dev.725028083 → 2.82.0-dev.c22380fc3

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.
Files changed (87) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
  3. package/dist/resources/extensions/gsd/auto.js +128 -52
  4. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  5. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  6. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  7. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  8. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  9. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  10. package/dist/resources/extensions/gsd/worktree-lifecycle.js +21 -2
  11. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  12. package/dist/web/standalone/.next/BUILD_ID +1 -1
  13. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  14. package/dist/web/standalone/.next/build-manifest.json +2 -2
  15. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  16. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  17. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  18. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  19. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  20. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  21. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  25. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/index.html +1 -1
  33. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  34. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  36. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  40. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  41. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  42. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  43. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  44. package/package.json +1 -1
  45. package/packages/contracts/dist/rpc.test.js +7 -0
  46. package/packages/contracts/dist/rpc.test.js.map +1 -1
  47. package/packages/contracts/dist/workflow.d.ts +21 -0
  48. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  49. package/packages/contracts/dist/workflow.js +24 -0
  50. package/packages/contracts/dist/workflow.js.map +1 -1
  51. package/packages/contracts/src/rpc.test.ts +8 -0
  52. package/packages/contracts/src/workflow.ts +24 -0
  53. package/packages/mcp-server/README.md +13 -4
  54. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  55. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  56. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  57. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  58. package/packages/mcp-server/src/workflow-tools.test.ts +22 -0
  59. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  60. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  61. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  62. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  63. package/packages/pi-tui/dist/tui.js +5 -0
  64. package/packages/pi-tui/dist/tui.js.map +1 -1
  65. package/packages/pi-tui/src/tui.ts +6 -0
  66. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  67. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  68. package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
  69. package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
  70. package/src/resources/extensions/gsd/auto.ts +136 -51
  71. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  72. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  73. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  74. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  75. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  76. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
  77. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -5
  78. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  79. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  80. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  81. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  82. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  83. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  84. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  85. package/src/resources/extensions/gsd/worktree-lifecycle.ts +20 -2
  86. /package/dist/web/standalone/.next/static/{KDRTXR-22LPCsa80X9dey → Wop3A7KRGyR06H3rla_1-}/_buildManifest.js +0 -0
  87. /package/dist/web/standalone/.next/static/{KDRTXR-22LPCsa80X9dey → Wop3A7KRGyR06H3rla_1-}/_ssgManifest.js +0 -0
@@ -14,7 +14,7 @@ import { parseSummary } from '../files.ts';
14
14
  import { deriveState } from '../state.ts';
15
15
  import { invalidateAllCaches } from '../cache.ts';
16
16
  import { ensureDbOpen } from '../bootstrap/dynamic-tools.ts';
17
- import { closeDatabase, getAllMilestones } from '../gsd-db.ts';
17
+ import { closeDatabase, getAllMilestones, getArtifact } from '../gsd-db.ts';
18
18
  import { importWrittenMigrationToDb } from '../migrate/command.ts';
19
19
  import type {
20
20
  GSDProject,
@@ -336,7 +336,12 @@ test('Scenario 2: Fully complete project — deriveState phase', async () => {
336
336
  assert.deepStrictEqual(preview.taskCompletionPct, 100, 'complete: preview taskCompletionPct');
337
337
  assert.deepStrictEqual(preview.requirements.total, 0, 'complete: preview requirements total');
338
338
 
339
+ const imported = await importWrittenMigrationToDb(base, preview);
340
+ assert.ok(imported.artifacts >= 6, 'complete: imports generated milestone artifacts');
341
+ assert.ok(getArtifact('milestones/M001/M001-VALIDATION.md') !== null, 'complete: M001-VALIDATION.md imported as artifact');
342
+ assert.ok(getArtifact('milestones/M001/M001-SUMMARY.md') !== null, 'complete: M001-SUMMARY.md imported as artifact');
339
343
  } finally {
344
+ closeDatabase();
340
345
  rmSync(base, { recursive: true, force: true });
341
346
  }
342
347
  });
@@ -271,6 +271,11 @@ describe("#2945 Bug 3: mergeAndExit must teardown worktree after successful merg
271
271
  // a real git fixture and verify the worktree directory is removed
272
272
  // from disk after the merge.
273
273
  const tmpBase = realpathSync(mkdtempSync(join(tmpdir(), "gsd-2945-bug3-")));
274
+ // ADR-016 phase 3 (#5693): Lifecycle.restoreToProjectRoot now chdirs to
275
+ // s.originalBasePath. Save cwd before the test so we can restore it
276
+ // before rmSync removes tmpBase — otherwise the next test in this file
277
+ // inherits a deleted cwd and process.cwd() throws ENOENT (uv_cwd).
278
+ const prevCwd = process.cwd();
274
279
  try {
275
280
  const git = (args: string[]): void => {
276
281
  execFileSync("git", args, { cwd: tmpBase, stdio: "pipe" });
@@ -325,6 +330,7 @@ describe("#2945 Bug 3: mergeAndExit must teardown worktree after successful merg
325
330
  `teardownAutoWorktree must be called after successful merge — worktree directory at ${wt} should be removed`,
326
331
  );
327
332
  } finally {
333
+ try { process.chdir(prevCwd); } catch { /* noop */ }
328
334
  try { rmSync(tmpBase, { recursive: true, force: true }); } catch { /* noop */ }
329
335
  }
330
336
  });
@@ -538,6 +538,31 @@ test("restoreToProjectRoot is no-op when originalBasePath is empty", () => {
538
538
  assert.equal(deps.calls.filter((c) => c.fn === "gitServiceFactory").length, 0);
539
539
  });
540
540
 
541
+ test("restoreToProjectRoot completes session-state restore even when chdir fails (ADR-016 phase 3, #5693)", () => {
542
+ // The verb attempts process.chdir to s.basePath after restoring it. The
543
+ // chdir is best-effort; failure must not abort the session-state restore.
544
+ // We exercise that contract by pointing originalBasePath at a path that
545
+ // cannot be chdir'd into.
546
+ const s = makeSession();
547
+ s.originalBasePath = "/this/path/should/not/exist/in/any/test/env";
548
+ s.basePath = "/project/.gsd/worktrees/M001";
549
+ const deps = makeDeps();
550
+ const lifecycle = new WorktreeLifecycle(s, deps);
551
+
552
+ // Capture cwd so we can confirm we did NOT successfully chdir.
553
+ const cwdBefore = process.cwd();
554
+ lifecycle.restoreToProjectRoot();
555
+
556
+ // Session-state restore happened despite chdir failure.
557
+ assert.equal(s.basePath, "/this/path/should/not/exist/in/any/test/env");
558
+ assert.equal(
559
+ deps.calls.filter((c) => c.fn === "gitServiceFactory").length,
560
+ 1,
561
+ );
562
+ // cwd is unchanged because chdir threw and was swallowed.
563
+ assert.equal(process.cwd(), cwdBefore);
564
+ });
565
+
541
566
  // ─── adoptSessionRoot (ADR-016 phase 2 / B2, issue #5620) ─────────────────────
542
567
 
543
568
  test("adoptSessionRoot sets basePath and seeds originalBasePath on a fresh session", () => {
@@ -1,3 +1,6 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Adapts shared GSD workflow handlers for MCP executor calls.
3
+
1
4
  import { ensureDbOpen } from "../bootstrap/dynamic-tools.js";
2
5
  import { sanitizeCompleteMilestoneParams } from "../bootstrap/sanitize-complete-milestone.js";
3
6
  import { loadWriteGateSnapshot, shouldBlockContextArtifactSaveInSnapshot, shouldBlockRootArtifactSaveInSnapshot } from "../bootstrap/write-gate.js";
@@ -25,6 +28,12 @@ import type { PlanSliceParams } from "./plan-slice.js";
25
28
  import { handlePlanSlice } from "./plan-slice.js";
26
29
  import type { ReplanSliceParams } from "./replan-slice.js";
27
30
  import { handleReplanSlice } from "./replan-slice.js";
31
+ import type { ReopenMilestoneParams } from "./reopen-milestone.js";
32
+ import { handleReopenMilestone } from "./reopen-milestone.js";
33
+ import type { ReopenSliceParams } from "./reopen-slice.js";
34
+ import { handleReopenSlice } from "./reopen-slice.js";
35
+ import type { ReopenTaskParams } from "./reopen-task.js";
36
+ import { handleReopenTask } from "./reopen-task.js";
28
37
  import type { ReassessRoadmapParams } from "./reassess-roadmap.js";
29
38
  import { handleReassessRoadmap } from "./reassess-roadmap.js";
30
39
  import type { ValidateMilestoneParams } from "./validate-milestone.js";
@@ -311,6 +320,9 @@ export type SliceCompleteExecutorParams = CompleteSliceParams;
311
320
  export type PlanMilestoneExecutorParams = PlanMilestoneParams;
312
321
  export type PlanSliceExecutorParams = PlanSliceParams;
313
322
  export type ReplanSliceExecutorParams = ReplanSliceParams;
323
+ export type ReopenTaskExecutorParams = ReopenTaskParams;
324
+ export type ReopenSliceExecutorParams = ReopenSliceParams;
325
+ export type ReopenMilestoneExecutorParams = ReopenMilestoneParams;
314
326
  export type ValidateMilestoneExecutorParams = ValidateMilestoneParams;
315
327
  export type ReassessRoadmapExecutorParams = ReassessRoadmapParams;
316
328
 
@@ -371,6 +383,129 @@ export async function executeTaskComplete(
371
383
  }
372
384
  }
373
385
 
386
+ export async function executeTaskReopen(
387
+ params: ReopenTaskExecutorParams,
388
+ basePath: string = process.cwd(),
389
+ ): Promise<ToolExecutionResult> {
390
+ const dbAvailable = await ensureDbOpen(basePath);
391
+ if (!dbAvailable) {
392
+ return {
393
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen task." }],
394
+ details: { operation: "reopen_task", error: "db_unavailable" },
395
+ isError: true,
396
+ };
397
+ }
398
+ try {
399
+ const result = await handleReopenTask(params, basePath);
400
+ if ("error" in result) {
401
+ return {
402
+ content: [{ type: "text", text: `Error reopening task: ${result.error}` }],
403
+ details: { operation: "reopen_task", error: result.error },
404
+ isError: true,
405
+ };
406
+ }
407
+ return {
408
+ content: [{ type: "text", text: `Reopened task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
409
+ details: {
410
+ operation: "reopen_task",
411
+ taskId: result.taskId,
412
+ sliceId: result.sliceId,
413
+ milestoneId: result.milestoneId,
414
+ },
415
+ };
416
+ } catch (err) {
417
+ const msg = err instanceof Error ? err.message : String(err);
418
+ logError("tool", `reopen_task tool failed: ${msg}`, { tool: "gsd_task_reopen", error: String(err) });
419
+ return {
420
+ content: [{ type: "text", text: `Error reopening task: ${msg}` }],
421
+ details: { operation: "reopen_task", error: msg },
422
+ isError: true,
423
+ };
424
+ }
425
+ }
426
+
427
+ export async function executeSliceReopen(
428
+ params: ReopenSliceExecutorParams,
429
+ basePath: string = process.cwd(),
430
+ ): Promise<ToolExecutionResult> {
431
+ const dbAvailable = await ensureDbOpen(basePath);
432
+ if (!dbAvailable) {
433
+ return {
434
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen slice." }],
435
+ details: { operation: "reopen_slice", error: "db_unavailable" },
436
+ isError: true,
437
+ };
438
+ }
439
+ try {
440
+ const result = await handleReopenSlice(params, basePath);
441
+ if ("error" in result) {
442
+ return {
443
+ content: [{ type: "text", text: `Error reopening slice: ${result.error}` }],
444
+ details: { operation: "reopen_slice", error: result.error },
445
+ isError: true,
446
+ };
447
+ }
448
+ return {
449
+ content: [{ type: "text", text: `Reopened slice ${result.sliceId} (${result.milestoneId})` }],
450
+ details: {
451
+ operation: "reopen_slice",
452
+ sliceId: result.sliceId,
453
+ milestoneId: result.milestoneId,
454
+ tasksReset: result.tasksReset,
455
+ },
456
+ };
457
+ } catch (err) {
458
+ const msg = err instanceof Error ? err.message : String(err);
459
+ logError("tool", `reopen_slice tool failed: ${msg}`, { tool: "gsd_slice_reopen", error: String(err) });
460
+ return {
461
+ content: [{ type: "text", text: `Error reopening slice: ${msg}` }],
462
+ details: { operation: "reopen_slice", error: msg },
463
+ isError: true,
464
+ };
465
+ }
466
+ }
467
+
468
+ export async function executeMilestoneReopen(
469
+ params: ReopenMilestoneExecutorParams,
470
+ basePath: string = process.cwd(),
471
+ ): Promise<ToolExecutionResult> {
472
+ const dbAvailable = await ensureDbOpen(basePath);
473
+ if (!dbAvailable) {
474
+ return {
475
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot reopen milestone." }],
476
+ details: { operation: "reopen_milestone", error: "db_unavailable" },
477
+ isError: true,
478
+ };
479
+ }
480
+ try {
481
+ const result = await handleReopenMilestone(params, basePath);
482
+ if ("error" in result) {
483
+ return {
484
+ content: [{ type: "text", text: `Error reopening milestone: ${result.error}` }],
485
+ details: { operation: "reopen_milestone", error: result.error },
486
+ isError: true,
487
+ };
488
+ }
489
+ return {
490
+ content: [{ type: "text", text: `Reopened milestone ${result.milestoneId}` }],
491
+ details: {
492
+ operation: "reopen_milestone",
493
+ milestoneId: result.milestoneId,
494
+ slicesReset: result.slicesReset,
495
+ tasksReset: result.tasksReset,
496
+ },
497
+ };
498
+ } catch (err) {
499
+ const msg = err instanceof Error ? err.message : String(err);
500
+ logError("tool", `reopen_milestone tool failed: ${msg}`, { tool: "gsd_milestone_reopen", error: String(err) });
501
+ return {
502
+ content: [{ type: "text", text: `Error reopening milestone: ${msg}` }],
503
+ details: { operation: "reopen_milestone", error: msg },
504
+ isError: true,
505
+ };
506
+ }
507
+ }
508
+
374
509
  export async function executeSliceComplete(
375
510
  params: SliceCompleteExecutorParams,
376
511
  basePath: string = process.cwd(),
@@ -1702,16 +1702,34 @@ export class WorktreeLifecycle {
1702
1702
  }
1703
1703
 
1704
1704
  /**
1705
- * Restore `s.basePath` to `s.originalBasePath` and rebuild `s.gitService`.
1706
- * No-op when `originalBasePath` is empty (fresh sessions).
1705
+ * Restore `s.basePath` to `s.originalBasePath`, chdir process cwd, and
1706
+ * rebuild `s.gitService`. No-op when `originalBasePath` is empty (fresh
1707
+ * sessions).
1707
1708
  *
1708
1709
  * Used by error/cleanup paths that need the session to behave as if the
1709
1710
  * worktree was never entered. Does NOT teardown the worktree directory —
1710
1711
  * callers that need teardown go through `exitMilestone({ merge: false })`.
1712
+ *
1713
+ * ADR-016 phase 3 (#5693): chdir lives inside the verb so callers do not
1714
+ * pair `restoreToProjectRoot()` with a redundant `process.chdir`. The
1715
+ * chdir runs BEFORE the throwable work (`rebuildGitService`, cache
1716
+ * invalidation) so that cleanup-path cwd is restored even if the
1717
+ * downstream rebuild throws. The chdir itself is best-effort; failure is
1718
+ * logged via debugLog and swallowed.
1711
1719
  */
1712
1720
  restoreToProjectRoot(): void {
1713
1721
  if (!this.s.originalBasePath) return;
1714
1722
  this.s.basePath = this.s.originalBasePath;
1723
+ try {
1724
+ process.chdir(this.s.basePath);
1725
+ } catch (err) {
1726
+ debugLog("WorktreeLifecycle", {
1727
+ action: "restoreToProjectRoot",
1728
+ result: "chdir-failed",
1729
+ basePath: this.s.basePath,
1730
+ error: err instanceof Error ? err.message : String(err),
1731
+ });
1732
+ }
1715
1733
  rebuildGitService(this.s, this.deps);
1716
1734
  invalidateAllCaches();
1717
1735
  }