@prestyj/cli 5.10.0 → 5.11.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 +3 -4
- package/dist/app-sidecar-auth-broadcast.test.d.ts +2 -0
- package/dist/app-sidecar-auth-broadcast.test.d.ts.map +1 -0
- package/dist/app-sidecar-auth-broadcast.test.js +282 -0
- package/dist/app-sidecar-auth-broadcast.test.js.map +1 -0
- package/dist/app-sidecar-sessions.d.ts +5 -2
- package/dist/app-sidecar-sessions.d.ts.map +1 -1
- package/dist/app-sidecar-sessions.js +34 -8
- package/dist/app-sidecar-sessions.js.map +1 -1
- package/dist/app-sidecar-sessions.test.js +95 -0
- package/dist/app-sidecar-sessions.test.js.map +1 -1
- package/dist/app-sidecar.js +497 -128
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli/command-routing.d.ts +1 -1
- package/dist/cli/command-routing.d.ts.map +1 -1
- package/dist/cli/command-routing.js +1 -0
- package/dist/cli/command-routing.js.map +1 -1
- package/dist/cli/command-routing.test.js +1 -0
- package/dist/cli/command-routing.test.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +167 -47
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +10 -1
- package/dist/config.test.js.map +1 -1
- package/dist/core/agent-notifications.d.ts +62 -0
- package/dist/core/agent-notifications.d.ts.map +1 -0
- package/dist/core/agent-notifications.js +92 -0
- package/dist/core/agent-notifications.js.map +1 -0
- package/dist/core/agent-notifications.test.d.ts +2 -0
- package/dist/core/agent-notifications.test.d.ts.map +1 -0
- package/dist/core/agent-notifications.test.js +97 -0
- package/dist/core/agent-notifications.test.js.map +1 -0
- package/dist/core/agent-session-checkpoint-flush.test.d.ts +2 -0
- package/dist/core/agent-session-checkpoint-flush.test.d.ts.map +1 -0
- package/dist/core/agent-session-checkpoint-flush.test.js +201 -0
- package/dist/core/agent-session-checkpoint-flush.test.js.map +1 -0
- package/dist/core/agent-session-compaction.test.js +323 -6
- package/dist/core/agent-session-compaction.test.js.map +1 -1
- package/dist/core/agent-session-crash-durability.test.d.ts +2 -0
- package/dist/core/agent-session-crash-durability.test.d.ts.map +1 -0
- package/dist/core/agent-session-crash-durability.test.js +102 -0
- package/dist/core/agent-session-crash-durability.test.js.map +1 -0
- package/dist/core/agent-session-marker-anchors.test.js +181 -2
- package/dist/core/agent-session-marker-anchors.test.js.map +1 -1
- package/dist/core/agent-session-model-switch.test.d.ts +2 -0
- package/dist/core/agent-session-model-switch.test.d.ts.map +1 -0
- package/dist/core/agent-session-model-switch.test.js +161 -0
- package/dist/core/agent-session-model-switch.test.js.map +1 -0
- package/dist/core/agent-session-notifications.test.d.ts +2 -0
- package/dist/core/agent-session-notifications.test.d.ts.map +1 -0
- package/dist/core/agent-session-notifications.test.js +114 -0
- package/dist/core/agent-session-notifications.test.js.map +1 -0
- package/dist/core/agent-session-process-gate.test.d.ts +2 -0
- package/dist/core/agent-session-process-gate.test.d.ts.map +1 -0
- package/dist/core/agent-session-process-gate.test.js +92 -0
- package/dist/core/agent-session-process-gate.test.js.map +1 -0
- package/dist/core/agent-session-queue.test.js +65 -0
- package/dist/core/agent-session-queue.test.js.map +1 -1
- package/dist/core/agent-session-review-coverage.test.js +80 -23
- package/dist/core/agent-session-review-coverage.test.js.map +1 -1
- package/dist/core/agent-session-slash-restore.test.d.ts +2 -0
- package/dist/core/agent-session-slash-restore.test.d.ts.map +1 -0
- package/dist/core/agent-session-slash-restore.test.js +121 -0
- package/dist/core/agent-session-slash-restore.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +214 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +978 -212
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/active-context.test.js +21 -0
- package/dist/core/compaction/active-context.test.js.map +1 -1
- package/dist/core/compaction/compactor.d.ts +108 -8
- package/dist/core/compaction/compactor.d.ts.map +1 -1
- package/dist/core/compaction/compactor.js +423 -119
- package/dist/core/compaction/compactor.js.map +1 -1
- package/dist/core/compaction/compactor.test.js +360 -8
- package/dist/core/compaction/compactor.test.js.map +1 -1
- package/dist/core/compaction/policy.d.ts +17 -0
- package/dist/core/compaction/policy.d.ts.map +1 -0
- package/dist/core/compaction/policy.js +22 -0
- package/dist/core/compaction/policy.js.map +1 -0
- package/dist/core/compaction/policy.test.d.ts +2 -0
- package/dist/core/compaction/policy.test.d.ts.map +1 -0
- package/dist/core/compaction/policy.test.js +35 -0
- package/dist/core/compaction/policy.test.js.map +1 -0
- package/dist/core/compaction/query-aware-selector.d.ts +33 -0
- package/dist/core/compaction/query-aware-selector.d.ts.map +1 -0
- package/dist/core/compaction/query-aware-selector.js +202 -0
- package/dist/core/compaction/query-aware-selector.js.map +1 -0
- package/dist/core/compaction/query-aware-selector.test.d.ts +2 -0
- package/dist/core/compaction/query-aware-selector.test.d.ts.map +1 -0
- package/dist/core/compaction/query-aware-selector.test.js +96 -0
- package/dist/core/compaction/query-aware-selector.test.js.map +1 -0
- package/dist/core/compaction/tool-result-pruner.d.ts +24 -11
- package/dist/core/compaction/tool-result-pruner.d.ts.map +1 -1
- package/dist/core/compaction/tool-result-pruner.js +98 -26
- package/dist/core/compaction/tool-result-pruner.js.map +1 -1
- package/dist/core/compaction/tool-result-pruner.test.js +178 -6
- package/dist/core/compaction/tool-result-pruner.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +23 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +10 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +28 -8
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/plugin-bundles.d.ts +23 -0
- package/dist/core/extensions/plugin-bundles.d.ts.map +1 -0
- package/dist/core/extensions/plugin-bundles.js +228 -0
- package/dist/core/extensions/plugin-bundles.js.map +1 -0
- package/dist/core/extensions/plugin-bundles.test.d.ts +2 -0
- package/dist/core/extensions/plugin-bundles.test.d.ts.map +1 -0
- package/dist/core/extensions/plugin-bundles.test.js +110 -0
- package/dist/core/extensions/plugin-bundles.test.js.map +1 -0
- package/dist/core/foreign-session-import.d.ts +120 -0
- package/dist/core/foreign-session-import.d.ts.map +1 -0
- package/dist/core/foreign-session-import.js +598 -0
- package/dist/core/foreign-session-import.js.map +1 -0
- package/dist/core/foreign-session-import.test.d.ts +2 -0
- package/dist/core/foreign-session-import.test.d.ts.map +1 -0
- package/dist/core/foreign-session-import.test.js +220 -0
- package/dist/core/foreign-session-import.test.js.map +1 -0
- package/dist/core/foreign-transcript-blocks.d.ts +51 -0
- package/dist/core/foreign-transcript-blocks.d.ts.map +1 -0
- package/dist/core/foreign-transcript-blocks.js +151 -0
- package/dist/core/foreign-transcript-blocks.js.map +1 -0
- package/dist/core/ideal-review.d.ts +20 -1
- package/dist/core/ideal-review.d.ts.map +1 -1
- package/dist/core/ideal-review.js +37 -2
- package/dist/core/ideal-review.js.map +1 -1
- package/dist/core/ideal-review.test.js +99 -3
- package/dist/core/ideal-review.test.js.map +1 -1
- package/dist/core/loop-breaker.d.ts.map +1 -1
- package/dist/core/loop-breaker.js +1 -0
- package/dist/core/loop-breaker.js.map +1 -1
- package/dist/core/lsp/client.d.ts +15 -0
- package/dist/core/lsp/client.d.ts.map +1 -1
- package/dist/core/lsp/client.js +39 -1
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/manager.d.ts +47 -9
- package/dist/core/lsp/manager.d.ts.map +1 -1
- package/dist/core/lsp/manager.js +96 -69
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/manager.test.js +18 -0
- package/dist/core/lsp/manager.test.js.map +1 -1
- package/dist/core/lsp/pool.d.ts +113 -0
- package/dist/core/lsp/pool.d.ts.map +1 -0
- package/dist/core/lsp/pool.js +255 -0
- package/dist/core/lsp/pool.js.map +1 -0
- package/dist/core/lsp/pool.test.d.ts +2 -0
- package/dist/core/lsp/pool.test.d.ts.map +1 -0
- package/dist/core/lsp/pool.test.js +286 -0
- package/dist/core/lsp/pool.test.js.map +1 -0
- package/dist/core/lsp/servers.d.ts.map +1 -1
- package/dist/core/lsp/servers.js +43 -3
- package/dist/core/lsp/servers.js.map +1 -1
- package/dist/core/lsp/servers.test.d.ts +2 -0
- package/dist/core/lsp/servers.test.d.ts.map +1 -0
- package/dist/core/lsp/servers.test.js +67 -0
- package/dist/core/lsp/servers.test.js.map +1 -0
- package/dist/core/lsp/windows.test.js +2 -14
- package/dist/core/lsp/windows.test.js.map +1 -1
- package/dist/core/mcp/catalog-cache.d.ts +63 -0
- package/dist/core/mcp/catalog-cache.d.ts.map +1 -0
- package/dist/core/mcp/catalog-cache.js +163 -0
- package/dist/core/mcp/catalog-cache.js.map +1 -0
- package/dist/core/mcp/catalog-cache.test.d.ts +2 -0
- package/dist/core/mcp/catalog-cache.test.d.ts.map +1 -0
- package/dist/core/mcp/catalog-cache.test.js +99 -0
- package/dist/core/mcp/catalog-cache.test.js.map +1 -0
- package/dist/core/mcp/client-session-recovery.test.d.ts +2 -0
- package/dist/core/mcp/client-session-recovery.test.d.ts.map +1 -0
- package/dist/core/mcp/client-session-recovery.test.js +231 -0
- package/dist/core/mcp/client-session-recovery.test.js.map +1 -0
- package/dist/core/mcp/client.d.ts +158 -0
- package/dist/core/mcp/client.d.ts.map +1 -1
- package/dist/core/mcp/client.js +476 -35
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/elicitation-bridge.d.ts +41 -0
- package/dist/core/mcp/elicitation-bridge.d.ts.map +1 -0
- package/dist/core/mcp/elicitation-bridge.js +52 -0
- package/dist/core/mcp/elicitation-bridge.js.map +1 -0
- package/dist/core/mcp/elicitation.test.d.ts +2 -0
- package/dist/core/mcp/elicitation.test.d.ts.map +1 -0
- package/dist/core/mcp/elicitation.test.js +158 -0
- package/dist/core/mcp/elicitation.test.js.map +1 -0
- package/dist/core/mcp/index.d.ts +5 -1
- package/dist/core/mcp/index.d.ts.map +1 -1
- package/dist/core/mcp/index.js +2 -0
- package/dist/core/mcp/index.js.map +1 -1
- package/dist/core/mcp/legacy-negotiation.test.d.ts +2 -0
- package/dist/core/mcp/legacy-negotiation.test.d.ts.map +1 -0
- package/dist/core/mcp/legacy-negotiation.test.js +80 -0
- package/dist/core/mcp/legacy-negotiation.test.js.map +1 -0
- package/dist/core/mcp/oauth-provider.d.ts +1 -2
- package/dist/core/mcp/oauth-provider.d.ts.map +1 -1
- package/dist/core/mcp/oauth-provider.js +6 -2
- package/dist/core/mcp/oauth-provider.js.map +1 -1
- package/dist/core/mcp/oauth-store.d.ts +1 -1
- package/dist/core/mcp/oauth-store.d.ts.map +1 -1
- package/dist/core/mcp/oauth-store.js.map +1 -1
- package/dist/core/mcp/session-elicitation-wiring.test.d.ts +2 -0
- package/dist/core/mcp/session-elicitation-wiring.test.d.ts.map +1 -0
- package/dist/core/mcp/session-elicitation-wiring.test.js +138 -0
- package/dist/core/mcp/session-elicitation-wiring.test.js.map +1 -0
- package/dist/core/mcp/shared-pool.d.ts +158 -0
- package/dist/core/mcp/shared-pool.d.ts.map +1 -0
- package/dist/core/mcp/shared-pool.js +235 -0
- package/dist/core/mcp/shared-pool.js.map +1 -0
- package/dist/core/mcp/shared-pool.test.d.ts +2 -0
- package/dist/core/mcp/shared-pool.test.d.ts.map +1 -0
- package/dist/core/mcp/shared-pool.test.js +425 -0
- package/dist/core/mcp/shared-pool.test.js.map +1 -0
- package/dist/core/mcp/types.d.ts +12 -0
- package/dist/core/mcp/types.d.ts.map +1 -1
- package/dist/core/mcp/when-connected.test.d.ts +2 -0
- package/dist/core/mcp/when-connected.test.d.ts.map +1 -0
- package/dist/core/mcp/when-connected.test.js +46 -0
- package/dist/core/mcp/when-connected.test.js.map +1 -0
- package/dist/core/nolan-context.d.ts.map +1 -1
- package/dist/core/nolan-context.js +8 -0
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/nolan-context.test.js +40 -0
- package/dist/core/nolan-context.test.js.map +1 -1
- package/dist/core/nolan-prompt.js +3 -0
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/nolan-prompt.test.js +5 -0
- package/dist/core/nolan-prompt.test.js.map +1 -1
- package/dist/core/persistent-shell.d.ts +3 -2
- package/dist/core/persistent-shell.d.ts.map +1 -1
- package/dist/core/persistent-shell.js +10 -3
- package/dist/core/persistent-shell.js.map +1 -1
- package/dist/core/process-gate.d.ts +45 -0
- package/dist/core/process-gate.d.ts.map +1 -0
- package/dist/core/process-gate.js +79 -0
- package/dist/core/process-gate.js.map +1 -0
- package/dist/core/process-gate.test.d.ts +2 -0
- package/dist/core/process-gate.test.d.ts.map +1 -0
- package/dist/core/process-gate.test.js +87 -0
- package/dist/core/process-gate.test.js.map +1 -0
- package/dist/core/process-manager-notifications.test.d.ts +2 -0
- package/dist/core/process-manager-notifications.test.d.ts.map +1 -0
- package/dist/core/process-manager-notifications.test.js +217 -0
- package/dist/core/process-manager-notifications.test.js.map +1 -0
- package/dist/core/process-manager.d.ts +50 -1
- package/dist/core/process-manager.d.ts.map +1 -1
- package/dist/core/process-manager.js +189 -2
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/project-discovery.d.ts +31 -6
- package/dist/core/project-discovery.d.ts.map +1 -1
- package/dist/core/project-discovery.js +287 -31
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/project-discovery.test.js +124 -0
- package/dist/core/project-discovery.test.js.map +1 -1
- package/dist/core/regrounding.d.ts.map +1 -1
- package/dist/core/regrounding.js +1 -0
- package/dist/core/regrounding.js.map +1 -1
- package/dist/core/run-claim.d.ts +37 -0
- package/dist/core/run-claim.d.ts.map +1 -0
- package/dist/core/run-claim.js +46 -0
- package/dist/core/run-claim.js.map +1 -0
- package/dist/core/run-claim.test.d.ts +2 -0
- package/dist/core/run-claim.test.d.ts.map +1 -0
- package/dist/core/run-claim.test.js +107 -0
- package/dist/core/run-claim.test.js.map +1 -0
- package/dist/core/run-journal.test.d.ts +2 -0
- package/dist/core/run-journal.test.d.ts.map +1 -0
- package/dist/core/run-journal.test.js +195 -0
- package/dist/core/run-journal.test.js.map +1 -0
- package/dist/core/run-lifecycle.d.ts +22 -3
- package/dist/core/run-lifecycle.d.ts.map +1 -1
- package/dist/core/run-lifecycle.js +12 -3
- package/dist/core/run-lifecycle.js.map +1 -1
- package/dist/core/sandbox-domains.d.ts +14 -0
- package/dist/core/sandbox-domains.d.ts.map +1 -0
- package/dist/core/sandbox-domains.js +76 -0
- package/dist/core/sandbox-domains.js.map +1 -0
- package/dist/core/sandbox-feedback.d.ts +22 -0
- package/dist/core/sandbox-feedback.d.ts.map +1 -0
- package/dist/core/sandbox-feedback.js +69 -0
- package/dist/core/sandbox-feedback.js.map +1 -0
- package/dist/core/sandbox-feedback.test.d.ts +2 -0
- package/dist/core/sandbox-feedback.test.d.ts.map +1 -0
- package/dist/core/sandbox-feedback.test.js +32 -0
- package/dist/core/sandbox-feedback.test.js.map +1 -0
- package/dist/core/sandbox.d.ts +91 -0
- package/dist/core/sandbox.d.ts.map +1 -0
- package/dist/core/sandbox.js +254 -0
- package/dist/core/sandbox.js.map +1 -0
- package/dist/core/sandbox.test.d.ts +2 -0
- package/dist/core/sandbox.test.d.ts.map +1 -0
- package/dist/core/sandbox.test.js +157 -0
- package/dist/core/sandbox.test.js.map +1 -0
- package/dist/core/session-compaction.d.ts +6 -0
- package/dist/core/session-compaction.d.ts.map +1 -1
- package/dist/core/session-compaction.js +11 -1
- package/dist/core/session-compaction.js.map +1 -1
- package/dist/core/session-compaction.test.js +18 -1
- package/dist/core/session-compaction.test.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js +12 -4
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-history.d.ts +95 -6
- package/dist/core/session-history.d.ts.map +1 -1
- package/dist/core/session-history.js +261 -17
- package/dist/core/session-history.js.map +1 -1
- package/dist/core/session-history.test.js +173 -2
- package/dist/core/session-history.test.js.map +1 -1
- package/dist/core/session-manager.d.ts +223 -6
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +515 -26
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.js +147 -3
- package/dist/core/session-manager.test.js.map +1 -1
- package/dist/core/session-notification-visibility.test.d.ts +2 -0
- package/dist/core/session-notification-visibility.test.d.ts.map +1 -0
- package/dist/core/session-notification-visibility.test.js +113 -0
- package/dist/core/session-notification-visibility.test.js.map +1 -0
- package/dist/core/session-preview.d.ts +5 -4
- package/dist/core/session-preview.d.ts.map +1 -1
- package/dist/core/session-preview.js +12 -5
- package/dist/core/session-preview.js.map +1 -1
- package/dist/core/session-restore-display.test.js +25 -0
- package/dist/core/session-restore-display.test.js.map +1 -1
- package/dist/core/session-storage.d.ts.map +1 -1
- package/dist/core/session-storage.js +39 -3
- package/dist/core/session-storage.js.map +1 -1
- package/dist/core/session-storage.test.js +6 -1
- package/dist/core/session-storage.test.js.map +1 -1
- package/dist/core/settings-manager.d.ts +8 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +26 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/steering.d.ts +12 -0
- package/dist/core/steering.d.ts.map +1 -1
- package/dist/core/steering.js +16 -0
- package/dist/core/steering.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +13 -0
- package/dist/core/subagent-manager.d.ts.map +1 -1
- package/dist/core/subagent-manager.js +39 -1
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/core/subagent-manager.test.js +43 -7
- package/dist/core/subagent-manager.test.js.map +1 -1
- package/dist/core/verification-evidence.d.ts +17 -0
- package/dist/core/verification-evidence.d.ts.map +1 -0
- package/dist/core/verification-evidence.js +283 -0
- package/dist/core/verification-evidence.js.map +1 -0
- package/dist/core/verification-evidence.test.d.ts +2 -0
- package/dist/core/verification-evidence.test.d.ts.map +1 -0
- package/dist/core/verification-evidence.test.js +103 -0
- package/dist/core/verification-evidence.test.js.map +1 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +17 -3
- package/dist/interactive.js.map +1 -1
- package/dist/modes/acp-mode.d.ts +122 -0
- package/dist/modes/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp-mode.js +1366 -0
- package/dist/modes/acp-mode.js.map +1 -0
- package/dist/modes/acp-mode.test.d.ts +2 -0
- package/dist/modes/acp-mode.test.d.ts.map +1 -0
- package/dist/modes/acp-mode.test.js +1065 -0
- package/dist/modes/acp-mode.test.js.map +1 -0
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/json-mode.d.ts +28 -0
- package/dist/modes/json-mode.d.ts.map +1 -1
- package/dist/modes/json-mode.js +37 -0
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/json-mode.test.d.ts +2 -0
- package/dist/modes/json-mode.test.d.ts.map +1 -0
- package/dist/modes/json-mode.test.js +84 -0
- package/dist/modes/json-mode.test.js.map +1 -0
- package/dist/modes/subagent-worker-mode.d.ts +3 -0
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +91 -11
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.test.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.test.d.ts.map +1 -0
- package/dist/modes/subagent-worker-mode.test.js +52 -0
- package/dist/modes/subagent-worker-mode.test.js.map +1 -0
- package/dist/session.d.ts +29 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +41 -0
- package/dist/session.js.map +1 -1
- package/dist/tools/bash.d.ts +2 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +55 -16
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/goals.d.ts +2 -2
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +2 -1
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/index.d.ts +13 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +20 -17
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/index.test.d.ts +2 -0
- package/dist/tools/index.test.d.ts.map +1 -0
- package/dist/tools/index.test.js +55 -0
- package/dist/tools/index.test.js.map +1 -0
- package/dist/tools/read-only-bash.d.ts +3 -0
- package/dist/tools/read-only-bash.d.ts.map +1 -1
- package/dist/tools/read-only-bash.js +7 -9
- package/dist/tools/read-only-bash.js.map +1 -1
- package/dist/tools/subagent-control.d.ts.map +1 -1
- package/dist/tools/subagent-control.js +6 -2
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +6 -0
- package/dist/tools/subagent-shared.d.ts.map +1 -1
- package/dist/tools/subagent-shared.js +6 -0
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +43 -8
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/subagent.test.js +65 -3
- package/dist/tools/subagent.test.js.map +1 -1
- package/dist/tools/task-output.d.ts.map +1 -1
- package/dist/tools/task-output.js +3 -1
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/tool-search.d.ts +12 -1
- package/dist/tools/tool-search.d.ts.map +1 -1
- package/dist/tools/tool-search.js +22 -3
- package/dist/tools/tool-search.js.map +1 -1
- package/dist/tools/tool-search.test.d.ts +2 -0
- package/dist/tools/tool-search.test.d.ts.map +1 -0
- package/dist/tools/tool-search.test.js +69 -0
- package/dist/tools/tool-search.test.js.map +1 -0
- package/dist/tools/web-fetch.d.ts +1 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +5 -2
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +27 -1
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +18 -4
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/utils/github.test.js +3 -3
- package/dist/utils/github.test.js.map +1 -1
- package/dist/utils/image.d.ts +26 -3
- package/dist/utils/image.d.ts.map +1 -1
- package/dist/utils/image.js +83 -14
- package/dist/utils/image.js.map +1 -1
- package/dist/utils/image.test.d.ts +2 -0
- package/dist/utils/image.test.d.ts.map +1 -0
- package/dist/utils/image.test.js +139 -0
- package/dist/utils/image.test.js.map +1 -0
- package/package.json +7 -6
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { RunLifecycle } from "./run-lifecycle.js";
|
|
6
|
+
import { SessionManager, RUN_STARTED_CUSTOM_KIND, RUN_FINISHED_CUSTOM_KIND, } from "./session-manager.js";
|
|
7
|
+
function recordingJournal() {
|
|
8
|
+
const calls = [];
|
|
9
|
+
return {
|
|
10
|
+
calls,
|
|
11
|
+
writer: {
|
|
12
|
+
started: (generation) => calls.push(`start:${generation}`),
|
|
13
|
+
finished: (generation, outcome) => calls.push(`finish:${generation}:${outcome}`),
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function startedEntry(generation, afterMessageCount = 0) {
|
|
18
|
+
return {
|
|
19
|
+
type: "custom",
|
|
20
|
+
kind: RUN_STARTED_CUSTOM_KIND,
|
|
21
|
+
id: `s${generation}`,
|
|
22
|
+
parentId: null,
|
|
23
|
+
timestamp: "2026-07-29T10:00:00.000Z",
|
|
24
|
+
data: {
|
|
25
|
+
version: 1,
|
|
26
|
+
generation,
|
|
27
|
+
startedAt: "2026-07-29T10:00:00.000Z",
|
|
28
|
+
afterMessageCount,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function finishedEntry(generation, outcome) {
|
|
33
|
+
return {
|
|
34
|
+
type: "custom",
|
|
35
|
+
kind: RUN_FINISHED_CUSTOM_KIND,
|
|
36
|
+
id: `f${generation}`,
|
|
37
|
+
parentId: null,
|
|
38
|
+
timestamp: "2026-07-29T10:01:00.000Z",
|
|
39
|
+
data: { version: 1, generation, outcome },
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
describe("RunLifecycle journalling", () => {
|
|
43
|
+
it("writes a matched pair for a clean run", () => {
|
|
44
|
+
const { writer, calls } = recordingJournal();
|
|
45
|
+
const lifecycle = new RunLifecycle(undefined, writer);
|
|
46
|
+
const lease = lifecycle.begin(vi.fn());
|
|
47
|
+
lifecycle.settle(lease.generation);
|
|
48
|
+
expect(calls).toEqual([`start:${lease.generation}`, `finish:${lease.generation}:completed`]);
|
|
49
|
+
});
|
|
50
|
+
it("records a failed run as failed", () => {
|
|
51
|
+
const { writer, calls } = recordingJournal();
|
|
52
|
+
const lifecycle = new RunLifecycle(undefined, writer);
|
|
53
|
+
const lease = lifecycle.begin(vi.fn());
|
|
54
|
+
lifecycle.settle(lease.generation, "failed");
|
|
55
|
+
expect(calls).toEqual([`start:${lease.generation}`, `finish:${lease.generation}:failed`]);
|
|
56
|
+
});
|
|
57
|
+
it("records a cancelled run as aborted regardless of the caller's outcome", async () => {
|
|
58
|
+
const { writer, calls } = recordingJournal();
|
|
59
|
+
const lifecycle = new RunLifecycle(undefined, writer);
|
|
60
|
+
const lease = lifecycle.begin(vi.fn());
|
|
61
|
+
void lifecycle.cancel(1000);
|
|
62
|
+
await Promise.resolve();
|
|
63
|
+
lifecycle.settle(lease.generation, "completed");
|
|
64
|
+
expect(calls).toEqual([`start:${lease.generation}`, `finish:${lease.generation}:aborted`]);
|
|
65
|
+
});
|
|
66
|
+
it("does not let a stale generation close a newer run's journal", () => {
|
|
67
|
+
const { writer, calls } = recordingJournal();
|
|
68
|
+
const lifecycle = new RunLifecycle(undefined, writer);
|
|
69
|
+
const first = lifecycle.begin(vi.fn());
|
|
70
|
+
lifecycle.settle(first.generation);
|
|
71
|
+
const second = lifecycle.begin(vi.fn());
|
|
72
|
+
// The stale settle must be a no-op — not a finish for generation 2.
|
|
73
|
+
expect(lifecycle.settle(first.generation)).toEqual({ settled: false, cancelled: false });
|
|
74
|
+
expect(calls).toEqual([`start:1`, `finish:1:completed`, `start:2`]);
|
|
75
|
+
lifecycle.settle(second.generation);
|
|
76
|
+
expect(calls.at(-1)).toBe("finish:2:completed");
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe("run journal reconstruction", () => {
|
|
80
|
+
const manager = new SessionManager(path.join(os.tmpdir(), "gg-run-journal-unused"));
|
|
81
|
+
it("pairs each start with its own generation's finish", () => {
|
|
82
|
+
const entries = [
|
|
83
|
+
startedEntry(1, 0),
|
|
84
|
+
finishedEntry(1, "completed"),
|
|
85
|
+
startedEntry(2, 4),
|
|
86
|
+
finishedEntry(2, "aborted"),
|
|
87
|
+
];
|
|
88
|
+
expect(manager.getRunJournal(entries)).toEqual([
|
|
89
|
+
{
|
|
90
|
+
generation: 1,
|
|
91
|
+
startedAt: "2026-07-29T10:00:00.000Z",
|
|
92
|
+
afterMessageCount: 0,
|
|
93
|
+
outcome: "completed",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
generation: 2,
|
|
97
|
+
startedAt: "2026-07-29T10:00:00.000Z",
|
|
98
|
+
afterMessageCount: 4,
|
|
99
|
+
outcome: "aborted",
|
|
100
|
+
},
|
|
101
|
+
]);
|
|
102
|
+
expect(manager.getUnfinishedRuns(entries)).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
it("detects a truncated log as unfinished exactly once", () => {
|
|
105
|
+
// The crash shape: the last run opened and the file just stops.
|
|
106
|
+
const entries = [startedEntry(1), finishedEntry(1, "completed"), startedEntry(2, 6)];
|
|
107
|
+
const unfinished = manager.getUnfinishedRuns(entries);
|
|
108
|
+
expect(unfinished).toHaveLength(1);
|
|
109
|
+
expect(unfinished[0]).toMatchObject({ generation: 2, afterMessageCount: 6 });
|
|
110
|
+
});
|
|
111
|
+
it("counts a duplicated start line once, not twice", () => {
|
|
112
|
+
// A replayed/re-persisted log must not manufacture phantom crashed runs.
|
|
113
|
+
const entries = [startedEntry(3), startedEntry(3), startedEntry(3)];
|
|
114
|
+
expect(manager.getUnfinishedRuns(entries)).toHaveLength(1);
|
|
115
|
+
});
|
|
116
|
+
it("detects a crash in a RESUMED session, where generations restart at 1", () => {
|
|
117
|
+
// Generations are not unique across a session file: RunLifecycle counts from
|
|
118
|
+
// zero per instance and a resumed session builds a fresh one, so the first
|
|
119
|
+
// run after every app restart is generation 1 again.
|
|
120
|
+
//
|
|
121
|
+
// Treating the reused number as a duplicate made a crash-after-restart
|
|
122
|
+
// invisible — exactly the case this journal exists to catch.
|
|
123
|
+
const entries = [
|
|
124
|
+
startedEntry(1, 0),
|
|
125
|
+
finishedEntry(1, "completed"),
|
|
126
|
+
// App restarts, same session resumed, generation 1 again — then dies.
|
|
127
|
+
startedEntry(1, 4),
|
|
128
|
+
];
|
|
129
|
+
expect(manager.getRunJournal(entries)).toHaveLength(2);
|
|
130
|
+
const unfinished = manager.getUnfinishedRuns(entries);
|
|
131
|
+
expect(unfinished).toHaveLength(1);
|
|
132
|
+
// The SECOND run is the crashed one; the first stays completed.
|
|
133
|
+
expect(unfinished[0]).toMatchObject({ generation: 1, afterMessageCount: 4 });
|
|
134
|
+
});
|
|
135
|
+
it("closes only the open run when a generation is reused", () => {
|
|
136
|
+
// gen 1 opens, a replayed start line repeats it, then one finish arrives.
|
|
137
|
+
// The finish must close the single open run and leave nothing dangling.
|
|
138
|
+
const entries = [startedEntry(1, 0), startedEntry(1, 6), finishedEntry(1, "completed")];
|
|
139
|
+
expect(manager.getRunJournal(entries)).toHaveLength(1);
|
|
140
|
+
expect(manager.getUnfinishedRuns(entries)).toEqual([]);
|
|
141
|
+
});
|
|
142
|
+
it("ignores a finish whose start was lost and malformed payloads", () => {
|
|
143
|
+
const orphan = finishedEntry(9, "completed");
|
|
144
|
+
const malformed = {
|
|
145
|
+
type: "custom",
|
|
146
|
+
kind: RUN_STARTED_CUSTOM_KIND,
|
|
147
|
+
id: "bad",
|
|
148
|
+
parentId: null,
|
|
149
|
+
timestamp: "2026-07-29T10:00:00.000Z",
|
|
150
|
+
data: { version: 2, generation: "not-a-number" },
|
|
151
|
+
};
|
|
152
|
+
expect(manager.getRunJournal([orphan, malformed])).toEqual([]);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe("run journal on disk", () => {
|
|
156
|
+
it("round-trips through a real session file", async () => {
|
|
157
|
+
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "gg-run-journal-"));
|
|
158
|
+
try {
|
|
159
|
+
const manager = new SessionManager(dir);
|
|
160
|
+
const session = await manager.create(process.cwd(), "anthropic", "claude-test");
|
|
161
|
+
await manager.appendRunStarted(session.path, {
|
|
162
|
+
version: 1,
|
|
163
|
+
generation: 1,
|
|
164
|
+
startedAt: "2026-07-29T10:00:00.000Z",
|
|
165
|
+
afterMessageCount: 2,
|
|
166
|
+
});
|
|
167
|
+
await manager.appendRunFinished(session.path, {
|
|
168
|
+
version: 1,
|
|
169
|
+
generation: 1,
|
|
170
|
+
outcome: "completed",
|
|
171
|
+
});
|
|
172
|
+
// Second run never closes — the process died.
|
|
173
|
+
await manager.appendRunStarted(session.path, {
|
|
174
|
+
version: 1,
|
|
175
|
+
generation: 2,
|
|
176
|
+
startedAt: "2026-07-29T10:05:00.000Z",
|
|
177
|
+
afterMessageCount: 5,
|
|
178
|
+
});
|
|
179
|
+
const loaded = await manager.load(session.path);
|
|
180
|
+
expect(manager.getRunJournal(loaded.entries).map((r) => r.outcome)).toEqual([
|
|
181
|
+
"completed",
|
|
182
|
+
undefined,
|
|
183
|
+
]);
|
|
184
|
+
const unfinished = manager.getUnfinishedRuns(loaded.entries);
|
|
185
|
+
expect(unfinished).toHaveLength(1);
|
|
186
|
+
expect(unfinished[0].generation).toBe(2);
|
|
187
|
+
// Journal entries are off-DAG, so they never enter the model's context.
|
|
188
|
+
expect(manager.getMessages(loaded.entries, loaded.header.leafId)).toEqual([]);
|
|
189
|
+
}
|
|
190
|
+
finally {
|
|
191
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=run-journal.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-journal.test.js","sourceRoot":"","sources":["../../src/core/run-journal.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,wBAAwB,GAGzB,MAAM,sBAAsB,CAAC;AAE9B,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,OAAO;QACL,KAAK;QACL,MAAM,EAAE;YACN,OAAO,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,UAAU,EAAE,CAAC;YAC1D,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,UAAU,IAAI,OAAO,EAAE,CAAC;SACjF;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,UAAkB,EAAE,iBAAiB,GAAG,CAAC;IAC7D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,uBAAuB;QAC7B,EAAE,EAAE,IAAI,UAAU,EAAE;QACpB,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,0BAA0B;QACrC,IAAI,EAAE;YACJ,OAAO,EAAE,CAAC;YACV,UAAU;YACV,SAAS,EAAE,0BAA0B;YACrC,iBAAiB;SAClB;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,UAAkB,EAAE,OAAmB;IAC5D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,wBAAwB;QAC9B,EAAE,EAAE,IAAI,UAAU,EAAE;QACpB,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,0BAA0B;QACrC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC,UAAU,EAAE,EAAE,UAAU,KAAK,CAAC,UAAU,YAAY,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC,UAAU,EAAE,EAAE,UAAU,KAAK,CAAC,UAAU,SAAS,CAAC,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvC,KAAK,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACxB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC,UAAU,EAAE,EAAE,UAAU,KAAK,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAExC,oEAAoE;QACpE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACzF,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,oBAAoB,EAAE,SAAS,CAAC,CAAC,CAAC;QACpE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAEpF,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,OAAO,GAAG;YACd,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;YAClB,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC;YAC7B,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;YAClB,aAAa,CAAC,CAAC,EAAE,SAAS,CAAC;SAC5B,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAC7C;gBACE,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,0BAA0B;gBACrC,iBAAiB,EAAE,CAAC;gBACpB,OAAO,EAAE,WAAW;aACrB;YACD;gBACE,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,0BAA0B;gBACrC,iBAAiB,EAAE,CAAC;gBACpB,OAAO,EAAE,SAAS;aACnB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,gEAAgE;QAChE,MAAM,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrF,MAAM,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,yEAAyE;QACzE,MAAM,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,6EAA6E;QAC7E,2EAA2E;QAC3E,qDAAqD;QACrD,EAAE;QACF,uEAAuE;QACvE,6DAA6D;QAC7D,MAAM,OAAO,GAAG;YACd,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;YAClB,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC;YAC7B,sEAAsE;YACtE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;SACnB,CAAC;QAEF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACnC,gEAAgE;QAChE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,0EAA0E;QAC1E,wEAAwE;QACxE,MAAM,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAExF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAiB;YAC9B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,uBAAuB;YAC7B,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,0BAA0B;YACrC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE;SACjD,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;YAEhF,MAAM,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE;gBAC3C,OAAO,EAAE,CAAC;gBACV,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,0BAA0B;gBACrC,iBAAiB,EAAE,CAAC;aACrB,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE;gBAC5C,OAAO,EAAE,CAAC;gBACV,UAAU,EAAE,CAAC;gBACb,OAAO,EAAE,WAAW;aACrB,CAAC,CAAC;YACH,8CAA8C;YAC9C,MAAM,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE;gBAC3C,OAAO,EAAE,CAAC;gBACV,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,0BAA0B;gBACrC,iBAAiB,EAAE,CAAC;aACrB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;gBAC1E,WAAW;gBACX,SAAS;aACV,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7D,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAE1C,wEAAwE;YACxE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
import type { RunOutcome } from "./session-manager.js";
|
|
1
2
|
export type RunState = "idle" | "running" | "cancelling";
|
|
3
|
+
/**
|
|
4
|
+
* Durable record of run boundaries. `RunLifecycle` already owns generation
|
|
5
|
+
* identity, so hanging the journal off it makes the on-disk pair inherit that
|
|
6
|
+
* generation-safety for free — a stale run cannot close a newer one's entry.
|
|
7
|
+
*
|
|
8
|
+
* Both hooks are fire-and-forget: journalling must never delay a run or fail
|
|
9
|
+
* one. Implementations swallow their own write errors.
|
|
10
|
+
*/
|
|
11
|
+
export interface RunJournalWriter {
|
|
12
|
+
started(generation: number): void;
|
|
13
|
+
finished(generation: number, outcome: RunOutcome): void;
|
|
14
|
+
}
|
|
2
15
|
export type CancelResult = {
|
|
3
16
|
status: "cancelled";
|
|
4
17
|
generation: number;
|
|
@@ -19,17 +32,23 @@ export declare class RunBusyError extends Error {
|
|
|
19
32
|
/** Generation-safe ownership and acknowledged bounded cancellation. */
|
|
20
33
|
export declare class RunLifecycle {
|
|
21
34
|
private readonly onStateChange?;
|
|
35
|
+
private readonly journal?;
|
|
22
36
|
private currentState;
|
|
23
37
|
private nextGeneration;
|
|
24
38
|
private active?;
|
|
25
|
-
constructor(onStateChange?: ((state: RunState) => void) | undefined);
|
|
39
|
+
constructor(onStateChange?: ((state: RunState) => void) | undefined, journal?: RunJournalWriter | undefined);
|
|
26
40
|
get state(): RunState;
|
|
27
41
|
get running(): boolean;
|
|
28
42
|
get generation(): number;
|
|
29
43
|
begin(abort: () => void): RunLease;
|
|
30
44
|
isCancellationRequested(generation: number): boolean;
|
|
31
|
-
/**
|
|
32
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Settle only the matching owner; stale generations cannot release a new run.
|
|
47
|
+
*
|
|
48
|
+
* `outcome` defaults to `completed`; a cancelled run always records `aborted`
|
|
49
|
+
* regardless, since cancellation is the authoritative signal here.
|
|
50
|
+
*/
|
|
51
|
+
settle(generation: number, outcome?: RunOutcome): {
|
|
33
52
|
settled: boolean;
|
|
34
53
|
cancelled: boolean;
|
|
35
54
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../../src/core/run-lifecycle.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AAEzD,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD,qBAAa,YAAa,SAAQ,KAAK;gBACzB,KAAK,EAAE,QAAQ;CAI5B;AAED,uEAAuE;AACvE,qBAAa,YAAY;
|
|
1
|
+
{"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../../src/core/run-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;CACzD;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD,qBAAa,YAAa,SAAQ,KAAK;gBACzB,KAAK,EAAE,QAAQ;CAI5B;AAED,uEAAuE;AACvE,qBAAa,YAAY;IAMrB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAN3B,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,MAAM,CAAC,CAAY;gBAGR,aAAa,CAAC,GAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAA,EACzC,OAAO,CAAC,EAAE,gBAAgB,YAAA;IAG7C,IAAI,KAAK,IAAI,QAAQ,CAEpB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,QAAQ;IAmBlC,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIpD;;;;;OAKG;IACH,MAAM,CACJ,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,UAAwB,GAChC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE;IAa3C,4EAA4E;IAC5E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAgChD,OAAO,CAAC,QAAQ;CAKjB"}
|
|
@@ -7,11 +7,13 @@ export class RunBusyError extends Error {
|
|
|
7
7
|
/** Generation-safe ownership and acknowledged bounded cancellation. */
|
|
8
8
|
export class RunLifecycle {
|
|
9
9
|
onStateChange;
|
|
10
|
+
journal;
|
|
10
11
|
currentState = "idle";
|
|
11
12
|
nextGeneration = 0;
|
|
12
13
|
active;
|
|
13
|
-
constructor(onStateChange) {
|
|
14
|
+
constructor(onStateChange, journal) {
|
|
14
15
|
this.onStateChange = onStateChange;
|
|
16
|
+
this.journal = journal;
|
|
15
17
|
}
|
|
16
18
|
get state() {
|
|
17
19
|
return this.currentState;
|
|
@@ -38,13 +40,19 @@ export class RunLifecycle {
|
|
|
38
40
|
resolveSettlement,
|
|
39
41
|
};
|
|
40
42
|
this.setState("running");
|
|
43
|
+
this.journal?.started(generation);
|
|
41
44
|
return { generation };
|
|
42
45
|
}
|
|
43
46
|
isCancellationRequested(generation) {
|
|
44
47
|
return this.active?.generation === generation && this.active.cancelRequested;
|
|
45
48
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Settle only the matching owner; stale generations cannot release a new run.
|
|
51
|
+
*
|
|
52
|
+
* `outcome` defaults to `completed`; a cancelled run always records `aborted`
|
|
53
|
+
* regardless, since cancellation is the authoritative signal here.
|
|
54
|
+
*/
|
|
55
|
+
settle(generation, outcome = "completed") {
|
|
48
56
|
const active = this.active;
|
|
49
57
|
if (!active || active.generation !== generation) {
|
|
50
58
|
return { settled: false, cancelled: false };
|
|
@@ -53,6 +61,7 @@ export class RunLifecycle {
|
|
|
53
61
|
this.active = undefined;
|
|
54
62
|
this.setState("idle");
|
|
55
63
|
active.resolveSettlement();
|
|
64
|
+
this.journal?.finished(generation, cancelled ? "aborted" : outcome);
|
|
56
65
|
return { settled: true, cancelled };
|
|
57
66
|
}
|
|
58
67
|
/** Abort once, then acknowledge only after the owning operation settles. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-lifecycle.js","sourceRoot":"","sources":["../../src/core/run-lifecycle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-lifecycle.js","sourceRoot":"","sources":["../../src/core/run-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default network allowlist for the OS command sandbox.
|
|
3
|
+
*
|
|
4
|
+
* The sandbox is allowlist-only (a bare `*` is rejected), so shipping it on by
|
|
5
|
+
* default is only viable if ordinary development still works untouched. These
|
|
6
|
+
* are the hosts mainstream toolchains actually contact for dependency
|
|
7
|
+
* resolution, source checkout and registry auth — nothing that reads user data.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately excluded: arbitrary app/API hosts, telemetry endpoints and
|
|
10
|
+
* URL shorteners. A project that needs one adds it once in Settings, which is
|
|
11
|
+
* the moment the boundary earns its keep.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DEFAULT_ALLOWED_DOMAINS: readonly string[];
|
|
14
|
+
//# sourceMappingURL=sandbox-domains.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-domains.d.ts","sourceRoot":"","sources":["../../src/core/sandbox-domains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAwEpD,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default network allowlist for the OS command sandbox.
|
|
3
|
+
*
|
|
4
|
+
* The sandbox is allowlist-only (a bare `*` is rejected), so shipping it on by
|
|
5
|
+
* default is only viable if ordinary development still works untouched. These
|
|
6
|
+
* are the hosts mainstream toolchains actually contact for dependency
|
|
7
|
+
* resolution, source checkout and registry auth — nothing that reads user data.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately excluded: arbitrary app/API hosts, telemetry endpoints and
|
|
10
|
+
* URL shorteners. A project that needs one adds it once in Settings, which is
|
|
11
|
+
* the moment the boundary earns its keep.
|
|
12
|
+
*/
|
|
13
|
+
export const DEFAULT_ALLOWED_DOMAINS = [
|
|
14
|
+
// ── Source hosting (git clone/fetch/push over HTTPS) ──
|
|
15
|
+
"github.com",
|
|
16
|
+
"*.github.com",
|
|
17
|
+
"*.githubusercontent.com",
|
|
18
|
+
"gitlab.com",
|
|
19
|
+
"*.gitlab.com",
|
|
20
|
+
"bitbucket.org",
|
|
21
|
+
"*.bitbucket.org",
|
|
22
|
+
"codeberg.org",
|
|
23
|
+
// ── JavaScript ──
|
|
24
|
+
"registry.npmjs.org",
|
|
25
|
+
"*.npmjs.org",
|
|
26
|
+
"registry.yarnpkg.com",
|
|
27
|
+
"*.yarnpkg.com",
|
|
28
|
+
"jsr.io",
|
|
29
|
+
"deno.land",
|
|
30
|
+
"*.deno.land",
|
|
31
|
+
"unpkg.com",
|
|
32
|
+
"cdn.jsdelivr.net",
|
|
33
|
+
"*.jsdelivr.net",
|
|
34
|
+
"cdnjs.cloudflare.com",
|
|
35
|
+
// ── Python ──
|
|
36
|
+
"pypi.org",
|
|
37
|
+
"*.pypi.org",
|
|
38
|
+
"files.pythonhosted.org",
|
|
39
|
+
"*.pythonhosted.org",
|
|
40
|
+
// ── Go (module proxy + checksum database) ──
|
|
41
|
+
"proxy.golang.org",
|
|
42
|
+
"sum.golang.org",
|
|
43
|
+
"*.golang.org",
|
|
44
|
+
"storage.googleapis.com",
|
|
45
|
+
// ── Rust ──
|
|
46
|
+
"crates.io",
|
|
47
|
+
"*.crates.io",
|
|
48
|
+
"static.rust-lang.org",
|
|
49
|
+
"*.rust-lang.org",
|
|
50
|
+
// ── Ruby ──
|
|
51
|
+
"rubygems.org",
|
|
52
|
+
"*.rubygems.org",
|
|
53
|
+
// ── JVM ──
|
|
54
|
+
"repo1.maven.org",
|
|
55
|
+
"*.maven.org",
|
|
56
|
+
"repo.maven.apache.org",
|
|
57
|
+
"plugins.gradle.org",
|
|
58
|
+
"*.gradle.org",
|
|
59
|
+
// ── PHP ──
|
|
60
|
+
"packagist.org",
|
|
61
|
+
"*.packagist.org",
|
|
62
|
+
// ── .NET ──
|
|
63
|
+
"api.nuget.org",
|
|
64
|
+
"*.nuget.org",
|
|
65
|
+
// ── Containers ──
|
|
66
|
+
"docker.io",
|
|
67
|
+
"*.docker.io",
|
|
68
|
+
"*.docker.com",
|
|
69
|
+
"ghcr.io",
|
|
70
|
+
"quay.io",
|
|
71
|
+
"registry.k8s.io",
|
|
72
|
+
// ── macOS/Linux toolchain installers ──
|
|
73
|
+
"formulae.brew.sh",
|
|
74
|
+
"*.brew.sh",
|
|
75
|
+
];
|
|
76
|
+
//# sourceMappingURL=sandbox-domains.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-domains.js","sourceRoot":"","sources":["../../src/core/sandbox-domains.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,yDAAyD;IACzD,YAAY;IACZ,cAAc;IACd,yBAAyB;IACzB,YAAY;IACZ,cAAc;IACd,eAAe;IACf,iBAAiB;IACjB,cAAc;IAEd,mBAAmB;IACnB,oBAAoB;IACpB,aAAa;IACb,sBAAsB;IACtB,eAAe;IACf,QAAQ;IACR,WAAW;IACX,aAAa;IACb,WAAW;IACX,kBAAkB;IAClB,gBAAgB;IAChB,sBAAsB;IAEtB,eAAe;IACf,UAAU;IACV,YAAY;IACZ,wBAAwB;IACxB,oBAAoB;IAEpB,8CAA8C;IAC9C,kBAAkB;IAClB,gBAAgB;IAChB,cAAc;IACd,wBAAwB;IAExB,aAAa;IACb,WAAW;IACX,aAAa;IACb,sBAAsB;IACtB,iBAAiB;IAEjB,aAAa;IACb,cAAc;IACd,gBAAgB;IAEhB,YAAY;IACZ,iBAAiB;IACjB,aAAa;IACb,uBAAuB;IACvB,oBAAoB;IACpB,cAAc;IAEd,YAAY;IACZ,eAAe;IACf,iBAAiB;IAEjB,aAAa;IACb,eAAe;IACf,aAAa;IAEb,mBAAmB;IACnB,WAAW;IACX,aAAa;IACb,cAAc;IACd,SAAS;IACT,SAAS;IACT,iBAAiB;IAEjB,yCAAyC;IACzC,kBAAkB;IAClB,WAAW;CACZ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn raw OS-sandbox denials into guidance the model can act on.
|
|
3
|
+
*
|
|
4
|
+
* A blocked command otherwise surfaces as inscrutable tool noise ("CONNECT
|
|
5
|
+
* tunnel failed, response 403", "Operation not permitted"), which the model
|
|
6
|
+
* tends to retry verbatim. Naming the boundary and the one-step fix is what
|
|
7
|
+
* turns a dead end into a recoverable turn.
|
|
8
|
+
*/
|
|
9
|
+
export interface SandboxDenialNote {
|
|
10
|
+
kind: "network" | "filesystem";
|
|
11
|
+
note: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Inspect finished command output for a sandbox denial.
|
|
15
|
+
*
|
|
16
|
+
* @param output Combined stdout/stderr as returned to the model.
|
|
17
|
+
* @param sandboxed Whether this command actually ran isolated.
|
|
18
|
+
*/
|
|
19
|
+
export declare function describeSandboxDenial(output: string, sandboxed: boolean): SandboxDenialNote | null;
|
|
20
|
+
/** Append the denial note to command output when one applies. */
|
|
21
|
+
export declare function annotateSandboxDenial(output: string, sandboxed: boolean): string;
|
|
22
|
+
//# sourceMappingURL=sandbox-feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-feedback.d.ts","sourceRoot":"","sources":["../../src/core/sandbox-feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA2BH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,OAAO,GACjB,iBAAiB,GAAG,IAAI,CA6B1B;AAED,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,CAGhF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn raw OS-sandbox denials into guidance the model can act on.
|
|
3
|
+
*
|
|
4
|
+
* A blocked command otherwise surfaces as inscrutable tool noise ("CONNECT
|
|
5
|
+
* tunnel failed, response 403", "Operation not permitted"), which the model
|
|
6
|
+
* tends to retry verbatim. Naming the boundary and the one-step fix is what
|
|
7
|
+
* turns a dead end into a recoverable turn.
|
|
8
|
+
*/
|
|
9
|
+
/** SRT's proxy rejection, plus how common clients report it. */
|
|
10
|
+
const NETWORK_DENIAL = [
|
|
11
|
+
"blocked-by-allowlist",
|
|
12
|
+
"Connection blocked by network allowlist",
|
|
13
|
+
"CONNECT tunnel failed, response 403",
|
|
14
|
+
];
|
|
15
|
+
const FILESYSTEM_DENIAL = ["Operation not permitted", "operation not permitted", "EPERM"];
|
|
16
|
+
/** Hosts the command tried to reach, best-effort, for a precise suggestion. */
|
|
17
|
+
function extractHosts(output) {
|
|
18
|
+
const hosts = new Set();
|
|
19
|
+
const patterns = [
|
|
20
|
+
/(?:CONNECT|to)\s+([a-z0-9.-]+\.[a-z]{2,})(?::\d+)?/gi,
|
|
21
|
+
/https?:\/\/([a-z0-9.-]+\.[a-z]{2,})/gi,
|
|
22
|
+
];
|
|
23
|
+
for (const pattern of patterns) {
|
|
24
|
+
for (const match of output.matchAll(pattern)) {
|
|
25
|
+
const host = match[1]?.toLowerCase();
|
|
26
|
+
if (host && !host.endsWith(".local"))
|
|
27
|
+
hosts.add(host);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return [...hosts].slice(0, 3);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Inspect finished command output for a sandbox denial.
|
|
34
|
+
*
|
|
35
|
+
* @param output Combined stdout/stderr as returned to the model.
|
|
36
|
+
* @param sandboxed Whether this command actually ran isolated.
|
|
37
|
+
*/
|
|
38
|
+
export function describeSandboxDenial(output, sandboxed) {
|
|
39
|
+
if (!sandboxed || !output)
|
|
40
|
+
return null;
|
|
41
|
+
if (NETWORK_DENIAL.some((marker) => output.includes(marker))) {
|
|
42
|
+
const hosts = extractHosts(output);
|
|
43
|
+
const target = hosts.length > 0 ? hosts.join(", ") : "that host";
|
|
44
|
+
return {
|
|
45
|
+
kind: "network",
|
|
46
|
+
note: `\n\n[Sandbox] Network blocked: ${target} is not an approved destination. ` +
|
|
47
|
+
`Common package registries and git hosts are approved already, so double-check the ` +
|
|
48
|
+
`address first. If the user genuinely needs it, ask them to add it under ` +
|
|
49
|
+
`Settings → Command safety → Approved sites (or turn command safety off).`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (FILESYSTEM_DENIAL.some((marker) => output.includes(marker))) {
|
|
53
|
+
return {
|
|
54
|
+
kind: "filesystem",
|
|
55
|
+
note: `\n\n[Sandbox] Write blocked: that path is either outside this project or a ` +
|
|
56
|
+
`protected file (.env). Prefer a path inside the project, or use the write ` +
|
|
57
|
+
`tool if the user asked for that exact file. If they genuinely need shell ` +
|
|
58
|
+
`writes elsewhere, ask them to enable Settings → Command safety → Allow ` +
|
|
59
|
+
`changes outside the project.`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/** Append the denial note to command output when one applies. */
|
|
65
|
+
export function annotateSandboxDenial(output, sandboxed) {
|
|
66
|
+
const denial = describeSandboxDenial(output, sandboxed);
|
|
67
|
+
return denial ? `${output}${denial.note}` : output;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=sandbox-feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-feedback.js","sourceRoot":"","sources":["../../src/core/sandbox-feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,gEAAgE;AAChE,MAAM,cAAc,GAAG;IACrB,sBAAsB;IACtB,yCAAyC;IACzC,qCAAqC;CACtC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,yBAAyB,EAAE,yBAAyB,EAAE,OAAO,CAAC,CAAC;AAE1F,+EAA+E;AAC/E,SAAS,YAAY,CAAC,MAAc;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,QAAQ,GAAG;QACf,sDAAsD;QACtD,uCAAuC;KACxC,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;YACrC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChC,CAAC;AAOD;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,SAAkB;IAElB,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEvC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACjE,OAAO;YACL,IAAI,EAAE,SAAS;YACf,IAAI,EACF,kCAAkC,MAAM,mCAAmC;gBAC3E,oFAAoF;gBACpF,0EAA0E;gBAC1E,0EAA0E;SAC7E,CAAC;IACJ,CAAC;IAED,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,IAAI,EACF,6EAA6E;gBAC7E,4EAA4E;gBAC5E,2EAA2E;gBAC3E,yEAAyE;gBACzE,8BAA8B;SACjC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,SAAkB;IACtE,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-feedback.test.d.ts","sourceRoot":"","sources":["../../src/core/sandbox-feedback.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { annotateSandboxDenial, describeSandboxDenial } from "./sandbox-feedback.js";
|
|
3
|
+
describe("describeSandboxDenial", () => {
|
|
4
|
+
it("names the blocked host and the one place a user can approve it", () => {
|
|
5
|
+
const output = "Exit code: 0\ncurl: (56) CONNECT tunnel failed, response 403\nCONNECT api.example.com:443";
|
|
6
|
+
const denial = describeSandboxDenial(output, true);
|
|
7
|
+
expect(denial?.kind).toBe("network");
|
|
8
|
+
expect(denial?.note).toContain("api.example.com");
|
|
9
|
+
expect(denial?.note).toContain("Approved sites");
|
|
10
|
+
// The model must not be told to silently give up or disable protection first.
|
|
11
|
+
expect(denial?.note).toContain("ask them");
|
|
12
|
+
});
|
|
13
|
+
it("points a blocked write back inside the project", () => {
|
|
14
|
+
const output = "touch: /Users/x/secret: Operation not permitted";
|
|
15
|
+
const denial = describeSandboxDenial(output, true);
|
|
16
|
+
expect(denial?.kind).toBe("filesystem");
|
|
17
|
+
expect(denial?.note).toContain("outside this project");
|
|
18
|
+
});
|
|
19
|
+
it("stays silent for ordinary failures and for unsandboxed commands", () => {
|
|
20
|
+
expect(describeSandboxDenial("Exit code: 1\nnpm ERR! missing script: buil", true)).toBeNull();
|
|
21
|
+
// Same text, but the command never ran isolated — the sandbox cannot be the cause.
|
|
22
|
+
expect(describeSandboxDenial("Operation not permitted", false)).toBeNull();
|
|
23
|
+
});
|
|
24
|
+
it("annotates output without discarding the original text", () => {
|
|
25
|
+
const output = "Exit code: 0\nConnection blocked by network allowlist";
|
|
26
|
+
const annotated = annotateSandboxDenial(output, true);
|
|
27
|
+
expect(annotated.startsWith(output)).toBe(true);
|
|
28
|
+
expect(annotated).toContain("[Sandbox]");
|
|
29
|
+
expect(annotateSandboxDenial(output, false)).toBe(output);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=sandbox-feedback.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-feedback.test.js","sourceRoot":"","sources":["../../src/core/sandbox-feedback.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAErF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,MAAM,GACV,2FAA2F,CAAC;QAE9F,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QACjD,8EAA8E;QAC9E,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG,iDAAiD,CAAC;QAEjE,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,qBAAqB,CAAC,6CAA6C,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC9F,mFAAmF;QACnF,MAAM,CAAC,qBAAqB,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG,uDAAuD,CAAC;QAEvE,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEtD,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|