@provos/ironcurtain 0.10.0 → 0.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 +60 -8
- package/dist/auth/oauth-provider.js +1 -4
- package/dist/auth/oauth-provider.js.map +1 -1
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -1
- package/dist/config/config-command.js +162 -7
- package/dist/config/config-command.js.map +1 -1
- package/dist/config/first-start.js +61 -0
- 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/paths.d.ts +175 -0
- package/dist/config/paths.js +308 -14
- package/dist/config/paths.js.map +1 -1
- package/dist/config/types.d.ts +7 -1
- package/dist/config/user-config.d.ts +53 -5
- package/dist/config/user-config.js +96 -30
- 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 +16 -2
- package/dist/daemon/daemon-command.js.map +1 -1
- package/dist/daemon/ironcurtain-daemon.d.ts +44 -1
- package/dist/daemon/ironcurtain-daemon.js +210 -8
- package/dist/daemon/ironcurtain-daemon.js.map +1 -1
- package/dist/docker/adapters/claude-code.js +194 -20
- package/dist/docker/adapters/claude-code.js.map +1 -1
- 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 +178 -4
- package/dist/docker/agent-adapter.js +14 -0
- package/dist/docker/agent-adapter.js.map +1 -1
- package/dist/docker/code-mode-proxy.d.ts +27 -0
- package/dist/docker/code-mode-proxy.js +3 -0
- package/dist/docker/code-mode-proxy.js.map +1 -1
- package/dist/docker/docker-agent-session.d.ts +113 -62
- package/dist/docker/docker-agent-session.js +242 -294
- package/dist/docker/docker-agent-session.js.map +1 -1
- package/dist/docker/docker-infrastructure.d.ts +246 -21
- package/dist/docker/docker-infrastructure.js +520 -29
- package/dist/docker/docker-infrastructure.js.map +1 -1
- package/dist/docker/docker-manager.d.ts +36 -1
- package/dist/docker/docker-manager.js +135 -30
- package/dist/docker/docker-manager.js.map +1 -1
- 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 +84 -1
- package/dist/docker/mitm-proxy.js +380 -18
- package/dist/docker/mitm-proxy.js.map +1 -1
- package/dist/docker/oauth-credentials.d.ts +46 -3
- package/dist/docker/oauth-credentials.js +56 -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/provider-config.d.ts +49 -2
- package/dist/docker/provider-config.js +202 -28
- package/dist/docker/provider-config.js.map +1 -1
- 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 +49 -1
- package/dist/docker/pty-session.js +199 -69
- 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/resource-limits.d.ts +125 -0
- package/dist/docker/resource-limits.js +200 -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/types.d.ts +53 -6
- package/dist/doctor/checks.d.ts +138 -0
- package/dist/doctor/checks.js +511 -0
- package/dist/doctor/checks.js.map +1 -0
- package/dist/doctor/doctor-command.d.ts +29 -0
- package/dist/doctor/doctor-command.js +160 -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 +84 -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 +24 -9
- 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-command.d.ts +10 -1
- package/dist/mux/mux-command.js +56 -35
- 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/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 +298 -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/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 +41 -6
- package/dist/persona/persona-command.js.map +1 -1
- 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/types.d.ts +16 -0
- 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.js +89 -50
- package/dist/pipeline/pipeline-runner.js.map +1 -1
- package/dist/pipeline/pipeline-shared.d.ts +1 -1
- package/dist/pipeline/pipeline-shared.js +3 -11
- 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/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 +14 -0
- package/dist/sandbox/index.js +335 -116
- 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 +324 -130
- package/dist/session/index.js.map +1 -1
- package/dist/session/preflight.d.ts +50 -13
- package/dist/session/preflight.js +252 -80
- 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 +311 -5
- package/dist/session/types.js +57 -1
- package/dist/session/types.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.js +7 -1
- 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.js +2 -1
- package/dist/trusted-process/call-circuit-breaker.js.map +1 -1
- 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 +166 -657
- 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 +90 -45
- 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/tool-call-coordinator.d.ts +269 -0
- package/dist/trusted-process/tool-call-coordinator.js +508 -0
- package/dist/trusted-process/tool-call-coordinator.js.map +1 -0
- package/dist/trusted-process/tool-call-pipeline.d.ts +205 -0
- package/dist/trusted-process/tool-call-pipeline.js +798 -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/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/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 +6 -0
- package/dist/web-ui/dispatch/persona-dispatch.js +116 -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 +201 -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 +31 -0
- package/dist/web-ui/dispatch/types.js +68 -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 +925 -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 +152 -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 +76 -0
- package/dist/web-ui/web-ui-server.js +461 -0
- package/dist/web-ui/web-ui-server.js.map +1 -0
- package/dist/web-ui/web-ui-types.d.ts +290 -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-BFO5z1js.js +76 -0
- package/dist/web-ui-static/assets/index-CCUwrkIL.css +1 -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-support.d.ts +92 -0
- package/dist/workflow/cli-support.js +423 -0
- package/dist/workflow/cli-support.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 +78 -0
- package/dist/workflow/discovery.js +203 -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/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 +66 -0
- package/dist/workflow/lint.js +410 -0
- package/dist/workflow/lint.js.map +1 -0
- package/dist/workflow/machine-builder.d.ts +90 -0
- package/dist/workflow/machine-builder.js +485 -0
- package/dist/workflow/machine-builder.js.map +1 -0
- package/dist/workflow/message-log.d.ts +85 -0
- package/dist/workflow/message-log.js +40 -0
- package/dist/workflow/message-log.js.map +1 -0
- package/dist/workflow/orchestrator.d.ts +450 -0
- package/dist/workflow/orchestrator.js +1941 -0
- package/dist/workflow/orchestrator.js.map +1 -0
- package/dist/workflow/prompt-builder.d.ts +39 -0
- package/dist/workflow/prompt-builder.js +242 -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 +259 -0
- package/dist/workflow/status-parser.js.map +1 -0
- package/dist/workflow/types.d.ts +498 -0
- package/dist/workflow/types.js +83 -0
- package/dist/workflow/types.js.map +1 -0
- package/dist/workflow/validate.d.ts +58 -0
- package/dist/workflow/validate.js +499 -0
- package/dist/workflow/validate.js.map +1 -0
- package/dist/workflow/workflow-command.d.ts +26 -0
- package/dist/workflow/workflow-command.js +648 -0
- package/dist/workflow/workflow-command.js.map +1 -0
- package/dist/workflow/workflow-discovery.d.ts +25 -0
- package/dist/workflow/workflow-discovery.js +100 -0
- package/dist/workflow/workflow-discovery.js.map +1 -0
- package/dist/workflow/workflow-manager.d.ts +122 -0
- package/dist/workflow/workflow-manager.js +308 -0
- package/dist/workflow/workflow-manager.js.map +1 -0
- package/dist/workflow/workflows/design-and-code/workflow.yaml +169 -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 +89 -0
- package/dist/workflow/workflows/vuln-discovery/skills/harness-design-fuzzing/SKILL.md +201 -0
- package/dist/workflow/workflows/vuln-discovery/skills/memory-safety-c-cpp/SKILL.md +166 -0
- package/dist/workflow/workflows/vuln-discovery/skills/vulnerability-triage/SKILL.md +185 -0
- package/dist/workflow/workflows/vuln-discovery/workflow.yaml +920 -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 +9 -0
- package/docker/Dockerfile.base.arm64 +9 -0
- package/docker/entrypoint-claude-code.sh +46 -0
- package/docker/entrypoint-goose.sh +25 -0
- package/package.json +19 -8
- 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/workflow.yaml +169 -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 +89 -0
- package/src/workflow/workflows/vuln-discovery/skills/harness-design-fuzzing/SKILL.md +201 -0
- package/src/workflow/workflows/vuln-discovery/skills/memory-safety-c-cpp/SKILL.md +166 -0
- package/src/workflow/workflows/vuln-discovery/skills/vulnerability-triage/SKILL.md +185 -0
- package/src/workflow/workflows/vuln-discovery/workflow.yaml +920 -0
- package/dist/pipeline/llm-logger.js.map +0 -1
- package/dist/session/errors.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@font-face{font-family:Orbitron;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/orbitron-latin-700-normal-4jsRXGGJ.woff2) format("woff2"),url(/assets/orbitron-latin-700-normal-DmYOh-W9.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:system-ui,-apple-system,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--destructive: 0 72% 51%;--destructive-foreground: 0 0% 98%;--success-foreground: 0 0% 98%;--radius: .5rem}[data-theme=iron]{--background: 220 14% 8%;--foreground: 210 20% 92%;--card: 220 14% 10%;--card-foreground: 210 20% 92%;--primary: 38 92% 55%;--primary-foreground: 220 14% 8%;--secondary: 220 12% 16%;--secondary-foreground: 210 20% 82%;--muted: 220 12% 16%;--muted-foreground: 215 12% 52%;--accent: 220 12% 14%;--accent-foreground: 210 20% 92%;--success: 142 72% 42%;--warning: 38 92% 55%;--warning-foreground: 220 14% 8%;--border: 220 12% 18%;--ring: 38 92% 55%;--sidebar: 220 14% 6%;color-scheme:dark}[data-theme=daylight]{--background: 40 20% 97%;--foreground: 220 20% 12%;--card: 0 0% 100%;--card-foreground: 220 20% 12%;--primary: 172 66% 36%;--primary-foreground: 0 0% 100%;--secondary: 220 10% 94%;--secondary-foreground: 220 20% 30%;--muted: 220 10% 94%;--muted-foreground: 220 10% 46%;--accent: 220 10% 92%;--accent-foreground: 220 20% 12%;--success: 142 72% 36%;--warning: 38 92% 50%;--warning-foreground: 220 14% 8%;--border: 220 12% 88%;--ring: 172 66% 36%;--sidebar: 0 0% 100%;color-scheme:light}[data-theme=midnight]{--background: 228 24% 8%;--foreground: 215 20% 90%;--card: 228 22% 11%;--card-foreground: 215 20% 90%;--primary: 213 94% 58%;--primary-foreground: 0 0% 100%;--secondary: 228 18% 16%;--secondary-foreground: 215 20% 80%;--muted: 228 18% 16%;--muted-foreground: 220 14% 50%;--accent: 228 18% 14%;--accent-foreground: 215 20% 90%;--success: 142 72% 42%;--warning: 45 93% 58%;--warning-foreground: 228 24% 8%;--border: 228 16% 18%;--ring: 213 94% 58%;--sidebar: 228 24% 6%;color-scheme:dark}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground));font-family:DM Sans,system-ui,sans-serif}code,.font-mono{font-family:JetBrains Mono,ui-monospace,monospace}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:hsl(var(--muted-foreground) / .25);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:hsl(var(--muted-foreground) / .4)}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-full{bottom:100%}.left-0{left:0}.right-0{right:0}.top-0{top:0}.top-full{top:100%}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.m-0{margin:0}.-mx-6{margin-left:-1.5rem;margin-right:-1.5rem}.mx-1\.5{margin-left:.375rem;margin-right:.375rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-20{margin-left:5rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-2{margin-right:.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-1\.5{height:.375rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-\[400px\]{height:400px}.h-full{height:100%}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-48{max-height:12rem}.max-h-80{max-height:20rem}.max-h-\[150px\]{max-height:150px}.max-h-\[60vh\]{max-height:60vh}.min-h-0{min-height:0px}.min-h-\[300px\]{min-height:300px}.min-h-\[80px\]{min-height:80px}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-16{width:4rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-48{width:12rem}.w-56{width:14rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[12rem\]{min-width:12rem}.min-w-\[18px\]{min-width:18px}.max-w-2xl{max-width:42rem}.max-w-\[28ch\]{max-width:28ch}.max-w-\[36ch\]{max-width:36ch}.max-w-full{max-width:100%}.max-w-sm{max-width:24rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x: -100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-0{--tw-translate-x: 0px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-x-1\.5>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.375rem * var(--tw-space-x-reverse));margin-left:calc(.375rem * calc(1 - var(--tw-space-x-reverse)))}.space-y-0>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(0px * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0px * var(--tw-space-y-reverse))}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-\[1\.5px\]{border-width:1.5px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-border{border-color:hsl(var(--border))}.border-border\/50{border-color:hsl(var(--border) / .5)}.border-destructive\/20{border-color:hsl(var(--destructive) / .2)}.border-destructive\/30{border-color:hsl(var(--destructive) / .3)}.border-destructive\/40{border-color:hsl(var(--destructive) / .4)}.border-destructive\/50{border-color:hsl(var(--destructive) / .5)}.border-muted-foreground\/30{border-color:hsl(var(--muted-foreground) / .3)}.border-muted-foreground\/40{border-color:hsl(var(--muted-foreground) / .4)}.border-primary{border-color:hsl(var(--primary))}.border-primary\/40{border-color:hsl(var(--primary) / .4)}.border-transparent{border-color:transparent}.border-warning\/30{border-color:hsl(var(--warning) / .3)}.border-t-current{border-top-color:currentColor}.border-t-muted-foreground{border-top-color:hsl(var(--muted-foreground))}.bg-accent{background-color:hsl(var(--accent))}.bg-accent\/20{background-color:hsl(var(--accent) / .2)}.bg-background{background-color:hsl(var(--background))}.bg-background\/95{background-color:hsl(var(--background) / .95)}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-card{background-color:hsl(var(--card))}.bg-card\/50{background-color:hsl(var(--card) / .5)}.bg-card\/75{background-color:hsl(var(--card) / .75)}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-destructive\/15{background-color:hsl(var(--destructive) / .15)}.bg-destructive\/5{background-color:hsl(var(--destructive) / .05)}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/10{background-color:hsl(var(--muted) / .1)}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/40{background-color:hsl(var(--muted) / .4)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-primary{background-color:hsl(var(--primary))}.bg-primary\/10{background-color:hsl(var(--primary) / .1)}.bg-primary\/15{background-color:hsl(var(--primary) / .15)}.bg-secondary{background-color:hsl(var(--secondary))}.bg-sidebar{background-color:hsl(var(--sidebar))}.bg-success{background-color:hsl(var(--success))}.bg-success\/15{background-color:hsl(var(--success) / .15)}.bg-transparent{background-color:transparent}.bg-warning{background-color:hsl(var(--warning))}.bg-warning\/10{background-color:hsl(var(--warning) / .1)}.bg-warning\/15{background-color:hsl(var(--warning) / .15)}.bg-warning\/5{background-color:hsl(var(--warning) / .05)}.fill-destructive\/20{fill:hsl(var(--destructive) / .2)}.fill-foreground{fill:hsl(var(--foreground))}.fill-muted-foreground{fill:hsl(var(--muted-foreground))}.fill-muted-foreground\/60{fill:hsl(var(--muted-foreground) / .6)}.fill-muted-foreground\/70{fill:hsl(var(--muted-foreground) / .7)}.fill-muted\/50{fill:hsl(var(--muted) / .5)}.fill-primary{fill:hsl(var(--primary))}.fill-primary-foreground{fill:hsl(var(--primary-foreground))}.fill-primary\/20{fill:hsl(var(--primary) / .2)}.fill-success{fill:hsl(var(--success))}.fill-success\/15{fill:hsl(var(--success) / .15)}.fill-warning\/10{fill:hsl(var(--warning) / .1)}.fill-warning\/20{fill:hsl(var(--warning) / .2)}.stroke-border{stroke:hsl(var(--border))}.stroke-destructive{stroke:hsl(var(--destructive))}.stroke-muted-foreground\/40{stroke:hsl(var(--muted-foreground) / .4)}.stroke-primary{stroke:hsl(var(--primary))}.stroke-success\/50{stroke:hsl(var(--success) / .5)}.stroke-warning{stroke:hsl(var(--warning))}.stroke-warning\/30{stroke:hsl(var(--warning) / .3)}.p-0{padding:0}.p-12{padding:3rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-16{padding-top:4rem;padding-bottom:4rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pb-\[15vh\]{padding-bottom:15vh}.pr-1{padding-right:.25rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.pt-\[10vh\]{padding-top:10vh}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,monospace}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-destructive\/60{color:hsl(var(--destructive) / .6)}.text-foreground{color:hsl(var(--foreground))}.text-foreground\/70{color:hsl(var(--foreground) / .7)}.text-foreground\/80{color:hsl(var(--foreground) / .8)}.text-foreground\/90{color:hsl(var(--foreground) / .9)}.text-inherit{color:inherit}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-muted-foreground\/30{color:hsl(var(--muted-foreground) / .3)}.text-muted-foreground\/50{color:hsl(var(--muted-foreground) / .5)}.text-muted-foreground\/60{color:hsl(var(--muted-foreground) / .6)}.text-muted-foreground\/70{color:hsl(var(--muted-foreground) / .7)}.text-primary{color:hsl(var(--primary))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-success{color:hsl(var(--success))}.text-success-foreground{color:hsl(var(--success-foreground))}.text-warning{color:hsl(var(--warning))}.text-white\/60{color:#fff9}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/40{--tw-shadow-color: rgb(0 0 0 / .4);--tw-shadow: var(--tw-shadow-colored)}.shadow-destructive\/5{--tw-shadow-color: hsl(var(--destructive) / .05);--tw-shadow: var(--tw-shadow-colored)}.outline{outline-style:solid}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.drop-shadow{--tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / .1)) drop-shadow(0 1px 1px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.theme-transition{transition:background-color .3s ease,color .2s ease,border-color .3s ease}.animate-fade-in{animation:fadeIn .3s ease-out}.prose-markdown{line-height:1.65;word-wrap:break-word;overflow-wrap:break-word}.prose-markdown p{margin:.25em 0}.prose-markdown strong{font-weight:700;color:hsl(var(--foreground))}.prose-markdown em{font-style:italic}.prose-markdown h1,.prose-markdown h2,.prose-markdown h3,.prose-markdown h4,.prose-markdown h5,.prose-markdown h6{font-weight:700;margin:.75em 0 .25em;color:hsl(var(--foreground))}.prose-markdown h1{font-size:1.4em}.prose-markdown h2{font-size:1.25em}.prose-markdown h3{font-size:1.1em}.prose-markdown code{font-family:JetBrains Mono,ui-monospace,monospace;font-size:.875em;background:hsl(var(--muted));padding:.15em .35em;border-radius:.25em}.prose-markdown pre{background:hsl(var(--muted));border:1px solid hsl(var(--border));border-radius:.375rem;padding:.75em 1em;margin:.5em 0;overflow-x:auto}.prose-markdown pre code{background:none;padding:0;font-size:.85em}.prose-markdown ul,.prose-markdown ol{margin:.35em 0;padding-left:1.5em}.prose-markdown ul{list-style:disc}.prose-markdown ol{list-style:decimal}.prose-markdown li{margin:.15em 0}.prose-markdown blockquote{border-left:3px solid hsl(var(--border));margin:.5em 0;padding:.25em .75em;color:hsl(var(--muted-foreground))}.prose-markdown table{border-collapse:collapse;width:100%;margin:.5em 0;font-size:.9em}.prose-markdown th,.prose-markdown td{border:1px solid hsl(var(--border));padding:.4em .75em;text-align:left}.prose-markdown th{background:hsl(var(--muted));font-weight:600}.prose-markdown a{color:hsl(var(--primary));text-decoration:underline;text-underline-offset:2px}.prose-markdown a:hover{opacity:.8}.prose-markdown hr{border:none;border-top:1px solid hsl(var(--border));margin:.75em 0}@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground\/50::-moz-placeholder{color:hsl(var(--muted-foreground) / .5)}.placeholder\:text-muted-foreground\/50::placeholder{color:hsl(var(--muted-foreground) / .5)}.hover\:border-border:hover{border-color:hsl(var(--border))}.hover\:border-destructive\/30:hover{border-color:hsl(var(--destructive) / .3)}.hover\:border-primary\/30:hover{border-color:hsl(var(--primary) / .3)}.hover\:border-warning\/30:hover{border-color:hsl(var(--warning) / .3)}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-accent\/30:hover{background-color:hsl(var(--accent) / .3)}.hover\:bg-accent\/40:hover{background-color:hsl(var(--accent) / .4)}.hover\:bg-accent\/50:hover{background-color:hsl(var(--accent) / .5)}.hover\:bg-destructive:hover{background-color:hsl(var(--destructive))}.hover\:bg-muted\/60:hover{background-color:hsl(var(--muted) / .6)}.hover\:bg-warning\/20:hover{background-color:hsl(var(--warning) / .2)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.hover\:text-destructive-foreground:hover{color:hsl(var(--destructive-foreground))}.hover\:text-foreground:hover{color:hsl(var(--foreground))}.hover\:underline:hover{text-decoration-line:underline}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-ring:focus{border-color:hsl(var(--ring))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-primary\/50:focus{--tw-ring-color: hsl(var(--primary) / .5)}.focus\:ring-ring\/40:focus{--tw-ring-color: hsl(var(--ring) / .4)}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-ring\/40:focus-visible{--tw-ring-color: hsl(var(--ring) / .4)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.active\:scale-\[0\.97\]:active{--tw-scale-x: .97;--tw-scale-y: .97;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:items-center{align-items:center}.sm\:pb-4{padding-bottom:1rem}.sm\:pt-\[20vh\]{padding-top:20vh}}@media(min-width:768px){.md\:flex{display:flex}.md\:hidden{display:none}.md\:flex-row{flex-direction:row}}@media(min-width:1024px){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@keyframes svelte-jz1l8o-pulse-slow{0%,to{opacity:1}50%{opacity:.75}}.animate-pulse-slow{animation:svelte-jz1l8o-pulse-slow 2s ease-in-out infinite}.wordmark-glow.svelte-8mgguq{filter:drop-shadow(0 0 8px rgba(0,255,65,.4)) drop-shadow(0 0 3px rgba(0,255,65,.3))}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="iron" class="h-full">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>IronCurtain</title>
|
|
7
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-BFO5z1js.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CCUwrkIL.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body class="bg-background text-foreground h-full antialiased">
|
|
12
|
+
<div id="app"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { WorkflowId } from './types.js';
|
|
2
|
+
export interface CollectedFile {
|
|
3
|
+
/** Path relative to the root directory, using forward slashes. */
|
|
4
|
+
readonly relativePath: string;
|
|
5
|
+
/** Absolute path on disk. */
|
|
6
|
+
readonly fullPath: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Recursively walks a directory and returns all regular files (not directories
|
|
10
|
+
* or symlinks). Results are sorted by relative path for deterministic ordering.
|
|
11
|
+
*/
|
|
12
|
+
export declare function collectFilesRecursive(dir: string): CollectedFile[];
|
|
13
|
+
/**
|
|
14
|
+
* Recursively checks whether a directory contains any regular files.
|
|
15
|
+
* More efficient than collectFilesRecursive when you only need a boolean.
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasAnyFiles(dir: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Copies output artifact directories to versioned backups before a state
|
|
20
|
+
* is re-entered. Agents always write to the same canonical paths — versioning
|
|
21
|
+
* is transparent to them.
|
|
22
|
+
*
|
|
23
|
+
* On the Nth visit (N > 1), each output's directory is copied to `<name>.v<N-1>`.
|
|
24
|
+
* For example, the second visit creates `.v1`, the third creates `.v2`.
|
|
25
|
+
*
|
|
26
|
+
* Idempotency: if the versioned directory already exists (e.g., on resume),
|
|
27
|
+
* the copy is skipped to avoid overwriting a clean snapshot with corrupted data.
|
|
28
|
+
*/
|
|
29
|
+
export declare function snapshotArtifacts(artifactDir: string, outputs: readonly string[], visitNumber: number, unversionedArtifacts: ReadonlySet<string>): void;
|
|
30
|
+
/** Manages artifact directories and files for workflow state transitions. */
|
|
31
|
+
export interface ArtifactManager {
|
|
32
|
+
/** Ensure the artifact directory structure exists for a workflow. Returns artifact dir path. */
|
|
33
|
+
initialize(workflowId: WorkflowId): string;
|
|
34
|
+
/** Read an artifact file's content. Returns undefined if not found. */
|
|
35
|
+
read(workflowId: WorkflowId, artifactName: string): string | undefined;
|
|
36
|
+
/** List all files in an artifact subdirectory. */
|
|
37
|
+
listArtifactFiles(workflowId: WorkflowId, artifactName: string): string[];
|
|
38
|
+
/** Check which expected outputs are missing. Returns list of missing artifact names. */
|
|
39
|
+
findMissing(workflowId: WorkflowId, expectedOutputs: readonly string[]): string[];
|
|
40
|
+
/** Compute SHA-256 hash of artifact directories' contents. Deterministic ordering. */
|
|
41
|
+
computeHash(workflowId: WorkflowId, artifactNames: readonly string[]): string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* File-based artifact manager. Each workflow gets an artifact directory at
|
|
45
|
+
* `{baseDir}/{workflowId}/artifacts/`. Within that, each artifact name
|
|
46
|
+
* maps to a subdirectory containing one or more files.
|
|
47
|
+
*/
|
|
48
|
+
export declare class FileArtifactManager implements ArtifactManager {
|
|
49
|
+
private readonly baseDir;
|
|
50
|
+
constructor(baseDir: string);
|
|
51
|
+
initialize(workflowId: WorkflowId): string;
|
|
52
|
+
read(workflowId: WorkflowId, artifactName: string): string | undefined;
|
|
53
|
+
listArtifactFiles(workflowId: WorkflowId, artifactName: string): string[];
|
|
54
|
+
findMissing(workflowId: WorkflowId, expectedOutputs: readonly string[]): string[];
|
|
55
|
+
computeHash(workflowId: WorkflowId, artifactNames: readonly string[]): string;
|
|
56
|
+
/** Get the artifact directory path for a workflow. */
|
|
57
|
+
artifactDirFor(workflowId: WorkflowId): string;
|
|
58
|
+
private artifactDir;
|
|
59
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { readFileSync, mkdirSync, readdirSync, existsSync, lstatSync, statSync, cpSync } from 'node:fs';
|
|
2
|
+
import { resolve, relative, sep } from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
/**
|
|
5
|
+
* Recursively walks a directory and returns all regular files (not directories
|
|
6
|
+
* or symlinks). Results are sorted by relative path for deterministic ordering.
|
|
7
|
+
*/
|
|
8
|
+
export function collectFilesRecursive(dir) {
|
|
9
|
+
if (!existsSync(dir))
|
|
10
|
+
return [];
|
|
11
|
+
const results = [];
|
|
12
|
+
walkDir(dir, dir, results);
|
|
13
|
+
results.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
14
|
+
return results;
|
|
15
|
+
}
|
|
16
|
+
function walkDir(rootDir, currentDir, results) {
|
|
17
|
+
let entries;
|
|
18
|
+
try {
|
|
19
|
+
entries = readdirSync(currentDir);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return; // Directory removed or inaccessible
|
|
23
|
+
}
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
const fullPath = resolve(currentDir, entry);
|
|
26
|
+
try {
|
|
27
|
+
const lstats = lstatSync(fullPath);
|
|
28
|
+
if (lstats.isSymbolicLink())
|
|
29
|
+
continue;
|
|
30
|
+
if (lstats.isDirectory()) {
|
|
31
|
+
walkDir(rootDir, fullPath, results);
|
|
32
|
+
}
|
|
33
|
+
else if (lstats.isFile()) {
|
|
34
|
+
results.push({
|
|
35
|
+
relativePath: relative(rootDir, fullPath).split(sep).join('/'),
|
|
36
|
+
fullPath,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// File removed between readdir and lstat, or permission error — skip
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Recursively checks whether a directory contains any regular files.
|
|
48
|
+
* More efficient than collectFilesRecursive when you only need a boolean.
|
|
49
|
+
*/
|
|
50
|
+
export function hasAnyFiles(dir) {
|
|
51
|
+
if (!existsSync(dir))
|
|
52
|
+
return false;
|
|
53
|
+
return hasAnyFilesInDir(dir);
|
|
54
|
+
}
|
|
55
|
+
function hasAnyFilesInDir(currentDir) {
|
|
56
|
+
let entries;
|
|
57
|
+
try {
|
|
58
|
+
entries = readdirSync(currentDir);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false; // Directory removed or inaccessible
|
|
62
|
+
}
|
|
63
|
+
for (const entry of entries) {
|
|
64
|
+
const fullPath = resolve(currentDir, entry);
|
|
65
|
+
try {
|
|
66
|
+
const lstats = lstatSync(fullPath);
|
|
67
|
+
if (lstats.isSymbolicLink())
|
|
68
|
+
continue;
|
|
69
|
+
if (lstats.isFile())
|
|
70
|
+
return true;
|
|
71
|
+
if (lstats.isDirectory() && hasAnyFilesInDir(fullPath))
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// File removed between readdir and lstat, or permission error — skip
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
// Artifact versioning
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
/**
|
|
85
|
+
* Copies output artifact directories to versioned backups before a state
|
|
86
|
+
* is re-entered. Agents always write to the same canonical paths — versioning
|
|
87
|
+
* is transparent to them.
|
|
88
|
+
*
|
|
89
|
+
* On the Nth visit (N > 1), each output's directory is copied to `<name>.v<N-1>`.
|
|
90
|
+
* For example, the second visit creates `.v1`, the third creates `.v2`.
|
|
91
|
+
*
|
|
92
|
+
* Idempotency: if the versioned directory already exists (e.g., on resume),
|
|
93
|
+
* the copy is skipped to avoid overwriting a clean snapshot with corrupted data.
|
|
94
|
+
*/
|
|
95
|
+
export function snapshotArtifacts(artifactDir, outputs, visitNumber, unversionedArtifacts) {
|
|
96
|
+
if (visitNumber <= 1)
|
|
97
|
+
return;
|
|
98
|
+
const versionSuffix = `.v${visitNumber - 1}`;
|
|
99
|
+
for (const output of outputs) {
|
|
100
|
+
if (unversionedArtifacts.has(output))
|
|
101
|
+
continue;
|
|
102
|
+
const src = resolve(artifactDir, output);
|
|
103
|
+
if (!existsSync(src))
|
|
104
|
+
continue;
|
|
105
|
+
const dest = resolve(artifactDir, `${output}${versionSuffix}`);
|
|
106
|
+
if (existsSync(dest))
|
|
107
|
+
continue;
|
|
108
|
+
try {
|
|
109
|
+
cpSync(src, dest, { recursive: true });
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
// Best-effort: a single failed copy must not abort a long-running agent run.
|
|
113
|
+
// Write directly to stderr to bypass any console hijacking
|
|
114
|
+
// (logger.setup() redirects console.error to a log file).
|
|
115
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
116
|
+
process.stderr.write(`[workflow] snapshotArtifacts: failed to copy "${src}" to "${dest}": ${message}\n`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// File-based implementation
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
/**
|
|
124
|
+
* File-based artifact manager. Each workflow gets an artifact directory at
|
|
125
|
+
* `{baseDir}/{workflowId}/artifacts/`. Within that, each artifact name
|
|
126
|
+
* maps to a subdirectory containing one or more files.
|
|
127
|
+
*/
|
|
128
|
+
export class FileArtifactManager {
|
|
129
|
+
baseDir;
|
|
130
|
+
constructor(baseDir) {
|
|
131
|
+
this.baseDir = baseDir;
|
|
132
|
+
}
|
|
133
|
+
initialize(workflowId) {
|
|
134
|
+
const artifactDir = this.artifactDir(workflowId);
|
|
135
|
+
mkdirSync(artifactDir, { recursive: true });
|
|
136
|
+
return artifactDir;
|
|
137
|
+
}
|
|
138
|
+
read(workflowId, artifactName) {
|
|
139
|
+
const dir = resolve(this.artifactDir(workflowId), artifactName);
|
|
140
|
+
if (!existsSync(dir))
|
|
141
|
+
return undefined;
|
|
142
|
+
// Try convention name first, then fall back to first file
|
|
143
|
+
const conventionPath = resolve(dir, `${artifactName}.md`);
|
|
144
|
+
if (existsSync(conventionPath)) {
|
|
145
|
+
return readFileSync(conventionPath, 'utf-8');
|
|
146
|
+
}
|
|
147
|
+
const files = collectFilesRecursive(dir);
|
|
148
|
+
if (files.length === 0)
|
|
149
|
+
return undefined;
|
|
150
|
+
return readFileSync(files[0].fullPath, 'utf-8');
|
|
151
|
+
}
|
|
152
|
+
listArtifactFiles(workflowId, artifactName) {
|
|
153
|
+
const dir = resolve(this.artifactDir(workflowId), artifactName);
|
|
154
|
+
return collectFilesRecursive(dir).map((f) => f.relativePath);
|
|
155
|
+
}
|
|
156
|
+
findMissing(workflowId, expectedOutputs) {
|
|
157
|
+
const artifactDir = this.artifactDir(workflowId);
|
|
158
|
+
const missing = [];
|
|
159
|
+
for (const name of expectedOutputs) {
|
|
160
|
+
const dir = resolve(artifactDir, name);
|
|
161
|
+
if (!hasAnyFiles(dir)) {
|
|
162
|
+
missing.push(name);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return missing;
|
|
166
|
+
}
|
|
167
|
+
computeHash(workflowId, artifactNames) {
|
|
168
|
+
const hash = createHash('sha256');
|
|
169
|
+
const artifactDir = this.artifactDir(workflowId);
|
|
170
|
+
for (const name of [...artifactNames].sort()) {
|
|
171
|
+
const dir = resolve(artifactDir, name);
|
|
172
|
+
const files = collectFilesRecursive(dir);
|
|
173
|
+
for (const file of files) {
|
|
174
|
+
const { size, mtimeMs } = statSync(file.fullPath);
|
|
175
|
+
hash.update(`${file.relativePath}:${size}:${mtimeMs}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return hash.digest('hex');
|
|
179
|
+
}
|
|
180
|
+
/** Get the artifact directory path for a workflow. */
|
|
181
|
+
artifactDirFor(workflowId) {
|
|
182
|
+
return this.artifactDir(workflowId);
|
|
183
|
+
}
|
|
184
|
+
artifactDir(workflowId) {
|
|
185
|
+
return resolve(this.baseDir, workflowId, 'artifacts');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/workflow/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Past-run checkpoint selection helpers.
|
|
3
|
+
*
|
|
4
|
+
* Both the CLI (`workflow resume`) and the daemon's
|
|
5
|
+
* `WorkflowManager.importExternalCheckpoint` need to scan a base directory
|
|
6
|
+
* for resumable workflow runs and pick the most recent. Centralized here
|
|
7
|
+
* so both paths use the same enumeration + filter + sort logic.
|
|
8
|
+
*
|
|
9
|
+
* Sort comparator: ISO-8601 string compare on `checkpoint.timestamp`. Both
|
|
10
|
+
* the previous CLI implementation (`new Date(...).getTime()`) and the
|
|
11
|
+
* previous daemon implementation (`a > b` string compare) produce the same
|
|
12
|
+
* order; string compare is one fewer allocation per row.
|
|
13
|
+
*/
|
|
14
|
+
import { type FileCheckpointStore } from './checkpoint.js';
|
|
15
|
+
import type { WorkflowCheckpoint, WorkflowId } from './types.js';
|
|
16
|
+
/** A resumable past run paired with its loaded checkpoint. */
|
|
17
|
+
export interface ResumableCheckpoint {
|
|
18
|
+
readonly workflowId: WorkflowId;
|
|
19
|
+
readonly checkpoint: WorkflowCheckpoint;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns every resumable past run under `baseDir`, sorted newest-first by
|
|
23
|
+
* `checkpoint.timestamp` (ISO-8601 string compare).
|
|
24
|
+
*
|
|
25
|
+
* "Resumable" means: the directory has a checkpoint file, the checkpoint
|
|
26
|
+
* loads successfully, and {@link isCheckpointResumable} returns true
|
|
27
|
+
* (i.e. the checkpoint is not in a `completed` final phase).
|
|
28
|
+
*/
|
|
29
|
+
export declare function findResumableCheckpoints(baseDir: string, store: FileCheckpointStore): ResumableCheckpoint[];
|
|
30
|
+
/**
|
|
31
|
+
* Returns the most recent resumable past run under `baseDir`, or `undefined`
|
|
32
|
+
* if none exist. Convenience wrapper over {@link findResumableCheckpoints}.
|
|
33
|
+
*/
|
|
34
|
+
export declare function findLatestResumableCheckpoint(baseDir: string, store: FileCheckpointStore): ResumableCheckpoint | undefined;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Past-run checkpoint selection helpers.
|
|
3
|
+
*
|
|
4
|
+
* Both the CLI (`workflow resume`) and the daemon's
|
|
5
|
+
* `WorkflowManager.importExternalCheckpoint` need to scan a base directory
|
|
6
|
+
* for resumable workflow runs and pick the most recent. Centralized here
|
|
7
|
+
* so both paths use the same enumeration + filter + sort logic.
|
|
8
|
+
*
|
|
9
|
+
* Sort comparator: ISO-8601 string compare on `checkpoint.timestamp`. Both
|
|
10
|
+
* the previous CLI implementation (`new Date(...).getTime()`) and the
|
|
11
|
+
* previous daemon implementation (`a > b` string compare) produce the same
|
|
12
|
+
* order; string compare is one fewer allocation per row.
|
|
13
|
+
*/
|
|
14
|
+
import { discoverWorkflowRuns } from './workflow-discovery.js';
|
|
15
|
+
import { isCheckpointResumable } from './checkpoint.js';
|
|
16
|
+
/**
|
|
17
|
+
* Returns every resumable past run under `baseDir`, sorted newest-first by
|
|
18
|
+
* `checkpoint.timestamp` (ISO-8601 string compare).
|
|
19
|
+
*
|
|
20
|
+
* "Resumable" means: the directory has a checkpoint file, the checkpoint
|
|
21
|
+
* loads successfully, and {@link isCheckpointResumable} returns true
|
|
22
|
+
* (i.e. the checkpoint is not in a `completed` final phase).
|
|
23
|
+
*/
|
|
24
|
+
export function findResumableCheckpoints(baseDir, store) {
|
|
25
|
+
const candidates = [];
|
|
26
|
+
for (const run of discoverWorkflowRuns(baseDir)) {
|
|
27
|
+
if (!run.hasCheckpoint)
|
|
28
|
+
continue;
|
|
29
|
+
const cp = store.load(run.workflowId);
|
|
30
|
+
if (!cp || !isCheckpointResumable(cp))
|
|
31
|
+
continue;
|
|
32
|
+
candidates.push({ workflowId: run.workflowId, checkpoint: cp });
|
|
33
|
+
}
|
|
34
|
+
candidates.sort((a, b) => {
|
|
35
|
+
if (a.checkpoint.timestamp === b.checkpoint.timestamp)
|
|
36
|
+
return 0;
|
|
37
|
+
return a.checkpoint.timestamp < b.checkpoint.timestamp ? 1 : -1;
|
|
38
|
+
});
|
|
39
|
+
return candidates;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns the most recent resumable past run under `baseDir`, or `undefined`
|
|
43
|
+
* if none exist. Convenience wrapper over {@link findResumableCheckpoints}.
|
|
44
|
+
*/
|
|
45
|
+
export function findLatestResumableCheckpoint(baseDir, store) {
|
|
46
|
+
return findResumableCheckpoints(baseDir, store)[0];
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=checkpoint-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-selection.js","sourceRoot":"","sources":["../../src/workflow/checkpoint-selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAA4B,MAAM,iBAAiB,CAAC;AASlF;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,KAA0B;IAClF,MAAM,UAAU,GAA0B,EAAE,CAAC;IAC7C,KAAK,MAAM,GAAG,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,aAAa;YAAE,SAAS;QACjC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAAE,SAAS;QAChD,UAAU,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,KAAK,CAAC,CAAC,UAAU,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAAe,EACf,KAA0B;IAE1B,OAAO,wBAAwB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { WorkflowId, WorkflowCheckpoint } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resumable iff not completed. `finalStatus` is undefined for mid-run and
|
|
4
|
+
* pre-B3b legacy checkpoints — both correctly resolve to `true`.
|
|
5
|
+
*
|
|
6
|
+
* Co-located with `WorkflowCheckpoint` storage so other modules can import
|
|
7
|
+
* the predicate without pulling in CLI / session dependencies.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isCheckpointResumable(cp: WorkflowCheckpoint): boolean;
|
|
10
|
+
/** Persistent storage for workflow checkpoints. */
|
|
11
|
+
export interface CheckpointStore {
|
|
12
|
+
/** Save a checkpoint. Overwrites any previous checkpoint for this workflow. */
|
|
13
|
+
save(workflowId: WorkflowId, checkpoint: WorkflowCheckpoint): void;
|
|
14
|
+
/** Load the most recent checkpoint for a workflow. Returns undefined if none exists. */
|
|
15
|
+
load(workflowId: WorkflowId): WorkflowCheckpoint | undefined;
|
|
16
|
+
/** List workflow IDs that have checkpoints (for resume discovery). */
|
|
17
|
+
listAll(): WorkflowId[];
|
|
18
|
+
/** Remove a checkpoint (on workflow completion or abort). */
|
|
19
|
+
remove(workflowId: WorkflowId): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* File-based checkpoint store. Each workflow gets a directory at
|
|
23
|
+
* `{baseDir}/{workflowId}/checkpoint.json`. Writes are atomic
|
|
24
|
+
* (write to temp file, then rename) to prevent corruption from
|
|
25
|
+
* partial writes.
|
|
26
|
+
*/
|
|
27
|
+
export declare class FileCheckpointStore implements CheckpointStore {
|
|
28
|
+
private readonly baseDir;
|
|
29
|
+
constructor(baseDir: string);
|
|
30
|
+
save(workflowId: WorkflowId, checkpoint: WorkflowCheckpoint): void;
|
|
31
|
+
load(workflowId: WorkflowId): WorkflowCheckpoint | undefined;
|
|
32
|
+
listAll(): WorkflowId[];
|
|
33
|
+
remove(workflowId: WorkflowId): void;
|
|
34
|
+
private checkpointPath;
|
|
35
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync, existsSync, renameSync } from 'node:fs';
|
|
2
|
+
import { resolve, dirname } from 'node:path';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Resumability predicate
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* Resumable iff not completed. `finalStatus` is undefined for mid-run and
|
|
9
|
+
* pre-B3b legacy checkpoints — both correctly resolve to `true`.
|
|
10
|
+
*
|
|
11
|
+
* Co-located with `WorkflowCheckpoint` storage so other modules can import
|
|
12
|
+
* the predicate without pulling in CLI / session dependencies.
|
|
13
|
+
*/
|
|
14
|
+
export function isCheckpointResumable(cp) {
|
|
15
|
+
return cp.finalStatus?.phase !== 'completed';
|
|
16
|
+
}
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// File-based implementation
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/**
|
|
21
|
+
* File-based checkpoint store. Each workflow gets a directory at
|
|
22
|
+
* `{baseDir}/{workflowId}/checkpoint.json`. Writes are atomic
|
|
23
|
+
* (write to temp file, then rename) to prevent corruption from
|
|
24
|
+
* partial writes.
|
|
25
|
+
*/
|
|
26
|
+
export class FileCheckpointStore {
|
|
27
|
+
baseDir;
|
|
28
|
+
constructor(baseDir) {
|
|
29
|
+
this.baseDir = baseDir;
|
|
30
|
+
}
|
|
31
|
+
save(workflowId, checkpoint) {
|
|
32
|
+
const filePath = this.checkpointPath(workflowId);
|
|
33
|
+
const dir = dirname(filePath);
|
|
34
|
+
mkdirSync(dir, { recursive: true });
|
|
35
|
+
const content = JSON.stringify(checkpoint, null, 2);
|
|
36
|
+
const tempPath = resolve(dir, `checkpoint.tmp.${randomUUID()}`);
|
|
37
|
+
writeFileSync(tempPath, content, 'utf-8');
|
|
38
|
+
renameSync(tempPath, filePath);
|
|
39
|
+
}
|
|
40
|
+
load(workflowId) {
|
|
41
|
+
const filePath = this.checkpointPath(workflowId);
|
|
42
|
+
try {
|
|
43
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
44
|
+
return JSON.parse(content);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
listAll() {
|
|
54
|
+
if (!existsSync(this.baseDir))
|
|
55
|
+
return [];
|
|
56
|
+
const entries = readdirSync(this.baseDir, { withFileTypes: true });
|
|
57
|
+
const ids = [];
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
if (!entry.isDirectory())
|
|
60
|
+
continue;
|
|
61
|
+
const checkpointFile = resolve(this.baseDir, entry.name, 'checkpoint.json');
|
|
62
|
+
if (existsSync(checkpointFile)) {
|
|
63
|
+
ids.push(entry.name);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return ids;
|
|
67
|
+
}
|
|
68
|
+
remove(workflowId) {
|
|
69
|
+
const filePath = this.checkpointPath(workflowId);
|
|
70
|
+
try {
|
|
71
|
+
rmSync(filePath);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
checkpointPath(workflowId) {
|
|
81
|
+
return resolve(this.baseDir, workflowId, 'checkpoint.json');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/workflow/checkpoint.ts"],"names":[],"mappings":"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"}
|