@provos/ironcurtain 0.10.0 → 0.12.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 +68 -14
- package/dist/auth/oauth-provider.js +1 -4
- package/dist/auth/oauth-provider.js.map +1 -1
- package/dist/cli-help.d.ts +12 -0
- package/dist/cli-help.js +21 -0
- package/dist/cli-help.js.map +1 -1
- package/dist/cli.js +46 -6
- package/dist/cli.js.map +1 -1
- package/dist/config/agent-model-guard.d.ts +14 -0
- package/dist/config/agent-model-guard.js +24 -0
- package/dist/config/agent-model-guard.js.map +1 -0
- package/dist/config/config-command.js +277 -7
- package/dist/config/config-command.js.map +1 -1
- package/dist/config/first-start.js +62 -7
- package/dist/config/first-start.js.map +1 -1
- package/dist/config/generated/compiled-policy.json +528 -161
- package/dist/config/generated/test-scenarios.json +4810 -170
- package/dist/config/generated/tool-annotations.json +34 -47
- package/dist/config/index.d.ts +58 -0
- package/dist/config/index.js +97 -15
- package/dist/config/index.js.map +1 -1
- package/dist/config/mcp-servers.json +2 -2
- package/dist/config/model-provider.d.ts +9 -0
- package/dist/config/model-provider.js +13 -0
- package/dist/config/model-provider.js.map +1 -1
- package/dist/config/paths.d.ts +217 -0
- package/dist/config/paths.js +363 -14
- package/dist/config/paths.js.map +1 -1
- package/dist/config/types.d.ts +7 -1
- package/dist/config/user-config.d.ts +101 -6
- package/dist/config/user-config.js +145 -31
- package/dist/config/user-config.js.map +1 -1
- package/dist/config/validate-policy-dir.d.ts +10 -0
- package/dist/config/validate-policy-dir.js +59 -0
- package/dist/config/validate-policy-dir.js.map +1 -0
- package/dist/cron/job-commands.js +22 -2
- package/dist/cron/job-commands.js.map +1 -1
- package/dist/cron/types.d.ts +16 -2
- package/dist/cron/types.js +1 -3
- package/dist/cron/types.js.map +1 -1
- package/dist/daemon/daemon-command.js +30 -7
- package/dist/daemon/daemon-command.js.map +1 -1
- package/dist/daemon/ironcurtain-daemon.d.ts +62 -1
- package/dist/daemon/ironcurtain-daemon.js +231 -8
- package/dist/daemon/ironcurtain-daemon.js.map +1 -1
- package/dist/daemon-client/daemon-client.d.ts +123 -0
- package/dist/daemon-client/daemon-client.js +324 -0
- package/dist/daemon-client/daemon-client.js.map +1 -0
- package/dist/docker/adapters/claude-code.js +194 -20
- package/dist/docker/adapters/claude-code.js.map +1 -1
- package/dist/docker/adapters/codex.d.ts +9 -0
- package/dist/docker/adapters/codex.js +297 -0
- package/dist/docker/adapters/codex.js.map +1 -0
- package/dist/docker/adapters/goose.d.ts +12 -11
- package/dist/docker/adapters/goose.js +80 -27
- package/dist/docker/adapters/goose.js.map +1 -1
- package/dist/docker/agent-adapter.d.ts +183 -5
- package/dist/docker/agent-adapter.js +16 -0
- package/dist/docker/agent-adapter.js.map +1 -1
- package/dist/docker/agent-registry.js +5 -0
- package/dist/docker/agent-registry.js.map +1 -1
- package/dist/docker/apple-container-manager.d.ts +49 -0
- package/dist/docker/apple-container-manager.js +464 -0
- package/dist/docker/apple-container-manager.js.map +1 -0
- package/dist/docker/code-mode-proxy.d.ts +38 -0
- package/dist/docker/code-mode-proxy.js +6 -1
- package/dist/docker/code-mode-proxy.js.map +1 -1
- package/dist/docker/container-lifecycle.d.ts +2 -2
- package/dist/docker/container-lifecycle.js.map +1 -1
- package/dist/docker/container-runtime.d.ts +29 -0
- package/dist/docker/container-runtime.js +76 -0
- package/dist/docker/container-runtime.js.map +1 -0
- package/dist/docker/docker-agent-session.d.ts +113 -62
- package/dist/docker/docker-agent-session.js +271 -294
- package/dist/docker/docker-agent-session.js.map +1 -1
- package/dist/docker/docker-infrastructure.d.ts +428 -26
- package/dist/docker/docker-infrastructure.js +1005 -70
- package/dist/docker/docker-infrastructure.js.map +1 -1
- package/dist/docker/docker-manager.d.ts +58 -3
- package/dist/docker/docker-manager.js +378 -33
- package/dist/docker/docker-manager.js.map +1 -1
- package/dist/docker/docker-probe.d.ts +45 -0
- package/dist/docker/docker-probe.js +86 -0
- package/dist/docker/docker-probe.js.map +1 -0
- package/dist/docker/docker-progress-sink.d.ts +43 -0
- package/dist/docker/docker-progress-sink.js +299 -0
- package/dist/docker/docker-progress-sink.js.map +1 -0
- package/dist/docker/mitm-proxy.d.ts +135 -1
- package/dist/docker/mitm-proxy.js +611 -25
- package/dist/docker/mitm-proxy.js.map +1 -1
- package/dist/docker/network-topology.d.ts +81 -0
- package/dist/docker/network-topology.js +160 -0
- package/dist/docker/network-topology.js.map +1 -0
- package/dist/docker/oauth-credentials.d.ts +59 -3
- package/dist/docker/oauth-credentials.js +181 -14
- package/dist/docker/oauth-credentials.js.map +1 -1
- package/dist/docker/oauth-token-manager.js +2 -2
- package/dist/docker/oauth-token-manager.js.map +1 -1
- package/dist/docker/orientation.d.ts +1 -1
- package/dist/docker/package-types.d.ts +1 -1
- package/dist/docker/provider-config.d.ts +78 -3
- package/dist/docker/provider-config.js +295 -31
- package/dist/docker/provider-config.js.map +1 -1
- package/dist/docker/provision-lock.d.ts +46 -0
- package/dist/docker/provision-lock.js +152 -0
- package/dist/docker/provision-lock.js.map +1 -0
- package/dist/docker/proxy-tools.d.ts +0 -2
- package/dist/docker/proxy-tools.js +2 -7
- package/dist/docker/proxy-tools.js.map +1 -1
- package/dist/docker/pty-session.d.ts +64 -1
- package/dist/docker/pty-session.js +306 -104
- package/dist/docker/pty-session.js.map +1 -1
- package/dist/docker/pty-types.d.ts +0 -2
- package/dist/docker/pty-types.js +0 -2
- package/dist/docker/pty-types.js.map +1 -1
- package/dist/docker/registry-proxy.d.ts +46 -0
- package/dist/docker/registry-proxy.js +255 -1
- package/dist/docker/registry-proxy.js.map +1 -1
- package/dist/docker/resource-limits.d.ts +134 -0
- package/dist/docker/resource-limits.js +203 -0
- package/dist/docker/resource-limits.js.map +1 -0
- package/dist/docker/spawn-with-idle-timeout.d.ts +39 -0
- package/dist/docker/spawn-with-idle-timeout.js +152 -0
- package/dist/docker/spawn-with-idle-timeout.js.map +1 -0
- package/dist/docker/sse-extractor.d.ts +51 -0
- package/dist/docker/sse-extractor.js +303 -0
- package/dist/docker/sse-extractor.js.map +1 -0
- package/dist/docker/token-stream-bus.d.ts +83 -0
- package/dist/docker/token-stream-bus.js +98 -0
- package/dist/docker/token-stream-bus.js.map +1 -0
- package/dist/docker/token-stream-types.d.ts +71 -0
- package/dist/docker/token-stream-types.js +8 -0
- package/dist/docker/token-stream-types.js.map +1 -0
- package/dist/docker/trajectory-capture.d.ts +79 -0
- package/dist/docker/trajectory-capture.js +521 -0
- package/dist/docker/trajectory-capture.js.map +1 -0
- package/dist/docker/trajectory-reassembler.d.ts +286 -0
- package/dist/docker/trajectory-reassembler.js +990 -0
- package/dist/docker/trajectory-reassembler.js.map +1 -0
- package/dist/docker/trajectory-tap.d.ts +100 -0
- package/dist/docker/trajectory-tap.js +410 -0
- package/dist/docker/trajectory-tap.js.map +1 -0
- package/dist/docker/trajectory-types.d.ts +187 -0
- package/dist/docker/trajectory-types.js +43 -0
- package/dist/docker/trajectory-types.js.map +1 -0
- package/dist/docker/types.d.ts +105 -12
- package/dist/doctor/checks.d.ts +171 -0
- package/dist/doctor/checks.js +598 -0
- package/dist/doctor/checks.js.map +1 -0
- package/dist/doctor/doctor-command.d.ts +29 -0
- package/dist/doctor/doctor-command.js +190 -0
- package/dist/doctor/doctor-command.js.map +1 -0
- package/dist/doctor/mcp-liveness.d.ts +28 -0
- package/dist/doctor/mcp-liveness.js +92 -0
- package/dist/doctor/mcp-liveness.js.map +1 -0
- package/dist/doctor/oauth-checks.d.ts +23 -0
- package/dist/doctor/oauth-checks.js +157 -0
- package/dist/doctor/oauth-checks.js.map +1 -0
- package/dist/doctor/output.d.ts +26 -0
- package/dist/doctor/output.js +82 -0
- package/dist/doctor/output.js.map +1 -0
- package/dist/escalation/listener-command.js +0 -3
- package/dist/escalation/listener-command.js.map +1 -1
- package/dist/event-bus/typed-event-bus.d.ts +26 -0
- package/dist/event-bus/typed-event-bus.js +35 -0
- package/dist/event-bus/typed-event-bus.js.map +1 -0
- package/dist/index.js +54 -21
- package/dist/index.js.map +1 -1
- package/dist/logger.js +31 -2
- package/dist/logger.js.map +1 -1
- package/dist/memory/auto-save.d.ts +18 -4
- package/dist/memory/auto-save.js +46 -6
- package/dist/memory/auto-save.js.map +1 -1
- package/dist/memory/memory-policy.d.ts +41 -0
- package/dist/memory/memory-policy.js +36 -0
- package/dist/memory/memory-policy.js.map +1 -0
- package/dist/mux/mux-app.d.ts +2 -0
- package/dist/mux/mux-app.js +1 -0
- package/dist/mux/mux-app.js.map +1 -1
- package/dist/mux/mux-command.d.ts +10 -1
- package/dist/mux/mux-command.js +74 -40
- package/dist/mux/mux-command.js.map +1 -1
- package/dist/mux/mux-renderer.js +2 -12
- package/dist/mux/mux-renderer.js.map +1 -1
- package/dist/mux/pty-bridge.d.ts +2 -0
- package/dist/mux/pty-bridge.js +3 -0
- package/dist/mux/pty-bridge.js.map +1 -1
- package/dist/mux/session-scanner.js +1 -2
- package/dist/mux/session-scanner.js.map +1 -1
- package/dist/{pipeline → observability}/llm-logger.d.ts +8 -3
- package/dist/{pipeline → observability}/llm-logger.js +8 -3
- package/dist/observability/llm-logger.js.map +1 -0
- package/dist/observe/observe-command.d.ts +12 -0
- package/dist/observe/observe-command.js +285 -0
- package/dist/observe/observe-command.js.map +1 -0
- package/dist/observe/observe-renderer.d.ts +24 -0
- package/dist/observe/observe-renderer.js +87 -0
- package/dist/observe/observe-renderer.js.map +1 -0
- package/dist/observe/observe-tui-rain.d.ts +42 -0
- package/dist/observe/observe-tui-rain.js +531 -0
- package/dist/observe/observe-tui-rain.js.map +1 -0
- package/dist/observe/observe-tui-text-panel.d.ts +46 -0
- package/dist/observe/observe-tui-text-panel.js +525 -0
- package/dist/observe/observe-tui-text-panel.js.map +1 -0
- package/dist/observe/observe-tui-types.d.ts +270 -0
- package/dist/observe/observe-tui-types.js +200 -0
- package/dist/observe/observe-tui-types.js.map +1 -0
- package/dist/observe/observe-tui-word-scorer.d.ts +143 -0
- package/dist/observe/observe-tui-word-scorer.js +572 -0
- package/dist/observe/observe-tui-word-scorer.js.map +1 -0
- package/dist/observe/observe-tui.d.ts +59 -0
- package/dist/observe/observe-tui.js +592 -0
- package/dist/observe/observe-tui.js.map +1 -0
- package/dist/persona/broad-policy-validator.d.ts +95 -0
- package/dist/persona/broad-policy-validator.js +171 -0
- package/dist/persona/broad-policy-validator.js.map +1 -0
- package/dist/persona/compile-persona-policy.d.ts +54 -2
- package/dist/persona/compile-persona-policy.js +29 -4
- package/dist/persona/compile-persona-policy.js.map +1 -1
- package/dist/persona/event-bus-progress-reporter.d.ts +57 -0
- package/dist/persona/event-bus-progress-reporter.js +66 -0
- package/dist/persona/event-bus-progress-reporter.js.map +1 -0
- package/dist/persona/memory-gate.d.ts +19 -0
- package/dist/persona/memory-gate.js +33 -0
- package/dist/persona/memory-gate.js.map +1 -0
- package/dist/persona/persona-command.js +77 -72
- package/dist/persona/persona-command.js.map +1 -1
- package/dist/persona/persona-compile-orchestrator.d.ts +101 -0
- package/dist/persona/persona-compile-orchestrator.js +504 -0
- package/dist/persona/persona-compile-orchestrator.js.map +1 -0
- package/dist/persona/persona-service.d.ts +137 -0
- package/dist/persona/persona-service.js +263 -0
- package/dist/persona/persona-service.js.map +1 -0
- package/dist/persona/policy-mutation-audit.d.ts +109 -0
- package/dist/persona/policy-mutation-audit.js +179 -0
- package/dist/persona/policy-mutation-audit.js.map +1 -0
- package/dist/persona/resolve.d.ts +22 -0
- package/dist/persona/resolve.js +45 -2
- package/dist/persona/resolve.js.map +1 -1
- package/dist/persona/rule-delta.d.ts +30 -0
- package/dist/persona/rule-delta.js +82 -0
- package/dist/persona/rule-delta.js.map +1 -0
- package/dist/persona/types.d.ts +28 -0
- package/dist/pipeline/annotate.js +10 -2
- package/dist/pipeline/annotate.js.map +1 -1
- package/dist/pipeline/compile.js +14 -2
- package/dist/pipeline/compile.js.map +1 -1
- package/dist/pipeline/constitution-compiler.d.ts +25 -14
- package/dist/pipeline/constitution-compiler.js +107 -38
- package/dist/pipeline/constitution-compiler.js.map +1 -1
- package/dist/pipeline/dynamic-list-types.d.ts +3 -6
- package/dist/pipeline/dynamic-list-types.js +3 -16
- package/dist/pipeline/dynamic-list-types.js.map +1 -1
- package/dist/pipeline/pipeline-runner.d.ts +63 -4
- package/dist/pipeline/pipeline-runner.js +242 -94
- package/dist/pipeline/pipeline-runner.js.map +1 -1
- package/dist/pipeline/pipeline-shared.d.ts +33 -4
- package/dist/pipeline/pipeline-shared.js +79 -19
- package/dist/pipeline/pipeline-shared.js.map +1 -1
- package/dist/pipeline/policy-verifier.js +16 -3
- package/dist/pipeline/policy-verifier.js.map +1 -1
- package/dist/pipeline/proxy-mcp-connections.js +17 -2
- package/dist/pipeline/proxy-mcp-connections.js.map +1 -1
- package/dist/pipeline/refresh-lists.js +3 -5
- package/dist/pipeline/refresh-lists.js.map +1 -1
- package/dist/pipeline/scenario-generator.d.ts +4 -8
- package/dist/pipeline/scenario-generator.js +13 -46
- package/dist/pipeline/scenario-generator.js.map +1 -1
- package/dist/sandbox/index.d.ts +29 -0
- package/dist/sandbox/index.js +351 -119
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/ironcurtain-protocol.d.ts +52 -0
- package/dist/sandbox/ironcurtain-protocol.js +185 -0
- package/dist/sandbox/ironcurtain-protocol.js.map +1 -0
- package/dist/session/agent-session.d.ts +6 -0
- package/dist/session/agent-session.js +16 -5
- package/dist/session/agent-session.js.map +1 -1
- package/dist/session/cli-transport.js +0 -6
- package/dist/session/cli-transport.js.map +1 -1
- package/dist/session/index.d.ts +35 -14
- package/dist/session/index.js +333 -130
- package/dist/session/index.js.map +1 -1
- package/dist/session/preflight.d.ts +21 -13
- package/dist/session/preflight.js +227 -88
- package/dist/session/preflight.js.map +1 -1
- package/dist/session/prompts.d.ts +2 -5
- package/dist/session/prompts.js.map +1 -1
- package/dist/session/session-manager.d.ts +61 -6
- package/dist/session/session-manager.js +72 -10
- package/dist/session/session-manager.js.map +1 -1
- package/dist/session/session-metadata.d.ts +21 -5
- package/dist/session/session-metadata.js +34 -12
- package/dist/session/session-metadata.js.map +1 -1
- package/dist/session/types.d.ts +320 -5
- package/dist/session/types.js +57 -1
- package/dist/session/types.js.map +1 -1
- package/dist/signal/bot-command.js +6 -1
- package/dist/signal/bot-command.js.map +1 -1
- package/dist/signal/setup-signal.js +13 -21
- package/dist/signal/setup-signal.js.map +1 -1
- package/dist/signal/signal-bot-daemon.d.ts +16 -1
- package/dist/signal/signal-bot-daemon.js +39 -27
- package/dist/signal/signal-bot-daemon.js.map +1 -1
- package/dist/signal/signal-container.d.ts +3 -3
- package/dist/signal/signal-container.js +9 -3
- package/dist/signal/signal-container.js.map +1 -1
- package/dist/skills/discovery.d.ts +77 -0
- package/dist/skills/discovery.js +206 -0
- package/dist/skills/discovery.js.map +1 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/staging.d.ts +28 -0
- package/dist/skills/staging.js +68 -0
- package/dist/skills/staging.js.map +1 -0
- package/dist/skills/types.d.ts +46 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/trusted-process/approval-whitelist.d.ts +0 -2
- package/dist/trusted-process/approval-whitelist.js +17 -17
- package/dist/trusted-process/approval-whitelist.js.map +1 -1
- package/dist/trusted-process/async-mutex.d.ts +32 -0
- package/dist/trusted-process/async-mutex.js +50 -0
- package/dist/trusted-process/async-mutex.js.map +1 -0
- package/dist/trusted-process/audit-log.d.ts +38 -1
- package/dist/trusted-process/audit-log.js +82 -13
- package/dist/trusted-process/audit-log.js.map +1 -1
- package/dist/trusted-process/call-circuit-breaker.d.ts +6 -0
- package/dist/trusted-process/call-circuit-breaker.js +23 -3
- package/dist/trusted-process/call-circuit-breaker.js.map +1 -1
- package/dist/trusted-process/container-command.d.ts +35 -0
- package/dist/trusted-process/container-command.js +49 -0
- package/dist/trusted-process/container-command.js.map +1 -0
- package/dist/trusted-process/control-server.d.ts +101 -0
- package/dist/trusted-process/control-server.js +282 -0
- package/dist/trusted-process/control-server.js.map +1 -0
- package/dist/trusted-process/domain-utils.d.ts +6 -6
- package/dist/trusted-process/domain-utils.js +7 -23
- package/dist/trusted-process/domain-utils.js.map +1 -1
- package/dist/trusted-process/error-prefixes.d.ts +16 -0
- package/dist/trusted-process/error-prefixes.js +17 -0
- package/dist/trusted-process/error-prefixes.js.map +1 -0
- package/dist/trusted-process/index.d.ts +40 -23
- package/dist/trusted-process/index.js +131 -225
- package/dist/trusted-process/index.js.map +1 -1
- package/dist/trusted-process/list-matcher.d.ts +17 -0
- package/dist/trusted-process/list-matcher.js +31 -0
- package/dist/trusted-process/list-matcher.js.map +1 -0
- package/dist/trusted-process/mcp-client-manager.d.ts +35 -6
- package/dist/trusted-process/mcp-client-manager.js +40 -45
- package/dist/trusted-process/mcp-client-manager.js.map +1 -1
- package/dist/trusted-process/mcp-proxy-server.d.ts +31 -120
- package/dist/trusted-process/mcp-proxy-server.js +201 -660
- package/dist/trusted-process/mcp-proxy-server.js.map +1 -1
- package/dist/trusted-process/policy-engine.d.ts +16 -4
- package/dist/trusted-process/policy-engine.js +103 -47
- package/dist/trusted-process/policy-engine.js.map +1 -1
- package/dist/trusted-process/policy-roots.d.ts +6 -0
- package/dist/trusted-process/policy-roots.js +20 -0
- package/dist/trusted-process/policy-roots.js.map +1 -1
- package/dist/trusted-process/sandbox-integration.d.ts +12 -0
- package/dist/trusted-process/sandbox-integration.js +18 -0
- package/dist/trusted-process/sandbox-integration.js.map +1 -1
- package/dist/trusted-process/tcp-server-transport.d.ts +12 -1
- package/dist/trusted-process/tcp-server-transport.js +9 -1
- package/dist/trusted-process/tcp-server-transport.js.map +1 -1
- package/dist/trusted-process/tool-call-coordinator.d.ts +283 -0
- package/dist/trusted-process/tool-call-coordinator.js +592 -0
- package/dist/trusted-process/tool-call-coordinator.js.map +1 -0
- package/dist/trusted-process/tool-call-pipeline.d.ts +213 -0
- package/dist/trusted-process/tool-call-pipeline.js +832 -0
- package/dist/trusted-process/tool-call-pipeline.js.map +1 -0
- package/dist/trusted-process/tool-description-hints.d.ts +1 -1
- package/dist/types/argument-roles.d.ts +1 -1
- package/dist/types/argument-roles.js +14 -1
- package/dist/types/argument-roles.js.map +1 -1
- package/dist/types/audit.d.ts +9 -0
- package/dist/{session → types}/errors.d.ts +8 -2
- package/dist/{session → types}/errors.js +8 -2
- package/dist/types/errors.js.map +1 -0
- package/dist/types/reserved-servers.d.ts +11 -0
- package/dist/types/reserved-servers.js +12 -0
- package/dist/types/reserved-servers.js.map +1 -0
- package/dist/types/server-listing.d.ts +14 -0
- package/dist/types/server-listing.js +2 -0
- package/dist/types/server-listing.js.map +1 -0
- package/dist/types/slug.d.ts +2 -0
- package/dist/types/slug.js +2 -0
- package/dist/types/slug.js.map +1 -1
- package/dist/types/url-normalize.d.ts +16 -0
- package/dist/types/url-normalize.js +33 -0
- package/dist/types/url-normalize.js.map +1 -0
- package/dist/util/atomic-write.d.ts +31 -0
- package/dist/util/atomic-write.js +43 -0
- package/dist/util/atomic-write.js.map +1 -0
- package/dist/utils/error-message.d.ts +8 -0
- package/dist/utils/error-message.js +11 -0
- package/dist/utils/error-message.js.map +1 -0
- package/dist/utils/exec-error.d.ts +19 -0
- package/dist/utils/exec-error.js +16 -0
- package/dist/utils/exec-error.js.map +1 -0
- package/dist/utils/is-plain-object.d.ts +7 -0
- package/dist/utils/is-plain-object.js +12 -0
- package/dist/utils/is-plain-object.js.map +1 -0
- package/dist/utils/preflight-checks.d.ts +16 -0
- package/dist/utils/preflight-checks.js +178 -0
- package/dist/utils/preflight-checks.js.map +1 -0
- package/dist/web-ui/__tests__/json-rpc-dispatch.test.d.ts +7 -0
- package/dist/web-ui/__tests__/json-rpc-dispatch.test.js +725 -0
- package/dist/web-ui/__tests__/json-rpc-dispatch.test.js.map +1 -0
- package/dist/web-ui/conn-registry.d.ts +14 -0
- package/dist/web-ui/conn-registry.js +25 -0
- package/dist/web-ui/conn-registry.js.map +1 -0
- package/dist/web-ui/dispatch/escalation-dispatch.d.ts +7 -0
- package/dist/web-ui/dispatch/escalation-dispatch.js +52 -0
- package/dist/web-ui/dispatch/escalation-dispatch.js.map +1 -0
- package/dist/web-ui/dispatch/job-dispatch.d.ts +8 -0
- package/dist/web-ui/dispatch/job-dispatch.js +83 -0
- package/dist/web-ui/dispatch/job-dispatch.js.map +1 -0
- package/dist/web-ui/dispatch/persona-dispatch.d.ts +50 -0
- package/dist/web-ui/dispatch/persona-dispatch.js +269 -0
- package/dist/web-ui/dispatch/persona-dispatch.js.map +1 -0
- package/dist/web-ui/dispatch/session-dispatch.d.ts +9 -0
- package/dist/web-ui/dispatch/session-dispatch.js +219 -0
- package/dist/web-ui/dispatch/session-dispatch.js.map +1 -0
- package/dist/web-ui/dispatch/token-stream-dispatch.d.ts +15 -0
- package/dist/web-ui/dispatch/token-stream-dispatch.js +55 -0
- package/dist/web-ui/dispatch/token-stream-dispatch.js.map +1 -0
- package/dist/web-ui/dispatch/types.d.ts +54 -0
- package/dist/web-ui/dispatch/types.js +72 -0
- package/dist/web-ui/dispatch/types.js.map +1 -0
- package/dist/web-ui/dispatch/workflow-dispatch.d.ts +103 -0
- package/dist/web-ui/dispatch/workflow-dispatch.js +1036 -0
- package/dist/web-ui/dispatch/workflow-dispatch.js.map +1 -0
- package/dist/web-ui/json-rpc-dispatch.d.ts +12 -0
- package/dist/web-ui/json-rpc-dispatch.js +34 -0
- package/dist/web-ui/json-rpc-dispatch.js.map +1 -0
- package/dist/web-ui/state-graph.d.ts +13 -0
- package/dist/web-ui/state-graph.js +82 -0
- package/dist/web-ui/state-graph.js.map +1 -0
- package/dist/web-ui/token-stream-bridge.d.ts +76 -0
- package/dist/web-ui/token-stream-bridge.js +265 -0
- package/dist/web-ui/token-stream-bridge.js.map +1 -0
- package/dist/web-ui/web-event-bus.d.ts +176 -0
- package/dist/web-ui/web-event-bus.js +19 -0
- package/dist/web-ui/web-event-bus.js.map +1 -0
- package/dist/web-ui/web-session-transport.d.ts +31 -0
- package/dist/web-ui/web-session-transport.js +109 -0
- package/dist/web-ui/web-session-transport.js.map +1 -0
- package/dist/web-ui/web-ui-server.d.ts +90 -0
- package/dist/web-ui/web-ui-server.js +477 -0
- package/dist/web-ui/web-ui-server.js.map +1 -0
- package/dist/web-ui/web-ui-types.d.ts +418 -0
- package/dist/web-ui/web-ui-types.js +32 -0
- package/dist/web-ui/web-ui-types.js.map +1 -0
- package/dist/web-ui/ws-utils.d.ts +5 -0
- package/dist/web-ui/ws-utils.js +12 -0
- package/dist/web-ui/ws-utils.js.map +1 -0
- package/dist/web-ui-static/assets/index-BD5U6ILh.css +1 -0
- package/dist/web-ui-static/assets/index-FMsHWEfK.js +79 -0
- package/dist/web-ui-static/assets/orbitron-latin-700-normal-4jsRXGGJ.woff2 +0 -0
- package/dist/web-ui-static/assets/orbitron-latin-700-normal-DmYOh-W9.woff +0 -0
- package/dist/web-ui-static/index.html +14 -0
- package/dist/workflow/artifacts.d.ts +59 -0
- package/dist/workflow/artifacts.js +188 -0
- package/dist/workflow/artifacts.js.map +1 -0
- package/dist/workflow/checkpoint-selection.d.ts +34 -0
- package/dist/workflow/checkpoint-selection.js +48 -0
- package/dist/workflow/checkpoint-selection.js.map +1 -0
- package/dist/workflow/checkpoint.d.ts +35 -0
- package/dist/workflow/checkpoint.js +84 -0
- package/dist/workflow/checkpoint.js.map +1 -0
- package/dist/workflow/cli-shared.d.ts +62 -0
- package/dist/workflow/cli-shared.js +117 -0
- package/dist/workflow/cli-shared.js.map +1 -0
- package/dist/workflow/cli-support.d.ts +92 -0
- package/dist/workflow/cli-support.js +421 -0
- package/dist/workflow/cli-support.js.map +1 -0
- package/dist/workflow/container-snapshots.d.ts +29 -0
- package/dist/workflow/container-snapshots.js +137 -0
- package/dist/workflow/container-snapshots.js.map +1 -0
- package/dist/workflow/daemon-gate-commands.d.ts +21 -0
- package/dist/workflow/daemon-gate-commands.js +599 -0
- package/dist/workflow/daemon-gate-commands.js.map +1 -0
- package/dist/workflow/definition-loader.d.ts +32 -0
- package/dist/workflow/definition-loader.js +56 -0
- package/dist/workflow/definition-loader.js.map +1 -0
- package/dist/workflow/discovery.d.ts +107 -0
- package/dist/workflow/discovery.js +263 -0
- package/dist/workflow/discovery.js.map +1 -0
- package/dist/workflow/errors.d.ts +66 -0
- package/dist/workflow/errors.js +49 -0
- package/dist/workflow/errors.js.map +1 -0
- package/dist/workflow/guards.d.ts +8 -0
- package/dist/workflow/guards.js +38 -0
- package/dist/workflow/guards.js.map +1 -0
- package/dist/workflow/lane-template.d.ts +89 -0
- package/dist/workflow/lane-template.js +141 -0
- package/dist/workflow/lane-template.js.map +1 -0
- package/dist/workflow/lint-integration.d.ts +64 -0
- package/dist/workflow/lint-integration.js +56 -0
- package/dist/workflow/lint-integration.js.map +1 -0
- package/dist/workflow/lint.d.ts +72 -0
- package/dist/workflow/lint.js +593 -0
- package/dist/workflow/lint.js.map +1 -0
- package/dist/workflow/machine-builder.d.ts +178 -0
- package/dist/workflow/machine-builder.js +678 -0
- package/dist/workflow/machine-builder.js.map +1 -0
- package/dist/workflow/message-log.d.ts +99 -0
- package/dist/workflow/message-log.js +40 -0
- package/dist/workflow/message-log.js.map +1 -0
- package/dist/workflow/orchestrator.d.ts +954 -0
- package/dist/workflow/orchestrator.js +3594 -0
- package/dist/workflow/orchestrator.js.map +1 -0
- package/dist/workflow/prompt-builder.d.ts +39 -0
- package/dist/workflow/prompt-builder.js +243 -0
- package/dist/workflow/prompt-builder.js.map +1 -0
- package/dist/workflow/run-state-command.d.ts +9 -0
- package/dist/workflow/run-state-command.js +414 -0
- package/dist/workflow/run-state-command.js.map +1 -0
- package/dist/workflow/run-state-debug-capture.d.ts +40 -0
- package/dist/workflow/run-state-debug-capture.js +101 -0
- package/dist/workflow/run-state-debug-capture.js.map +1 -0
- package/dist/workflow/status-parser.d.ts +68 -0
- package/dist/workflow/status-parser.js +274 -0
- package/dist/workflow/status-parser.js.map +1 -0
- package/dist/workflow/types.d.ts +598 -0
- package/dist/workflow/types.js +85 -0
- package/dist/workflow/types.js.map +1 -0
- package/dist/workflow/validate.d.ts +80 -0
- package/dist/workflow/validate.js +788 -0
- package/dist/workflow/validate.js.map +1 -0
- package/dist/workflow/workflow-command.d.ts +9 -0
- package/dist/workflow/workflow-command.js +670 -0
- package/dist/workflow/workflow-command.js.map +1 -0
- package/dist/workflow/workflow-discovery.d.ts +27 -0
- package/dist/workflow/workflow-discovery.js +121 -0
- package/dist/workflow/workflow-discovery.js.map +1 -0
- package/dist/workflow/workflow-manager.d.ts +156 -0
- package/dist/workflow/workflow-manager.js +359 -0
- package/dist/workflow/workflow-manager.js.map +1 -0
- package/dist/workflow/workflows/design-and-code/README.md +50 -0
- package/dist/workflow/workflows/design-and-code/workflow.yaml +169 -0
- package/dist/workflow/workflows/deterministic-eval-smoke/scripts/format_report.js +29 -0
- package/dist/workflow/workflows/deterministic-eval-smoke/scripts/package.json +5 -0
- package/dist/workflow/workflows/deterministic-eval-smoke/scripts/requirements.txt +1 -0
- package/dist/workflow/workflows/deterministic-eval-smoke/scripts/run_eval.py +41 -0
- package/dist/workflow/workflows/deterministic-eval-smoke/workflow.yaml +57 -0
- package/dist/workflow/workflows/deterministic-verdict-smoke/scripts/classify.py +18 -0
- package/dist/workflow/workflows/deterministic-verdict-smoke/workflow.yaml +51 -0
- package/dist/workflow/workflows/evolve/scripts/LICENSE +201 -0
- package/dist/workflow/workflows/evolve/scripts/README.md +314 -0
- package/dist/workflow/workflows/evolve/scripts/evolve-brief +16 -0
- package/dist/workflow/workflows/evolve/scripts/evolve-cognition +16 -0
- package/dist/workflow/workflows/evolve/scripts/evolve-db +16 -0
- package/dist/workflow/workflows/evolve/scripts/evolve-eval +16 -0
- package/dist/workflow/workflows/evolve/scripts/evolve-files +16 -0
- package/dist/workflow/workflows/evolve/scripts/evolve-summary +16 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/__init__.py +14 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/__init__.py +17 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/base.py +21 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/factory.py +90 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/greedy.py +17 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/island.py +316 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/random.py +18 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/algorithms/ucb1.py +55 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/best_snapshot.py +62 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/cli.py +752 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/cognition.py +127 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/database.py +218 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/diff.py +57 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/embedding.py +84 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/file_lock.py +45 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/run_state.py +343 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/sampling_config.py +173 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/structures.py +93 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_core/vector_index.py +191 -0
- package/dist/workflow/workflows/evolve/scripts/evolve_result.py +1503 -0
- package/dist/workflow/workflows/evolve/scripts/requirements.txt +2 -0
- package/dist/workflow/workflows/evolve/workflow.yaml +646 -0
- package/dist/workflow/workflows/test-email-summary/skills/email-formatting/SKILL.md +55 -0
- package/dist/workflow/workflows/test-email-summary/skills/gmail-query-syntax/SKILL.md +63 -0
- package/dist/workflow/workflows/test-email-summary/skills/json-schema-emails/SKILL.md +41 -0
- package/dist/workflow/workflows/test-email-summary/skills/json-schema-emails/schema.json +34 -0
- package/dist/workflow/workflows/test-email-summary/skills/summary-style-guide/SKILL.md +51 -0
- package/dist/workflow/workflows/test-email-summary/workflow.yaml +90 -0
- package/dist/workflow/workflows/vuln-discovery/skills/harness-design-fuzzing/SKILL.md +206 -0
- package/dist/workflow/workflows/vuln-discovery/skills/memory-safety-c-cpp/SKILL.md +167 -0
- package/dist/workflow/workflows/vuln-discovery/skills/vulnerability-triage/SKILL.md +189 -0
- package/dist/workflow/workflows/vuln-discovery/workflow.yaml +925 -0
- package/dist/workflow/worktree.d.ts +43 -0
- package/dist/workflow/worktree.js +106 -0
- package/dist/workflow/worktree.js.map +1 -0
- package/docker/Dockerfile.base +31 -0
- package/docker/Dockerfile.base.arm64 +27 -0
- package/docker/Dockerfile.claude-code +3 -1
- package/docker/Dockerfile.codex +17 -0
- package/docker/Dockerfile.goose +3 -1
- package/docker/entrypoint-claude-code.sh +7 -0
- package/docker/entrypoint-codex.sh +42 -0
- package/docker/entrypoint-goose.sh +6 -0
- package/docker/entrypoint-uid-remap.sh +93 -0
- package/package.json +27 -11
- package/packages/web-ui/README.md +113 -0
- package/packages/web-ui/docs/workflow-state-machine.png +0 -0
- package/src/config/generated/compiled-policy.json +528 -161
- package/src/config/generated/test-scenarios.json +4810 -170
- package/src/config/generated/tool-annotations.json +34 -47
- package/src/config/mcp-servers.json +2 -2
- package/src/workflow/workflows/design-and-code/README.md +50 -0
- package/src/workflow/workflows/design-and-code/workflow.yaml +169 -0
- package/src/workflow/workflows/deterministic-eval-smoke/scripts/format_report.js +29 -0
- package/src/workflow/workflows/deterministic-eval-smoke/scripts/package.json +5 -0
- package/src/workflow/workflows/deterministic-eval-smoke/scripts/requirements.txt +1 -0
- package/src/workflow/workflows/deterministic-eval-smoke/scripts/run_eval.py +41 -0
- package/src/workflow/workflows/deterministic-eval-smoke/workflow.yaml +57 -0
- package/src/workflow/workflows/deterministic-verdict-smoke/scripts/classify.py +18 -0
- package/src/workflow/workflows/deterministic-verdict-smoke/workflow.yaml +51 -0
- package/src/workflow/workflows/evolve/scripts/LICENSE +201 -0
- package/src/workflow/workflows/evolve/scripts/README.md +314 -0
- package/src/workflow/workflows/evolve/scripts/evolve-brief +16 -0
- package/src/workflow/workflows/evolve/scripts/evolve-cognition +16 -0
- package/src/workflow/workflows/evolve/scripts/evolve-db +16 -0
- package/src/workflow/workflows/evolve/scripts/evolve-eval +16 -0
- package/src/workflow/workflows/evolve/scripts/evolve-files +16 -0
- package/src/workflow/workflows/evolve/scripts/evolve-summary +16 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/__init__.py +14 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/__init__.py +17 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/base.py +21 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/factory.py +90 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/greedy.py +17 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/island.py +316 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/random.py +18 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/algorithms/ucb1.py +55 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/best_snapshot.py +62 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/cli.py +752 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/cognition.py +127 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/database.py +218 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/diff.py +57 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/embedding.py +84 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/file_lock.py +45 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/run_state.py +343 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/sampling_config.py +173 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/structures.py +93 -0
- package/src/workflow/workflows/evolve/scripts/evolve_core/vector_index.py +191 -0
- package/src/workflow/workflows/evolve/scripts/evolve_result.py +1503 -0
- package/src/workflow/workflows/evolve/scripts/requirements.txt +2 -0
- package/src/workflow/workflows/evolve/workflow.yaml +646 -0
- package/src/workflow/workflows/test-email-summary/skills/email-formatting/SKILL.md +55 -0
- package/src/workflow/workflows/test-email-summary/skills/gmail-query-syntax/SKILL.md +63 -0
- package/src/workflow/workflows/test-email-summary/skills/json-schema-emails/SKILL.md +41 -0
- package/src/workflow/workflows/test-email-summary/skills/json-schema-emails/schema.json +34 -0
- package/src/workflow/workflows/test-email-summary/skills/summary-style-guide/SKILL.md +51 -0
- package/src/workflow/workflows/test-email-summary/workflow.yaml +90 -0
- package/src/workflow/workflows/vuln-discovery/skills/harness-design-fuzzing/SKILL.md +206 -0
- package/src/workflow/workflows/vuln-discovery/skills/memory-safety-c-cpp/SKILL.md +167 -0
- package/src/workflow/workflows/vuln-discovery/skills/vulnerability-triage/SKILL.md +189 -0
- package/src/workflow/workflows/vuln-discovery/workflow.yaml +925 -0
- package/dist/pipeline/llm-logger.js.map +0 -1
- package/dist/session/errors.js.map +0 -1
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { ResolvedSkill, SkillDiscoveryError, SkillDiscoveryErrorReason, SkillFrontmatter, SkillSource, } from './types.js';
|
|
2
|
+
export { ACTIONABLE_DISCOVERY_REASONS, discoverSkills, discoverSkillsWithErrors, resolveSkillsForSession, } from './discovery.js';
|
|
3
|
+
export type { DiscoverSkillsResult, ResolveSkillsOptions } from './discovery.js';
|
|
4
|
+
export { stageSkillsToBundle, createCachedStager, validateSkillName } from './staging.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skills/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,4BAA4B,EAC5B,cAAc,EACd,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ResolvedSkill } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Rejects skill names whose `resolve(destDir, name)` would either
|
|
4
|
+
* overlay the staging root (`''`, `.`), escape it (`..`), or nest
|
|
5
|
+
* beneath it (`/`, `\\`) — the container's one-level walk only sees
|
|
6
|
+
* `<root>/<name>/SKILL.md`. Throws on rejection.
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateSkillName(name: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Replaces the contents of `destDir` with the resolved set: each skill
|
|
11
|
+
* is copied to `<destDir>/<skill.name>/`. Skill names are validated by
|
|
12
|
+
* {@link validateSkillName}.
|
|
13
|
+
*
|
|
14
|
+
* Wipes children individually rather than the parent itself. Workflow
|
|
15
|
+
* bundles bind-mount this directory into a long-lived container; on
|
|
16
|
+
* Linux a bind mount pins the source's inode at mount time, so removing
|
|
17
|
+
* and recreating the parent dir leaves the container's mount pointing
|
|
18
|
+
* at the freed (now-empty) inode. Per-child cleanup keeps the parent
|
|
19
|
+
* inode stable across re-stages.
|
|
20
|
+
*/
|
|
21
|
+
export declare function stageSkillsToBundle(skills: readonly ResolvedSkill[], destDir: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Builds a `stage(skills)` closure pinned to `destDir` that skips the
|
|
24
|
+
* wipe-and-rebuild when the resolved set is byte-identical to the
|
|
25
|
+
* previous call. Used by workflow bundles to keep state-transition
|
|
26
|
+
* latency near-zero when consecutive states resolve to the same skills.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createCachedStager(destDir: string): (skills: readonly ResolvedSkill[]) => boolean;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { cpSync, mkdirSync, readdirSync, rmSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
/** Stable signature for change-detection in `createCachedStager`. */
|
|
4
|
+
function computeSignature(skills) {
|
|
5
|
+
return skills
|
|
6
|
+
.map((s) => `${s.name}\0${s.sourceDir}`)
|
|
7
|
+
.sort()
|
|
8
|
+
.join('\n');
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Rejects skill names whose `resolve(destDir, name)` would either
|
|
12
|
+
* overlay the staging root (`''`, `.`), escape it (`..`), or nest
|
|
13
|
+
* beneath it (`/`, `\\`) — the container's one-level walk only sees
|
|
14
|
+
* `<root>/<name>/SKILL.md`. Throws on rejection.
|
|
15
|
+
*/
|
|
16
|
+
export function validateSkillName(name) {
|
|
17
|
+
if (name === '') {
|
|
18
|
+
throw new Error('Invalid skill name: name is empty');
|
|
19
|
+
}
|
|
20
|
+
if (name === '.' || name === '..') {
|
|
21
|
+
throw new Error(`Invalid skill name: "${name}" is not a valid directory name`);
|
|
22
|
+
}
|
|
23
|
+
if (name.includes('/') || name.includes('\\')) {
|
|
24
|
+
throw new Error(`Invalid skill name: "${name}" contains a path separator`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Replaces the contents of `destDir` with the resolved set: each skill
|
|
29
|
+
* is copied to `<destDir>/<skill.name>/`. Skill names are validated by
|
|
30
|
+
* {@link validateSkillName}.
|
|
31
|
+
*
|
|
32
|
+
* Wipes children individually rather than the parent itself. Workflow
|
|
33
|
+
* bundles bind-mount this directory into a long-lived container; on
|
|
34
|
+
* Linux a bind mount pins the source's inode at mount time, so removing
|
|
35
|
+
* and recreating the parent dir leaves the container's mount pointing
|
|
36
|
+
* at the freed (now-empty) inode. Per-child cleanup keeps the parent
|
|
37
|
+
* inode stable across re-stages.
|
|
38
|
+
*/
|
|
39
|
+
export function stageSkillsToBundle(skills, destDir) {
|
|
40
|
+
const normalizedDestDir = resolve(destDir);
|
|
41
|
+
mkdirSync(normalizedDestDir, { recursive: true });
|
|
42
|
+
for (const entry of readdirSync(normalizedDestDir)) {
|
|
43
|
+
rmSync(resolve(normalizedDestDir, entry), { recursive: true, force: true });
|
|
44
|
+
}
|
|
45
|
+
for (const skill of skills) {
|
|
46
|
+
validateSkillName(skill.name);
|
|
47
|
+
const target = resolve(normalizedDestDir, skill.name);
|
|
48
|
+
cpSync(skill.sourceDir, target, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Builds a `stage(skills)` closure pinned to `destDir` that skips the
|
|
53
|
+
* wipe-and-rebuild when the resolved set is byte-identical to the
|
|
54
|
+
* previous call. Used by workflow bundles to keep state-transition
|
|
55
|
+
* latency near-zero when consecutive states resolve to the same skills.
|
|
56
|
+
*/
|
|
57
|
+
export function createCachedStager(destDir) {
|
|
58
|
+
let lastSignature;
|
|
59
|
+
return (skills) => {
|
|
60
|
+
const signature = computeSignature(skills);
|
|
61
|
+
if (signature === lastSignature)
|
|
62
|
+
return false;
|
|
63
|
+
stageSkillsToBundle(skills, destDir);
|
|
64
|
+
lastSignature = signature;
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=staging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staging.js","sourceRoot":"","sources":["../../src/skills/staging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,qEAAqE;AACrE,SAAS,gBAAgB,CAAC,MAAgC;IACxD,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;SACvC,IAAI,EAAE;SACN,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,iCAAiC,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,6BAA6B,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAgC,EAAE,OAAe;IACnF,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,SAAS,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,IAAI,aAAiC,CAAC;IACtC,OAAO,CAAC,MAAM,EAAE,EAAE;QAChB,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,SAAS,KAAK,aAAa;YAAE,OAAO,KAAK,CAAC;QAC9C,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrC,aAAa,GAAG,SAAS,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface SkillFrontmatter {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly description: string;
|
|
4
|
+
readonly [extra: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** Layer of origin; determines precedence in `resolveSkillsForSession` (workflow > persona > user). */
|
|
7
|
+
export type SkillSource = 'user' | 'persona' | 'workflow';
|
|
8
|
+
export interface ResolvedSkill {
|
|
9
|
+
/** From the frontmatter — not the directory name; collision key during layering. */
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly source: SkillSource;
|
|
12
|
+
/** Absolute host path; copied recursively by `stageSkillsToBundle`. */
|
|
13
|
+
readonly sourceDir: string;
|
|
14
|
+
readonly description: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Why a candidate skill directory could not be resolved into a
|
|
18
|
+
* `ResolvedSkill`. Surfaced through `discoverSkillsWithErrors` so
|
|
19
|
+
* runtime sessions and the workflow lint surface can give authors
|
|
20
|
+
* actionable feedback instead of a silently-empty skills set.
|
|
21
|
+
*
|
|
22
|
+
* - `missing-manifest`: directory has no `SKILL.md`. Often legitimate
|
|
23
|
+
* (e.g., a `node_modules/` or `.git/` subdir under the skills root),
|
|
24
|
+
* so the runtime wrapper does NOT log this — only consumers that
|
|
25
|
+
* walked a known skills tree (e.g., a workflow package) should
|
|
26
|
+
* surface it as a warning.
|
|
27
|
+
* - `unreadable`: `readFileSync` failed (permission error, etc.).
|
|
28
|
+
* - `malformed-frontmatter`: the `---` fence is missing, or the YAML
|
|
29
|
+
* between fences failed to parse, or the parsed value isn't an object.
|
|
30
|
+
* - `missing-required-fields`: frontmatter parsed but `name` or
|
|
31
|
+
* `description` is missing or non-string.
|
|
32
|
+
* - `duplicate-name`: two or more skill directories under the same
|
|
33
|
+
* skills root resolve to the same frontmatter `name`. Composition is
|
|
34
|
+
* keyed on the frontmatter name, so duplicates are non-deterministic
|
|
35
|
+
* without a tiebreaker. Reported once per losing entry; the winner
|
|
36
|
+
* (lexicographically-first directory name) is yielded as a normal
|
|
37
|
+
* `ResolvedSkill`.
|
|
38
|
+
*/
|
|
39
|
+
export type SkillDiscoveryErrorReason = 'missing-manifest' | 'unreadable' | 'malformed-frontmatter' | 'missing-required-fields' | 'duplicate-name';
|
|
40
|
+
export interface SkillDiscoveryError {
|
|
41
|
+
/** Absolute path to the offending directory under the skills root. */
|
|
42
|
+
readonly skillDir: string;
|
|
43
|
+
readonly reason: SkillDiscoveryErrorReason;
|
|
44
|
+
/** Optional extra context (e.g., the YAML parse error message). */
|
|
45
|
+
readonly detail?: string;
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/skills/types.ts"],"names":[],"mappings":""}
|
|
@@ -58,8 +58,6 @@ export interface WhitelistPattern {
|
|
|
58
58
|
export interface WhitelistCandidateIpc {
|
|
59
59
|
/** Human-readable summary, e.g. "Allow write_file within /home/user/Documents" */
|
|
60
60
|
readonly description: string;
|
|
61
|
-
/** Warning for zero-constraint side-effectful patterns. */
|
|
62
|
-
readonly warning?: string;
|
|
63
61
|
}
|
|
64
62
|
/**
|
|
65
63
|
* Result of a whitelist match check.
|
|
@@ -74,8 +74,14 @@ export function extractWhitelistCandidates(serverName, toolName, args, annotatio
|
|
|
74
74
|
// Determine which roles to extract constraints for
|
|
75
75
|
const rolesToExtract = escalatedRoles ?? collectDistinctRoles(annotation);
|
|
76
76
|
const constraints = buildConstraints(rolesToExtract, args, annotation);
|
|
77
|
+
// Zero-constraint patterns would blanket-approve ALL future calls to the tool.
|
|
78
|
+
// This happens when a tool's arguments only have 'none' roles (no resource
|
|
79
|
+
// identifiers). Refuse to offer whitelisting in this case — each invocation
|
|
80
|
+
// must be individually approved.
|
|
81
|
+
if (constraints.length === 0) {
|
|
82
|
+
return { patterns: [], ipcs: [] };
|
|
83
|
+
}
|
|
77
84
|
const description = buildDescription(serverName, toolName, constraints);
|
|
78
|
-
const warning = buildWarning(constraints);
|
|
79
85
|
const pattern = {
|
|
80
86
|
serverName,
|
|
81
87
|
toolName,
|
|
@@ -87,7 +93,6 @@ export function extractWhitelistCandidates(serverName, toolName, args, annotatio
|
|
|
87
93
|
};
|
|
88
94
|
const ipc = {
|
|
89
95
|
description,
|
|
90
|
-
...(warning ? { warning } : {}),
|
|
91
96
|
};
|
|
92
97
|
// Phase 1: returns a single candidate pattern. The array-based return type and
|
|
93
98
|
// whitelistSelection index in the IPC protocol are designed to support future
|
|
@@ -172,9 +177,6 @@ function buildConstraintForRole(role, category, value) {
|
|
|
172
177
|
* Builds a human-readable description from constraints.
|
|
173
178
|
*/
|
|
174
179
|
function buildDescription(serverName, toolName, constraints) {
|
|
175
|
-
if (constraints.length === 0) {
|
|
176
|
-
return `Allow ${serverName}/${toolName} (exact tool match only)`;
|
|
177
|
-
}
|
|
178
180
|
const parts = constraints.map((c) => {
|
|
179
181
|
switch (c.kind) {
|
|
180
182
|
case 'directory':
|
|
@@ -187,15 +189,6 @@ function buildDescription(serverName, toolName, constraints) {
|
|
|
187
189
|
});
|
|
188
190
|
return `Allow ${serverName}/${toolName} ${parts.join(', ')}`;
|
|
189
191
|
}
|
|
190
|
-
/**
|
|
191
|
-
* Generates a warning for zero-constraint tools.
|
|
192
|
-
*/
|
|
193
|
-
function buildWarning(constraints) {
|
|
194
|
-
if (constraints.length === 0) {
|
|
195
|
-
return 'Whitelisting will auto-approve ALL future calls to this tool for this session.';
|
|
196
|
-
}
|
|
197
|
-
return undefined;
|
|
198
|
-
}
|
|
199
192
|
// ---------------------------------------------------------------------------
|
|
200
193
|
// Factory
|
|
201
194
|
// ---------------------------------------------------------------------------
|
|
@@ -206,6 +199,12 @@ export function createApprovalWhitelist() {
|
|
|
206
199
|
const patterns = [];
|
|
207
200
|
return {
|
|
208
201
|
add(patternData) {
|
|
202
|
+
// Defense-in-depth: reject zero-constraint patterns that would blanket-approve
|
|
203
|
+
// all calls to a tool. extractWhitelistCandidates() already prevents this, but
|
|
204
|
+
// guard here too so a future caller can't reintroduce the vulnerability.
|
|
205
|
+
if (patternData.constraints.length === 0) {
|
|
206
|
+
throw new Error(`Refusing to add zero-constraint whitelist pattern for ${patternData.serverName}/${patternData.toolName}`);
|
|
207
|
+
}
|
|
209
208
|
const id = uuidv4();
|
|
210
209
|
const pattern = { ...patternData, id };
|
|
211
210
|
patterns.push(pattern);
|
|
@@ -217,9 +216,10 @@ export function createApprovalWhitelist() {
|
|
|
217
216
|
continue;
|
|
218
217
|
if (pattern.toolName !== toolName)
|
|
219
218
|
continue;
|
|
220
|
-
// All constraints must match (AND semantics)
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
// All constraints must match (AND semantics).
|
|
220
|
+
// Zero-constraint patterns are rejected by add(), so every pattern
|
|
221
|
+
// here has at least one constraint to evaluate.
|
|
222
|
+
const allMatch = pattern.constraints.every((c) => constraintMatches(c, resolvedArgs, annotation));
|
|
223
223
|
if (allMatch) {
|
|
224
224
|
return { matched: true, patternId: pattern.id, pattern };
|
|
225
225
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-whitelist.js","sourceRoot":"","sources":["../../src/trusted-process/approval-whitelist.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"approval-whitelist.js","sourceRoot":"","sources":["../../src/trusted-process/approval-whitelist.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAuEjF,kFAAkF;AAClF,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,kBAAkB,EAAE,CAAC,EAAW,CAAC;AA8B5E,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAE9E,MAAM,uBAAuB,GAA8B,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAExG,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E;;GAEG;AACH,SAAS,iBAAiB,CACxB,UAA+B,EAC/B,IAA6B,EAC7B,UAA0B;IAE1B,qDAAqD;IACrD,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEtC,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,WAAW;YACd,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;gBACxB,IAAI,CAAC;oBACH,OAAO,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;gBACpD,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CAAC;QACL,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;gBACxB,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBAC3C,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;oBACjE,OAAO,MAAM,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBAClE,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,0BAA0B,CACxC,UAAkB,EAClB,QAAgB,EAChB,IAA6B,EAC7B,UAA0B,EAC1B,cAAmD,EACnD,YAAoB,EACpB,gBAAwB;IAExB,mDAAmD;IACnD,MAAM,cAAc,GAAG,cAAc,IAAI,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAE1E,MAAM,WAAW,GAAG,gBAAgB,CAAC,cAAc,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAEvE,+EAA+E;IAC/E,2EAA2E;IAC3E,4EAA4E;IAC5E,iCAAiC;IACjC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAExE,MAAM,OAAO,GAAiC;QAC5C,UAAU;QACV,QAAQ;QACR,WAAW;QACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,kBAAkB,EAAE,YAAY;QAChC,cAAc,EAAE,gBAAgB;QAChC,WAAW;KACZ,CAAC;IAEF,MAAM,GAAG,GAA0B;QACjC,WAAW;KACZ,CAAC;IAEF,+EAA+E;IAC/E,8EAA8E;IAC9E,uFAAuF;IACvF,OAAO,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,KAA8B,EAC9B,IAA6B,EAC7B,UAA0B;IAE1B,MAAM,WAAW,GAA0B,EAAE,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAE/D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACzE,IAAI,CAAC,UAAU;gBAAE,SAAS;YAE1B,yDAAyD;YACzD,MAAM,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,qDAAqD;AACrD,SAAS,aAAa,CAAC,CAAsB;IAC3C,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QACxC,KAAK,QAAQ;YACX,OAAO,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACrC,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,IAAkB,EAAE,QAAgB,EAAE,KAAa;IACjF,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,qEAAqE;YACrE,IAAI,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;YACxD,IAAI,CAAC;gBACH,0EAA0E;gBAC1E,+EAA+E;gBAC/E,2EAA2E;gBAC3E,8EAA8E;gBAC9E,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;gBAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;gBAClC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;YACrD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC/C,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;gBACtD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7D;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,UAAkB,EAAE,QAAgB,EAAE,WAA2C;IACzG,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAClC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,WAAW;gBACd,OAAO,GAAG,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;YAC3C,KAAK,QAAQ;gBACX,OAAO,GAAG,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC;YACxC,KAAK,OAAO;gBACV,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,SAAS,UAAU,IAAI,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IAExC,OAAO;QACL,GAAG,CAAC,WAAyC;YAC3C,+EAA+E;YAC/E,+EAA+E;YAC/E,yEAAyE;YACzE,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,KAAK,CACb,yDAAyD,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,QAAQ,EAAE,CAC1G,CAAC;YACJ,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,EAAsB,CAAC;YACxC,MAAM,OAAO,GAAqB,EAAE,GAAG,WAAW,EAAE,EAAE,EAAE,CAAC;YACzD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,KAAK,CACH,UAAkB,EAClB,QAAgB,EAChB,YAAqC,EACrC,UAA0B;YAE1B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,OAAO,CAAC,UAAU,KAAK,UAAU;oBAAE,SAAS;gBAChD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;oBAAE,SAAS;gBAE5C,8CAA8C;gBAC9C,mEAAmE;gBACnE,gDAAgD;gBAChD,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;gBAElG,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC;gBAC3D,CAAC;YACH,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO;YACL,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,IAAI;YACN,OAAO,QAAQ,CAAC,MAAM,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal async mutex for serializing access to coordinator-owned state.
|
|
3
|
+
*
|
|
4
|
+
* Used by ToolCallCoordinator to:
|
|
5
|
+
* - Serialize concurrent handleToolCall invocations against each other
|
|
6
|
+
* (protects ApprovalWhitelist, CallCircuitBreaker, ServerContextMap
|
|
7
|
+
* from read-modify-write races)
|
|
8
|
+
* - Reserve a separate lock for future loadPolicy operations
|
|
9
|
+
*
|
|
10
|
+
* Implementation notes:
|
|
11
|
+
* - Single-threaded: `Node.js` concurrency happens only at await points,
|
|
12
|
+
* so a simple promise-chain mutex is sufficient.
|
|
13
|
+
* - Fair FIFO order: each acquirer receives a release token after the
|
|
14
|
+
* previous holder's promise resolves. No priority inversion risk.
|
|
15
|
+
* - Non-reentrant: a holder that calls `acquire()` recursively will deadlock.
|
|
16
|
+
*/
|
|
17
|
+
export declare class AsyncMutex {
|
|
18
|
+
private waitTail;
|
|
19
|
+
/**
|
|
20
|
+
* Acquires the mutex, returning a `release()` function.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* const release = await mutex.acquire();
|
|
24
|
+
* try { ... } finally { release(); }
|
|
25
|
+
*/
|
|
26
|
+
acquire(): Promise<() => void>;
|
|
27
|
+
/**
|
|
28
|
+
* Runs `fn` while holding the mutex. Preferred form for call sites
|
|
29
|
+
* that do not need manual release control.
|
|
30
|
+
*/
|
|
31
|
+
withLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal async mutex for serializing access to coordinator-owned state.
|
|
3
|
+
*
|
|
4
|
+
* Used by ToolCallCoordinator to:
|
|
5
|
+
* - Serialize concurrent handleToolCall invocations against each other
|
|
6
|
+
* (protects ApprovalWhitelist, CallCircuitBreaker, ServerContextMap
|
|
7
|
+
* from read-modify-write races)
|
|
8
|
+
* - Reserve a separate lock for future loadPolicy operations
|
|
9
|
+
*
|
|
10
|
+
* Implementation notes:
|
|
11
|
+
* - Single-threaded: `Node.js` concurrency happens only at await points,
|
|
12
|
+
* so a simple promise-chain mutex is sufficient.
|
|
13
|
+
* - Fair FIFO order: each acquirer receives a release token after the
|
|
14
|
+
* previous holder's promise resolves. No priority inversion risk.
|
|
15
|
+
* - Non-reentrant: a holder that calls `acquire()` recursively will deadlock.
|
|
16
|
+
*/
|
|
17
|
+
export class AsyncMutex {
|
|
18
|
+
waitTail = Promise.resolve();
|
|
19
|
+
/**
|
|
20
|
+
* Acquires the mutex, returning a `release()` function.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* const release = await mutex.acquire();
|
|
24
|
+
* try { ... } finally { release(); }
|
|
25
|
+
*/
|
|
26
|
+
async acquire() {
|
|
27
|
+
let release;
|
|
28
|
+
const next = new Promise((resolve) => {
|
|
29
|
+
release = resolve;
|
|
30
|
+
});
|
|
31
|
+
const prior = this.waitTail;
|
|
32
|
+
this.waitTail = next;
|
|
33
|
+
await prior;
|
|
34
|
+
return release;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Runs `fn` while holding the mutex. Preferred form for call sites
|
|
38
|
+
* that do not need manual release control.
|
|
39
|
+
*/
|
|
40
|
+
async withLock(fn) {
|
|
41
|
+
const release = await this.acquire();
|
|
42
|
+
try {
|
|
43
|
+
return await fn();
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
release();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=async-mutex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-mutex.js","sourceRoot":"","sources":["../../src/trusted-process/async-mutex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,UAAU;IACb,QAAQ,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEpD;;;;;;OAMG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,OAAoB,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACzC,OAAO,GAAG,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,KAAK,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAI,EAAoB;QACpC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -3,10 +3,47 @@ export interface AuditLogOptions {
|
|
|
3
3
|
/** When true, PII/credential patterns are redacted before writing. */
|
|
4
4
|
redact?: boolean;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Append-only JSONL writer for audit entries.
|
|
8
|
+
*
|
|
9
|
+
* Writes are synchronous (`appendFileSync`) for two reasons: durability
|
|
10
|
+
* and read-after-write determinism. An async `WriteStream` buffers
|
|
11
|
+
* chunks and flushes them on the event loop; on fast machines (the CI
|
|
12
|
+
* ubuntu-latest runner being the motivating case) the test/inspection
|
|
13
|
+
* code can call `readFileSync(auditPath)` before the last write has
|
|
14
|
+
* reached disk. More importantly, a process crash between a policy
|
|
15
|
+
* decision and the next flush would silently drop the audit entry for
|
|
16
|
+
* that decision — the exact window where durability matters most. The
|
|
17
|
+
* sibling logger (`src/logger.ts`) uses the same pattern for the same
|
|
18
|
+
* reason. Since `rotate()` was removed in the coordinator redesign,
|
|
19
|
+
* this class's only remaining job is one append per tool call, which
|
|
20
|
+
* does not justify the async buffering machinery.
|
|
21
|
+
*
|
|
22
|
+
* Each coordinator owns exactly one `AuditLog` targeting a single file
|
|
23
|
+
* for its entire lifetime. Workflow runs write one file per run
|
|
24
|
+
* (entries tagged with `persona` so consumers can slice by re-entry);
|
|
25
|
+
* single-session modes write one file per session. Policy hot-swap
|
|
26
|
+
* only updates `currentPersona` on the coordinator and all entries
|
|
27
|
+
* continue to land in the same file.
|
|
28
|
+
*/
|
|
6
29
|
export declare class AuditLog {
|
|
7
|
-
private
|
|
30
|
+
private readonly path;
|
|
8
31
|
private readonly redact;
|
|
32
|
+
private closed;
|
|
33
|
+
private streamError;
|
|
9
34
|
constructor(path: string, options?: AuditLogOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Appends a single audit entry to the log file.
|
|
37
|
+
*
|
|
38
|
+
* A trusted process that cannot audit is a security violation: we
|
|
39
|
+
* fail loudly rather than silently drop entries. If a previous write
|
|
40
|
+
* failed, we rethrow the cached error without attempting a new write
|
|
41
|
+
* so the caller sees a deterministic, idempotent failure surface.
|
|
42
|
+
*
|
|
43
|
+
* @throws if called after `close()`.
|
|
44
|
+
* @throws if any previous write (or the ctor's `mkdirSync`) failed.
|
|
45
|
+
* @throws if this write fails (ENOSPC, EACCES, etc.).
|
|
46
|
+
*/
|
|
10
47
|
log(entry: AuditEntry): void;
|
|
11
48
|
close(): Promise<void>;
|
|
12
49
|
}
|
|
@@ -1,25 +1,94 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
2
3
|
import { redactObject } from './audit-redactor.js';
|
|
4
|
+
/**
|
|
5
|
+
* Append-only JSONL writer for audit entries.
|
|
6
|
+
*
|
|
7
|
+
* Writes are synchronous (`appendFileSync`) for two reasons: durability
|
|
8
|
+
* and read-after-write determinism. An async `WriteStream` buffers
|
|
9
|
+
* chunks and flushes them on the event loop; on fast machines (the CI
|
|
10
|
+
* ubuntu-latest runner being the motivating case) the test/inspection
|
|
11
|
+
* code can call `readFileSync(auditPath)` before the last write has
|
|
12
|
+
* reached disk. More importantly, a process crash between a policy
|
|
13
|
+
* decision and the next flush would silently drop the audit entry for
|
|
14
|
+
* that decision — the exact window where durability matters most. The
|
|
15
|
+
* sibling logger (`src/logger.ts`) uses the same pattern for the same
|
|
16
|
+
* reason. Since `rotate()` was removed in the coordinator redesign,
|
|
17
|
+
* this class's only remaining job is one append per tool call, which
|
|
18
|
+
* does not justify the async buffering machinery.
|
|
19
|
+
*
|
|
20
|
+
* Each coordinator owns exactly one `AuditLog` targeting a single file
|
|
21
|
+
* for its entire lifetime. Workflow runs write one file per run
|
|
22
|
+
* (entries tagged with `persona` so consumers can slice by re-entry);
|
|
23
|
+
* single-session modes write one file per session. Policy hot-swap
|
|
24
|
+
* only updates `currentPersona` on the coordinator and all entries
|
|
25
|
+
* continue to land in the same file.
|
|
26
|
+
*/
|
|
3
27
|
export class AuditLog {
|
|
4
|
-
|
|
28
|
+
path;
|
|
5
29
|
redact;
|
|
30
|
+
closed = false;
|
|
31
|
+
// Latched write error. Once any `appendFileSync` has failed (ENOSPC,
|
|
32
|
+
// EACCES, missing parent dir that was deleted mid-session, etc.) we
|
|
33
|
+
// stop attempting further writes and rethrow the cached error on
|
|
34
|
+
// every subsequent `log()` call. This preserves the "fail-closed"
|
|
35
|
+
// invariant: a trusted process that cannot audit must stop
|
|
36
|
+
// processing tool calls, and must report the same root-cause error
|
|
37
|
+
// each time it's asked to audit afterwards.
|
|
38
|
+
streamError = null;
|
|
6
39
|
constructor(path, options) {
|
|
7
|
-
this.
|
|
40
|
+
this.path = path;
|
|
41
|
+
// Match the old `createWriteStream` behavior of auto-creating the
|
|
42
|
+
// parent directory for common session/workflow layouts. If this
|
|
43
|
+
// itself fails (e.g., a path component is a file), we latch the
|
|
44
|
+
// error so the first `log()` rethrows it synchronously — the
|
|
45
|
+
// caller experiences the same fail-closed contract either way.
|
|
46
|
+
try {
|
|
47
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
this.streamError = err instanceof Error ? err : new Error(String(err));
|
|
51
|
+
}
|
|
8
52
|
this.redact = options?.redact ?? false;
|
|
9
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Appends a single audit entry to the log file.
|
|
56
|
+
*
|
|
57
|
+
* A trusted process that cannot audit is a security violation: we
|
|
58
|
+
* fail loudly rather than silently drop entries. If a previous write
|
|
59
|
+
* failed, we rethrow the cached error without attempting a new write
|
|
60
|
+
* so the caller sees a deterministic, idempotent failure surface.
|
|
61
|
+
*
|
|
62
|
+
* @throws if called after `close()`.
|
|
63
|
+
* @throws if any previous write (or the ctor's `mkdirSync`) failed.
|
|
64
|
+
* @throws if this write fails (ENOSPC, EACCES, etc.).
|
|
65
|
+
*/
|
|
10
66
|
log(entry) {
|
|
67
|
+
if (this.closed) {
|
|
68
|
+
throw new Error('AuditLog.log() called after close()');
|
|
69
|
+
}
|
|
70
|
+
if (this.streamError) {
|
|
71
|
+
throw new Error(`AuditLog stream error: ${this.streamError.message}`);
|
|
72
|
+
}
|
|
11
73
|
const toWrite = this.redact ? redactAuditEntry(entry) : entry;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
else
|
|
20
|
-
resolve();
|
|
74
|
+
try {
|
|
75
|
+
appendFileSync(this.path, JSON.stringify(toWrite) + '\n');
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
this.streamError = err instanceof Error ? err : new Error(String(err));
|
|
79
|
+
throw new Error(`AuditLog stream error: ${this.streamError.message}`, {
|
|
80
|
+
cause: err,
|
|
21
81
|
});
|
|
22
|
-
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
close() {
|
|
85
|
+
if (this.closed)
|
|
86
|
+
return Promise.resolve();
|
|
87
|
+
this.closed = true;
|
|
88
|
+
// Synchronous writes have nothing to flush and no fd to release.
|
|
89
|
+
// Returns a promise purely for API compatibility with the existing
|
|
90
|
+
// coordinator teardown path, which `await`s this call.
|
|
91
|
+
return Promise.resolve();
|
|
23
92
|
}
|
|
24
93
|
}
|
|
25
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/trusted-process/audit-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/trusted-process/audit-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
export interface CircuitBreakerConfig {
|
|
12
12
|
windowMs: number;
|
|
13
13
|
threshold: number;
|
|
14
|
+
/**
|
|
15
|
+
* Number of concurrent worker lanes expected to share this breaker.
|
|
16
|
+
* Identical calls from N lanes should consume N slots before the
|
|
17
|
+
* ordinary single-lane runaway threshold applies.
|
|
18
|
+
*/
|
|
19
|
+
workerCount: number;
|
|
14
20
|
}
|
|
15
21
|
export type CircuitBreakerVerdict = {
|
|
16
22
|
allowed: true;
|
|
@@ -9,15 +9,22 @@
|
|
|
9
9
|
* Runs AFTER policy evaluation so every call is always audited.
|
|
10
10
|
*/
|
|
11
11
|
import { computeHash } from '../hash.js';
|
|
12
|
+
import { ERROR_PREFIX_CIRCUIT_BREAKER } from './error-prefixes.js';
|
|
12
13
|
const DEFAULT_CONFIG = {
|
|
13
14
|
windowMs: 60_000,
|
|
14
15
|
threshold: 20,
|
|
16
|
+
workerCount: 1,
|
|
15
17
|
};
|
|
16
18
|
export class CallCircuitBreaker {
|
|
17
19
|
config;
|
|
18
20
|
windows = new Map();
|
|
19
21
|
constructor(config) {
|
|
20
|
-
|
|
22
|
+
const merged = { ...DEFAULT_CONFIG, ...config };
|
|
23
|
+
this.config = {
|
|
24
|
+
...merged,
|
|
25
|
+
threshold: Math.max(1, Math.floor(merged.threshold)),
|
|
26
|
+
workerCount: Math.max(1, Math.floor(merged.workerCount)),
|
|
27
|
+
};
|
|
21
28
|
}
|
|
22
29
|
/**
|
|
23
30
|
* Check whether a tool call should be allowed.
|
|
@@ -42,10 +49,23 @@ export class CallCircuitBreaker {
|
|
|
42
49
|
else if (firstValid === -1) {
|
|
43
50
|
timestamps.length = 0;
|
|
44
51
|
}
|
|
45
|
-
|
|
52
|
+
// Scale the GLOBAL per-`(tool:argsHash)` threshold by `workerCount` so
|
|
53
|
+
// N homogeneous lanes issuing the same call do not false-trip the
|
|
54
|
+
// single-lane runaway guard. Trade-off: because the window is keyed
|
|
55
|
+
// only by `(tool, argsHash)` and NOT by lane, this grants `threshold *
|
|
56
|
+
// workerCount` headroom to the WHOLE bucket -- so a single runaway lane
|
|
57
|
+
// gets `threshold * N` slots to itself, weakening the DoS guard by a
|
|
58
|
+
// factor of N. Harmless today (`workerCount` is always 1 in
|
|
59
|
+
// production). REQUIRED PREREQUISITE before any caller sets
|
|
60
|
+
// `workerCount > 1`: per-lane bucketing (key the window by lane id) so
|
|
61
|
+
// each lane keeps its own single-lane threshold. Lane ids do not exist
|
|
62
|
+
// yet, so this cannot be implemented here -- see
|
|
63
|
+
// docs/designs/evolve-sync-parallelism-slice.md §5.2.
|
|
64
|
+
const effectiveThreshold = this.config.threshold * this.config.workerCount;
|
|
65
|
+
if (timestamps.length >= effectiveThreshold) {
|
|
46
66
|
return {
|
|
47
67
|
allowed: false,
|
|
48
|
-
reason:
|
|
68
|
+
reason: `${ERROR_PREFIX_CIRCUIT_BREAKER} Tool '${toolName}' called ${effectiveThreshold} times ` +
|
|
49
69
|
`with identical arguments within ${this.config.windowMs / 1000}s window. ` +
|
|
50
70
|
'Try a different approach.',
|
|
51
71
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-circuit-breaker.js","sourceRoot":"","sources":["../../src/trusted-process/call-circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"call-circuit-breaker.js","sourceRoot":"","sources":["../../src/trusted-process/call-circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAanE,MAAM,cAAc,GAAyB;IAC3C,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,EAAE;IACb,WAAW,EAAE,CAAC;CACf,CAAC;AAIF,MAAM,OAAO,kBAAkB;IACZ,MAAM,CAAuB;IACtC,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAE9C,YAAY,MAAsC;QAChD,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,MAAM;YACT,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACpD,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;SACzD,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAgB,EAAE,IAA6B;QACnD,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,QAAQ,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAE1C,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,UAAU,GAAG,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACpC,CAAC;QAED,sCAAsC;QACtC,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAC3D,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,CAAC;QAED,uEAAuE;QACvE,kEAAkE;QAClE,oEAAoE;QACpE,uEAAuE;QACvE,wEAAwE;QACxE,qEAAqE;QACrE,4DAA4D;QAC5D,4DAA4D;QAC5D,uEAAuE;QACvE,uEAAuE;QACvE,iDAAiD;QACjD,sDAAsD;QACtD,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QAC3E,IAAI,UAAU,CAAC,MAAM,IAAI,kBAAkB,EAAE,CAAC;YAC5C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EACJ,GAAG,4BAA4B,UAAU,QAAQ,YAAY,kBAAkB,SAAS;oBACxF,mCAAmC,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,YAAY;oBAC1E,2BAA2B;aAC9B,CAAC;QACJ,CAAC;QAED,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,uBAAuB;IACvB,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
|