@opengsd/gsd-pi 1.8.0 → 1.8.1-dev.897b3c90
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 +8 -3
- package/dist/cli.js +5 -1
- package/dist/headless-events.d.ts +2 -1
- package/dist/headless-events.js +11 -3
- package/dist/headless-milestone-readiness.d.ts +29 -0
- package/dist/headless-milestone-readiness.js +161 -0
- package/dist/headless.js +25 -2
- package/dist/print-mode-exit.d.ts +12 -0
- package/dist/print-mode-exit.js +14 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +16 -47
- package/dist/resources/extensions/browser-tools/capture.js +2 -77
- package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +35 -1
- package/dist/resources/extensions/gsd/auto.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +78 -4
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +84 -26
- package/dist/resources/extensions/gsd/command-feedback.js +16 -12
- package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
- package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +51 -16
- package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
- package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
- package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
- package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +4 -4
- package/dist/resources/extensions/gsd/doctor-history.js +65 -0
- package/dist/resources/extensions/gsd/doctor-state-checks.js +509 -0
- package/dist/resources/extensions/gsd/doctor-workspace-checks.js +91 -0
- package/dist/resources/extensions/gsd/doctor.js +14 -653
- package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
- package/dist/resources/extensions/gsd/gsd-db.js +187 -45
- package/dist/resources/extensions/gsd/guided-flow.js +29 -10
- package/dist/resources/extensions/gsd/markdown-renderer.js +16 -2
- package/dist/resources/extensions/gsd/md-importer.js +109 -16
- package/dist/resources/extensions/gsd/migrate/command.js +19 -162
- package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
- package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
- package/dist/resources/extensions/gsd/migrate/planning-writer.js +20 -19
- package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
- package/dist/resources/extensions/gsd/migration-auto-check.js +4 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
- package/dist/resources/extensions/gsd/paths.js +4 -1
- package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
- package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +54 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +48 -5
- package/dist/resources/extensions/gsd/stop-notice.js +15 -1
- package/dist/resources/extensions/gsd/sync-lock.js +13 -7
- package/dist/resources/extensions/gsd/tools/complete-task.js +82 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
- package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
- package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
- package/dist/resources/extensions/gsd/unit-registry.js +4 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
- package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
- package/dist/resources/extensions/mac-tools/index.js +31 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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.js +1 -1
- 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.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.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.js +2 -2
- 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.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.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.js +2 -2
- 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.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.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.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.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.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/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.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.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.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.js +2 -2
- 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.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.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.js +2 -2
- 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.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.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.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.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.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.js +2 -2
- 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.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.js +4 -4
- 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.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 +5 -5
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +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 +5 -5
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/package.json +0 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +31 -3
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +12 -10
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -1
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +5 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/cloud-config.test.js +51 -1
- package/packages/daemon/dist/cloud-config.test.js.map +1 -1
- package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
- package/packages/daemon/dist/local-tool-executor.js +2 -0
- package/packages/daemon/dist/local-tool-executor.js.map +1 -1
- package/packages/daemon/package.json +6 -6
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/dist/cli.d.ts +5 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cli.js +160 -0
- package/packages/gsd-cloud/dist/cli.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.js +231 -0
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.js +37 -0
- package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
- package/packages/gsd-cloud/dist/config.d.ts +17 -0
- package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/config.js +146 -0
- package/packages/gsd-cloud/dist/config.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.js +128 -0
- package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
- package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.js +11 -0
- package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.js +29 -0
- package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
- package/packages/gsd-cloud/dist/index.d.ts +7 -0
- package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/index.js +8 -0
- package/packages/gsd-cloud/dist/index.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
- package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
- package/packages/gsd-cloud/dist/logger.d.ts +25 -0
- package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/logger.js +72 -0
- package/packages/gsd-cloud/dist/logger.js.map +1 -0
- package/packages/gsd-cloud/dist/types.d.ts +51 -0
- package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/types.js +9 -0
- package/packages/gsd-cloud/dist/types.js.map +1 -0
- package/packages/gsd-cloud/package.json +3 -3
- package/packages/mcp-server/README.md +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +64 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +60 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +54 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +19 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +16 -47
- package/src/resources/extensions/browser-tools/capture.ts +2 -86
- package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +38 -1
- package/src/resources/extensions/gsd/auto.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +91 -4
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -24
- package/src/resources/extensions/gsd/command-feedback.ts +19 -12
- package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
- package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +53 -17
- package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
- package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
- package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
- package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +4 -4
- package/src/resources/extensions/gsd/doctor-history.ts +81 -0
- package/src/resources/extensions/gsd/doctor-state-checks.ts +527 -0
- package/src/resources/extensions/gsd/doctor-workspace-checks.ts +97 -0
- package/src/resources/extensions/gsd/doctor.ts +14 -673
- package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
- package/src/resources/extensions/gsd/gsd-db.ts +255 -52
- package/src/resources/extensions/gsd/guided-flow.ts +39 -10
- package/src/resources/extensions/gsd/markdown-renderer.ts +23 -7
- package/src/resources/extensions/gsd/md-importer.ts +116 -13
- package/src/resources/extensions/gsd/migrate/command.ts +21 -227
- package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
- package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
- package/src/resources/extensions/gsd/migrate/planning-writer.ts +21 -23
- package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
- package/src/resources/extensions/gsd/migration-auto-check.ts +3 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
- package/src/resources/extensions/gsd/paths.ts +4 -1
- package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
- package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +67 -20
- package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +47 -5
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
- package/src/resources/extensions/gsd/stop-notice.ts +18 -1
- package/src/resources/extensions/gsd/sync-lock.ts +14 -6
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +286 -0
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +76 -1
- package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/doctor-history-public-api.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
- package/src/resources/extensions/gsd/tests/planning-writer.test.ts +47 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +18 -3
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
- package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +177 -25
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +120 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
- package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
- package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
- package/src/resources/extensions/gsd/types.ts +11 -0
- package/src/resources/extensions/gsd/unit-registry.ts +4 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
- package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
- package/src/resources/extensions/mac-tools/index.ts +52 -9
- package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
- /package/dist/web/standalone/.next/static/{seHIUVbR1mm7LfG83nWJO → TezjdjSHBVRRr54XjAvte}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{seHIUVbR1mm7LfG83nWJO → TezjdjSHBVRRr54XjAvte}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { createTestContext } from './test-helpers.ts';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import * as os from 'node:os';
|
|
5
|
+
import {
|
|
6
|
+
openDatabase,
|
|
7
|
+
closeDatabase,
|
|
8
|
+
_getAdapter,
|
|
9
|
+
type ReworkBriefFindingInput,
|
|
10
|
+
} from '../gsd-db.ts';
|
|
11
|
+
import { handleReworkBriefSave } from '../tools/rework-brief.ts';
|
|
12
|
+
|
|
13
|
+
const { assertEq, assertTrue, assertMatch, report } = createTestContext();
|
|
14
|
+
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
// Helpers
|
|
17
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
18
|
+
|
|
19
|
+
function tempDbPath(): string {
|
|
20
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-rework-brief-'));
|
|
21
|
+
return path.join(dir, 'test.db');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function cleanup(dbPath: string): void {
|
|
25
|
+
closeDatabase();
|
|
26
|
+
try {
|
|
27
|
+
const dir = path.dirname(dbPath);
|
|
28
|
+
for (const f of fs.readdirSync(dir)) fs.unlinkSync(path.join(dir, f));
|
|
29
|
+
fs.rmdirSync(dir);
|
|
30
|
+
} catch {
|
|
31
|
+
// best effort
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function finding(overrides: Partial<ReworkBriefFindingInput> = {}): ReworkBriefFindingInput {
|
|
36
|
+
return {
|
|
37
|
+
findingId: 'F1',
|
|
38
|
+
severity: 'blocking',
|
|
39
|
+
description: 'Compile regression',
|
|
40
|
+
requiredFix: 'Fix compile error',
|
|
41
|
+
verificationCommands: ['pnpm run typecheck:extensions'],
|
|
42
|
+
...overrides,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const baseParams = {
|
|
47
|
+
briefId: 'RB-001',
|
|
48
|
+
milestoneId: 'M001',
|
|
49
|
+
sliceId: 'S01',
|
|
50
|
+
taskId: 'T01',
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function findingRow(): { status: string; evidence: string; decision_ref: string } | undefined {
|
|
54
|
+
return _getAdapter()!
|
|
55
|
+
.prepare("SELECT status, evidence, decision_ref FROM rework_brief_findings WHERE brief_id = 'RB-001' AND finding_id = 'F1'")
|
|
56
|
+
.get() as { status: string; evidence: string; decision_ref: string } | undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
60
|
+
// rework-brief: a blocking finding saved as non-pending must carry the same
|
|
61
|
+
// justification a reworkResolution would, otherwise it bypasses the
|
|
62
|
+
// gsd_task_complete blocking gate (which only sees `pending` rows).
|
|
63
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
64
|
+
|
|
65
|
+
console.log('\n=== rework-brief: rejects blocking resolved finding without evidence ===');
|
|
66
|
+
{
|
|
67
|
+
const dbPath = tempDbPath();
|
|
68
|
+
openDatabase(dbPath);
|
|
69
|
+
|
|
70
|
+
const result = await handleReworkBriefSave({
|
|
71
|
+
...baseParams,
|
|
72
|
+
findings: [finding({ status: 'resolved' })],
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
assertTrue('error' in result, 'blocking resolved finding without evidence should be rejected');
|
|
76
|
+
if ('error' in result) {
|
|
77
|
+
assertMatch(result.error, /evidence is required/i, 'error should mention the evidence requirement');
|
|
78
|
+
}
|
|
79
|
+
const rows = _getAdapter()!.prepare('SELECT COUNT(*) AS n FROM rework_brief_findings').get() as { n: number };
|
|
80
|
+
assertEq(rows.n, 0, 'no finding rows should be persisted when validation fails');
|
|
81
|
+
|
|
82
|
+
cleanup(dbPath);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('\n=== rework-brief: rejects blocking deferred-with-override without decisionRef ===');
|
|
86
|
+
{
|
|
87
|
+
const dbPath = tempDbPath();
|
|
88
|
+
openDatabase(dbPath);
|
|
89
|
+
|
|
90
|
+
const result = await handleReworkBriefSave({
|
|
91
|
+
...baseParams,
|
|
92
|
+
findings: [finding({ status: 'deferred-with-override', evidence: 'Maintainer accepted temporary deferral.' })],
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
assertTrue('error' in result, 'deferred-with-override without decisionRef should be rejected');
|
|
96
|
+
if ('error' in result) {
|
|
97
|
+
assertMatch(result.error, /decisionRef is required/i, 'error should mention the decisionRef requirement');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
cleanup(dbPath);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log('\n=== rework-brief: rejects invalid finding status ===');
|
|
104
|
+
{
|
|
105
|
+
const dbPath = tempDbPath();
|
|
106
|
+
openDatabase(dbPath);
|
|
107
|
+
|
|
108
|
+
const result = await handleReworkBriefSave({
|
|
109
|
+
...baseParams,
|
|
110
|
+
findings: [finding({ status: 'bogus' as unknown as ReworkBriefFindingInput['status'] })],
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
assertTrue('error' in result, 'an unknown status value should be rejected');
|
|
114
|
+
if ('error' in result) {
|
|
115
|
+
assertMatch(result.error, /status must be/i, 'error should name the allowed statuses');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
cleanup(dbPath);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
122
|
+
// rework-brief: legitimate saves still succeed.
|
|
123
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
124
|
+
|
|
125
|
+
console.log('\n=== rework-brief: blocking finding defaults to pending ===');
|
|
126
|
+
{
|
|
127
|
+
const dbPath = tempDbPath();
|
|
128
|
+
openDatabase(dbPath);
|
|
129
|
+
|
|
130
|
+
const result = await handleReworkBriefSave({
|
|
131
|
+
...baseParams,
|
|
132
|
+
findings: [finding()],
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
assertTrue(!('error' in result), 'a blocking finding without a status should be accepted');
|
|
136
|
+
assertEq(findingRow()?.status, 'pending', 'finding without status should default to pending');
|
|
137
|
+
|
|
138
|
+
cleanup(dbPath);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.log('\n=== rework-brief: accepts blocking resolved finding with evidence ===');
|
|
142
|
+
{
|
|
143
|
+
const dbPath = tempDbPath();
|
|
144
|
+
openDatabase(dbPath);
|
|
145
|
+
|
|
146
|
+
const result = await handleReworkBriefSave({
|
|
147
|
+
...baseParams,
|
|
148
|
+
findings: [finding({ status: 'resolved', evidence: 'Fixed compile error and reran pnpm run typecheck:extensions.' })],
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
assertTrue(!('error' in result), 'a resolved blocking finding with evidence should be accepted');
|
|
152
|
+
assertEq(findingRow()?.status, 'resolved', 'finding should persist as resolved when evidence is supplied');
|
|
153
|
+
assertMatch(findingRow()?.evidence ?? '', /Fixed compile error/, 'resolution evidence should be persisted');
|
|
154
|
+
|
|
155
|
+
cleanup(dbPath);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
console.log('\n=== rework-brief: accepts blocking deferred-with-override with evidence and decisionRef ===');
|
|
159
|
+
{
|
|
160
|
+
const dbPath = tempDbPath();
|
|
161
|
+
openDatabase(dbPath);
|
|
162
|
+
|
|
163
|
+
const result = await handleReworkBriefSave({
|
|
164
|
+
...baseParams,
|
|
165
|
+
findings: [finding({
|
|
166
|
+
status: 'deferred-with-override',
|
|
167
|
+
evidence: 'Maintainer accepted temporary deferral.',
|
|
168
|
+
decisionRef: 'DEC-2026-07-07-rework-deferral',
|
|
169
|
+
})],
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
assertTrue(!('error' in result), 'a deferred-with-override finding with evidence and decisionRef should be accepted');
|
|
173
|
+
assertEq(findingRow()?.status, 'deferred-with-override', 'finding should persist the override status');
|
|
174
|
+
assertEq(findingRow()?.decision_ref, 'DEC-2026-07-07-rework-deferral', 'decision reference should be persisted');
|
|
175
|
+
|
|
176
|
+
cleanup(dbPath);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
console.log('\n=== rework-brief: advisory resolved finding does not require evidence ===');
|
|
180
|
+
{
|
|
181
|
+
const dbPath = tempDbPath();
|
|
182
|
+
openDatabase(dbPath);
|
|
183
|
+
|
|
184
|
+
// Advisory findings never gate gsd_task_complete, so pre-resolving one
|
|
185
|
+
// without evidence is harmless and stays permitted.
|
|
186
|
+
const result = await handleReworkBriefSave({
|
|
187
|
+
...baseParams,
|
|
188
|
+
findings: [finding({ severity: 'advisory', status: 'resolved' })],
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
assertTrue(!('error' in result), 'an advisory resolved finding should be accepted without evidence');
|
|
192
|
+
assertEq(findingRow()?.status, 'resolved', 'advisory finding status should be preserved');
|
|
193
|
+
|
|
194
|
+
cleanup(dbPath);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
report();
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
updateTaskStatus,
|
|
26
26
|
} from "../gsd-db.ts";
|
|
27
27
|
import { handleSkipSlice } from "../tools/skip-slice.ts";
|
|
28
|
+
import { skipSliceCascade } from "../db/writers/cascades.ts";
|
|
28
29
|
|
|
29
30
|
describe("handleSkipSlice cascades skip to tasks (#4375)", () => {
|
|
30
31
|
let dir: string;
|
|
@@ -122,4 +123,24 @@ describe("handleSkipSlice cascades skip to tasks (#4375)", () => {
|
|
|
122
123
|
assert.match(result.error!, /not found/i);
|
|
123
124
|
assert.equal(result.errorCode, "slice_not_found");
|
|
124
125
|
});
|
|
126
|
+
|
|
127
|
+
test("skipSliceCascade rejects a slice in the legacy 'closed' status without nulling completed_at", () => {
|
|
128
|
+
const completedAt = "2026-01-01T00:00:00.000Z";
|
|
129
|
+
updateSliceStatus("M001", "S03", "closed", completedAt);
|
|
130
|
+
|
|
131
|
+
const outcome = skipSliceCascade("M001", "S03");
|
|
132
|
+
assert.deepEqual(outcome, { ok: false, reason: "slice-already-complete" });
|
|
133
|
+
|
|
134
|
+
const slice = getSlice("M001", "S03");
|
|
135
|
+
assert.equal(slice?.status, "closed", "closed slice must not be downgraded to skipped");
|
|
136
|
+
assert.equal(slice?.completed_at, completedAt, "completed_at must be preserved");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("skipSliceCascade still re-skips an already-skipped slice (ok, wasAlreadySkipped)", () => {
|
|
140
|
+
updateSliceStatus("M001", "S03", "skipped");
|
|
141
|
+
|
|
142
|
+
const outcome = skipSliceCascade("M001", "S03");
|
|
143
|
+
assert.equal(outcome.ok, true);
|
|
144
|
+
if (outcome.ok) assert.equal(outcome.wasAlreadySkipped, true);
|
|
145
|
+
});
|
|
125
146
|
});
|
|
@@ -107,11 +107,11 @@ test("ADR-017 (#5700): sketch-flag drift detected and repaired end-to-end", asyn
|
|
|
107
107
|
sketchScope: "limited",
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
-
// Simulate the post-crash scenario: PLAN.md
|
|
111
|
-
// is_sketch flag is still 1.
|
|
110
|
+
// Simulate the post-crash scenario: a *real* PLAN.md (a decomposed task)
|
|
111
|
+
// exists on disk but the is_sketch flag is still 1.
|
|
112
112
|
writeFileSync(
|
|
113
113
|
join(base, ".gsd", "phases", "01-test", "01-02-PLAN.md"),
|
|
114
|
-
"
|
|
114
|
+
makeStalePlanContent("S02", [{ id: "T01", title: "Build the feature", done: false }]),
|
|
115
115
|
);
|
|
116
116
|
assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "pre: flagged as sketch");
|
|
117
117
|
|
|
@@ -131,6 +131,120 @@ test("ADR-017 (#5700): sketch-flag drift detected and repaired end-to-end", asyn
|
|
|
131
131
|
}
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
+
test("#1287: stub/placeholder PLAN does NOT clear the sketch flag", async (t) => {
|
|
135
|
+
const base = makeFixtureBase();
|
|
136
|
+
t.after(() => cleanup(base));
|
|
137
|
+
|
|
138
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
139
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
140
|
+
insertSlice({
|
|
141
|
+
id: "S02",
|
|
142
|
+
milestoneId: "M001",
|
|
143
|
+
title: "Feature",
|
|
144
|
+
status: "pending",
|
|
145
|
+
risk: "medium",
|
|
146
|
+
depends: [],
|
|
147
|
+
demo: "S02 demo.",
|
|
148
|
+
sequence: 1,
|
|
149
|
+
isSketch: true,
|
|
150
|
+
sketchScope: "limited",
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const planPath = join(base, ".gsd", "phases", "01-test", "01-02-PLAN.md");
|
|
154
|
+
|
|
155
|
+
// A bare stub PLAN (no decomposed tasks) must not clear the flag.
|
|
156
|
+
writeFileSync(planPath, "# S02 Plan\n");
|
|
157
|
+
clearRendererCaches();
|
|
158
|
+
let state = makeState({ activeMilestone: { id: "M001", title: "Test" } });
|
|
159
|
+
let result = await reconcileBeforeDispatch(base, {
|
|
160
|
+
invalidateStateCache: () => {},
|
|
161
|
+
deriveState: async () => state,
|
|
162
|
+
});
|
|
163
|
+
assert.equal(result.ok, true);
|
|
164
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "stub PLAN: flag stays set");
|
|
165
|
+
assert.equal(result.repaired.length, 0, "stub PLAN: no repair");
|
|
166
|
+
|
|
167
|
+
// A projection round-trip stub whose only task is a synthetic "Plan NN"
|
|
168
|
+
// placeholder (migrate/transformer.buildTaskTitle) must also not clear it.
|
|
169
|
+
writeFileSync(
|
|
170
|
+
planPath,
|
|
171
|
+
makeStalePlanContent("S02", [{ id: "T01", title: "Plan 01", done: false }]),
|
|
172
|
+
);
|
|
173
|
+
clearRendererCaches();
|
|
174
|
+
state = makeState({ activeMilestone: { id: "M001", title: "Test" } });
|
|
175
|
+
result = await reconcileBeforeDispatch(base, {
|
|
176
|
+
invalidateStateCache: () => {},
|
|
177
|
+
deriveState: async () => state,
|
|
178
|
+
});
|
|
179
|
+
assert.equal(result.ok, true);
|
|
180
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "placeholder task: flag stays set");
|
|
181
|
+
assert.equal(result.repaired.length, 0, "placeholder task: no repair");
|
|
182
|
+
|
|
183
|
+
// buildTaskTitle also emits `${phase} ${plan}` (e.g. "00 01") when the plan
|
|
184
|
+
// frontmatter carries phase/plan. This projected placeholder must not clear
|
|
185
|
+
// the flag either.
|
|
186
|
+
writeFileSync(
|
|
187
|
+
planPath,
|
|
188
|
+
makeStalePlanContent("S02", [{ id: "T01", title: "00 01", done: false }]),
|
|
189
|
+
);
|
|
190
|
+
clearRendererCaches();
|
|
191
|
+
state = makeState({ activeMilestone: { id: "M001", title: "Test" } });
|
|
192
|
+
result = await reconcileBeforeDispatch(base, {
|
|
193
|
+
invalidateStateCache: () => {},
|
|
194
|
+
deriveState: async () => state,
|
|
195
|
+
});
|
|
196
|
+
assert.equal(result.ok, true);
|
|
197
|
+
assert.equal(
|
|
198
|
+
getSlice("M001", "S02")?.is_sketch,
|
|
199
|
+
1,
|
|
200
|
+
"phase/plan placeholder task: flag stays set",
|
|
201
|
+
);
|
|
202
|
+
assert.equal(result.repaired.length, 0, "phase/plan placeholder task: no repair");
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("#1288: real tasks shaped like `word + number` still clear the sketch flag", async (t) => {
|
|
206
|
+
const base = makeFixtureBase();
|
|
207
|
+
t.after(() => cleanup(base));
|
|
208
|
+
|
|
209
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
210
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
211
|
+
insertSlice({
|
|
212
|
+
id: "S02",
|
|
213
|
+
milestoneId: "M001",
|
|
214
|
+
title: "Feature",
|
|
215
|
+
status: "pending",
|
|
216
|
+
risk: "medium",
|
|
217
|
+
depends: [],
|
|
218
|
+
demo: "S02 demo.",
|
|
219
|
+
sequence: 1,
|
|
220
|
+
isSketch: true,
|
|
221
|
+
sketchScope: "limited",
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const planPath = join(base, ".gsd", "phases", "01-test", "01-02-PLAN.md");
|
|
225
|
+
|
|
226
|
+
// `Step 1` / `RFC 1234` match the loose `word + number` shape but are genuine
|
|
227
|
+
// decomposed tasks. buildTaskTitle only emits `${phase} ${plan}` with a
|
|
228
|
+
// digit-led phase, so these must NOT be read as placeholders (#1288): a real
|
|
229
|
+
// plan-slice like this must still clear the stale is_sketch flag.
|
|
230
|
+
writeFileSync(
|
|
231
|
+
planPath,
|
|
232
|
+
makeStalePlanContent("S02", [
|
|
233
|
+
{ id: "T01", title: "Step 1", done: false },
|
|
234
|
+
{ id: "T02", title: "RFC 1234", done: false },
|
|
235
|
+
]),
|
|
236
|
+
);
|
|
237
|
+
clearRendererCaches();
|
|
238
|
+
const state = makeState({ activeMilestone: { id: "M001", title: "Test" } });
|
|
239
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
240
|
+
invalidateStateCache: () => {},
|
|
241
|
+
deriveState: async () => state,
|
|
242
|
+
});
|
|
243
|
+
assert.equal(result.ok, true);
|
|
244
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "real task titles: flag cleared");
|
|
245
|
+
assert.equal(result.repaired.length, 1, "real task titles: repaired once");
|
|
246
|
+
});
|
|
247
|
+
|
|
134
248
|
test("ADR-017 (#5700): repair failure throws ReconciliationFailedError with shape", async () => {
|
|
135
249
|
const seenDrift: DriftRecord = { kind: "stale-sketch-flag", mid: "M001", sid: "S02" };
|
|
136
250
|
const handler: DriftHandler = {
|
|
@@ -1032,7 +1146,7 @@ test("ADR-017 (#5703): live worker lock is not cleared", async (t) => {
|
|
|
1032
1146
|
|
|
1033
1147
|
// ─── #5704: unregistered-milestone drift ────────────────────────────────────
|
|
1034
1148
|
|
|
1035
|
-
test("ADR-017 (#5704): unregistered-milestone drift
|
|
1149
|
+
test("ADR-017 (#5704/#1281): unregistered-milestone drift pauses with a hint instead of hard-escalating", async (t) => {
|
|
1036
1150
|
const base = mkdtempSync(join(tmpdir(), "gsd-adr017-projmd-"));
|
|
1037
1151
|
const milestoneDir = join(base, ".gsd", "phases", "42-test");
|
|
1038
1152
|
mkdirSync(milestoneDir, { recursive: true });
|
|
@@ -1059,29 +1173,67 @@ test("ADR-017 (#5704): unregistered-milestone drift fails closed without importi
|
|
|
1059
1173
|
// Pre-condition: filesystem has the milestone, DB does NOT.
|
|
1060
1174
|
assert.equal(getMilestone("M042"), null, "pre: DB has no row for M042");
|
|
1061
1175
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
return true;
|
|
1080
|
-
},
|
|
1081
|
-
);
|
|
1176
|
+
// #1281: the handler exposes a `blocker`, so reconciliation returns a
|
|
1177
|
+
// non-fatal pause-with-hint (ok:true + blocker) rather than throwing.
|
|
1178
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1179
|
+
invalidateStateCache: () => {},
|
|
1180
|
+
deriveState: async () => makeState(),
|
|
1181
|
+
});
|
|
1182
|
+
assert.equal(result.ok, true);
|
|
1183
|
+
const blocker = result.blockers.find((b) => /M042/.test(b));
|
|
1184
|
+
assert.ok(blocker, "expected an M042 unregistered-milestone blocker");
|
|
1185
|
+
assert.match(blocker!, /markdown projection/);
|
|
1186
|
+
// Hint leads with targeted, non-destructive actions (rename/discard)...
|
|
1187
|
+
assert.match(blocker!, /Rename/);
|
|
1188
|
+
assert.match(blocker!, /Discard/);
|
|
1189
|
+
// ...and reframes recover as a destructive last resort, not the fix (#826).
|
|
1190
|
+
assert.match(blocker!, /\/gsd recover/);
|
|
1191
|
+
assert.match(blocker!, /last resort/i);
|
|
1192
|
+
// Runtime never imports markdown into the DB.
|
|
1082
1193
|
assert.equal(getMilestone("M042"), null, "post: DB still has no row for M042");
|
|
1083
1194
|
});
|
|
1084
1195
|
|
|
1196
|
+
test("#1281: descriptive flat-phase dir registered under a suffixed id → no false-positive drift", async (t) => {
|
|
1197
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-1281-suffix-"));
|
|
1198
|
+
// Descriptive slug the flat-phase extractor cannot recover the suffix from →
|
|
1199
|
+
// it derives the bare `M007`, which has no DB row.
|
|
1200
|
+
const milestoneDir = join(base, ".gsd", "phases", "07-v40fmq-m007-v40fmq-navigation-footer-system");
|
|
1201
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
1202
|
+
writeFileSync(
|
|
1203
|
+
join(milestoneDir, "M007-v40fmq-ROADMAP.md"),
|
|
1204
|
+
[
|
|
1205
|
+
"# M007: Navigation Footer System",
|
|
1206
|
+
"",
|
|
1207
|
+
"**Vision:** Verify no false-positive unregistered-milestone drift",
|
|
1208
|
+
"",
|
|
1209
|
+
"## Slices",
|
|
1210
|
+
"",
|
|
1211
|
+
"- [ ] **S01: Foundation** `risk:medium` `depends:[]`",
|
|
1212
|
+
"",
|
|
1213
|
+
].join("\n"),
|
|
1214
|
+
);
|
|
1215
|
+
t.after(() => {
|
|
1216
|
+
try { closeDatabase(); } catch { /* noop */ }
|
|
1217
|
+
rmSync(base, { recursive: true, force: true });
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1220
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1221
|
+
// The milestone IS registered — under the unique_milestone_ids suffixed id.
|
|
1222
|
+
insertMilestone({ id: "M007-v40fmq", title: "Navigation Footer System", status: "complete" });
|
|
1223
|
+
|
|
1224
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1225
|
+
invalidateStateCache: () => {},
|
|
1226
|
+
deriveState: async () => makeState(),
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
assert.equal(result.ok, true);
|
|
1230
|
+
assert.equal(
|
|
1231
|
+
result.blockers.some((b) => /unregistered/i.test(b) || /M007/.test(b)),
|
|
1232
|
+
false,
|
|
1233
|
+
"bare M007 derived from the slug must resolve to the registered M007-v40fmq row",
|
|
1234
|
+
);
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1085
1237
|
test("ADR-017 (#5704): registered milestone (DB row present) → no drift", async (t) => {
|
|
1086
1238
|
const base = mkdtempSync(join(tmpdir(), "gsd-adr017-projmd-clean-"));
|
|
1087
1239
|
const milestoneDir = join(base, ".gsd", "phases", "01-test");
|
|
@@ -1977,7 +2129,7 @@ test("deriveState is pure: stale sketch healed only via reconcileBeforeDispatch"
|
|
|
1977
2129
|
});
|
|
1978
2130
|
writeFileSync(
|
|
1979
2131
|
join(base, ".gsd", "phases", "01-test", "01-02-PLAN.md"),
|
|
1980
|
-
"
|
|
2132
|
+
makeStalePlanContent("S02", [{ id: "T01", title: "Build the feature", done: false }]),
|
|
1981
2133
|
);
|
|
1982
2134
|
|
|
1983
2135
|
const { deriveState } = await import("../state.ts");
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
isPauseNotice,
|
|
15
15
|
isBlockedNoticeMessage,
|
|
16
16
|
isManualResolutionNotice,
|
|
17
|
+
isInteractiveMenuUnavailableNotice,
|
|
17
18
|
PAUSED_NOTICE_PREFIXES,
|
|
18
19
|
TERMINAL_NOTICE_PREFIXES,
|
|
19
20
|
} from "../stop-notice.js";
|
|
@@ -62,6 +63,22 @@ describe("emitter↔detector round-trip", () => {
|
|
|
62
63
|
assert.ok(isBlockedNoticeMessage(message));
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
test("un-showable menu notices classify as blocked (#1294)", () => {
|
|
67
|
+
// Emitted verbatim by notifyCommandMenuUnavailable (next-action-ui.ts / command-feedback.ts).
|
|
68
|
+
const menuUnavailable =
|
|
69
|
+
"gsd — m002: editorial hn menu could not be shown in this session.\nrun /gsd when ready.";
|
|
70
|
+
assert.ok(isInteractiveMenuUnavailableNotice(menuUnavailable));
|
|
71
|
+
assert.ok(isBlockedNoticeMessage(menuUnavailable));
|
|
72
|
+
|
|
73
|
+
// Emitted by notifyPickerCommandNeedsInteractiveMenu (command-feedback.ts).
|
|
74
|
+
const pickerGuidance = "/gsd did not start: milestone menu needs an interactive session";
|
|
75
|
+
assert.ok(isInteractiveMenuUnavailableNotice(pickerGuidance));
|
|
76
|
+
assert.ok(isBlockedNoticeMessage(pickerGuidance));
|
|
77
|
+
|
|
78
|
+
// Unrelated notices are not swept up.
|
|
79
|
+
assert.equal(isInteractiveMenuUnavailableNotice("auto-mode complete"), false);
|
|
80
|
+
});
|
|
81
|
+
|
|
65
82
|
test("terminal prefixes cover the known stop vocabulary", () => {
|
|
66
83
|
for (const message of ["auto-mode stopped.", "auto-mode complete", "auto-mode idle", "no active milestone"]) {
|
|
67
84
|
assert.ok(TERMINAL_NOTICE_PREFIXES.some((prefix) => message.startsWith(prefix)), message);
|
|
@@ -174,3 +174,22 @@ test('sync-lock: contended fresh lock fails fast without honoring long sync time
|
|
|
174
174
|
cleanupDir(base);
|
|
175
175
|
}
|
|
176
176
|
});
|
|
177
|
+
|
|
178
|
+
test('sync-lock: uncreatable lock path fails open instead of spinning forever', () => {
|
|
179
|
+
const base = tempDir();
|
|
180
|
+
try {
|
|
181
|
+
// `.gsd` is a dangling symlink to a missing target: the O_EXCL open lands
|
|
182
|
+
// on a missing parent and throws non-EEXIST on every attempt. Without the
|
|
183
|
+
// fail-open guard the retry loop spins forever, blocking the event loop.
|
|
184
|
+
fs.symlinkSync(path.join(base, 'missing-external-state'), path.join(base, '.gsd'), 'junction');
|
|
185
|
+
|
|
186
|
+
const startedAt = performance.now();
|
|
187
|
+
const result = acquireSyncLock(base, 0, 'write-gate.lock');
|
|
188
|
+
const elapsedMs = performance.now() - startedAt;
|
|
189
|
+
|
|
190
|
+
assert.strictEqual(result.acquired, false, 'uncreatable lock path must fail open, not acquire');
|
|
191
|
+
assert.ok(elapsedMs < 250, `must return promptly, not spin; elapsed=${elapsedMs.toFixed(1)}ms`);
|
|
192
|
+
} finally {
|
|
193
|
+
cleanupDir(base);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
@@ -43,6 +43,8 @@ import {
|
|
|
43
43
|
insertMilestone,
|
|
44
44
|
upsertMilestonePlanning,
|
|
45
45
|
insertSlice,
|
|
46
|
+
insertTask,
|
|
47
|
+
saveReworkBrief,
|
|
46
48
|
} from "../gsd-db.ts";
|
|
47
49
|
|
|
48
50
|
// ─── Pure composer tests ──────────────────────────────────────────────────
|
|
@@ -518,6 +520,38 @@ test("#4782 phase 2: buildReassessRoadmapPrompt emits composer-shaped context wi
|
|
|
518
520
|
assert.ok(!prompt.includes("Slice Context (from discussion)"));
|
|
519
521
|
});
|
|
520
522
|
|
|
523
|
+
|
|
524
|
+
test("execute-task prompt injects unresolved blocking rework findings", async (t) => {
|
|
525
|
+
const base = makeFixtureBase();
|
|
526
|
+
t.after(() => cleanup(base));
|
|
527
|
+
invalidateAllCaches();
|
|
528
|
+
|
|
529
|
+
seed(base, "M001");
|
|
530
|
+
writeArtifacts(base);
|
|
531
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Task", status: "pending" });
|
|
532
|
+
saveReworkBrief({
|
|
533
|
+
briefId: "RB-001",
|
|
534
|
+
milestoneId: "M001",
|
|
535
|
+
sliceId: "S01",
|
|
536
|
+
taskId: "T01",
|
|
537
|
+
findings: [{
|
|
538
|
+
findingId: "F1",
|
|
539
|
+
severity: "blocking",
|
|
540
|
+
description: "Compile regression",
|
|
541
|
+
requiredFix: "Restore typecheck",
|
|
542
|
+
verificationCommands: ["pnpm run typecheck:extensions"],
|
|
543
|
+
}],
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
const prompt = await buildExecuteTaskPrompt("M001", "S01", "First", "T01", "Task", base);
|
|
547
|
+
|
|
548
|
+
assert.match(prompt, /Blocking Rework Findings \(non-optional\)/);
|
|
549
|
+
assert.match(prompt, /F1/);
|
|
550
|
+
assert.match(prompt, /Compile regression/);
|
|
551
|
+
assert.match(prompt, /pnpm run typecheck:extensions/);
|
|
552
|
+
assert.match(prompt, /reworkResolution/);
|
|
553
|
+
});
|
|
554
|
+
|
|
521
555
|
test("execute-task prompt omits on-demand slice research when the artifact is absent", async (t) => {
|
|
522
556
|
const base = makeFixtureBase();
|
|
523
557
|
t.after(() => cleanup(base));
|