gsd-pi 2.65.0-dev.5c8557b → 2.65.0-dev.800ece0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp-server.js +6 -2
- package/dist/resources/extensions/browser-tools/capture.js +20 -1
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
- package/dist/resources/extensions/gsd/auto/finalize-timeout.js +2 -0
- package/dist/resources/extensions/gsd/auto/loop.js +2 -2
- package/dist/resources/extensions/gsd/auto/phases.js +48 -5
- package/dist/resources/extensions/gsd/auto/run-unit.js +13 -2
- package/dist/resources/extensions/gsd/auto/session.js +4 -0
- package/dist/resources/extensions/gsd/auto/types.js +2 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +2 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +99 -9
- package/dist/resources/extensions/gsd/auto-model-selection.js +7 -5
- package/dist/resources/extensions/gsd/auto-post-unit.js +17 -6
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +40 -22
- package/dist/resources/extensions/gsd/auto-start.js +175 -12
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +10 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +29 -7
- package/dist/resources/extensions/gsd/auto.js +21 -15
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -4
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -0
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -3
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +31 -1
- package/dist/resources/extensions/gsd/commands/context.js +8 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -2
- package/dist/resources/extensions/gsd/commands-extensions.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +312 -0
- package/dist/resources/extensions/gsd/db-writer.js +13 -3
- package/dist/resources/extensions/gsd/detection.js +1 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/dist/resources/extensions/gsd/doctor.js +2 -1
- package/dist/resources/extensions/gsd/files.js +17 -0
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +47 -4
- package/dist/resources/extensions/gsd/guided-flow.js +220 -29
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/json-persistence.js +5 -2
- package/dist/resources/extensions/gsd/md-importer.js +14 -7
- package/dist/resources/extensions/gsd/notification-overlay.js +1 -1
- package/dist/resources/extensions/gsd/notification-widget.js +2 -1
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +17 -11
- package/dist/resources/extensions/gsd/pre-execution-checks.js +26 -5
- package/dist/resources/extensions/gsd/preferences-types.js +3 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +45 -1
- package/dist/resources/extensions/gsd/preferences.js +9 -2
- package/dist/resources/extensions/gsd/preparation.js +1092 -0
- package/dist/resources/extensions/gsd/prompt-validation.js +67 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +6 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
- package/dist/resources/extensions/gsd/prompts/queue.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +2 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
- package/dist/resources/extensions/gsd/quick.js +19 -15
- package/dist/resources/extensions/gsd/reactive-graph.js +12 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +24 -5
- package/dist/resources/extensions/gsd/safety/content-validator.js +3 -3
- package/dist/resources/extensions/gsd/session-lock.js +23 -1
- package/dist/resources/extensions/gsd/state.js +115 -28
- package/dist/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -3
- package/dist/resources/extensions/gsd/tools/complete-slice.js +27 -6
- package/dist/resources/extensions/gsd/tools/complete-task.js +31 -7
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -5
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +5 -2
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +119 -0
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +30 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +18 -0
- package/dist/resources/extensions/gsd/triage-resolution.js +33 -16
- package/dist/resources/extensions/gsd/undo.js +3 -2
- package/dist/resources/extensions/gsd/workflow-events.js +1 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +7 -9
- package/dist/resources/extensions/gsd/workflow-reconcile.js +100 -9
- package/dist/resources/extensions/gsd/workflow-templates.js +11 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +5 -2
- package/dist/resources/extensions/gsd/worktree.js +9 -0
- package/dist/resources/extensions/shared/interview-ui.js +1 -1
- package/dist/resources/extensions/subagent/agents.js +19 -5
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- 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 +18 -18
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/6502.8874bcae249c02e1.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-a1c1e452c6b32d04.js → webpack-9fed74684e1c5bb1.js} +1 -1
- package/package.json +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 +30 -19
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +51 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +9 -9
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +10 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +20 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +15 -1
- 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 +18 -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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +80 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +37 -25
- package/packages/pi-coding-agent/src/core/sdk.ts +9 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +20 -4
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +27 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +16 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +5 -0
- package/packages/pi-tui/dist/components/image.d.ts +2 -0
- package/packages/pi-tui/dist/components/image.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/image.js +4 -0
- package/packages/pi-tui/dist/components/image.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.d.ts +6 -0
- package/packages/pi-tui/dist/components/image.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/image.test.js +32 -0
- package/packages/pi-tui/dist/components/image.test.js.map +1 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +3 -1
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/components/image.test.ts +36 -0
- package/packages/pi-tui/src/components/image.ts +5 -0
- package/packages/pi-tui/src/tui.ts +3 -1
- package/src/resources/extensions/browser-tools/capture.ts +19 -1
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +93 -0
- package/src/resources/extensions/gsd/auto/finalize-timeout.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop.ts +2 -2
- package/src/resources/extensions/gsd/auto/phases.ts +68 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +12 -2
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto/types.ts +5 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +2 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +110 -9
- package/src/resources/extensions/gsd/auto-model-selection.ts +7 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +16 -6
- package/src/resources/extensions/gsd/auto-prompts.ts +31 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +29 -23
- package/src/resources/extensions/gsd/auto-start.ts +188 -10
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +10 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +28 -7
- package/src/resources/extensions/gsd/auto.ts +19 -8
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -0
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +4 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +36 -1
- package/src/resources/extensions/gsd/commands/context.ts +7 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +26 -2
- package/src/resources/extensions/gsd/commands-extensions.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +331 -0
- package/src/resources/extensions/gsd/db-writer.ts +11 -3
- package/src/resources/extensions/gsd/detection.ts +1 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -1
- package/src/resources/extensions/gsd/files.ts +19 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/gsd-db.ts +46 -4
- package/src/resources/extensions/gsd/guided-flow.ts +254 -30
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/json-persistence.ts +6 -3
- package/src/resources/extensions/gsd/md-importer.ts +13 -6
- package/src/resources/extensions/gsd/notification-overlay.ts +1 -1
- package/src/resources/extensions/gsd/notification-widget.ts +2 -1
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +19 -11
- package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -7
- package/src/resources/extensions/gsd/preferences-types.ts +25 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +45 -1
- package/src/resources/extensions/gsd/preferences.ts +9 -2
- package/src/resources/extensions/gsd/preparation.ts +1419 -0
- package/src/resources/extensions/gsd/prompt-validation.ts +88 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +3 -3
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +424 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +6 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -4
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +23 -0
- package/src/resources/extensions/gsd/prompts/queue.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +2 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +56 -23
- package/src/resources/extensions/gsd/quick.ts +20 -15
- package/src/resources/extensions/gsd/reactive-graph.ts +18 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +21 -5
- package/src/resources/extensions/gsd/safety/content-validator.ts +3 -3
- package/src/resources/extensions/gsd/session-lock.ts +17 -1
- package/src/resources/extensions/gsd/state.ts +115 -26
- package/src/resources/extensions/gsd/templates/context-enhanced.md +138 -0
- package/src/resources/extensions/gsd/tests/adversarial-review-fixes.test.ts +223 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +33 -2
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +72 -0
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/defer-milestone-stamp.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +11 -9
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +28 -30
- package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
- package/src/resources/extensions/gsd/tests/integration-prepared-discussion.test.ts +525 -0
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +11 -10
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +189 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +284 -20
- package/src/resources/extensions/gsd/tests/pre-execution-fail-closed.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/preparation.test.ts +1211 -0
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/prompt-builder.test.ts +669 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +7 -4
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +6 -7
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/subagent-agent-discovery.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/symlink-extension-discovery.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/wave1-critical-regressions.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/wave2-events-regressions.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/wave3-session-regressions.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/wave4-write-safety-regressions.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/wave5-consistency-regressions.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-audit.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +16 -17
- package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +13 -9
- package/src/resources/extensions/gsd/tests/worktree.test.ts +26 -9
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +127 -2
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +13 -3
- package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -6
- package/src/resources/extensions/gsd/tools/complete-task.ts +29 -7
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +11 -9
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +5 -2
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +152 -0
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +27 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +17 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +37 -17
- package/src/resources/extensions/gsd/types.ts +4 -0
- package/src/resources/extensions/gsd/undo.ts +3 -2
- package/src/resources/extensions/gsd/workflow-events.ts +5 -3
- package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +7 -8
- package/src/resources/extensions/gsd/workflow-reconcile.ts +109 -8
- package/src/resources/extensions/gsd/workflow-templates.ts +11 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +4 -2
- package/src/resources/extensions/gsd/worktree.ts +10 -0
- package/src/resources/extensions/shared/interview-ui.ts +1 -1
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +8 -10
- package/src/resources/extensions/subagent/agents.ts +30 -6
- package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +0 -9
- /package/dist/web/standalone/.next/static/{qq3YfHPfyqvh3DIMVmsRH → E0hBt4ifuG7QBbhUR5-6U}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{qq3YfHPfyqvh3DIMVmsRH → E0hBt4ifuG7QBbhUR5-6U}/_ssgManifest.js +0 -0
|
@@ -7,12 +7,20 @@ import {
|
|
|
7
7
|
transaction,
|
|
8
8
|
updateTaskStatus,
|
|
9
9
|
updateSliceStatus,
|
|
10
|
+
updateMilestoneStatus,
|
|
10
11
|
getSliceTasks,
|
|
12
|
+
insertMilestone,
|
|
13
|
+
_getAdapter,
|
|
14
|
+
getMilestoneSlices,
|
|
11
15
|
insertVerificationEvidence,
|
|
12
16
|
upsertDecision,
|
|
13
17
|
openDatabase,
|
|
18
|
+
setTaskBlockerDiscovered,
|
|
14
19
|
} from "./gsd-db.js";
|
|
15
20
|
import { isClosedStatus } from "./status-guards.js";
|
|
21
|
+
import { invalidateStateCache } from "./state.js";
|
|
22
|
+
import { clearPathCache } from "./paths.js";
|
|
23
|
+
import { clearParseCache } from "./files.js";
|
|
16
24
|
import { writeManifest } from "./workflow-manifest.js";
|
|
17
25
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
18
26
|
import { acquireSyncLock, releaseSyncLock } from "./sync-lock.js";
|
|
@@ -73,7 +81,15 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
73
81
|
transaction(() => {
|
|
74
82
|
for (const event of events) {
|
|
75
83
|
const p = event.params;
|
|
76
|
-
|
|
84
|
+
// Normalize cmd format: completion tools write hyphens ("complete-task"),
|
|
85
|
+
// legacy logs use underscores ("complete_task"). Accept both formats.
|
|
86
|
+
// Type guard: malformed event lines with non-string cmd are skipped.
|
|
87
|
+
if (typeof event.cmd !== "string") {
|
|
88
|
+
logWarning("reconcile", `Event with non-string cmd skipped: ${JSON.stringify(event.cmd)}`);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const cmd = event.cmd.replace(/-/g, "_");
|
|
92
|
+
switch (cmd) {
|
|
77
93
|
case "complete_task": {
|
|
78
94
|
const milestoneId = p["milestoneId"] as string;
|
|
79
95
|
const sliceId = p["sliceId"] as string;
|
|
@@ -89,13 +105,11 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
89
105
|
break;
|
|
90
106
|
}
|
|
91
107
|
case "report_blocker": {
|
|
92
|
-
// report_blocker marks the task with blocker_discovered = 1
|
|
93
|
-
// The DB helper updateTaskStatus doesn't handle blockers,
|
|
94
|
-
// so we just update status to "blocked" as a best-effort replay.
|
|
95
108
|
const milestoneId = p["milestoneId"] as string;
|
|
96
109
|
const sliceId = p["sliceId"] as string;
|
|
97
110
|
const taskId = p["taskId"] as string;
|
|
98
111
|
updateTaskStatus(milestoneId, sliceId, taskId, "blocked");
|
|
112
|
+
setTaskBlockerDiscovered(milestoneId, sliceId, taskId, true);
|
|
99
113
|
break;
|
|
100
114
|
}
|
|
101
115
|
case "record_verification": {
|
|
@@ -120,9 +134,66 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
120
134
|
replaySliceComplete(milestoneId, sliceId, event.ts);
|
|
121
135
|
break;
|
|
122
136
|
}
|
|
137
|
+
case "complete_milestone": {
|
|
138
|
+
const milestoneId = p["milestoneId"] as string;
|
|
139
|
+
if (!milestoneId) break;
|
|
140
|
+
// Invariant check: only mark complete if all slices are closed.
|
|
141
|
+
// Without this guard, a reordered/partial event stream could close
|
|
142
|
+
// a milestone while work is still incomplete.
|
|
143
|
+
const mSlices = getMilestoneSlices(milestoneId);
|
|
144
|
+
const allClosed = mSlices.length === 0 || mSlices.every(s => isClosedStatus(s.status));
|
|
145
|
+
if (allClosed) {
|
|
146
|
+
updateMilestoneStatus(milestoneId, "complete", event.ts);
|
|
147
|
+
} else {
|
|
148
|
+
logWarning("reconcile", `Skipping complete_milestone replay for ${milestoneId}: not all slices are closed`);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "plan_milestone": {
|
|
153
|
+
// Replay milestone creation — uses INSERT OR IGNORE (gsd-db's insertMilestone is safe)
|
|
154
|
+
const mId = p["milestoneId"] as string;
|
|
155
|
+
if (mId) {
|
|
156
|
+
insertMilestone({ id: mId, title: (p["title"] as string) ?? mId });
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
123
160
|
case "plan_slice": {
|
|
124
|
-
//
|
|
125
|
-
//
|
|
161
|
+
// Replay slice creation — strict INSERT OR IGNORE to avoid overwriting
|
|
162
|
+
// progressed status. insertSlice() uses ON CONFLICT DO UPDATE which
|
|
163
|
+
// could downgrade a completed slice back to pending.
|
|
164
|
+
const milestoneId = p["milestoneId"] as string;
|
|
165
|
+
const sliceId = p["sliceId"] as string;
|
|
166
|
+
if (milestoneId && sliceId) {
|
|
167
|
+
const adapter = _getAdapter();
|
|
168
|
+
if (adapter) {
|
|
169
|
+
adapter.prepare(
|
|
170
|
+
`INSERT OR IGNORE INTO slices (milestone_id, id, title, status, created_at)
|
|
171
|
+
VALUES (:mid, :sid, :title, 'pending', :ts)`,
|
|
172
|
+
).run({ ":mid": milestoneId, ":sid": sliceId, ":title": (p["title"] as string) ?? sliceId, ":ts": event.ts });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
case "plan_task": {
|
|
178
|
+
// Replay task creation — strict INSERT OR IGNORE to avoid overwriting
|
|
179
|
+
// progressed status. insertTask() uses ON CONFLICT DO UPDATE which
|
|
180
|
+
// could downgrade a done/in-progress task back to pending.
|
|
181
|
+
const milestoneId = p["milestoneId"] as string;
|
|
182
|
+
const sliceId = p["sliceId"] as string;
|
|
183
|
+
const taskId = p["taskId"] as string;
|
|
184
|
+
if (milestoneId && sliceId && taskId) {
|
|
185
|
+
const adapter = _getAdapter();
|
|
186
|
+
if (adapter) {
|
|
187
|
+
adapter.prepare(
|
|
188
|
+
`INSERT OR IGNORE INTO tasks (milestone_id, slice_id, id, title, status, created_at)
|
|
189
|
+
VALUES (:mid, :sid, :tid, :title, 'pending', :ts)`,
|
|
190
|
+
).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId, ":title": (p["title"] as string) ?? taskId, ":ts": event.ts });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case "replan_slice": {
|
|
196
|
+
// Informational — replan events don't mutate DB during replay
|
|
126
197
|
break;
|
|
127
198
|
}
|
|
128
199
|
case "save_decision": {
|
|
@@ -140,7 +211,7 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
140
211
|
break;
|
|
141
212
|
}
|
|
142
213
|
default:
|
|
143
|
-
|
|
214
|
+
logWarning("reconcile", `Unknown event cmd during replay: "${event.cmd}" — skipped`);
|
|
144
215
|
break;
|
|
145
216
|
}
|
|
146
217
|
}
|
|
@@ -158,26 +229,42 @@ export function extractEntityKey(
|
|
|
158
229
|
event: WorkflowEvent,
|
|
159
230
|
): { type: string; id: string } | null {
|
|
160
231
|
const p = event.params;
|
|
232
|
+
// Normalize cmd format: accept both hyphens and underscores
|
|
233
|
+
if (typeof event.cmd !== "string") return null;
|
|
234
|
+
const cmd = event.cmd.replace(/-/g, "_");
|
|
161
235
|
|
|
162
|
-
switch (
|
|
236
|
+
switch (cmd) {
|
|
163
237
|
case "complete_task":
|
|
164
238
|
case "start_task":
|
|
165
239
|
case "report_blocker":
|
|
166
240
|
case "record_verification":
|
|
241
|
+
case "plan_task":
|
|
167
242
|
return typeof p["taskId"] === "string"
|
|
168
243
|
? { type: "task", id: p["taskId"] }
|
|
169
244
|
: null;
|
|
170
245
|
|
|
171
246
|
case "complete_slice":
|
|
247
|
+
case "replan_slice":
|
|
172
248
|
return typeof p["sliceId"] === "string"
|
|
173
249
|
? { type: "slice", id: p["sliceId"] }
|
|
174
250
|
: null;
|
|
175
251
|
|
|
252
|
+
case "complete_milestone":
|
|
253
|
+
return typeof p["milestoneId"] === "string"
|
|
254
|
+
? { type: "milestone", id: p["milestoneId"] }
|
|
255
|
+
: null;
|
|
256
|
+
|
|
176
257
|
case "plan_slice":
|
|
177
258
|
return typeof p["sliceId"] === "string"
|
|
178
259
|
? { type: "slice_plan", id: p["sliceId"] }
|
|
179
260
|
: null;
|
|
180
261
|
|
|
262
|
+
case "complete_milestone":
|
|
263
|
+
case "plan_milestone":
|
|
264
|
+
return typeof p["milestoneId"] === "string"
|
|
265
|
+
? { type: "milestone", id: p["milestoneId"] }
|
|
266
|
+
: null;
|
|
267
|
+
|
|
181
268
|
case "save_decision":
|
|
182
269
|
if (typeof p["scope"] === "string" && typeof p["decision"] === "string") {
|
|
183
270
|
return { type: "decision", id: `${p["scope"]}:${p["decision"]}` };
|
|
@@ -360,6 +447,14 @@ function _reconcileWorktreeLogsInner(
|
|
|
360
447
|
const merged = indexed.map(({ e }) => e);
|
|
361
448
|
|
|
362
449
|
// Step 7: Write merged event log FIRST (so crash recovery can re-derive DB state)
|
|
450
|
+
// Guard: detect concurrent appendEvent calls between our read (step 1) and
|
|
451
|
+
// this rewrite. If the log grew, re-read and retry to avoid dropping events.
|
|
452
|
+
const preWriteEvents = readEvents(mainLogPath);
|
|
453
|
+
if (preWriteEvents.length > mainEvents.length) {
|
|
454
|
+
logWarning("reconcile", `Event log grew during reconcile (${mainEvents.length} → ${preWriteEvents.length}), retrying with fresh read`);
|
|
455
|
+
return _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath);
|
|
456
|
+
}
|
|
457
|
+
|
|
363
458
|
const baseEvents = mainEvents.slice(0, forkPoint + 1);
|
|
364
459
|
const mergedLog = baseEvents.concat(merged);
|
|
365
460
|
const logContent = mergedLog.map((e) => JSON.stringify(e)).join("\n") + (mergedLog.length > 0 ? "\n" : "");
|
|
@@ -377,6 +472,12 @@ function _reconcileWorktreeLogsInner(
|
|
|
377
472
|
logWarning("reconcile", "manifest write failed (non-fatal)", { error: (err as Error).message });
|
|
378
473
|
}
|
|
379
474
|
|
|
475
|
+
// Step 10: Invalidate caches so deriveState() sees post-reconcile DB state.
|
|
476
|
+
// Use targeted invalidation (not invalidateAllCaches) to avoid wiping artifacts table.
|
|
477
|
+
invalidateStateCache();
|
|
478
|
+
clearPathCache();
|
|
479
|
+
clearParseCache();
|
|
480
|
+
|
|
380
481
|
return { autoMerged: merged.length, conflicts: [] };
|
|
381
482
|
}
|
|
382
483
|
|
|
@@ -58,8 +58,17 @@ let cachedRegistry: TemplateRegistry | null = null;
|
|
|
58
58
|
export function loadRegistry(): TemplateRegistry {
|
|
59
59
|
if (cachedRegistry) return cachedRegistry;
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
if (!existsSync(registryPath)) {
|
|
62
|
+
cachedRegistry = { version: 1, templates: {} };
|
|
63
|
+
return cachedRegistry;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const content = readFileSync(registryPath, "utf-8");
|
|
68
|
+
cachedRegistry = JSON.parse(content) as TemplateRegistry;
|
|
69
|
+
} catch {
|
|
70
|
+
cachedRegistry = { version: 1, templates: {} };
|
|
71
|
+
}
|
|
63
72
|
return cachedRegistry;
|
|
64
73
|
}
|
|
65
74
|
|
|
@@ -89,7 +89,9 @@ function normalizePathForComparison(path: string): string {
|
|
|
89
89
|
*/
|
|
90
90
|
export function resolveGitDir(basePath: string): string {
|
|
91
91
|
const gitPath = join(basePath, ".git");
|
|
92
|
-
if (!existsSync(gitPath)) return
|
|
92
|
+
if (!existsSync(gitPath)) return gitPath;
|
|
93
|
+
// In a normal repo .git is a directory — skip the file read (#3597)
|
|
94
|
+
if (lstatSync(gitPath).isDirectory()) return gitPath;
|
|
93
95
|
try {
|
|
94
96
|
const content = readFileSync(gitPath, "utf-8").trim();
|
|
95
97
|
if (content.startsWith("gitdir: ")) {
|
|
@@ -98,7 +100,7 @@ export function resolveGitDir(basePath: string): string {
|
|
|
98
100
|
} catch (e) {
|
|
99
101
|
logWarning("worktree", `.git file read failed: ${(e as Error).message}`);
|
|
100
102
|
}
|
|
101
|
-
return
|
|
103
|
+
return gitPath;
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
export function worktreesDir(basePath: string): string {
|
|
@@ -42,6 +42,16 @@ function getService(basePath: string): GitServiceImpl {
|
|
|
42
42
|
return cachedService;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Clear the cached GitServiceImpl. For testing only — forces the next
|
|
47
|
+
* getService() call to re-read preferences and create a fresh instance.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export function _resetServiceCache(): void {
|
|
51
|
+
cachedService = null;
|
|
52
|
+
cachedBasePath = null;
|
|
53
|
+
}
|
|
54
|
+
|
|
45
55
|
/**
|
|
46
56
|
* Set the active milestone ID on the cached GitServiceImpl.
|
|
47
57
|
* This enables integration branch resolution in getMainBranch().
|
|
@@ -300,7 +300,7 @@ export async function showInterviewRound(
|
|
|
300
300
|
// instead of being trapped in a re-asking loop (bug #2715).
|
|
301
301
|
// Only auto-open if the user hasn't already provided notes —
|
|
302
302
|
// otherwise Enter from notes mode loops back here endlessly.
|
|
303
|
-
if (!isMultiSelect(currentIdx) && states[currentIdx].cursorIndex === noneOrDoneIdx(currentIdx) && !states[currentIdx].notes) {
|
|
303
|
+
if (!isMultiSelect(currentIdx) && states[currentIdx].cursorIndex === noneOrDoneIdx(currentIdx) && !states[currentIdx].notes && !states[currentIdx].notesVisible) {
|
|
304
304
|
states[currentIdx].notesVisible = true;
|
|
305
305
|
focusNotes = true;
|
|
306
306
|
loadStateToEditor();
|
|
@@ -109,25 +109,23 @@ describe("interview-ui notes loop regression (#3502)", () => {
|
|
|
109
109
|
assert.equal(answer.selected, "None of the above");
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
-
it("
|
|
112
|
+
it("Enter on empty notes advances instead of re-opening (notesVisible guard)", async () => {
|
|
113
113
|
// Press Down twice to "None of the above", Enter to select
|
|
114
|
-
// Then immediately Enter again (empty notes) —
|
|
115
|
-
//
|
|
116
|
-
//
|
|
114
|
+
// Then immediately Enter again (empty notes) — notesVisible is already
|
|
115
|
+
// true from auto-open, so the guard prevents re-opening and Enter
|
|
116
|
+
// advances to review. The notes remain empty.
|
|
117
117
|
const result = await runWithInputs(questions, [
|
|
118
118
|
DOWN, // cursor → 1
|
|
119
119
|
DOWN, // cursor → 2 (None of the above)
|
|
120
|
-
ENTER, // commit → auto-opens notes
|
|
121
|
-
ENTER, // empty notes →
|
|
122
|
-
|
|
123
|
-
ENTER, // now notes = "ok" → should advance to review
|
|
124
|
-
ENTER, // submit
|
|
120
|
+
ENTER, // commit → auto-opens notes (notesVisible = true)
|
|
121
|
+
ENTER, // empty notes → notesVisible prevents re-open → advances to review
|
|
122
|
+
ENTER, // submit from review screen
|
|
125
123
|
]);
|
|
126
124
|
|
|
127
125
|
assert.ok(result, "should return a result");
|
|
128
126
|
const answer = result.answers.q1;
|
|
129
127
|
assert.ok(answer, "answer for q1 should exist");
|
|
130
|
-
assert.equal(answer.notes, "
|
|
128
|
+
assert.equal(answer.notes, "");
|
|
131
129
|
});
|
|
132
130
|
|
|
133
131
|
it("normal option selection is unaffected", async () => {
|
|
@@ -25,6 +25,33 @@ export interface AgentDiscoveryResult {
|
|
|
25
25
|
projectAgentsDir: string | null;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
interface AgentFrontmatter extends Record<string, unknown> {
|
|
29
|
+
name?: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
tools?: string | string[];
|
|
32
|
+
model?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function parseAgentTools(value: string | string[] | undefined): string[] | undefined {
|
|
36
|
+
if (typeof value === "string") {
|
|
37
|
+
const tools = value
|
|
38
|
+
.split(",")
|
|
39
|
+
.map((tool) => tool.trim())
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
return tools.length > 0 ? tools : undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (Array.isArray(value)) {
|
|
45
|
+
const tools = value
|
|
46
|
+
.flatMap((tool) => typeof tool === "string" ? tool.split(",") : [])
|
|
47
|
+
.map((tool) => tool.trim())
|
|
48
|
+
.filter(Boolean);
|
|
49
|
+
return tools.length > 0 ? tools : undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
28
55
|
function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig[] {
|
|
29
56
|
const agents: AgentConfig[] = [];
|
|
30
57
|
|
|
@@ -51,16 +78,13 @@ function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig
|
|
|
51
78
|
continue;
|
|
52
79
|
}
|
|
53
80
|
|
|
54
|
-
const { frontmatter, body } = parseFrontmatter<
|
|
81
|
+
const { frontmatter, body } = parseFrontmatter<AgentFrontmatter>(content);
|
|
55
82
|
|
|
56
|
-
if (
|
|
83
|
+
if (typeof frontmatter.name !== "string" || typeof frontmatter.description !== "string") {
|
|
57
84
|
continue;
|
|
58
85
|
}
|
|
59
86
|
|
|
60
|
-
const tools = frontmatter.tools
|
|
61
|
-
?.split(",")
|
|
62
|
-
.map((t: string) => t.trim())
|
|
63
|
-
.filter(Boolean);
|
|
87
|
+
const tools = parseAgentTools(frontmatter.tools);
|
|
64
88
|
|
|
65
89
|
agents.push({
|
|
66
90
|
name: frontmatter.name,
|