gsd-pi 2.77.0-dev.58d3d4d6c → 2.77.0-dev.cfd69e714
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/claude-cli-check.js +5 -1
- package/dist/headless.js +49 -4
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
- package/dist/resources/extensions/gsd/auto/loop.js +43 -0
- package/dist/resources/extensions/gsd/auto/phases.js +15 -21
- package/dist/resources/extensions/gsd/auto/session.js +0 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +102 -24
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +71 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +329 -102
- package/dist/resources/extensions/gsd/auto-recovery.js +195 -23
- package/dist/resources/extensions/gsd/auto-start.js +34 -24
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
- package/dist/resources/extensions/gsd/auto.js +31 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/gate-registry.js +2 -2
- package/dist/resources/extensions/gsd/git-constants.js +28 -1
- package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
- package/dist/resources/extensions/gsd/git-service.js +126 -2
- package/dist/resources/extensions/gsd/gsd-db.js +6 -3
- package/dist/resources/extensions/gsd/guided-flow.js +17 -5
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/session-lock.js +19 -10
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state.js +44 -33
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +34 -8
- package/dist/resources/extensions/mcp-client/index.js +3 -1
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -5
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +2 -3
- package/packages/daemon/src/logger.ts +4 -3
- package/packages/mcp-server/dist/server.d.ts +24 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +88 -87
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/src/mcp-server.test.ts +25 -3
- package/packages/mcp-server/src/readers/graph.test.ts +87 -15
- package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
- package/packages/mcp-server/src/server.ts +131 -105
- package/packages/mcp-server/src/workflow-tools.test.ts +80 -39
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
- package/packages/native/src/__tests__/ps.test.mjs +14 -8
- package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
- package/packages/native/src/__tests__/truncate.test.mjs +17 -2
- package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +9 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +36 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/capability-patches.ts +10 -2
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +48 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
- package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +36 -12
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +14 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +19 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/dist/editor-component.d.ts +2 -0
- package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
- package/packages/pi-tui/dist/editor-component.js.map +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +41 -12
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/editor.ts +22 -0
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/src/editor-component.ts +3 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/scripts/install.js +15 -1
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +33 -1
- package/src/resources/extensions/gsd/auto/loop.ts +47 -0
- package/src/resources/extensions/gsd/auto/phases.ts +16 -20
- package/src/resources/extensions/gsd/auto/session.ts +0 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +113 -24
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +82 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +330 -90
- package/src/resources/extensions/gsd/auto-recovery.ts +225 -24
- package/src/resources/extensions/gsd/auto-start.ts +54 -6
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
- package/src/resources/extensions/gsd/auto.ts +43 -22
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +9 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/gate-registry.ts +2 -2
- package/src/resources/extensions/gsd/git-constants.ts +30 -1
- package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
- package/src/resources/extensions/gsd/git-service.ts +133 -2
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow.ts +20 -5
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/session-lock.ts +20 -10
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state.ts +49 -44
- package/src/resources/extensions/gsd/sync-lock.ts +97 -39
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +94 -289
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -197
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +9 -105
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -57
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -62
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -49
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -133
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +12 -61
- package/src/resources/extensions/gsd/tests/test-helpers.ts +21 -8
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -81
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/types.ts +3 -3
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +55 -7
- package/src/resources/extensions/mcp-client/index.ts +3 -1
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
- package/src/resources/extensions/ollama/index.ts +5 -1
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
- package/src/resources/extensions/remote-questions/manager.ts +36 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -144
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -75
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/forensics-worktree-telemetry.test.ts +0 -145
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -130
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -43
- /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Cev5xrAYA3ZGTRLyjR2fX → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
|
@@ -29,10 +29,17 @@ describe("Input", () => {
|
|
|
29
29
|
const input = new Input();
|
|
30
30
|
input.secure = true;
|
|
31
31
|
input.focused = true;
|
|
32
|
-
|
|
32
|
+
const SECRET = "secret123";
|
|
33
|
+
input.handleInput(SECRET);
|
|
33
34
|
const line = input.render(40)[0] ?? "";
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
// Previous assertion was `line.includes("*********")` — a literal
|
|
36
|
+
// 9-star string that silently goes stale if SECRET is renamed to
|
|
37
|
+
// a different length (#4796). Match any run of asterisks and
|
|
38
|
+
// assert its length covers the secret.
|
|
39
|
+
assert.ok(!line.includes(SECRET), "rendered line must not expose raw secret text");
|
|
40
|
+
const maskMatch = line.match(/\*+/);
|
|
41
|
+
assert.ok(maskMatch, `rendered line must include masked characters, got: ${JSON.stringify(line)}`);
|
|
42
|
+
assert.ok(maskMatch[0].length >= SECRET.length, `mask must cover at least the secret length (${SECRET.length}), got ${maskMatch[0].length} asterisks`);
|
|
36
43
|
});
|
|
37
44
|
it("maps kitty keypad digits to text instead of inserting private-use glyphs", () => {
|
|
38
45
|
const input = new Input();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/input.test.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,4DAA4D;AAE5D,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,yDAAyD;QACzD,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAEtC,2BAA2B;QAC3B,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QAEtB,mDAAmD;QACnD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,iEAAiE;QACjE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACnC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACjE,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACrB,KAAK,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"input.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/input.test.ts"],"names":[],"mappings":"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","sourcesContent":["// pi-tui Input component regression tests\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { Input } from \"../input.js\";\n\ndescribe(\"Input\", () => {\n\tit(\"paste buffer is cleared when focus is lost\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\t// Simulate starting a paste (bracket paste start marker)\n\t\tinput.handleInput(\"\\x1b[200~partial\");\n\n\t\t// Now lose focus mid-paste\n\t\tinput.focused = false;\n\n\t\t// Regain focus — should not have stale paste state\n\t\tinput.focused = true;\n\n\t\t// Typing normal text should work without paste buffer corruption\n\t\tinput.handleInput(\"hello\");\n\t\tassert.equal(input.getValue(), \"hello\");\n\t});\n\n\tit(\"focused getter/setter works correctly\", () => {\n\t\tconst input = new Input();\n\t\tassert.equal(input.focused, false);\n\t\tinput.focused = true;\n\t\tassert.equal(input.focused, true);\n\t\tinput.focused = false;\n\t\tassert.equal(input.focused, false);\n\t});\n\n\tit(\"secure mode obscures typed characters in render output\", () => {\n\t\tconst input = new Input();\n\t\tinput.secure = true;\n\t\tinput.focused = true;\n\t\tconst SECRET = \"secret123\";\n\t\tinput.handleInput(SECRET);\n\n\t\tconst line = input.render(40)[0] ?? \"\";\n\t\t// Previous assertion was `line.includes(\"*********\")` — a literal\n\t\t// 9-star string that silently goes stale if SECRET is renamed to\n\t\t// a different length (#4796). Match any run of asterisks and\n\t\t// assert its length covers the secret.\n\t\tassert.ok(\n\t\t\t!line.includes(SECRET),\n\t\t\t\"rendered line must not expose raw secret text\",\n\t\t);\n\t\tconst maskMatch = line.match(/\\*+/);\n\t\tassert.ok(\n\t\t\tmaskMatch,\n\t\t\t`rendered line must include masked characters, got: ${JSON.stringify(line)}`,\n\t\t);\n\t\tassert.ok(\n\t\t\tmaskMatch[0].length >= SECRET.length,\n\t\t\t`mask must cover at least the secret length (${SECRET.length}), got ${maskMatch[0].length} asterisks`,\n\t\t);\n\t});\n\n\tit(\"maps kitty keypad digits to text instead of inserting private-use glyphs\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\tinput.handleInput(\"\\x1b[57400;129u\");\n\n\t\tassert.equal(input.getValue(), \"1\");\n\t});\n\n\tit(\"ignores kitty keypad navigation keys in text input\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\tinput.handleInput(\"\\x1b[57417u\");\n\n\t\tassert.equal(input.getValue(), \"\");\n\t});\n});\n"]}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
// pi-tui Loader component regression tests
|
|
2
|
-
//
|
|
2
|
+
//
|
|
3
|
+
// The previous version of this file contained 3 tests that called
|
|
4
|
+
// `start()`/`stop()`/`dispose()` with no assertions at all — the claimed
|
|
5
|
+
// regression ("interval leak") would not have failed any of them. See
|
|
6
|
+
// #4794 / #4784.
|
|
7
|
+
//
|
|
8
|
+
// This rewrite uses Node's `mock.timers` to observe the interval that
|
|
9
|
+
// `Loader` registers internally, and `mock.fn()` on the mock TUI to
|
|
10
|
+
// count render requests. Each test asserts on observable behaviour:
|
|
11
|
+
// how many `requestRender` calls happen per tick, whether the interval
|
|
12
|
+
// is cleared on stop/dispose, and whether post-dispose stop() is safe.
|
|
3
13
|
import { describe, it, mock, beforeEach, afterEach } from "node:test";
|
|
14
|
+
import assert from "node:assert/strict";
|
|
4
15
|
import { Loader } from "../loader.js";
|
|
5
16
|
function makeMockTUI() {
|
|
6
17
|
return { requestRender: mock.fn() };
|
|
@@ -10,28 +21,61 @@ describe("Loader", () => {
|
|
|
10
21
|
let tui;
|
|
11
22
|
beforeEach(() => {
|
|
12
23
|
tui = makeMockTUI();
|
|
24
|
+
mock.timers.enable({ apis: ["setInterval"] });
|
|
13
25
|
});
|
|
14
26
|
afterEach(() => {
|
|
15
|
-
|
|
27
|
+
try {
|
|
28
|
+
loader?.stop();
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* best-effort */
|
|
32
|
+
}
|
|
33
|
+
mock.timers.reset();
|
|
34
|
+
});
|
|
35
|
+
it("constructor starts a spinner that ticks every 80ms and requests renders", () => {
|
|
36
|
+
loader = new Loader(tui, (s) => s, (s) => s, "test");
|
|
37
|
+
// Initial render request from start().
|
|
38
|
+
const initial = tui.requestRender.mock.callCount();
|
|
39
|
+
assert.ok(initial >= 1, `constructor should trigger at least one render (got ${initial})`);
|
|
40
|
+
// Advance 80ms — one interval tick should call requestRender once more.
|
|
41
|
+
mock.timers.tick(80);
|
|
42
|
+
assert.equal(tui.requestRender.mock.callCount(), initial + 1, "80ms tick should advance the spinner and call requestRender");
|
|
43
|
+
// Advance another 240ms — three more ticks.
|
|
44
|
+
mock.timers.tick(240);
|
|
45
|
+
assert.equal(tui.requestRender.mock.callCount(), initial + 4, "four total ticks after the initial render");
|
|
16
46
|
});
|
|
17
47
|
it("start() is idempotent — calling twice does not leak intervals", () => {
|
|
18
48
|
loader = new Loader(tui, (s) => s, (s) => s, "test");
|
|
19
|
-
// Constructor
|
|
49
|
+
// Constructor already started one interval. Call start() again.
|
|
20
50
|
loader.start();
|
|
21
|
-
|
|
51
|
+
const before = tui.requestRender.mock.callCount();
|
|
52
|
+
mock.timers.tick(80);
|
|
53
|
+
const after = tui.requestRender.mock.callCount();
|
|
54
|
+
// Exactly ONE tick's worth of work should happen — if the second
|
|
55
|
+
// start() leaked an interval, we'd see two increments per tick.
|
|
56
|
+
assert.equal(after - before, 1, "double-start must not double-tick (interval leak would show 2 increments)");
|
|
57
|
+
});
|
|
58
|
+
it("stop() clears the interval — no more ticks advance requestRender", () => {
|
|
59
|
+
loader = new Loader(tui, (s) => s, (s) => s, "test");
|
|
22
60
|
loader.stop();
|
|
61
|
+
const beforeTick = tui.requestRender.mock.callCount();
|
|
62
|
+
mock.timers.tick(400); // 5 tick intervals
|
|
63
|
+
assert.equal(tui.requestRender.mock.callCount(), beforeTick, "stopped loader must not advance renders");
|
|
23
64
|
});
|
|
24
65
|
it("dispose() stops the interval and nulls the TUI reference", () => {
|
|
25
66
|
loader = new Loader(tui, (s) => s, (s) => s, "test");
|
|
26
67
|
loader.dispose();
|
|
27
|
-
|
|
28
|
-
|
|
68
|
+
const beforeTick = tui.requestRender.mock.callCount();
|
|
69
|
+
mock.timers.tick(400);
|
|
70
|
+
assert.equal(tui.requestRender.mock.callCount(), beforeTick, "disposed loader must not advance renders");
|
|
71
|
+
// Calling stop() after dispose() must not throw.
|
|
72
|
+
assert.doesNotThrow(() => loader.stop());
|
|
29
73
|
});
|
|
30
|
-
it("stop() is safe to call multiple times", () => {
|
|
74
|
+
it("stop() is safe to call multiple times without throwing", () => {
|
|
31
75
|
loader = new Loader(tui, (s) => s, (s) => s, "test");
|
|
32
76
|
loader.stop();
|
|
33
|
-
loader.stop();
|
|
34
|
-
loader.stop();
|
|
77
|
+
assert.doesNotThrow(() => loader.stop());
|
|
78
|
+
assert.doesNotThrow(() => loader.stop());
|
|
35
79
|
});
|
|
36
80
|
});
|
|
37
81
|
//# sourceMappingURL=loader.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/loader.test.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,
|
|
1
|
+
{"version":3,"file":"loader.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/loader.test.ts"],"names":[],"mappings":"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","sourcesContent":["// pi-tui Loader component regression tests\n//\n// The previous version of this file contained 3 tests that called\n// `start()`/`stop()`/`dispose()` with no assertions at all — the claimed\n// regression (\"interval leak\") would not have failed any of them. See\n// #4794 / #4784.\n//\n// This rewrite uses Node's `mock.timers` to observe the interval that\n// `Loader` registers internally, and `mock.fn()` on the mock TUI to\n// count render requests. Each test asserts on observable behaviour:\n// how many `requestRender` calls happen per tick, whether the interval\n// is cleared on stop/dispose, and whether post-dispose stop() is safe.\n\nimport { describe, it, mock, beforeEach, afterEach } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { Loader } from \"../loader.js\";\n\ninterface MockTui {\n requestRender: ReturnType<typeof mock.fn>;\n}\n\nfunction makeMockTUI(): MockTui {\n return { requestRender: mock.fn() };\n}\n\ndescribe(\"Loader\", () => {\n let loader: Loader;\n let tui: MockTui;\n\n beforeEach(() => {\n tui = makeMockTUI();\n mock.timers.enable({ apis: [\"setInterval\"] });\n });\n\n afterEach(() => {\n try {\n loader?.stop();\n } catch {\n /* best-effort */\n }\n mock.timers.reset();\n });\n\n it(\"constructor starts a spinner that ticks every 80ms and requests renders\", () => {\n loader = new Loader(tui as never, (s) => s, (s) => s, \"test\");\n // Initial render request from start().\n const initial = tui.requestRender.mock.callCount();\n assert.ok(\n initial >= 1,\n `constructor should trigger at least one render (got ${initial})`,\n );\n\n // Advance 80ms — one interval tick should call requestRender once more.\n mock.timers.tick(80);\n assert.equal(\n tui.requestRender.mock.callCount(),\n initial + 1,\n \"80ms tick should advance the spinner and call requestRender\",\n );\n\n // Advance another 240ms — three more ticks.\n mock.timers.tick(240);\n assert.equal(\n tui.requestRender.mock.callCount(),\n initial + 4,\n \"four total ticks after the initial render\",\n );\n });\n\n it(\"start() is idempotent — calling twice does not leak intervals\", () => {\n loader = new Loader(tui as never, (s) => s, (s) => s, \"test\");\n // Constructor already started one interval. Call start() again.\n loader.start();\n\n const before = tui.requestRender.mock.callCount();\n mock.timers.tick(80);\n const after = tui.requestRender.mock.callCount();\n // Exactly ONE tick's worth of work should happen — if the second\n // start() leaked an interval, we'd see two increments per tick.\n assert.equal(\n after - before,\n 1,\n \"double-start must not double-tick (interval leak would show 2 increments)\",\n );\n });\n\n it(\"stop() clears the interval — no more ticks advance requestRender\", () => {\n loader = new Loader(tui as never, (s) => s, (s) => s, \"test\");\n loader.stop();\n\n const beforeTick = tui.requestRender.mock.callCount();\n mock.timers.tick(400); // 5 tick intervals\n assert.equal(\n tui.requestRender.mock.callCount(),\n beforeTick,\n \"stopped loader must not advance renders\",\n );\n });\n\n it(\"dispose() stops the interval and nulls the TUI reference\", () => {\n loader = new Loader(tui as never, (s) => s, (s) => s, \"test\");\n loader.dispose();\n\n const beforeTick = tui.requestRender.mock.callCount();\n mock.timers.tick(400);\n assert.equal(\n tui.requestRender.mock.callCount(),\n beforeTick,\n \"disposed loader must not advance renders\",\n );\n\n // Calling stop() after dispose() must not throw.\n assert.doesNotThrow(() => loader.stop());\n });\n\n it(\"stop() is safe to call multiple times without throwing\", () => {\n loader = new Loader(tui as never, (s) => s, (s) => s, \"test\");\n loader.stop();\n assert.doesNotThrow(() => loader.stop());\n assert.doesNotThrow(() => loader.stop());\n });\n});\n"]}
|
|
@@ -59,8 +59,12 @@ test("Markdown trims trailing empty lines", () => {
|
|
|
59
59
|
const text = "Some text\n\n";
|
|
60
60
|
const md = new Markdown(text, 0, 0, noopTheme());
|
|
61
61
|
const lines = md.render(80);
|
|
62
|
-
//
|
|
62
|
+
// Previous assertion was `lastLine.trim().length > 0 || lines.length === 1`
|
|
63
|
+
// — the `|| lines.length === 1` disjunction trivially passed for any
|
|
64
|
+
// single-line render, so a regression that returned `['']` still
|
|
65
|
+
// passed (#4796). Assert the trim invariant directly.
|
|
66
|
+
assert.ok(lines.length > 0, "render must produce at least one line");
|
|
63
67
|
const lastLine = lines[lines.length - 1];
|
|
64
|
-
assert.ok(lastLine.trim().length > 0
|
|
68
|
+
assert.ok(lastLine.trim().length > 0, `last line must have visible content after trim, got: ${JSON.stringify(lastLine)}`);
|
|
65
69
|
});
|
|
66
70
|
//# sourceMappingURL=markdown-maxlines.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-maxlines.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/markdown-maxlines.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"markdown-maxlines.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/markdown-maxlines.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\";\nimport { test } from \"node:test\";\n\nimport { Markdown, type MarkdownTheme } from \"../markdown.js\";\n\nfunction noopTheme(): MarkdownTheme {\n\tconst identity = (text: string) => text;\n\treturn {\n\t\theading: identity,\n\t\tlink: identity,\n\t\tlinkUrl: identity,\n\t\tcode: identity,\n\t\tcodeBlock: identity,\n\t\tcodeBlockBorder: identity,\n\t\tquote: identity,\n\t\tquoteBorder: identity,\n\t\thr: identity,\n\t\tlistBullet: identity,\n\t\tbold: identity,\n\t\titalic: identity,\n\t\tstrikethrough: identity,\n\t\tunderline: identity,\n\t};\n}\n\ntest(\"Markdown renders all lines when maxLines is not set\", () => {\n\tconst text = \"Line 1\\n\\nLine 2\\n\\nLine 3\\n\\nLine 4\\n\\nLine 5\";\n\tconst md = new Markdown(text, 0, 0, noopTheme());\n\tconst lines = md.render(80);\n\t// Each paragraph produces a line + an inter-paragraph blank line\n\tconst contentLines = lines.filter((l) => l.trim().length > 0);\n\tassert.ok(contentLines.length >= 5, `expected at least 5 content lines, got ${contentLines.length}`);\n});\n\ntest(\"Markdown truncates from the top when maxLines is exceeded\", () => {\n\tconst text = \"Line 1\\n\\nLine 2\\n\\nLine 3\\n\\nLine 4\\n\\nLine 5\";\n\tconst md = new Markdown(text, 0, 0, noopTheme());\n\tmd.maxLines = 3;\n\tconst lines = md.render(80);\n\tassert.ok(lines.length <= 3, `expected at most 3 lines, got ${lines.length}`);\n\t// First line should be the ellipsis indicator\n\tassert.ok(lines[0].includes(\"…\"), \"first line should contain ellipsis indicator\");\n\tassert.ok(lines[0].includes(\"above\"), \"first line should mention lines above\");\n});\n\ntest(\"Markdown preserves most recent content when truncating\", () => {\n\tconst text = \"First paragraph\\n\\nSecond paragraph\\n\\nThird paragraph\\n\\nFourth paragraph\\n\\nFifth paragraph\";\n\tconst md = new Markdown(text, 0, 0, noopTheme());\n\tmd.maxLines = 3;\n\tconst lines = md.render(80);\n\t// The last rendered line should contain \"Fifth paragraph\" (the most recent content)\n\tconst lastContentLine = lines.filter((l) => !l.includes(\"…\")).pop() ?? \"\";\n\tassert.ok(\n\t\tlastContentLine.includes(\"Fifth paragraph\"),\n\t\t`expected last content line to contain \"Fifth paragraph\", got \"${lastContentLine}\"`,\n\t);\n});\n\ntest(\"Markdown does not truncate when content fits within maxLines\", () => {\n\tconst text = \"Short text\";\n\tconst md = new Markdown(text, 0, 0, noopTheme());\n\tmd.maxLines = 10;\n\tconst lines = md.render(80);\n\tassert.ok(!lines.some((l) => l.includes(\"…\")), \"should not contain ellipsis when content fits\");\n\tassert.ok(lines.some((l) => l.includes(\"Short text\")), \"should contain the original text\");\n});\n\ntest(\"Markdown trims trailing empty lines\", () => {\n\tconst text = \"Some text\\n\\n\";\n\tconst md = new Markdown(text, 0, 0, noopTheme());\n\tconst lines = md.render(80);\n\t// Previous assertion was `lastLine.trim().length > 0 || lines.length === 1`\n\t// — the `|| lines.length === 1` disjunction trivially passed for any\n\t// single-line render, so a regression that returned `['']` still\n\t// passed (#4796). Assert the trim invariant directly.\n\tassert.ok(lines.length > 0, \"render must produce at least one line\");\n\tconst lastLine = lines[lines.length - 1];\n\tassert.ok(\n\t\tlastLine.trim().length > 0,\n\t\t`last line must have visible content after trim, got: ${JSON.stringify(lastLine)}`,\n\t);\n});\n"]}
|
|
@@ -55,6 +55,7 @@ export declare class Editor implements Component, Focusable {
|
|
|
55
55
|
private visualLineMapCache;
|
|
56
56
|
onSubmit?: (text: string) => void;
|
|
57
57
|
onChange?: (text: string) => void;
|
|
58
|
+
onPasteImagePath?: (filePath: string) => void;
|
|
58
59
|
disableSubmit: boolean;
|
|
59
60
|
constructor(tui: TUI, theme: EditorTheme, options?: EditorOptions);
|
|
60
61
|
getPaddingX(): number;
|
|
@@ -110,6 +111,19 @@ export declare class Editor implements Component, Focusable {
|
|
|
110
111
|
* Prevents synchronous fuzzyFind calls from blocking the event loop on every keystroke.
|
|
111
112
|
*/
|
|
112
113
|
private debouncedTriggerAutocomplete;
|
|
114
|
+
/**
|
|
115
|
+
* Image file extensions recognized when pasted as a file path.
|
|
116
|
+
*
|
|
117
|
+
* Restricted to formats commonly accepted by AI vision APIs and that have
|
|
118
|
+
* reliable magic-byte signatures for content verification. SVG is excluded
|
|
119
|
+
* (XML/JS-bearing); BMP/TIFF/HEIC/HEIF/AVIF excluded for compatibility and
|
|
120
|
+
* verification simplicity — users can convert before pasting.
|
|
121
|
+
*
|
|
122
|
+
* Detection assumes terminal emulators (iTerm2, Warp, etc.) paste a single
|
|
123
|
+
* absolute file path on drag-drop. Multi-line pastes and bare extensions
|
|
124
|
+
* are intentionally not matched.
|
|
125
|
+
*/
|
|
126
|
+
private static readonly IMAGE_EXTENSIONS;
|
|
113
127
|
private handlePaste;
|
|
114
128
|
private addNewLine;
|
|
115
129
|
private shouldSubmitOnBackslashEnter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/components/editor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/components/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -855,9 +855,28 @@ export class Editor {
|
|
|
855
855
|
this.tui.requestRender();
|
|
856
856
|
}, Editor.AUTOCOMPLETE_DEBOUNCE_MS);
|
|
857
857
|
}
|
|
858
|
+
/**
|
|
859
|
+
* Image file extensions recognized when pasted as a file path.
|
|
860
|
+
*
|
|
861
|
+
* Restricted to formats commonly accepted by AI vision APIs and that have
|
|
862
|
+
* reliable magic-byte signatures for content verification. SVG is excluded
|
|
863
|
+
* (XML/JS-bearing); BMP/TIFF/HEIC/HEIF/AVIF excluded for compatibility and
|
|
864
|
+
* verification simplicity — users can convert before pasting.
|
|
865
|
+
*
|
|
866
|
+
* Detection assumes terminal emulators (iTerm2, Warp, etc.) paste a single
|
|
867
|
+
* absolute file path on drag-drop. Multi-line pastes and bare extensions
|
|
868
|
+
* are intentionally not matched.
|
|
869
|
+
*/
|
|
870
|
+
static { this.IMAGE_EXTENSIONS = /\.(png|jpe?g|gif|webp)$/i; }
|
|
858
871
|
handlePaste(pastedText) {
|
|
859
872
|
this.historyIndex = -1; // Exit history browsing mode
|
|
860
873
|
this.lastAction = null;
|
|
874
|
+
// Detect pasted image file paths (from terminal emulators like iTerm2)
|
|
875
|
+
const trimmed = pastedText.trim();
|
|
876
|
+
if (this.onPasteImagePath && !trimmed.includes("\n") && Editor.IMAGE_EXTENSIONS.test(trimmed)) {
|
|
877
|
+
this.onPasteImagePath(trimmed);
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
861
880
|
this.pushUndoSnapshot();
|
|
862
881
|
// Clean the pasted text
|
|
863
882
|
const cleanText = pastedText.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|