gsd-pi 2.57.0-dev.f22a903 → 2.58.0-dev.778d6ac
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/cli.js +49 -35
- package/dist/headless-ui.d.ts +17 -0
- package/dist/headless-ui.js +97 -3
- package/dist/headless.js +67 -6
- package/dist/help-text.js +1 -0
- package/dist/onboarding.js +44 -0
- package/dist/resource-loader.js +16 -1
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/ask-user-questions.js +16 -3
- package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
- package/dist/resources/extensions/context7/extension-manifest.json +1 -1
- package/dist/resources/extensions/get-secrets-from-user.js +8 -5
- package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
- package/dist/resources/extensions/google-search/index.js +2 -1
- package/dist/resources/extensions/gsd/auto/phases.js +25 -21
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -2
- package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
- package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
- package/dist/resources/extensions/gsd/auto-start.js +35 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +196 -12
- package/dist/resources/extensions/gsd/auto.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
- package/dist/resources/extensions/gsd/captures.js +56 -4
- package/dist/resources/extensions/gsd/db-writer.js +116 -8
- package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
- package/dist/resources/extensions/gsd/doctor.js +3 -1
- package/dist/resources/extensions/gsd/error-classifier.js +13 -10
- package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
- package/dist/resources/extensions/gsd/forensics.js +123 -20
- package/dist/resources/extensions/gsd/git-service.js +23 -1
- package/dist/resources/extensions/gsd/gitignore.js +33 -0
- package/dist/resources/extensions/gsd/gsd-db.js +36 -9
- package/dist/resources/extensions/gsd/guided-flow.js +106 -44
- package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
- package/dist/resources/extensions/gsd/health-widget.js +17 -0
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
- package/dist/resources/extensions/gsd/migrate-external.js +8 -1
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
- package/dist/resources/extensions/gsd/model-router.js +35 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
- package/dist/resources/extensions/gsd/notifications.js +16 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
- package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
- package/dist/resources/extensions/gsd/paths.js +43 -0
- package/dist/resources/extensions/gsd/preferences-models.js +14 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -1
- package/dist/resources/extensions/gsd/preferences.js +13 -16
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/dist/resources/extensions/gsd/repo-identity.js +205 -11
- package/dist/resources/extensions/gsd/rethink.js +5 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
- package/dist/resources/extensions/gsd/state.js +85 -27
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
- package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
- package/dist/resources/extensions/gsd/undo.js +2 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
- package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
- package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
- package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
- package/dist/resources/extensions/gsd/workspace-index.js +24 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
- package/dist/resources/extensions/mcp-client/index.js +11 -7
- package/dist/resources/extensions/ollama/index.js +112 -0
- package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
- package/dist/resources/extensions/ollama/ollama-client.js +168 -0
- package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
- package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
- package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
- package/dist/resources/extensions/ollama/types.js +2 -0
- package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/dist/resources/extensions/shared/interview-ui.js +11 -1
- package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/startup-model-validation.d.ts +39 -0
- package/dist/startup-model-validation.js +50 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
- 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/page_client-reference-manifest.js +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/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
- package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
- 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.7593d7797a4b3999.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
- package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
- package/dist/web-mode.js +2 -1
- package/package.json +2 -2
- package/packages/daemon/src/cli.ts +49 -0
- package/packages/daemon/src/daemon.test.ts +104 -1
- package/packages/daemon/src/daemon.ts +24 -1
- package/packages/daemon/src/discord-bot.ts +73 -3
- package/packages/daemon/src/event-bridge.ts +15 -9
- package/packages/daemon/src/event-formatter.ts +30 -2
- package/packages/daemon/src/index.ts +9 -0
- package/packages/daemon/src/launchd.test.ts +356 -0
- package/packages/daemon/src/launchd.ts +242 -0
- package/packages/daemon/src/message-batcher.test.ts +2 -2
- package/packages/daemon/src/message-batcher.ts +9 -3
- package/packages/daemon/src/orchestrator.test.ts +1 -0
- package/packages/daemon/src/orchestrator.ts +106 -2
- package/packages/native/dist/ast/index.js +9 -5
- package/packages/native/dist/ast/types.js +2 -1
- package/packages/native/dist/clipboard/index.js +12 -7
- package/packages/native/dist/clipboard/types.js +2 -1
- package/packages/native/dist/diff/index.js +12 -7
- package/packages/native/dist/diff/types.js +2 -1
- package/packages/native/dist/fd/index.js +6 -3
- package/packages/native/dist/fd/types.js +2 -1
- package/packages/native/dist/glob/index.js +9 -5
- package/packages/native/dist/glob/types.js +2 -1
- package/packages/native/dist/grep/index.js +9 -5
- package/packages/native/dist/grep/types.js +2 -1
- package/packages/native/dist/gsd-parser/index.js +18 -11
- package/packages/native/dist/gsd-parser/types.js +2 -1
- package/packages/native/dist/highlight/index.js +12 -7
- package/packages/native/dist/highlight/types.js +2 -1
- package/packages/native/dist/html/index.js +6 -3
- package/packages/native/dist/html/types.js +2 -1
- package/packages/native/dist/image/index.js +10 -5
- package/packages/native/dist/image/types.js +7 -4
- package/packages/native/dist/index.js +70 -17
- package/packages/native/dist/json-parse/index.js +13 -8
- package/packages/native/dist/native.js +47 -10
- package/packages/native/dist/ps/index.js +15 -9
- package/packages/native/dist/ps/types.js +2 -1
- package/packages/native/dist/stream-process/index.js +12 -7
- package/packages/native/dist/text/index.js +24 -14
- package/packages/native/dist/text/types.js +5 -2
- package/packages/native/dist/truncate/index.js +12 -7
- package/packages/native/dist/ttsr/index.js +12 -7
- package/packages/native/dist/ttsr/types.js +2 -1
- package/packages/native/dist/xxhash/index.js +9 -5
- package/packages/native/package.json +19 -19
- package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
- package/packages/native/src/native.ts +9 -8
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
- package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/proxy.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
- package/packages/pi-agent-core/src/agent-loop.ts +3 -2
- package/packages/pi-agent-core/src/proxy.ts +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
- package/packages/pi-ai/dist/types.d.ts +3 -3
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +24 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/index.ts +1 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
- package/packages/pi-ai/src/types.ts +3 -2
- package/packages/pi-ai/src/utils/json-parse.ts +28 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/exec.js +3 -1
- package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/index.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 +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
- package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +31 -2
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
- package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +2 -2
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
- package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
- package/packages/pi-coding-agent/src/core/exec.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
- package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
- package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
- package/packages/pi-coding-agent/src/core/index.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
- package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
- package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
- package/packages/pi-coding-agent/src/core/messages.ts +29 -2
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
- package/packages/pi-coding-agent/src/index.ts +6 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
- package/packages/pi-tui/dist/terminal.d.ts +2 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +9 -0
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/terminal.ts +14 -0
- package/packages/pi-tui/src/tui.ts +8 -0
- package/pkg/package.json +1 -1
- package/scripts/ensure-workspace-builds.cjs +45 -14
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/ask-user-questions.ts +21 -3
- package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
- package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
- package/src/resources/extensions/context7/extension-manifest.json +1 -1
- package/src/resources/extensions/get-secrets-from-user.ts +8 -5
- package/src/resources/extensions/google-search/extension-manifest.json +1 -1
- package/src/resources/extensions/google-search/index.ts +2 -1
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/phases.ts +43 -34
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
- package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-start.ts +35 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +190 -9
- package/src/resources/extensions/gsd/auto.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
- package/src/resources/extensions/gsd/captures.ts +63 -3
- package/src/resources/extensions/gsd/db-writer.ts +140 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
- package/src/resources/extensions/gsd/doctor.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +14 -11
- package/src/resources/extensions/gsd/extension-manifest.json +16 -1
- package/src/resources/extensions/gsd/forensics.ts +144 -20
- package/src/resources/extensions/gsd/git-service.ts +26 -3
- package/src/resources/extensions/gsd/gitignore.ts +33 -0
- package/src/resources/extensions/gsd/gsd-db.ts +43 -7
- package/src/resources/extensions/gsd/guided-flow.ts +114 -45
- package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
- package/src/resources/extensions/gsd/health-widget.ts +17 -0
- package/src/resources/extensions/gsd/index.ts +1 -0
- package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
- package/src/resources/extensions/gsd/migrate-external.ts +9 -1
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
- package/src/resources/extensions/gsd/model-router.ts +35 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
- package/src/resources/extensions/gsd/notifications.ts +16 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
- package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
- package/src/resources/extensions/gsd/paths.ts +42 -0
- package/src/resources/extensions/gsd/preferences-models.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +13 -15
- package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
- package/src/resources/extensions/gsd/repo-identity.ts +186 -11
- package/src/resources/extensions/gsd/rethink.ts +6 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
- package/src/resources/extensions/gsd/state.ts +84 -32
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
- package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
- package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
- package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
- package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
- package/src/resources/extensions/gsd/types.ts +4 -2
- package/src/resources/extensions/gsd/undo.ts +2 -2
- package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
- package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
- package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
- package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
- package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
- package/src/resources/extensions/gsd/workspace-index.ts +30 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
- package/src/resources/extensions/mcp-client/index.ts +13 -7
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
- package/src/resources/extensions/ollama/index.ts +130 -0
- package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
- package/src/resources/extensions/ollama/ollama-client.ts +196 -0
- package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
- package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
- package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
- package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
- package/src/resources/extensions/ollama/types.ts +130 -0
- package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
- package/src/resources/extensions/shared/interview-ui.ts +12 -1
- package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
- package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
- package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
- package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
- /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* db-path-worktree-symlink.test.ts — #2517
|
|
3
|
+
*
|
|
4
|
+
* Regression test for the db_unavailable loop in worktree/symlink layouts.
|
|
5
|
+
*
|
|
6
|
+
* The path resolver must handle BOTH worktree path families:
|
|
7
|
+
* - /.gsd/worktrees/<MID>/... (direct layout)
|
|
8
|
+
* - /.gsd/projects/<hash>/worktrees/<MID>/... (symlink-resolved layout)
|
|
9
|
+
*
|
|
10
|
+
* When the second layout is not recognised, ensureDbOpen derives a wrong DB
|
|
11
|
+
* path, the open fails silently, and every completion tool call returns
|
|
12
|
+
* db_unavailable — triggering an artifact retry re-dispatch loop.
|
|
13
|
+
*
|
|
14
|
+
* Additionally, the post-unit artifact retry path must NOT retry when the
|
|
15
|
+
* completion tool failed due to db_unavailable (infra failure), because
|
|
16
|
+
* retrying can never succeed and causes cost spikes.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { readFileSync } from "node:fs";
|
|
20
|
+
import { join, sep } from "node:path";
|
|
21
|
+
import { createTestContext } from "./test-helpers.ts";
|
|
22
|
+
|
|
23
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
24
|
+
|
|
25
|
+
// ── Part 1: resolveProjectRootDbPath handles symlink-resolved layout ─────
|
|
26
|
+
|
|
27
|
+
console.log("\n=== #2517 Part 1: resolveProjectRootDbPath symlink layout ===");
|
|
28
|
+
|
|
29
|
+
// Import the resolver directly
|
|
30
|
+
const { resolveProjectRootDbPath } = await import("../bootstrap/dynamic-tools.js");
|
|
31
|
+
|
|
32
|
+
// Standard worktree layout (already works)
|
|
33
|
+
const standardPath = `/home/user/myproject/.gsd/worktrees/M001/work`;
|
|
34
|
+
const standardResult = resolveProjectRootDbPath(standardPath);
|
|
35
|
+
assertEq(
|
|
36
|
+
standardResult,
|
|
37
|
+
join("/home/user/myproject", ".gsd", "gsd.db"),
|
|
38
|
+
"Standard worktree layout resolves to project root DB path",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// Symlink-resolved layout (the regression — /.gsd/projects/<hash>/worktrees/...)
|
|
42
|
+
const symlinkPath = `/home/user/myproject/.gsd/projects/abc123def/worktrees/M001/work`;
|
|
43
|
+
const symlinkResult = resolveProjectRootDbPath(symlinkPath);
|
|
44
|
+
assertEq(
|
|
45
|
+
symlinkResult,
|
|
46
|
+
join("/home/user/myproject", ".gsd", "gsd.db"),
|
|
47
|
+
"Symlink-resolved layout (/.gsd/projects/<hash>/worktrees/) resolves to project root DB path (#2517)",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Windows-style separators for symlink layout
|
|
51
|
+
if (sep === "\\") {
|
|
52
|
+
const winSymlinkPath = `C:\\Users\\dev\\project\\.gsd\\projects\\abc123def\\worktrees\\M001\\work`;
|
|
53
|
+
const winResult = resolveProjectRootDbPath(winSymlinkPath);
|
|
54
|
+
assertEq(
|
|
55
|
+
winResult,
|
|
56
|
+
join("C:\\Users\\dev\\project", ".gsd", "gsd.db"),
|
|
57
|
+
"Windows symlink layout resolves correctly",
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
// On non-Windows, test forward-slash variant explicitly
|
|
61
|
+
const fwdSymlinkPath = `/home/user/myproject/.gsd/projects/abc123def/worktrees/M001/work`;
|
|
62
|
+
const fwdResult = resolveProjectRootDbPath(fwdSymlinkPath);
|
|
63
|
+
assertEq(
|
|
64
|
+
fwdResult,
|
|
65
|
+
join("/home/user/myproject", ".gsd", "gsd.db"),
|
|
66
|
+
"Forward-slash symlink layout resolves correctly on POSIX",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Edge: deeper nesting under projects/<hash>/worktrees
|
|
71
|
+
const deepSymlinkPath = `/home/user/myproject/.gsd/projects/deadbeef42/worktrees/M003/sub/dir`;
|
|
72
|
+
const deepResult = resolveProjectRootDbPath(deepSymlinkPath);
|
|
73
|
+
assertEq(
|
|
74
|
+
deepResult,
|
|
75
|
+
join("/home/user/myproject", ".gsd", "gsd.db"),
|
|
76
|
+
"Deep symlink worktree path still resolves to project root DB",
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Non-worktree path should be unchanged
|
|
80
|
+
const normalPath = `/home/user/myproject`;
|
|
81
|
+
const normalResult = resolveProjectRootDbPath(normalPath);
|
|
82
|
+
assertEq(
|
|
83
|
+
normalResult,
|
|
84
|
+
join("/home/user/myproject", ".gsd", "gsd.db"),
|
|
85
|
+
"Non-worktree path is unchanged",
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
// ── Part 2: ensureDbOpen returns structured failure context ──────────────
|
|
89
|
+
|
|
90
|
+
console.log("\n=== #2517 Part 2: ensureDbOpen structured diagnostics ===");
|
|
91
|
+
|
|
92
|
+
const dynamicToolsSrc = readFileSync(
|
|
93
|
+
join(import.meta.dirname, "..", "bootstrap", "dynamic-tools.ts"),
|
|
94
|
+
"utf-8",
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// ensureDbOpen should return a structured result, not just boolean false
|
|
98
|
+
// Check that the catch block provides diagnostic information
|
|
99
|
+
assertTrue(
|
|
100
|
+
dynamicToolsSrc.includes("resolvedPath") || dynamicToolsSrc.includes("diagnostic"),
|
|
101
|
+
"ensureDbOpen catch block surfaces diagnostic information (resolvedPath or diagnostic) instead of bare false (#2517)",
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// ── Part 3: post-unit does NOT artifact-retry on db_unavailable ──────────
|
|
105
|
+
|
|
106
|
+
console.log("\n=== #2517 Part 3: post-unit db_unavailable is infra-fatal ===");
|
|
107
|
+
|
|
108
|
+
const postUnitSrc = readFileSync(
|
|
109
|
+
join(import.meta.dirname, "..", "auto-post-unit.ts"),
|
|
110
|
+
"utf-8",
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// The artifact retry block should check DB availability and skip retry
|
|
114
|
+
// when the DB is unavailable (infra failure, not a missing artifact).
|
|
115
|
+
assertTrue(
|
|
116
|
+
postUnitSrc.includes("db_unavailable") || postUnitSrc.includes("isDbAvailable"),
|
|
117
|
+
"post-unit artifact retry path checks DB availability to avoid retry loop (#2517)",
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Verify the retry block is guarded: when !isDbAvailable(), the code must
|
|
121
|
+
// NOT return "retry". The pattern should be: if (!verified && !isDbAvailable()) { skip }
|
|
122
|
+
// followed by else if (!verified) { ... return "retry" }
|
|
123
|
+
const dbUnavailableGuard = postUnitSrc.match(
|
|
124
|
+
/!triggerArtifactVerified\s*&&\s*!isDbAvailable\(\)/,
|
|
125
|
+
);
|
|
126
|
+
assertTrue(
|
|
127
|
+
!!dbUnavailableGuard,
|
|
128
|
+
"The retry block explicitly guards against !isDbAvailable() before returning 'retry' (#2517)",
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
report();
|
|
@@ -416,23 +416,18 @@ describe('db-writer', () => {
|
|
|
416
416
|
}
|
|
417
417
|
});
|
|
418
418
|
|
|
419
|
-
test('updateRequirementInDb — not found', async () => {
|
|
419
|
+
test('updateRequirementInDb — upserts when not found (#2919)', async () => {
|
|
420
420
|
const tmpDir = makeTmpDir();
|
|
421
421
|
const dbPath = path.join(tmpDir, '.gsd', 'gsd.db');
|
|
422
422
|
openDatabase(dbPath);
|
|
423
423
|
|
|
424
424
|
try {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
(err as Error).message.includes('R999'),
|
|
432
|
-
'error message mentions the missing ID',
|
|
433
|
-
);
|
|
434
|
-
}
|
|
435
|
-
assert.ok(threw, 'throws when requirement not found');
|
|
425
|
+
// Previously threw; now upserts a skeleton requirement with the provided updates
|
|
426
|
+
await updateRequirementInDb('R999', { status: 'validated' }, tmpDir);
|
|
427
|
+
const created = getRequirementById('R999');
|
|
428
|
+
assert.ok(created !== null, 'R999 should be created by upsert');
|
|
429
|
+
assert.deepStrictEqual(created!.status, 'validated', 'Upserted requirement should have validated status');
|
|
430
|
+
assert.deepStrictEqual(created!.id, 'R999', 'Upserted requirement should keep the provided ID');
|
|
436
431
|
} finally {
|
|
437
432
|
closeDatabase();
|
|
438
433
|
cleanupDir(tmpDir);
|
|
@@ -4,7 +4,7 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
6
6
|
|
|
7
|
-
import { deriveState, invalidateStateCache, _deriveStateImpl, deriveStateFromDb } from '../state.ts';
|
|
7
|
+
import { deriveState, invalidateStateCache, _deriveStateImpl, deriveStateFromDb, isGhostMilestone } from '../state.ts';
|
|
8
8
|
import {
|
|
9
9
|
openDatabase,
|
|
10
10
|
closeDatabase,
|
|
@@ -934,8 +934,8 @@ describe('derive-state-db', async () => {
|
|
|
934
934
|
}
|
|
935
935
|
});
|
|
936
936
|
|
|
937
|
-
// ─── Test 21: Ghost milestone skipped
|
|
938
|
-
test('derive-state-db: ghost milestone skipped', async () => {
|
|
937
|
+
// ─── Test 21: Ghost milestone skipped (no DB row, no worktree) ─────────
|
|
938
|
+
test('derive-state-db: ghost milestone skipped when no DB row and no worktree', async () => {
|
|
939
939
|
const base = createFixtureBase();
|
|
940
940
|
try {
|
|
941
941
|
// Ghost: milestone dir exists with only META.json, no context/roadmap/summary
|
|
@@ -948,8 +948,7 @@ describe('derive-state-db', async () => {
|
|
|
948
948
|
const fileState = await _deriveStateImpl(base);
|
|
949
949
|
|
|
950
950
|
openDatabase(':memory:');
|
|
951
|
-
//
|
|
952
|
-
insertMilestone({ id: 'M001', title: '', status: 'active' });
|
|
951
|
+
// Only insert M002 — M001 has no DB row (simulates row loss / never inserted)
|
|
953
952
|
insertMilestone({ id: 'M002', title: 'Real', status: 'active' });
|
|
954
953
|
|
|
955
954
|
invalidateStateCache();
|
|
@@ -1051,4 +1050,78 @@ describe('derive-state-db', async () => {
|
|
|
1051
1050
|
closeDatabase();
|
|
1052
1051
|
}
|
|
1053
1052
|
});
|
|
1053
|
+
|
|
1054
|
+
// ─── Queued milestone with worktree not flagged as ghost (#2921) ──────
|
|
1055
|
+
test('derive-state-db: queued milestone with worktree not flagged as ghost (#2921)', async () => {
|
|
1056
|
+
const base = createFixtureBase();
|
|
1057
|
+
try {
|
|
1058
|
+
// M001: complete milestone with summary
|
|
1059
|
+
writeFile(base, 'milestones/M001/M001-SUMMARY.md', '# M001 Summary\n\nDone.');
|
|
1060
|
+
|
|
1061
|
+
// M002: queued milestone — directory + slices dir exists, but no content files.
|
|
1062
|
+
// This is what happens when ensureMilestoneDbRow creates M002 but the DB row
|
|
1063
|
+
// is lost during worktree teardown.
|
|
1064
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M002', 'slices'), { recursive: true });
|
|
1065
|
+
|
|
1066
|
+
// A worktree exists for M002, proving it's a legitimate milestone
|
|
1067
|
+
mkdirSync(join(base, '.gsd', 'worktrees', 'M002'), { recursive: true });
|
|
1068
|
+
|
|
1069
|
+
// isGhostMilestone should NOT treat M002 as ghost when worktree exists
|
|
1070
|
+
assert.ok(!isGhostMilestone(base, 'M002'), 'ghost-wt: M002 with worktree is NOT a ghost');
|
|
1071
|
+
|
|
1072
|
+
// DB has M001 complete but M002 row was lost
|
|
1073
|
+
openDatabase(':memory:');
|
|
1074
|
+
insertMilestone({ id: 'M001', title: 'First', status: 'complete' });
|
|
1075
|
+
// No M002 row — simulates DB row loss during worktree teardown
|
|
1076
|
+
|
|
1077
|
+
invalidateStateCache();
|
|
1078
|
+
const dbState = await deriveStateFromDb(base);
|
|
1079
|
+
|
|
1080
|
+
// M002 should be reconciled from disk (not skipped as ghost) and become active
|
|
1081
|
+
const m002Entry = dbState.registry.find(e => e.id === 'M002');
|
|
1082
|
+
assert.ok(m002Entry !== undefined, 'ghost-wt: M002 should be in registry');
|
|
1083
|
+
assert.deepStrictEqual(dbState.activeMilestone?.id, 'M002', 'ghost-wt: M002 should be active');
|
|
1084
|
+
// Should NOT be phase: complete
|
|
1085
|
+
assert.notEqual(dbState.phase, 'complete', 'ghost-wt: phase should not be complete');
|
|
1086
|
+
|
|
1087
|
+
closeDatabase();
|
|
1088
|
+
} finally {
|
|
1089
|
+
closeDatabase();
|
|
1090
|
+
cleanup(base);
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1094
|
+
// ─── Queued milestone with DB row not flagged as ghost (#2921) ────────
|
|
1095
|
+
test('derive-state-db: queued milestone with DB row not flagged as ghost (#2921)', async () => {
|
|
1096
|
+
const base = createFixtureBase();
|
|
1097
|
+
try {
|
|
1098
|
+
// M001: complete milestone with summary
|
|
1099
|
+
writeFile(base, 'milestones/M001/M001-SUMMARY.md', '# M001 Summary\n\nDone.');
|
|
1100
|
+
|
|
1101
|
+
// M002: queued milestone — directory exists, no content files, but has DB row
|
|
1102
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M002', 'slices'), { recursive: true });
|
|
1103
|
+
|
|
1104
|
+
// DB has both M001 complete and M002 queued
|
|
1105
|
+
openDatabase(':memory:');
|
|
1106
|
+
insertMilestone({ id: 'M001', title: 'First', status: 'complete' });
|
|
1107
|
+
insertMilestone({ id: 'M002', title: 'Second', status: 'queued' });
|
|
1108
|
+
|
|
1109
|
+
// isGhostMilestone should NOT treat M002 as ghost when DB row exists
|
|
1110
|
+
assert.ok(!isGhostMilestone(base, 'M002'), 'ghost-dbrow: M002 with DB row is NOT a ghost');
|
|
1111
|
+
|
|
1112
|
+
invalidateStateCache();
|
|
1113
|
+
const dbState = await deriveStateFromDb(base);
|
|
1114
|
+
|
|
1115
|
+
// M002 should not be skipped
|
|
1116
|
+
const m002Entry = dbState.registry.find(e => e.id === 'M002');
|
|
1117
|
+
assert.ok(m002Entry !== undefined, 'ghost-dbrow: M002 should be in registry');
|
|
1118
|
+
assert.deepStrictEqual(dbState.activeMilestone?.id, 'M002', 'ghost-dbrow: M002 should be active');
|
|
1119
|
+
assert.notEqual(dbState.phase, 'complete', 'ghost-dbrow: phase should not be complete');
|
|
1120
|
+
|
|
1121
|
+
closeDatabase();
|
|
1122
|
+
} finally {
|
|
1123
|
+
closeDatabase();
|
|
1124
|
+
cleanup(base);
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1054
1127
|
});
|
|
@@ -930,6 +930,35 @@ slice: S01
|
|
|
930
930
|
}
|
|
931
931
|
});
|
|
932
932
|
|
|
933
|
+
// ─── Test: queued milestone with worktree not flagged as ghost (#2921) ──
|
|
934
|
+
test('queued milestone with worktree not flagged as ghost (#2921)', async () => {
|
|
935
|
+
const base = createFixtureBase();
|
|
936
|
+
try {
|
|
937
|
+
// Create a milestone directory with only an empty slices subdir — no content files.
|
|
938
|
+
// This would normally be a ghost, but it has a worktree directory.
|
|
939
|
+
const milestoneDir = join(base, '.gsd', 'milestones', 'M002');
|
|
940
|
+
mkdirSync(join(milestoneDir, 'slices'), { recursive: true });
|
|
941
|
+
|
|
942
|
+
// Create a worktree directory for M002, simulating an active worktree
|
|
943
|
+
const worktreeDir = join(base, '.gsd', 'worktrees', 'M002');
|
|
944
|
+
mkdirSync(worktreeDir, { recursive: true });
|
|
945
|
+
|
|
946
|
+
// isGhostMilestone should return false because the worktree exists
|
|
947
|
+
assert.ok(!isGhostMilestone(base, 'M002'), 'M002 with worktree should NOT be a ghost');
|
|
948
|
+
|
|
949
|
+
// Also create a completed M001 so deriveState has something before M002
|
|
950
|
+
writeMilestoneSummary(base, 'M001', '# M001 Summary\n\nDone.');
|
|
951
|
+
|
|
952
|
+
const state = await deriveState(base);
|
|
953
|
+
// M002 should appear in the registry (not filtered as ghost)
|
|
954
|
+
const m002Entry = state.registry.find(e => e.id === 'M002');
|
|
955
|
+
assert.ok(m002Entry !== undefined, 'M002 should be in registry when worktree exists');
|
|
956
|
+
assert.deepStrictEqual(state.activeMilestone?.id, 'M002', 'M002 should be active milestone');
|
|
957
|
+
} finally {
|
|
958
|
+
cleanup(base);
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
|
|
933
962
|
// ─── Test: zero-slice roadmap → pre-planning, not blocked (#1785) ────
|
|
934
963
|
test('zero-slice roadmap → pre-planning, not blocked (#1785)', async () => {
|
|
935
964
|
const base = createFixtureBase();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Validates that all Discord invite links in user-facing files point to valid,
|
|
8
|
+
* consistent invite URLs — not expired vanity links.
|
|
9
|
+
*
|
|
10
|
+
* Regression test for https://github.com/gsd-build/gsd-2/issues/2699
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const ROOT = process.cwd();
|
|
14
|
+
|
|
15
|
+
/** Canonical Discord invite for the GSD community. */
|
|
16
|
+
const VALID_INVITE = "https://discord.com/invite/nKXTsAcmbT";
|
|
17
|
+
|
|
18
|
+
/** Files that contain user-facing Discord invite links. */
|
|
19
|
+
const FILES_WITH_INVITE_LINKS: string[] = [
|
|
20
|
+
"README.md",
|
|
21
|
+
"docs/what-is-pi/15-pi-packages-the-ecosystem.md",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
describe("Discord invite links (#2699)", () => {
|
|
25
|
+
for (const relPath of FILES_WITH_INVITE_LINKS) {
|
|
26
|
+
it(`${relPath} contains only the canonical Discord invite`, () => {
|
|
27
|
+
const content = readFileSync(join(ROOT, relPath), "utf8");
|
|
28
|
+
|
|
29
|
+
// Extract all Discord invite URLs (discord.gg/X or discord.com/invite/X)
|
|
30
|
+
const invitePattern = /https?:\/\/(?:discord\.gg|discord\.com\/invite)\/[A-Za-z0-9]+/g;
|
|
31
|
+
const matches = content.match(invitePattern);
|
|
32
|
+
|
|
33
|
+
assert.ok(
|
|
34
|
+
matches && matches.length > 0,
|
|
35
|
+
`Expected at least one Discord invite link in ${relPath}`,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
for (const link of matches) {
|
|
39
|
+
assert.equal(
|
|
40
|
+
link,
|
|
41
|
+
VALID_INVITE,
|
|
42
|
+
`Invalid Discord invite in ${relPath}: found "${link}", expected "${VALID_INVITE}"`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* discuss-empty-db-fallback.test.ts — Tests for #2892.
|
|
3
|
+
*
|
|
4
|
+
* When the DB is open but empty (e.g., after crash/truncation),
|
|
5
|
+
* getMilestoneSlices() returns [] and showDiscuss() incorrectly declares
|
|
6
|
+
* "All slices are complete." The fix adds a roadmap fallback: when the DB
|
|
7
|
+
* returns zero slices but a ROADMAP file exists, parse slices from the
|
|
8
|
+
* roadmap instead of treating zero slices as "all complete."
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, test } from "node:test";
|
|
12
|
+
import assert from "node:assert/strict";
|
|
13
|
+
import { readFileSync } from "node:fs";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { dirname, join } from "node:path";
|
|
16
|
+
import { parseRoadmapSlices } from "../roadmap-slices.ts";
|
|
17
|
+
|
|
18
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
function readGuidedFlowSource(): string {
|
|
21
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
22
|
+
const thisDir = dirname(thisFile);
|
|
23
|
+
return readFileSync(join(thisDir, "..", "guided-flow.ts"), "utf-8");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const SAMPLE_ROADMAP = `# M012 Roadmap
|
|
27
|
+
|
|
28
|
+
## Slices
|
|
29
|
+
- [ ] **S01: Core setup** \`risk:low\` \`depends:[]\`
|
|
30
|
+
> After this: basic project scaffolding works
|
|
31
|
+
- [ ] **S02: Auth module** \`risk:medium\` \`depends:[S01]\`
|
|
32
|
+
> After this: users can log in
|
|
33
|
+
- [ ] **S03: Dashboard** \`risk:low\` \`depends:[S02]\`
|
|
34
|
+
> After this: dashboard renders
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
// ─── Tests ───────────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
describe("discuss-empty-db-fallback (#2892)", () => {
|
|
40
|
+
|
|
41
|
+
test("1. parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
|
|
42
|
+
const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
|
|
43
|
+
assert.strictEqual(slices.length, 3, "should parse 3 slices from sample roadmap");
|
|
44
|
+
assert.strictEqual(slices[0]!.id, "S01");
|
|
45
|
+
assert.strictEqual(slices[1]!.id, "S02");
|
|
46
|
+
assert.strictEqual(slices[2]!.id, "S03");
|
|
47
|
+
// All slices are incomplete ([ ] not [x])
|
|
48
|
+
assert.ok(slices.every(s => !s.done), "all slices should be incomplete");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("2. guided-flow imports parseRoadmapSlices for roadmap fallback", () => {
|
|
52
|
+
const source = readGuidedFlowSource();
|
|
53
|
+
assert.ok(
|
|
54
|
+
source.includes("parseRoadmapSlices"),
|
|
55
|
+
"guided-flow must import parseRoadmapSlices to support roadmap fallback when DB is empty",
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("3. guided-flow has roadmap fallback when normSlices is empty but roadmapContent exists", () => {
|
|
60
|
+
const source = readGuidedFlowSource();
|
|
61
|
+
// The fix must add a fallback that checks normSlices.length === 0 && roadmapContent
|
|
62
|
+
// and repopulates normSlices from the roadmap before the pendingSlices guard.
|
|
63
|
+
//
|
|
64
|
+
// Pattern: after DB query produces normSlices, if empty + roadmap exists,
|
|
65
|
+
// fall back to parseRoadmapSlices(roadmapContent).
|
|
66
|
+
const fallbackPattern = /normSlices\.length\s*===\s*0\s*&&\s*roadmapContent/;
|
|
67
|
+
assert.ok(
|
|
68
|
+
fallbackPattern.test(source),
|
|
69
|
+
"guided-flow must check normSlices.length === 0 && roadmapContent to trigger roadmap fallback",
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("4. guided-flow no longer has unguarded pendingSlices === 0 exit after DB-only query", () => {
|
|
74
|
+
const source = readGuidedFlowSource();
|
|
75
|
+
// Extract the showDiscuss function body
|
|
76
|
+
const fnMatch = source.match(
|
|
77
|
+
/async function showDiscuss\s*\([^)]*\)[^{]*\{([\s\S]*?)\nfunction\s/,
|
|
78
|
+
);
|
|
79
|
+
assert.ok(!!fnMatch, "showDiscuss function body must be found");
|
|
80
|
+
|
|
81
|
+
if (fnMatch) {
|
|
82
|
+
const body = fnMatch[1]!;
|
|
83
|
+
// After the DB query block (isDbAvailable/getMilestoneSlices), there should
|
|
84
|
+
// be a roadmap fallback BEFORE the pendingSlices.length === 0 check.
|
|
85
|
+
// Find the getMilestoneSlices call and the pendingSlices === 0 check
|
|
86
|
+
const dbQueryIdx = body.indexOf("getMilestoneSlices");
|
|
87
|
+
const fallbackIdx = body.indexOf("parseRoadmapSlices");
|
|
88
|
+
const pendingGuardIdx = body.indexOf('pendingSlices.length === 0');
|
|
89
|
+
|
|
90
|
+
assert.ok(dbQueryIdx > 0, "getMilestoneSlices call must exist");
|
|
91
|
+
assert.ok(fallbackIdx > 0, "parseRoadmapSlices fallback must exist");
|
|
92
|
+
assert.ok(pendingGuardIdx > 0, "pendingSlices.length === 0 guard must exist");
|
|
93
|
+
assert.ok(
|
|
94
|
+
fallbackIdx > dbQueryIdx && fallbackIdx < pendingGuardIdx,
|
|
95
|
+
"parseRoadmapSlices fallback must appear BETWEEN DB query and pendingSlices === 0 guard",
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("5. roadmap-parsed slices map to NormSlice format with done=false by default", () => {
|
|
101
|
+
// When falling back to roadmap, incomplete slices ([ ]) should map to done:false,
|
|
102
|
+
// ensuring they appear as pending and are NOT falsely reported as complete.
|
|
103
|
+
const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
|
|
104
|
+
const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
|
|
105
|
+
const pendingSlices = normSlices.filter(s => !s.done);
|
|
106
|
+
assert.strictEqual(pendingSlices.length, 3,
|
|
107
|
+
"all 3 incomplete roadmap slices should be pending — not falsely treated as complete");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("6. roadmap with completed slices correctly reports them as done", () => {
|
|
111
|
+
const completedRoadmap = `# M012 Roadmap
|
|
112
|
+
|
|
113
|
+
## Slices
|
|
114
|
+
- [x] **S01: Core setup** \`risk:low\` \`depends:[]\`
|
|
115
|
+
> After this: basic project scaffolding works
|
|
116
|
+
- [ ] **S02: Auth module** \`risk:medium\` \`depends:[S01]\`
|
|
117
|
+
> After this: users can log in
|
|
118
|
+
- [x] **S03: Dashboard** \`risk:low\` \`depends:[S02]\`
|
|
119
|
+
> After this: dashboard renders
|
|
120
|
+
`;
|
|
121
|
+
const slices = parseRoadmapSlices(completedRoadmap);
|
|
122
|
+
const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
|
|
123
|
+
const pendingSlices = normSlices.filter(s => !s.done);
|
|
124
|
+
assert.strictEqual(pendingSlices.length, 1, "only S02 should be pending");
|
|
125
|
+
assert.strictEqual(pendingSlices[0]!.id, "S02");
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -238,4 +238,44 @@ describe("discuss-queued-milestones (#2307)", () => {
|
|
|
238
238
|
"queued milestone picker must label entries with [queued] to distinguish from active",
|
|
239
239
|
);
|
|
240
240
|
});
|
|
241
|
+
|
|
242
|
+
// ─── #3150: allDiscussed early-return must not block queued milestone discussion ──
|
|
243
|
+
|
|
244
|
+
test("12. allDiscussed path checks for pending milestones before returning (#3150)", () => {
|
|
245
|
+
const source = readGuidedFlowSource();
|
|
246
|
+
|
|
247
|
+
// Extract the allDiscussed block — the if (allDiscussed) { ... } body
|
|
248
|
+
const allDiscussedMatch = source.match(
|
|
249
|
+
/const allDiscussed = pendingSlices\.every\([\s\S]*?\n if \(allDiscussed\) \{([\s\S]*?)\n \}/,
|
|
250
|
+
);
|
|
251
|
+
assert.ok(!!allDiscussedMatch, "allDiscussed guard block must exist in showDiscuss()");
|
|
252
|
+
|
|
253
|
+
if (allDiscussedMatch) {
|
|
254
|
+
const body = allDiscussedMatch[1];
|
|
255
|
+
// The fix must check for pending milestones and route to showDiscussQueuedMilestone
|
|
256
|
+
assert.ok(
|
|
257
|
+
body.includes("pending") && body.includes("showDiscussQueuedMilestone"),
|
|
258
|
+
"allDiscussed block must check for pending milestones and call showDiscussQueuedMilestone before returning (#3150)",
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test("13. pendingSlices.length===0 path checks for pending milestones before returning (#3150)", () => {
|
|
264
|
+
const source = readGuidedFlowSource();
|
|
265
|
+
|
|
266
|
+
// Find the pendingSlices.length === 0 guard block
|
|
267
|
+
const zeroSlicesMatch = source.match(
|
|
268
|
+
/if \(pendingSlices\.length === 0\) \{([\s\S]*?)\n \}/,
|
|
269
|
+
);
|
|
270
|
+
assert.ok(!!zeroSlicesMatch, "pendingSlices.length === 0 guard block must exist in showDiscuss()");
|
|
271
|
+
|
|
272
|
+
if (zeroSlicesMatch) {
|
|
273
|
+
const body = zeroSlicesMatch[1];
|
|
274
|
+
// The fix must check for pending milestones and route to showDiscussQueuedMilestone
|
|
275
|
+
assert.ok(
|
|
276
|
+
body.includes("pending") && body.includes("showDiscussQueuedMilestone"),
|
|
277
|
+
"pendingSlices.length===0 block must check for pending milestones and call showDiscussQueuedMilestone before returning (#3150)",
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
});
|
|
241
281
|
});
|
|
@@ -87,7 +87,26 @@ export function load(url, context, nextLoad) {
|
|
|
87
87
|
emitDecoratorMetadata: true,
|
|
88
88
|
},
|
|
89
89
|
});
|
|
90
|
-
|
|
90
|
+
// Inject CJS-compatible globals (__dirname, __filename, require) so that
|
|
91
|
+
// workspace packages compiled as ESM can still use them. This avoids the
|
|
92
|
+
// need for import.meta.url behind indirect invocation patterns that fail in
|
|
93
|
+
// CJS and in dynamically-created scopes.
|
|
94
|
+
// Only inject globals that the source file doesn't already declare itself.
|
|
95
|
+
const preambleLines = [
|
|
96
|
+
'import { fileURLToPath as __preamble_fUTP } from "node:url";',
|
|
97
|
+
'import { dirname as __preamble_dn } from "node:path";',
|
|
98
|
+
'import { createRequire as __preamble_cR } from "node:module";',
|
|
99
|
+
];
|
|
100
|
+
if (!outputText.includes('const __filename') && !outputText.includes('let __filename')) {
|
|
101
|
+
preambleLines.push('const __filename = __preamble_fUTP(import.meta.url);');
|
|
102
|
+
}
|
|
103
|
+
if (!outputText.includes('const __dirname') && !outputText.includes('let __dirname')) {
|
|
104
|
+
preambleLines.push('const __dirname = __preamble_dn(__preamble_fUTP(import.meta.url));');
|
|
105
|
+
}
|
|
106
|
+
if (!outputText.includes('const require') && !outputText.includes('let require')) {
|
|
107
|
+
preambleLines.push('const require = __preamble_cR(import.meta.url);');
|
|
108
|
+
}
|
|
109
|
+
return { format: 'module', source: preambleLines.join('\n') + '\n' + outputText, shortCircuit: true };
|
|
91
110
|
}
|
|
92
111
|
return nextLoad(url, context);
|
|
93
112
|
}
|