@oscharko-dev/keiko 0.1.0-beta.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/LICENSE +202 -0
- package/NOTICE +7 -0
- package/README.md +621 -0
- package/TRADEMARKS.md +41 -0
- package/dist/audit/aggregate.d.ts +5 -0
- package/dist/audit/aggregate.js +25 -0
- package/dist/audit/build.d.ts +2 -0
- package/dist/audit/build.js +224 -0
- package/dist/audit/errors.d.ts +25 -0
- package/dist/audit/errors.js +39 -0
- package/dist/audit/index-api.d.ts +14 -0
- package/dist/audit/index-api.js +131 -0
- package/dist/audit/index.d.ts +12 -0
- package/dist/audit/index.js +17 -0
- package/dist/audit/persist.d.ts +8 -0
- package/dist/audit/persist.js +40 -0
- package/dist/audit/redaction.d.ts +3 -0
- package/dist/audit/redaction.js +61 -0
- package/dist/audit/report.d.ts +18 -0
- package/dist/audit/report.js +50 -0
- package/dist/audit/retention.d.ts +3 -0
- package/dist/audit/retention.js +95 -0
- package/dist/audit/runid.d.ts +1 -0
- package/dist/audit/runid.js +29 -0
- package/dist/audit/side-file.d.ts +12 -0
- package/dist/audit/side-file.js +82 -0
- package/dist/audit/store.d.ts +12 -0
- package/dist/audit/store.js +198 -0
- package/dist/audit/types.d.ts +188 -0
- package/dist/audit/types.js +8 -0
- package/dist/audit/workflow-evidence.d.ts +27 -0
- package/dist/audit/workflow-evidence.js +145 -0
- package/dist/cli/context.d.ts +2 -0
- package/dist/cli/context.js +102 -0
- package/dist/cli/evaluate.d.ts +7 -0
- package/dist/cli/evaluate.js +207 -0
- package/dist/cli/evidence.d.ts +8 -0
- package/dist/cli/evidence.js +88 -0
- package/dist/cli/gateway-config.d.ts +10 -0
- package/dist/cli/gateway-config.js +12 -0
- package/dist/cli/gen-tests.d.ts +7 -0
- package/dist/cli/gen-tests.js +208 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +14 -0
- package/dist/cli/investigate.d.ts +8 -0
- package/dist/cli/investigate.js +242 -0
- package/dist/cli/models.d.ts +3 -0
- package/dist/cli/models.js +64 -0
- package/dist/cli/run.d.ts +7 -0
- package/dist/cli/run.js +187 -0
- package/dist/cli/runner.d.ts +6 -0
- package/dist/cli/runner.js +83 -0
- package/dist/cli/ui.d.ts +31 -0
- package/dist/cli/ui.js +240 -0
- package/dist/cli/verify.d.ts +2 -0
- package/dist/cli/verify.js +103 -0
- package/dist/evaluations/fixtures/bug-investigation/happy-path.d.ts +2 -0
- package/dist/evaluations/fixtures/bug-investigation/happy-path.js +66 -0
- package/dist/evaluations/fixtures/bug-investigation/investigation-only.d.ts +2 -0
- package/dist/evaluations/fixtures/bug-investigation/investigation-only.js +39 -0
- package/dist/evaluations/fixtures/bug-investigation/unsafe-action.d.ts +2 -0
- package/dist/evaluations/fixtures/bug-investigation/unsafe-action.js +37 -0
- package/dist/evaluations/fixtures/index.d.ts +7 -0
- package/dist/evaluations/fixtures/index.js +35 -0
- package/dist/evaluations/fixtures/support.d.ts +5 -0
- package/dist/evaluations/fixtures/support.js +42 -0
- package/dist/evaluations/fixtures/unit-tests/happy-path.d.ts +2 -0
- package/dist/evaluations/fixtures/unit-tests/happy-path.js +40 -0
- package/dist/evaluations/fixtures/unit-tests/retry-then-accept.d.ts +2 -0
- package/dist/evaluations/fixtures/unit-tests/retry-then-accept.js +39 -0
- package/dist/evaluations/fixtures/unit-tests/unsafe-action.d.ts +2 -0
- package/dist/evaluations/fixtures/unit-tests/unsafe-action.js +32 -0
- package/dist/evaluations/index.d.ts +12 -0
- package/dist/evaluations/index.js +12 -0
- package/dist/evaluations/manifest-check.d.ts +1 -0
- package/dist/evaluations/manifest-check.js +48 -0
- package/dist/evaluations/model-provider.d.ts +12 -0
- package/dist/evaluations/model-provider.js +26 -0
- package/dist/evaluations/render.d.ts +2 -0
- package/dist/evaluations/render.js +59 -0
- package/dist/evaluations/runner-support.d.ts +27 -0
- package/dist/evaluations/runner-support.js +163 -0
- package/dist/evaluations/runner.d.ts +20 -0
- package/dist/evaluations/runner.js +174 -0
- package/dist/evaluations/scorer.d.ts +14 -0
- package/dist/evaluations/scorer.js +131 -0
- package/dist/evaluations/scripted-model.d.ts +6 -0
- package/dist/evaluations/scripted-model.js +26 -0
- package/dist/evaluations/surface-parity.d.ts +2 -0
- package/dist/evaluations/surface-parity.js +184 -0
- package/dist/evaluations/types.d.ts +74 -0
- package/dist/evaluations/types.js +16 -0
- package/dist/gateway/capabilities.d.ts +11 -0
- package/dist/gateway/capabilities.data.d.ts +2 -0
- package/dist/gateway/capabilities.data.js +203 -0
- package/dist/gateway/capabilities.js +41 -0
- package/dist/gateway/config.d.ts +15 -0
- package/dist/gateway/config.js +154 -0
- package/dist/gateway/errors.d.ts +72 -0
- package/dist/gateway/errors.js +82 -0
- package/dist/gateway/gateway.d.ts +19 -0
- package/dist/gateway/gateway.js +94 -0
- package/dist/gateway/index.d.ts +10 -0
- package/dist/gateway/index.js +11 -0
- package/dist/gateway/model-selection.d.ts +9 -0
- package/dist/gateway/model-selection.js +36 -0
- package/dist/gateway/normalize.d.ts +7 -0
- package/dist/gateway/normalize.js +93 -0
- package/dist/gateway/openai-adapter.d.ts +20 -0
- package/dist/gateway/openai-adapter.js +263 -0
- package/dist/gateway/redaction.d.ts +1 -0
- package/dist/gateway/redaction.js +51 -0
- package/dist/gateway/resilience.d.ts +24 -0
- package/dist/gateway/resilience.js +166 -0
- package/dist/gateway/types.d.ts +108 -0
- package/dist/gateway/types.js +2 -0
- package/dist/harness/adapters.d.ts +23 -0
- package/dist/harness/adapters.js +38 -0
- package/dist/harness/context.d.ts +33 -0
- package/dist/harness/context.js +21 -0
- package/dist/harness/emitter.d.ts +15 -0
- package/dist/harness/emitter.js +72 -0
- package/dist/harness/errors.d.ts +21 -0
- package/dist/harness/errors.js +39 -0
- package/dist/harness/executor.d.ts +3 -0
- package/dist/harness/executor.js +211 -0
- package/dist/harness/fingerprint.d.ts +6 -0
- package/dist/harness/fingerprint.js +43 -0
- package/dist/harness/index.d.ts +9 -0
- package/dist/harness/index.js +13 -0
- package/dist/harness/loop.d.ts +3 -0
- package/dist/harness/loop.js +159 -0
- package/dist/harness/patcher.d.ts +4 -0
- package/dist/harness/patcher.js +49 -0
- package/dist/harness/planner.d.ts +3 -0
- package/dist/harness/planner.js +21 -0
- package/dist/harness/ports.d.ts +61 -0
- package/dist/harness/ports.js +4 -0
- package/dist/harness/session.d.ts +25 -0
- package/dist/harness/session.js +116 -0
- package/dist/harness/sinks.d.ts +30 -0
- package/dist/harness/sinks.js +72 -0
- package/dist/harness/tasks/explain-plan.d.ts +3 -0
- package/dist/harness/tasks/explain-plan.js +29 -0
- package/dist/harness/tasks/generate-unit-tests.d.ts +3 -0
- package/dist/harness/tasks/generate-unit-tests.js +28 -0
- package/dist/harness/tasks/investigate-bug.d.ts +3 -0
- package/dist/harness/tasks/investigate-bug.js +31 -0
- package/dist/harness/tasks/policy.d.ts +11 -0
- package/dist/harness/tasks/policy.js +22 -0
- package/dist/harness/tasks/verify.d.ts +3 -0
- package/dist/harness/tasks/verify.js +16 -0
- package/dist/harness/types.d.ts +270 -0
- package/dist/harness/types.js +33 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +36 -0
- package/dist/sdk/index.d.ts +9 -0
- package/dist/sdk/index.js +37 -0
- package/dist/sdk/run-agent.d.ts +16 -0
- package/dist/sdk/run-agent.js +56 -0
- package/dist/tools/browser/cdp-client.d.ts +35 -0
- package/dist/tools/browser/cdp-client.js +218 -0
- package/dist/tools/browser/errors.d.ts +25 -0
- package/dist/tools/browser/errors.js +55 -0
- package/dist/tools/browser/index.d.ts +5 -0
- package/dist/tools/browser/index.js +6 -0
- package/dist/tools/browser/session.d.ts +44 -0
- package/dist/tools/browser/session.js +748 -0
- package/dist/tools/browser/types.d.ts +48 -0
- package/dist/tools/browser/types.js +2 -0
- package/dist/tools/browser/validators.d.ts +5 -0
- package/dist/tools/browser/validators.js +97 -0
- package/dist/tools/errors.d.ts +59 -0
- package/dist/tools/errors.js +94 -0
- package/dist/tools/exec.d.ts +42 -0
- package/dist/tools/exec.js +327 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/patch-content.d.ts +10 -0
- package/dist/tools/patch-content.js +126 -0
- package/dist/tools/patch-normalize.d.ts +1 -0
- package/dist/tools/patch-normalize.js +80 -0
- package/dist/tools/patch-parse.d.ts +8 -0
- package/dist/tools/patch-parse.js +201 -0
- package/dist/tools/patch.d.ts +18 -0
- package/dist/tools/patch.js +403 -0
- package/dist/tools/registry.d.ts +36 -0
- package/dist/tools/registry.js +231 -0
- package/dist/tools/sandbox.d.ts +8 -0
- package/dist/tools/sandbox.js +121 -0
- package/dist/tools/schemas.d.ts +2 -0
- package/dist/tools/schemas.js +51 -0
- package/dist/tools/terminal-policy.d.ts +9 -0
- package/dist/tools/terminal-policy.js +313 -0
- package/dist/tools/types.d.ts +99 -0
- package/dist/tools/types.js +103 -0
- package/dist/tools/writer.d.ts +7 -0
- package/dist/tools/writer.js +20 -0
- package/dist/ui/browser.d.ts +10 -0
- package/dist/ui/browser.js +231 -0
- package/dist/ui/chat-handlers.d.ts +4 -0
- package/dist/ui/chat-handlers.js +281 -0
- package/dist/ui/csp-hashes.json +17 -0
- package/dist/ui/csp.d.ts +2 -0
- package/dist/ui/csp.js +66 -0
- package/dist/ui/deps.d.ts +34 -0
- package/dist/ui/deps.js +137 -0
- package/dist/ui/evidence.d.ts +27 -0
- package/dist/ui/evidence.js +142 -0
- package/dist/ui/files-deny.d.ts +2 -0
- package/dist/ui/files-deny.js +12 -0
- package/dist/ui/files.d.ts +65 -0
- package/dist/ui/files.js +492 -0
- package/dist/ui/headers.d.ts +2 -0
- package/dist/ui/headers.js +21 -0
- package/dist/ui/host-check.d.ts +2 -0
- package/dist/ui/host-check.js +58 -0
- package/dist/ui/index.d.ts +20 -0
- package/dist/ui/index.js +23 -0
- package/dist/ui/load-csp.d.ts +1 -0
- package/dist/ui/load-csp.js +28 -0
- package/dist/ui/read-handlers.d.ts +8 -0
- package/dist/ui/read-handlers.js +247 -0
- package/dist/ui/routes.d.ts +36 -0
- package/dist/ui/routes.js +129 -0
- package/dist/ui/run-engine.d.ts +20 -0
- package/dist/ui/run-engine.js +345 -0
- package/dist/ui/run-handlers.d.ts +8 -0
- package/dist/ui/run-handlers.js +431 -0
- package/dist/ui/run-request.d.ts +13 -0
- package/dist/ui/run-request.js +219 -0
- package/dist/ui/runs.d.ts +43 -0
- package/dist/ui/runs.js +92 -0
- package/dist/ui/server.d.ts +11 -0
- package/dist/ui/server.js +143 -0
- package/dist/ui/sink.d.ts +27 -0
- package/dist/ui/sink.js +80 -0
- package/dist/ui/sse.d.ts +7 -0
- package/dist/ui/sse.js +27 -0
- package/dist/ui/static/404.html +1 -0
- package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_buildManifest.js +1 -0
- package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_ssgManifest.js +1 -0
- package/dist/ui/static/_next/static/chunks/255-d47fd57964443afe.js +1 -0
- package/dist/ui/static/_next/static/chunks/4-be1fef693af8e088.js +1 -0
- package/dist/ui/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/_not-found/page-75825b09bcecad97.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/launch/page-9c86a13c29884245.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/layout-bdea63fe87947d50.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/page-4168c12c68b7a853.js +1 -0
- package/dist/ui/static/_next/static/chunks/framework-a6e0b7e30f98059a.js +1 -0
- package/dist/ui/static/_next/static/chunks/main-778a50aebff02192.js +1 -0
- package/dist/ui/static/_next/static/chunks/main-app-30679af7240d63e9.js +1 -0
- package/dist/ui/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
- package/dist/ui/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
- package/dist/ui/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/ui/static/_next/static/chunks/webpack-4a462cecab786e93.js +1 -0
- package/dist/ui/static/_next/static/css/be7cb54d5c5673b6.css +1 -0
- package/dist/ui/static/assets/editors/goland.svg +35 -0
- package/dist/ui/static/assets/editors/intellij.svg +39 -0
- package/dist/ui/static/assets/editors/pycharm.svg +58 -0
- package/dist/ui/static/assets/editors/rustrover.svg +19 -0
- package/dist/ui/static/assets/editors/vscode.svg +1 -0
- package/dist/ui/static/assets/editors/webstorm.svg +21 -0
- package/dist/ui/static/assets/icons/anthropic.svg +1 -0
- package/dist/ui/static/assets/icons/brave.svg +1 -0
- package/dist/ui/static/assets/icons/css3.svg +1 -0
- package/dist/ui/static/assets/icons/docker.svg +1 -0
- package/dist/ui/static/assets/icons/git.svg +1 -0
- package/dist/ui/static/assets/icons/github.svg +1 -0
- package/dist/ui/static/assets/icons/go.svg +1 -0
- package/dist/ui/static/assets/icons/gradle.svg +1 -0
- package/dist/ui/static/assets/icons/grafana.svg +1 -0
- package/dist/ui/static/assets/icons/graphql.svg +1 -0
- package/dist/ui/static/assets/icons/html5.svg +1 -0
- package/dist/ui/static/assets/icons/image.svg +1 -0
- package/dist/ui/static/assets/icons/java.svg +1 -0
- package/dist/ui/static/assets/icons/javascript.svg +1 -0
- package/dist/ui/static/assets/icons/json.svg +1 -0
- package/dist/ui/static/assets/icons/kafka.svg +1 -0
- package/dist/ui/static/assets/icons/kubernetes.svg +1 -0
- package/dist/ui/static/assets/icons/linear.svg +1 -0
- package/dist/ui/static/assets/icons/markdown.svg +1 -0
- package/dist/ui/static/assets/icons/nginx.svg +1 -0
- package/dist/ui/static/assets/icons/nodejs.svg +1 -0
- package/dist/ui/static/assets/icons/notion.svg +1 -0
- package/dist/ui/static/assets/icons/openai.svg +1 -0
- package/dist/ui/static/assets/icons/playwright.svg +1 -0
- package/dist/ui/static/assets/icons/postgresql.svg +1 -0
- package/dist/ui/static/assets/icons/prometheus.svg +1 -0
- package/dist/ui/static/assets/icons/properties.svg +1 -0
- package/dist/ui/static/assets/icons/puppeteer.svg +1 -0
- package/dist/ui/static/assets/icons/python.svg +1 -0
- package/dist/ui/static/assets/icons/react.svg +1 -0
- package/dist/ui/static/assets/icons/redis.svg +1 -0
- package/dist/ui/static/assets/icons/rust.svg +1 -0
- package/dist/ui/static/assets/icons/sentry.svg +1 -0
- package/dist/ui/static/assets/icons/slack.svg +1 -0
- package/dist/ui/static/assets/icons/spring.svg +1 -0
- package/dist/ui/static/assets/icons/typescript.svg +1 -0
- package/dist/ui/static/assets/icons/upstash.svg +1 -0
- package/dist/ui/static/assets/icons/yaml.svg +1 -0
- package/dist/ui/static/assets/keiko-logo.svg +10 -0
- package/dist/ui/static/index.html +1 -0
- package/dist/ui/static/index.txt +19 -0
- package/dist/ui/static/keiko-logo.svg +10 -0
- package/dist/ui/static/launch.html +1 -0
- package/dist/ui/static/launch.txt +19 -0
- package/dist/ui/static.d.ts +3 -0
- package/dist/ui/static.js +72 -0
- package/dist/ui/store/chats.d.ts +14 -0
- package/dist/ui/store/chats.js +110 -0
- package/dist/ui/store/db.d.ts +6 -0
- package/dist/ui/store/db.js +182 -0
- package/dist/ui/store/errors.d.ts +12 -0
- package/dist/ui/store/errors.js +30 -0
- package/dist/ui/store/index.d.ts +6 -0
- package/dist/ui/store/index.js +6 -0
- package/dist/ui/store/messages.d.ts +5 -0
- package/dist/ui/store/messages.js +137 -0
- package/dist/ui/store/paths.d.ts +4 -0
- package/dist/ui/store/paths.js +69 -0
- package/dist/ui/store/projects.d.ts +7 -0
- package/dist/ui/store/projects.js +61 -0
- package/dist/ui/store/schema.d.ts +3 -0
- package/dist/ui/store/schema.js +77 -0
- package/dist/ui/store/types.d.ts +80 -0
- package/dist/ui/store/types.js +3 -0
- package/dist/ui/store/validation.d.ts +4 -0
- package/dist/ui/store/validation.js +72 -0
- package/dist/ui/store-handlers.d.ts +16 -0
- package/dist/ui/store-handlers.js +465 -0
- package/dist/ui/terminal-errors.d.ts +21 -0
- package/dist/ui/terminal-errors.js +45 -0
- package/dist/ui/terminal-evidence.d.ts +20 -0
- package/dist/ui/terminal-evidence.js +65 -0
- package/dist/ui/terminal-routes.d.ts +9 -0
- package/dist/ui/terminal-routes.js +219 -0
- package/dist/ui/terminal.d.ts +67 -0
- package/dist/ui/terminal.js +835 -0
- package/dist/verification/classify.d.ts +10 -0
- package/dist/verification/classify.js +53 -0
- package/dist/verification/detect.d.ts +4 -0
- package/dist/verification/detect.js +81 -0
- package/dist/verification/errors.d.ts +11 -0
- package/dist/verification/errors.js +21 -0
- package/dist/verification/index.d.ts +17 -0
- package/dist/verification/index.js +13 -0
- package/dist/verification/limits.d.ts +3 -0
- package/dist/verification/limits.js +40 -0
- package/dist/verification/monitor.d.ts +4 -0
- package/dist/verification/monitor.js +58 -0
- package/dist/verification/orchestrator.d.ts +16 -0
- package/dist/verification/orchestrator.js +363 -0
- package/dist/verification/plan.d.ts +9 -0
- package/dist/verification/plan.js +125 -0
- package/dist/verification/summary.d.ts +40 -0
- package/dist/verification/summary.js +67 -0
- package/dist/verification/types.d.ts +63 -0
- package/dist/verification/types.js +13 -0
- package/dist/workflows/bug-investigation/context.d.ts +7 -0
- package/dist/workflows/bug-investigation/context.js +119 -0
- package/dist/workflows/bug-investigation/descriptor.d.ts +3 -0
- package/dist/workflows/bug-investigation/descriptor.js +46 -0
- package/dist/workflows/bug-investigation/emit.d.ts +12 -0
- package/dist/workflows/bug-investigation/emit.js +35 -0
- package/dist/workflows/bug-investigation/events.d.ts +81 -0
- package/dist/workflows/bug-investigation/events.js +9 -0
- package/dist/workflows/bug-investigation/failure-parse.d.ts +3 -0
- package/dist/workflows/bug-investigation/failure-parse.js +154 -0
- package/dist/workflows/bug-investigation/guard.d.ts +2 -0
- package/dist/workflows/bug-investigation/guard.js +69 -0
- package/dist/workflows/bug-investigation/index.d.ts +7 -0
- package/dist/workflows/bug-investigation/index.js +13 -0
- package/dist/workflows/bug-investigation/internal.d.ts +37 -0
- package/dist/workflows/bug-investigation/internal.js +64 -0
- package/dist/workflows/bug-investigation/model-loop.d.ts +4 -0
- package/dist/workflows/bug-investigation/model-loop.js +223 -0
- package/dist/workflows/bug-investigation/parse.d.ts +3 -0
- package/dist/workflows/bug-investigation/parse.js +123 -0
- package/dist/workflows/bug-investigation/prompt.d.ts +4 -0
- package/dist/workflows/bug-investigation/prompt.js +107 -0
- package/dist/workflows/bug-investigation/report.d.ts +23 -0
- package/dist/workflows/bug-investigation/report.js +151 -0
- package/dist/workflows/bug-investigation/stages.d.ts +13 -0
- package/dist/workflows/bug-investigation/stages.js +242 -0
- package/dist/workflows/bug-investigation/types.d.ts +91 -0
- package/dist/workflows/bug-investigation/types.js +14 -0
- package/dist/workflows/bug-investigation/verify-stage.d.ts +10 -0
- package/dist/workflows/bug-investigation/verify-stage.js +91 -0
- package/dist/workflows/bug-investigation/workflow.d.ts +2 -0
- package/dist/workflows/bug-investigation/workflow.js +74 -0
- package/dist/workflows/descriptor.d.ts +20 -0
- package/dist/workflows/descriptor.js +8 -0
- package/dist/workflows/index.d.ts +3 -0
- package/dist/workflows/index.js +2 -0
- package/dist/workflows/unit-tests/context.d.ts +7 -0
- package/dist/workflows/unit-tests/context.js +129 -0
- package/dist/workflows/unit-tests/conventions.d.ts +4 -0
- package/dist/workflows/unit-tests/conventions.js +87 -0
- package/dist/workflows/unit-tests/descriptor.d.ts +4 -0
- package/dist/workflows/unit-tests/descriptor.js +43 -0
- package/dist/workflows/unit-tests/emit.d.ts +12 -0
- package/dist/workflows/unit-tests/emit.js +35 -0
- package/dist/workflows/unit-tests/events.d.ts +78 -0
- package/dist/workflows/unit-tests/events.js +7 -0
- package/dist/workflows/unit-tests/index.d.ts +6 -0
- package/dist/workflows/unit-tests/index.js +10 -0
- package/dist/workflows/unit-tests/internal.d.ts +35 -0
- package/dist/workflows/unit-tests/internal.js +43 -0
- package/dist/workflows/unit-tests/model-loop.d.ts +4 -0
- package/dist/workflows/unit-tests/model-loop.js +95 -0
- package/dist/workflows/unit-tests/parse.d.ts +6 -0
- package/dist/workflows/unit-tests/parse.js +68 -0
- package/dist/workflows/unit-tests/prompt.d.ts +4 -0
- package/dist/workflows/unit-tests/prompt.js +71 -0
- package/dist/workflows/unit-tests/report.d.ts +21 -0
- package/dist/workflows/unit-tests/report.js +90 -0
- package/dist/workflows/unit-tests/stages.d.ts +9 -0
- package/dist/workflows/unit-tests/stages.js +155 -0
- package/dist/workflows/unit-tests/types.d.ts +70 -0
- package/dist/workflows/unit-tests/types.js +11 -0
- package/dist/workflows/unit-tests/verify-stage.d.ts +9 -0
- package/dist/workflows/unit-tests/verify-stage.js +56 -0
- package/dist/workflows/unit-tests/workflow.d.ts +2 -0
- package/dist/workflows/unit-tests/workflow.js +58 -0
- package/dist/workspace/contextPack.d.ts +9 -0
- package/dist/workspace/contextPack.js +94 -0
- package/dist/workspace/detect.d.ts +3 -0
- package/dist/workspace/detect.js +135 -0
- package/dist/workspace/discovery.d.ts +9 -0
- package/dist/workspace/discovery.js +167 -0
- package/dist/workspace/errors.d.ts +39 -0
- package/dist/workspace/errors.js +66 -0
- package/dist/workspace/fs.d.ts +21 -0
- package/dist/workspace/fs.js +36 -0
- package/dist/workspace/ignore.d.ts +14 -0
- package/dist/workspace/ignore.js +176 -0
- package/dist/workspace/index.d.ts +11 -0
- package/dist/workspace/index.js +13 -0
- package/dist/workspace/paths.d.ts +2 -0
- package/dist/workspace/paths.js +38 -0
- package/dist/workspace/realpath.d.ts +7 -0
- package/dist/workspace/realpath.js +72 -0
- package/dist/workspace/retrieval.d.ts +9 -0
- package/dist/workspace/retrieval.js +74 -0
- package/dist/workspace/summary.d.ts +3 -0
- package/dist/workspace/summary.js +54 -0
- package/dist/workspace/types.d.ts +103 -0
- package/dist/workspace/types.js +27 -0
- package/package.json +58 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { QueueEventSink } from "./sink.js";
|
|
2
|
+
export type RunStatus = "running" | "completed" | "cancelled" | "failed";
|
|
3
|
+
export interface AppliableSnapshot {
|
|
4
|
+
readonly kind: "unit-tests" | "bug-investigation";
|
|
5
|
+
readonly payload: unknown;
|
|
6
|
+
readonly limits: Record<string, unknown> | undefined;
|
|
7
|
+
}
|
|
8
|
+
export interface RunRecord {
|
|
9
|
+
readonly runId: string;
|
|
10
|
+
readonly fingerprint: string;
|
|
11
|
+
readonly modelId: string;
|
|
12
|
+
readonly sink: QueueEventSink;
|
|
13
|
+
status: RunStatus;
|
|
14
|
+
report: unknown;
|
|
15
|
+
readonly cancel: (reason?: string) => void;
|
|
16
|
+
appliable: AppliableSnapshot | undefined;
|
|
17
|
+
applyReport: unknown;
|
|
18
|
+
appliedAt: number | undefined;
|
|
19
|
+
terminatedAt: number | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface RegisterRunInput {
|
|
22
|
+
readonly runId: string;
|
|
23
|
+
readonly fingerprint: string;
|
|
24
|
+
readonly modelId: string;
|
|
25
|
+
readonly sink: QueueEventSink;
|
|
26
|
+
readonly cancel: (reason?: string) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface RunRegistryOptions {
|
|
29
|
+
readonly maxActiveRuns?: number | undefined;
|
|
30
|
+
readonly terminatedTtlMs?: number | undefined;
|
|
31
|
+
readonly now?: (() => number) | undefined;
|
|
32
|
+
}
|
|
33
|
+
export declare class ActiveRunLimitError extends Error {
|
|
34
|
+
constructor(limit: number);
|
|
35
|
+
}
|
|
36
|
+
export interface RunRegistry {
|
|
37
|
+
register: (input: RegisterRunInput) => RunRecord;
|
|
38
|
+
get: (runId: string) => RunRecord | undefined;
|
|
39
|
+
complete: (runId: string, status: Exclude<RunStatus, "running">, report: unknown, appliable: AppliableSnapshot | undefined) => void;
|
|
40
|
+
activeCount: () => number;
|
|
41
|
+
size: () => number;
|
|
42
|
+
}
|
|
43
|
+
export declare function createRunRegistry(options?: RunRegistryOptions): RunRegistry;
|
package/dist/ui/runs.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// The in-memory run registry (ADR-0011 D7). It maps a runId to a live run record (the streaming
|
|
2
|
+
// sink, the run status, the captured final report, and a cancel handle). It is BOUNDED on two axes:
|
|
3
|
+
// a cap on simultaneously-active runs (a new run is refused past the cap) and a TTL after which a
|
|
4
|
+
// TERMINATED run's record — including its event ring buffer — is evicted to reclaim memory (D7's
|
|
5
|
+
// documented retention: buffers are dropped once the run terminates and its TTL elapses). The
|
|
6
|
+
// registry is created via `createRunRegistry` and hung off the handler deps, never a module global,
|
|
7
|
+
// so each server instance (and each test) owns an isolated registry with no cross-talk.
|
|
8
|
+
export class ActiveRunLimitError extends Error {
|
|
9
|
+
constructor(limit) {
|
|
10
|
+
super(`active run limit reached (${String(limit)})`);
|
|
11
|
+
this.name = "ActiveRunLimitError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const DEFAULT_MAX_ACTIVE_RUNS = 16;
|
|
15
|
+
const DEFAULT_TERMINATED_TTL_MS = 600_000;
|
|
16
|
+
function isTerminal(status) {
|
|
17
|
+
return status !== "running";
|
|
18
|
+
}
|
|
19
|
+
function evictExpired(state) {
|
|
20
|
+
const cutoff = state.now();
|
|
21
|
+
for (const [runId, record] of state.records) {
|
|
22
|
+
if (record.terminatedAt !== undefined && cutoff - record.terminatedAt >= state.ttlMs) {
|
|
23
|
+
state.records.delete(runId);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function countActive(state) {
|
|
28
|
+
let count = 0;
|
|
29
|
+
for (const record of state.records.values()) {
|
|
30
|
+
if (!isTerminal(record.status)) {
|
|
31
|
+
count += 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return count;
|
|
35
|
+
}
|
|
36
|
+
function registerRun(state, input) {
|
|
37
|
+
evictExpired(state);
|
|
38
|
+
if (countActive(state) >= state.maxActive) {
|
|
39
|
+
throw new ActiveRunLimitError(state.maxActive);
|
|
40
|
+
}
|
|
41
|
+
const record = {
|
|
42
|
+
runId: input.runId,
|
|
43
|
+
fingerprint: input.fingerprint,
|
|
44
|
+
modelId: input.modelId,
|
|
45
|
+
sink: input.sink,
|
|
46
|
+
status: "running",
|
|
47
|
+
report: undefined,
|
|
48
|
+
cancel: input.cancel,
|
|
49
|
+
appliable: undefined,
|
|
50
|
+
applyReport: undefined,
|
|
51
|
+
appliedAt: undefined,
|
|
52
|
+
terminatedAt: undefined,
|
|
53
|
+
};
|
|
54
|
+
state.records.set(input.runId, record);
|
|
55
|
+
return record;
|
|
56
|
+
}
|
|
57
|
+
function completeRun(state, runId, status, report, appliable) {
|
|
58
|
+
const record = state.records.get(runId);
|
|
59
|
+
if (record === undefined) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
record.status = status;
|
|
63
|
+
record.report = report;
|
|
64
|
+
record.appliable = appliable;
|
|
65
|
+
record.terminatedAt = state.now();
|
|
66
|
+
}
|
|
67
|
+
export function createRunRegistry(options = {}) {
|
|
68
|
+
const state = {
|
|
69
|
+
records: new Map(),
|
|
70
|
+
maxActive: options.maxActiveRuns ?? DEFAULT_MAX_ACTIVE_RUNS,
|
|
71
|
+
ttlMs: options.terminatedTtlMs ?? DEFAULT_TERMINATED_TTL_MS,
|
|
72
|
+
now: options.now ?? Date.now,
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
register: (input) => registerRun(state, input),
|
|
76
|
+
get: (runId) => {
|
|
77
|
+
evictExpired(state);
|
|
78
|
+
return state.records.get(runId);
|
|
79
|
+
},
|
|
80
|
+
complete: (runId, status, report, appliable) => {
|
|
81
|
+
completeRun(state, runId, status, report, appliable);
|
|
82
|
+
},
|
|
83
|
+
activeCount: () => {
|
|
84
|
+
evictExpired(state);
|
|
85
|
+
return countActive(state);
|
|
86
|
+
},
|
|
87
|
+
size: () => {
|
|
88
|
+
evictExpired(state);
|
|
89
|
+
return state.records.size;
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Server } from "node:http";
|
|
2
|
+
import { type UiHandlerDeps } from "./deps.js";
|
|
3
|
+
export declare const DEFAULT_UI_PORT = 4319;
|
|
4
|
+
export declare const UI_HOST = "127.0.0.1";
|
|
5
|
+
export interface UiServerDeps {
|
|
6
|
+
readonly staticRoot: string;
|
|
7
|
+
readonly csp: string;
|
|
8
|
+
readonly port: number;
|
|
9
|
+
readonly handlerDeps?: UiHandlerDeps | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function createUiServer(deps: UiServerDeps): Server;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// The local UI BFF binds 127.0.0.1 only, applies security headers and CSP to every response,
|
|
2
|
+
// rejects non-loopback Host/Origin headers, dispatches API routes through injected handlers,
|
|
3
|
+
// and serves the static export from a contained root.
|
|
4
|
+
import { createServer } from "node:http";
|
|
5
|
+
import { extname, join } from "node:path";
|
|
6
|
+
import { applySecurityHeaders } from "./headers.js";
|
|
7
|
+
import { isAllowedHost } from "./host-check.js";
|
|
8
|
+
import { resolveContainedPath, serveFile } from "./static.js";
|
|
9
|
+
import { errorBody, isApiPath, matchRoute, methodNotAllowedBody, notFoundBody, STREAMING, } from "./routes.js";
|
|
10
|
+
import { buildRedactor } from "./deps.js";
|
|
11
|
+
import { createRunRegistry } from "./runs.js";
|
|
12
|
+
import { createInMemoryUiStore } from "./store/index.js";
|
|
13
|
+
export const DEFAULT_UI_PORT = 4319;
|
|
14
|
+
export const UI_HOST = "127.0.0.1";
|
|
15
|
+
function writeJson(res, status, body) {
|
|
16
|
+
res.statusCode = status;
|
|
17
|
+
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
18
|
+
res.end(JSON.stringify(body));
|
|
19
|
+
}
|
|
20
|
+
function isJsonRequest(req) {
|
|
21
|
+
const header = req.headers["content-type"];
|
|
22
|
+
const value = typeof header === "string" ? header : header?.[0];
|
|
23
|
+
return value?.split(";", 1)[0]?.trim().toLowerCase() === "application/json";
|
|
24
|
+
}
|
|
25
|
+
function hasCsrfHeader(req) {
|
|
26
|
+
const header = req.headers["x-keiko-csrf"];
|
|
27
|
+
const value = Array.isArray(header) ? header[0] : header;
|
|
28
|
+
return value === "1";
|
|
29
|
+
}
|
|
30
|
+
function rejectUnsupportedMediaType(res) {
|
|
31
|
+
writeJson(res, 415, errorBody("UNSUPPORTED_MEDIA_TYPE", "State-changing API requests must use JSON."));
|
|
32
|
+
}
|
|
33
|
+
function rejectCsrf(res) {
|
|
34
|
+
writeJson(res, 403, errorBody("FORBIDDEN_CSRF", "Missing state-changing request guard."));
|
|
35
|
+
}
|
|
36
|
+
// A minimal default deps object so a 3-arg server can still serve the deps-bound read routes (e.g.
|
|
37
|
+
// `/api/models` and `/api/workspace`, which need no config) without a config or evidence dir. The
|
|
38
|
+
// fallback UI store is in-memory: a 3-arg server is used by the Wave 1 host smoke and by tests that
|
|
39
|
+
// never exercise the store routes, so an ephemeral in-memory store is the safe degraded shape.
|
|
40
|
+
function fallbackDeps() {
|
|
41
|
+
return {
|
|
42
|
+
config: undefined,
|
|
43
|
+
configPresent: false,
|
|
44
|
+
evidenceStore: { put: () => "", list: () => [], get: () => undefined, delete: () => undefined },
|
|
45
|
+
env: {},
|
|
46
|
+
redactor: buildRedactor({}),
|
|
47
|
+
registry: createRunRegistry(),
|
|
48
|
+
modelPortFactory: () => undefined,
|
|
49
|
+
store: createInMemoryUiStore(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function isStateChangingMethod(method) {
|
|
53
|
+
return (method === "POST" || method === "PATCH" || method === "PUT" || method === "DELETE");
|
|
54
|
+
}
|
|
55
|
+
// Returns true when the request was rejected (caller should return immediately).
|
|
56
|
+
function rejectIfInvalidStateChange(req, res) {
|
|
57
|
+
if (!isJsonRequest(req)) {
|
|
58
|
+
rejectUnsupportedMediaType(res);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (!hasCsrfHeader(req)) {
|
|
62
|
+
rejectCsrf(res);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
async function dispatchApi(handlerDeps, req, res, method, url) {
|
|
68
|
+
const match = matchRoute(method, url.pathname);
|
|
69
|
+
if (match === undefined) {
|
|
70
|
+
writeJson(res, 404, notFoundBody());
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (match === "method-not-allowed") {
|
|
74
|
+
writeJson(res, 405, methodNotAllowedBody());
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (isStateChangingMethod(method) && rejectIfInvalidStateChange(req, res)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const ctx = { req, res, params: match.params, url };
|
|
81
|
+
const outcome = await match.definition.handler(ctx, handlerDeps);
|
|
82
|
+
if (outcome === STREAMING) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
writeJson(res, outcome.status, outcome.body);
|
|
86
|
+
}
|
|
87
|
+
async function serveStatic(res, staticRoot, pathname) {
|
|
88
|
+
const targets = pathname === "/"
|
|
89
|
+
? ["/index.html"]
|
|
90
|
+
: extname(pathname) === ""
|
|
91
|
+
? [pathname, `${pathname}.html`, `${pathname}/index.html`]
|
|
92
|
+
: [pathname];
|
|
93
|
+
for (const target of targets) {
|
|
94
|
+
const resolved = resolveContainedPath(staticRoot, target);
|
|
95
|
+
if (resolved !== undefined && (await serveFile(res, resolved))) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const indexPath = join(staticRoot, "index.html");
|
|
100
|
+
if (await serveFile(res, indexPath)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
writeJson(res, 404, errorBody("NOT_FOUND", "The requested resource was not found."));
|
|
104
|
+
}
|
|
105
|
+
function rejectForbiddenHost(res) {
|
|
106
|
+
const body = errorBody("FORBIDDEN_HOST", "Request host is not the local interface.");
|
|
107
|
+
writeJson(res, 403, body);
|
|
108
|
+
}
|
|
109
|
+
function handle(deps, handlerDeps, req, res) {
|
|
110
|
+
const url = new URL(req.url ?? "/", `http://${UI_HOST}`);
|
|
111
|
+
const apiPath = isApiPath(url.pathname);
|
|
112
|
+
applySecurityHeaders(res, deps.csp, apiPath);
|
|
113
|
+
if (!isAllowedHost(req, deps.port)) {
|
|
114
|
+
rejectForbiddenHost(res);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
118
|
+
const work = apiPath
|
|
119
|
+
? dispatchApi(handlerDeps, req, res, method, url)
|
|
120
|
+
: serveStatic(res, deps.staticRoot, url.pathname);
|
|
121
|
+
void work.catch(() => {
|
|
122
|
+
if (!res.headersSent) {
|
|
123
|
+
writeJson(res, 500, errorBody("INTERNAL", "An unexpected error occurred."));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
res.end();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// Creates the BFF server. The caller binds it with `server.listen(deps.port, UI_HOST)` so it never
|
|
131
|
+
// listens on a non-loopback interface. The previous PTY WebSocket upgrade handler is removed —
|
|
132
|
+
// the terminal tool is now bounded-exec over plain HTTP (ADR-0018 D1/D8).
|
|
133
|
+
export function createUiServer(deps) {
|
|
134
|
+
const handlerDeps = deps.handlerDeps ?? fallbackDeps();
|
|
135
|
+
const server = createServer((req, res) => {
|
|
136
|
+
handle(deps, handlerDeps, req, res);
|
|
137
|
+
});
|
|
138
|
+
server.on("upgrade", (_req, socket) => {
|
|
139
|
+
socket.write("HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n");
|
|
140
|
+
socket.destroy();
|
|
141
|
+
});
|
|
142
|
+
return server;
|
|
143
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface StreamEvent {
|
|
2
|
+
readonly schemaVersion: "1";
|
|
3
|
+
readonly runId: string;
|
|
4
|
+
readonly fingerprint: string;
|
|
5
|
+
readonly seq: number;
|
|
6
|
+
readonly ts: number;
|
|
7
|
+
readonly type: string;
|
|
8
|
+
}
|
|
9
|
+
export interface SseWriter {
|
|
10
|
+
readonly write: (event: StreamEvent) => boolean | undefined;
|
|
11
|
+
readonly close: () => void;
|
|
12
|
+
}
|
|
13
|
+
export interface QueueEventSinkOptions {
|
|
14
|
+
readonly bufferCapacity?: number | undefined;
|
|
15
|
+
}
|
|
16
|
+
export declare class QueueEventSink {
|
|
17
|
+
private readonly buffer;
|
|
18
|
+
private readonly capacity;
|
|
19
|
+
private readonly writers;
|
|
20
|
+
private terminated;
|
|
21
|
+
readonly emit: (event: StreamEvent) => void;
|
|
22
|
+
constructor(options?: QueueEventSinkOptions);
|
|
23
|
+
attach(writer: SseWriter, afterSeq: number): () => void;
|
|
24
|
+
closeAll(): void;
|
|
25
|
+
isTerminated(): boolean;
|
|
26
|
+
buffered(afterSeq?: number): readonly StreamEvent[];
|
|
27
|
+
}
|
package/dist/ui/sink.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// The QueueEventSink bridges the harness's push-only, synchronous EventSink (and the structurally
|
|
2
|
+
// identical workflow WorkflowEventSink / BugWorkflowEventSink) to Server-Sent Events (ADR-0011 D7).
|
|
3
|
+
// It satisfies all three sink shapes — each is `{ emit(event): void }` over an event that carries
|
|
4
|
+
// the `{ schemaVersion, runId, fingerprint, seq, ts, type }` envelope — with one `emit` typed over
|
|
5
|
+
// that structural envelope (no `any`; the concrete unions are assignable to it).
|
|
6
|
+
//
|
|
7
|
+
// It deliberately does NOT set `retainsRawContent`, so the harness emitter redacts every SENSITIVE
|
|
8
|
+
// field before this sink ever receives an event (the browser only sees redacted events). Internally
|
|
9
|
+
// it (a) appends each received event to a per-run BOUNDED ring buffer for replay-on-connect (oldest
|
|
10
|
+
// dropped past the cap), and (b) fans the event out to any currently-attached SSE writers. A late or
|
|
11
|
+
// reconnecting subscriber replays the buffer (respecting Last-Event-ID = the harness `seq`), then
|
|
12
|
+
// receives live events, then a close after the terminal event.
|
|
13
|
+
const DEFAULT_BUFFER_CAPACITY = 512;
|
|
14
|
+
export class QueueEventSink {
|
|
15
|
+
// retainsRawContent is intentionally absent (never true): the harness must redact before emit.
|
|
16
|
+
buffer = [];
|
|
17
|
+
capacity;
|
|
18
|
+
writers = new Set();
|
|
19
|
+
terminated = false;
|
|
20
|
+
// Bound so the sink can be passed directly as an `EventSink`/`WorkflowEventSink`/`BugWorkflowEventSink`.
|
|
21
|
+
emit = (event) => {
|
|
22
|
+
this.buffer.push(event);
|
|
23
|
+
if (this.buffer.length > this.capacity) {
|
|
24
|
+
this.buffer.shift();
|
|
25
|
+
}
|
|
26
|
+
for (const writer of [...this.writers]) {
|
|
27
|
+
try {
|
|
28
|
+
const accepted = writer.write(event);
|
|
29
|
+
if (accepted === false) {
|
|
30
|
+
this.writers.delete(writer);
|
|
31
|
+
writer.close();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
this.writers.delete(writer);
|
|
36
|
+
writer.close();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
constructor(options = {}) {
|
|
41
|
+
this.capacity = options.bufferCapacity ?? DEFAULT_BUFFER_CAPACITY;
|
|
42
|
+
}
|
|
43
|
+
// Attaches an SSE writer: replays the buffered events with `seq` strictly greater than
|
|
44
|
+
// `afterSeq` (Last-Event-ID resume), then keeps the writer attached for live fan-out. Returns a
|
|
45
|
+
// detach function the caller invokes on client disconnect to stop fan-out and avoid leaks.
|
|
46
|
+
attach(writer, afterSeq) {
|
|
47
|
+
for (const event of this.buffer) {
|
|
48
|
+
if (event.seq > afterSeq) {
|
|
49
|
+
const accepted = writer.write(event);
|
|
50
|
+
if (accepted === false) {
|
|
51
|
+
writer.close();
|
|
52
|
+
return () => undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
this.writers.add(writer);
|
|
57
|
+
return () => {
|
|
58
|
+
this.writers.delete(writer);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Closes and clears every attached writer (called once the run terminates). The ring buffer is
|
|
62
|
+
// retained for the registry TTL so a late subscriber can still replay history before eviction.
|
|
63
|
+
closeAll() {
|
|
64
|
+
if (this.terminated) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.terminated = true;
|
|
68
|
+
for (const writer of this.writers) {
|
|
69
|
+
writer.close();
|
|
70
|
+
}
|
|
71
|
+
this.writers.clear();
|
|
72
|
+
}
|
|
73
|
+
isTerminated() {
|
|
74
|
+
return this.terminated;
|
|
75
|
+
}
|
|
76
|
+
// Snapshot of buffered events with `seq` strictly greater than `afterSeq` (inspection/replay aid).
|
|
77
|
+
buffered(afterSeq = -1) {
|
|
78
|
+
return this.buffer.filter((event) => event.seq > afterSeq);
|
|
79
|
+
}
|
|
80
|
+
}
|
package/dist/ui/sse.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ServerResponse } from "node:http";
|
|
2
|
+
import type { StreamEvent } from "./sink.js";
|
|
3
|
+
import type { Redactor } from "./deps.js";
|
|
4
|
+
export declare const SSE_HEADERS: Readonly<Record<string, string>>;
|
|
5
|
+
export declare function frameEvent(event: StreamEvent, redactor: Redactor): string;
|
|
6
|
+
export declare function readyMessage(): string;
|
|
7
|
+
export declare function writeEvent(res: ServerResponse, event: StreamEvent, redactor: Redactor): boolean;
|
package/dist/ui/sse.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Server-Sent Events framing for the run event stream (ADR-0011 D5/D7). One harness/workflow event
|
|
2
|
+
// becomes one SSE message: `id:` is the event `seq` (the Last-Event-ID resume cursor), `event:` is
|
|
3
|
+
// the event `type`, `data:` is the redacted event JSON on a single line, terminated by a blank line.
|
|
4
|
+
// The event JSON is produced by `JSON.stringify`, which never emits a raw newline inside a string
|
|
5
|
+
// (newlines are escaped as `\n`), so a single `data:` line is always valid — no regex, no manual
|
|
6
|
+
// escaping. A synthetic `ready` message is sent after the buffered replay.
|
|
7
|
+
export const SSE_HEADERS = {
|
|
8
|
+
"Content-Type": "text/event-stream; charset=utf-8",
|
|
9
|
+
"Cache-Control": "no-store",
|
|
10
|
+
Connection: "keep-alive",
|
|
11
|
+
};
|
|
12
|
+
// Frames one event as an SSE message. The event is redacted (defense in depth: live events are
|
|
13
|
+
// already redacted by the harness emitter, D7) before serialization.
|
|
14
|
+
export function frameEvent(event, redactor) {
|
|
15
|
+
const data = JSON.stringify(redactor(event));
|
|
16
|
+
return `id: ${String(event.seq)}\nevent: ${event.type}\ndata: ${data}\n\n`;
|
|
17
|
+
}
|
|
18
|
+
// The synthetic message sent once the buffered replay completes, signalling the client that it is
|
|
19
|
+
// now live. Carries no data payload.
|
|
20
|
+
export function readyMessage() {
|
|
21
|
+
return `event: ready\ndata: {}\n\n`;
|
|
22
|
+
}
|
|
23
|
+
// Writes one framed event to the response stream. Returns Node's backpressure signal so the caller can
|
|
24
|
+
// detach a slow client instead of letting the HTTP response buffer grow without bound.
|
|
25
|
+
export function writeEvent(res, event, redactor) {
|
|
26
|
+
return res.write(frameEvent(event, redactor));
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!DOCTYPE html><!--ca_A01hy9W98aRvMZKdAw--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/be7cb54d5c5673b6.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-4a462cecab786e93.js"/><script src="/_next/static/chunks/4bd1b696-c023c6e3521b1417.js" async=""></script><script src="/_next/static/chunks/255-d47fd57964443afe.js" async=""></script><script src="/_next/static/chunks/main-app-30679af7240d63e9.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Keiko</title><meta name="description" content="Keiko local developer-assist workspace."/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-4a462cecab786e93.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[9766,[],\"\"]\n3:I[8924,[],\"\"]\n4:I[4431,[],\"OutletBoundary\"]\n6:I[5278,[],\"AsyncMetadataOutlet\"]\n8:I[4431,[],\"ViewportBoundary\"]\na:I[4431,[],\"MetadataBoundary\"]\nb:\"$Sreact.suspense\"\nd:I[7150,[],\"\"]\n:HL[\"/_next/static/css/be7cb54d5c5673b6.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"ca-A01hy9W98aRvMZKdAw\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/be7cb54d5c5673b6.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",[\"$\",\"$L6\",null,{\"promise\":\"$@7\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],null],[\"$\",\"$La\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$b\",null,{\"fallback\":null,\"children\":\"$Lc\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"7:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Keiko\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Keiko local developer-assist workspace.\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"c:\"$7:metadata\"\n"])</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__BUILD_MANIFEST=function(e,r,t){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:3,errorRate:1e-4,numBits:58,numHashes:14,bitArray:[1,1,0,e,0,e,e,e,r,e,e,e,r,e,r,e,r,r,e,r,e,r,e,r,r,e,r,r,e,r,e,e,e,e,e,e,e,e,e,e,e,r,e,r,e,r,r,e,e,e,r,e,r,r,r,r,e,e]},__routerFilterDynamic:{numItems:r,errorRate:1e-4,numBits:r,numHashes:null,bitArray:[]},"/_error":["static/chunks/pages/_error-cb2a52f75f2162e2.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|