gsd-pi 2.77.0-dev.58d3d4d6c → 2.77.0-dev.cfd69e714
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 +1 -1
- package/dist/claude-cli-check.js +5 -1
- package/dist/headless.js +49 -4
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
- package/dist/resources/extensions/gsd/auto/loop.js +43 -0
- package/dist/resources/extensions/gsd/auto/phases.js +15 -21
- package/dist/resources/extensions/gsd/auto/session.js +0 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +102 -24
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +71 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +329 -102
- package/dist/resources/extensions/gsd/auto-recovery.js +195 -23
- package/dist/resources/extensions/gsd/auto-start.js +34 -24
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
- package/dist/resources/extensions/gsd/auto.js +31 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/gate-registry.js +2 -2
- package/dist/resources/extensions/gsd/git-constants.js +28 -1
- package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
- package/dist/resources/extensions/gsd/git-service.js +126 -2
- package/dist/resources/extensions/gsd/gsd-db.js +6 -3
- package/dist/resources/extensions/gsd/guided-flow.js +17 -5
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/session-lock.js +19 -10
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state.js +44 -33
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +34 -8
- package/dist/resources/extensions/mcp-client/index.js +3 -1
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -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 +5 -5
- 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/api/git/route.js +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 +5 -5
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- 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/package.json +2 -3
- package/packages/daemon/src/logger.ts +4 -3
- package/packages/mcp-server/dist/server.d.ts +24 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +88 -87
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +25 -3
- package/packages/mcp-server/src/readers/graph.test.ts +87 -15
- package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
- package/packages/mcp-server/src/server.ts +131 -105
- package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
- package/packages/native/src/__tests__/ps.test.mjs +14 -8
- package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
- package/packages/native/src/__tests__/truncate.test.mjs +17 -2
- package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +9 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +36 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/capability-patches.ts +10 -2
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +48 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
- package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +14 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +19 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/dist/editor-component.d.ts +2 -0
- package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
- package/packages/pi-tui/dist/editor-component.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/editor.ts +22 -0
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/src/editor-component.ts +3 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/scripts/install.js +15 -1
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
- package/src/resources/extensions/gsd/auto/loop.ts +47 -0
- package/src/resources/extensions/gsd/auto/phases.ts +16 -20
- package/src/resources/extensions/gsd/auto/session.ts +0 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +113 -24
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +82 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +330 -90
- package/src/resources/extensions/gsd/auto-recovery.ts +225 -24
- package/src/resources/extensions/gsd/auto-start.ts +54 -6
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
- package/src/resources/extensions/gsd/auto.ts +43 -22
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/gate-registry.ts +2 -2
- package/src/resources/extensions/gsd/git-constants.ts +30 -1
- package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
- package/src/resources/extensions/gsd/git-service.ts +133 -2
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow.ts +20 -5
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/session-lock.ts +20 -10
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state.ts +49 -44
- package/src/resources/extensions/gsd/sync-lock.ts +97 -39
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +94 -289
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -197
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +9 -105
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -57
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -62
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -49
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -133
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +12 -61
- package/src/resources/extensions/gsd/tests/test-helpers.ts +21 -8
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -81
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/types.ts +3 -3
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +55 -7
- package/src/resources/extensions/mcp-client/index.ts +3 -1
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
- package/src/resources/extensions/ollama/index.ts +5 -1
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
- package/src/resources/extensions/remote-questions/manager.ts +36 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -144
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -75
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/forensics-worktree-telemetry.test.ts +0 -145
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -130
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -43
- /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
|
@@ -19,9 +19,11 @@ import { getPendingGatesForTurn } from "./gsd-db.js";
|
|
|
19
19
|
import { assertGateCoverage, getGatesForTurn, } from "./gate-registry.js";
|
|
20
20
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
21
21
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
22
|
+
import { composeInlinedContext } from "./unit-context-composer.js";
|
|
22
23
|
import { logWarning } from "./workflow-logger.js";
|
|
23
24
|
import { inlineGraphSubgraph } from "./graph-context.js";
|
|
24
25
|
import { buildExtractionStepsBlock } from "./commands-extract-learnings.js";
|
|
26
|
+
import { warnIfManifestHasMissingSkills } from "./skill-manifest.js";
|
|
25
27
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
26
28
|
/**
|
|
27
29
|
* Historical static ceiling for the preamble cap. Kept as an upper bound even
|
|
@@ -201,6 +203,87 @@ export async function inlineFileSmart(absPath, relPath, label, query, threshold
|
|
|
201
203
|
const truncated = truncateAtSectionBoundary(content, threshold).content;
|
|
202
204
|
return `### ${label}\nSource: \`${relPath}\`\n\n${truncated}`;
|
|
203
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Compact slice-summary excerpt for milestone-level closers (#4780).
|
|
208
|
+
*
|
|
209
|
+
* Emits the frontmatter fields + short body section heads rather than the
|
|
210
|
+
* full SUMMARY.md body, and keeps the source path in the header so the
|
|
211
|
+
* closer agent can Read the full file on demand when drafting LEARNINGS.
|
|
212
|
+
*
|
|
213
|
+
* Scope: designed for `buildCompleteMilestonePrompt`, which previously
|
|
214
|
+
* inlined the full SUMMARY per slice and routinely paid ~300–500K tokens
|
|
215
|
+
* per close when the narrative was never synthesized. Not used by
|
|
216
|
+
* `buildValidateMilestonePrompt` yet — validate needs fuller verification
|
|
217
|
+
* evidence; follow-up PR can extend or parameterize.
|
|
218
|
+
*
|
|
219
|
+
* If parsing fails (unrecognizable frontmatter, missing id, etc.) the
|
|
220
|
+
* function falls back to `inlineFile` so the closer loses no information.
|
|
221
|
+
*/
|
|
222
|
+
export async function buildSliceSummaryExcerpt(absPath, relPath, sid) {
|
|
223
|
+
const header = `### ${sid} Summary (excerpt)\nSource: \`${relPath}\``;
|
|
224
|
+
const content = absPath ? await loadFile(absPath) : null;
|
|
225
|
+
if (!content) {
|
|
226
|
+
return `${header}\n\n_(not found — file does not exist yet)_`;
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
const s = parseSummary(content);
|
|
230
|
+
if (!s.frontmatter.id) {
|
|
231
|
+
// Unrecognizable — fall back to full file so no context is lost.
|
|
232
|
+
return `### ${sid} Summary\nSource: \`${relPath}\`\n\n${content.trim()}`;
|
|
233
|
+
}
|
|
234
|
+
const lines = [header, ""];
|
|
235
|
+
if (s.title)
|
|
236
|
+
lines.push(`**Title:** ${s.title}`);
|
|
237
|
+
if (s.oneLiner)
|
|
238
|
+
lines.push(`**One-liner:** ${s.oneLiner}`);
|
|
239
|
+
if (s.frontmatter.verification_result) {
|
|
240
|
+
lines.push(`**Verification:** \`${s.frontmatter.verification_result}\``);
|
|
241
|
+
}
|
|
242
|
+
lines.push(`**Blockers:** ${s.frontmatter.blocker_discovered ? "⚠️ blocker recorded — Read full summary" : "none"}`);
|
|
243
|
+
if (s.frontmatter.duration)
|
|
244
|
+
lines.push(`**Duration:** ${s.frontmatter.duration}`);
|
|
245
|
+
if (s.frontmatter.provides.length > 0)
|
|
246
|
+
lines.push(`**Provides:** ${s.frontmatter.provides.join("; ")}`);
|
|
247
|
+
if (s.frontmatter.affects.length > 0)
|
|
248
|
+
lines.push(`**Affects:** ${s.frontmatter.affects.join("; ")}`);
|
|
249
|
+
if (s.frontmatter.key_decisions.length > 0)
|
|
250
|
+
lines.push(`**Key decisions:** ${s.frontmatter.key_decisions.join("; ")}`);
|
|
251
|
+
if (s.frontmatter.patterns_established.length > 0)
|
|
252
|
+
lines.push(`**Patterns established:** ${s.frontmatter.patterns_established.join("; ")}`);
|
|
253
|
+
if (s.frontmatter.key_files.length > 0) {
|
|
254
|
+
const files = s.frontmatter.key_files.slice(0, 8);
|
|
255
|
+
const more = s.frontmatter.key_files.length > files.length ? ` (+${s.frontmatter.key_files.length - files.length} more)` : "";
|
|
256
|
+
lines.push(`**Key files:** ${files.join(", ")}${more}`);
|
|
257
|
+
}
|
|
258
|
+
// Cap section bodies (coderabbit review on #4908): if any of these
|
|
259
|
+
// narrative sections balloon, excerpt mode still inflates and
|
|
260
|
+
// undermines the token-reduction goal. 800 chars (~200 tokens) is
|
|
261
|
+
// enough to carry intent; the closer agent Reads the full file when
|
|
262
|
+
// it needs richer context for LEARNINGS synthesis.
|
|
263
|
+
const SECTION_CAP_CHARS = 800;
|
|
264
|
+
const capSection = (body) => {
|
|
265
|
+
const trimmed = body.trim();
|
|
266
|
+
if (trimmed.length <= SECTION_CAP_CHARS)
|
|
267
|
+
return trimmed;
|
|
268
|
+
return `${trimmed.slice(0, SECTION_CAP_CHARS)}\n… (truncated — see full \`${relPath}\`)`;
|
|
269
|
+
};
|
|
270
|
+
if (s.deviations && s.deviations.trim()) {
|
|
271
|
+
lines.push("", "#### Deviations", capSection(s.deviations));
|
|
272
|
+
}
|
|
273
|
+
if (s.knownLimitations && s.knownLimitations.trim()) {
|
|
274
|
+
lines.push("", "#### Known limitations", capSection(s.knownLimitations));
|
|
275
|
+
}
|
|
276
|
+
if (s.followUps && s.followUps.trim()) {
|
|
277
|
+
lines.push("", "#### Follow-ups", capSection(s.followUps));
|
|
278
|
+
}
|
|
279
|
+
lines.push("", `> **On-demand:** read \`${relPath}\` for the full "What Happened" narrative, integration notes, and detailed file-change list when drafting LEARNINGS, the Decision Re-evaluation table, or cross-slice synthesis.`);
|
|
280
|
+
return lines.join("\n");
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// Defensive — any parse failure falls back to full inline.
|
|
284
|
+
return `### ${sid} Summary\nSource: \`${relPath}\`\n\n${content.trim()}`;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
204
287
|
/**
|
|
205
288
|
* Load and inline dependency slice summaries (full content, not just paths).
|
|
206
289
|
*/
|
|
@@ -593,10 +676,23 @@ function formatSkillActivationBlock(skillNames) {
|
|
|
593
676
|
return `<skill_activation>${calls}.</skill_activation>`;
|
|
594
677
|
}
|
|
595
678
|
export function buildSkillActivationBlock(params) {
|
|
596
|
-
const prefs = params.preferences ?? loadEffectiveGSDPreferences()?.preferences;
|
|
679
|
+
const prefs = params.preferences ?? loadEffectiveGSDPreferences(params.base)?.preferences;
|
|
597
680
|
const contextTokens = tokenizeSkillContext(params.milestoneId, params.milestoneTitle, params.sliceId, params.sliceTitle, params.taskId, params.taskTitle);
|
|
598
|
-
const
|
|
681
|
+
const loaded = (typeof getLoadedSkills === 'function' ? getLoadedSkills() : []).filter(skill => !skill.disableModelInvocation);
|
|
682
|
+
// Skill activation here is driven entirely by explicit sources
|
|
683
|
+
// (always_use_skills, prefer_skills, skill_rules, task-plan skills_used).
|
|
684
|
+
// Every match is an explicit user/project intent and must not be dropped
|
|
685
|
+
// by the unit-type manifest — user intent is stronger signal than
|
|
686
|
+
// defaults. The manifest's real home is the skill catalog rendering
|
|
687
|
+
// layer (pi-coding-agent `formatSkillsForPrompt`); that wiring is tracked
|
|
688
|
+
// as the "load-time short-circuit" follow-up to RFC #4779.
|
|
689
|
+
//
|
|
690
|
+
// `unitType` stays plumbed so the strict-mode warning can surface
|
|
691
|
+
// manifest entries that reference uninstalled skills, and so the
|
|
692
|
+
// activation-block site is ready to opt in once PR B lands.
|
|
693
|
+
const visibleSkills = loaded;
|
|
599
694
|
const installedNames = new Set(visibleSkills.map(skill => normalizeSkillReference(skill.name)));
|
|
695
|
+
warnIfManifestHasMissingSkills(params.unitType, installedNames);
|
|
600
696
|
const avoided = new Set(resolvePreferenceSkillNames(prefs?.avoid_skills ?? [], params.base));
|
|
601
697
|
const matched = new Set();
|
|
602
698
|
for (const name of resolvePreferenceSkillNames(prefs?.always_use_skills ?? [], params.base)) {
|
|
@@ -979,31 +1075,63 @@ export async function buildDiscussMilestonePrompt(mid, midTitle, base, structure
|
|
|
979
1075
|
return basePrompt;
|
|
980
1076
|
}
|
|
981
1077
|
export async function buildResearchMilestonePrompt(mid, midTitle, base) {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1078
|
+
// #4782 phase 3: research-milestone migrated through the composer.
|
|
1079
|
+
// Declared inline order: milestone-context, project, requirements,
|
|
1080
|
+
// decisions, templates. Knowledge stays outside the composer
|
|
1081
|
+
// (budget-driven, scoped by keyword extraction — future phase folds
|
|
1082
|
+
// policy-driven blocks in).
|
|
1083
|
+
const resolveArtifact = async (key) => {
|
|
1084
|
+
switch (key) {
|
|
1085
|
+
case "milestone-context": {
|
|
1086
|
+
const p = resolveMilestoneFile(base, mid, "CONTEXT");
|
|
1087
|
+
const r = relMilestoneFile(base, mid, "CONTEXT");
|
|
1088
|
+
return await inlineFile(p, r, "Milestone Context");
|
|
1089
|
+
}
|
|
1090
|
+
case "project":
|
|
1091
|
+
return await inlineProjectFromDb(base);
|
|
1092
|
+
case "requirements":
|
|
1093
|
+
return await inlineRequirementsFromDb(base, mid);
|
|
1094
|
+
case "decisions":
|
|
1095
|
+
return await inlineDecisionsFromDb(base, mid);
|
|
1096
|
+
case "templates":
|
|
1097
|
+
return inlineTemplate("research", "Research");
|
|
1098
|
+
default:
|
|
1099
|
+
return null;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
const composed = await composeInlinedContext("research-milestone", resolveArtifact);
|
|
1103
|
+
// Knowledge block stays outside the composer — budgeted, scoped via
|
|
1104
|
+
// keyword extraction (#4719). Inserted between decisions and the
|
|
1105
|
+
// templates block to match the pre-migration output order. We split
|
|
1106
|
+
// the composer output around the templates section to preserve that
|
|
1107
|
+
// ordering.
|
|
996
1108
|
const knowledgeInlineRM = await inlineKnowledgeBudgeted(base, extractKeywords(midTitle));
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1109
|
+
const parts = [];
|
|
1110
|
+
if (knowledgeInlineRM && composed) {
|
|
1111
|
+
// Insert knowledge before the template block so the overall order is:
|
|
1112
|
+
// milestone-context → project → requirements → decisions → KNOWLEDGE → research template
|
|
1113
|
+
const idx = composed.lastIndexOf("### Output Template:");
|
|
1114
|
+
if (idx > 0) {
|
|
1115
|
+
const before = composed.slice(0, idx).replace(/\n\n---\n\n$/, "");
|
|
1116
|
+
const after = composed.slice(idx);
|
|
1117
|
+
parts.push(before, knowledgeInlineRM, after);
|
|
1118
|
+
}
|
|
1119
|
+
else {
|
|
1120
|
+
parts.push(composed, knowledgeInlineRM);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
else if (composed) {
|
|
1124
|
+
parts.push(composed);
|
|
1125
|
+
if (knowledgeInlineRM)
|
|
1126
|
+
parts.push(knowledgeInlineRM);
|
|
1127
|
+
}
|
|
1128
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${parts.join("\n\n---\n\n")}`);
|
|
1001
1129
|
const outputRelPath = relMilestoneFile(base, mid, "RESEARCH");
|
|
1002
1130
|
return loadPrompt("research-milestone", {
|
|
1003
1131
|
workingDirectory: base,
|
|
1004
1132
|
milestoneId: mid, milestoneTitle: midTitle,
|
|
1005
1133
|
milestonePath: relMilestonePath(base, mid),
|
|
1006
|
-
contextPath:
|
|
1134
|
+
contextPath: relMilestoneFile(base, mid, "CONTEXT"),
|
|
1007
1135
|
outputPath: join(base, outputRelPath),
|
|
1008
1136
|
inlinedContext,
|
|
1009
1137
|
skillActivation: buildSkillActivationBlock({
|
|
@@ -1011,6 +1139,7 @@ export async function buildResearchMilestonePrompt(mid, midTitle, base) {
|
|
|
1011
1139
|
milestoneId: mid,
|
|
1012
1140
|
milestoneTitle: midTitle,
|
|
1013
1141
|
extraContext: [inlinedContext],
|
|
1142
|
+
unitType: "research-milestone",
|
|
1014
1143
|
}),
|
|
1015
1144
|
...buildSkillDiscoveryVars(),
|
|
1016
1145
|
});
|
|
@@ -1086,6 +1215,7 @@ export async function buildPlanMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1086
1215
|
milestoneId: mid,
|
|
1087
1216
|
milestoneTitle: midTitle,
|
|
1088
1217
|
extraContext: [inlinedContext],
|
|
1218
|
+
unitType: "plan-milestone",
|
|
1089
1219
|
}),
|
|
1090
1220
|
...buildSkillDiscoveryVars(),
|
|
1091
1221
|
});
|
|
@@ -1159,6 +1289,7 @@ export async function buildResearchSlicePrompt(mid, _midTitle, sid, sTitle, base
|
|
|
1159
1289
|
sliceId: sid,
|
|
1160
1290
|
sliceTitle: sTitle,
|
|
1161
1291
|
extraContext: [inlinedContext, depContent],
|
|
1292
|
+
unitType: "research-slice",
|
|
1162
1293
|
}),
|
|
1163
1294
|
...buildSkillDiscoveryVars(),
|
|
1164
1295
|
});
|
|
@@ -1245,6 +1376,7 @@ async function renderSlicePrompt(options) {
|
|
|
1245
1376
|
sliceId: sid,
|
|
1246
1377
|
sliceTitle: sTitle,
|
|
1247
1378
|
extraContext: [inlinedContext, depContent],
|
|
1379
|
+
unitType: promptTemplate,
|
|
1248
1380
|
}),
|
|
1249
1381
|
...extraVars,
|
|
1250
1382
|
});
|
|
@@ -1455,51 +1587,93 @@ export async function buildExecuteTaskPrompt(mid, sid, sTitle, tid, tTitle, base
|
|
|
1455
1587
|
}
|
|
1456
1588
|
export async function buildCompleteSlicePrompt(mid, midTitle, sid, sTitle, base, level) {
|
|
1457
1589
|
const inlineLevel = level ?? resolveInlineLevel();
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
const
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
}
|
|
1475
|
-
// Scoped + budgeted — see issue #4719. Slice context is richer than
|
|
1476
|
-
// milestone context at complete-slice time, so combine both title sources.
|
|
1477
|
-
const knowledgeInlineCS = await inlineKnowledgeBudgeted(base, [...extractKeywords(midTitle), ...extractKeywords(sTitle)]);
|
|
1478
|
-
if (knowledgeInlineCS)
|
|
1479
|
-
inlined.push(knowledgeInlineCS);
|
|
1480
|
-
// Inline all task summaries for this slice
|
|
1481
|
-
const tDir = resolveTasksDir(base, mid, sid);
|
|
1482
|
-
if (tDir) {
|
|
1483
|
-
const summaryFiles = resolveTaskFiles(tDir, "SUMMARY").sort();
|
|
1484
|
-
for (const file of summaryFiles) {
|
|
1485
|
-
const absPath = join(tDir, file);
|
|
1486
|
-
const content = await loadFile(absPath);
|
|
1487
|
-
const sRel = relSlicePath(base, mid, sid);
|
|
1488
|
-
const relPath = `${sRel}/tasks/${file}`;
|
|
1489
|
-
if (content) {
|
|
1490
|
-
inlined.push(`### Task Summary: ${file.replace(/-SUMMARY\.md$/i, "")}\nSource: \`${relPath}\`\n\n${content.trim()}`);
|
|
1590
|
+
// #4782 phase 3: complete-slice migrated through composer. Manifest
|
|
1591
|
+
// declares [roadmap, slice-context, slice-plan, requirements,
|
|
1592
|
+
// prior-task-summaries, templates]. Overrides prepend and knowledge
|
|
1593
|
+
// splice stay imperative — they need the composer v2 contract
|
|
1594
|
+
// (computed + prepend blocks; see RFC #4924).
|
|
1595
|
+
const resolveArtifact = async (key) => {
|
|
1596
|
+
switch (key) {
|
|
1597
|
+
case "roadmap": {
|
|
1598
|
+
const p = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1599
|
+
const r = relMilestoneFile(base, mid, "ROADMAP");
|
|
1600
|
+
return await inlineFile(p, r, "Milestone Roadmap");
|
|
1601
|
+
}
|
|
1602
|
+
case "slice-context": {
|
|
1603
|
+
const p = resolveSliceFile(base, mid, sid, "CONTEXT");
|
|
1604
|
+
const r = relSliceFile(base, mid, sid, "CONTEXT");
|
|
1605
|
+
return await inlineFileOptional(p, r, "Slice Context (from discussion)");
|
|
1491
1606
|
}
|
|
1607
|
+
case "slice-plan": {
|
|
1608
|
+
const p = resolveSliceFile(base, mid, sid, "PLAN");
|
|
1609
|
+
const r = relSliceFile(base, mid, sid, "PLAN");
|
|
1610
|
+
return await inlineFile(p, r, "Slice Plan");
|
|
1611
|
+
}
|
|
1612
|
+
case "requirements":
|
|
1613
|
+
if (inlineLevel === "minimal")
|
|
1614
|
+
return null;
|
|
1615
|
+
return await inlineRequirementsFromDb(base, mid, sid, inlineLevel);
|
|
1616
|
+
case "prior-task-summaries": {
|
|
1617
|
+
const tDir = resolveTasksDir(base, mid, sid);
|
|
1618
|
+
if (!tDir)
|
|
1619
|
+
return null;
|
|
1620
|
+
const summaryFiles = resolveTaskFiles(tDir, "SUMMARY").sort();
|
|
1621
|
+
const sRel = relSlicePath(base, mid, sid);
|
|
1622
|
+
const blocks = [];
|
|
1623
|
+
for (const file of summaryFiles) {
|
|
1624
|
+
const absPath = join(tDir, file);
|
|
1625
|
+
const content = await loadFile(absPath);
|
|
1626
|
+
if (!content)
|
|
1627
|
+
continue;
|
|
1628
|
+
const relPath = `${sRel}/tasks/${file}`;
|
|
1629
|
+
blocks.push(`### Task Summary: ${file.replace(/-SUMMARY\.md$/i, "")}\nSource: \`${relPath}\`\n\n${content.trim()}`);
|
|
1630
|
+
}
|
|
1631
|
+
return blocks.length > 0 ? blocks.join("\n\n---\n\n") : null;
|
|
1632
|
+
}
|
|
1633
|
+
case "templates": {
|
|
1634
|
+
const parts = [inlineTemplate("slice-summary", "Slice Summary")];
|
|
1635
|
+
if (inlineLevel !== "minimal") {
|
|
1636
|
+
parts.push(inlineTemplate("uat", "UAT"));
|
|
1637
|
+
}
|
|
1638
|
+
return parts.join("\n\n---\n\n");
|
|
1639
|
+
}
|
|
1640
|
+
default:
|
|
1641
|
+
return null;
|
|
1642
|
+
}
|
|
1643
|
+
};
|
|
1644
|
+
const composed = await composeInlinedContext("complete-slice", resolveArtifact);
|
|
1645
|
+
// Knowledge splices in between requirements and prior-task-summaries
|
|
1646
|
+
// so overall order matches pre-migration: roadmap → slice-context →
|
|
1647
|
+
// slice-plan → requirements → KNOWLEDGE → task summaries → templates.
|
|
1648
|
+
const knowledgeInlineCS = await inlineKnowledgeBudgeted(base, [...extractKeywords(midTitle), ...extractKeywords(sTitle)]);
|
|
1649
|
+
let body = composed;
|
|
1650
|
+
if (knowledgeInlineCS && body) {
|
|
1651
|
+
// Splice knowledge right before the first "### Task Summary:" block
|
|
1652
|
+
// to preserve pre-migration ordering. If no task summaries exist,
|
|
1653
|
+
// splice before the templates block (which inlineTemplate emits as
|
|
1654
|
+
// "### Output Template: Slice Summary").
|
|
1655
|
+
const taskIdx = body.indexOf("### Task Summary:");
|
|
1656
|
+
const templatesIdx = body.lastIndexOf("### Output Template: Slice Summary");
|
|
1657
|
+
const spliceIdx = taskIdx > -1 ? taskIdx : templatesIdx;
|
|
1658
|
+
if (spliceIdx > 0) {
|
|
1659
|
+
const before = body.slice(0, spliceIdx).replace(/\n\n---\n\n$/, "");
|
|
1660
|
+
const after = body.slice(spliceIdx);
|
|
1661
|
+
body = [before, knowledgeInlineCS, after].join("\n\n---\n\n");
|
|
1662
|
+
}
|
|
1663
|
+
else {
|
|
1664
|
+
body = `${body}\n\n---\n\n${knowledgeInlineCS}`;
|
|
1492
1665
|
}
|
|
1493
1666
|
}
|
|
1494
|
-
inlined
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
}
|
|
1667
|
+
// Overrides section prepends to the top of the inlined context —
|
|
1668
|
+
// standard pattern for slice-level builders (until composer v2 lands
|
|
1669
|
+
// the prepend contract).
|
|
1498
1670
|
const completeActiveOverrides = await loadActiveOverrides(base);
|
|
1499
1671
|
const completeOverridesInline = formatOverridesSection(completeActiveOverrides);
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1672
|
+
const finalBody = completeOverridesInline
|
|
1673
|
+
? `${completeOverridesInline}\n\n---\n\n${body}`
|
|
1674
|
+
: body;
|
|
1675
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${finalBody}`);
|
|
1676
|
+
const roadmapRel = relMilestoneFile(base, mid, "ROADMAP");
|
|
1503
1677
|
const sliceRel = relSlicePath(base, mid, sid);
|
|
1504
1678
|
const sliceSummaryPath = join(base, `${sliceRel}/${sid}-SUMMARY.md`);
|
|
1505
1679
|
const sliceUatPath = join(base, `${sliceRel}/${sid}-UAT.md`);
|
|
@@ -1550,13 +1724,21 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1550
1724
|
}
|
|
1551
1725
|
}
|
|
1552
1726
|
const seenSlices = new Set();
|
|
1727
|
+
const summaryRelPaths = [];
|
|
1553
1728
|
for (const sid of sliceIds) {
|
|
1554
1729
|
if (seenSlices.has(sid))
|
|
1555
1730
|
continue;
|
|
1556
1731
|
seenSlices.add(sid);
|
|
1557
1732
|
const summaryPath = resolveSliceFile(base, mid, sid, "SUMMARY");
|
|
1558
1733
|
const summaryRel = relSliceFile(base, mid, sid, "SUMMARY");
|
|
1559
|
-
|
|
1734
|
+
summaryRelPaths.push(summaryRel);
|
|
1735
|
+
// Compact excerpt instead of full inline (#4780). Closer Reads the
|
|
1736
|
+
// full file on-demand when synthesizing LEARNINGS narrative.
|
|
1737
|
+
inlined.push(await buildSliceSummaryExcerpt(summaryPath, summaryRel, sid));
|
|
1738
|
+
}
|
|
1739
|
+
if (summaryRelPaths.length > 0) {
|
|
1740
|
+
const pathList = summaryRelPaths.map(p => `- \`${p}\``).join("\n");
|
|
1741
|
+
inlined.push(`### On-demand Slice Summaries\n\nExcerpted above. Read the full file for any slice when the excerpt's section heads don't carry enough narrative for the milestone summary you're drafting:\n\n${pathList}`);
|
|
1560
1742
|
}
|
|
1561
1743
|
// Inline root GSD files (skip for minimal — completion can read these if needed)
|
|
1562
1744
|
if (inlineLevel !== "minimal") {
|
|
@@ -1603,6 +1785,7 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1603
1785
|
milestoneId: mid,
|
|
1604
1786
|
milestoneTitle: midTitle,
|
|
1605
1787
|
extraContext: [inlinedContext],
|
|
1788
|
+
unitType: "complete-milestone",
|
|
1606
1789
|
}),
|
|
1607
1790
|
});
|
|
1608
1791
|
}
|
|
@@ -1746,6 +1929,7 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1746
1929
|
milestoneId: mid,
|
|
1747
1930
|
milestoneTitle: midTitle,
|
|
1748
1931
|
extraContext: [inlinedContext],
|
|
1932
|
+
unitType: "validate-milestone",
|
|
1749
1933
|
}),
|
|
1750
1934
|
});
|
|
1751
1935
|
}
|
|
@@ -1821,23 +2005,42 @@ export async function buildReplanSlicePrompt(mid, midTitle, sid, sTitle, base) {
|
|
|
1821
2005
|
sliceId: sid,
|
|
1822
2006
|
sliceTitle: sTitle,
|
|
1823
2007
|
extraContext: [inlinedContext, captureContext],
|
|
2008
|
+
unitType: "replan-slice",
|
|
1824
2009
|
}),
|
|
1825
2010
|
});
|
|
1826
2011
|
}
|
|
1827
2012
|
export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base) {
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
const
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
2013
|
+
// #4782 phase 3: run-uat migrated to compose its inlined context via
|
|
2014
|
+
// the manifest. Behavior-equivalent — resolver dispatches to the same
|
|
2015
|
+
// inline* helpers as the pre-migration builder.
|
|
2016
|
+
const resolveArtifact = async (key) => {
|
|
2017
|
+
switch (key) {
|
|
2018
|
+
case "slice-uat": {
|
|
2019
|
+
// Use the in-memory snapshot the caller already loaded (#4925 review).
|
|
2020
|
+
// Re-reading from disk via inlineFile(p, uatPath, ...) would risk
|
|
2021
|
+
// drift between the inlined body and uatType (computed from
|
|
2022
|
+
// uatContent below) if the file changes mid-dispatch.
|
|
2023
|
+
const trimmed = uatContent.trim();
|
|
2024
|
+
if (!trimmed) {
|
|
2025
|
+
return `### ${sliceId} UAT\nSource: \`${uatPath}\`\n\n_(not found — file does not exist yet)_`;
|
|
2026
|
+
}
|
|
2027
|
+
return `### ${sliceId} UAT\nSource: \`${uatPath}\`\n\n${trimmed}`;
|
|
2028
|
+
}
|
|
2029
|
+
case "slice-summary": {
|
|
2030
|
+
const p = resolveSliceFile(base, mid, sliceId, "SUMMARY");
|
|
2031
|
+
if (!p)
|
|
2032
|
+
return null;
|
|
2033
|
+
const r = relSliceFile(base, mid, sliceId, "SUMMARY");
|
|
2034
|
+
return await inlineFileOptional(p, r, `${sliceId} Summary`);
|
|
2035
|
+
}
|
|
2036
|
+
case "project":
|
|
2037
|
+
return await inlineProjectFromDb(base);
|
|
2038
|
+
default:
|
|
2039
|
+
return null;
|
|
2040
|
+
}
|
|
2041
|
+
};
|
|
2042
|
+
const composed = await composeInlinedContext("run-uat", resolveArtifact);
|
|
2043
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${composed}`);
|
|
1841
2044
|
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "ASSESSMENT"));
|
|
1842
2045
|
const uatType = getUatType(uatContent);
|
|
1843
2046
|
return loadPrompt("run-uat", {
|
|
@@ -1853,39 +2056,62 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
|
|
|
1853
2056
|
milestoneId: mid,
|
|
1854
2057
|
sliceId,
|
|
1855
2058
|
extraContext: [inlinedContext],
|
|
2059
|
+
unitType: "run-uat",
|
|
1856
2060
|
}),
|
|
1857
2061
|
});
|
|
1858
2062
|
}
|
|
1859
2063
|
export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId, base, level) {
|
|
1860
2064
|
const inlineLevel = level ?? resolveInlineLevel();
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
2065
|
+
// #4782 phase 2 pilot: reassess-roadmap is the first unit type to
|
|
2066
|
+
// compose its inlined context through the manifest-driven composer.
|
|
2067
|
+
// The resolver below dispatches artifact keys to the existing inline*
|
|
2068
|
+
// helpers, preserving identical output so the migration is
|
|
2069
|
+
// observable-equivalent. Knowledge stays outside the composer (it's
|
|
2070
|
+
// budget-driven, not manifest-driven) until a later phase formalizes
|
|
2071
|
+
// knowledge/memory policies as composer inputs.
|
|
2072
|
+
const resolveArtifact = async (key) => {
|
|
2073
|
+
switch (key) {
|
|
2074
|
+
case "roadmap": {
|
|
2075
|
+
const p = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
2076
|
+
const r = relMilestoneFile(base, mid, "ROADMAP");
|
|
2077
|
+
return await inlineFile(p, r, "Current Roadmap");
|
|
2078
|
+
}
|
|
2079
|
+
case "slice-context": {
|
|
2080
|
+
const p = resolveSliceFile(base, mid, completedSliceId, "CONTEXT");
|
|
2081
|
+
const r = relSliceFile(base, mid, completedSliceId, "CONTEXT");
|
|
2082
|
+
return await inlineFileOptional(p, r, "Slice Context (from discussion)");
|
|
2083
|
+
}
|
|
2084
|
+
case "slice-summary": {
|
|
2085
|
+
const p = resolveSliceFile(base, mid, completedSliceId, "SUMMARY");
|
|
2086
|
+
const r = relSliceFile(base, mid, completedSliceId, "SUMMARY");
|
|
2087
|
+
return await inlineFile(p, r, `${completedSliceId} Summary`);
|
|
2088
|
+
}
|
|
2089
|
+
case "project":
|
|
2090
|
+
if (inlineLevel === "minimal")
|
|
2091
|
+
return null;
|
|
2092
|
+
return await inlineProjectFromDb(base);
|
|
2093
|
+
case "requirements":
|
|
2094
|
+
if (inlineLevel === "minimal")
|
|
2095
|
+
return null;
|
|
2096
|
+
return await inlineRequirementsFromDb(base, mid, undefined, inlineLevel);
|
|
2097
|
+
case "decisions":
|
|
2098
|
+
if (inlineLevel === "minimal")
|
|
2099
|
+
return null;
|
|
2100
|
+
return await inlineDecisionsFromDb(base, mid, undefined, inlineLevel);
|
|
2101
|
+
default:
|
|
2102
|
+
return null;
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
const composed = await composeInlinedContext("reassess-roadmap", resolveArtifact);
|
|
2106
|
+
const parts = [];
|
|
2107
|
+
if (composed)
|
|
2108
|
+
parts.push(composed);
|
|
2109
|
+
// Knowledge block stays outside the composer — budgeted, scoped via
|
|
2110
|
+
// keyword extraction (#4719). Future phase folds it in.
|
|
1885
2111
|
const knowledgeInlineRA = await inlineKnowledgeBudgeted(base, extractKeywords(midTitle));
|
|
1886
2112
|
if (knowledgeInlineRA)
|
|
1887
|
-
|
|
1888
|
-
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${
|
|
2113
|
+
parts.push(knowledgeInlineRA);
|
|
2114
|
+
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${parts.join("\n\n---\n\n")}`);
|
|
1889
2115
|
const assessmentPath = join(base, relSliceFile(base, mid, completedSliceId, "ASSESSMENT"));
|
|
1890
2116
|
// Build deferred captures context for reassess prompt
|
|
1891
2117
|
let deferredCaptures = "(none)";
|
|
@@ -1905,7 +2131,7 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
|
|
|
1905
2131
|
milestoneId: mid,
|
|
1906
2132
|
milestoneTitle: midTitle,
|
|
1907
2133
|
completedSliceId,
|
|
1908
|
-
roadmapPath:
|
|
2134
|
+
roadmapPath: relMilestoneFile(base, mid, "ROADMAP"),
|
|
1909
2135
|
assessmentPath,
|
|
1910
2136
|
inlinedContext,
|
|
1911
2137
|
deferredCaptures,
|
|
@@ -1915,6 +2141,7 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
|
|
|
1915
2141
|
milestoneId: mid,
|
|
1916
2142
|
milestoneTitle: midTitle,
|
|
1917
2143
|
extraContext: [inlinedContext, deferredCaptures],
|
|
2144
|
+
unitType: "reassess-roadmap",
|
|
1918
2145
|
}),
|
|
1919
2146
|
});
|
|
1920
2147
|
}
|