@opengsd/gsd-pi 1.4.0-dev.c18009cd → 1.5.0-dev.553dc518
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/README.md +10 -10
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
- package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +4 -5
- package/dist/resources/extensions/gsd/auto-start.js +3 -2
- package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
- package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
- package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
- package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
- package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
- package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
- package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
- package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
- package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
- package/dist/resources/extensions/gsd/auto.js +9 -3
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +19 -1
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +118 -21
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
- package/dist/resources/extensions/gsd/db/queries.js +9 -9
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
- package/dist/resources/extensions/gsd/flat-phase-migration.js +14 -3
- package/dist/resources/extensions/gsd/forensics.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
- package/dist/resources/extensions/gsd/git-service.js +45 -0
- package/dist/resources/extensions/gsd/gsd-db.js +11 -0
- package/dist/resources/extensions/gsd/guided-flow.js +6 -10
- package/dist/resources/extensions/gsd/markdown-renderer.js +15 -3
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +82 -0
- package/dist/resources/extensions/gsd/prompts/system.md +6 -6
- package/dist/resources/extensions/gsd/quick.js +12 -3
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
- package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
- package/dist/resources/extensions/gsd/tool-contract.js +14 -0
- package/dist/resources/extensions/gsd/unit-registry.js +12 -2
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
- package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
- package/dist/resources/extensions/gsd/worktree-command.js +1 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
- package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
- 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 +8 -8
- 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 +8 -8
- 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/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +24 -35
- package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
- package/package.json +6 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +14 -9
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
- package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
- package/packages/pi-ai/dist/tool-result-content.js +62 -0
- package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +8 -20
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +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/dist/core/export-html/template.js +53 -4
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
- package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +4 -5
- package/src/resources/extensions/gsd/auto-start.ts +4 -2
- package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
- package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
- package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
- package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
- package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
- package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
- package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
- package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
- package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
- package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
- package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
- package/src/resources/extensions/gsd/auto.ts +11 -17
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +19 -1
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +152 -21
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
- package/src/resources/extensions/gsd/db/queries.ts +9 -9
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
- package/src/resources/extensions/gsd/flat-phase-migration.ts +14 -3
- package/src/resources/extensions/gsd/forensics.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +53 -0
- package/src/resources/extensions/gsd/gsd-db.ts +13 -0
- package/src/resources/extensions/gsd/guided-flow.ts +7 -11
- package/src/resources/extensions/gsd/markdown-renderer.ts +15 -3
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/preferences-types.ts +30 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +69 -0
- package/src/resources/extensions/gsd/prompts/system.md +6 -6
- package/src/resources/extensions/gsd/quick.ts +11 -3
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
- package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
- package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
- package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
- package/src/resources/extensions/gsd/tool-contract.ts +29 -0
- package/src/resources/extensions/gsd/unit-registry.ts +16 -2
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
- package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
- package/src/resources/extensions/gsd/worktree-command.ts +1 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
- package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
- /package/dist/web/standalone/.next/static/{L2UMqXELiDH3oz-7yguXp → ZpFDazP-38PXBPiI_LdZf}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L2UMqXELiDH3oz-7yguXp → ZpFDazP-38PXBPiI_LdZf}/_ssgManifest.js +0 -0
|
@@ -428,6 +428,52 @@ test("checkEngineHealth repair prunes stale phases artifact rows with present mi
|
|
|
428
428
|
assert.deepEqual(rows.map((row) => row.path), []);
|
|
429
429
|
});
|
|
430
430
|
|
|
431
|
+
test("checkEngineHealth repair keeps phases rows whose own file is still present", async (t) => {
|
|
432
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-keep-present-phase-artifact-"));
|
|
433
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
434
|
+
|
|
435
|
+
const gsdDir = join(base, ".gsd");
|
|
436
|
+
const livePath = "phases/01-m001/01-01-PLAN.md";
|
|
437
|
+
const replacementPath = "milestones/M001/slices/S01/S01-PLAN.md";
|
|
438
|
+
// Both the active phases/ file AND a legacy milestones/ copy exist on disk.
|
|
439
|
+
// The row is "fixable" (a milestones replacement is present), but its own
|
|
440
|
+
// file is present too — repair must not drop the live row.
|
|
441
|
+
mkdirSync(join(gsdDir, "phases", "01-m001"), { recursive: true });
|
|
442
|
+
writeFileSync(join(gsdDir, livePath), "# Plan\n", "utf-8");
|
|
443
|
+
mkdirSync(join(gsdDir, "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
444
|
+
writeFileSync(join(gsdDir, replacementPath), "# Plan\n", "utf-8");
|
|
445
|
+
|
|
446
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
447
|
+
insertArtifact({
|
|
448
|
+
path: livePath,
|
|
449
|
+
artifact_type: "PLAN",
|
|
450
|
+
milestone_id: "M001",
|
|
451
|
+
slice_id: "S01",
|
|
452
|
+
task_id: null,
|
|
453
|
+
full_content: "# plan\n",
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
const issues: any[] = [];
|
|
457
|
+
const fixes: string[] = [];
|
|
458
|
+
await checkEngineHealth(base, issues, fixes, { repair: true });
|
|
459
|
+
|
|
460
|
+
assert.equal(
|
|
461
|
+
fixes.some((fix) => fix.includes(livePath)),
|
|
462
|
+
false,
|
|
463
|
+
"repair must not prune a row whose own file is present on disk",
|
|
464
|
+
);
|
|
465
|
+
assert.equal(
|
|
466
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === livePath),
|
|
467
|
+
false,
|
|
468
|
+
"a present artifact must not be reported missing",
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
const rows = _getAdapter()!
|
|
472
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
473
|
+
.all() as Array<{ path: string }>;
|
|
474
|
+
assert.deepEqual(rows.map((row) => row.path), [livePath]);
|
|
475
|
+
});
|
|
476
|
+
|
|
431
477
|
test("checkEngineHealth repair prunes stale phases task rows against tasks/<T>-<TYPE>.md replacements", async (t) => {
|
|
432
478
|
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-prune-stale-task-phase-artifact-"));
|
|
433
479
|
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
@@ -540,6 +586,134 @@ test("checkEngineHealth marks escaped phases rows fixable when a milestones repl
|
|
|
540
586
|
assert.equal(issue.fixable, true, "escaped phases rows with a milestones replacement must be marked fixable");
|
|
541
587
|
});
|
|
542
588
|
|
|
589
|
+
test("checkEngineHealth resolves legacy milestones rows through flat-phase files", async (t) => {
|
|
590
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-flat-fallback-"));
|
|
591
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
592
|
+
|
|
593
|
+
const gsdDir = join(base, ".gsd");
|
|
594
|
+
const flatPath = "phases/01-foundation/01-01-PLAN.md";
|
|
595
|
+
const legacyPath = "milestones/M001/slices/S01/S01-PLAN.md";
|
|
596
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
597
|
+
writeFileSync(join(gsdDir, flatPath), "# Plan\n", "utf-8");
|
|
598
|
+
|
|
599
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
600
|
+
insertArtifact({
|
|
601
|
+
path: legacyPath,
|
|
602
|
+
artifact_type: "PLAN",
|
|
603
|
+
milestone_id: "M001",
|
|
604
|
+
slice_id: "S01",
|
|
605
|
+
task_id: null,
|
|
606
|
+
full_content: "# legacy plan row\n",
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
const issues: any[] = [];
|
|
610
|
+
await checkEngineHealth(base, issues, []);
|
|
611
|
+
|
|
612
|
+
assert.equal(
|
|
613
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === legacyPath),
|
|
614
|
+
false,
|
|
615
|
+
"legacy milestones rows should not be reported missing when the flat-phase file exists",
|
|
616
|
+
);
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
test("checkEngineHealth repair prunes stale milestones rows with present flat-phase files", async (t) => {
|
|
620
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-prune-stale-legacy-artifact-"));
|
|
621
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
622
|
+
|
|
623
|
+
const gsdDir = join(base, ".gsd");
|
|
624
|
+
const flatPath = "phases/01-foundation/01-01-PLAN.md";
|
|
625
|
+
const stalePath = "milestones/M001/slices/S01/S01-PLAN.md";
|
|
626
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
627
|
+
writeFileSync(join(gsdDir, flatPath), "# Plan\n", "utf-8");
|
|
628
|
+
|
|
629
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
630
|
+
insertArtifact({
|
|
631
|
+
path: stalePath,
|
|
632
|
+
artifact_type: "PLAN",
|
|
633
|
+
milestone_id: "M001",
|
|
634
|
+
slice_id: "S01",
|
|
635
|
+
task_id: null,
|
|
636
|
+
full_content: "# stale plan row\n",
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const issues: any[] = [];
|
|
640
|
+
const fixes: string[] = [];
|
|
641
|
+
await checkEngineHealth(base, issues, fixes, { repair: true });
|
|
642
|
+
|
|
643
|
+
assert.equal(
|
|
644
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === stalePath),
|
|
645
|
+
false,
|
|
646
|
+
"repair should not report stale legacy rows it pruned",
|
|
647
|
+
);
|
|
648
|
+
assert.ok(fixes.includes(`pruned stale legacy artifact row ${stalePath}`));
|
|
649
|
+
|
|
650
|
+
const rows = _getAdapter()!
|
|
651
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
652
|
+
.all() as Array<{ path: string }>;
|
|
653
|
+
assert.deepEqual(rows.map((row) => row.path), []);
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
test("checkEngineHealth marks stale milestones task rows without flat files fixable", async (t) => {
|
|
657
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-fixable-stale-legacy-task-artifact-"));
|
|
658
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
659
|
+
|
|
660
|
+
const gsdDir = join(base, ".gsd");
|
|
661
|
+
const stalePath = "milestones/M001/slices/S01/tasks/T01-PLAN.md";
|
|
662
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
663
|
+
|
|
664
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
665
|
+
insertArtifact({
|
|
666
|
+
path: stalePath,
|
|
667
|
+
artifact_type: "PLAN",
|
|
668
|
+
milestone_id: "M001",
|
|
669
|
+
slice_id: "S01",
|
|
670
|
+
task_id: "T01",
|
|
671
|
+
full_content: "# stale task plan row\n",
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
const issues: any[] = [];
|
|
675
|
+
await checkEngineHealth(base, issues, []);
|
|
676
|
+
|
|
677
|
+
const issue = issues.find((candidate) => candidate.code === "artifact_file_missing" && candidate.file === stalePath);
|
|
678
|
+
assert.ok(issue, "missing stale legacy task row should still be reported when repair is off");
|
|
679
|
+
assert.equal(issue.fixable, true, "stale legacy task rows without flat files should be fixable");
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
test("checkEngineHealth repair prunes stale milestones task rows without flat files", async (t) => {
|
|
683
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-prune-stale-legacy-task-artifact-"));
|
|
684
|
+
t.after(() => rmSync(base, { recursive: true, force: true }));
|
|
685
|
+
|
|
686
|
+
const gsdDir = join(base, ".gsd");
|
|
687
|
+
const stalePath = "milestones/M001/slices/S01/tasks/T01-PLAN.md";
|
|
688
|
+
mkdirSync(join(gsdDir, "phases", "01-foundation"), { recursive: true });
|
|
689
|
+
|
|
690
|
+
openDatabase(join(gsdDir, "gsd.db"));
|
|
691
|
+
insertArtifact({
|
|
692
|
+
path: stalePath,
|
|
693
|
+
artifact_type: "PLAN",
|
|
694
|
+
milestone_id: "M001",
|
|
695
|
+
slice_id: "S01",
|
|
696
|
+
task_id: "T01",
|
|
697
|
+
full_content: "# stale task plan row\n",
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
const issues: any[] = [];
|
|
701
|
+
const fixes: string[] = [];
|
|
702
|
+
await checkEngineHealth(base, issues, fixes, { repair: true });
|
|
703
|
+
|
|
704
|
+
assert.equal(
|
|
705
|
+
issues.some((issue) => issue.code === "artifact_file_missing" && issue.file === stalePath),
|
|
706
|
+
false,
|
|
707
|
+
"repair should prune stale legacy task rows that have no flat file representation",
|
|
708
|
+
);
|
|
709
|
+
assert.ok(fixes.includes(`pruned stale legacy artifact row ${stalePath}`));
|
|
710
|
+
|
|
711
|
+
const rows = _getAdapter()!
|
|
712
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
713
|
+
.all() as Array<{ path: string }>;
|
|
714
|
+
assert.deepEqual(rows.map((row) => row.path), []);
|
|
715
|
+
});
|
|
716
|
+
|
|
543
717
|
function taskSummary(id: string, verificationResult = "passed"): string {
|
|
544
718
|
return [
|
|
545
719
|
"---",
|
|
@@ -13,7 +13,7 @@ import { basename, join } from "node:path";
|
|
|
13
13
|
import {
|
|
14
14
|
fastForwardReusedMilestoneBranchIfSafe,
|
|
15
15
|
_isBranchCheckedOutElsewhere,
|
|
16
|
-
} from "../auto-worktree.js";
|
|
16
|
+
} from "../auto-worktree-branch-lifecycle.js";
|
|
17
17
|
|
|
18
18
|
const NO_PROMPT_ENV = {
|
|
19
19
|
...process.env,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
needsFlatPhaseMigration,
|
|
14
14
|
pruneStaleFlatPhaseBackups,
|
|
15
15
|
} from "../flat-phase-migration.ts";
|
|
16
|
-
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getAllMilestones, getMilestoneSlices, getSliceTasks } from "../gsd-db.ts";
|
|
16
|
+
import { openDatabase, closeDatabase, insertArtifact, insertMilestone, insertSlice, insertTask, getAllMilestones, getMilestoneSlices, getSliceTasks, _getAdapter } from "../gsd-db.ts";
|
|
17
17
|
|
|
18
18
|
const tmpDirs: string[] = [];
|
|
19
19
|
function makeTmp(options: { withTask?: boolean } = {}): string {
|
|
@@ -120,6 +120,49 @@ test("migrateToFlatPhase preserves milestone/slice/task counts in DB", async ()
|
|
|
120
120
|
assert.equal(getSliceTasks("M001", "S01").length, tasksBefore);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
+
test("migrateToFlatPhase prunes legacy milestones artifact rows after flat render", async () => {
|
|
124
|
+
const base = makeTmp();
|
|
125
|
+
insertArtifact({
|
|
126
|
+
path: "milestones/M001/M001-ROADMAP.md",
|
|
127
|
+
artifact_type: "ROADMAP",
|
|
128
|
+
milestone_id: "M001",
|
|
129
|
+
slice_id: null,
|
|
130
|
+
task_id: null,
|
|
131
|
+
full_content: "# M001: Foundation\n",
|
|
132
|
+
});
|
|
133
|
+
insertArtifact({
|
|
134
|
+
path: "milestones/M001/slices/S01/S01-PLAN.md",
|
|
135
|
+
artifact_type: "PLAN",
|
|
136
|
+
milestone_id: "M001",
|
|
137
|
+
slice_id: "S01",
|
|
138
|
+
task_id: null,
|
|
139
|
+
full_content: "# Plan\n",
|
|
140
|
+
});
|
|
141
|
+
insertArtifact({
|
|
142
|
+
path: "milestones/M001/slices/S01/tasks/T01-PLAN.md",
|
|
143
|
+
artifact_type: "PLAN",
|
|
144
|
+
milestone_id: "M001",
|
|
145
|
+
slice_id: "S01",
|
|
146
|
+
task_id: "T01",
|
|
147
|
+
full_content: "# Task Plan\n",
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
await migrateToFlatPhase(base);
|
|
151
|
+
|
|
152
|
+
const rows = _getAdapter()!
|
|
153
|
+
.prepare("SELECT path FROM artifacts ORDER BY path")
|
|
154
|
+
.all() as Array<{ path: string }>;
|
|
155
|
+
assert.equal(
|
|
156
|
+
rows.some((row) => row.path.startsWith("milestones/")),
|
|
157
|
+
false,
|
|
158
|
+
"legacy milestones/ artifact rows should be pruned after successful flat migration",
|
|
159
|
+
);
|
|
160
|
+
assert.ok(
|
|
161
|
+
rows.some((row) => row.path.startsWith("phases/")),
|
|
162
|
+
"flat-phase render should leave replacement projection rows in the artifacts table",
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
123
166
|
test("migrateToFlatPhase is idempotent (second run is a no-op)", async () => {
|
|
124
167
|
const base = makeTmp();
|
|
125
168
|
await migrateToFlatPhase(base);
|
|
@@ -7,7 +7,8 @@ import { join } from "node:path";
|
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
|
|
10
|
-
import { renderPlanFromDb, renderRoadmapFromDb } from "../markdown-renderer.ts";
|
|
10
|
+
import { renderPlanFromDb, renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-renderer.ts";
|
|
11
|
+
import { clearPathCache } from "../paths.ts";
|
|
11
12
|
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask } from "../gsd-db.ts";
|
|
12
13
|
|
|
13
14
|
const tmpDirs: string[] = [];
|
|
@@ -81,3 +82,26 @@ test("renderPlanFromDb does NOT write per-task plan files", async () => {
|
|
|
81
82
|
// taskPlanPaths should be empty — no per-task files written
|
|
82
83
|
assert.equal(result.taskPlanPaths.length, 0);
|
|
83
84
|
});
|
|
85
|
+
|
|
86
|
+
// Regression for #1190: a stray slices/SID/ subdir inside a flat-phase milestone
|
|
87
|
+
// must not divert the ASSESSMENT write into slices/SID/ (a hybrid path that
|
|
88
|
+
// auto-mode verification cannot find). It must land at the phase root.
|
|
89
|
+
test("renderAssessmentFromDb writes to the phase root even when a stray slices/SID/ dir exists", async () => {
|
|
90
|
+
const base = makeTmp();
|
|
91
|
+
const plan = await renderPlanFromDb(base, "M001", "S01");
|
|
92
|
+
const phaseDir = plan.planPath.slice(0, plan.planPath.lastIndexOf("01-01-PLAN.md"));
|
|
93
|
+
|
|
94
|
+
// Simulate the anomaly: an earlier planning step created slices/S01/ inside
|
|
95
|
+
// the flat-phase dir.
|
|
96
|
+
mkdirSync(join(phaseDir, "slices", "S01"), { recursive: true });
|
|
97
|
+
clearPathCache();
|
|
98
|
+
|
|
99
|
+
const result = await renderAssessmentFromDb(base, "M001", "S01", {
|
|
100
|
+
verdict: "on-track",
|
|
101
|
+
assessment: "Roadmap is on track.",
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
assert.match(result.assessmentPath, /phases[/\\]01-[^/\\]+[/\\]01-01-ASSESSMENT\.md$/);
|
|
105
|
+
assert.ok(!result.assessmentPath.includes(join("slices", "S01")), "must not write under slices/S01/");
|
|
106
|
+
assert.ok(existsSync(result.assessmentPath), "assessment file should exist at the phase root");
|
|
107
|
+
});
|
|
@@ -33,6 +33,10 @@ import {
|
|
|
33
33
|
getMilestoneSliceSummaries,
|
|
34
34
|
getClosedSliceIds,
|
|
35
35
|
getActiveMilestoneFromDb,
|
|
36
|
+
getActiveSliceFromDb,
|
|
37
|
+
getActiveTaskFromDb,
|
|
38
|
+
getActiveTaskIdFromDb,
|
|
39
|
+
getSliceTaskCounts,
|
|
36
40
|
deleteMilestone,
|
|
37
41
|
clearEngineHierarchy,
|
|
38
42
|
recordMilestoneCommitAttribution,
|
|
@@ -240,6 +244,42 @@ describe('gsd-db', () => {
|
|
|
240
244
|
closeDatabase();
|
|
241
245
|
});
|
|
242
246
|
|
|
247
|
+
test("gsd-db: active readers use the shared closed-status vocabulary", () => {
|
|
248
|
+
openDatabase(":memory:");
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
insertMilestone({ id: "M001", title: "Status vocabulary", status: "active" });
|
|
252
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "Closed dep", status: "closed", sequence: 1 });
|
|
253
|
+
insertSlice({ id: "S02", milestoneId: "M001", title: "Runnable", status: "pending", depends: ["S01"], sequence: 2 });
|
|
254
|
+
insertTask({ id: "T01", sliceId: "S02", milestoneId: "M001", title: "Skipped", status: "skipped", sequence: 1 });
|
|
255
|
+
insertTask({ id: "T02", sliceId: "S02", milestoneId: "M001", title: "Closed", status: "closed", sequence: 2 });
|
|
256
|
+
insertTask({ id: "T03", sliceId: "S02", milestoneId: "M001", title: "Pending", status: "pending", sequence: 3 });
|
|
257
|
+
|
|
258
|
+
assert.equal(
|
|
259
|
+
getActiveSliceFromDb("M001")?.id,
|
|
260
|
+
"S02",
|
|
261
|
+
"closed dependency slices must satisfy dependencies and be excluded from active slice selection",
|
|
262
|
+
);
|
|
263
|
+
assert.equal(
|
|
264
|
+
getActiveTaskFromDb("M001", "S02")?.id,
|
|
265
|
+
"T03",
|
|
266
|
+
"skipped/closed tasks must be excluded from active task selection",
|
|
267
|
+
);
|
|
268
|
+
assert.equal(
|
|
269
|
+
getActiveTaskIdFromDb("M001", "S02")?.id,
|
|
270
|
+
"T03",
|
|
271
|
+
"lightweight active task selection must use the same closed-status vocabulary",
|
|
272
|
+
);
|
|
273
|
+
assert.deepEqual(
|
|
274
|
+
getSliceTaskCounts("M001", "S02"),
|
|
275
|
+
{ total: 3, done: 2, pending: 1 },
|
|
276
|
+
"slice task counts must derive done/pending from the shared closed-status vocabulary",
|
|
277
|
+
);
|
|
278
|
+
} finally {
|
|
279
|
+
closeDatabase();
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
243
283
|
test('gsd-db: active_decisions view excludes superseded', () => {
|
|
244
284
|
openDatabase(':memory:');
|
|
245
285
|
|
package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts
CHANGED
|
@@ -25,12 +25,10 @@ import { join } from "node:path";
|
|
|
25
25
|
import { tmpdir } from "node:os";
|
|
26
26
|
import { execSync } from "node:child_process";
|
|
27
27
|
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
mergeMilestoneToMain,
|
|
33
|
-
} from "../../auto-worktree.ts";
|
|
28
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
29
|
+
import { isInAutoWorktree } from "../../auto-worktree-entry.ts";
|
|
30
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
31
|
+
import { getAutoWorktreeOriginalBase } from "../../auto-worktree-session-registry.ts";
|
|
34
32
|
|
|
35
33
|
function run(command: string, cwd: string): string {
|
|
36
34
|
return execSync(command, {
|
|
@@ -12,7 +12,8 @@ import { join } from "node:path";
|
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
import { execSync } from "node:child_process";
|
|
14
14
|
|
|
15
|
-
import { createAutoWorktree
|
|
15
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
16
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
16
17
|
import { nativeMergeSquash } from "../../native-git-bridge.ts";
|
|
17
18
|
|
|
18
19
|
function run(cmd: string, cwd: string): string {
|
package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts
CHANGED
|
@@ -19,12 +19,12 @@ import { join } from "node:path";
|
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import { execSync } from "node:child_process";
|
|
21
21
|
|
|
22
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
22
23
|
import {
|
|
23
|
-
createAutoWorktree,
|
|
24
24
|
mergeMilestoneToMain,
|
|
25
|
-
getAutoWorktreeOriginalBase,
|
|
26
25
|
_setRestoreEntryFnForTests,
|
|
27
|
-
} from "../../auto-worktree.ts";
|
|
26
|
+
} from "../../auto-worktree-merge.ts";
|
|
27
|
+
import { getAutoWorktreeOriginalBase } from "../../auto-worktree-session-registry.ts";
|
|
28
28
|
import { getSliceBranchName } from "../../worktree.ts";
|
|
29
29
|
import { nativeMergeSquash } from "../../native-git-bridge.ts";
|
|
30
30
|
import { drainLogs, setStderrLoggingEnabled } from "../../workflow-logger.ts";
|
|
@@ -17,17 +17,16 @@ import {
|
|
|
17
17
|
writeGsdMilestoneContext,
|
|
18
18
|
} from "./gsd-integration-fixture.ts";
|
|
19
19
|
|
|
20
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
21
|
+
import { enterAutoWorktree, isInAutoWorktree } from "../../auto-worktree-entry.ts";
|
|
22
|
+
import { getAutoWorktreePath } from "../../auto-worktree-path-resolution.ts";
|
|
20
23
|
import {
|
|
21
|
-
createAutoWorktree,
|
|
22
|
-
teardownAutoWorktree,
|
|
23
|
-
isInAutoWorktree,
|
|
24
|
-
getAutoWorktreePath,
|
|
25
|
-
enterAutoWorktree,
|
|
26
|
-
getAutoWorktreeOriginalBase,
|
|
27
24
|
getActiveAutoWorktreeContext,
|
|
28
|
-
|
|
25
|
+
getAutoWorktreeOriginalBase,
|
|
29
26
|
_resetAutoWorktreeOriginalBaseForTests,
|
|
30
|
-
} from "../../auto-worktree.ts";
|
|
27
|
+
} from "../../auto-worktree-session-registry.ts";
|
|
28
|
+
import { syncGsdStateToWorktree } from "../../auto-worktree-sync.ts";
|
|
29
|
+
import { teardownAutoWorktree } from "../../auto-worktree-teardown.ts";
|
|
31
30
|
|
|
32
31
|
// Note: execSync is used intentionally in tests for git operations with
|
|
33
32
|
// controlled, hardcoded inputs (no user input). This is safe and matches
|
package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts
CHANGED
|
@@ -22,11 +22,8 @@ import { join } from "node:path";
|
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
import { execSync } from "node:child_process";
|
|
24
24
|
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
mergeMilestoneToMain,
|
|
28
|
-
autoWorktreeBranch,
|
|
29
|
-
} from "../../auto-worktree.ts";
|
|
25
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
26
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
30
27
|
import { captureIntegrationBranch, getSliceBranchName } from "../../worktree.ts";
|
|
31
28
|
import { writeIntegrationBranch, readIntegrationBranch } from "../../git-service.ts";
|
|
32
29
|
import { nextMilestoneId, generateMilestoneSuffix } from "../../guided-flow.ts";
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
RUNTIME_EXCLUSION_PATHS,
|
|
16
16
|
VALID_BRANCH_NAME,
|
|
17
17
|
runGit,
|
|
18
|
+
taskBranchArgs,
|
|
18
19
|
readIntegrationBranch,
|
|
19
20
|
resolveMilestoneIntegrationBranch,
|
|
20
21
|
writeIntegrationBranch,
|
|
@@ -1119,6 +1120,81 @@ process.exit(result.status ?? 0);
|
|
|
1119
1120
|
rmSync(repo, { recursive: true, force: true });
|
|
1120
1121
|
}
|
|
1121
1122
|
|
|
1123
|
+
// ─── taskBranchArgs ───────────────────────────────────────────────────
|
|
1124
|
+
|
|
1125
|
+
test('taskBranchArgs starts new workflow branches from the base branch, not from HEAD', () => {
|
|
1126
|
+
const repo = initBranchTestRepo();
|
|
1127
|
+
|
|
1128
|
+
assert.deepStrictEqual(
|
|
1129
|
+
taskBranchArgs(repo, "gsd/spike/first", "main", "main"),
|
|
1130
|
+
["checkout", "-b", "gsd/spike/first"],
|
|
1131
|
+
"branching while on the base branch itself needs no explicit start point",
|
|
1132
|
+
);
|
|
1133
|
+
|
|
1134
|
+
// Simulate a finished workflow left checked out with its own commit.
|
|
1135
|
+
run("git checkout -b gsd/spike/first", repo);
|
|
1136
|
+
createFile(repo, "first.txt", "first workflow output");
|
|
1137
|
+
runGit(repo, ["add", "-A"]);
|
|
1138
|
+
runGit(repo, ["commit", "-m", "first workflow work"]);
|
|
1139
|
+
_resetHasChangesCache();
|
|
1140
|
+
|
|
1141
|
+
const args = taskBranchArgs(repo, "gsd/spike/second", "gsd/spike/first", "main");
|
|
1142
|
+
assert.deepStrictEqual(
|
|
1143
|
+
args,
|
|
1144
|
+
["checkout", "-b", "gsd/spike/second", "main"],
|
|
1145
|
+
"next workflow branch starts from the base so workflows do not stack",
|
|
1146
|
+
);
|
|
1147
|
+
|
|
1148
|
+
runGit(repo, args);
|
|
1149
|
+
assert.deepStrictEqual(
|
|
1150
|
+
run("git rev-parse HEAD", repo),
|
|
1151
|
+
run("git rev-parse main", repo),
|
|
1152
|
+
"second workflow branch points at the base, without the first workflow's commit",
|
|
1153
|
+
);
|
|
1154
|
+
|
|
1155
|
+
rmSync(repo, { recursive: true, force: true });
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
test('taskBranchArgs keeps branch-from-HEAD on user branches and unsafe states', () => {
|
|
1159
|
+
const repo = initBranchTestRepo();
|
|
1160
|
+
|
|
1161
|
+
// Manual feature branch: the user chose to stand here — new workflow
|
|
1162
|
+
// branches base on it, never silently jump to main.
|
|
1163
|
+
run("git checkout -b feature/login", repo);
|
|
1164
|
+
createFile(repo, "feature.txt", "feature work");
|
|
1165
|
+
runGit(repo, ["add", "-A"]);
|
|
1166
|
+
runGit(repo, ["commit", "-m", "feature work"]);
|
|
1167
|
+
_resetHasChangesCache();
|
|
1168
|
+
assert.deepStrictEqual(
|
|
1169
|
+
taskBranchArgs(repo, "gsd/spike/from-feature", "feature/login", "main"),
|
|
1170
|
+
["checkout", "-b", "gsd/spike/from-feature"],
|
|
1171
|
+
"a manual feature branch is a deliberate base — no redirect to main",
|
|
1172
|
+
);
|
|
1173
|
+
|
|
1174
|
+
// Base branch without a local ref (e.g. origin/HEAD names a branch that
|
|
1175
|
+
// was never checked out locally): fall back to HEAD instead of failing.
|
|
1176
|
+
run("git checkout -b gsd/spike/stale", repo);
|
|
1177
|
+
_resetHasChangesCache();
|
|
1178
|
+
assert.deepStrictEqual(
|
|
1179
|
+
taskBranchArgs(repo, "gsd/spike/next", "gsd/spike/stale", "no-such-branch"),
|
|
1180
|
+
["checkout", "-b", "gsd/spike/next"],
|
|
1181
|
+
"missing local base ref falls back to branch-from-HEAD",
|
|
1182
|
+
);
|
|
1183
|
+
|
|
1184
|
+
// Dirty tree on a task branch: a tree-changing start point would abort
|
|
1185
|
+
// the checkout or strand the changes — fall back to HEAD.
|
|
1186
|
+
createFile(repo, "dirty.txt", "uncommitted");
|
|
1187
|
+
runGit(repo, ["add", "-A"]);
|
|
1188
|
+
_resetHasChangesCache();
|
|
1189
|
+
assert.deepStrictEqual(
|
|
1190
|
+
taskBranchArgs(repo, "gsd/spike/next", "gsd/spike/stale", "main"),
|
|
1191
|
+
["checkout", "-b", "gsd/spike/next"],
|
|
1192
|
+
"dirty working tree falls back to branch-from-HEAD",
|
|
1193
|
+
);
|
|
1194
|
+
|
|
1195
|
+
rmSync(repo, { recursive: true, force: true });
|
|
1196
|
+
});
|
|
1197
|
+
|
|
1122
1198
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1123
1199
|
// S05: Enhanced features — snapshots, pre-merge checks
|
|
1124
1200
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -28,7 +28,7 @@ import { join } from "node:path";
|
|
|
28
28
|
import { tmpdir } from "node:os";
|
|
29
29
|
import { execSync } from "node:child_process";
|
|
30
30
|
|
|
31
|
-
import { mergeMilestoneToMain } from "../../auto-worktree.ts";
|
|
31
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
32
32
|
import { MergeConflictError } from "../../git-service.ts";
|
|
33
33
|
|
|
34
34
|
function run(cmd: string, cwd: string): string {
|
|
@@ -6,7 +6,7 @@ import { join } from "node:path";
|
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
|
|
8
8
|
import { GSDError } from "../../errors.js";
|
|
9
|
-
import { mergeMilestoneToMain } from "../../auto-worktree.ts";
|
|
9
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
10
10
|
|
|
11
11
|
function run(cmd: string, cwd: string): string {
|
|
12
12
|
return execSync(cmd, {
|
|
@@ -29,7 +29,8 @@ import { join } from "node:path";
|
|
|
29
29
|
import { tmpdir } from "node:os";
|
|
30
30
|
import { execSync } from "node:child_process";
|
|
31
31
|
|
|
32
|
-
import { createAutoWorktree
|
|
32
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
33
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
33
34
|
import { closeDatabase } from "../../gsd-db.ts";
|
|
34
35
|
import { getSliceBranchName } from "../../worktree.ts";
|
|
35
36
|
|
package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts
CHANGED
|
@@ -16,13 +16,11 @@ import { execSync } from "node:child_process";
|
|
|
16
16
|
import { dirname } from "node:path";
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
mergeMilestoneToMain,
|
|
25
|
-
} from "../../auto-worktree.ts";
|
|
19
|
+
import { createAutoWorktree } from "../../auto-worktree-creation.ts";
|
|
20
|
+
import { isInAutoWorktree } from "../../auto-worktree-entry.ts";
|
|
21
|
+
import { mergeMilestoneToMain } from "../../auto-worktree-merge.ts";
|
|
22
|
+
import { getAutoWorktreeOriginalBase } from "../../auto-worktree-session-registry.ts";
|
|
23
|
+
import { teardownAutoWorktree } from "../../auto-worktree-teardown.ts";
|
|
26
24
|
|
|
27
25
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
28
26
|
|
package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts
CHANGED
|
@@ -25,10 +25,8 @@ import {
|
|
|
25
25
|
markDepthVerified,
|
|
26
26
|
clearDiscussionFlowState,
|
|
27
27
|
} from "../../bootstrap/write-gate.ts";
|
|
28
|
-
import {
|
|
29
|
-
|
|
30
|
-
_resetAutoWorktreeOriginalBaseForTests,
|
|
31
|
-
} from "../../auto-worktree.ts";
|
|
28
|
+
import { _resetAutoWorktreeOriginalBaseForTests } from "../../auto-worktree-session-registry.ts";
|
|
29
|
+
import { teardownAutoWorktree } from "../../auto-worktree-teardown.ts";
|
|
32
30
|
import {
|
|
33
31
|
openDatabaseByWorkspace,
|
|
34
32
|
closeAllDatabases,
|
|
@@ -8,7 +8,7 @@ import { join } from "node:path";
|
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
9
9
|
import { execFileSync } from "node:child_process";
|
|
10
10
|
|
|
11
|
-
import { mergeMilestoneToMain } from "../auto-worktree.ts";
|
|
11
|
+
import { mergeMilestoneToMain } from "../auto-worktree-merge.ts";
|
|
12
12
|
import { checkCloseoutConsistencyGate } from "../closeout-consistency-gate.ts";
|
|
13
13
|
import {
|
|
14
14
|
closeDatabase,
|
|
@@ -14,7 +14,7 @@ import { tmpdir } from "node:os";
|
|
|
14
14
|
import { delimiter, join } from "node:path";
|
|
15
15
|
import { execFileSync } from "node:child_process";
|
|
16
16
|
|
|
17
|
-
import { mergeMilestoneToMain } from "../auto-worktree.ts";
|
|
17
|
+
import { mergeMilestoneToMain } from "../auto-worktree-merge.ts";
|
|
18
18
|
import { closeDatabase, insertAssessment, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
|
|
19
19
|
import { GIT_NO_PROMPT_ENV } from "../git-constants.js";
|
|
20
20
|
import { _clearGsdRootCache } from "../paths.ts";
|
|
@@ -19,7 +19,7 @@ import { join } from "node:path";
|
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import { execFileSync } from "node:child_process";
|
|
21
21
|
|
|
22
|
-
import { mergeMilestoneToMain } from "../auto-worktree.ts";
|
|
22
|
+
import { mergeMilestoneToMain } from "../auto-worktree-merge.ts";
|
|
23
23
|
import { _resetServiceCache } from "../worktree.ts";
|
|
24
24
|
import { _clearGsdRootCache } from "../paths.ts";
|
|
25
25
|
|