@prestyj/cli 5.8.0 → 5.10.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/README.md +1 -1
- package/assets/skills/evidence-led-ui/LICENSES.md +12 -0
- package/assets/skills/evidence-led-ui/SKILL.md +15 -7
- package/assets/skills/evidence-led-ui/references/anti-defaults.md +9 -1
- package/assets/skills/evidence-led-ui/references/craft-rulings.md +33 -0
- package/assets/skills/evidence-led-ui/references/production-contract.md +41 -21
- package/assets/skills/evidence-led-ui/references/provenance.md +7 -5
- package/assets/skills/evidence-led-ui/references/quality-rubric.md +10 -10
- package/dist/app-sidecar-sessions.d.ts +8 -0
- package/dist/app-sidecar-sessions.d.ts.map +1 -0
- package/dist/app-sidecar-sessions.js +31 -0
- package/dist/app-sidecar-sessions.js.map +1 -0
- package/dist/app-sidecar-sessions.test.d.ts +2 -0
- package/dist/app-sidecar-sessions.test.d.ts.map +1 -0
- package/dist/app-sidecar-sessions.test.js +83 -0
- package/dist/app-sidecar-sessions.test.js.map +1 -0
- package/dist/app-sidecar.js +623 -120
- package/dist/app-sidecar.js.map +1 -1
- package/dist/chat-agents/general.test.js +5 -3
- package/dist/chat-agents/general.test.js.map +1 -1
- package/dist/chat-agents/memory.d.ts.map +1 -1
- package/dist/chat-agents/memory.js +14 -5
- package/dist/chat-agents/memory.js.map +1 -1
- package/dist/chat-agents/memory.test.js +11 -1
- package/dist/chat-agents/memory.test.js.map +1 -1
- package/dist/chat-agents/shared.js +1 -1
- package/dist/chat-agents/shared.js.map +1 -1
- package/dist/chat-agents/specialists.test.js +3 -2
- package/dist/chat-agents/specialists.test.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +59 -30
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +50 -2
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +61 -1
- package/dist/config.test.js.map +1 -1
- package/dist/core/agent-mcp-passthrough.test.d.ts +2 -0
- package/dist/core/agent-mcp-passthrough.test.d.ts.map +1 -0
- package/dist/core/agent-mcp-passthrough.test.js +61 -0
- package/dist/core/agent-mcp-passthrough.test.js.map +1 -0
- package/dist/core/agent-session-add-dir.test.d.ts +2 -0
- package/dist/core/agent-session-add-dir.test.d.ts.map +1 -0
- package/dist/core/agent-session-add-dir.test.js +110 -0
- package/dist/core/agent-session-add-dir.test.js.map +1 -0
- package/dist/core/agent-session-compaction.test.js +23 -7
- package/dist/core/agent-session-compaction.test.js.map +1 -1
- package/dist/core/agent-session-marker-anchors.test.d.ts +2 -0
- package/dist/core/agent-session-marker-anchors.test.d.ts.map +1 -0
- package/dist/core/agent-session-marker-anchors.test.js +147 -0
- package/dist/core/agent-session-marker-anchors.test.js.map +1 -0
- package/dist/core/agent-session-memory-tail.test.js +4 -7
- package/dist/core/agent-session-memory-tail.test.js.map +1 -1
- package/dist/core/agent-session-queue.test.js +4 -7
- package/dist/core/agent-session-queue.test.js.map +1 -1
- package/dist/core/agent-session-subagent-policy.test.js +7 -3
- package/dist/core/agent-session-subagent-policy.test.js.map +1 -1
- package/dist/core/agent-session.d.ts +46 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +177 -19
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agent-tools-allowlist.test.js +5 -3
- package/dist/core/agent-tools-allowlist.test.js.map +1 -1
- package/dist/core/agents.d.ts +12 -1
- package/dist/core/agents.d.ts.map +1 -1
- package/dist/core/agents.js +25 -1
- package/dist/core/agents.js.map +1 -1
- package/dist/core/agents.test.d.ts +2 -0
- package/dist/core/agents.test.d.ts.map +1 -0
- package/dist/core/agents.test.js +67 -0
- package/dist/core/agents.test.js.map +1 -0
- package/dist/core/auth-providers.js +1 -1
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +1 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +20 -11
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +17 -4
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/compaction/token-estimator.test.js +1 -1
- package/dist/core/compaction/token-estimator.test.js.map +1 -1
- package/dist/core/encode-cwd.d.ts +17 -0
- package/dist/core/encode-cwd.d.ts.map +1 -1
- package/dist/core/encode-cwd.js +20 -7
- package/dist/core/encode-cwd.js.map +1 -1
- package/dist/core/encode-cwd.test.js +20 -1
- package/dist/core/encode-cwd.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +5 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +6 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/goal-controller.test.js +3 -3
- package/dist/core/goal-controller.test.js.map +1 -1
- package/dist/core/ideal-review.d.ts.map +1 -1
- package/dist/core/ideal-review.js +6 -1
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/ideal-review.test.js +7 -2
- package/dist/core/ideal-review.test.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/input-normalization.test.d.ts +2 -0
- package/dist/core/input-normalization.test.d.ts.map +1 -0
- package/dist/core/input-normalization.test.js +75 -0
- package/dist/core/input-normalization.test.js.map +1 -0
- package/dist/core/local-endpoint-store.d.ts +50 -0
- package/dist/core/local-endpoint-store.d.ts.map +1 -0
- package/dist/core/local-endpoint-store.js +201 -0
- package/dist/core/local-endpoint-store.js.map +1 -0
- package/dist/core/local-endpoint-store.test.d.ts +2 -0
- package/dist/core/local-endpoint-store.test.d.ts.map +1 -0
- package/dist/core/local-endpoint-store.test.js +131 -0
- package/dist/core/local-endpoint-store.test.js.map +1 -0
- package/dist/core/loop-breaker.d.ts +38 -1
- package/dist/core/loop-breaker.d.ts.map +1 -1
- package/dist/core/loop-breaker.js +84 -2
- package/dist/core/loop-breaker.js.map +1 -1
- package/dist/core/loop-breaker.test.js +108 -1
- package/dist/core/loop-breaker.test.js.map +1 -1
- package/dist/core/lsp/client.d.ts +50 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +158 -13
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/jsonrpc.d.ts +38 -1
- package/dist/core/lsp/jsonrpc.d.ts.map +1 -1
- package/dist/core/lsp/jsonrpc.js +13 -1
- package/dist/core/lsp/jsonrpc.js.map +1 -1
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +23 -2
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/manager.test.js +32 -1
- package/dist/core/lsp/manager.test.js.map +1 -1
- package/dist/core/lsp/test-support.d.ts +18 -0
- package/dist/core/lsp/test-support.d.ts.map +1 -0
- package/dist/core/lsp/test-support.js +27 -0
- package/dist/core/lsp/test-support.js.map +1 -0
- package/dist/core/lsp/uri.test.d.ts +2 -0
- package/dist/core/lsp/uri.test.d.ts.map +1 -0
- package/dist/core/lsp/uri.test.js +56 -0
- package/dist/core/lsp/uri.test.js.map +1 -0
- package/dist/core/lsp/windows.test.d.ts +2 -0
- package/dist/core/lsp/windows.test.d.ts.map +1 -0
- package/dist/core/lsp/windows.test.js +251 -0
- package/dist/core/lsp/windows.test.js.map +1 -0
- package/dist/core/mcp/resolve-stdio.d.ts +35 -0
- package/dist/core/mcp/resolve-stdio.d.ts.map +1 -1
- package/dist/core/mcp/resolve-stdio.js +80 -1
- package/dist/core/mcp/resolve-stdio.js.map +1 -1
- package/dist/core/mcp/resolve-stdio.test.js +99 -4
- package/dist/core/mcp/resolve-stdio.test.js.map +1 -1
- package/dist/core/message-images.d.ts +12 -0
- package/dist/core/message-images.d.ts.map +1 -0
- package/dist/core/message-images.js +52 -0
- package/dist/core/message-images.js.map +1 -0
- package/dist/core/message-images.test.d.ts +2 -0
- package/dist/core/message-images.test.d.ts.map +1 -0
- package/dist/core/message-images.test.js +62 -0
- package/dist/core/message-images.test.js.map +1 -0
- package/dist/core/network-guard.d.ts +47 -0
- package/dist/core/network-guard.d.ts.map +1 -0
- package/dist/core/network-guard.js +208 -0
- package/dist/core/network-guard.js.map +1 -0
- package/dist/core/network-guard.test.d.ts +2 -0
- package/dist/core/network-guard.test.d.ts.map +1 -0
- package/dist/core/network-guard.test.js +72 -0
- package/dist/core/network-guard.test.js.map +1 -0
- package/dist/core/persistent-shell.d.ts +3 -1
- package/dist/core/persistent-shell.d.ts.map +1 -1
- package/dist/core/persistent-shell.js +13 -3
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-manager-dev-server-repro.test.js +34 -12
- package/dist/core/process-manager-dev-server-repro.test.js.map +1 -1
- package/dist/core/process-manager.d.ts +1 -1
- package/dist/core/process-manager.d.ts.map +1 -1
- package/dist/core/process-manager.js +23 -13
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/project-discovery.d.ts +8 -1
- package/dist/core/project-discovery.d.ts.map +1 -1
- package/dist/core/project-discovery.js +145 -62
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/project-discovery.test.js +131 -1
- package/dist/core/project-discovery.test.js.map +1 -1
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js +89 -156
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/prompt-commands.test.js +4 -10
- package/dist/core/prompt-commands.test.js.map +1 -1
- package/dist/core/radio.test.js +4 -1
- package/dist/core/radio.test.js.map +1 -1
- package/dist/core/runtime-mode.d.ts +2 -0
- package/dist/core/runtime-mode.d.ts.map +1 -1
- package/dist/core/runtime-mode.js +4 -0
- package/dist/core/runtime-mode.js.map +1 -1
- package/dist/core/session-export.d.ts +98 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +356 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-export.test.d.ts +2 -0
- package/dist/core/session-export.test.d.ts.map +1 -0
- package/dist/core/session-export.test.js +353 -0
- package/dist/core/session-export.test.js.map +1 -0
- package/dist/core/session-manager.d.ts +27 -7
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +257 -124
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-storage.d.ts +57 -0
- package/dist/core/session-storage.d.ts.map +1 -0
- package/dist/core/session-storage.js +592 -0
- package/dist/core/session-storage.js.map +1 -0
- package/dist/core/session-storage.test.d.ts +2 -0
- package/dist/core/session-storage.test.d.ts.map +1 -0
- package/dist/core/session-storage.test.js +272 -0
- package/dist/core/session-storage.test.js.map +1 -0
- package/dist/core/settings-manager.d.ts +7 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/setup-history.d.ts +0 -6
- package/dist/core/setup-history.d.ts.map +1 -1
- package/dist/core/setup-history.js +2 -18
- package/dist/core/setup-history.js.map +1 -1
- package/dist/core/setup-history.test.js +11 -26
- package/dist/core/setup-history.test.js.map +1 -1
- package/dist/core/sidecar-error-reporter.d.ts +12 -0
- package/dist/core/sidecar-error-reporter.d.ts.map +1 -0
- package/dist/core/sidecar-error-reporter.js +57 -0
- package/dist/core/sidecar-error-reporter.js.map +1 -0
- package/dist/core/sidecar-error-reporter.test.d.ts +2 -0
- package/dist/core/sidecar-error-reporter.test.d.ts.map +1 -0
- package/dist/core/sidecar-error-reporter.test.js +61 -0
- package/dist/core/sidecar-error-reporter.test.js.map +1 -0
- package/dist/core/skills-routing.test.js +3 -1
- package/dist/core/skills-routing.test.js.map +1 -1
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +4 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +18 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +42 -10
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/slash-commands.test.d.ts +2 -0
- package/dist/core/slash-commands.test.d.ts.map +1 -0
- package/dist/core/slash-commands.test.js +59 -0
- package/dist/core/slash-commands.test.js.map +1 -0
- package/dist/core/speed-benchmark.test.js +9 -3
- package/dist/core/speed-benchmark.test.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +8 -1
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +35 -2
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +34 -0
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/core/subagent-store.test.js +14 -2
- package/dist/core/subagent-store.test.js.map +1 -1
- package/dist/core/verify-commands.d.ts.map +1 -1
- package/dist/core/verify-commands.js +1 -6
- package/dist/core/verify-commands.js.map +1 -1
- package/dist/core/verify-commands.test.js +1 -5
- package/dist/core/verify-commands.test.js.map +1 -1
- package/dist/core/workspace-guard.d.ts +40 -0
- package/dist/core/workspace-guard.d.ts.map +1 -0
- package/dist/core/workspace-guard.js +115 -0
- package/dist/core/workspace-guard.js.map +1 -0
- package/dist/core/workspace-guard.test.d.ts +2 -0
- package/dist/core/workspace-guard.test.d.ts.map +1 -0
- package/dist/core/workspace-guard.test.js +107 -0
- package/dist/core/workspace-guard.test.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/json-mode.d.ts +7 -0
- package/dist/modes/json-mode.d.ts.map +1 -1
- package/dist/modes/json-mode.js +10 -0
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +11 -0
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/session.d.ts +4 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +38 -101
- package/dist/session.js.map +1 -1
- package/dist/session.test.d.ts +2 -0
- package/dist/session.test.d.ts.map +1 -0
- package/dist/session.test.js +35 -0
- package/dist/session.test.js.map +1 -0
- package/dist/system-prompt.d.ts +23 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +119 -31
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +154 -14
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/test-support/fake-home.d.ts +20 -0
- package/dist/test-support/fake-home.d.ts.map +1 -0
- package/dist/test-support/fake-home.js +37 -0
- package/dist/test-support/fake-home.js.map +1 -0
- package/dist/tools/bash.d.ts +4 -2
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +57 -9
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/bash.test.js +156 -8
- package/dist/tools/bash.test.js.map +1 -1
- package/dist/tools/edit-robustness.test.js +3 -1
- package/dist/tools/edit-robustness.test.js.map +1 -1
- package/dist/tools/edit.d.ts +2 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +7 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +7 -0
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/exit-plan.d.ts.map +1 -1
- package/dist/tools/exit-plan.js +15 -4
- package/dist/tools/exit-plan.js.map +1 -1
- package/dist/tools/exit-plan.test.d.ts +2 -0
- package/dist/tools/exit-plan.test.d.ts.map +1 -0
- package/dist/tools/exit-plan.test.js +72 -0
- package/dist/tools/exit-plan.test.js.map +1 -0
- package/dist/tools/find.d.ts.map +1 -1
- package/dist/tools/find.js +4 -1
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/grep.d.ts +3 -1
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +143 -14
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/grep.test.js +59 -0
- package/dist/tools/grep.test.js.map +1 -1
- package/dist/tools/index.d.ts +14 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/overflow.test.js +4 -7
- package/dist/tools/overflow.test.js.map +1 -1
- package/dist/tools/path-utils.d.ts +15 -0
- package/dist/tools/path-utils.d.ts.map +1 -1
- package/dist/tools/path-utils.js +17 -0
- package/dist/tools/path-utils.js.map +1 -1
- package/dist/tools/path-utils.test.js +7 -2
- package/dist/tools/path-utils.test.js.map +1 -1
- package/dist/tools/prompt-hints.js +1 -1
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/screenshot.js +1 -1
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/search-code.d.ts.map +1 -1
- package/dist/tools/search-code.js +6 -4
- package/dist/tools/search-code.js.map +1 -1
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +4 -2
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/source-path.d.ts.map +1 -1
- package/dist/tools/source-path.js +9 -0
- package/dist/tools/source-path.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +1 -1
- package/dist/tools/subagent-shared.d.ts.map +1 -1
- package/dist/tools/subagent-shared.js +4 -1
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent-shared.test.js +21 -1
- package/dist/tools/subagent-shared.test.js.map +1 -1
- package/dist/tools/subagent.d.ts +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +8 -0
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/web-fetch.d.ts +2 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +17 -6
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-fetch.test.js +34 -0
- package/dist/tools/web-fetch.test.js.map +1 -1
- package/dist/tools/web-search.d.ts +2 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +34 -7
- package/dist/tools/web-search.js.map +1 -1
- package/dist/tools/write.d.ts +2 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +7 -1
- package/dist/tools/write.js.map +1 -1
- package/dist/tools/write.test.js +12 -0
- package/dist/tools/write.test.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +22 -85
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/app-items.d.ts +11 -12
- package/dist/ui/app-items.d.ts.map +1 -1
- package/dist/ui/app-items.js +10 -0
- package/dist/ui/app-items.js.map +1 -1
- package/dist/ui/components/ActivityIndicator.d.ts.map +1 -1
- package/dist/ui/components/ActivityIndicator.js +1 -0
- package/dist/ui/components/ActivityIndicator.js.map +1 -1
- package/dist/ui/components/Footer.d.ts +1 -1
- package/dist/ui/components/Footer.js +2 -2
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/Footer.test.js +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +5 -2
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +49 -8
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/hooks/usePixelFixFlow.d.ts +1 -2
- package/dist/ui/hooks/usePixelFixFlow.d.ts.map +1 -1
- package/dist/ui/hooks/usePixelFixFlow.js +2 -5
- package/dist/ui/hooks/usePixelFixFlow.js.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts +8 -5
- package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.js +2 -30
- package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
- package/dist/ui/login.js +1 -1
- package/dist/ui/login.js.map +1 -1
- package/dist/ui/terminal-history-status-renderers.d.ts +1 -2
- package/dist/ui/terminal-history-status-renderers.d.ts.map +1 -1
- package/dist/ui/terminal-history-status-renderers.js +2 -15
- package/dist/ui/terminal-history-status-renderers.js.map +1 -1
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +2 -4
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/ui/thinking-level-cycle.test.js +8 -8
- package/dist/ui/thinking-level-cycle.test.js.map +1 -1
- package/dist/ui/transcript/MiscRows.d.ts +1 -4
- package/dist/ui/transcript/MiscRows.d.ts.map +1 -1
- package/dist/ui/transcript/MiscRows.js +2 -7
- package/dist/ui/transcript/MiscRows.js.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
- package/dist/ui/transcript/TranscriptRenderer.js +1 -3
- package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
- package/dist/ui/transcript/presentation.d.ts +1 -9
- package/dist/ui/transcript/presentation.d.ts.map +1 -1
- package/dist/ui/transcript/presentation.js +0 -9
- package/dist/ui/transcript/presentation.js.map +1 -1
- package/dist/ui/transcript/spacing.d.ts +2 -2
- package/dist/ui/transcript/spacing.d.ts.map +1 -1
- package/dist/ui/transcript/spacing.js +0 -1
- package/dist/ui/transcript/spacing.js.map +1 -1
- package/dist/ui/transcript/spacing.test.js +1 -3
- package/dist/ui/transcript/spacing.test.js.map +1 -1
- package/dist/ui/tui-history-parity.test.js +2 -9
- package/dist/ui/tui-history-parity.test.js.map +1 -1
- package/dist/utils/github.d.ts +20 -0
- package/dist/utils/github.d.ts.map +1 -0
- package/dist/utils/github.js +65 -0
- package/dist/utils/github.js.map +1 -0
- package/dist/utils/github.test.d.ts +2 -0
- package/dist/utils/github.test.d.ts.map +1 -0
- package/dist/utils/github.test.js +23 -0
- package/dist/utils/github.test.js.map +1 -0
- package/dist/utils/http-body.d.ts +19 -0
- package/dist/utils/http-body.d.ts.map +1 -0
- package/dist/utils/http-body.js +58 -0
- package/dist/utils/http-body.js.map +1 -0
- package/dist/utils/http-body.test.d.ts +2 -0
- package/dist/utils/http-body.test.d.ts.map +1 -0
- package/dist/utils/http-body.test.js +68 -0
- package/dist/utils/http-body.test.js.map +1 -0
- package/dist/utils/process.d.ts +26 -3
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +68 -10
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/process.test.d.ts +2 -0
- package/dist/utils/process.test.d.ts.map +1 -0
- package/dist/utils/process.test.js +42 -0
- package/dist/utils/process.test.js.map +1 -0
- package/dist/utils/text.d.ts +9 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +11 -0
- package/dist/utils/text.js.map +1 -0
- package/package.json +4 -4
|
@@ -5,7 +5,10 @@ import path from "node:path";
|
|
|
5
5
|
import { ProcessManager } from "./process-manager.js";
|
|
6
6
|
async function waitForOutput(manager, id, predicate) {
|
|
7
7
|
let combined = "";
|
|
8
|
-
|
|
8
|
+
// 200 x 100ms = 20s. The old 5s budget was enough on a developer machine but
|
|
9
|
+
// not on a loaded Windows CI runner, where spawning node and binding a port
|
|
10
|
+
// is markedly slower — the test failed there on timing, not behavior.
|
|
11
|
+
for (let i = 0; i < 200; i += 1) {
|
|
9
12
|
const result = await manager.readOutput(id);
|
|
10
13
|
combined += result.output;
|
|
11
14
|
if (predicate(combined))
|
|
@@ -79,8 +82,12 @@ describe("ProcessManager dev-server lifecycle repro", () => {
|
|
|
79
82
|
process.env.GG_TEST_SHOULD_NOT_LEAK = oldSecret;
|
|
80
83
|
}
|
|
81
84
|
});
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
// Windows has no process groups: signalling the wrapper leaves its whole
|
|
86
|
+
// descendant tree (the dev server everyone actually wants dead) running. So
|
|
87
|
+
// stop() force-kills the PID tree with taskkill FIRST, and reports honestly
|
|
88
|
+
// when the process is still alive after the 5s grace window.
|
|
89
|
+
it("force-kills the PID tree with taskkill on Windows", async () => {
|
|
90
|
+
const taskkill = vi.fn().mockReturnValue({ status: 1 });
|
|
84
91
|
manager = new ProcessManager({
|
|
85
92
|
platform: "win32",
|
|
86
93
|
kill: vi.fn(() => {
|
|
@@ -92,11 +99,10 @@ describe("ProcessManager dev-server lifecycle repro", () => {
|
|
|
92
99
|
const started = await manager.start(`${JSON.stringify(process.execPath)} -e "setInterval(()=>{},1000)"`, tmpDir);
|
|
93
100
|
try {
|
|
94
101
|
const stopped = await manager.stop(started.id);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
expect(
|
|
98
|
-
|
|
99
|
-
});
|
|
102
|
+
// The mocked taskkill never really kills the child, so the 5s window
|
|
103
|
+
// elapses and the user is told the truth instead of "stopped".
|
|
104
|
+
expect(stopped).toContain("Failed to stop process");
|
|
105
|
+
expect(taskkill).toHaveBeenCalledWith(expect.stringMatching(/taskkill\.exe$/), ["/PID", String(started.pid), "/T", "/F"], expect.objectContaining({ stdio: "ignore", windowsHide: true }));
|
|
100
106
|
}
|
|
101
107
|
finally {
|
|
102
108
|
// This test deliberately mocks `kill` and `spawnSync`, so neither the
|
|
@@ -105,7 +111,8 @@ describe("ProcessManager dev-server lifecycle repro", () => {
|
|
|
105
111
|
// this suite orphans a live `node -e setInterval` process forever.
|
|
106
112
|
killRealProcessTree(started.pid);
|
|
107
113
|
}
|
|
108
|
-
|
|
114
|
+
// stop() waits out its full 5s grace window before reporting failure.
|
|
115
|
+
}, 45_000);
|
|
109
116
|
it("starts, reads, and stops a long-running Node HTTP server through the worker background path", async () => {
|
|
110
117
|
manager = new ProcessManager();
|
|
111
118
|
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "gg-dev-server-repro-"));
|
|
@@ -122,7 +129,11 @@ describe("ProcessManager dev-server lifecycle repro", () => {
|
|
|
122
129
|
` clearInterval(interval);\n` +
|
|
123
130
|
` server.close(() => process.exit(0));\n` +
|
|
124
131
|
`});\n`);
|
|
125
|
-
|
|
132
|
+
// Both paths MUST be quoted. Unquoted, bash eats the backslashes in a
|
|
133
|
+
// Windows path: `C:\hostedtoolcache\…\node.exe` reached the shell as
|
|
134
|
+
// `C:hostedtoolcache…node.exe` and failed with "command not found". Every
|
|
135
|
+
// other manager.start call in this file already quotes; this one did not.
|
|
136
|
+
const started = await manager.start(`${JSON.stringify(process.execPath)} ${JSON.stringify(fixture)}`, tmpDir);
|
|
126
137
|
expect(started.pid).toBeGreaterThan(0);
|
|
127
138
|
expect(started.logFile).toMatch(/\.log$/);
|
|
128
139
|
const initial = await waitForOutput(manager, started.id, (output) => output.includes("DEV_SERVER_READY"));
|
|
@@ -136,8 +147,19 @@ describe("ProcessManager dev-server lifecycle repro", () => {
|
|
|
136
147
|
const final = await manager.readOutput(started.id, true);
|
|
137
148
|
expect(final.isRunning).toBe(false);
|
|
138
149
|
expect(final.exitCode).not.toBeNull();
|
|
139
|
-
|
|
140
|
-
|
|
150
|
+
if (process.platform === "win32") {
|
|
151
|
+
// Windows has no SIGTERM. `stop()` force-kills the PID tree with taskkill
|
|
152
|
+
// /F precisely because there is no process group and no graceful signal
|
|
153
|
+
// to send, so a SIGTERM handler CANNOT run and the server gets no chance
|
|
154
|
+
// to clean up. That is a real, unavoidable platform difference — what
|
|
155
|
+
// matters (asserted above) is that the process and its children are
|
|
156
|
+
// genuinely dead, which is the failure mode users actually hit.
|
|
157
|
+
expect(final.output).toContain("DEV_SERVER_READY");
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
expect(final.output).toContain("DEV_SERVER_SIGTERM");
|
|
161
|
+
}
|
|
162
|
+
}, 45_000);
|
|
141
163
|
const posixIt = process.platform === "win32" ? it.skip : it;
|
|
142
164
|
posixIt("kills the whole detached process group on POSIX/WSL shutdown", async () => {
|
|
143
165
|
manager = new ProcessManager();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager-dev-server-repro.test.js","sourceRoot":"","sources":["../../src/core/process-manager-dev-server-repro.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,KAAK,UAAU,aAAa,CAC1B,OAAuB,EACvB,EAAU,EACV,SAAsC;IAEtC,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"process-manager-dev-server-repro.test.js","sourceRoot":"","sources":["../../src/core/process-manager-dev-server-repro.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/core/process-manager.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/core/process-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAWpD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IAC3B,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;CAC9B;AAWD,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHhC,OAAO,CAAC,SAAS,CAAwC;IACzD,OAAO,CAAC,QAAQ,CAAmC;gBAEtB,GAAG,GAAE,iBAAsB;IAElD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiDzD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAgC5E;;;;;OAKG;IACG,SAAS,CACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,OAAO,CAAA;KAAO,GAC5C,OAAO,CAAC,MAAM,CAAC;IAoCZ,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CvC,IAAI,IAAI,iBAAiB,EAAE;IAW3B,WAAW,IAAI,IAAI;CASpB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { spawn
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import fsp from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
@@ -9,13 +9,12 @@ import { getSafeToolEnv } from "../tools/safe-env.js";
|
|
|
9
9
|
import { resolveShell } from "./shell.js";
|
|
10
10
|
const BG_DIR = path.join(os.homedir(), ".ezcoder", "bg");
|
|
11
11
|
function stopProcessTree(pid, ops = {}) {
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
stdio: "ignore",
|
|
15
|
-
});
|
|
12
|
+
if (ops.killProcessTree) {
|
|
13
|
+
ops.killProcessTree(pid);
|
|
16
14
|
return;
|
|
17
15
|
}
|
|
18
|
-
|
|
16
|
+
// killProcessTree is itself platform-aware (taskkill /T /F on Windows).
|
|
17
|
+
killProcessTree(pid, { platform: ops.platform, kill: ops.kill, spawnSync: ops.spawnSync });
|
|
19
18
|
}
|
|
20
19
|
export class ProcessManager {
|
|
21
20
|
ops;
|
|
@@ -139,19 +138,27 @@ export class ProcessManager {
|
|
|
139
138
|
if (!child || proc.exitCode !== null) {
|
|
140
139
|
return `Process ${id} already exited (code ${proc.exitCode})`;
|
|
141
140
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
const isWindows = (this.ops.platform ?? process.platform) === "win32";
|
|
142
|
+
if (isWindows) {
|
|
143
|
+
// Windows has no process groups and no real SIGTERM: signalling the
|
|
144
|
+
// wrapper only orphans its descendants. Force-kill the PID tree up front.
|
|
145
|
+
stopProcessTree(proc.pid, this.ops);
|
|
145
146
|
}
|
|
146
|
-
|
|
147
|
+
else {
|
|
148
|
+
// SIGTERM the group first so POSIX children get a chance to clean up.
|
|
147
149
|
try {
|
|
148
|
-
(this.ops.kill ?? process.kill)(proc.pid, "SIGTERM");
|
|
150
|
+
(this.ops.kill ?? process.kill)(-proc.pid, "SIGTERM");
|
|
149
151
|
}
|
|
150
152
|
catch {
|
|
151
|
-
|
|
153
|
+
try {
|
|
154
|
+
(this.ops.kill ?? process.kill)(proc.pid, "SIGTERM");
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return `Process ${id} already exited`;
|
|
158
|
+
}
|
|
152
159
|
}
|
|
153
160
|
}
|
|
154
|
-
// Wait up to 5s, then
|
|
161
|
+
// Wait up to 5s, then hard-kill a surviving tree.
|
|
155
162
|
const exited = await new Promise((resolve) => {
|
|
156
163
|
const timeout = setTimeout(() => resolve(false), 5000);
|
|
157
164
|
child.on("close", () => {
|
|
@@ -160,6 +167,9 @@ export class ProcessManager {
|
|
|
160
167
|
});
|
|
161
168
|
});
|
|
162
169
|
if (!exited) {
|
|
170
|
+
if (isWindows) {
|
|
171
|
+
return `Failed to stop process ${id}: it did not exit within 5 seconds and may still be running.`;
|
|
172
|
+
}
|
|
163
173
|
stopProcessTree(proc.pid, this.ops);
|
|
164
174
|
}
|
|
165
175
|
return `Process ${id} stopped`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/core/process-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-manager.js","sourceRoot":"","sources":["../../src/core/process-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,10 +14,17 @@ export interface DiscoveredProject {
|
|
|
14
14
|
* show a combined badge.
|
|
15
15
|
*/
|
|
16
16
|
export declare function discoverProjects(): Promise<DiscoveredProject[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Is `value` an absolute path on any platform?
|
|
19
|
+
*
|
|
20
|
+
* `path.isAbsolute` is platform-bound, but a portable session store can contain
|
|
21
|
+
* Windows drive/UNC paths or POSIX paths regardless of the current host.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isAbsoluteCwd(value: string): boolean;
|
|
17
24
|
export interface RecentSession {
|
|
18
25
|
/** Session id. */
|
|
19
26
|
id: string;
|
|
20
|
-
/** Absolute path to
|
|
27
|
+
/** Absolute resumable path to a plain or gzip EZ Coder session. */
|
|
21
28
|
path: string;
|
|
22
29
|
/** Legacy saved label, falling back to the first real user prompt. */
|
|
23
30
|
preview: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../src/core/project-discovery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../src/core/project-discovery.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA6BrE;AA2DD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AA+VD,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,KAAK,SAAI,EACT,WAAW,SAA4B,GACtC,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB1B"}
|
|
@@ -4,8 +4,9 @@ import readline from "node:readline";
|
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { getAppPaths } from "../config.js";
|
|
7
|
-
import { encodeCwd } from "./encode-cwd.js";
|
|
7
|
+
import { encodeCwd, stripExtendedLengthPrefix } from "./encode-cwd.js";
|
|
8
8
|
import { getUserSessionPrompt } from "./session-preview.js";
|
|
9
|
+
import { isSessionPath, openSessionReadStream, resolveSessionPath } from "./session-storage.js";
|
|
9
10
|
/**
|
|
10
11
|
* Scan ezcoder + Claude Code + Codex session stores and return one row per
|
|
11
12
|
* project, sorted most-recent first. Duplicates (same cwd) are collapsed; the
|
|
@@ -70,15 +71,18 @@ async function discoverEzcoderProjects() {
|
|
|
70
71
|
const results = [];
|
|
71
72
|
for (const entry of entries) {
|
|
72
73
|
const dir = path.join(sessionsDir, entry);
|
|
73
|
-
const mtime = await
|
|
74
|
+
const mtime = await maxGgcoderSessionMtime(dir);
|
|
74
75
|
if (mtime === null)
|
|
75
76
|
continue;
|
|
76
|
-
const rawCwd = (await
|
|
77
|
+
const rawCwd = (await readFirstFromGgcoderDir(dir, ezcoderCwdExtractor)) ?? fallbackUnderscoreDecode(entry);
|
|
77
78
|
if (!rawCwd)
|
|
78
79
|
continue;
|
|
79
80
|
// Normalize traversal segments (e.g. an agent launched with cwd
|
|
80
|
-
// `.../src-tauri/../..`) so the basename isn't a stray ".."
|
|
81
|
-
|
|
81
|
+
// `.../src-tauri/../..`) so the basename isn't a stray "..", and drop any
|
|
82
|
+
// Windows extended-length prefix so a session recorded as `\\?\C:\proj`
|
|
83
|
+
// (what Rust's canonicalize used to hand the sidecar) resolves to the same
|
|
84
|
+
// project as a plain `C:\proj` instead of listing a prefixed duplicate.
|
|
85
|
+
const cwd = path.resolve(stripExtendedLengthPrefix(rawCwd));
|
|
82
86
|
if (!(await isDirectory(cwd)))
|
|
83
87
|
continue;
|
|
84
88
|
results.push({
|
|
@@ -92,12 +96,32 @@ async function discoverEzcoderProjects() {
|
|
|
92
96
|
return results;
|
|
93
97
|
}
|
|
94
98
|
/**
|
|
95
|
-
*
|
|
99
|
+
* Is `value` an absolute path on any platform?
|
|
100
|
+
*
|
|
101
|
+
* `path.isAbsolute` is platform-bound, but a portable session store can contain
|
|
102
|
+
* Windows drive/UNC paths or POSIX paths regardless of the current host.
|
|
103
|
+
*/
|
|
104
|
+
export function isAbsoluteCwd(value) {
|
|
105
|
+
return path.posix.isAbsolute(value) || path.win32.isAbsolute(value);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Best-effort decode of an ezcoder session directory name back to a cwd, used
|
|
96
109
|
* only when the session files carry no `cwd` header. Lossy by design (literal
|
|
97
110
|
* underscores are indistinguishable from separators); the caller still verifies
|
|
98
111
|
* the result is an existing directory.
|
|
112
|
+
*
|
|
113
|
+
* `encodeCwd` drops the drive colon (`C:\a\b` → `C_a_b`), so on Windows we
|
|
114
|
+
* re-attach it for a leading single-letter segment; otherwise a decoded
|
|
115
|
+
* `/C/a/b` names a directory that never exists and the project disappears.
|
|
99
116
|
*/
|
|
100
117
|
function fallbackUnderscoreDecode(entry) {
|
|
118
|
+
if (process.platform === "win32") {
|
|
119
|
+
const parts = entry.split("_");
|
|
120
|
+
if (parts.length > 1 && /^[A-Za-z]$/.test(parts[0])) {
|
|
121
|
+
return `${parts[0]}:\\${parts.slice(1).join("\\")}`;
|
|
122
|
+
}
|
|
123
|
+
return entry.replace(/_/g, "\\");
|
|
124
|
+
}
|
|
101
125
|
return "/" + entry.replace(/_/g, "/");
|
|
102
126
|
}
|
|
103
127
|
/**
|
|
@@ -196,6 +220,14 @@ async function maxJsonlMtime(dir) {
|
|
|
196
220
|
max = f.mtime;
|
|
197
221
|
return max > 0 ? max : null;
|
|
198
222
|
}
|
|
223
|
+
async function maxGgcoderSessionMtime(dir) {
|
|
224
|
+
if (!(await isDirectory(dir)))
|
|
225
|
+
return null;
|
|
226
|
+
const files = await collectGgcoderSessionFiles(dir, 2);
|
|
227
|
+
if (files.length === 0)
|
|
228
|
+
return null;
|
|
229
|
+
return Math.max(...files.map((file) => file.mtime));
|
|
230
|
+
}
|
|
199
231
|
/**
|
|
200
232
|
* Walk `dir` up to `maxDepth` levels deep collecting every .jsonl file. Used
|
|
201
233
|
* for both Claude Code (top-level + `<uuid>/subagents/`) and Codex
|
|
@@ -230,10 +262,40 @@ async function collectJsonlFiles(dir, maxDepth) {
|
|
|
230
262
|
}
|
|
231
263
|
}
|
|
232
264
|
}
|
|
265
|
+
async function collectGgcoderSessionFiles(dir, maxDepth) {
|
|
266
|
+
const byResolvedPath = new Map();
|
|
267
|
+
await walk(dir, 0);
|
|
268
|
+
return [...byResolvedPath.values()];
|
|
269
|
+
async function walk(current, depth) {
|
|
270
|
+
let entries;
|
|
271
|
+
try {
|
|
272
|
+
entries = await fs.readdir(current, { withFileTypes: true });
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
for (const entry of entries) {
|
|
278
|
+
const fullPath = path.join(current, entry.name);
|
|
279
|
+
if (entry.isFile() && isSessionPath(entry.name)) {
|
|
280
|
+
try {
|
|
281
|
+
const resolvedPath = await resolveSessionPath(fullPath);
|
|
282
|
+
const stat = await fs.stat(resolvedPath);
|
|
283
|
+
byResolvedPath.set(resolvedPath, { path: resolvedPath, mtime: stat.mtimeMs });
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
// Ignore malformed redirects, incomplete archives, and raced files.
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else if (entry.isDirectory() && depth < maxDepth && !entry.name.endsWith(".assets")) {
|
|
290
|
+
await walk(fullPath, depth + 1);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
233
295
|
const claudeCwdExtractor = (line) => {
|
|
234
296
|
try {
|
|
235
297
|
const parsed = JSON.parse(line);
|
|
236
|
-
if (typeof parsed.cwd === "string" && parsed.cwd
|
|
298
|
+
if (typeof parsed.cwd === "string" && isAbsoluteCwd(parsed.cwd))
|
|
237
299
|
return parsed.cwd;
|
|
238
300
|
}
|
|
239
301
|
catch {
|
|
@@ -248,7 +310,7 @@ const claudeCwdExtractor = (line) => {
|
|
|
248
310
|
const ezcoderCwdExtractor = (line) => {
|
|
249
311
|
try {
|
|
250
312
|
const parsed = JSON.parse(line);
|
|
251
|
-
if (parsed.type === "session" && typeof parsed.cwd === "string" && parsed.cwd
|
|
313
|
+
if (parsed.type === "session" && typeof parsed.cwd === "string" && isAbsoluteCwd(parsed.cwd)) {
|
|
252
314
|
return parsed.cwd;
|
|
253
315
|
}
|
|
254
316
|
}
|
|
@@ -265,7 +327,7 @@ const codexCwdExtractor = (line) => {
|
|
|
265
327
|
try {
|
|
266
328
|
const parsed = JSON.parse(line);
|
|
267
329
|
const cwd = parsed.payload?.cwd;
|
|
268
|
-
if (typeof cwd === "string" && cwd
|
|
330
|
+
if (typeof cwd === "string" && isAbsoluteCwd(cwd))
|
|
269
331
|
return cwd;
|
|
270
332
|
}
|
|
271
333
|
catch {
|
|
@@ -274,14 +336,13 @@ const codexCwdExtractor = (line) => {
|
|
|
274
336
|
// Legacy format (pre-late-2025): cwd embedded as <cwd>...</cwd> inside an
|
|
275
337
|
// <environment_context> user-message string.
|
|
276
338
|
const m = CODEX_CWD_RE.exec(line);
|
|
277
|
-
if (m && m[1] && m[1]
|
|
339
|
+
if (m && m[1] && isAbsoluteCwd(m[1]))
|
|
278
340
|
return m[1];
|
|
279
341
|
return null;
|
|
280
342
|
};
|
|
281
343
|
/**
|
|
282
|
-
* Walk all
|
|
283
|
-
* extractor result.
|
|
284
|
-
* layout).
|
|
344
|
+
* Walk all plain Claude/Codex JSONL files under `dir` newest-first, returning
|
|
345
|
+
* the first non-null extractor result.
|
|
285
346
|
*/
|
|
286
347
|
async function readFirstFromJsonlDir(dir, extractor) {
|
|
287
348
|
const files = await collectJsonlFiles(dir, 2);
|
|
@@ -295,6 +356,28 @@ async function readFirstFromJsonlDir(dir, extractor) {
|
|
|
295
356
|
}
|
|
296
357
|
return null;
|
|
297
358
|
}
|
|
359
|
+
async function readFirstFromGgcoderDir(dir, extractor) {
|
|
360
|
+
const files = await collectGgcoderSessionFiles(dir, 2);
|
|
361
|
+
files.sort((a, b) => b.mtime - a.mtime);
|
|
362
|
+
for (const file of files) {
|
|
363
|
+
try {
|
|
364
|
+
const { stream } = await openSessionReadStream(file.path);
|
|
365
|
+
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
366
|
+
let lines = 0;
|
|
367
|
+
for await (const line of rl) {
|
|
368
|
+
if (++lines > 200)
|
|
369
|
+
break;
|
|
370
|
+
const value = extractor(line);
|
|
371
|
+
if (value)
|
|
372
|
+
return value;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// A corrupt archive must not hide otherwise valid projects in this store.
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
298
381
|
/**
|
|
299
382
|
* Stream `file` line-by-line and return the first non-null extractor result.
|
|
300
383
|
* Caps lines so a giant transcript can't stall discovery.
|
|
@@ -339,7 +422,15 @@ function fallbackDashDecode(entry) {
|
|
|
339
422
|
// result is an existing directory.
|
|
340
423
|
if (!entry.startsWith("-"))
|
|
341
424
|
return null;
|
|
342
|
-
|
|
425
|
+
const body = entry.slice(1);
|
|
426
|
+
if (process.platform === "win32") {
|
|
427
|
+
// Claude Code on Windows encodes `C:\a\b` as `C--a-b` (drive colon → dash).
|
|
428
|
+
const drive = /^([A-Za-z])--(.*)$/.exec(body);
|
|
429
|
+
if (drive)
|
|
430
|
+
return `${drive[1]}:\\${drive[2].replace(/-/g, "\\")}`;
|
|
431
|
+
return body.replace(/-/g, "\\");
|
|
432
|
+
}
|
|
433
|
+
return "/" + body.replace(/-/g, "/");
|
|
343
434
|
}
|
|
344
435
|
function formatRelativeTime(ms) {
|
|
345
436
|
if (ms === 0)
|
|
@@ -373,7 +464,7 @@ function formatRelativeTime(ms) {
|
|
|
373
464
|
*/
|
|
374
465
|
export async function listRecentSessions(cwd, limit = 5, sessionsDir = getAppPaths().sessionsDir) {
|
|
375
466
|
const dir = path.join(sessionsDir, encodeCwd(cwd));
|
|
376
|
-
const files = await
|
|
467
|
+
const files = await collectGgcoderSessionFiles(dir, 1);
|
|
377
468
|
if (files.length === 0)
|
|
378
469
|
return [];
|
|
379
470
|
files.sort((a, b) => b.mtime - a.mtime);
|
|
@@ -395,8 +486,8 @@ export async function listRecentSessions(cwd, limit = 5, sessionsDir = getAppPat
|
|
|
395
486
|
}
|
|
396
487
|
/** Single-pass parse of one session file: identity + count + activity + preview. */
|
|
397
488
|
async function readSessionSummary(file) {
|
|
398
|
-
|
|
399
|
-
const
|
|
489
|
+
try {
|
|
490
|
+
const { path: resolvedPath, stream } = await openSessionReadStream(file);
|
|
400
491
|
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
401
492
|
let id = "";
|
|
402
493
|
let conversationId = "";
|
|
@@ -406,64 +497,56 @@ async function readSessionSummary(file) {
|
|
|
406
497
|
let preview = "";
|
|
407
498
|
let label = "";
|
|
408
499
|
let valid = false;
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return;
|
|
413
|
-
done = true;
|
|
414
|
-
resolve(valid
|
|
415
|
-
? {
|
|
416
|
-
id,
|
|
417
|
-
conversationId: conversationId || id,
|
|
418
|
-
path: file,
|
|
419
|
-
preview: label || headerPreview || preview,
|
|
420
|
-
lastActiveDisplay: rel(lastActivity),
|
|
421
|
-
messageCount,
|
|
422
|
-
}
|
|
423
|
-
: null);
|
|
424
|
-
rl.close();
|
|
425
|
-
stream.destroy();
|
|
426
|
-
};
|
|
427
|
-
rl.on("line", (line) => {
|
|
428
|
-
if (done || !line)
|
|
429
|
-
return;
|
|
500
|
+
for await (const line of rl) {
|
|
501
|
+
if (!line)
|
|
502
|
+
continue;
|
|
430
503
|
try {
|
|
431
|
-
const
|
|
504
|
+
const entry = JSON.parse(line);
|
|
432
505
|
if (!valid) {
|
|
433
|
-
if (
|
|
434
|
-
return
|
|
506
|
+
if (entry.type !== "session")
|
|
507
|
+
return null;
|
|
435
508
|
valid = true;
|
|
436
|
-
id =
|
|
437
|
-
conversationId =
|
|
438
|
-
if (typeof
|
|
439
|
-
headerPreview =
|
|
509
|
+
id = entry.id ?? "";
|
|
510
|
+
conversationId = entry.conversationId ?? id;
|
|
511
|
+
if (typeof entry.preview === "string") {
|
|
512
|
+
headerPreview = entry.preview.replace(/\s+/g, " ").trim().slice(0, 80);
|
|
440
513
|
}
|
|
441
|
-
if (
|
|
442
|
-
lastActivity =
|
|
443
|
-
|
|
514
|
+
if (entry.timestamp)
|
|
515
|
+
lastActivity = entry.timestamp;
|
|
516
|
+
continue;
|
|
444
517
|
}
|
|
445
|
-
if (
|
|
446
|
-
label =
|
|
518
|
+
if (entry.type === "label" && typeof entry.label === "string" && entry.label.trim()) {
|
|
519
|
+
label = entry.label.replace(/\s+/g, " ").trim().slice(0, 80);
|
|
447
520
|
}
|
|
448
|
-
else if (
|
|
449
|
-
messageCount
|
|
450
|
-
if (
|
|
451
|
-
lastActivity =
|
|
452
|
-
if (!preview &&
|
|
453
|
-
const text = getUserSessionPrompt(
|
|
521
|
+
else if (entry.type === "message") {
|
|
522
|
+
messageCount += 1;
|
|
523
|
+
if (entry.timestamp)
|
|
524
|
+
lastActivity = entry.timestamp;
|
|
525
|
+
if (!preview && entry.message?.role === "user") {
|
|
526
|
+
const text = getUserSessionPrompt(entry.message.content);
|
|
454
527
|
if (text)
|
|
455
528
|
preview = text.replace(/\s+/g, " ").trim().slice(0, 80);
|
|
456
529
|
}
|
|
457
530
|
}
|
|
458
531
|
}
|
|
459
532
|
catch {
|
|
460
|
-
//
|
|
533
|
+
// Skip malformed lines; archive migration preserves them byte-for-byte.
|
|
461
534
|
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
535
|
+
}
|
|
536
|
+
return valid
|
|
537
|
+
? {
|
|
538
|
+
id,
|
|
539
|
+
conversationId: conversationId || id,
|
|
540
|
+
path: resolvedPath,
|
|
541
|
+
preview: label || headerPreview || preview,
|
|
542
|
+
lastActiveDisplay: rel(lastActivity),
|
|
543
|
+
messageCount,
|
|
544
|
+
}
|
|
545
|
+
: null;
|
|
546
|
+
}
|
|
547
|
+
catch {
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
467
550
|
}
|
|
468
551
|
function rel(timestamp) {
|
|
469
552
|
return formatRelativeTime(Date.parse(timestamp) || 0);
|