gsd-pi 2.66.1-dev.ed243f2 → 2.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/claude-cli-check.d.ts +8 -0
- package/dist/claude-cli-check.js +36 -0
- package/dist/cli.js +40 -0
- package/dist/onboarding.js +19 -2
- package/dist/resources/extensions/ask-user-questions.js +79 -11
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +4 -3
- package/dist/resources/extensions/claude-code-cli/readiness.js +63 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +10 -3
- package/dist/resources/extensions/gsd/auto/loop.js +13 -1
- package/dist/resources/extensions/gsd/auto/phases.js +22 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto/session.js +1 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +65 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +30 -28
- package/dist/resources/extensions/gsd/auto-model-selection.js +12 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +173 -25
- package/dist/resources/extensions/gsd/auto-recovery.js +11 -12
- package/dist/resources/extensions/gsd/auto.js +13 -1
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +18 -6
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +59 -5
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +8 -5
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +186 -14
- package/dist/resources/extensions/gsd/codebase-generator.js +4 -0
- package/dist/resources/extensions/gsd/commands/handlers/core.js +3 -3
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -4
- package/dist/resources/extensions/gsd/context-store.js +134 -2
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -1
- package/dist/resources/extensions/gsd/detection.js +6 -0
- package/dist/resources/extensions/gsd/files.js +19 -2
- package/dist/resources/extensions/gsd/guided-flow.js +12 -8
- package/dist/resources/extensions/gsd/index.js +1 -1
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +2 -0
- package/dist/resources/extensions/gsd/parsers-legacy.js +3 -1
- package/dist/resources/extensions/gsd/preferences.js +6 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
- package/dist/resources/extensions/gsd/prompts/discuss.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/dist/resources/extensions/gsd/prompts/rethink.md +6 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -4
- package/dist/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +2 -1
- package/dist/resources/extensions/gsd/state.js +2 -1
- package/dist/resources/extensions/gsd/visualizer-overlay.js +27 -26
- package/dist/resources/extensions/gsd/workflow-reconcile.js +46 -7
- package/dist/resources/extensions/remote-questions/manager.js +8 -0
- package/dist/resources/extensions/shared/interview-ui.js +10 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- 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 +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.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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/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/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 +2 -2
- 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 +2 -2
- 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 +4 -4
- 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 +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +14 -14
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- 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/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +4 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/json-parse.js +11 -1
- package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js +60 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.js +14 -0
- package/packages/pi-ai/dist/utils/tests/json-parse.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +10 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +4 -3
- package/packages/pi-ai/src/utils/json-parse.ts +11 -1
- package/packages/pi-ai/src/utils/repair-tool-json.ts +69 -1
- package/packages/pi-ai/src/utils/tests/json-parse.test.ts +17 -0
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +13 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -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 +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +16 -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 +58 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +58 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +4 -0
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +69 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +66 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +5 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +18 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +11 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +2 -2
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +13 -0
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +35 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/tui.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +43 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -0
- package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/packages/pi-tui/dist/autocomplete.js +9 -7
- package/packages/pi-tui/dist/autocomplete.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts +2 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js +54 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js.map +1 -0
- package/packages/pi-tui/dist/components/editor.d.ts +3 -1
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +14 -3
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +6 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +8 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +15 -0
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +43 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +50 -0
- package/packages/pi-tui/src/autocomplete.ts +9 -7
- package/packages/pi-tui/src/components/__tests__/editor.test.ts +64 -0
- package/packages/pi-tui/src/components/editor.ts +14 -3
- package/packages/pi-tui/src/stdin-buffer.ts +7 -0
- package/packages/pi-tui/src/tui.ts +9 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +103 -11
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +4 -3
- package/src/resources/extensions/claude-code-cli/readiness.ts +67 -12
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +12 -3
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +17 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +18 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -1
- package/src/resources/extensions/gsd/auto/loop.ts +14 -1
- package/src/resources/extensions/gsd/auto/phases.ts +27 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +14 -2
- package/src/resources/extensions/gsd/auto/session.ts +1 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +76 -16
- package/src/resources/extensions/gsd/auto-dispatch.ts +36 -35
- package/src/resources/extensions/gsd/auto-model-selection.ts +12 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +195 -25
- package/src/resources/extensions/gsd/auto-recovery.ts +15 -15
- package/src/resources/extensions/gsd/auto.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +27 -6
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +67 -6
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +11 -8
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +209 -16
- package/src/resources/extensions/gsd/codebase-generator.ts +4 -0
- package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -6
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -4
- package/src/resources/extensions/gsd/context-store.ts +167 -2
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +3 -1
- package/src/resources/extensions/gsd/detection.ts +6 -0
- package/src/resources/extensions/gsd/files.ts +21 -2
- package/src/resources/extensions/gsd/guided-flow.ts +15 -8
- package/src/resources/extensions/gsd/index.ts +6 -0
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +2 -0
- package/src/resources/extensions/gsd/parsers-legacy.ts +3 -1
- package/src/resources/extensions/gsd/preferences.ts +6 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-prepared.md +7 -7
- package/src/resources/extensions/gsd/prompts/discuss.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -3
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
- package/src/resources/extensions/gsd/prompts/rethink.md +6 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -4
- package/src/resources/extensions/gsd/prompts/worktree-merge.md +3 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +4 -1
- package/src/resources/extensions/gsd/state.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +52 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +21 -7
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/decision-scope-cascade.test.ts +370 -0
- package/src/resources/extensions/gsd/tests/detection.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +53 -13
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/measurement.test.ts +531 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +71 -2
- package/src/resources/extensions/gsd/tests/parsers.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/reactive-graph.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +210 -35
- package/src/resources/extensions/gsd/visualizer-overlay.ts +31 -27
- package/src/resources/extensions/gsd/workflow-reconcile.ts +59 -8
- package/src/resources/extensions/remote-questions/manager.ts +9 -0
- package/src/resources/extensions/shared/interview-ui.ts +13 -0
- package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- /package/dist/web/standalone/.next/static/{HAq0VE4k68rhRvJbQL1VW → DFZllMYDbO0OwyS6FSvm5}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{HAq0VE4k68rhRvJbQL1VW → DFZllMYDbO0OwyS6FSvm5}/_ssgManifest.js +0 -0
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Exercises shouldBlockContextWrite() — a pure function that implements:
|
|
5
5
|
* (a) toolName !== "write" → pass
|
|
6
|
-
* (b)
|
|
6
|
+
* (b) milestone context must resolve to a verified milestone
|
|
7
7
|
* (c) path doesn't match /M\d+-CONTEXT\.md$/ → pass
|
|
8
|
-
* (d)
|
|
8
|
+
* (d) non-context files → pass
|
|
9
9
|
* (e) else → block with actionable reason
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -14,12 +14,12 @@ import assert from 'node:assert/strict';
|
|
|
14
14
|
import {
|
|
15
15
|
isDepthConfirmationAnswer,
|
|
16
16
|
shouldBlockContextWrite,
|
|
17
|
-
isDepthVerified,
|
|
18
|
-
isQueuePhaseActive,
|
|
19
17
|
setQueuePhaseActive,
|
|
20
18
|
} from '../index.ts';
|
|
21
19
|
import {
|
|
22
20
|
markDepthVerified,
|
|
21
|
+
isMilestoneDepthVerified,
|
|
22
|
+
shouldBlockContextArtifactSave,
|
|
23
23
|
clearDiscussionFlowState,
|
|
24
24
|
resetWriteGateState,
|
|
25
25
|
} from '../bootstrap/write-gate.ts';
|
|
@@ -53,26 +53,27 @@ test('write-gate: blocks CONTEXT.md write during discussion without depth verifi
|
|
|
53
53
|
// ─── Scenario 3: Allows CONTEXT.md write after depth verification ──
|
|
54
54
|
|
|
55
55
|
test('write-gate: allows CONTEXT.md write after depth verification', () => {
|
|
56
|
+
clearDiscussionFlowState();
|
|
57
|
+
markDepthVerified('M001');
|
|
56
58
|
const result = shouldBlockContextWrite(
|
|
57
59
|
'write',
|
|
58
60
|
'/Users/dev/project/.gsd/milestones/M001/M001-CONTEXT.md',
|
|
59
61
|
'M001',
|
|
60
|
-
true,
|
|
61
62
|
);
|
|
62
63
|
assert.strictEqual(result.block, false, 'should not block after depth verification');
|
|
63
64
|
assert.strictEqual(result.reason, undefined, 'should have no reason');
|
|
65
|
+
clearDiscussionFlowState();
|
|
64
66
|
});
|
|
65
67
|
|
|
66
|
-
// ─── Scenario 4:
|
|
68
|
+
// ─── Scenario 4: Ambiguous session context no longer bypasses the gate ──
|
|
67
69
|
|
|
68
|
-
test('write-gate:
|
|
70
|
+
test('write-gate: blocks CONTEXT.md write when milestoneId is ambiguous', () => {
|
|
69
71
|
const result = shouldBlockContextWrite(
|
|
70
72
|
'write',
|
|
71
73
|
'.gsd/milestones/M001/M001-CONTEXT.md',
|
|
72
74
|
null,
|
|
73
|
-
false,
|
|
74
75
|
);
|
|
75
|
-
assert.strictEqual(result.block,
|
|
76
|
+
assert.strictEqual(result.block, true, 'should block when milestone context is ambiguous');
|
|
76
77
|
});
|
|
77
78
|
|
|
78
79
|
// ─── Scenario 5: Allows non-CONTEXT.md writes during discussion ──
|
|
@@ -83,7 +84,6 @@ test('write-gate: allows non-CONTEXT.md writes during discussion', () => {
|
|
|
83
84
|
'write',
|
|
84
85
|
'.gsd/milestones/M001/M001-DISCUSSION.md',
|
|
85
86
|
'M001',
|
|
86
|
-
false,
|
|
87
87
|
);
|
|
88
88
|
assert.strictEqual(r1.block, false, 'DISCUSSION.md should pass');
|
|
89
89
|
|
|
@@ -92,7 +92,6 @@ test('write-gate: allows non-CONTEXT.md writes during discussion', () => {
|
|
|
92
92
|
'write',
|
|
93
93
|
'.gsd/milestones/M001/slices/S01/S01-PLAN.md',
|
|
94
94
|
'M001',
|
|
95
|
-
false,
|
|
96
95
|
);
|
|
97
96
|
assert.strictEqual(r2.block, false, 'slice plan should pass');
|
|
98
97
|
|
|
@@ -101,7 +100,6 @@ test('write-gate: allows non-CONTEXT.md writes during discussion', () => {
|
|
|
101
100
|
'write',
|
|
102
101
|
'src/index.ts',
|
|
103
102
|
'M001',
|
|
104
|
-
false,
|
|
105
103
|
);
|
|
106
104
|
assert.strictEqual(r3.block, false, 'regular code file should pass');
|
|
107
105
|
});
|
|
@@ -113,7 +111,6 @@ test('write-gate: regex does not match slice context files (S01-CONTEXT.md)', ()
|
|
|
113
111
|
'write',
|
|
114
112
|
'.gsd/milestones/M001/slices/S01/S01-CONTEXT.md',
|
|
115
113
|
'M001',
|
|
116
|
-
false,
|
|
117
114
|
);
|
|
118
115
|
assert.strictEqual(result.block, false, 'S01-CONTEXT.md should not be blocked');
|
|
119
116
|
});
|
|
@@ -125,7 +122,6 @@ test('write-gate: blocked reason contains depth_verification keyword and anti-by
|
|
|
125
122
|
'write',
|
|
126
123
|
'.gsd/milestones/M999/M999-CONTEXT.md',
|
|
127
124
|
'M999',
|
|
128
|
-
false,
|
|
129
125
|
);
|
|
130
126
|
assert.strictEqual(result.block, true);
|
|
131
127
|
assert.ok(result.reason!.includes('depth_verification'), 'reason should mention depth_verification question id');
|
|
@@ -141,7 +137,6 @@ test('write-gate: blocks CONTEXT.md write in queue mode without depth verificati
|
|
|
141
137
|
'write',
|
|
142
138
|
'.gsd/milestones/M001/M001-CONTEXT.md',
|
|
143
139
|
null, // no milestoneId in queue mode
|
|
144
|
-
false, // not depth-verified
|
|
145
140
|
true, // queue phase active
|
|
146
141
|
);
|
|
147
142
|
assert.strictEqual(result.block, true, 'should block in queue mode without depth verification');
|
|
@@ -151,48 +146,228 @@ test('write-gate: blocks CONTEXT.md write in queue mode without depth verificati
|
|
|
151
146
|
// ─── Scenario 9: Queue mode allows CONTEXT.md write after depth verification ──
|
|
152
147
|
|
|
153
148
|
test('write-gate: allows CONTEXT.md write in queue mode after depth verification', () => {
|
|
149
|
+
clearDiscussionFlowState();
|
|
150
|
+
markDepthVerified('M001');
|
|
154
151
|
const result = shouldBlockContextWrite(
|
|
155
152
|
'write',
|
|
156
153
|
'.gsd/milestones/M001/M001-CONTEXT.md',
|
|
157
154
|
null, // no milestoneId in queue mode
|
|
158
|
-
true, // depth-verified
|
|
159
155
|
true, // queue phase active
|
|
160
156
|
);
|
|
161
157
|
assert.strictEqual(result.block, false, 'should not block in queue mode after depth verification');
|
|
158
|
+
clearDiscussionFlowState();
|
|
162
159
|
});
|
|
163
160
|
|
|
164
|
-
// ─── Scenario 10:
|
|
165
|
-
// This is the core regression for #1812: in queue mode, the tool_result handler
|
|
166
|
-
// must call markDepthVerified() even when getDiscussionMilestoneId() is null.
|
|
161
|
+
// ─── Scenario 10: depth verification is scoped per milestone, not global ──
|
|
167
162
|
|
|
168
|
-
test('write-gate: markDepthVerified
|
|
163
|
+
test('write-gate: markDepthVerified unlocks only the matching milestone', () => {
|
|
169
164
|
clearDiscussionFlowState();
|
|
170
|
-
|
|
165
|
+
markDepthVerified('M001');
|
|
171
166
|
|
|
172
|
-
|
|
173
|
-
const blocked = shouldBlockContextWrite(
|
|
167
|
+
const allowed = shouldBlockContextWrite(
|
|
174
168
|
'write',
|
|
175
169
|
'.gsd/milestones/M001/M001-CONTEXT.md',
|
|
176
170
|
null,
|
|
177
|
-
isDepthVerified(),
|
|
178
|
-
isQueuePhaseActive(),
|
|
179
171
|
);
|
|
180
|
-
assert.strictEqual(
|
|
172
|
+
assert.strictEqual(allowed.block, false, 'should allow the verified milestone');
|
|
181
173
|
|
|
182
|
-
|
|
183
|
-
markDepthVerified();
|
|
184
|
-
|
|
185
|
-
// After marking: should pass
|
|
186
|
-
const allowed = shouldBlockContextWrite(
|
|
174
|
+
const blockedOther = shouldBlockContextWrite(
|
|
187
175
|
'write',
|
|
188
|
-
'.gsd/milestones/
|
|
176
|
+
'.gsd/milestones/M002/M002-CONTEXT.md',
|
|
189
177
|
null,
|
|
190
|
-
isDepthVerified(),
|
|
191
|
-
isQueuePhaseActive(),
|
|
192
178
|
);
|
|
193
|
-
assert.strictEqual(
|
|
179
|
+
assert.strictEqual(blockedOther.block, true, 'other milestones should remain blocked');
|
|
180
|
+
assert.strictEqual(isMilestoneDepthVerified('M001'), true);
|
|
181
|
+
assert.strictEqual(isMilestoneDepthVerified('M002'), false);
|
|
182
|
+
|
|
183
|
+
clearDiscussionFlowState();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// ─── Scenario 11: gsd_summary_save CONTEXT contract is milestone-scoped ──
|
|
187
|
+
|
|
188
|
+
test('write-gate: gsd_summary_save only blocks final milestone CONTEXT writes', () => {
|
|
189
|
+
clearDiscussionFlowState();
|
|
190
|
+
|
|
191
|
+
assert.strictEqual(
|
|
192
|
+
shouldBlockContextArtifactSave('CONTEXT-DRAFT', 'M001').block,
|
|
193
|
+
false,
|
|
194
|
+
'draft CONTEXT should be allowed',
|
|
195
|
+
);
|
|
196
|
+
assert.strictEqual(
|
|
197
|
+
shouldBlockContextArtifactSave('CONTEXT', 'M001', 'S01').block,
|
|
198
|
+
false,
|
|
199
|
+
'slice CONTEXT should be allowed',
|
|
200
|
+
);
|
|
201
|
+
assert.strictEqual(
|
|
202
|
+
shouldBlockContextArtifactSave('CONTEXT', 'M001').block,
|
|
203
|
+
true,
|
|
204
|
+
'final milestone CONTEXT should block before verification',
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
markDepthVerified('M001');
|
|
208
|
+
assert.strictEqual(
|
|
209
|
+
shouldBlockContextArtifactSave('CONTEXT', 'M001').block,
|
|
210
|
+
false,
|
|
211
|
+
'final milestone CONTEXT should pass after verification',
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
clearDiscussionFlowState();
|
|
215
|
+
});
|
|
194
216
|
|
|
217
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
218
|
+
// Discussion gate enforcement tests (pending gate mechanism)
|
|
219
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
220
|
+
|
|
221
|
+
import {
|
|
222
|
+
isGateQuestionId,
|
|
223
|
+
shouldBlockPendingGate,
|
|
224
|
+
shouldBlockPendingGateBash,
|
|
225
|
+
setPendingGate,
|
|
226
|
+
clearPendingGate,
|
|
227
|
+
getPendingGate,
|
|
228
|
+
} from '../bootstrap/write-gate.ts';
|
|
229
|
+
|
|
230
|
+
// ─── Scenario 19: isGateQuestionId recognizes all gate patterns ──
|
|
231
|
+
|
|
232
|
+
test('write-gate: isGateQuestionId recognizes all gate patterns', () => {
|
|
233
|
+
assert.strictEqual(isGateQuestionId('layer1_scope_gate'), true);
|
|
234
|
+
assert.strictEqual(isGateQuestionId('layer2_architecture_gate'), true);
|
|
235
|
+
assert.strictEqual(isGateQuestionId('layer3_error_gate'), true);
|
|
236
|
+
assert.strictEqual(isGateQuestionId('layer4_quality_gate'), true);
|
|
237
|
+
assert.strictEqual(isGateQuestionId('depth_verification'), true);
|
|
238
|
+
assert.strictEqual(isGateQuestionId('depth_verification_M002'), true);
|
|
239
|
+
assert.strictEqual(isGateQuestionId('my_layer1_scope_gate_question'), true);
|
|
240
|
+
// Non-gate question IDs
|
|
241
|
+
assert.strictEqual(isGateQuestionId('project_intent'), false);
|
|
242
|
+
assert.strictEqual(isGateQuestionId('feature_priority'), false);
|
|
243
|
+
assert.strictEqual(isGateQuestionId(''), false);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// ─── Scenario 20: setPendingGate / getPendingGate / clearPendingGate lifecycle ──
|
|
247
|
+
|
|
248
|
+
test('write-gate: pending gate lifecycle (set, get, clear)', () => {
|
|
195
249
|
clearDiscussionFlowState();
|
|
250
|
+
assert.strictEqual(getPendingGate(), null, 'starts null');
|
|
251
|
+
|
|
252
|
+
setPendingGate('layer1_scope_gate');
|
|
253
|
+
assert.strictEqual(getPendingGate(), 'layer1_scope_gate', 'set correctly');
|
|
254
|
+
|
|
255
|
+
clearPendingGate();
|
|
256
|
+
assert.strictEqual(getPendingGate(), null, 'cleared correctly');
|
|
257
|
+
|
|
258
|
+
// clearDiscussionFlowState also clears pending gate
|
|
259
|
+
setPendingGate('layer2_architecture_gate');
|
|
260
|
+
clearDiscussionFlowState();
|
|
261
|
+
assert.strictEqual(getPendingGate(), null, 'clearDiscussionFlowState clears pending gate');
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// ─── Scenario 21: shouldBlockPendingGate blocks non-safe tools when gate is pending ──
|
|
265
|
+
|
|
266
|
+
test('write-gate: shouldBlockPendingGate blocks write/edit during pending gate', () => {
|
|
267
|
+
clearDiscussionFlowState();
|
|
268
|
+
setPendingGate('layer1_scope_gate');
|
|
269
|
+
|
|
270
|
+
// write should be blocked during discussion
|
|
271
|
+
const writeResult = shouldBlockPendingGate('write', 'M001', false);
|
|
272
|
+
assert.strictEqual(writeResult.block, true, 'write should be blocked');
|
|
273
|
+
assert.ok(writeResult.reason!.includes('layer1_scope_gate'), 'reason mentions the gate');
|
|
274
|
+
|
|
275
|
+
// edit should be blocked
|
|
276
|
+
const editResult = shouldBlockPendingGate('edit', 'M001', false);
|
|
277
|
+
assert.strictEqual(editResult.block, true, 'edit should be blocked');
|
|
278
|
+
|
|
279
|
+
// gsd tools should be blocked
|
|
280
|
+
const gsdResult = shouldBlockPendingGate('gsd_plan_milestone', 'M001', false);
|
|
281
|
+
assert.strictEqual(gsdResult.block, true, 'gsd tools should be blocked');
|
|
282
|
+
|
|
283
|
+
clearDiscussionFlowState();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// ─── Scenario 22: shouldBlockPendingGate allows safe tools when gate is pending ──
|
|
287
|
+
|
|
288
|
+
test('write-gate: shouldBlockPendingGate allows read-only and ask_user_questions during pending gate', () => {
|
|
289
|
+
clearDiscussionFlowState();
|
|
290
|
+
setPendingGate('layer1_scope_gate');
|
|
291
|
+
|
|
292
|
+
// ask_user_questions is always safe (model needs to re-ask)
|
|
293
|
+
assert.strictEqual(shouldBlockPendingGate('ask_user_questions', 'M001').block, false);
|
|
294
|
+
// read-only tools are safe
|
|
295
|
+
assert.strictEqual(shouldBlockPendingGate('read', 'M001').block, false);
|
|
296
|
+
assert.strictEqual(shouldBlockPendingGate('grep', 'M001').block, false);
|
|
297
|
+
assert.strictEqual(shouldBlockPendingGate('glob', 'M001').block, false);
|
|
298
|
+
assert.strictEqual(shouldBlockPendingGate('ls', 'M001').block, false);
|
|
299
|
+
|
|
300
|
+
clearDiscussionFlowState();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// ─── Scenario 23: shouldBlockPendingGate still blocks when the session is ambiguous ──
|
|
304
|
+
|
|
305
|
+
test('write-gate: shouldBlockPendingGate blocks outside discussion when a gate is pending', () => {
|
|
306
|
+
clearDiscussionFlowState();
|
|
307
|
+
setPendingGate('layer1_scope_gate');
|
|
308
|
+
|
|
309
|
+
// No milestoneId and no queue phase — still block because the gate is pending
|
|
310
|
+
const result = shouldBlockPendingGate('write', null, false);
|
|
311
|
+
assert.strictEqual(result.block, true, 'should block even when milestoneId is null');
|
|
312
|
+
|
|
313
|
+
clearDiscussionFlowState();
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// ─── Scenario 24: shouldBlockPendingGate blocks in queue mode ──
|
|
317
|
+
|
|
318
|
+
test('write-gate: shouldBlockPendingGate blocks in queue mode when gate is pending', () => {
|
|
319
|
+
clearDiscussionFlowState();
|
|
320
|
+
setQueuePhaseActive(true);
|
|
321
|
+
setPendingGate('depth_verification');
|
|
322
|
+
|
|
323
|
+
const result = shouldBlockPendingGate('write', null, true);
|
|
324
|
+
assert.strictEqual(result.block, true, 'should block in queue mode');
|
|
325
|
+
|
|
326
|
+
clearDiscussionFlowState();
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// ─── Scenario 25: shouldBlockPendingGateBash allows read-only commands ──
|
|
330
|
+
|
|
331
|
+
test('write-gate: shouldBlockPendingGateBash allows read-only commands during pending gate', () => {
|
|
332
|
+
clearDiscussionFlowState();
|
|
333
|
+
setPendingGate('layer2_architecture_gate');
|
|
334
|
+
|
|
335
|
+
assert.strictEqual(shouldBlockPendingGateBash('cat file.txt', 'M001').block, false);
|
|
336
|
+
assert.strictEqual(shouldBlockPendingGateBash('git log --oneline', 'M001').block, false);
|
|
337
|
+
assert.strictEqual(shouldBlockPendingGateBash('grep -r pattern .', 'M001').block, false);
|
|
338
|
+
assert.strictEqual(shouldBlockPendingGateBash('ls -la', 'M001').block, false);
|
|
339
|
+
|
|
340
|
+
clearDiscussionFlowState();
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// ─── Scenario 26: shouldBlockPendingGateBash blocks mutating commands ──
|
|
344
|
+
|
|
345
|
+
test('write-gate: shouldBlockPendingGateBash blocks mutating commands during pending gate', () => {
|
|
346
|
+
clearDiscussionFlowState();
|
|
347
|
+
setPendingGate('layer2_architecture_gate');
|
|
348
|
+
|
|
349
|
+
const result = shouldBlockPendingGateBash('npm run build', 'M001');
|
|
350
|
+
assert.strictEqual(result.block, true, 'mutating bash should be blocked');
|
|
351
|
+
assert.ok(result.reason!.includes('layer2_architecture_gate'));
|
|
352
|
+
|
|
353
|
+
clearDiscussionFlowState();
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
// ─── Scenario 27: no pending gate means no blocking ──
|
|
357
|
+
|
|
358
|
+
test('write-gate: no pending gate means no blocking', () => {
|
|
359
|
+
clearDiscussionFlowState();
|
|
360
|
+
|
|
361
|
+
assert.strictEqual(shouldBlockPendingGate('write', 'M001').block, false);
|
|
362
|
+
assert.strictEqual(shouldBlockPendingGateBash('npm run build', 'M001').block, false);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// ─── Scenario 28: resetWriteGateState clears pending gate ──
|
|
366
|
+
|
|
367
|
+
test('write-gate: resetWriteGateState clears pending gate', () => {
|
|
368
|
+
setPendingGate('layer3_error_gate');
|
|
369
|
+
resetWriteGateState();
|
|
370
|
+
assert.strictEqual(getPendingGate(), null);
|
|
196
371
|
});
|
|
197
372
|
|
|
198
373
|
// ─── Standard options fixture used across depth confirmation tests ──
|
|
@@ -34,6 +34,24 @@ const TAB_LABELS = [
|
|
|
34
34
|
"0 Export",
|
|
35
35
|
];
|
|
36
36
|
|
|
37
|
+
type TabBarEntry = { label: string; width: number };
|
|
38
|
+
|
|
39
|
+
function buildTabBarEntries(activeTab: number, filterText: string, capturesPendingCount?: number): TabBarEntry[] {
|
|
40
|
+
return TAB_LABELS.map((label, i) => {
|
|
41
|
+
let displayLabel = label;
|
|
42
|
+
if (i === activeTab && filterText) {
|
|
43
|
+
displayLabel += " \u2731";
|
|
44
|
+
}
|
|
45
|
+
if (i === 8 && capturesPendingCount) {
|
|
46
|
+
displayLabel += ` (${capturesPendingCount})`;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
label: displayLabel,
|
|
50
|
+
width: visibleWidth(displayLabel) + 2,
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
export class GSDVisualizerOverlay {
|
|
38
56
|
private tui: { requestRender: () => void };
|
|
39
57
|
private theme: Theme;
|
|
@@ -116,15 +134,14 @@ export class GSDVisualizerOverlay {
|
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
handleInput(data: string): void {
|
|
137
|
+
if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c"))) {
|
|
138
|
+
this.dispose();
|
|
139
|
+
this.onClose();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
119
143
|
// Filter mode input routing
|
|
120
144
|
if (this.filterMode) {
|
|
121
|
-
if (matchesKey(data, Key.escape)) {
|
|
122
|
-
this.filterMode = false;
|
|
123
|
-
this.filterText = "";
|
|
124
|
-
this.invalidate();
|
|
125
|
-
this.tui.requestRender();
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
145
|
if (matchesKey(data, Key.enter)) {
|
|
129
146
|
this.filterMode = false;
|
|
130
147
|
this.invalidate();
|
|
@@ -179,8 +196,9 @@ export class GSDVisualizerOverlay {
|
|
|
179
196
|
// Left click — check if on tab bar row
|
|
180
197
|
if (mouse.y === 2) {
|
|
181
198
|
let xPos = 3;
|
|
182
|
-
|
|
183
|
-
|
|
199
|
+
const tabs = buildTabBarEntries(this.activeTab, this.filterText, this.data?.captures?.pendingCount);
|
|
200
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
201
|
+
const tabWidth = tabs[i]!.width;
|
|
184
202
|
if (mouse.x >= xPos && mouse.x < xPos + tabWidth) {
|
|
185
203
|
this.activeTab = i;
|
|
186
204
|
this.invalidate();
|
|
@@ -194,12 +212,6 @@ export class GSDVisualizerOverlay {
|
|
|
194
212
|
return;
|
|
195
213
|
}
|
|
196
214
|
|
|
197
|
-
if (matchesKey(data, Key.escape) || matchesKey(data, Key.ctrl("c"))) {
|
|
198
|
-
this.dispose();
|
|
199
|
-
this.onClose();
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
215
|
if (matchesKey(data, Key.shift("tab"))) {
|
|
204
216
|
this.activeTab = (this.activeTab - 1 + TAB_COUNT) % TAB_COUNT;
|
|
205
217
|
this.invalidate();
|
|
@@ -442,20 +454,12 @@ export class GSDVisualizerOverlay {
|
|
|
442
454
|
const content: string[] = [];
|
|
443
455
|
|
|
444
456
|
// Tab bar
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
// Show filter indicator on active tab with filter
|
|
448
|
-
if (i === this.activeTab && this.filterText) {
|
|
449
|
-
displayLabel += " \u2731";
|
|
450
|
-
}
|
|
451
|
-
// Show captures badge
|
|
452
|
-
if (i === 8 && this.data?.captures?.pendingCount) {
|
|
453
|
-
displayLabel += ` (${this.data.captures.pendingCount})`;
|
|
454
|
-
}
|
|
457
|
+
const tabEntries = buildTabBarEntries(this.activeTab, this.filterText, this.data?.captures?.pendingCount);
|
|
458
|
+
const tabs = tabEntries.map((entry, i) => {
|
|
455
459
|
if (i === this.activeTab) {
|
|
456
|
-
return th.fg("accent", `[${
|
|
460
|
+
return th.fg("accent", `[${entry.label}]`);
|
|
457
461
|
}
|
|
458
|
-
return th.fg("dim", `[${
|
|
462
|
+
return th.fg("dim", `[${entry.label}]`);
|
|
459
463
|
});
|
|
460
464
|
content.push(" " + tabs.join(" "));
|
|
461
465
|
content.push("");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
3
3
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
4
|
-
import { readEvents, findForkPoint,
|
|
4
|
+
import { readEvents, findForkPoint, getSessionId } from "./workflow-events.js";
|
|
5
5
|
import type { WorkflowEvent } from "./workflow-events.js";
|
|
6
6
|
import {
|
|
7
7
|
transaction,
|
|
@@ -329,6 +329,41 @@ export function detectConflicts(
|
|
|
329
329
|
return conflicts;
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
+
function rewriteDivergedEventsForEntity(
|
|
333
|
+
divergedEvents: WorkflowEvent[],
|
|
334
|
+
entityType: string,
|
|
335
|
+
entityId: string,
|
|
336
|
+
replacementEvents: WorkflowEvent[],
|
|
337
|
+
): WorkflowEvent[] {
|
|
338
|
+
const rewritten: WorkflowEvent[] = [];
|
|
339
|
+
let inserted = false;
|
|
340
|
+
|
|
341
|
+
for (const event of divergedEvents) {
|
|
342
|
+
const key = extractEntityKey(event);
|
|
343
|
+
if (key?.type === entityType && key.id === entityId) {
|
|
344
|
+
if (!inserted) {
|
|
345
|
+
rewritten.push(...replacementEvents);
|
|
346
|
+
inserted = true;
|
|
347
|
+
}
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
rewritten.push(event);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (!inserted) {
|
|
354
|
+
rewritten.push(...replacementEvents);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return rewritten;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function writeEventLog(basePath: string, events: WorkflowEvent[]): void {
|
|
361
|
+
const dir = join(basePath, ".gsd");
|
|
362
|
+
mkdirSync(dir, { recursive: true });
|
|
363
|
+
const content = events.map((e) => JSON.stringify(e)).join("\n") + (events.length > 0 ? "\n" : "");
|
|
364
|
+
atomicWriteSync(join(dir, "event-log.jsonl"), content);
|
|
365
|
+
}
|
|
366
|
+
|
|
332
367
|
// ─── writeConflictsFile ───────────────────────────────────────────────────────
|
|
333
368
|
|
|
334
369
|
/**
|
|
@@ -575,8 +610,8 @@ function parseEventBlock(block: string): WorkflowEvent[] {
|
|
|
575
610
|
|
|
576
611
|
/**
|
|
577
612
|
* Resolve a single conflict by picking one side's events.
|
|
578
|
-
* Replays the picked events through the DB helpers,
|
|
579
|
-
* and updates or removes CONFLICTS.md.
|
|
613
|
+
* Replays the picked events through the DB helpers, rewrites the chosen side's
|
|
614
|
+
* event log so the conflict is durable, and updates or removes CONFLICTS.md.
|
|
580
615
|
*
|
|
581
616
|
* When the last conflict is resolved, non-conflicting events from both sides
|
|
582
617
|
* are also replayed (they were blocked by the all-or-nothing D-04 rule).
|
|
@@ -598,14 +633,30 @@ export function resolveConflict(
|
|
|
598
633
|
const conflict = conflicts[idx]!;
|
|
599
634
|
const eventsToReplay = pick === "main" ? conflict.mainSideEvents : conflict.worktreeSideEvents;
|
|
600
635
|
|
|
636
|
+
const mainLogPath = join(basePath, ".gsd", "event-log.jsonl");
|
|
637
|
+
const wtLogPath = join(worktreeBasePath, ".gsd", "event-log.jsonl");
|
|
638
|
+
const mainEvents = readEvents(mainLogPath);
|
|
639
|
+
const wtEvents = readEvents(wtLogPath);
|
|
640
|
+
const forkPoint = findForkPoint(mainEvents, wtEvents);
|
|
641
|
+
const mainBaseEvents = mainEvents.slice(0, forkPoint + 1);
|
|
642
|
+
const wtBaseEvents = wtEvents.slice(0, forkPoint + 1);
|
|
643
|
+
const mainDiverged = mainEvents.slice(forkPoint + 1);
|
|
644
|
+
const wtDiverged = wtEvents.slice(forkPoint + 1);
|
|
645
|
+
|
|
646
|
+
const rewrittenTargetEvents = pick === "main"
|
|
647
|
+
? rewriteDivergedEventsForEntity(wtDiverged, entityType, entityId, eventsToReplay)
|
|
648
|
+
: rewriteDivergedEventsForEntity(mainDiverged, entityType, entityId, eventsToReplay);
|
|
649
|
+
|
|
650
|
+
const targetBasePath = pick === "main" ? worktreeBasePath : basePath;
|
|
651
|
+
const targetBaseEvents = pick === "main" ? wtBaseEvents : mainBaseEvents;
|
|
652
|
+
writeEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
|
|
653
|
+
|
|
601
654
|
// Replay resolved events through the DB (updates DB state)
|
|
602
655
|
openDatabase(join(basePath, ".gsd", "gsd.db"));
|
|
603
656
|
replayEvents(eventsToReplay);
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
appendEvent(basePath, { cmd: event.cmd, params: event.params, ts: event.ts, actor: event.actor });
|
|
608
|
-
}
|
|
657
|
+
invalidateStateCache();
|
|
658
|
+
clearPathCache();
|
|
659
|
+
clearParseCache();
|
|
609
660
|
|
|
610
661
|
// Remove resolved conflict from list
|
|
611
662
|
conflicts.splice(idx, 1);
|
|
@@ -24,6 +24,15 @@ interface QuestionInput {
|
|
|
24
24
|
allowMultiple?: boolean;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Check whether a remote channel is configured without triggering any
|
|
29
|
+
* side effects (no HTTP requests, no prompt records). Used by the race
|
|
30
|
+
* logic to decide routing before committing to a remote dispatch.
|
|
31
|
+
*/
|
|
32
|
+
export function isRemoteConfigured(): boolean {
|
|
33
|
+
return resolveRemoteConfig() !== null;
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
export async function tryRemoteQuestions(
|
|
28
37
|
questions: QuestionInput[],
|
|
29
38
|
signal?: AbortSignal,
|
|
@@ -80,6 +80,12 @@ export interface InterviewRoundOptions {
|
|
|
80
80
|
* Label for the Esc-confirm overlay header. Defaults to "End interview?".
|
|
81
81
|
*/
|
|
82
82
|
exitHeadline?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Optional AbortSignal to cancel the interview externally (e.g. when racing
|
|
85
|
+
* against a remote question channel). When aborted, the TUI closes and the
|
|
86
|
+
* promise resolves with an empty answers object.
|
|
87
|
+
*/
|
|
88
|
+
signal?: AbortSignal;
|
|
83
89
|
/**
|
|
84
90
|
* Text for the "exit" hint shown in the review screen footer and exit confirm overlay.
|
|
85
91
|
* Defaults to "end interview".
|
|
@@ -207,6 +213,13 @@ export async function showInterviewRound(
|
|
|
207
213
|
let exitCursor = 0; // 0 = keep going (default), 1 = end interview
|
|
208
214
|
let cachedLines: string[] | undefined;
|
|
209
215
|
|
|
216
|
+
// External cancellation (e.g. remote channel won the race)
|
|
217
|
+
if (opts.signal) {
|
|
218
|
+
const onAbort = () => done({ endInterview: false, answers: {} });
|
|
219
|
+
if (opts.signal.aborted) { onAbort(); }
|
|
220
|
+
else { opts.signal.addEventListener("abort", onAbort, { once: true }); }
|
|
221
|
+
}
|
|
222
|
+
|
|
210
223
|
// Editor is created once; editorTheme comes from the design system
|
|
211
224
|
const editorRef = { current: null as Editor | null };
|
|
212
225
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8974],{2600:(e,t,n)=>{Promise.resolve().then(n.bind(n,66919))},5214:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorage",{enumerable:!0,get:function(){return r.workAsyncStorageInstance}});let r=n(17828)},17828:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorageInstance",{enumerable:!0,get:function(){return r}});let r=(0,n(64054).createAsyncLocalStorage)()},21957:(e,t,n)=>{"use strict";function r({moduleIds:e}){return null}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadChunks",{enumerable:!0,get:function(){return r}}),n(95155),n(47650),n(5214),n(2451),n(53887)},37206:(e,t,n)=>{"use strict";n.d(t,{default:()=>u.a});var r=n(75707),u=n.n(r)},41112:(e,t,n)=>{"use strict";function r({reason:e,children:t}){return t}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return r}}),n(1980)},64054:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n={bindSnapshot:function(){return s},createAsyncLocalStorage:function(){return a},createSnapshot:function(){return i}};for(var r in n)Object.defineProperty(t,r,{enumerable:!0,get:n[r]});let u=Object.defineProperty(Error("Invariant: AsyncLocalStorage accessed in runtime where it is not available"),"__NEXT_ERROR_CODE",{value:"E504",enumerable:!1,configurable:!0});class l{disable(){throw u}getStore(){}run(){throw u}exit(){throw u}enterWith(){throw u}static bind(e){return e}}let o="u">typeof globalThis&&globalThis.AsyncLocalStorage;function a(){return o?new o:new l}function s(e){return o?o.bind(e):l.bind(e)}function i(){return o?o.snapshot():function(e,...t){return e(...t)}}},66919:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(95155);let u=(0,n(37206).default)(()=>Promise.all([n.e(1838),n.e(6079),n.e(4986),n.e(2008),n.e(6502)]).then(n.bind(n,46502)).then(e=>e.GSDAppShell),{loadableGenerated:{webpack:()=>[46502]},ssr:!1,loading:()=>(0,r.jsx)("div",{className:"flex h-screen items-center justify-center bg-background text-sm text-muted-foreground",children:"Loading workspace…"})});function l(){return(0,r.jsx)(u,{})}},68635:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return s}});let r=n(95155),u=n(12115),l=n(41112);function o(e){return{default:e&&"default"in e?e.default:e}}n(21957);let a={loader:()=>Promise.resolve(o(()=>null)),loading:null,ssr:!0},s=function(e){let t={...a,...e},n=(0,u.lazy)(()=>t.loader().then(o)),s=t.loading;function i(e){let o=s?(0,r.jsx)(s,{isLoading:!0,pastDelay:!0,error:null}):null,a=!t.ssr||!!t.loading,i=a?u.Suspense:u.Fragment,c=t.ssr?(0,r.jsxs)(r.Fragment,{children:[null,(0,r.jsx)(n,{...e})]}):(0,r.jsx)(l.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(n,{...e})});return(0,r.jsx)(i,{...a?{fallback:o}:{},children:c})}return i.displayName="LoadableComponent",i}},75707:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});let r=n(73623)._(n(68635));function u(e,t){let n={};"function"==typeof e&&(n.loader=e);let u={...n,...t};return(0,r.default)({...u,modules:u.loadableGenerated?.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=2600)),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{19393:()=>{},55548:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,27123,23)),Promise.resolve().then(n.t.bind(n,61304,23)),Promise.resolve().then(n.t.bind(n,78616,23)),Promise.resolve().then(n.t.bind(n,64777,23)),Promise.resolve().then(n.t.bind(n,57121,23)),Promise.resolve().then(n.t.bind(n,74581,23)),Promise.resolve().then(n.t.bind(n,90484,23)),Promise.resolve().then(n.bind(n,86869))}},e=>{var s=s=>e(e.s=s);e.O(0,[8441,3794],()=>(s(83861),s(55548))),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9337],{43946:(e,s,_)=>{Promise.resolve().then(_.t.bind(_,27123,23))}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=43946)),_N_E=e.O()}]);
|
|
File without changes
|
|
File without changes
|