agenticreplay 0.1.0 → 0.1.2
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 +14 -13
- package/bin/agenticreplay.js +2 -0
- package/node_modules/@agenticreplay/adapters/dist/claude-code.d.ts +37 -0
- package/node_modules/@agenticreplay/adapters/dist/claude-code.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/claude-code.js +103 -0
- package/node_modules/@agenticreplay/adapters/dist/claude-code.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/codex.d.ts +36 -0
- package/node_modules/@agenticreplay/adapters/dist/codex.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/codex.js +130 -0
- package/node_modules/@agenticreplay/adapters/dist/codex.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/contract.d.ts +65 -0
- package/node_modules/@agenticreplay/adapters/dist/contract.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/contract.js +460 -0
- package/node_modules/@agenticreplay/adapters/dist/contract.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/cursor.d.ts +40 -0
- package/node_modules/@agenticreplay/adapters/dist/cursor.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/cursor.js +71 -0
- package/node_modules/@agenticreplay/adapters/dist/cursor.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/detect.d.ts +47 -0
- package/node_modules/@agenticreplay/adapters/dist/detect.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/detect.js +123 -0
- package/node_modules/@agenticreplay/adapters/dist/detect.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/env.d.ts +60 -0
- package/node_modules/@agenticreplay/adapters/dist/env.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/env.js +99 -0
- package/node_modules/@agenticreplay/adapters/dist/env.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/exec.d.ts +25 -0
- package/node_modules/@agenticreplay/adapters/dist/exec.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/exec.js +51 -0
- package/node_modules/@agenticreplay/adapters/dist/exec.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/generic-openai.d.ts +8 -0
- package/node_modules/@agenticreplay/adapters/dist/generic-openai.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/generic-openai.js +31 -0
- package/node_modules/@agenticreplay/adapters/dist/generic-openai.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/goose.d.ts +39 -0
- package/node_modules/@agenticreplay/adapters/dist/goose.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/goose.js +81 -0
- package/node_modules/@agenticreplay/adapters/dist/goose.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/grok.d.ts +23 -0
- package/node_modules/@agenticreplay/adapters/dist/grok.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/grok.js +50 -0
- package/node_modules/@agenticreplay/adapters/dist/grok.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/hermes.d.ts +70 -0
- package/node_modules/@agenticreplay/adapters/dist/hermes.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/hermes.js +88 -0
- package/node_modules/@agenticreplay/adapters/dist/hermes.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/index.d.ts +25 -0
- package/node_modules/@agenticreplay/adapters/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/index.js +25 -0
- package/node_modules/@agenticreplay/adapters/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/indexrag.d.ts +27 -0
- package/node_modules/@agenticreplay/adapters/dist/indexrag.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/indexrag.js +236 -0
- package/node_modules/@agenticreplay/adapters/dist/indexrag.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/kilo.d.ts +21 -0
- package/node_modules/@agenticreplay/adapters/dist/kilo.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/kilo.js +35 -0
- package/node_modules/@agenticreplay/adapters/dist/kilo.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/mcode.d.ts +81 -0
- package/node_modules/@agenticreplay/adapters/dist/mcode.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/mcode.js +368 -0
- package/node_modules/@agenticreplay/adapters/dist/mcode.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/mcp-config.d.ts +17 -0
- package/node_modules/@agenticreplay/adapters/dist/mcp-config.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/mcp-config.js +62 -0
- package/node_modules/@agenticreplay/adapters/dist/mcp-config.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/mimo.d.ts +26 -0
- package/node_modules/@agenticreplay/adapters/dist/mimo.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/mimo.js +40 -0
- package/node_modules/@agenticreplay/adapters/dist/mimo.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/node.d.ts +19 -0
- package/node_modules/@agenticreplay/adapters/dist/node.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/node.js +59 -0
- package/node_modules/@agenticreplay/adapters/dist/node.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/openclaw.d.ts +19 -0
- package/node_modules/@agenticreplay/adapters/dist/openclaw.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/openclaw.js +43 -0
- package/node_modules/@agenticreplay/adapters/dist/openclaw.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-api-bases.d.ts +2 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-api-bases.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-api-bases.js +201 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-api-bases.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-capture.d.ts +26 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-capture.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-capture.js +132 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-capture.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-catalog.d.ts +5 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-catalog.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-catalog.js +43 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-catalog.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-config.d.ts +40 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-config.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-config.js +185 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode-config.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode.d.ts +10 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode.js +243 -0
- package/node_modules/@agenticreplay/adapters/dist/opencode.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/qwen.d.ts +51 -0
- package/node_modules/@agenticreplay/adapters/dist/qwen.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/qwen.js +105 -0
- package/node_modules/@agenticreplay/adapters/dist/qwen.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/registry.d.ts +19 -0
- package/node_modules/@agenticreplay/adapters/dist/registry.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/registry.js +110 -0
- package/node_modules/@agenticreplay/adapters/dist/registry.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/scaffold.d.ts +26 -0
- package/node_modules/@agenticreplay/adapters/dist/scaffold.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/scaffold.js +125 -0
- package/node_modules/@agenticreplay/adapters/dist/scaffold.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/session.d.ts +47 -0
- package/node_modules/@agenticreplay/adapters/dist/session.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/session.js +112 -0
- package/node_modules/@agenticreplay/adapters/dist/session.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/zcode.d.ts +60 -0
- package/node_modules/@agenticreplay/adapters/dist/zcode.d.ts.map +1 -0
- package/node_modules/@agenticreplay/adapters/dist/zcode.js +424 -0
- package/node_modules/@agenticreplay/adapters/dist/zcode.js.map +1 -0
- package/node_modules/@agenticreplay/adapters/package.json +29 -0
- package/node_modules/@agenticreplay/core/dist/blobs.d.ts +21 -0
- package/node_modules/@agenticreplay/core/dist/blobs.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/blobs.js +102 -0
- package/node_modules/@agenticreplay/core/dist/blobs.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/fetch.d.ts +38 -0
- package/node_modules/@agenticreplay/core/dist/fetch.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/fetch.js +47 -0
- package/node_modules/@agenticreplay/core/dist/fetch.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/graph.d.ts +106 -0
- package/node_modules/@agenticreplay/core/dist/graph.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/graph.js +394 -0
- package/node_modules/@agenticreplay/core/dist/graph.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/index.d.ts +9 -0
- package/node_modules/@agenticreplay/core/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/index.js +9 -0
- package/node_modules/@agenticreplay/core/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/paths.d.ts +45 -0
- package/node_modules/@agenticreplay/core/dist/paths.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/paths.js +149 -0
- package/node_modules/@agenticreplay/core/dist/paths.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/private-files.d.ts +37 -0
- package/node_modules/@agenticreplay/core/dist/private-files.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/private-files.js +353 -0
- package/node_modules/@agenticreplay/core/dist/private-files.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/reader.d.ts +45 -0
- package/node_modules/@agenticreplay/core/dist/reader.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/reader.js +152 -0
- package/node_modules/@agenticreplay/core/dist/reader.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/redaction.d.ts +69 -0
- package/node_modules/@agenticreplay/core/dist/redaction.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/redaction.js +768 -0
- package/node_modules/@agenticreplay/core/dist/redaction.js.map +1 -0
- package/node_modules/@agenticreplay/core/dist/writer.d.ts +75 -0
- package/node_modules/@agenticreplay/core/dist/writer.d.ts.map +1 -0
- package/node_modules/@agenticreplay/core/dist/writer.js +368 -0
- package/node_modules/@agenticreplay/core/dist/writer.js.map +1 -0
- package/node_modules/@agenticreplay/core/package.json +26 -0
- package/node_modules/@agenticreplay/fs-capture/dist/capture.d.ts +84 -0
- package/node_modules/@agenticreplay/fs-capture/dist/capture.d.ts.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/capture.js +147 -0
- package/node_modules/@agenticreplay/fs-capture/dist/capture.js.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/git.d.ts +25 -0
- package/node_modules/@agenticreplay/fs-capture/dist/git.d.ts.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/git.js +108 -0
- package/node_modules/@agenticreplay/fs-capture/dist/git.js.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/index.d.ts +4 -0
- package/node_modules/@agenticreplay/fs-capture/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/index.js +4 -0
- package/node_modules/@agenticreplay/fs-capture/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/shadow.d.ts +271 -0
- package/node_modules/@agenticreplay/fs-capture/dist/shadow.d.ts.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/dist/shadow.js +668 -0
- package/node_modules/@agenticreplay/fs-capture/dist/shadow.js.map +1 -0
- package/node_modules/@agenticreplay/fs-capture/package.json +25 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/cli.d.ts +100 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/cli.d.ts.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/cli.js +334 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/cli.js.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/framing.d.ts +41 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/framing.d.ts.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/framing.js +94 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/framing.js.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/index.d.ts +5 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/index.js +5 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/mock.d.ts +70 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/mock.d.ts.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/mock.js +138 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/mock.js.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/shim.d.ts +24 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/shim.d.ts.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/shim.js +105 -0
- package/node_modules/@agenticreplay/mcp-shim/dist/shim.js.map +1 -0
- package/node_modules/@agenticreplay/mcp-shim/package.json +26 -0
- package/node_modules/@agenticreplay/node-instrument/dist/capture.d.ts +58 -0
- package/node_modules/@agenticreplay/node-instrument/dist/capture.d.ts.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/capture.js +404 -0
- package/node_modules/@agenticreplay/node-instrument/dist/capture.js.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/index.d.ts +4 -0
- package/node_modules/@agenticreplay/node-instrument/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/index.js +4 -0
- package/node_modules/@agenticreplay/node-instrument/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/install.d.ts +47 -0
- package/node_modules/@agenticreplay/node-instrument/dist/install.d.ts.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/install.js +174 -0
- package/node_modules/@agenticreplay/node-instrument/dist/install.js.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/rewrite.d.ts +33 -0
- package/node_modules/@agenticreplay/node-instrument/dist/rewrite.d.ts.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/dist/rewrite.js +61 -0
- package/node_modules/@agenticreplay/node-instrument/dist/rewrite.js.map +1 -0
- package/node_modules/@agenticreplay/node-instrument/package.json +23 -0
- package/node_modules/@agenticreplay/plugin-api/dist/canonical.d.ts +87 -0
- package/node_modules/@agenticreplay/plugin-api/dist/canonical.d.ts.map +1 -0
- package/node_modules/@agenticreplay/plugin-api/dist/canonical.js +10 -0
- package/node_modules/@agenticreplay/plugin-api/dist/canonical.js.map +1 -0
- package/node_modules/@agenticreplay/plugin-api/dist/index.d.ts +3 -0
- package/node_modules/@agenticreplay/plugin-api/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/plugin-api/dist/index.js +3 -0
- package/node_modules/@agenticreplay/plugin-api/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/plugin-api/dist/plugins.d.ts +258 -0
- package/node_modules/@agenticreplay/plugin-api/dist/plugins.d.ts.map +1 -0
- package/node_modules/@agenticreplay/plugin-api/dist/plugins.js +2 -0
- package/node_modules/@agenticreplay/plugin-api/dist/plugins.js.map +1 -0
- package/node_modules/@agenticreplay/plugin-api/package.json +22 -0
- package/node_modules/@agenticreplay/providers/dist/index.d.ts +34 -0
- package/node_modules/@agenticreplay/providers/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/index.js +34 -0
- package/node_modules/@agenticreplay/providers/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/pricing.d.ts +44 -0
- package/node_modules/@agenticreplay/providers/dist/pricing.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/pricing.js +126 -0
- package/node_modules/@agenticreplay/providers/dist/pricing.js.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/anthropic.d.ts +66 -0
- package/node_modules/@agenticreplay/providers/dist/translate/anthropic.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/anthropic.js +569 -0
- package/node_modules/@agenticreplay/providers/dist/translate/anthropic.js.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai-responses.d.ts +51 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai-responses.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai-responses.js +574 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai-responses.js.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai.d.ts +60 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai.js +577 -0
- package/node_modules/@agenticreplay/providers/dist/translate/openai.js.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/sse.d.ts +29 -0
- package/node_modules/@agenticreplay/providers/dist/translate/sse.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/sse.js +97 -0
- package/node_modules/@agenticreplay/providers/dist/translate/sse.js.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/util.d.ts +34 -0
- package/node_modules/@agenticreplay/providers/dist/translate/util.d.ts.map +1 -0
- package/node_modules/@agenticreplay/providers/dist/translate/util.js +106 -0
- package/node_modules/@agenticreplay/providers/dist/translate/util.js.map +1 -0
- package/node_modules/@agenticreplay/providers/package.json +26 -0
- package/node_modules/@agenticreplay/proxy/dist/ca.d.ts +45 -0
- package/node_modules/@agenticreplay/proxy/dist/ca.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/ca.js +264 -0
- package/node_modules/@agenticreplay/proxy/dist/ca.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/der.d.ts +51 -0
- package/node_modules/@agenticreplay/proxy/dist/der.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/der.js +144 -0
- package/node_modules/@agenticreplay/proxy/dist/der.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/dialects.d.ts +81 -0
- package/node_modules/@agenticreplay/proxy/dist/dialects.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/dialects.js +329 -0
- package/node_modules/@agenticreplay/proxy/dist/dialects.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/forward.d.ts +34 -0
- package/node_modules/@agenticreplay/proxy/dist/forward.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/forward.js +44 -0
- package/node_modules/@agenticreplay/proxy/dist/forward.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/index.d.ts +9 -0
- package/node_modules/@agenticreplay/proxy/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/index.js +9 -0
- package/node_modules/@agenticreplay/proxy/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/intercept.d.ts +234 -0
- package/node_modules/@agenticreplay/proxy/dist/intercept.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/intercept.js +1258 -0
- package/node_modules/@agenticreplay/proxy/dist/intercept.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/matching.d.ts +109 -0
- package/node_modules/@agenticreplay/proxy/dist/matching.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/matching.js +928 -0
- package/node_modules/@agenticreplay/proxy/dist/matching.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/retrieval.d.ts +93 -0
- package/node_modules/@agenticreplay/proxy/dist/retrieval.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/retrieval.js +233 -0
- package/node_modules/@agenticreplay/proxy/dist/retrieval.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/server.d.ts +327 -0
- package/node_modules/@agenticreplay/proxy/dist/server.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/server.js +2291 -0
- package/node_modules/@agenticreplay/proxy/dist/server.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/tls-hosts.d.ts +54 -0
- package/node_modules/@agenticreplay/proxy/dist/tls-hosts.d.ts.map +1 -0
- package/node_modules/@agenticreplay/proxy/dist/tls-hosts.js +178 -0
- package/node_modules/@agenticreplay/proxy/dist/tls-hosts.js.map +1 -0
- package/node_modules/@agenticreplay/proxy/package.json +28 -0
- package/node_modules/@agenticreplay/schema/dist/constants.d.ts +30 -0
- package/node_modules/@agenticreplay/schema/dist/constants.d.ts.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/constants.js +66 -0
- package/node_modules/@agenticreplay/schema/dist/constants.js.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/index.d.ts +4 -0
- package/node_modules/@agenticreplay/schema/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/index.js +4 -0
- package/node_modules/@agenticreplay/schema/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/types.d.ts +97 -0
- package/node_modules/@agenticreplay/schema/dist/types.d.ts.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/types.js +7 -0
- package/node_modules/@agenticreplay/schema/dist/types.js.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/validate.d.ts +13 -0
- package/node_modules/@agenticreplay/schema/dist/validate.d.ts.map +1 -0
- package/node_modules/@agenticreplay/schema/dist/validate.js +44 -0
- package/node_modules/@agenticreplay/schema/dist/validate.js.map +1 -0
- package/node_modules/@agenticreplay/schema/package.json +28 -0
- package/node_modules/@agenticreplay/shell-shim/dist/index.d.ts +4 -0
- package/node_modules/@agenticreplay/shell-shim/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/index.js +4 -0
- package/node_modules/@agenticreplay/shell-shim/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/install.d.ts +75 -0
- package/node_modules/@agenticreplay/shell-shim/dist/install.d.ts.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/install.js +353 -0
- package/node_modules/@agenticreplay/shell-shim/dist/install.js.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/resolve.d.ts +2 -0
- package/node_modules/@agenticreplay/shell-shim/dist/resolve.d.ts.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/resolve.js +97 -0
- package/node_modules/@agenticreplay/shell-shim/dist/resolve.js.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner-bin.d.ts +3 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner-bin.d.ts.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner-bin.js +4 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner-bin.js.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner.d.ts +45 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner.d.ts.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner.js +105 -0
- package/node_modules/@agenticreplay/shell-shim/dist/runner.js.map +1 -0
- package/node_modules/@agenticreplay/shell-shim/package.json +26 -0
- package/node_modules/@agenticreplay/viewer/dist/bundle.d.ts +11 -0
- package/node_modules/@agenticreplay/viewer/dist/bundle.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/bundle.js +36 -0
- package/node_modules/@agenticreplay/viewer/dist/bundle.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/client/main.d.ts +12 -0
- package/node_modules/@agenticreplay/viewer/dist/client/main.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/client/main.js +249 -0
- package/node_modules/@agenticreplay/viewer/dist/client/main.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/credit.d.ts +22 -0
- package/node_modules/@agenticreplay/viewer/dist/credit.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/credit.js +22 -0
- package/node_modules/@agenticreplay/viewer/dist/credit.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/css.d.ts +11 -0
- package/node_modules/@agenticreplay/viewer/dist/css.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/css.js +410 -0
- package/node_modules/@agenticreplay/viewer/dist/css.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/export.d.ts +21 -0
- package/node_modules/@agenticreplay/viewer/dist/export.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/export.js +22 -0
- package/node_modules/@agenticreplay/viewer/dist/export.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/html.d.ts +32 -0
- package/node_modules/@agenticreplay/viewer/dist/html.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/html.js +252 -0
- package/node_modules/@agenticreplay/viewer/dist/html.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/index.d.ts +16 -0
- package/node_modules/@agenticreplay/viewer/dist/index.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/index.js +16 -0
- package/node_modules/@agenticreplay/viewer/dist/index.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/render.d.ts +126 -0
- package/node_modules/@agenticreplay/viewer/dist/render.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/render.js +699 -0
- package/node_modules/@agenticreplay/viewer/dist/render.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/serve.d.ts +21 -0
- package/node_modules/@agenticreplay/viewer/dist/serve.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/serve.js +122 -0
- package/node_modules/@agenticreplay/viewer/dist/serve.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/trace-dir.d.ts +28 -0
- package/node_modules/@agenticreplay/viewer/dist/trace-dir.d.ts.map +1 -0
- package/node_modules/@agenticreplay/viewer/dist/trace-dir.js +120 -0
- package/node_modules/@agenticreplay/viewer/dist/trace-dir.js.map +1 -0
- package/node_modules/@agenticreplay/viewer/package.json +25 -0
- package/node_modules/ajv/.runkit_example.js +23 -0
- package/node_modules/ajv/LICENSE +22 -0
- package/node_modules/ajv/README.md +207 -0
- package/node_modules/ajv/dist/2019.d.ts +19 -0
- package/node_modules/ajv/dist/2019.js +61 -0
- package/node_modules/ajv/dist/2019.js.map +1 -0
- package/node_modules/ajv/dist/2020.d.ts +19 -0
- package/node_modules/ajv/dist/2020.js +55 -0
- package/node_modules/ajv/dist/2020.js.map +1 -0
- package/node_modules/ajv/dist/ajv.d.ts +18 -0
- package/node_modules/ajv/dist/ajv.js +50 -0
- package/node_modules/ajv/dist/ajv.js.map +1 -0
- package/node_modules/ajv/dist/compile/codegen/code.d.ts +40 -0
- package/node_modules/ajv/dist/compile/codegen/code.js +156 -0
- package/node_modules/ajv/dist/compile/codegen/code.js.map +1 -0
- package/node_modules/ajv/dist/compile/codegen/index.d.ts +79 -0
- package/node_modules/ajv/dist/compile/codegen/index.js +697 -0
- package/node_modules/ajv/dist/compile/codegen/index.js.map +1 -0
- package/node_modules/ajv/dist/compile/codegen/scope.d.ts +79 -0
- package/node_modules/ajv/dist/compile/codegen/scope.js +143 -0
- package/node_modules/ajv/dist/compile/codegen/scope.js.map +1 -0
- package/node_modules/ajv/dist/compile/errors.d.ts +13 -0
- package/node_modules/ajv/dist/compile/errors.js +123 -0
- package/node_modules/ajv/dist/compile/errors.js.map +1 -0
- package/node_modules/ajv/dist/compile/index.d.ts +80 -0
- package/node_modules/ajv/dist/compile/index.js +242 -0
- package/node_modules/ajv/dist/compile/index.js.map +1 -0
- package/node_modules/ajv/dist/compile/jtd/parse.d.ts +4 -0
- package/node_modules/ajv/dist/compile/jtd/parse.js +350 -0
- package/node_modules/ajv/dist/compile/jtd/parse.js.map +1 -0
- package/node_modules/ajv/dist/compile/jtd/serialize.d.ts +4 -0
- package/node_modules/ajv/dist/compile/jtd/serialize.js +236 -0
- package/node_modules/ajv/dist/compile/jtd/serialize.js.map +1 -0
- package/node_modules/ajv/dist/compile/jtd/types.d.ts +6 -0
- package/node_modules/ajv/dist/compile/jtd/types.js +14 -0
- package/node_modules/ajv/dist/compile/jtd/types.js.map +1 -0
- package/node_modules/ajv/dist/compile/names.d.ts +20 -0
- package/node_modules/ajv/dist/compile/names.js +28 -0
- package/node_modules/ajv/dist/compile/names.js.map +1 -0
- package/node_modules/ajv/dist/compile/ref_error.d.ts +6 -0
- package/node_modules/ajv/dist/compile/ref_error.js +12 -0
- package/node_modules/ajv/dist/compile/ref_error.js.map +1 -0
- package/node_modules/ajv/dist/compile/resolve.d.ts +12 -0
- package/node_modules/ajv/dist/compile/resolve.js +155 -0
- package/node_modules/ajv/dist/compile/resolve.js.map +1 -0
- package/node_modules/ajv/dist/compile/rules.d.ts +28 -0
- package/node_modules/ajv/dist/compile/rules.js +26 -0
- package/node_modules/ajv/dist/compile/rules.js.map +1 -0
- package/node_modules/ajv/dist/compile/util.d.ts +40 -0
- package/node_modules/ajv/dist/compile/util.js +178 -0
- package/node_modules/ajv/dist/compile/util.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/applicability.d.ts +6 -0
- package/node_modules/ajv/dist/compile/validate/applicability.js +19 -0
- package/node_modules/ajv/dist/compile/validate/applicability.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/boolSchema.d.ts +4 -0
- package/node_modules/ajv/dist/compile/validate/boolSchema.js +50 -0
- package/node_modules/ajv/dist/compile/validate/boolSchema.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/dataType.d.ts +17 -0
- package/node_modules/ajv/dist/compile/validate/dataType.js +203 -0
- package/node_modules/ajv/dist/compile/validate/dataType.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/defaults.d.ts +2 -0
- package/node_modules/ajv/dist/compile/validate/defaults.js +35 -0
- package/node_modules/ajv/dist/compile/validate/defaults.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/index.d.ts +42 -0
- package/node_modules/ajv/dist/compile/validate/index.js +520 -0
- package/node_modules/ajv/dist/compile/validate/index.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/keyword.d.ts +8 -0
- package/node_modules/ajv/dist/compile/validate/keyword.js +124 -0
- package/node_modules/ajv/dist/compile/validate/keyword.js.map +1 -0
- package/node_modules/ajv/dist/compile/validate/subschema.d.ts +47 -0
- package/node_modules/ajv/dist/compile/validate/subschema.js +81 -0
- package/node_modules/ajv/dist/compile/validate/subschema.js.map +1 -0
- package/node_modules/ajv/dist/core.d.ts +174 -0
- package/node_modules/ajv/dist/core.js +618 -0
- package/node_modules/ajv/dist/core.js.map +1 -0
- package/node_modules/ajv/dist/jtd.d.ts +47 -0
- package/node_modules/ajv/dist/jtd.js +72 -0
- package/node_modules/ajv/dist/jtd.js.map +1 -0
- package/node_modules/ajv/dist/refs/data.json +13 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/index.d.ts +2 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/index.js +28 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/index.js.map +1 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/applicator.json +53 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/content.json +17 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/core.json +57 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/format.json +14 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/meta-data.json +37 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/validation.json +90 -0
- package/node_modules/ajv/dist/refs/json-schema-2019-09/schema.json +39 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/index.d.ts +2 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/index.js +30 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/index.js.map +1 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.json +48 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.json +17 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.json +51 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.json +14 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.json +37 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.json +15 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json +90 -0
- package/node_modules/ajv/dist/refs/json-schema-2020-12/schema.json +55 -0
- package/node_modules/ajv/dist/refs/json-schema-draft-06.json +137 -0
- package/node_modules/ajv/dist/refs/json-schema-draft-07.json +151 -0
- package/node_modules/ajv/dist/refs/json-schema-secure.json +88 -0
- package/node_modules/ajv/dist/refs/jtd-schema.d.ts +3 -0
- package/node_modules/ajv/dist/refs/jtd-schema.js +118 -0
- package/node_modules/ajv/dist/refs/jtd-schema.js.map +1 -0
- package/node_modules/ajv/dist/runtime/equal.d.ts +6 -0
- package/node_modules/ajv/dist/runtime/equal.js +7 -0
- package/node_modules/ajv/dist/runtime/equal.js.map +1 -0
- package/node_modules/ajv/dist/runtime/parseJson.d.ts +18 -0
- package/node_modules/ajv/dist/runtime/parseJson.js +185 -0
- package/node_modules/ajv/dist/runtime/parseJson.js.map +1 -0
- package/node_modules/ajv/dist/runtime/quote.d.ts +5 -0
- package/node_modules/ajv/dist/runtime/quote.js +30 -0
- package/node_modules/ajv/dist/runtime/quote.js.map +1 -0
- package/node_modules/ajv/dist/runtime/re2.d.ts +6 -0
- package/node_modules/ajv/dist/runtime/re2.js +6 -0
- package/node_modules/ajv/dist/runtime/re2.js.map +1 -0
- package/node_modules/ajv/dist/runtime/timestamp.d.ts +5 -0
- package/node_modules/ajv/dist/runtime/timestamp.js +42 -0
- package/node_modules/ajv/dist/runtime/timestamp.js.map +1 -0
- package/node_modules/ajv/dist/runtime/ucs2length.d.ts +5 -0
- package/node_modules/ajv/dist/runtime/ucs2length.js +24 -0
- package/node_modules/ajv/dist/runtime/ucs2length.js.map +1 -0
- package/node_modules/ajv/dist/runtime/uri.d.ts +6 -0
- package/node_modules/ajv/dist/runtime/uri.js +6 -0
- package/node_modules/ajv/dist/runtime/uri.js.map +1 -0
- package/node_modules/ajv/dist/runtime/validation_error.d.ts +7 -0
- package/node_modules/ajv/dist/runtime/validation_error.js +11 -0
- package/node_modules/ajv/dist/runtime/validation_error.js.map +1 -0
- package/node_modules/ajv/dist/standalone/index.d.ts +6 -0
- package/node_modules/ajv/dist/standalone/index.js +90 -0
- package/node_modules/ajv/dist/standalone/index.js.map +1 -0
- package/node_modules/ajv/dist/standalone/instance.d.ts +12 -0
- package/node_modules/ajv/dist/standalone/instance.js +35 -0
- package/node_modules/ajv/dist/standalone/instance.js.map +1 -0
- package/node_modules/ajv/dist/types/index.d.ts +183 -0
- package/node_modules/ajv/dist/types/index.js +3 -0
- package/node_modules/ajv/dist/types/index.js.map +1 -0
- package/node_modules/ajv/dist/types/json-schema.d.ts +125 -0
- package/node_modules/ajv/dist/types/json-schema.js +3 -0
- package/node_modules/ajv/dist/types/json-schema.js.map +1 -0
- package/node_modules/ajv/dist/types/jtd-schema.d.ts +174 -0
- package/node_modules/ajv/dist/types/jtd-schema.js +3 -0
- package/node_modules/ajv/dist/types/jtd-schema.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/additionalItems.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +49 -0
- package/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +106 -0
- package/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/allOf.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/applicator/allOf.js +23 -0
- package/node_modules/ajv/dist/vocabularies/applicator/allOf.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/anyOf.d.ts +4 -0
- package/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +12 -0
- package/node_modules/ajv/dist/vocabularies/applicator/anyOf.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/contains.d.ts +7 -0
- package/node_modules/ajv/dist/vocabularies/applicator/contains.js +95 -0
- package/node_modules/ajv/dist/vocabularies/applicator/contains.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/dependencies.d.ts +21 -0
- package/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +85 -0
- package/node_modules/ajv/dist/vocabularies/applicator/dependencies.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js +11 -0
- package/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/if.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/applicator/if.js +66 -0
- package/node_modules/ajv/dist/vocabularies/applicator/if.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/index.d.ts +13 -0
- package/node_modules/ajv/dist/vocabularies/applicator/index.js +44 -0
- package/node_modules/ajv/dist/vocabularies/applicator/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/items.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/applicator/items.js +52 -0
- package/node_modules/ajv/dist/vocabularies/applicator/items.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/items2020.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/applicator/items2020.js +30 -0
- package/node_modules/ajv/dist/vocabularies/applicator/items2020.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/not.d.ts +4 -0
- package/node_modules/ajv/dist/vocabularies/applicator/not.js +26 -0
- package/node_modules/ajv/dist/vocabularies/applicator/not.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/oneOf.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +60 -0
- package/node_modules/ajv/dist/vocabularies/applicator/oneOf.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/patternProperties.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +75 -0
- package/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/prefixItems.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +12 -0
- package/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/properties.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/applicator/properties.js +54 -0
- package/node_modules/ajv/dist/vocabularies/applicator/properties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/propertyNames.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +38 -0
- package/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/applicator/thenElse.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +13 -0
- package/node_modules/ajv/dist/vocabularies/applicator/thenElse.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/code.d.ts +17 -0
- package/node_modules/ajv/dist/vocabularies/code.js +131 -0
- package/node_modules/ajv/dist/vocabularies/code.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/core/id.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/core/id.js +10 -0
- package/node_modules/ajv/dist/vocabularies/core/id.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/core/index.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/core/index.js +16 -0
- package/node_modules/ajv/dist/vocabularies/core/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/core/ref.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/core/ref.js +122 -0
- package/node_modules/ajv/dist/vocabularies/core/ref.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/discriminator/index.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/discriminator/index.js +104 -0
- package/node_modules/ajv/dist/vocabularies/discriminator/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/discriminator/types.d.ts +10 -0
- package/node_modules/ajv/dist/vocabularies/discriminator/types.js +9 -0
- package/node_modules/ajv/dist/vocabularies/discriminator/types.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/draft2020.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/draft2020.js +23 -0
- package/node_modules/ajv/dist/vocabularies/draft2020.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/draft7.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/draft7.js +17 -0
- package/node_modules/ajv/dist/vocabularies/draft7.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js +30 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js +51 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/index.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/index.js +9 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js +16 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js +10 -0
- package/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/errors.d.ts +9 -0
- package/node_modules/ajv/dist/vocabularies/errors.js +3 -0
- package/node_modules/ajv/dist/vocabularies/errors.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/format/format.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/format/format.js +92 -0
- package/node_modules/ajv/dist/vocabularies/format/format.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/format/index.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/format/index.js +6 -0
- package/node_modules/ajv/dist/vocabularies/format/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/discriminator.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/jtd/discriminator.js +71 -0
- package/node_modules/ajv/dist/vocabularies/jtd/discriminator.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/elements.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/jtd/elements.js +24 -0
- package/node_modules/ajv/dist/vocabularies/jtd/elements.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/enum.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/jtd/enum.js +43 -0
- package/node_modules/ajv/dist/vocabularies/jtd/enum.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/error.d.ts +9 -0
- package/node_modules/ajv/dist/vocabularies/jtd/error.js +20 -0
- package/node_modules/ajv/dist/vocabularies/jtd/error.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/index.d.ts +10 -0
- package/node_modules/ajv/dist/vocabularies/jtd/index.js +29 -0
- package/node_modules/ajv/dist/vocabularies/jtd/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/metadata.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/jtd/metadata.js +25 -0
- package/node_modules/ajv/dist/vocabularies/jtd/metadata.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/nullable.d.ts +4 -0
- package/node_modules/ajv/dist/vocabularies/jtd/nullable.js +22 -0
- package/node_modules/ajv/dist/vocabularies/jtd/nullable.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/optionalProperties.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/jtd/optionalProperties.js +15 -0
- package/node_modules/ajv/dist/vocabularies/jtd/optionalProperties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/properties.d.ts +22 -0
- package/node_modules/ajv/dist/vocabularies/jtd/properties.js +149 -0
- package/node_modules/ajv/dist/vocabularies/jtd/properties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/ref.d.ts +4 -0
- package/node_modules/ajv/dist/vocabularies/jtd/ref.js +67 -0
- package/node_modules/ajv/dist/vocabularies/jtd/ref.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/type.d.ts +10 -0
- package/node_modules/ajv/dist/vocabularies/jtd/type.js +69 -0
- package/node_modules/ajv/dist/vocabularies/jtd/type.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/union.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/jtd/union.js +12 -0
- package/node_modules/ajv/dist/vocabularies/jtd/union.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/jtd/values.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/jtd/values.js +51 -0
- package/node_modules/ajv/dist/vocabularies/jtd/values.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/metadata.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/metadata.js +18 -0
- package/node_modules/ajv/dist/vocabularies/metadata.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/next.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/next.js +8 -0
- package/node_modules/ajv/dist/vocabularies/next.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/index.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/index.js +7 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js +40 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js +65 -0
- package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/const.d.ts +6 -0
- package/node_modules/ajv/dist/vocabularies/validation/const.js +25 -0
- package/node_modules/ajv/dist/vocabularies/validation/const.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/dependentRequired.d.ts +5 -0
- package/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js +12 -0
- package/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/enum.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/validation/enum.js +48 -0
- package/node_modules/ajv/dist/vocabularies/validation/enum.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/index.d.ts +16 -0
- package/node_modules/ajv/dist/vocabularies/validation/index.js +33 -0
- package/node_modules/ajv/dist/vocabularies/validation/index.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitContains.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitContains.js +15 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitContains.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitItems.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitItems.js +24 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitItems.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitLength.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitLength.js +27 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitLength.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitNumber.d.ts +11 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +27 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitNumber.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitProperties.d.ts +3 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +24 -0
- package/node_modules/ajv/dist/vocabularies/validation/limitProperties.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/multipleOf.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +26 -0
- package/node_modules/ajv/dist/vocabularies/validation/multipleOf.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/pattern.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/validation/pattern.js +33 -0
- package/node_modules/ajv/dist/vocabularies/validation/pattern.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/required.d.ts +8 -0
- package/node_modules/ajv/dist/vocabularies/validation/required.js +79 -0
- package/node_modules/ajv/dist/vocabularies/validation/required.js.map +1 -0
- package/node_modules/ajv/dist/vocabularies/validation/uniqueItems.d.ts +9 -0
- package/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +64 -0
- package/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js.map +1 -0
- package/node_modules/ajv/lib/2019.ts +81 -0
- package/node_modules/ajv/lib/2020.ts +75 -0
- package/node_modules/ajv/lib/ajv.ts +70 -0
- package/node_modules/ajv/lib/compile/codegen/code.ts +169 -0
- package/node_modules/ajv/lib/compile/codegen/index.ts +852 -0
- package/node_modules/ajv/lib/compile/codegen/scope.ts +215 -0
- package/node_modules/ajv/lib/compile/errors.ts +184 -0
- package/node_modules/ajv/lib/compile/index.ts +324 -0
- package/node_modules/ajv/lib/compile/jtd/parse.ts +411 -0
- package/node_modules/ajv/lib/compile/jtd/serialize.ts +277 -0
- package/node_modules/ajv/lib/compile/jtd/types.ts +16 -0
- package/node_modules/ajv/lib/compile/names.ts +27 -0
- package/node_modules/ajv/lib/compile/ref_error.ts +13 -0
- package/node_modules/ajv/lib/compile/resolve.ts +149 -0
- package/node_modules/ajv/lib/compile/rules.ts +50 -0
- package/node_modules/ajv/lib/compile/util.ts +213 -0
- package/node_modules/ajv/lib/compile/validate/applicability.ts +22 -0
- package/node_modules/ajv/lib/compile/validate/boolSchema.ts +47 -0
- package/node_modules/ajv/lib/compile/validate/dataType.ts +230 -0
- package/node_modules/ajv/lib/compile/validate/defaults.ts +32 -0
- package/node_modules/ajv/lib/compile/validate/index.ts +582 -0
- package/node_modules/ajv/lib/compile/validate/keyword.ts +171 -0
- package/node_modules/ajv/lib/compile/validate/subschema.ts +135 -0
- package/node_modules/ajv/lib/core.ts +892 -0
- package/node_modules/ajv/lib/jtd.ts +132 -0
- package/node_modules/ajv/lib/refs/data.json +13 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts +28 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json +53 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json +17 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json +57 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json +14 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json +37 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json +90 -0
- package/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json +39 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts +30 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json +48 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json +17 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json +51 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json +14 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json +37 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json +15 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json +90 -0
- package/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json +55 -0
- package/node_modules/ajv/lib/refs/json-schema-draft-06.json +137 -0
- package/node_modules/ajv/lib/refs/json-schema-draft-07.json +151 -0
- package/node_modules/ajv/lib/refs/json-schema-secure.json +88 -0
- package/node_modules/ajv/lib/refs/jtd-schema.ts +130 -0
- package/node_modules/ajv/lib/runtime/equal.ts +7 -0
- package/node_modules/ajv/lib/runtime/parseJson.ts +177 -0
- package/node_modules/ajv/lib/runtime/quote.ts +31 -0
- package/node_modules/ajv/lib/runtime/re2.ts +6 -0
- package/node_modules/ajv/lib/runtime/timestamp.ts +46 -0
- package/node_modules/ajv/lib/runtime/ucs2length.ts +20 -0
- package/node_modules/ajv/lib/runtime/uri.ts +6 -0
- package/node_modules/ajv/lib/runtime/validation_error.ts +13 -0
- package/node_modules/ajv/lib/standalone/index.ts +100 -0
- package/node_modules/ajv/lib/standalone/instance.ts +36 -0
- package/node_modules/ajv/lib/types/index.ts +244 -0
- package/node_modules/ajv/lib/types/json-schema.ts +187 -0
- package/node_modules/ajv/lib/types/jtd-schema.ts +273 -0
- package/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts +56 -0
- package/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts +118 -0
- package/node_modules/ajv/lib/vocabularies/applicator/allOf.ts +22 -0
- package/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts +14 -0
- package/node_modules/ajv/lib/vocabularies/applicator/contains.ts +109 -0
- package/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts +112 -0
- package/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts +11 -0
- package/node_modules/ajv/lib/vocabularies/applicator/if.ts +80 -0
- package/node_modules/ajv/lib/vocabularies/applicator/index.ts +53 -0
- package/node_modules/ajv/lib/vocabularies/applicator/items.ts +59 -0
- package/node_modules/ajv/lib/vocabularies/applicator/items2020.ts +36 -0
- package/node_modules/ajv/lib/vocabularies/applicator/not.ts +38 -0
- package/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts +82 -0
- package/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts +91 -0
- package/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts +12 -0
- package/node_modules/ajv/lib/vocabularies/applicator/properties.ts +57 -0
- package/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts +50 -0
- package/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts +13 -0
- package/node_modules/ajv/lib/vocabularies/code.ts +168 -0
- package/node_modules/ajv/lib/vocabularies/core/id.ts +10 -0
- package/node_modules/ajv/lib/vocabularies/core/index.ts +16 -0
- package/node_modules/ajv/lib/vocabularies/core/ref.ts +129 -0
- package/node_modules/ajv/lib/vocabularies/discriminator/index.ts +113 -0
- package/node_modules/ajv/lib/vocabularies/discriminator/types.ts +12 -0
- package/node_modules/ajv/lib/vocabularies/draft2020.ts +23 -0
- package/node_modules/ajv/lib/vocabularies/draft7.ts +17 -0
- package/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts +31 -0
- package/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts +51 -0
- package/node_modules/ajv/lib/vocabularies/dynamic/index.ts +9 -0
- package/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts +14 -0
- package/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts +10 -0
- package/node_modules/ajv/lib/vocabularies/errors.ts +18 -0
- package/node_modules/ajv/lib/vocabularies/format/format.ts +120 -0
- package/node_modules/ajv/lib/vocabularies/format/index.ts +6 -0
- package/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts +89 -0
- package/node_modules/ajv/lib/vocabularies/jtd/elements.ts +32 -0
- package/node_modules/ajv/lib/vocabularies/jtd/enum.ts +45 -0
- package/node_modules/ajv/lib/vocabularies/jtd/error.ts +23 -0
- package/node_modules/ajv/lib/vocabularies/jtd/index.ts +37 -0
- package/node_modules/ajv/lib/vocabularies/jtd/metadata.ts +24 -0
- package/node_modules/ajv/lib/vocabularies/jtd/nullable.ts +21 -0
- package/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts +15 -0
- package/node_modules/ajv/lib/vocabularies/jtd/properties.ts +184 -0
- package/node_modules/ajv/lib/vocabularies/jtd/ref.ts +76 -0
- package/node_modules/ajv/lib/vocabularies/jtd/type.ts +75 -0
- package/node_modules/ajv/lib/vocabularies/jtd/union.ts +12 -0
- package/node_modules/ajv/lib/vocabularies/jtd/values.ts +58 -0
- package/node_modules/ajv/lib/vocabularies/metadata.ts +17 -0
- package/node_modules/ajv/lib/vocabularies/next.ts +8 -0
- package/node_modules/ajv/lib/vocabularies/unevaluated/index.ts +7 -0
- package/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts +47 -0
- package/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts +85 -0
- package/node_modules/ajv/lib/vocabularies/validation/const.ts +28 -0
- package/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts +23 -0
- package/node_modules/ajv/lib/vocabularies/validation/enum.ts +54 -0
- package/node_modules/ajv/lib/vocabularies/validation/index.ts +49 -0
- package/node_modules/ajv/lib/vocabularies/validation/limitContains.ts +16 -0
- package/node_modules/ajv/lib/vocabularies/validation/limitItems.ts +26 -0
- package/node_modules/ajv/lib/vocabularies/validation/limitLength.ts +30 -0
- package/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts +42 -0
- package/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts +26 -0
- package/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts +34 -0
- package/node_modules/ajv/lib/vocabularies/validation/pattern.ts +39 -0
- package/node_modules/ajv/lib/vocabularies/validation/required.ts +98 -0
- package/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts +79 -0
- package/node_modules/ajv/package.json +126 -0
- package/node_modules/ajv-formats/LICENSE +21 -0
- package/node_modules/ajv-formats/README.md +125 -0
- package/node_modules/ajv-formats/dist/formats.d.ts +9 -0
- package/node_modules/ajv-formats/dist/formats.js +208 -0
- package/node_modules/ajv-formats/dist/formats.js.map +1 -0
- package/node_modules/ajv-formats/dist/index.d.ts +15 -0
- package/node_modules/ajv-formats/dist/index.js +37 -0
- package/node_modules/ajv-formats/dist/index.js.map +1 -0
- package/node_modules/ajv-formats/dist/limit.d.ts +10 -0
- package/node_modules/ajv-formats/dist/limit.js +69 -0
- package/node_modules/ajv-formats/dist/limit.js.map +1 -0
- package/node_modules/ajv-formats/package.json +74 -0
- package/node_modules/ajv-formats/src/formats.ts +269 -0
- package/node_modules/ajv-formats/src/index.ts +62 -0
- package/node_modules/ajv-formats/src/limit.ts +99 -0
- package/node_modules/fast-deep-equal/LICENSE +21 -0
- package/node_modules/fast-deep-equal/README.md +96 -0
- package/node_modules/fast-deep-equal/es6/index.d.ts +2 -0
- package/node_modules/fast-deep-equal/es6/index.js +72 -0
- package/node_modules/fast-deep-equal/es6/react.d.ts +2 -0
- package/node_modules/fast-deep-equal/es6/react.js +79 -0
- package/node_modules/fast-deep-equal/index.d.ts +4 -0
- package/node_modules/fast-deep-equal/index.js +46 -0
- package/node_modules/fast-deep-equal/package.json +61 -0
- package/node_modules/fast-deep-equal/react.d.ts +2 -0
- package/node_modules/fast-deep-equal/react.js +53 -0
- package/node_modules/fast-uri/.gitattributes +2 -0
- package/node_modules/fast-uri/.github/dependabot.yml +13 -0
- package/node_modules/fast-uri/.github/workflows/ci.yml +106 -0
- package/node_modules/fast-uri/.github/workflows/lock-threads.yml +19 -0
- package/node_modules/fast-uri/.github/workflows/package-manager-ci.yml +24 -0
- package/node_modules/fast-uri/LICENSE +30 -0
- package/node_modules/fast-uri/README.md +152 -0
- package/node_modules/fast-uri/benchmark/benchmark.mjs +159 -0
- package/node_modules/fast-uri/benchmark/equal.mjs +51 -0
- package/node_modules/fast-uri/benchmark/non-simple-domain.mjs +22 -0
- package/node_modules/fast-uri/benchmark/package.json +17 -0
- package/node_modules/fast-uri/benchmark/string-array-to-hex-stripped.mjs +24 -0
- package/node_modules/fast-uri/benchmark/ws-is-secure.mjs +65 -0
- package/node_modules/fast-uri/eslint.config.js +6 -0
- package/node_modules/fast-uri/index.js +631 -0
- package/node_modules/fast-uri/lib/schemes.js +272 -0
- package/node_modules/fast-uri/lib/utils.js +747 -0
- package/node_modules/fast-uri/package.json +68 -0
- package/node_modules/fast-uri/test/ajv.test.js +43 -0
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +163 -0
- package/node_modules/fast-uri/test/equal.test.js +145 -0
- package/node_modules/fast-uri/test/fixtures/uri-js-parse.json +503 -0
- package/node_modules/fast-uri/test/fixtures/uri-js-serialize.json +120 -0
- package/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +124 -0
- package/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
- package/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
- package/node_modules/fast-uri/test/parse.test.js +327 -0
- package/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
- package/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
- package/node_modules/fast-uri/test/resolve.test.js +87 -0
- package/node_modules/fast-uri/test/rfc-3986.test.js +90 -0
- package/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
- package/node_modules/fast-uri/test/security-normalization.test.js +178 -0
- package/node_modules/fast-uri/test/security.test.js +431 -0
- package/node_modules/fast-uri/test/serialize.test.js +151 -0
- package/node_modules/fast-uri/test/uri-js-compatibility.test.js +33 -0
- package/node_modules/fast-uri/test/uri-js.test.js +912 -0
- package/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
- package/node_modules/fast-uri/test/util.test.js +38 -0
- package/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
- package/node_modules/fast-uri/tsconfig.json +9 -0
- package/node_modules/fast-uri/types/index.d.ts +60 -0
- package/node_modules/fast-uri/types/index.test-d.ts +17 -0
- package/node_modules/json-schema-traverse/.eslintrc.yml +27 -0
- package/node_modules/json-schema-traverse/.github/FUNDING.yml +2 -0
- package/node_modules/json-schema-traverse/.github/workflows/build.yml +28 -0
- package/node_modules/json-schema-traverse/.github/workflows/publish.yml +27 -0
- package/node_modules/json-schema-traverse/LICENSE +21 -0
- package/node_modules/json-schema-traverse/README.md +95 -0
- package/node_modules/json-schema-traverse/index.d.ts +40 -0
- package/node_modules/json-schema-traverse/index.js +93 -0
- package/node_modules/json-schema-traverse/package.json +43 -0
- package/node_modules/json-schema-traverse/spec/.eslintrc.yml +6 -0
- package/node_modules/json-schema-traverse/spec/fixtures/schema.js +125 -0
- package/node_modules/json-schema-traverse/spec/index.spec.js +171 -0
- package/node_modules/require-from-string/index.js +34 -0
- package/node_modules/require-from-string/license +21 -0
- package/node_modules/require-from-string/package.json +28 -0
- package/node_modules/require-from-string/readme.md +56 -0
- package/package.json +49 -2
- package/packages/cli/dist/agent-spans.d.ts +238 -0
- package/packages/cli/dist/agent-spans.d.ts.map +1 -0
- package/packages/cli/dist/agent-spans.js +677 -0
- package/packages/cli/dist/agent-spans.js.map +1 -0
- package/packages/cli/dist/api.d.ts +127 -0
- package/packages/cli/dist/api.d.ts.map +1 -0
- package/packages/cli/dist/api.js +159 -0
- package/packages/cli/dist/api.js.map +1 -0
- package/packages/cli/dist/archive.d.ts +24 -0
- package/packages/cli/dist/archive.d.ts.map +1 -0
- package/packages/cli/dist/archive.js +230 -0
- package/packages/cli/dist/archive.js.map +1 -0
- package/packages/cli/dist/args.d.ts +57 -0
- package/packages/cli/dist/args.d.ts.map +1 -0
- package/packages/cli/dist/args.js +180 -0
- package/packages/cli/dist/args.js.map +1 -0
- package/packages/cli/dist/attach.d.ts +48 -0
- package/packages/cli/dist/attach.d.ts.map +1 -0
- package/packages/cli/dist/attach.js +153 -0
- package/packages/cli/dist/attach.js.map +1 -0
- package/packages/cli/dist/capture-limits.d.ts +7 -0
- package/packages/cli/dist/capture-limits.d.ts.map +1 -0
- package/packages/cli/dist/capture-limits.js +13 -0
- package/packages/cli/dist/capture-limits.js.map +1 -0
- package/packages/cli/dist/cli.d.ts +3 -0
- package/packages/cli/dist/cli.d.ts.map +1 -0
- package/packages/cli/dist/cli.js +4 -0
- package/packages/cli/dist/cli.js.map +1 -0
- package/packages/cli/dist/commands/attach.d.ts +49 -0
- package/packages/cli/dist/commands/attach.d.ts.map +1 -0
- package/packages/cli/dist/commands/attach.js +350 -0
- package/packages/cli/dist/commands/attach.js.map +1 -0
- package/packages/cli/dist/commands/compare.d.ts +27 -0
- package/packages/cli/dist/commands/compare.d.ts.map +1 -0
- package/packages/cli/dist/commands/compare.js +187 -0
- package/packages/cli/dist/commands/compare.js.map +1 -0
- package/packages/cli/dist/commands/doctor.d.ts +24 -0
- package/packages/cli/dist/commands/doctor.d.ts.map +1 -0
- package/packages/cli/dist/commands/doctor.js +402 -0
- package/packages/cli/dist/commands/doctor.js.map +1 -0
- package/packages/cli/dist/commands/gc.d.ts +24 -0
- package/packages/cli/dist/commands/gc.d.ts.map +1 -0
- package/packages/cli/dist/commands/gc.js +326 -0
- package/packages/cli/dist/commands/gc.js.map +1 -0
- package/packages/cli/dist/commands/inspect.d.ts +45 -0
- package/packages/cli/dist/commands/inspect.d.ts.map +1 -0
- package/packages/cli/dist/commands/inspect.js +375 -0
- package/packages/cli/dist/commands/inspect.js.map +1 -0
- package/packages/cli/dist/commands/quickstart.d.ts +48 -0
- package/packages/cli/dist/commands/quickstart.d.ts.map +1 -0
- package/packages/cli/dist/commands/quickstart.js +413 -0
- package/packages/cli/dist/commands/quickstart.js.map +1 -0
- package/packages/cli/dist/commands/record.d.ts +31 -0
- package/packages/cli/dist/commands/record.d.ts.map +1 -0
- package/packages/cli/dist/commands/record.js +958 -0
- package/packages/cli/dist/commands/record.js.map +1 -0
- package/packages/cli/dist/commands/replay.d.ts +184 -0
- package/packages/cli/dist/commands/replay.d.ts.map +1 -0
- package/packages/cli/dist/commands/replay.js +2014 -0
- package/packages/cli/dist/commands/replay.js.map +1 -0
- package/packages/cli/dist/commands/scrub.d.ts +34 -0
- package/packages/cli/dist/commands/scrub.d.ts.map +1 -0
- package/packages/cli/dist/commands/scrub.js +765 -0
- package/packages/cli/dist/commands/scrub.js.map +1 -0
- package/packages/cli/dist/commands/setup.d.ts +23 -0
- package/packages/cli/dist/commands/setup.d.ts.map +1 -0
- package/packages/cli/dist/commands/setup.js +239 -0
- package/packages/cli/dist/commands/setup.js.map +1 -0
- package/packages/cli/dist/commands/sync.d.ts +236 -0
- package/packages/cli/dist/commands/sync.d.ts.map +1 -0
- package/packages/cli/dist/commands/sync.js +1270 -0
- package/packages/cli/dist/commands/sync.js.map +1 -0
- package/packages/cli/dist/config.d.ts +69 -0
- package/packages/cli/dist/config.d.ts.map +1 -0
- package/packages/cli/dist/config.js +144 -0
- package/packages/cli/dist/config.js.map +1 -0
- package/packages/cli/dist/exchange-events.d.ts +80 -0
- package/packages/cli/dist/exchange-events.d.ts.map +1 -0
- package/packages/cli/dist/exchange-events.js +296 -0
- package/packages/cli/dist/exchange-events.js.map +1 -0
- package/packages/cli/dist/flags.d.ts +41 -0
- package/packages/cli/dist/flags.d.ts.map +1 -0
- package/packages/cli/dist/flags.js +292 -0
- package/packages/cli/dist/flags.js.map +1 -0
- package/packages/cli/dist/fs-events.d.ts +19 -0
- package/packages/cli/dist/fs-events.d.ts.map +1 -0
- package/packages/cli/dist/fs-events.js +89 -0
- package/packages/cli/dist/fs-events.js.map +1 -0
- package/packages/cli/dist/index.d.ts +18 -0
- package/packages/cli/dist/index.d.ts.map +1 -0
- package/packages/cli/dist/index.js +18 -0
- package/packages/cli/dist/index.js.map +1 -0
- package/packages/cli/dist/main.d.ts +2 -0
- package/packages/cli/dist/main.d.ts.map +1 -0
- package/packages/cli/dist/main.js +404 -0
- package/packages/cli/dist/main.js.map +1 -0
- package/packages/cli/dist/mcp-server.d.ts +44 -0
- package/packages/cli/dist/mcp-server.d.ts.map +1 -0
- package/packages/cli/dist/mcp-server.js +250 -0
- package/packages/cli/dist/mcp-server.js.map +1 -0
- package/packages/cli/dist/mcp.d.ts +126 -0
- package/packages/cli/dist/mcp.d.ts.map +1 -0
- package/packages/cli/dist/mcp.js +290 -0
- package/packages/cli/dist/mcp.js.map +1 -0
- package/packages/cli/dist/out.d.ts +107 -0
- package/packages/cli/dist/out.d.ts.map +1 -0
- package/packages/cli/dist/out.js +280 -0
- package/packages/cli/dist/out.js.map +1 -0
- package/packages/cli/dist/rasterize.d.ts +62 -0
- package/packages/cli/dist/rasterize.d.ts.map +1 -0
- package/packages/cli/dist/rasterize.js +154 -0
- package/packages/cli/dist/rasterize.js.map +1 -0
- package/packages/cli/dist/serial.d.ts +19 -0
- package/packages/cli/dist/serial.d.ts.map +1 -0
- package/packages/cli/dist/serial.js +34 -0
- package/packages/cli/dist/serial.js.map +1 -0
- package/packages/cli/dist/share-card.d.ts +73 -0
- package/packages/cli/dist/share-card.d.ts.map +1 -0
- package/packages/cli/dist/share-card.js +413 -0
- package/packages/cli/dist/share-card.js.map +1 -0
- package/packages/cli/dist/snapshot.d.ts +39 -0
- package/packages/cli/dist/snapshot.d.ts.map +1 -0
- package/packages/cli/dist/snapshot.js +43 -0
- package/packages/cli/dist/snapshot.js.map +1 -0
- package/packages/cli/dist/tls-capture.d.ts +135 -0
- package/packages/cli/dist/tls-capture.d.ts.map +1 -0
- package/packages/cli/dist/tls-capture.js +586 -0
- package/packages/cli/dist/tls-capture.js.map +1 -0
- package/packages/cli/dist/upstream.d.ts +29 -0
- package/packages/cli/dist/upstream.d.ts.map +1 -0
- package/packages/cli/dist/upstream.js +41 -0
- package/packages/cli/dist/upstream.js.map +1 -0
- package/packages/cli/dist/version.d.ts +2 -0
- package/packages/cli/dist/version.d.ts.map +1 -0
- package/packages/cli/dist/version.js +18 -0
- package/packages/cli/dist/version.js.map +1 -0
- package/packages/cli/package.json +11 -11
- package/.dockerignore +0 -11
- package/.gitattributes +0 -19
- package/.github/workflows/ci.yml +0 -146
- package/.grok-plugin/plugin.json +0 -12
- package/.mcp.json +0 -8
- package/.prettierignore +0 -4
- package/.prettierrc.json +0 -1
- package/CONTRIBUTING.md +0 -106
- package/Dockerfile +0 -30
- package/MAINTAINERS.md +0 -24
- package/RELEASING.md +0 -183
- package/SECURITY.md +0 -149
- package/capture/CAPTURE-RUNBOOK.md +0 -271
- package/capture/CURSOR-HTTP2.md +0 -226
- package/capture/README.md +0 -349
- package/capture/capture-run.gif +0 -0
- package/capture/capture.mjs +0 -1883
- package/capture/fable-capture.gif +0 -0
- package/capture/fable-capture.mp4 +0 -0
- package/capture/muse-shim.mjs +0 -114
- package/capture/render-run.mjs +0 -125
- package/capture/render.mjs +0 -228
- package/companion-kiokuko-dsh.patch +0 -7806
- package/docs/agenticreplay-acceptance.md +0 -135
- package/docs/architecture.md +0 -160
- package/docs/chain-card.png +0 -0
- package/docs/compare-card.png +0 -0
- package/docs/demo-cli.gif +0 -0
- package/docs/demo-viewer.gif +0 -0
- package/docs/fidelity.md +0 -16
- package/docs/good-first-issues.md +0 -78
- package/docs/graph-card.png +0 -0
- package/docs/how-to/compare-models-on-the-same-failure.md +0 -58
- package/docs/how-to/debug-a-failing-agent-run.md +0 -127
- package/docs/how-to/why-did-my-agent-delete-my-file.md +0 -92
- package/docs/i18n/README.ar.md +0 -597
- package/docs/i18n/README.de.md +0 -648
- package/docs/i18n/README.es.md +0 -642
- package/docs/i18n/README.fr.md +0 -649
- package/docs/i18n/README.ja.md +0 -608
- package/docs/i18n/README.ko.md +0 -598
- package/docs/i18n/README.zh-CN.md +0 -574
- package/docs/integrations.md +0 -628
- package/docs/launch-path.md +0 -215
- package/docs/media/README.md +0 -101
- package/docs/media/sync-transcript.txt +0 -18
- package/docs/media/transcript.txt +0 -29
- package/docs/opencode-capture.md +0 -137
- package/docs/plugins.md +0 -250
- package/docs/proposals/action-graph-and-reasoning.md +0 -354
- package/docs/sync-card.png +0 -0
- package/docs/validation.md +0 -52
- package/docs/viewer-timeline.png +0 -0
- package/examples/traces/README.md +0 -50
- package/examples/traces/run_9f2c14a03b71/blobs/1b/1b694f32b8c582ace6b35ad64050e532fb3ee3ecc1a2763a82cf42ad0f2a3dd0 +0 -10
- package/examples/traces/run_9f2c14a03b71/blobs/51/517b5b8ec6c3b13121dbaec61784e2a024247c7c4efd9ba068b582ee57bd2764 +0 -4
- package/examples/traces/run_9f2c14a03b71/blobs/5b/5bba1bd069013d86363f69c00c1ae77c84c4e113aeeb7431c8141af4fed76860 +0 -7
- package/examples/traces/run_9f2c14a03b71/blobs/84/84247e7b385fd5f99a6728a509838e52ef963af92f44ef6eccbed6910de1438d +0 -10
- package/examples/traces/run_9f2c14a03b71/blobs/ac/ac9b4be9bdf7fe63c7b5135e2d14c4c0745a48771e733804869790590455f8e8 +0 -7
- package/examples/traces/run_9f2c14a03b71/events.jsonl +0 -31
- package/examples/traces/run_9f2c14a03b71/manifest.json +0 -46
- package/examples/traces/run_9f2c14a03b71/redactions.json +0 -17
- package/llms.txt +0 -26
- package/packages/adapters/fixtures/harness/claude-code.json +0 -12
- package/packages/adapters/fixtures/harness/codex.json +0 -10
- package/packages/adapters/fixtures/harness/cursor.json +0 -10
- package/packages/adapters/fixtures/harness/exec.json +0 -10
- package/packages/adapters/fixtures/harness/generic-openai.json +0 -14
- package/packages/adapters/fixtures/harness/goose.json +0 -14
- package/packages/adapters/fixtures/harness/grok.json +0 -18
- package/packages/adapters/fixtures/harness/hermes.json +0 -10
- package/packages/adapters/fixtures/harness/indexrag.json +0 -21
- package/packages/adapters/fixtures/harness/kilo.json +0 -10
- package/packages/adapters/fixtures/harness/mcode.json +0 -10
- package/packages/adapters/fixtures/harness/mimo.json +0 -10
- package/packages/adapters/fixtures/harness/node.json +0 -22
- package/packages/adapters/fixtures/harness/openclaw.json +0 -21
- package/packages/adapters/fixtures/harness/opencode.json +0 -20
- package/packages/adapters/fixtures/harness/qwen.json +0 -20
- package/packages/adapters/fixtures/harness/zcode.json +0 -10
- package/packages/adapters/package.json +0 -29
- package/packages/adapters/src/claude-code.ts +0 -109
- package/packages/adapters/src/codex.ts +0 -135
- package/packages/adapters/src/contract.ts +0 -531
- package/packages/adapters/src/cursor.ts +0 -76
- package/packages/adapters/src/detect.ts +0 -132
- package/packages/adapters/src/env.ts +0 -118
- package/packages/adapters/src/exec.ts +0 -59
- package/packages/adapters/src/generic-openai.ts +0 -36
- package/packages/adapters/src/goose.ts +0 -87
- package/packages/adapters/src/grok.ts +0 -60
- package/packages/adapters/src/hermes.ts +0 -92
- package/packages/adapters/src/index.ts +0 -24
- package/packages/adapters/src/indexrag.ts +0 -254
- package/packages/adapters/src/kilo.ts +0 -39
- package/packages/adapters/src/mcode.ts +0 -392
- package/packages/adapters/src/mcp-config.ts +0 -84
- package/packages/adapters/src/mimo.ts +0 -44
- package/packages/adapters/src/node.ts +0 -71
- package/packages/adapters/src/openclaw.ts +0 -50
- package/packages/adapters/src/opencode-api-bases.ts +0 -200
- package/packages/adapters/src/opencode-capture.ts +0 -164
- package/packages/adapters/src/opencode-catalog.ts +0 -44
- package/packages/adapters/src/opencode-config.ts +0 -209
- package/packages/adapters/src/opencode.ts +0 -257
- package/packages/adapters/src/qwen.ts +0 -113
- package/packages/adapters/src/registry.ts +0 -121
- package/packages/adapters/src/scaffold.ts +0 -173
- package/packages/adapters/src/session.ts +0 -138
- package/packages/adapters/src/zcode.ts +0 -440
- package/packages/adapters/test/adapters.test.ts +0 -666
- package/packages/adapters/test/contract.test.ts +0 -601
- package/packages/adapters/test/exec-adapter.test.ts +0 -114
- package/packages/adapters/test/harness-versions.test.ts +0 -220
- package/packages/adapters/test/indexrag.test.ts +0 -192
- package/packages/adapters/test/mcode.test.ts +0 -678
- package/packages/adapters/test/mcp-config.test.ts +0 -118
- package/packages/adapters/test/named-agents.test.ts +0 -262
- package/packages/adapters/test/node-adapter.test.ts +0 -98
- package/packages/adapters/test/opencode-capture.test.ts +0 -137
- package/packages/adapters/test/opencode-catalog.test.ts +0 -178
- package/packages/adapters/test/opencode-config.test.ts +0 -63
- package/packages/adapters/test/scaffold.test.ts +0 -156
- package/packages/adapters/test/session.test.ts +0 -368
- package/packages/adapters/test/zcode.test.ts +0 -497
- package/packages/adapters/tsconfig.json +0 -16
- package/packages/cli/README.md +0 -92
- package/packages/cli/src/agent-spans.ts +0 -752
- package/packages/cli/src/api.ts +0 -275
- package/packages/cli/src/archive.ts +0 -264
- package/packages/cli/src/args.ts +0 -207
- package/packages/cli/src/attach.ts +0 -178
- package/packages/cli/src/capture-limits.ts +0 -21
- package/packages/cli/src/cli.ts +0 -4
- package/packages/cli/src/commands/attach.ts +0 -441
- package/packages/cli/src/commands/compare.ts +0 -218
- package/packages/cli/src/commands/doctor.ts +0 -447
- package/packages/cli/src/commands/gc.ts +0 -372
- package/packages/cli/src/commands/inspect.ts +0 -482
- package/packages/cli/src/commands/quickstart.ts +0 -479
- package/packages/cli/src/commands/record.ts +0 -1069
- package/packages/cli/src/commands/replay.ts +0 -2289
- package/packages/cli/src/commands/scrub.ts +0 -865
- package/packages/cli/src/commands/setup.ts +0 -294
- package/packages/cli/src/commands/sync.ts +0 -1429
- package/packages/cli/src/config.ts +0 -182
- package/packages/cli/src/exchange-events.ts +0 -369
- package/packages/cli/src/flags.ts +0 -316
- package/packages/cli/src/fs-events.ts +0 -103
- package/packages/cli/src/index.ts +0 -17
- package/packages/cli/src/main.ts +0 -419
- package/packages/cli/src/mcp-server.ts +0 -314
- package/packages/cli/src/mcp.ts +0 -350
- package/packages/cli/src/out.ts +0 -350
- package/packages/cli/src/rasterize.ts +0 -205
- package/packages/cli/src/serial.ts +0 -38
- package/packages/cli/src/share-card.ts +0 -514
- package/packages/cli/src/snapshot.ts +0 -80
- package/packages/cli/src/tls-capture.ts +0 -688
- package/packages/cli/src/upstream.ts +0 -75
- package/packages/cli/src/version.ts +0 -21
- package/packages/cli/test/agent-spans-drain.test.ts +0 -157
- package/packages/cli/test/agent-spans-race.test.ts +0 -97
- package/packages/cli/test/agent-spans.test.ts +0 -1032
- package/packages/cli/test/api.test.ts +0 -178
- package/packages/cli/test/archive.test.ts +0 -143
- package/packages/cli/test/args.test.ts +0 -164
- package/packages/cli/test/attach-command.test.ts +0 -356
- package/packages/cli/test/attach.test.ts +0 -198
- package/packages/cli/test/capture-oracle.test.ts +0 -160
- package/packages/cli/test/capture-warning.test.ts +0 -215
- package/packages/cli/test/chain-card.test.ts +0 -190
- package/packages/cli/test/claude-capture.test.ts +0 -242
- package/packages/cli/test/compare.test.ts +0 -329
- package/packages/cli/test/config-permission-failure.test.ts +0 -41
- package/packages/cli/test/config.test.ts +0 -239
- package/packages/cli/test/declared-inside-replay.test.ts +0 -170
- package/packages/cli/test/doctor.test.ts +0 -276
- package/packages/cli/test/e2e.test.ts +0 -1230
- package/packages/cli/test/exchange-events.test.ts +0 -345
- package/packages/cli/test/failure-lines.test.ts +0 -47
- package/packages/cli/test/fixtures/deaf-agent.mjs +0 -11
- package/packages/cli/test/fixtures/embedding-agent.mjs +0 -32
- package/packages/cli/test/fixtures/fake-agent.mjs +0 -114
- package/packages/cli/test/fixtures/fake-model.mjs +0 -105
- package/packages/cli/test/fixtures/gateway-agent.mjs +0 -20
- package/packages/cli/test/fixtures/ide-parent.mjs +0 -34
- package/packages/cli/test/fixtures/mcp-agent.mjs +0 -64
- package/packages/cli/test/fixtures/proxy-call.mjs +0 -105
- package/packages/cli/test/fixtures/responses-agent.mjs +0 -82
- package/packages/cli/test/fixtures/responses-model.mjs +0 -94
- package/packages/cli/test/fixtures/tls-agent.mjs +0 -35
- package/packages/cli/test/fixtures/vercel-agent.mjs +0 -81
- package/packages/cli/test/flag-values.test.ts +0 -162
- package/packages/cli/test/flags.test.ts +0 -313
- package/packages/cli/test/fork-provenance.test.ts +0 -224
- package/packages/cli/test/fork-tls.test.ts +0 -190
- package/packages/cli/test/gateway-e2e.test.ts +0 -110
- package/packages/cli/test/gc.test.ts +0 -531
- package/packages/cli/test/generated-esm.test.ts +0 -87
- package/packages/cli/test/graph-card.test.ts +0 -249
- package/packages/cli/test/graph-command.test.ts +0 -258
- package/packages/cli/test/grok-bot-e2e.test.ts +0 -349
- package/packages/cli/test/inspect.test.ts +0 -412
- package/packages/cli/test/intercept-failures.test.ts +0 -74
- package/packages/cli/test/json-only.test.ts +0 -88
- package/packages/cli/test/json-output.test.ts +0 -221
- package/packages/cli/test/list-gateway.test.ts +0 -770
- package/packages/cli/test/mcp-capture.test.ts +0 -498
- package/packages/cli/test/mcp-server.test.ts +0 -315
- package/packages/cli/test/nested-repo-replay.test.ts +0 -972
- package/packages/cli/test/no-credential-in-attrs.test.ts +0 -255
- package/packages/cli/test/opencode-capture.test.ts +0 -422
- package/packages/cli/test/opencode-catalog-capture.test.ts +0 -175
- package/packages/cli/test/out.test.ts +0 -491
- package/packages/cli/test/pinned-fetch.test.ts +0 -154
- package/packages/cli/test/prompt-scrub.test.ts +0 -132
- package/packages/cli/test/publish-order.test.ts +0 -87
- package/packages/cli/test/quickstart.test.ts +0 -579
- package/packages/cli/test/rasterize.test.ts +0 -86
- package/packages/cli/test/record-detection.test.ts +0 -156
- package/packages/cli/test/record-teardown.test.ts +0 -203
- package/packages/cli/test/replay-putback.test.ts +0 -242
- package/packages/cli/test/replay-spill.test.ts +0 -116
- package/packages/cli/test/replay-teardown.test.ts +0 -143
- package/packages/cli/test/replay-trace.test.ts +0 -199
- package/packages/cli/test/replay-transport.test.ts +0 -113
- package/packages/cli/test/reset-roots.test.ts +0 -67
- package/packages/cli/test/responses-e2e.test.ts +0 -119
- package/packages/cli/test/retrieval-context.test.ts +0 -168
- package/packages/cli/test/review-regressions.test.ts +0 -168
- package/packages/cli/test/route-decision.test.ts +0 -134
- package/packages/cli/test/run-dir-sidecars.test.ts +0 -779
- package/packages/cli/test/scrub.test.ts +0 -936
- package/packages/cli/test/serial.test.ts +0 -65
- package/packages/cli/test/setup.test.ts +0 -535
- package/packages/cli/test/share-card.test.ts +0 -135
- package/packages/cli/test/shell-capture.test.ts +0 -184
- package/packages/cli/test/shell-frames-drain.test.ts +0 -91
- package/packages/cli/test/snapshot-retry.test.ts +0 -54
- package/packages/cli/test/support-claims.test.ts +0 -127
- package/packages/cli/test/sync-credentials.test.ts +0 -177
- package/packages/cli/test/sync.test.ts +0 -1709
- package/packages/cli/test/tls-intercept.test.ts +0 -548
- package/packages/cli/test/upstream-visible.test.ts +0 -314
- package/packages/cli/test/vercel-sdk-e2e.test.ts +0 -105
- package/packages/cli/test/version.test.ts +0 -20
- package/packages/cli/tsconfig.json +0 -40
- package/packages/core/package.json +0 -26
- package/packages/core/src/blobs.ts +0 -109
- package/packages/core/src/fetch.ts +0 -48
- package/packages/core/src/graph.ts +0 -450
- package/packages/core/src/index.ts +0 -8
- package/packages/core/src/paths.ts +0 -180
- package/packages/core/src/private-files.ts +0 -394
- package/packages/core/src/reader.ts +0 -175
- package/packages/core/src/redaction.ts +0 -826
- package/packages/core/src/writer.ts +0 -467
- package/packages/core/test/blobs.test.ts +0 -170
- package/packages/core/test/capture-contract.test.ts +0 -179
- package/packages/core/test/data-uri-redaction.test.ts +0 -758
- package/packages/core/test/graph.test.ts +0 -520
- package/packages/core/test/integration.test.ts +0 -148
- package/packages/core/test/paths-permission-failure.test.ts +0 -53
- package/packages/core/test/paths.test.ts +0 -339
- package/packages/core/test/private-files-owner.test.ts +0 -77
- package/packages/core/test/private-files-scratch-race.test.ts +0 -62
- package/packages/core/test/private-files.test.ts +0 -251
- package/packages/core/test/reader.test.ts +0 -271
- package/packages/core/test/redaction.test.ts +0 -525
- package/packages/core/test/writer.test.ts +0 -531
- package/packages/core/tsconfig.json +0 -6
- package/packages/fs-capture/package.json +0 -25
- package/packages/fs-capture/src/capture.ts +0 -193
- package/packages/fs-capture/src/git.ts +0 -131
- package/packages/fs-capture/src/index.ts +0 -3
- package/packages/fs-capture/src/shadow.ts +0 -751
- package/packages/fs-capture/test/capture.test.ts +0 -241
- package/packages/fs-capture/test/git.test.ts +0 -118
- package/packages/fs-capture/test/helpers.ts +0 -28
- package/packages/fs-capture/test/shadow.test.ts +0 -1058
- package/packages/fs-capture/tsconfig.json +0 -6
- package/packages/mcp-shim/package.json +0 -26
- package/packages/mcp-shim/src/cli.ts +0 -372
- package/packages/mcp-shim/src/framing.ts +0 -106
- package/packages/mcp-shim/src/index.ts +0 -4
- package/packages/mcp-shim/src/mock.ts +0 -194
- package/packages/mcp-shim/src/shim.ts +0 -126
- package/packages/mcp-shim/test/cli.test.ts +0 -489
- package/packages/mcp-shim/test/framing.test.ts +0 -143
- package/packages/mcp-shim/test/mock.test.ts +0 -200
- package/packages/mcp-shim/test/shim.test.ts +0 -287
- package/packages/mcp-shim/tsconfig.json +0 -5
- package/packages/node-instrument/package.json +0 -23
- package/packages/node-instrument/src/capture.ts +0 -505
- package/packages/node-instrument/src/index.ts +0 -3
- package/packages/node-instrument/src/install.ts +0 -186
- package/packages/node-instrument/src/rewrite.ts +0 -66
- package/packages/node-instrument/test/capture.test.ts +0 -423
- package/packages/node-instrument/test/install.test.ts +0 -427
- package/packages/node-instrument/test/rewrite.test.ts +0 -85
- package/packages/node-instrument/tsconfig.json +0 -9
- package/packages/plugin-api/package.json +0 -22
- package/packages/plugin-api/src/canonical.ts +0 -73
- package/packages/plugin-api/src/index.ts +0 -2
- package/packages/plugin-api/src/plugins.ts +0 -265
- package/packages/plugin-api/test/canonical.test.ts +0 -58
- package/packages/plugin-api/tsconfig.json +0 -5
- package/packages/providers/package.json +0 -26
- package/packages/providers/src/index.ts +0 -34
- package/packages/providers/src/pricing.ts +0 -140
- package/packages/providers/src/translate/anthropic.ts +0 -620
- package/packages/providers/src/translate/openai-responses.ts +0 -638
- package/packages/providers/src/translate/openai.ts +0 -630
- package/packages/providers/src/translate/sse.ts +0 -99
- package/packages/providers/src/translate/util.ts +0 -111
- package/packages/providers/test/anthropic-translate.test.ts +0 -687
- package/packages/providers/test/openai-responses-translate.test.ts +0 -377
- package/packages/providers/test/openai-translate.test.ts +0 -884
- package/packages/providers/test/pricing.test.ts +0 -171
- package/packages/providers/tsconfig.json +0 -6
- package/packages/proxy/package.json +0 -28
- package/packages/proxy/src/ca.ts +0 -376
- package/packages/proxy/src/der.ts +0 -152
- package/packages/proxy/src/dialects.ts +0 -413
- package/packages/proxy/src/forward.ts +0 -64
- package/packages/proxy/src/index.ts +0 -8
- package/packages/proxy/src/intercept.ts +0 -1554
- package/packages/proxy/src/matching.ts +0 -1056
- package/packages/proxy/src/retrieval.ts +0 -290
- package/packages/proxy/src/server.ts +0 -2875
- package/packages/proxy/src/tls-hosts.ts +0 -205
- package/packages/proxy/test/beta-headers.test.ts +0 -39
- package/packages/proxy/test/ca.test.ts +0 -146
- package/packages/proxy/test/forward.test.ts +0 -306
- package/packages/proxy/test/hop-by-hop.test.ts +0 -118
- package/packages/proxy/test/image-matching.test.ts +0 -129
- package/packages/proxy/test/indexing-concurrency.test.ts +0 -224
- package/packages/proxy/test/lookahead.test.ts +0 -160
- package/packages/proxy/test/malformed-body.test.ts +0 -73
- package/packages/proxy/test/matching.test.ts +0 -822
- package/packages/proxy/test/passthrough.test.ts +0 -599
- package/packages/proxy/test/recorded-upstream.test.ts +0 -253
- package/packages/proxy/test/responses-dialect.test.ts +0 -239
- package/packages/proxy/test/retrieval.test.ts +0 -589
- package/packages/proxy/test/server.test.ts +0 -1281
- package/packages/proxy/test/tls-hosts.test.ts +0 -190
- package/packages/proxy/test/tls-intercept.test.ts +0 -1769
- package/packages/proxy/tsconfig.json +0 -22
- package/packages/schema/package.json +0 -28
- package/packages/schema/src/constants.ts +0 -73
- package/packages/schema/src/index.ts +0 -3
- package/packages/schema/src/types.ts +0 -103
- package/packages/schema/src/validate.ts +0 -60
- package/packages/schema/test/schema-parity.test.ts +0 -116
- package/packages/schema/tsconfig.json +0 -5
- package/packages/shell-shim/package.json +0 -26
- package/packages/shell-shim/src/index.ts +0 -3
- package/packages/shell-shim/src/install.ts +0 -406
- package/packages/shell-shim/src/resolve.ts +0 -98
- package/packages/shell-shim/src/runner-bin.ts +0 -4
- package/packages/shell-shim/src/runner.ts +0 -149
- package/packages/shell-shim/test/resolve.test.ts +0 -125
- package/packages/shell-shim/test/shim.test.ts +0 -548
- package/packages/shell-shim/test/transport-race.test.ts +0 -109
- package/packages/shell-shim/tsconfig.json +0 -13
- package/packages/viewer/package.json +0 -25
- package/packages/viewer/src/bundle.ts +0 -36
- package/packages/viewer/src/client/main.ts +0 -248
- package/packages/viewer/src/credit.ts +0 -24
- package/packages/viewer/src/css.ts +0 -409
- package/packages/viewer/src/export.ts +0 -38
- package/packages/viewer/src/html.ts +0 -356
- package/packages/viewer/src/index.ts +0 -16
- package/packages/viewer/src/render.ts +0 -791
- package/packages/viewer/src/serve.ts +0 -150
- package/packages/viewer/src/trace-dir.ts +0 -140
- package/packages/viewer/test/bundle.test.ts +0 -47
- package/packages/viewer/test/client.test.ts +0 -378
- package/packages/viewer/test/export.test.ts +0 -131
- package/packages/viewer/test/fixtures.ts +0 -69
- package/packages/viewer/test/html.test.ts +0 -453
- package/packages/viewer/test/playback.test.ts +0 -54
- package/packages/viewer/test/render.test.ts +0 -714
- package/packages/viewer/test/serve.test.ts +0 -125
- package/packages/viewer/tsconfig.json +0 -6
- package/prompt/AIDER/deepseek-v4-1-flash-system-prompt.md +0 -29
- package/prompt/CLAUDECODE/claude-fable-5-1-print-system-prompt.md +0 -127
- package/prompt/CLAUDECODE/claude-fable-5-1-system-prompt.md +0 -169
- package/prompt/CLAUDECODE/claude-opus-4-8-system-prompt.md +0 -131
- package/prompt/CLAUDECODE/claude-opus-5-system-prompt.md +0 -149
- package/prompt/CLINE/openai-gpt-4o-mini-system-prompt.md +0 -37
- package/prompt/CODEX/gpt-5-6-luna-system-prompt.md +0 -183
- package/prompt/CODEX/gpt-5-6-sol-system-prompt.md +0 -218
- package/prompt/CODEX/gpt-6-1-sol-system-prompt.md +0 -242
- package/prompt/CODEX/gpt-6-astra-system-prompt.md +0 -170
- package/prompt/CODEX/gpt-6-luna-system-prompt.md +0 -223
- package/prompt/CODEX/gpt-6-sol-system-prompt.md +0 -226
- package/prompt/CRUSH/deepseek-v4-1-flash-system-prompt.md +0 -472
- package/prompt/CURSOR/grok-4-5-high-system-prompt.md +0 -40
- package/prompt/DSH/deepseek-flash-system-prompt.md +0 -31
- package/prompt/GEMINICLI/gemini-3-5-flash-system-prompt.md +0 -168
- package/prompt/GOOSE/deepseek-v4-1-flash-system-prompt.md +0 -180
- package/prompt/HACKERAI/openai-gpt-4o-mini-system-prompt.md +0 -70
- package/prompt/HERMES/nemotron-3-5-lightning-free-system-prompt.md +0 -111
- package/prompt/KILOCODE/kilo-auto-free-system-prompt.md +0 -129
- package/prompt/MCODE/deepseek-deepseek-v4-flash-free-coding-system-prompt.md +0 -128
- package/prompt/MCODE/deepseek-deepseek-v4-flash-free-tui-system-prompt.md +0 -119
- package/prompt/MCODE/deepseek-deepseek-v4-flash-free-work-system-prompt.md +0 -140
- package/prompt/MIMOCODE/mimo-v2-5-pro-system-prompt.md +0 -411
- package/prompt/MIMOCODE/mimo-v2-5-system-prompt.md +0 -411
- package/prompt/MUSECODE/muse-spark-1-3-system-prompt.md +0 -78
- package/prompt/OPENCLAW/gpt-5-6-sol-system-prompt.md +0 -333
- package/prompt/OPENCODE/big-pickle-system-prompt.md +0 -114
- package/prompt/OPENCODE/gpt-5-6-sol-system-prompt.md +0 -126
- package/prompt/OPENCODE/ling-3-0-flash-fin-free-system-prompt.md +0 -114
- package/prompt/OPENCODE/mimo-v2-5-free-system-prompt.md +0 -114
- package/prompt/OPENCODE/muse-spark-1-2-contributor-free-system-prompt.md +0 -84
- package/prompt/OPENCODE/nemotron-3-5-lightning-free-system-prompt.md +0 -114
- package/prompt/OPENCODE/nemotron-3-ultra-free-system-prompt.md +0 -114
- package/prompt/PI/openai-gpt-4o-mini-system-prompt.md +0 -31
- package/prompt/QWENCODE/gpt-5-6-sol-system-prompt.md +0 -290
- package/prompt/ZCODE/glm-4-6-system-prompt.md +0 -91
- package/python/README.md +0 -132
- package/python/agenticreplay_trace/__init__.py +0 -58
- package/python/agenticreplay_trace/graph.py +0 -137
- package/python/agenticreplay_trace/models.py +0 -491
- package/python/agenticreplay_trace/py.typed +0 -0
- package/python/agenticreplay_trace/reader.py +0 -295
- package/python/conftest.py +0 -12
- package/python/examples/analyze.py +0 -114
- package/python/pyproject.toml +0 -45
- package/python/tests/conftest.py +0 -102
- package/python/tests/test_capture_contract.py +0 -24
- package/python/tests/test_conformance.py +0 -235
- package/python/tests/test_examples.py +0 -60
- package/python/tests/test_graph.py +0 -247
- package/python/tests/test_models.py +0 -342
- package/python/tests/test_reader.py +0 -423
- package/python-langgraph/README.md +0 -159
- package/python-langgraph/agenticreplay_langgraph/__init__.py +0 -21
- package/python-langgraph/agenticreplay_langgraph/handler.py +0 -317
- package/python-langgraph/agenticreplay_langgraph/hook.py +0 -168
- package/python-langgraph/pyproject.toml +0 -35
- package/python-langgraph/tests/test_handler.py +0 -370
- package/python-langgraph/tests/test_integration.py +0 -484
- package/python-openai-agents/README.md +0 -145
- package/python-openai-agents/agenticreplay_openai_agents/__init__.py +0 -11
- package/python-openai-agents/agenticreplay_openai_agents/processor.py +0 -331
- package/python-openai-agents/pyproject.toml +0 -34
- package/python-openai-agents/tests/test_processor.py +0 -457
- package/scripts/check-neutrality.mjs +0 -62
- package/scripts/codex-client-acceptance.mjs +0 -133
- package/scripts/conformance.mjs +0 -245
- package/scripts/fidelity.mjs +0 -170
- package/scripts/hermes-client-acceptance.mjs +0 -158
- package/scripts/host-client-acceptance.mjs +0 -732
- package/scripts/installed-smoke.mjs +0 -316
- package/scripts/publish-order.mjs +0 -96
- package/scripts/regenerate-quickstart.mjs +0 -79
- package/scripts/render-cards.mjs +0 -178
- package/scripts/render-demo.mjs +0 -139
- package/scripts/render-sync-card.mjs +0 -96
- package/scripts/set-version.mjs +0 -152
- package/scripts/set-version.test.ts +0 -220
- package/scripts/sync-server-json.mjs +0 -13
- package/scripts/update-opencode-api-bases.mjs +0 -29
- package/server.json +0 -28
- package/skills/agenticreplay-replay/SKILL.md +0 -211
- package/spec/agenticreplay-trace-v0.md +0 -223
- package/test/integrations/README.md +0 -133
- package/test/integrations/agents/ai_sdk_openai.mjs +0 -24
- package/test/integrations/agents/anthropic_sdk.py +0 -10
- package/test/integrations/agents/browser_use_agent.py +0 -24
- package/test/integrations/agents/crewai_agent.py +0 -44
- package/test/integrations/agents/crewai_model_names.py +0 -72
- package/test/integrations/agents/hardcoded_origin.mjs +0 -13
- package/test/integrations/agents/haystack_pipeline.py +0 -28
- package/test/integrations/agents/haystack_rag.py +0 -35
- package/test/integrations/agents/langgraph_agent.py +0 -54
- package/test/integrations/agents/langgraph_nodes.py +0 -62
- package/test/integrations/agents/litellm_agent.py +0 -11
- package/test/integrations/agents/llama_index_agent.py +0 -27
- package/test/integrations/agents/llama_index_model_names.py +0 -67
- package/test/integrations/agents/mastra_agent.mjs +0 -20
- package/test/integrations/agents/mcp_agent.py +0 -44
- package/test/integrations/agents/mcp_server.py +0 -20
- package/test/integrations/agents/openai_agents_handoff.py +0 -52
- package/test/integrations/agents/openai_agents_sdk.py +0 -29
- package/test/integrations/agents/openai_async.py +0 -17
- package/test/integrations/agents/openai_sdk.py +0 -10
- package/test/integrations/agents/openhands_agent.py +0 -34
- package/test/integrations/agents/rag_pipeline.py +0 -79
- package/test/integrations/agents/vision_agent.py +0 -63
- package/test/integrations/run.mjs +0 -719
- package/test/integrations/stub-origin.mjs +0 -229
- package/tsconfig.base.json +0 -20
- package/tsconfig.json +0 -41
- package/vitest.config.ts +0 -39
- package/vitest.setup.ts +0 -25
- /package/{packages → node_modules/@agenticreplay}/schema/schema/event.schema.json +0 -0
- /package/{packages → node_modules/@agenticreplay}/schema/schema/manifest.schema.json +0 -0
|
@@ -1,1429 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import {
|
|
3
|
-
chmod,
|
|
4
|
-
link,
|
|
5
|
-
mkdir,
|
|
6
|
-
readFile,
|
|
7
|
-
readdir,
|
|
8
|
-
rename,
|
|
9
|
-
rm,
|
|
10
|
-
stat,
|
|
11
|
-
utimes,
|
|
12
|
-
writeFile,
|
|
13
|
-
} from 'node:fs/promises';
|
|
14
|
-
import { dirname, join, relative, sep } from 'node:path';
|
|
15
|
-
import { ensureRunsDir, resolveRunSelector, runDirFor, sha256File } from '@agenticreplay/core';
|
|
16
|
-
import type { ParsedArgs } from '../args.js';
|
|
17
|
-
import { tame, type Output } from '../out.js';
|
|
18
|
-
import {
|
|
19
|
-
readConfig,
|
|
20
|
-
gatewayHeaders,
|
|
21
|
-
namedPushDestination,
|
|
22
|
-
sameOrigin,
|
|
23
|
-
type AgenticReplayConfig,
|
|
24
|
-
fetchPinned,
|
|
25
|
-
} from '../config.js';
|
|
26
|
-
import { recordableOrigin } from '@agenticreplay/proxy';
|
|
27
|
-
import { readArchive, writeArchive, type ArchiveEntry } from '../archive.js';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Moving a run between this machine and a configured gateway.
|
|
31
|
-
*
|
|
32
|
-
* The gateway records what a local `agenticreplay record` cannot see — every key, every colleague, every CI
|
|
33
|
-
* job, and the routing decision behind each call — while the local recorder sees the shell, the
|
|
34
|
-
* filesystem and MCP. Both write the same `agenticreplay-trace v0`, so the interesting direction is neither
|
|
35
|
-
* one alone: pull a run a colleague's CI produced and `agenticreplay show` it, or push a local reproduction
|
|
36
|
-
* to where the rest of the team can read it.
|
|
37
|
-
*
|
|
38
|
-
* THE REDACTOR IS UPSTREAM OF THIS SINK, BY CONSTRUCTION. CONTRIBUTING requires a new sink to go
|
|
39
|
-
* through the redactor, and push is one — it is the first command that sends trace bytes to a host
|
|
40
|
-
* over the network. It does not re-run redaction, and it must not: `TraceWriter` puts every event
|
|
41
|
-
* through "spill, redact, validate, append" on its way to disk, precisely so no caller can bypass
|
|
42
|
-
* it, so the bytes push reads are already redacted. Re-scrubbing them here would either be a no-op
|
|
43
|
-
* or would rewrite bytes the manifest's integrity root already covers — which is the one thing
|
|
44
|
-
* that makes an archive unpushable.
|
|
45
|
-
*
|
|
46
|
-
* What push adds instead is a second, independent line: the gateway scans the archive on arrival
|
|
47
|
-
* and REFUSES it if it finds plaintext secrets, which is why `--force` exists and why it is opt-in.
|
|
48
|
-
*
|
|
49
|
-
* WHAT A PUSH ACTUALLY DISCLOSES. A run holds source, shell output and workspace snapshots (the
|
|
50
|
-
* snapshots as content-addressed blobs, so they travel with it). SECURITY.md says to treat a
|
|
51
|
-
* recording as sensitive, and sending one to a gateway is a disclosure to whoever can read that
|
|
52
|
-
* workspace — so the destination is never defaulted, and `push.packed` reports the file count and
|
|
53
|
-
* byte size before the request goes out rather than after.
|
|
54
|
-
*
|
|
55
|
-
* WHAT IS DELIBERATELY NOT HERE. Neither command converts, re-orders or re-serialises anything.
|
|
56
|
-
* The gateway recomputes the integrity root over `events.jsonl` and refuses a push whose root does
|
|
57
|
-
* not match its manifest, so the only correct thing to send is the bytes already on disk. Push
|
|
58
|
-
* reads files and zips them; pull unzips and writes them. Any cleverness in between would be a bug
|
|
59
|
-
* that reports success locally and is rejected — or worse, accepted with a root that no longer
|
|
60
|
-
* describes the events.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* The store's file modes, the same constants core/src/writer.ts and core/src/blobs.ts use.
|
|
65
|
-
*
|
|
66
|
-
* SECURITY.md states them as a promise — "Trace files and blobs are written mode 0600, run
|
|
67
|
-
* directories 0700" — and a pulled run is exactly as sensitive as a recorded one: it is the
|
|
68
|
-
* gateway's copy of the same source, shell output and workspace snapshots. Passing the mode to
|
|
69
|
-
* mkdir/writeFile is not sufficient on its own, because the process umask masks bits out of a
|
|
70
|
-
* creation mode; the explicit chmod after the fact is what actually makes the promise true.
|
|
71
|
-
*/
|
|
72
|
-
const FILE_MODE = 0o600;
|
|
73
|
-
const DIR_MODE = 0o700;
|
|
74
|
-
|
|
75
|
-
/** The endpoint paths this speaks, kept together because they are the whole API surface. */
|
|
76
|
-
const UPLOAD_PATH = '/api/replay/runs';
|
|
77
|
-
const exportPath = (runKey: string): string =>
|
|
78
|
-
`/api/replay/runs/${encodeURIComponent(runKey)}/export`;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Which of the three a message is explaining, where the reason differs.
|
|
82
|
-
*
|
|
83
|
-
* The RULES do not differ: same named-destination gate, same credential homing, same refusal to
|
|
84
|
-
* go unauthenticated. Only the sentence does — and it has to, because the answer to "why can I
|
|
85
|
-
* not do this here" is a different fact for each. Saying "a run carries source, shell output and
|
|
86
|
-
* workspace snapshots" to someone who asked for a *listing* names a risk they are not taking, and
|
|
87
|
-
* the message stops being believed the first time it is wrong.
|
|
88
|
-
*/
|
|
89
|
-
type GatewayUse = 'push' | 'pull' | 'list';
|
|
90
|
-
|
|
91
|
-
/** What actually goes to the host, per operation. A sentence of its own, so each reads as one. */
|
|
92
|
-
const AT_STAKE: Record<GatewayUse, string> = {
|
|
93
|
-
push: 'A run carries source, shell output and workspace snapshots, and your key travels with it.',
|
|
94
|
-
pull: 'Your key goes there, and what answers is written into this machine’s store.',
|
|
95
|
-
list: 'Your key goes there.',
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/** How the same refusal reads for each. */
|
|
99
|
-
const NEEDS_KEY: Record<GatewayUse, string> = {
|
|
100
|
-
push: 'A push needs',
|
|
101
|
-
pull: 'A pull needs',
|
|
102
|
-
list: 'Listing needs',
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* The gateway a sync command talks to: flag, then environment, then a configured gateway THE USER
|
|
107
|
-
* NAMED.
|
|
108
|
-
*
|
|
109
|
-
* Gateway configuration is explicit. Configurations that explicitly mark an unnamed default
|
|
110
|
-
* are refused; neither sync command selects a destination on the user's behalf.
|
|
111
|
-
*
|
|
112
|
-
* `namedPushDestination` is that promise as one function, so both sync commands and anything added
|
|
113
|
-
* later ask the same question instead of each re-deriving it.
|
|
114
|
-
*/
|
|
115
|
-
async function resolveGateway(
|
|
116
|
-
args: ParsedArgs,
|
|
117
|
-
env: NodeJS.ProcessEnv,
|
|
118
|
-
use: GatewayUse,
|
|
119
|
-
): Promise<{ url: string; headers: Record<string, string> }> {
|
|
120
|
-
const config: AgenticReplayConfig = await readConfig(env);
|
|
121
|
-
const named = namedPushDestination(config);
|
|
122
|
-
const url = args.str('gateway') ?? env.AGENTICREPLAY_GATEWAY_URL ?? named;
|
|
123
|
-
if (!url) {
|
|
124
|
-
// Two different situations, and telling them apart is the whole value of the message: nothing
|
|
125
|
-
// configured at all, versus a gateway that IS configured but only as setup's own default for
|
|
126
|
-
// model traffic. The second reads as a bug unless it says so.
|
|
127
|
-
throw new Error(
|
|
128
|
-
config.gateway?.url !== undefined
|
|
129
|
-
? `the configured gateway (${recordableOrigin(config.gateway.url) ?? '(unprintable)'}) is agenticreplay setup's default for MODEL ` +
|
|
130
|
-
`traffic, not a destination you named for your runs. ${AT_STAKE[use]} ` +
|
|
131
|
-
'Name it explicitly: pass --gateway <url>, set ' +
|
|
132
|
-
'AGENTICREPLAY_GATEWAY_URL, or re-run `agenticreplay setup --gateway <url>`.'
|
|
133
|
-
: 'no gateway configured. Run `agenticreplay setup --gateway <url>`, or pass --gateway, ' +
|
|
134
|
-
'or set AGENTICREPLAY_GATEWAY_URL.',
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// NO CREDENTIAL TRAVELS ANYWHERE BUT THE ORIGIN IT WAS SET UP FOR — from EITHER source.
|
|
139
|
-
//
|
|
140
|
-
// The first version of this gate applied the origin check to the stored key only, and I argued
|
|
141
|
-
// on the thread that an env key alongside an override was "a deliberate pairing made in one
|
|
142
|
-
// invocation". Review pointed at the README in this same PR, which tells you to
|
|
143
|
-
// `read -rs AGENTICREPLAY_GATEWAY_KEY && export AGENTICREPLAY_GATEWAY_KEY` — and an export PERSISTS. So the
|
|
144
|
-
// pairing was an assumption nothing enforced: a user who exported the key for their real gateway
|
|
145
|
-
// and later runs `agenticreplay push --gateway <other-host>` (a typo, a stale alias, a URL someone sent
|
|
146
|
-
// them) attaches that key and the whole recording to the other host — the exact request that is
|
|
147
|
-
// REFUSED when the same key sits in config. An asymmetry that depends on where a credential is
|
|
148
|
-
// stored rather than on where it is going is not a security boundary.
|
|
149
|
-
//
|
|
150
|
-
// Each key therefore has a HOME: the origin it was configured for.
|
|
151
|
-
//
|
|
152
|
-
// stored key -> config.gateway.url
|
|
153
|
-
// env key -> AGENTICREPLAY_GATEWAY_URL
|
|
154
|
-
//
|
|
155
|
-
// and a key is only sent when the destination matches its home.
|
|
156
|
-
//
|
|
157
|
-
// AN ENV KEY WITH NO HOME IS NOT HOMED AT THE CONFIGURED GATEWAY (orcacode-review). This read
|
|
158
|
-
// `env.AGENTICREPLAY_GATEWAY_URL ?? configured`, which substituted a home the key had never been
|
|
159
|
-
// associated with — and the README's CI recipe exports the KEY ALONE, so the substitution fired
|
|
160
|
-
// on the common case rather than an exotic one. A key exported for host A then travelled to the
|
|
161
|
-
// configured host B, in place of B's OWN stored key, because the stored branch is this branch's
|
|
162
|
-
// `else`. That is the fail-open shape the whole gate exists to prevent, and it contradicted both
|
|
163
|
-
// the README ("an exported key's [home] is AGENTICREPLAY_GATEWAY_URL") and the sentence two lines above
|
|
164
|
-
// it: the exemption is for a key whose only destination is the one THIS INVOCATION named, and
|
|
165
|
-
// here nothing in the invocation named it — the config did.
|
|
166
|
-
//
|
|
167
|
-
// So a homeless env key travels only when `--gateway` named the destination on this command
|
|
168
|
-
// line. That is exactly the CI shape the env key exists for, and nothing else.
|
|
169
|
-
const envKey = env.AGENTICREPLAY_GATEWAY_KEY?.trim();
|
|
170
|
-
const configured = config.gateway?.url;
|
|
171
|
-
const envHome = env.AGENTICREPLAY_GATEWAY_URL?.trim() || undefined;
|
|
172
|
-
const invocationNamedTheHost = args.str('gateway') !== undefined;
|
|
173
|
-
const envKeyApplies =
|
|
174
|
-
envKey !== undefined &&
|
|
175
|
-
envKey !== '' &&
|
|
176
|
-
(envHome === undefined ? invocationNamedTheHost : sameOrigin(url, envHome));
|
|
177
|
-
|
|
178
|
-
let headers: Record<string, string> = {};
|
|
179
|
-
if (envKeyApplies) {
|
|
180
|
-
// gatewayHeaders() returns {} rather than an empty bearer when it has no key — see its own
|
|
181
|
-
// note — so an env key is folded in here rather than relying on that.
|
|
182
|
-
headers = { authorization: `Bearer ${envKey}`, 'x-api-key': envKey };
|
|
183
|
-
} else if (configured !== undefined && sameOrigin(url, configured)) {
|
|
184
|
-
// Falling THROUGH rather than refusing: an env key that does not apply here is not a reason to
|
|
185
|
-
// withhold the credential the user configured for this very host.
|
|
186
|
-
headers = gatewayHeaders(config, env);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (!headers.authorization) {
|
|
190
|
-
// REFUSED, NOT ATTEMPTED ANONYMOUSLY. None of the three fails cleanly at the gateway without a
|
|
191
|
-
// credential — an unauthenticated request is exactly what a misconfigured public endpoint
|
|
192
|
-
// answers — and a 200 is the worst way to find out: for a push, that the run went somewhere
|
|
193
|
-
// with no owner; for a pull or a listing, that what came back was never scoped to you.
|
|
194
|
-
throw new Error(
|
|
195
|
-
`no API key for this gateway. ${NEEDS_KEY[use]} a key carrying the \`replay\` scope: ` +
|
|
196
|
-
'set AGENTICREPLAY_GATEWAY_KEY, or run `agenticreplay setup --gateway <url> --key-env <VAR>`.',
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
return { url: url.replace(/\/+$/, ''), headers };
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* The message a failed request should produce.
|
|
204
|
-
*
|
|
205
|
-
* The gateway answers `{success:false, message}` for everything it refuses, and that message is the
|
|
206
|
-
* only part a person can act on — "archive contains 2 plaintext secrets" versus "request failed
|
|
207
|
-
* with status 422". Falls back to the status when the body is not the shape we expect, because a
|
|
208
|
-
* proxy in between may answer instead of the gateway.
|
|
209
|
-
*
|
|
210
|
-
* ON ONE LINE, whatever the gateway sent. The CLI prints the first line of an error as what
|
|
211
|
-
* happened and every line after it as why, each line indented alike — so a newline in the
|
|
212
|
-
* gateway's words became a line of the CLI's own, and `Invalid key\nnext: agenticreplay push --force`
|
|
213
|
-
* printed a `next:` this code never wrote. Tamed here, where the text comes in, because nothing
|
|
214
|
-
* downstream can tell the gateway's line breaks from the ones a message was composed with.
|
|
215
|
-
*/
|
|
216
|
-
function refusal(status: number, body: string): string {
|
|
217
|
-
try {
|
|
218
|
-
const parsed = JSON.parse(body) as { message?: unknown };
|
|
219
|
-
if (typeof parsed.message === 'string' && parsed.message !== '') return tame(parsed.message);
|
|
220
|
-
} catch {
|
|
221
|
-
// Not JSON — fall through to the status line.
|
|
222
|
-
}
|
|
223
|
-
const trimmed = tame(body.trim().slice(0, 200));
|
|
224
|
-
return trimmed === '' ? `gateway answered ${status}` : `gateway answered ${status}: ${trimmed}`;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* One row of the gateway's run listing — the fields a terminal shows, and no more.
|
|
229
|
-
*
|
|
230
|
-
* Named after what listings actually carry — and two deployments carry different things.
|
|
231
|
-
*
|
|
232
|
-
* An older gateway answered with nine fields and no timestamp at all:
|
|
233
|
-
*
|
|
234
|
-
* {"run_key","source","client_app","turns","tool_calls","models","layers","outcome","bytes"}
|
|
235
|
-
*
|
|
236
|
-
* The production gateway, read through its own console on 2026-09-23, sends twenty-eight — the
|
|
237
|
-
* same nine plus `first_ts`, `last_ts`, `created_at`, `updated_at` and `expire_at`, all in
|
|
238
|
-
* seconds, and account bookkeeping this has no use for. An earlier version of this comment said
|
|
239
|
-
* no listing carried `created_at`; that was true of the older deployment and false of production,
|
|
240
|
-
* and it was written as though it were true of both.
|
|
241
|
-
*
|
|
242
|
-
* `gateway` recordings report `outcome` as the model's stop reason or a status (`end_turn`,
|
|
243
|
-
* `error`) and `client_app` as whatever the gateway identified (`Unknown`, `curl`, `Node`); a run
|
|
244
|
-
* pushed from here reports its exit (`exit 0`) and the adapter that recorded it.
|
|
245
|
-
*/
|
|
246
|
-
export interface GatewayRun {
|
|
247
|
-
runKey: string;
|
|
248
|
-
/** `gateway` for a run it recorded itself, `upload` for one pushed from here. */
|
|
249
|
-
source: string;
|
|
250
|
-
/** Seconds, as the gateway reports them; 0 when the listing carries no timestamp. */
|
|
251
|
-
startedAt: number;
|
|
252
|
-
turns: number;
|
|
253
|
-
/** Tool calls the run made — `tool_calls` in the response. */
|
|
254
|
-
toolCalls: number;
|
|
255
|
-
models: string[];
|
|
256
|
-
/**
|
|
257
|
-
* Which capture layers the run holds: `model` and `route` for a gateway recording, plus `fs`,
|
|
258
|
-
* `shell`, `mcp` and `net` on one recorded here. The listing reports it directly, so there is
|
|
259
|
-
* no need to infer it from SOURCE.
|
|
260
|
-
*/
|
|
261
|
-
layers: string[];
|
|
262
|
-
outcome: string;
|
|
263
|
-
clientApp: string;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Where a start time comes from, best first.
|
|
268
|
-
*
|
|
269
|
-
* `first_ts` is the run's first event. `created_at` is when the GATEWAY stored the row — for a
|
|
270
|
-
* run pushed from here, that is the push. Production shows the difference: a run whose first
|
|
271
|
-
* event was 09:36:26 was pushed and stored at 09:38:09, and the local manifest of another says
|
|
272
|
-
* 09:40:11.6 against a `first_ts` of 09:40:12 and a `created_at` of 09:40:13. Preferring
|
|
273
|
-
* `created_at` labelled the push as the start, so a run recorded on Monday and pushed on Friday
|
|
274
|
-
* read as Friday's — and the same run showed two different start times in `agenticreplay list` and
|
|
275
|
-
* `agenticreplay list --remote`.
|
|
276
|
-
*/
|
|
277
|
-
const STARTED_KEYS = ['started_at', 'first_ts', 'created_at'] as const;
|
|
278
|
-
|
|
279
|
-
/** The years a run can have started in. Fixed, not "now": a test must not expire. */
|
|
280
|
-
const EARLIEST = Date.UTC(2020, 0, 1) / 1000;
|
|
281
|
-
const LATEST = Date.UTC(2100, 0, 1) / 1000;
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* A start time in seconds, or 0 when nothing offered is one a person could believe.
|
|
285
|
-
*
|
|
286
|
-
* Three units are in use — seconds, and the milliseconds and microseconds of anything written
|
|
287
|
-
* against `Date.now()` — and across the years a run can have started in they do not overlap, so
|
|
288
|
-
* the magnitude says which arrived rather than a guess. Anything still outside those years is not
|
|
289
|
-
* a start time: `-1` rendered as 1969, a millisecond value as the year 58675, and a microsecond
|
|
290
|
-
* one made `toISOString` throw `Invalid time value` and took the whole listing down with it.
|
|
291
|
-
*/
|
|
292
|
-
function asSeconds(v: unknown): number {
|
|
293
|
-
if (typeof v !== 'number' || !Number.isFinite(v)) return 0;
|
|
294
|
-
const s = v >= 1e14 ? v / 1e6 : v >= 1e11 ? v / 1e3 : v;
|
|
295
|
-
return s >= EARLIEST && s < LATEST ? Math.floor(s) : 0;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
function startedFrom(it: Record<string, unknown>): number {
|
|
299
|
-
// The first BELIEVABLE one, not the first numeric one: a `started_at` of -1 beside a sound
|
|
300
|
-
// `first_ts` should not cost the row its date.
|
|
301
|
-
for (const key of STARTED_KEYS) {
|
|
302
|
-
const s = asSeconds(it[key]);
|
|
303
|
-
if (s !== 0) return s;
|
|
304
|
-
}
|
|
305
|
-
return 0;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* What the gateway is holding, so that `agenticreplay pull` has somewhere to get a run id from.
|
|
310
|
-
*
|
|
311
|
-
* `pull` is the only command whose required argument cannot be obtained from the CLI: `push`
|
|
312
|
-
* defaults to the last run, but "last" means nothing for a run this machine has never seen (the
|
|
313
|
-
* comment on POSITIONALS says exactly that). So the id had to come from somewhere else entirely,
|
|
314
|
-
* and a recording the gateway made itself — which is most of them — could not be discovered here
|
|
315
|
-
* at all.
|
|
316
|
-
*
|
|
317
|
-
* A GET on the path push already POSTs to. Same gateway resolution, same headers, same
|
|
318
|
-
* redirect-refusing fetch: nothing about where a key may travel changes because the verb did.
|
|
319
|
-
*/
|
|
320
|
-
/**
|
|
321
|
-
* `--limit` as a count, the way `agenticreplay gc --keep` reads its own.
|
|
322
|
-
*
|
|
323
|
-
* `NUMERIC` guarantees it parsed as a number and nothing more, so `--limit 0` asked the gateway
|
|
324
|
-
* for no runs and `--limit -1` asked it for a negative number of them. Both were sent. What comes
|
|
325
|
-
* back from either is the gateway's opinion of a nonsense request, which is not an answer this
|
|
326
|
-
* should be relaying.
|
|
327
|
-
*/
|
|
328
|
-
function readLimit(args: ParsedArgs): number {
|
|
329
|
-
if (!args.has('limit')) return 20;
|
|
330
|
-
const n = args.num('limit');
|
|
331
|
-
if (n === undefined || !Number.isInteger(n) || n < 1) {
|
|
332
|
-
throw new Error(
|
|
333
|
-
'--limit needs a whole number of runs to list, like --limit 10' +
|
|
334
|
-
'\nit is how many the gateway should return, newest first',
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
return n;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* `--source` as one of the two the gateway has.
|
|
342
|
-
*
|
|
343
|
-
* Production answers an unknown source with 200 and an empty list, so `--source gatway` printed
|
|
344
|
-
* "the gateway is holding no runs for this key" to someone whose gateway held forty-five. A typo
|
|
345
|
-
* became a false statement about the server. The comparison is case-insensitive because the
|
|
346
|
-
* gateway's is (`source=Gateway` returns gateway runs), and the value sent is normalised.
|
|
347
|
-
*/
|
|
348
|
-
const SOURCES = ['gateway', 'upload'] as const;
|
|
349
|
-
|
|
350
|
-
export function readSource(args: ParsedArgs): (typeof SOURCES)[number] | undefined {
|
|
351
|
-
const raw = args.str('source');
|
|
352
|
-
if (raw === undefined) return undefined;
|
|
353
|
-
const source = SOURCES.find((s) => s === raw.toLowerCase());
|
|
354
|
-
if (source === undefined) {
|
|
355
|
-
throw new Error(
|
|
356
|
-
`--source is gateway or upload, not ${JSON.stringify(raw)}` +
|
|
357
|
-
'\ngateway: runs the gateway recorded itself; upload: runs pushed to it',
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
return source;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/** What a listing row must be before it can be one: an object naming a run you could pull. */
|
|
364
|
-
function isRunRow(raw: unknown): raw is Record<string, unknown> {
|
|
365
|
-
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) return false;
|
|
366
|
-
const key = (raw as Record<string, unknown>)['run_key'];
|
|
367
|
-
return typeof key === 'string' && key !== '';
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
export async function listGatewayRuns(
|
|
371
|
-
args: ParsedArgs,
|
|
372
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
373
|
-
): Promise<{ runs: GatewayRun[]; skipped: number }> {
|
|
374
|
-
const { url, headers } = await resolveGateway(args, env, 'list');
|
|
375
|
-
const query = new URLSearchParams({ limit: String(readLimit(args)) });
|
|
376
|
-
// Passed through rather than filtered here: the gateway already separates the two, and doing it
|
|
377
|
-
// locally would page through runs only to discard them.
|
|
378
|
-
const source = readSource(args);
|
|
379
|
-
if (source !== undefined) query.set('source', source);
|
|
380
|
-
|
|
381
|
-
const res = await fetchPinned(`${url}${UPLOAD_PATH}?${query.toString()}`, { headers });
|
|
382
|
-
if (!res.ok) throw new Error(refusal(res.status, await res.text()));
|
|
383
|
-
|
|
384
|
-
// A 2xx THAT IS NOT JSON IS SOMEBODY ELSE ANSWERING. `refusal` already says as much about error
|
|
385
|
-
// bodies — "a proxy in between may answer instead of the gateway" — and the success path had no
|
|
386
|
-
// such thought: a captive portal's login page came back as `Unexpected token '<'`, which reads
|
|
387
|
-
// as a bug in agenticreplay rather than as the network fact it is.
|
|
388
|
-
const body = await res.json().catch(() => {
|
|
389
|
-
throw new Error(
|
|
390
|
-
`${url} answered ${res.status} but not JSON ` +
|
|
391
|
-
`(content-type: ${res.headers.get('content-type') ?? 'none'}). ` +
|
|
392
|
-
'Something between here and that host answered instead — a proxy, or a portal asking ' +
|
|
393
|
-
'you to log in. Check the address, or point --gateway at one that is reachable.',
|
|
394
|
-
);
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
// `null` is valid JSON and has no properties: a 200 whose body was `null` read `.data` off it
|
|
398
|
-
// and surfaced `Cannot read properties of null` — the crash the row filter below exists to
|
|
399
|
-
// prevent, one level up.
|
|
400
|
-
const raw = (body as { data?: { items?: unknown } } | null)?.data?.items;
|
|
401
|
-
const all = Array.isArray(raw) ? raw : [];
|
|
402
|
-
// A row that is not an object, or names no run, is not a run you could pull — and reading
|
|
403
|
-
// `run_key` off `null` threw a TypeError at the user with agenticreplay's name on it. Counted rather
|
|
404
|
-
// than dropped in silence: a gateway sending these is broken, and that is worth saying.
|
|
405
|
-
const items = all.filter(isRunRow);
|
|
406
|
-
const runs = items.map((it): GatewayRun => {
|
|
407
|
-
return {
|
|
408
|
-
runKey: String(it['run_key'] ?? ''),
|
|
409
|
-
source: String(it['source'] ?? ''),
|
|
410
|
-
startedAt: startedFrom(it),
|
|
411
|
-
turns: typeof it['turns'] === 'number' ? it['turns'] : 0,
|
|
412
|
-
toolCalls: typeof it['tool_calls'] === 'number' ? it['tool_calls'] : 0,
|
|
413
|
-
models: Array.isArray(it['models']) ? it['models'].map(String) : [],
|
|
414
|
-
layers: Array.isArray(it['layers']) ? it['layers'].map(String) : [],
|
|
415
|
-
outcome: String(it['outcome'] ?? ''),
|
|
416
|
-
clientApp: String(it['client_app'] ?? ''),
|
|
417
|
-
};
|
|
418
|
-
});
|
|
419
|
-
return { runs, skipped: all.length - items.length };
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* The run directory's top-level entries that a push SHIPS. Everything else stays on the machine.
|
|
424
|
-
*
|
|
425
|
-
* AN ALLOWLIST, AND IT USED TO BE A DENYLIST OF ONE (`tls/`). That is the whole fix
|
|
426
|
-
* (orcacode-review, `agenticreplay push` packing unredacted capture scaffolding): a denylist ships every
|
|
427
|
-
* file nobody has thought about yet, and a run directory accumulates files that are not trace
|
|
428
|
-
* content — `mcp-config.json` (MCP server `env` blocks, preserved verbatim by `rewriteMcpConfig`,
|
|
429
|
-
* which is where an MCP server's API token lives), `shell-frames.jsonl` (raw argv of every command
|
|
430
|
-
* the agent ran), `mcp-frames.jsonl` (raw JSON-RPC bodies), `shims/` (generated launchers holding
|
|
431
|
-
* this machine's paths), `tls/` (the run's own interception CA private key). Each of those was
|
|
432
|
-
* being POSTed to the gateway, stored there, and served to everyone who pulls the run.
|
|
433
|
-
*
|
|
434
|
-
* The reason a denylist cannot be made complete here is `agenticreplay scrub`. Scrub rewrites
|
|
435
|
-
* `manifest.json`, `events.jsonl` and `blobs/` and nothing else, so a user who scrubs a secret and
|
|
436
|
-
* then pushes was shipping an unscrubbed copy of it in the raw frame logs — the scrub reported
|
|
437
|
-
* success and the secret went out anyway. `push` is the sharing path; shipping a file scrub cannot
|
|
438
|
-
* reach defeats the command whose entire job is to make sharing safe.
|
|
439
|
-
*
|
|
440
|
-
* Why each entry is here:
|
|
441
|
-
*
|
|
442
|
-
* manifest.json / events.jsonl / blobs the trace, and what scrub covers.
|
|
443
|
-
* redactions.json the scrub ledger — by rule and COUNT, never by value —
|
|
444
|
-
* so the recipient can see the run was scrubbed.
|
|
445
|
-
* fs the workspace snapshots. Scrub cannot rewrite them
|
|
446
|
-
* either (it warns `fs_store_not_scrubbed` and offers
|
|
447
|
-
* `--drop-fs`), but unlike the frame logs they are content
|
|
448
|
-
* the user recorded ON PURPOSE, and README says a run
|
|
449
|
-
* carries them.
|
|
450
|
-
*
|
|
451
|
-
* ONE THING IS DELIBERATELY LOST, and it is worth stating rather than discovering: `agenticreplay replay`
|
|
452
|
-
* mocks MCP servers from `mcp-frames.jsonl`, so replaying a PULLED run no longer has those frames.
|
|
453
|
-
* That is a degraded secondary feature against a credential disclosure, and the unblock is the
|
|
454
|
-
* project rule this file already lives under — redaction belongs in the write path
|
|
455
|
-
* (CONTRIBUTING.md). Once the MCP tee redacts as it writes, `mcp-frames.jsonl` joins this list.
|
|
456
|
-
*
|
|
457
|
-
* Nested copies are untouched: a `tls/` or `shims/` INSIDE a recorded workspace snapshot is
|
|
458
|
-
* something the user recorded, and the filter applies at the top level only.
|
|
459
|
-
*/
|
|
460
|
-
const PUSHED_TOP_LEVEL = new Set(['manifest.json', 'events.jsonl', 'redactions.json', 'blobs']);
|
|
461
|
-
|
|
462
|
-
/**
|
|
463
|
-
* The workspace snapshots, which ship only when the user asks for them with `--fs`.
|
|
464
|
-
*
|
|
465
|
-
* THIS WAS ON THE ALLOWLIST AND SHOULD NOT HAVE BEEN (orcacode-review). I kept `fs/` on the
|
|
466
|
-
* grounds that it is "content the user recorded ON PURPOSE, and README says a run carries them",
|
|
467
|
-
* and that does not distinguish it from anything else here: the user ran the shell commands on
|
|
468
|
-
* purpose too, and `shell-frames.jsonl` came off this list all the same.
|
|
469
|
-
*
|
|
470
|
-
* What actually decides it is the rule the rest of the allowlist is built on — push must not ship
|
|
471
|
-
* a file `agenticreplay scrub` cannot reach. The shadow git store is the largest such file by far. Scrub
|
|
472
|
-
* says so itself: it cannot rewrite the store (the objects are zlib-deflated and addressed by the
|
|
473
|
-
* hash of their contents, so editing one rewrites every id that reaches it), so it SEARCHES and
|
|
474
|
-
* REPORTS instead and offers `--drop-fs`. SECURITY.md states the same in the same words: after a
|
|
475
|
-
* scrub, "objects still hold the material".
|
|
476
|
-
*
|
|
477
|
-
* So the sequence was: scrub finds a secret in the workspace, tells the user it is still in the
|
|
478
|
-
* store, the user pushes, and the whole workspace — including whatever the fixed pattern list
|
|
479
|
-
* misses, which SECURITY.md names `id_ecdsa` as an example of — goes to a shared gateway and is
|
|
480
|
-
* served to everyone who pulls it. The gateway's own scan does not see it either: the objects are
|
|
481
|
-
* deflated, so a plaintext scan of the archive reads nothing.
|
|
482
|
-
*
|
|
483
|
-
* `--fs` keeps the capability for the case it exists for (a teammate who needs the tree to
|
|
484
|
-
* reproduce), as a decision the pusher makes rather than a default they inherit, and push says out
|
|
485
|
-
* loud what it is about to send. `agenticreplay scrub --drop-fs` remains the way to make the run safe
|
|
486
|
-
* rather than merely quiet.
|
|
487
|
-
*/
|
|
488
|
-
const FS_SNAPSHOT_DIR = 'fs';
|
|
489
|
-
|
|
490
|
-
/** Every pushable file under a run directory, as archive entries named `<run_id>/<path>`. */
|
|
491
|
-
async function runEntries(
|
|
492
|
-
runDir: string,
|
|
493
|
-
runId: string,
|
|
494
|
-
includeFs: boolean,
|
|
495
|
-
): Promise<ArchiveEntry[]> {
|
|
496
|
-
const entries: ArchiveEntry[] = [];
|
|
497
|
-
const walk = async (dir: string): Promise<void> => {
|
|
498
|
-
for (const item of await readdir(dir, { withFileTypes: true })) {
|
|
499
|
-
// Top level only — see PUSHED_TOP_LEVEL.
|
|
500
|
-
if (dir === runDir) {
|
|
501
|
-
const allowed =
|
|
502
|
-
PUSHED_TOP_LEVEL.has(item.name) || (includeFs && item.name === FS_SNAPSHOT_DIR);
|
|
503
|
-
if (!allowed) continue;
|
|
504
|
-
}
|
|
505
|
-
const full = join(dir, item.name);
|
|
506
|
-
if (item.isDirectory()) {
|
|
507
|
-
await walk(full);
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
if (!item.isFile()) continue;
|
|
511
|
-
// Zip names are '/'-separated whatever the host uses.
|
|
512
|
-
const rel = relative(runDir, full).split(sep).join('/');
|
|
513
|
-
entries.push({ name: `${runId}/${rel}`, bytes: new Uint8Array(await readFile(full)) });
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
await walk(runDir);
|
|
517
|
-
// Sorted so the same run produces the same archive twice — a push that differs byte for byte
|
|
518
|
-
// between two invocations makes every digest comparison downstream meaningless.
|
|
519
|
-
return entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/** Build a multipart body by hand: the CLI takes no new runtime dependencies. */
|
|
523
|
-
function multipart(
|
|
524
|
-
fieldName: string,
|
|
525
|
-
fileName: string,
|
|
526
|
-
bytes: Uint8Array,
|
|
527
|
-
): { body: Uint8Array; contentType: string } {
|
|
528
|
-
const boundary = `----agenticreplay${Date.now().toString(16)}${Math.random().toString(16).slice(2)}`;
|
|
529
|
-
const head = new TextEncoder().encode(
|
|
530
|
-
`--${boundary}\r\n` +
|
|
531
|
-
`Content-Disposition: form-data; name="${fieldName}"; filename="${fileName}"\r\n` +
|
|
532
|
-
'Content-Type: application/zip\r\n\r\n',
|
|
533
|
-
);
|
|
534
|
-
const tail = new TextEncoder().encode(`\r\n--${boundary}--\r\n`);
|
|
535
|
-
const body = new Uint8Array(head.length + bytes.length + tail.length);
|
|
536
|
-
body.set(head, 0);
|
|
537
|
-
body.set(bytes, head.length);
|
|
538
|
-
body.set(tail, head.length + bytes.length);
|
|
539
|
-
return { body, contentType: `multipart/form-data; boundary=${boundary}` };
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Serialise everything that touches one run's directory.
|
|
544
|
-
*
|
|
545
|
-
* The deterministic scratch names that made a half-done swap RECOVERABLE also made it shared: two
|
|
546
|
-
* pulls of the same run now aim at the same `.incoming` and `.replaced`. I argued when I introduced
|
|
547
|
-
* them that this was a fair trade because "a race is recoverable, a disappearance is not" — and
|
|
548
|
-
* review showed the race produces exactly the disappearance I claimed it could not. Interleave a
|
|
549
|
-
* recovery's cleanup with another pull's two renames and both copies go: the recovery stats `dest`,
|
|
550
|
-
* finds the old run, and removes what it believes is litter while the pull is mid-swap, so the
|
|
551
|
-
* staged new copy and the retired old one are both deleted and the rollback finds nothing to
|
|
552
|
-
* restore.
|
|
553
|
-
*
|
|
554
|
-
* Verifying siblings "immediately before" each removal does not fix it — that is the same
|
|
555
|
-
* check-then-act one instruction later. Exclusion is the fix, and this is the smallest form of it:
|
|
556
|
-
* an O_EXCL lock file beside the run, held across recovery, staging and the swap together.
|
|
557
|
-
*
|
|
558
|
-
* A lock file needs an answer for the process that dies holding one, or the first crash makes the
|
|
559
|
-
* run permanently unpullable — which would be a worse failure than the one being fixed. So a lock
|
|
560
|
-
* older than STALE_LOCK_MS is broken and taken. That is a heuristic, and it is sound here for a
|
|
561
|
-
* reason worth stating: the work under the lock is bounded by the pull's own archive write, and a
|
|
562
|
-
* pull still running after ten minutes has a bigger problem than a stolen lock.
|
|
563
|
-
*/
|
|
564
|
-
const STALE_LOCK_MS = 10 * 60 * 1000;
|
|
565
|
-
|
|
566
|
-
/**
|
|
567
|
-
* How often a held lock's mtime is refreshed. A third of the stale window, so two beats can be lost
|
|
568
|
-
* — a suspended laptop, a stalled disk — before the lock looks abandoned.
|
|
569
|
-
*
|
|
570
|
-
* Exported so the heartbeat test names this value instead of re-deriving the arithmetic, which is
|
|
571
|
-
* the sort of duplicate that keeps passing after the real one changes.
|
|
572
|
-
*/
|
|
573
|
-
export const LOCK_HEARTBEAT_MS = Math.max(1_000, Math.floor(STALE_LOCK_MS / 3));
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* Release a run lock — but ONLY the one this process is holding.
|
|
577
|
-
*
|
|
578
|
-
* The unconditional `rm` this replaces was unsafe because of the stale-break above, not in spite of
|
|
579
|
-
* it. A pull that overruns STALE_LOCK_MS has its lock broken by a second pull, which then holds a
|
|
580
|
-
* FRESH lock of its own; the first pull's `finally` removed the PATH rather than its own lock, so
|
|
581
|
-
* it deleted the second pull's. A third pull then walks in beside the second, and the two of them
|
|
582
|
-
* are exactly the concurrent recovery-and-swap this lock exists to prevent — where both copies of
|
|
583
|
-
* the run can go.
|
|
584
|
-
*
|
|
585
|
-
* The token is a pid AND a uuid. A pid alone is not an identity across a ten-minute stale window on
|
|
586
|
-
* a busy machine: pids wrap, and the process that inherits ours would be granted our lock.
|
|
587
|
-
*
|
|
588
|
-
* Read-then-unlink is not atomic, so this is a narrowing rather than a proof — which is the right
|
|
589
|
-
* shape for an advisory lock whose worst case is already bounded by the stale-break. What it
|
|
590
|
-
* removes is the case that happens deterministically rather than by interleaving.
|
|
591
|
-
*
|
|
592
|
-
* Exported for the test that pins the rule: the release runs inside a `finally`, and no caller can
|
|
593
|
-
* interpose on that window through pullCommand.
|
|
594
|
-
*/
|
|
595
|
-
export async function releaseRunLock(lock: string, token: string): Promise<void> {
|
|
596
|
-
// CLAIM, THEN VERIFY — read-then-unlink was never a compare-and-swap (orcacode-review).
|
|
597
|
-
//
|
|
598
|
-
// The old body read the bytes at the path and unlinked THE PATH two awaits later, so a
|
|
599
|
-
// stale-break landing in between made the comparison describe a lock that no longer existed and
|
|
600
|
-
// the unlink destroy the one that had replaced it. The comment here called that "a narrowing
|
|
601
|
-
// rather than a proof", which accurately described a hole and was not a reason to leave it: the
|
|
602
|
-
// one line in this file that can delete another holder's lock is exactly that unlink.
|
|
603
|
-
// DO NOT OPEN THE WINDOW WE ALREADY KNOW WE WILL LOSE (orcacode-review).
|
|
604
|
-
//
|
|
605
|
-
// The claim below is a rename: for the instant between it and `restoreLockFile` the path is FREE,
|
|
606
|
-
// and a third pull waiting on it can create a lock there. Harmless when the lock really is ours —
|
|
607
|
-
// it is ours precisely because nobody else is waiting on it — but the case that put this comment
|
|
608
|
-
// here is the deterministic one: a pull whose lock was stale-broken mid-staging aborts, and its
|
|
609
|
-
// `finally` then runs this on a lock it demonstrably does not own, EVERY time. The reader below
|
|
610
|
-
// hands it straight back, but only after the path has stood empty, and the pull that now owns the
|
|
611
|
-
// run sees its own `stillHeld()` fail.
|
|
612
|
-
//
|
|
613
|
-
// So ask first. A plain read is not a compare-and-swap and does not pretend to be one — the claim
|
|
614
|
-
// still verifies — but a read that says "not ours" is never wrong in the direction that matters,
|
|
615
|
-
// and skipping on it removes the window from the case that happens by schedule rather than by
|
|
616
|
-
// interleaving. Fail-closed toward NOT TOUCHING: if the lock is unreadable we leave it, and the
|
|
617
|
-
// stale-break reclaims it.
|
|
618
|
-
if (!(await lockStillHeld(lock, token))) return;
|
|
619
|
-
const aside = await claimLockFile(lock, 'releasing');
|
|
620
|
-
if (aside === undefined) return;
|
|
621
|
-
const holder = await readFile(aside, 'utf8').catch(() => undefined);
|
|
622
|
-
if (holder === token) {
|
|
623
|
-
await rm(aside, { force: true }).catch(() => undefined);
|
|
624
|
-
return;
|
|
625
|
-
}
|
|
626
|
-
// Not ours — or unreadable, which is not evidence that it IS ours. Either way it belongs to
|
|
627
|
-
// somebody else now, so it goes back rather than away.
|
|
628
|
-
await restoreLockFile(aside, lock);
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* Take exclusive possession of whatever file is at `lock`, or of nothing.
|
|
633
|
-
*
|
|
634
|
-
* `rename` moves an INODE: exactly one racer can take it and the rest get ENOENT, so afterwards the
|
|
635
|
-
* caller holds something no other process can reach and can examine it without it changing
|
|
636
|
-
* underneath. That is what makes the checks in releaseRunLock and breakStaleRunLock actual
|
|
637
|
-
* compare-and-swaps, rather than two independent reads of a path that agree with each other about
|
|
638
|
-
* nothing.
|
|
639
|
-
*/
|
|
640
|
-
async function claimLockFile(lock: string, why: string): Promise<string | undefined> {
|
|
641
|
-
const aside = `${lock}.${why}.${process.pid}.${randomUUID()}`;
|
|
642
|
-
try {
|
|
643
|
-
await rename(lock, aside);
|
|
644
|
-
return aside;
|
|
645
|
-
} catch {
|
|
646
|
-
// Someone else claimed it first, or it is already gone.
|
|
647
|
-
return undefined;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
/**
|
|
652
|
-
* Put a claimed lock file back, and destroy the claim ONLY once that has succeeded.
|
|
653
|
-
*
|
|
654
|
-
* `link` fails EEXIST rather than clobbering, so it cannot overwrite a lock another waiter took
|
|
655
|
-
* while this one was held aside.
|
|
656
|
-
*
|
|
657
|
-
* WHEN IT CANNOT BE RETURNED, THE FILE STAYS (orcacode-review). The previous version removed the
|
|
658
|
-
* aside unconditionally after a swallowed `link` failure — deleting the only copy of a live
|
|
659
|
-
* holder's lock, which is the precise outcome the break exists to prevent, reached through its own
|
|
660
|
-
* cleanup. A left-behind `.releasing.*` / `.breaking.*` file holds no lock and matches no
|
|
661
|
-
* RUN_ID_PATTERN, so every command ignores it; that is strictly better than a live holder whose
|
|
662
|
-
* lock has evaporated while it is mid-swap.
|
|
663
|
-
*/
|
|
664
|
-
export async function restoreLockFile(aside: string, lock: string): Promise<boolean> {
|
|
665
|
-
for (let attempt = 0; attempt < 5; attempt++) {
|
|
666
|
-
try {
|
|
667
|
-
await link(aside, lock);
|
|
668
|
-
await rm(aside, { force: true }).catch(() => undefined);
|
|
669
|
-
return true;
|
|
670
|
-
} catch {
|
|
671
|
-
// EEXIST: another waiter holds the path right now. Brief retries cover the case where it is
|
|
672
|
-
// about to release; past that, leaving the file is the safe answer.
|
|
673
|
-
await new Promise((ok) => setTimeout(ok, 20));
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
return false;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* Break a lock judged stale, without ever removing a LIVE one.
|
|
681
|
-
*
|
|
682
|
-
* Two waiters can judge one abandoned lock stale. The first breaks it and acquires; the second must
|
|
683
|
-
* not then delete the FRESH lock that replaced it. So the break claims the file atomically and
|
|
684
|
-
* re-checks the age on the copy it now exclusively owns — winning the claim is not the same as the
|
|
685
|
-
* file having been stale, because the path can be re-acquired between the verdict and the claim.
|
|
686
|
-
*
|
|
687
|
-
* A crash between the claim and the unlink leaves a `.breaking.*` file beside the run. It matches
|
|
688
|
-
* no RUN_ID_PATTERN, so every command ignores it, and it holds no lock.
|
|
689
|
-
*
|
|
690
|
-
* Exported for the test that drives the interleaving directly: the window between the `stat` and
|
|
691
|
-
* the break is inside `withRunLock`'s retry loop, and no caller can reach into it.
|
|
692
|
-
*/
|
|
693
|
-
export async function breakStaleRunLock(lock: string): Promise<void> {
|
|
694
|
-
const aside = await claimLockFile(lock, 'breaking');
|
|
695
|
-
if (aside === undefined) return;
|
|
696
|
-
const age = await stat(aside)
|
|
697
|
-
.then((st) => Date.now() - st.mtimeMs)
|
|
698
|
-
.catch(() => undefined);
|
|
699
|
-
if (age !== undefined && age > STALE_LOCK_MS) {
|
|
700
|
-
await rm(aside, { force: true }).catch(() => undefined);
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
// NOT STALE ON THE COPY WE NOW HOLD — a live holder's lock that arrived between the verdict and
|
|
704
|
-
// the claim, and it goes back untouched.
|
|
705
|
-
//
|
|
706
|
-
// An unreadable stat lands here too, which REVERSES what this used to do. It treated that as
|
|
707
|
-
// stale "rather than restoring a lock we cannot describe" — the same fail-open reasoning the
|
|
708
|
-
// whole function is against. Failing to read a file is not evidence that its holder is dead.
|
|
709
|
-
await restoreLockFile(aside, lock);
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
/**
|
|
713
|
-
* withRunLock, exported for the test that observes the heartbeat.
|
|
714
|
-
*
|
|
715
|
-
* The heartbeat is an interval armed inside the lock's own scope, so nothing a caller can reach
|
|
716
|
-
* observes it; the test needs the real thing on a real file, because the failures worth catching
|
|
717
|
-
* are "never armed", "armed on the wrong path" and "cleared too early".
|
|
718
|
-
*/
|
|
719
|
-
export function withRunLockForTest<T>(
|
|
720
|
-
dest: string,
|
|
721
|
-
fn: (stillHeld: () => Promise<boolean>) => Promise<T>,
|
|
722
|
-
): Promise<T> {
|
|
723
|
-
return withRunLock(dest, fn);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
async function withRunLock<T>(
|
|
727
|
-
dest: string,
|
|
728
|
-
// The callback is handed a `stillHeld` probe rather than the lock's path and token, so the swap
|
|
729
|
-
// can re-check ownership without any caller being able to forge or release it.
|
|
730
|
-
fn: (stillHeld: () => Promise<boolean>) => Promise<T>,
|
|
731
|
-
): Promise<T> {
|
|
732
|
-
const lock = `${dest}.lock`;
|
|
733
|
-
// See releaseRunLock for why this is a token and not just a pid.
|
|
734
|
-
const token = `${process.pid} ${randomUUID()}\n`;
|
|
735
|
-
let held = false;
|
|
736
|
-
for (let attempt = 0; attempt < 60 && !held; attempt++) {
|
|
737
|
-
try {
|
|
738
|
-
await writeFile(lock, token, { flag: 'wx', mode: FILE_MODE });
|
|
739
|
-
held = true;
|
|
740
|
-
} catch (err) {
|
|
741
|
-
// ONLY EEXIST MEANS "someone else holds it". Anything else — a missing parent, a read-only
|
|
742
|
-
// store, no space — is a real failure, and spinning on it burns the whole retry budget before
|
|
743
|
-
// reporting an error that was never going to change. The first version caught everything and
|
|
744
|
-
// took six seconds to fail on a workspace whose .agenticreplay/runs did not exist yet, which is the
|
|
745
|
-
// ordinary first-pull case.
|
|
746
|
-
if ((err as NodeJS.ErrnoException)?.code !== 'EEXIST') throw err;
|
|
747
|
-
const stale = await stat(lock)
|
|
748
|
-
.then((st) => Date.now() - st.mtimeMs)
|
|
749
|
-
.catch(() => 0);
|
|
750
|
-
if (stale > STALE_LOCK_MS) {
|
|
751
|
-
await breakStaleRunLock(lock);
|
|
752
|
-
continue;
|
|
753
|
-
}
|
|
754
|
-
await new Promise((ok) => setTimeout(ok, 100));
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
if (!held) {
|
|
758
|
-
throw new Error(
|
|
759
|
-
`another agenticreplay pull is working on this run (${lock} is held). Wait for it to finish, or ` +
|
|
760
|
-
`remove that file if no pull is running.`,
|
|
761
|
-
);
|
|
762
|
-
}
|
|
763
|
-
// A LIVE HOLDER MUST NEVER LOOK STALE (orcacode-review).
|
|
764
|
-
//
|
|
765
|
-
// The lock was written once and never touched again, so its mtime is its CREATION time and
|
|
766
|
-
// "stale" meant "older than ten minutes", not "dead". The work under this lock is the staging
|
|
767
|
-
// write — one mkdir/writeFile/chmod per archive entry, up to writeArchive's own bound of 65 534
|
|
768
|
-
// — so a large `fs/` snapshot on a slow or network-backed store genuinely takes longer than
|
|
769
|
-
// STALE_LOCK_MS. Its lock was then broken WHILE IT WAS WRITING, and the second pull entered the
|
|
770
|
-
// same critical section over the same deterministic scratch names: the two interleave, and the
|
|
771
|
-
// run that lands is a blend of both copies or is missing half its workspace snapshot, with
|
|
772
|
-
// nothing reporting it.
|
|
773
|
-
//
|
|
774
|
-
// The heartbeat makes staleness mean what the break assumes it means. A process killed outright
|
|
775
|
-
// stops beating and its lock ages out exactly as before, so the break still works on the case it
|
|
776
|
-
// was written for.
|
|
777
|
-
//
|
|
778
|
-
// AND IT MUST ONLY BEAT ON OUR OWN LOCK. The beat refreshed whatever file sat at the path, which
|
|
779
|
-
// after a stale-break is somebody else's lock — and refreshing it is not a harmless write. It is
|
|
780
|
-
// the one write that decides whether a lock can ever be broken: a pull whose lock was taken from
|
|
781
|
-
// it goes on holding the new holder's lock open, so if THAT pull dies its lock never ages out and
|
|
782
|
-
// the run is wedged until a human deletes the file. The concept the break rests on is defeated by
|
|
783
|
-
// a process that no longer has any claim on it.
|
|
784
|
-
//
|
|
785
|
-
// Read-then-utimes is a narrowing, not a compare-and-swap; the same shape and the same reason as
|
|
786
|
-
// releaseRunLock's own pre-check, and it removes the case that happens by schedule.
|
|
787
|
-
//
|
|
788
|
-
// unref'd, or the interval would hold the CLI open after the pull finishes.
|
|
789
|
-
const beat = setInterval(() => {
|
|
790
|
-
void (async () => {
|
|
791
|
-
if (!(await lockStillHeld(lock, token))) return;
|
|
792
|
-
const now = new Date();
|
|
793
|
-
await utimes(lock, now, now).catch(() => undefined);
|
|
794
|
-
})();
|
|
795
|
-
}, LOCK_HEARTBEAT_MS);
|
|
796
|
-
beat.unref?.();
|
|
797
|
-
try {
|
|
798
|
-
return await fn(() => lockStillHeld(lock, token));
|
|
799
|
-
} finally {
|
|
800
|
-
clearInterval(beat);
|
|
801
|
-
await releaseRunLock(lock, token);
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
/**
|
|
806
|
-
* Whether `lock` still holds our token — checked immediately before the swap's destructive renames.
|
|
807
|
-
*
|
|
808
|
-
* Belt and braces behind the heartbeat, for the one case the heartbeat cannot cover: a process
|
|
809
|
-
* stopped long enough (SIGSTOP, a suspended laptop) that its beats did not land, whose lock was
|
|
810
|
-
* then legitimately broken and re-taken. Resuming into the two renames from there is what deletes
|
|
811
|
-
* both copies of the run, so the swap asks once more rather than trusting a claim made minutes ago.
|
|
812
|
-
*/
|
|
813
|
-
async function lockStillHeld(lock: string, token: string): Promise<boolean> {
|
|
814
|
-
return (await readFile(lock, 'utf8').catch(() => undefined)) === token;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
/**
|
|
818
|
-
* Complete or roll back a swap that a previous pull did not finish. Call under withRunLock.
|
|
819
|
-
*
|
|
820
|
-
* The swap moves the old run aside and the new one into place — two renames with a gap. A process
|
|
821
|
-
* killed inside that gap leaves `<run>` absent, the finished new copy at `<run>.incoming` and the
|
|
822
|
-
* old one at `<run>.replaced`; neither sibling matches RUN_ID_PATTERN, so every command ignores
|
|
823
|
-
* both and the run is simply gone.
|
|
824
|
-
*
|
|
825
|
-
* `.replaced` IS THE EVIDENCE THAT `.incoming` IS COMPLETE, and the first version of this function
|
|
826
|
-
* missed that. It promoted `.incoming` whenever `dest` was absent, on the reasoning that "the
|
|
827
|
-
* interrupted pull had already written every byte and was one rename from done". True of a REPLACE,
|
|
828
|
-
* where staging is finished before `dest` is moved aside — so a replace crash always leaves BOTH
|
|
829
|
-
* siblings. Not true of a first pull, which writes entries straight into `.incoming` and renames it
|
|
830
|
-
* once at the end: a crash there leaves a PARTIAL `.incoming` and no `.replaced` at all. Promoting
|
|
831
|
-
* that installed a truncated recording as the run, which `list`, `show`, `scrub` and `push` would
|
|
832
|
-
* then treat as whole — and the next pull, the one that would have fetched the good copy, refused
|
|
833
|
-
* with "already exists locally" and a flag the user has no reason to reach for.
|
|
834
|
-
*
|
|
835
|
-
* So the rule is not "newest wins", it is "only a copy something PROVES complete wins":
|
|
836
|
-
*
|
|
837
|
-
* - `dest` missing, both siblings present — a replace crashed between the renames. `.incoming` is
|
|
838
|
-
* whole. Finish the swap.
|
|
839
|
-
* - `dest` missing, only `.replaced` — the move-aside happened, the new copy never landed. Put
|
|
840
|
-
* the old run back.
|
|
841
|
-
* - `dest` missing, only `.incoming` — a FIRST pull died mid-write. Partial, unprovable, and the
|
|
842
|
-
* archive is still on the gateway. Remove it and let this pull fetch again.
|
|
843
|
-
* - `dest` present — the swap completed; the siblings are litter.
|
|
844
|
-
*
|
|
845
|
-
* Best-effort throughout: a store we cannot tidy is not a reason to refuse a pull that would fix it
|
|
846
|
-
* anyway.
|
|
847
|
-
*/
|
|
848
|
-
export async function recoverInterruptedSwap(
|
|
849
|
-
dest: string,
|
|
850
|
-
// REQUIRED, not optional, and that is the fix (orcacode-review). This is the FIFTH site of
|
|
851
|
-
// "nothing that lost the lock may touch what the lock protects", and it was the only one that
|
|
852
|
-
// did not ask — while being the most destructive of the set, since every branch below either
|
|
853
|
-
// `rm -rf`s or promotes one of the two deterministic scratch names. `revertStagedSwap`'s own
|
|
854
|
-
// comment already stated the rule this signature now enforces: "once the lock has moved they
|
|
855
|
-
// name ANOTHER pull's in-flight state: the `rm` below would delete the staging directory the
|
|
856
|
-
// new holder is writing into".
|
|
857
|
-
//
|
|
858
|
-
// Taking the probe as a parameter rather than probing at the two call sites is deliberate. A
|
|
859
|
-
// call site can be added without one — the early-recovery site did exactly that, passing
|
|
860
|
-
// `() => recoverInterruptedSwap(early)` and discarding the probe `withRunLock` had handed it —
|
|
861
|
-
// and the next such site would reopen the hole silently. A required parameter cannot be
|
|
862
|
-
// forgotten: it fails to compile.
|
|
863
|
-
stillHeld: () => Promise<boolean>,
|
|
864
|
-
): Promise<void> {
|
|
865
|
-
const staging = `${dest}.incoming`;
|
|
866
|
-
const retired = `${dest}.replaced`;
|
|
867
|
-
const present = async (p: string): Promise<boolean> => !!(await stat(p).catch(() => undefined));
|
|
868
|
-
// EVERY mutation asks again, not just the first. The probe is a file read, so the window between
|
|
869
|
-
// two of these is real: a recovery that decided "dest is present, the siblings are litter" and
|
|
870
|
-
// then lost the lock must not go on to delete siblings that now belong to the new holder.
|
|
871
|
-
const drop = async (p: string): Promise<void> => {
|
|
872
|
-
if (!(await stillHeld())) return;
|
|
873
|
-
await rm(p, { recursive: true, force: true }).catch(() => undefined);
|
|
874
|
-
};
|
|
875
|
-
const promote = async (from: string, to: string): Promise<void> => {
|
|
876
|
-
if (!(await stillHeld())) return;
|
|
877
|
-
await rename(from, to).catch(() => undefined);
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
// Fail-closed toward NOT TOUCHING, the same direction revertStagedSwap fails: an evicted pull
|
|
881
|
-
// that resumes here does nothing, leaving litter the next holder reclaims under its own lock.
|
|
882
|
-
// The other direction destroys a copy that is nobody's to destroy.
|
|
883
|
-
if (!(await stillHeld())) return;
|
|
884
|
-
|
|
885
|
-
const [hasDest, hasStaging, hasRetired] = await Promise.all([
|
|
886
|
-
present(dest),
|
|
887
|
-
present(staging),
|
|
888
|
-
present(retired),
|
|
889
|
-
]);
|
|
890
|
-
|
|
891
|
-
if (hasDest) {
|
|
892
|
-
await drop(staging);
|
|
893
|
-
await drop(retired);
|
|
894
|
-
return;
|
|
895
|
-
}
|
|
896
|
-
if (hasStaging && hasRetired) {
|
|
897
|
-
await promote(staging, dest);
|
|
898
|
-
if (await present(dest)) await drop(retired);
|
|
899
|
-
return;
|
|
900
|
-
}
|
|
901
|
-
if (hasRetired) {
|
|
902
|
-
await promote(retired, dest);
|
|
903
|
-
return;
|
|
904
|
-
}
|
|
905
|
-
if (hasStaging) {
|
|
906
|
-
// Partial by construction — see the note above. The gateway still has the archive.
|
|
907
|
-
await drop(staging);
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
/**
|
|
912
|
-
* Undo a staging attempt that threw, putting the original run back — but only while this pull still
|
|
913
|
-
* owns the lock.
|
|
914
|
-
*
|
|
915
|
-
* Put the original back before reporting the failure: the caller is about to be told the pull did
|
|
916
|
-
* not happen, and that has to be true of the store as well as of the message. If even this fails,
|
|
917
|
-
* the deterministic scratch names mean the next pull recovers it rather than the copy being lost —
|
|
918
|
-
* which is exactly why the revert may swallow its own error and the version before it may not have.
|
|
919
|
-
*
|
|
920
|
-
* THE REVERT IS LOCK-PROTECTED WORK LIKE THE STAGING IT UNDOES. Both scratch paths are deterministic
|
|
921
|
-
* per destination, so once the lock has moved they name ANOTHER pull's in-flight state: the `rm`
|
|
922
|
-
* below would delete the staging directory the new holder is writing into, and the rename would put
|
|
923
|
-
* a run back over the one it had moved aside. That is the destructive resume the ownership re-check
|
|
924
|
-
* before the swap exists to prevent, performed by the check's own abort path.
|
|
925
|
-
*
|
|
926
|
-
* Gated on ownership rather than on which error was thrown, because the error does not identify the
|
|
927
|
-
* case: an ENOENT raised by the new holder's own recovery arrives here indistinguishable from a
|
|
928
|
-
* corrupt archive. Fail-closed toward NOT TOUCHING: an unreadable lock leaves litter, which
|
|
929
|
-
* `recoverInterruptedSwap` reclaims under the lock at the head of every pull, while the other
|
|
930
|
-
* direction destroys a copy that is nobody's to destroy.
|
|
931
|
-
*/
|
|
932
|
-
export async function revertStagedSwap(
|
|
933
|
-
stillHeld: () => Promise<boolean>,
|
|
934
|
-
paths: { dest: string; staging: string; retired: string; existing: boolean },
|
|
935
|
-
): Promise<void> {
|
|
936
|
-
const { dest, staging, retired, existing } = paths;
|
|
937
|
-
if (!(await stillHeld())) return;
|
|
938
|
-
if (existing) await rename(retired, dest).catch(() => undefined);
|
|
939
|
-
await rm(staging, { recursive: true, force: true });
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
/**
|
|
943
|
-
* push — send a local run to the gateway.
|
|
944
|
-
*
|
|
945
|
-
* `agenticreplay push [run] [--gateway URL] [--force]`
|
|
946
|
-
*/
|
|
947
|
-
export async function pushCommand(
|
|
948
|
-
args: ParsedArgs,
|
|
949
|
-
out: Output,
|
|
950
|
-
cwd = process.cwd(),
|
|
951
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
952
|
-
): Promise<void> {
|
|
953
|
-
const { url, headers } = await resolveGateway(args, env, 'push');
|
|
954
|
-
const ref = await resolveRunSelector(cwd, args.positionals[0] ?? 'last');
|
|
955
|
-
const manifest = JSON.parse(await readFile(join(ref.dir, 'manifest.json'), 'utf8')) as {
|
|
956
|
-
run_id?: unknown;
|
|
957
|
-
};
|
|
958
|
-
const runId = typeof manifest.run_id === 'string' ? manifest.run_id : '';
|
|
959
|
-
if (runId === '') throw new Error(`${ref.dir}/manifest.json has no run_id`);
|
|
960
|
-
|
|
961
|
-
const includeFs = args.bool('fs');
|
|
962
|
-
const entries = await runEntries(ref.dir, runId, includeFs);
|
|
963
|
-
const archive = await writeArchive(entries);
|
|
964
|
-
out.phase('push.packed', {
|
|
965
|
-
run: runId,
|
|
966
|
-
files: entries.length,
|
|
967
|
-
bytes: archive.length,
|
|
968
|
-
// Said on the way out, beside the count, because it is the one part of the payload scrub
|
|
969
|
-
// cannot have cleaned — see FS_SNAPSHOT_DIR.
|
|
970
|
-
fs: includeFs ? 'included' : 'withheld',
|
|
971
|
-
});
|
|
972
|
-
if (includeFs) {
|
|
973
|
-
out.warn('push.fs_included', {
|
|
974
|
-
note:
|
|
975
|
-
'workspace file contents travel raw: `agenticreplay scrub` cannot rewrite the snapshot store, ' +
|
|
976
|
-
'so anything it reported as still present is going with this push',
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
// `force` is the gateway's own flag for "store this even though the scan found something". It is
|
|
981
|
-
// opt-in on purpose: the default refusal is what stops a secret reaching a shared server.
|
|
982
|
-
const target = `${url}${UPLOAD_PATH}${args.bool('force') ? '?force=1' : ''}`;
|
|
983
|
-
const { body, contentType } = multipart('file', `${runId}.agenticreplay.zip`, archive);
|
|
984
|
-
const res = await fetchPinned(target, {
|
|
985
|
-
method: 'POST',
|
|
986
|
-
headers: { ...headers, 'content-type': contentType },
|
|
987
|
-
body,
|
|
988
|
-
});
|
|
989
|
-
const text = await res.text();
|
|
990
|
-
if (!res.ok) throw new Error(refusal(res.status, text));
|
|
991
|
-
|
|
992
|
-
let replaced = false;
|
|
993
|
-
try {
|
|
994
|
-
const parsed = JSON.parse(text) as { data?: { replaced?: unknown } };
|
|
995
|
-
replaced = parsed.data?.replaced === true;
|
|
996
|
-
} catch {
|
|
997
|
-
// A 200 whose body we cannot read is still a successful push; the run key is what matters and
|
|
998
|
-
// we already know it.
|
|
999
|
-
}
|
|
1000
|
-
// PRINTED THROUGH recordableOrigin, exactly as setup.ts:136 prints the same value. config.ts
|
|
1001
|
-
// states the promise this keeps — "nothing ever prints it back" — and a success line is not
|
|
1002
|
-
// exempt from it: `https://gw.example/v1?key=SECRET` is an ordinary query-authenticated gateway,
|
|
1003
|
-
// and this line lands in the terminal, in --json, and in the CI log of the README's own
|
|
1004
|
-
// `agenticreplay push last` recipe.
|
|
1005
|
-
out.phase('push.done', {
|
|
1006
|
-
run: runId,
|
|
1007
|
-
replaced,
|
|
1008
|
-
gateway: recordableOrigin(url) ?? '(unprintable)',
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
function lostTheLock(): Error {
|
|
1013
|
-
return new Error(
|
|
1014
|
-
'another agenticreplay pull took this run\u2019s lock while this one was staging; nothing was ' +
|
|
1015
|
-
'installed. Re-run the pull.',
|
|
1016
|
-
);
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
/**
|
|
1020
|
-
* Write an archive's entries into the staging directory, STOPPING THE MOMENT THE LOCK IS NOT OURS.
|
|
1021
|
-
*
|
|
1022
|
-
* THE FOURTH SITE OF "nothing that lost the lock may touch what the lock protects", and the half
|
|
1023
|
-
* the previous commit missed (orcacode-review). Gating the REVERT stopped an evicted pull from
|
|
1024
|
-
* DELETING the new holder's staging; it said nothing about the evicted pull's WRITES. The only
|
|
1025
|
-
* ownership probe sat after this whole loop, so a pull stopped long enough to be stale-broken
|
|
1026
|
-
* resumed and went on writing entries into `<dest>.incoming` — which, the scratch name being
|
|
1027
|
-
* deterministic, is by then the directory the NEW holder is staging into. The new holder renames
|
|
1028
|
-
* the blend into place and prints `pull.done`.
|
|
1029
|
-
*
|
|
1030
|
-
* Two archives of one run key differ in ordinary operation — a re-push, a scrub between fetches, or
|
|
1031
|
-
* the truncated export the `x-agenticreplay-run-truncated` header warns about — so the result is a run whose
|
|
1032
|
-
* manifest integrity root covers one copy while some of its blobs are the other's. That is verbatim
|
|
1033
|
-
* the outcome withRunLock's own comment says the lock exists to rule out: "the run that lands is a
|
|
1034
|
-
* blend of both copies … with nothing reporting it."
|
|
1035
|
-
*
|
|
1036
|
-
* Every 256 entries, so the syscall is noise next to the writes between them (one small read
|
|
1037
|
-
* against thousands of file writes) while the unowned window stays bounded by a fixed count rather
|
|
1038
|
-
* than by the archive's size. Probed BEFORE the first write too, so an already-evicted pull writes
|
|
1039
|
-
* nothing at all — including the mkdir of a directory that is no longer its own.
|
|
1040
|
-
*
|
|
1041
|
-
* Aborting leaves the partial staging as litter, which is correct: `recoverInterruptedSwap` runs
|
|
1042
|
-
* under the lock at the head of every pull and reclaims it. Exported for the test, because the
|
|
1043
|
-
* window is a SIGSTOP wide and a test that tries to hit it by timing is a coin flip.
|
|
1044
|
-
*/
|
|
1045
|
-
export async function stageRunEntries(
|
|
1046
|
-
entries: { name: string; bytes: Uint8Array }[],
|
|
1047
|
-
runId: string,
|
|
1048
|
-
staging: string,
|
|
1049
|
-
stillHeld: () => Promise<boolean>,
|
|
1050
|
-
): Promise<void> {
|
|
1051
|
-
if (!(await stillHeld())) throw lostTheLock();
|
|
1052
|
-
await mkdir(staging, { recursive: true, mode: DIR_MODE });
|
|
1053
|
-
await chmod(staging, DIR_MODE).catch(() => undefined);
|
|
1054
|
-
for (const [index, entry] of entries.entries()) {
|
|
1055
|
-
if (index > 0 && (index & 0xff) === 0 && !(await stillHeld())) throw lostTheLock();
|
|
1056
|
-
const rel = entry.name.slice(entry.name.indexOf('/') + 1);
|
|
1057
|
-
if (rel === '' || entry.name.indexOf('/') < 0) continue;
|
|
1058
|
-
const path = join(staging, ...rel.split('/'));
|
|
1059
|
-
// A TRAILING SLASH NAMES A DIRECTORY (orcacode-review). `runEntries` walks files and skips
|
|
1060
|
-
// directories, so nothing this CLI writes produces such an entry — but pull is documented
|
|
1061
|
-
// to read archives from the gateway's Go writer and from whatever produced them before
|
|
1062
|
-
// that, and every general-purpose zip writer emits them (`zip -r`, shutil.make_archive, a
|
|
1063
|
-
// filepath.Walk that appends "/" for a dir).
|
|
1064
|
-
//
|
|
1065
|
-
// Written as a file, the empty payload lands AS the directory: the next entry under it
|
|
1066
|
-
// dies with ENOTDIR and the whole pull rolls back, or — when the archive has no file under
|
|
1067
|
-
// it — the pull SUCCEEDS and installs a run whose `blobs` is a zero-byte file. That last
|
|
1068
|
-
// one is the silent-wrong-store outcome the rest of this function exists to avoid.
|
|
1069
|
-
if (entry.name.endsWith('/')) {
|
|
1070
|
-
await mkdir(path, { recursive: true, mode: DIR_MODE });
|
|
1071
|
-
await chmod(path, DIR_MODE).catch(() => undefined);
|
|
1072
|
-
continue;
|
|
1073
|
-
}
|
|
1074
|
-
await mkdir(dirname(path), { recursive: true, mode: DIR_MODE });
|
|
1075
|
-
await writeFile(path, entry.bytes, { mode: FILE_MODE });
|
|
1076
|
-
await chmod(path, FILE_MODE).catch(() => undefined);
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
* Move the staged copy into place, undoing the move-aside on EVERY failure — a lost lock,
|
|
1082
|
-
* a rename the filesystem refused, anything.
|
|
1083
|
-
*
|
|
1084
|
-
* Returns whether the old run was moved aside. That is only a SUCCESS signal, telling the
|
|
1085
|
-
* caller whether a `retired` directory is left to remove; a throw has already restored the
|
|
1086
|
-
* old run here. It cannot be otherwise: a function that throws returns nothing, so the
|
|
1087
|
-
* caller's `movedAside` is still `false` and its revert would put nothing back.
|
|
1088
|
-
*
|
|
1089
|
-
* Exported for the test: the window is the gap between two renames, and this file already
|
|
1090
|
-
* learned that a test aiming at such a window by timing is a coin flip.
|
|
1091
|
-
*/
|
|
1092
|
-
export async function swapStagedRun(
|
|
1093
|
-
paths: { dest: string; staging: string; retired: string; existing: boolean },
|
|
1094
|
-
stillHeld: () => Promise<boolean>,
|
|
1095
|
-
): Promise<boolean> {
|
|
1096
|
-
const { dest, staging, retired, existing } = paths;
|
|
1097
|
-
let movedAside = false;
|
|
1098
|
-
// PROBED ON BOTH SIDES OF THE MOVE-ASIDE, AND THE MOVE IS UNDONE (orcacode-review).
|
|
1099
|
-
//
|
|
1100
|
-
// One probe before the two renames was not enough, and the previous comment here —
|
|
1101
|
-
// "this one is what stops the DESTRUCTIVE half" — overstated it in exactly the case it
|
|
1102
|
-
// was written for. A pull stopped between the probe and `rename(dest, retired)` resumes
|
|
1103
|
-
// after its lock has been broken and a whole other pull has completed: the move-aside
|
|
1104
|
-
// then succeeds and carries away the run THAT pull just installed. The second rename
|
|
1105
|
-
// fails (the shared staging is gone), `revertStagedSwap` correctly refuses to put
|
|
1106
|
-
// anything back because the lock is not ours — and the result is a store where `<run>`
|
|
1107
|
-
// does not exist and the only copy sits at `<run>.replaced`, which matches no
|
|
1108
|
-
// RUN_ID_PATTERN and is therefore invisible to list, show, scrub, gc, export and push.
|
|
1109
|
-
// The "run that no command can reach again" this file's comments exist to rule out,
|
|
1110
|
-
// reached through the very guard added to prevent it.
|
|
1111
|
-
//
|
|
1112
|
-
// So: probe as late as possible before each destructive step, and UNDO the move-aside
|
|
1113
|
-
// when the second probe refuses. Still a narrowing rather than a proof — the same
|
|
1114
|
-
// standard the other three sites document — but the window shrinks from "the whole
|
|
1115
|
-
// swap" to "one rename", and the failure mode changes from a vanished run to litter
|
|
1116
|
-
// that `recoverInterruptedSwap` reclaims.
|
|
1117
|
-
//
|
|
1118
|
-
// THE ROLLBACK IS GATED ON HAVING DONE THE MOVE, not on `existing`. `<run>.replaced`
|
|
1119
|
-
// can also be another pull's move-aside, and renaming THAT over `dest` is the same
|
|
1120
|
-
// class of fault this whole sequence is about: only the process that moved a thing may
|
|
1121
|
-
// move it back.
|
|
1122
|
-
//
|
|
1123
|
-
// AND IT IS OWNED BY ONE `catch`, NOT BY THE PROBE (orcacode-review, second report on
|
|
1124
|
-
// this function). The probe's own restore covered the case it was written for — the
|
|
1125
|
-
// lock being broken between the renames — and nothing else. `rename(staging, dest)`
|
|
1126
|
-
// has a whole other family of failures: EACCES/EPERM/EIO on a store that just went
|
|
1127
|
-
// read-only or is being indexed, a Windows handle on the directory we have only this
|
|
1128
|
-
// moment finished writing, ENOTEMPTY if `dest` reappeared. On any of those the lock is
|
|
1129
|
-
// still perfectly ours, so `abortUnlessOurs` never runs, and `swapStagedRun` throws.
|
|
1130
|
-
//
|
|
1131
|
-
// The caller could not cover it either, and that is the part worth stating plainly:
|
|
1132
|
-
// `movedAside` is a local, so `movedAside = await swapStagedRun(...)` does not assign
|
|
1133
|
-
// on a throw. The caller's copy is still `false`, `revertStagedSwap` is told
|
|
1134
|
-
// `existing: false`, and it dutifully puts nothing back. On-disk result: `<run>` gone,
|
|
1135
|
-
// the user's only copy at `<run>.replaced` — invisible to list, show, events,
|
|
1136
|
-
// checkpoints, export, scrub, gc and push, because it matches no RUN_ID_PATTERN — and
|
|
1137
|
-
// the freshly staged replacement deleted. Exactly the vanished run this sequence's
|
|
1138
|
-
// comments exist to rule out, and exactly what `revertStagedSwap`'s own comment
|
|
1139
|
-
// promises cannot happen ("the caller is about to be told the pull did not happen, and
|
|
1140
|
-
// that has to be true of the store as well as of the message").
|
|
1141
|
-
//
|
|
1142
|
-
// A function cannot both return a value and throw, so the doc's promise — "returns
|
|
1143
|
-
// whether the old run was moved aside, so the caller's revert knows whether it is
|
|
1144
|
-
// entitled to move anything back" — is unkeepable on the failure path BY
|
|
1145
|
-
// CONSTRUCTION. So the failure path stops depending on the caller: every exit from
|
|
1146
|
-
// here that is not the completed swap restores the move-aside itself, and the return
|
|
1147
|
-
// value now only tells a SUCCESSFUL caller whether there is a `retired` directory left
|
|
1148
|
-
// to remove. One place undoes the move, and it covers every throw rather than the one
|
|
1149
|
-
// that was reported.
|
|
1150
|
-
const abortUnlessOurs = async (): Promise<void> => {
|
|
1151
|
-
if (await stillHeld()) return;
|
|
1152
|
-
throw lostTheLock();
|
|
1153
|
-
};
|
|
1154
|
-
|
|
1155
|
-
await abortUnlessOurs();
|
|
1156
|
-
if (existing) {
|
|
1157
|
-
await rename(dest, retired);
|
|
1158
|
-
movedAside = true;
|
|
1159
|
-
}
|
|
1160
|
-
try {
|
|
1161
|
-
await abortUnlessOurs();
|
|
1162
|
-
await rename(staging, dest);
|
|
1163
|
-
} catch (err) {
|
|
1164
|
-
// Best-effort by necessity: if the rename failed because `dest` came back, this
|
|
1165
|
-
// fails too and `<run>.replaced` stays for `recoverInterruptedSwap` to reclaim.
|
|
1166
|
-
// Litter that a later `agenticreplay pull` puts right, not a run nothing can reach.
|
|
1167
|
-
if (movedAside) await rename(retired, dest).catch(() => undefined);
|
|
1168
|
-
throw err;
|
|
1169
|
-
}
|
|
1170
|
-
return movedAside;
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
/**
|
|
1174
|
-
* pull — fetch a gateway run into the local store.
|
|
1175
|
-
*
|
|
1176
|
-
* `agenticreplay pull <run> [--gateway URL] [--force]`
|
|
1177
|
-
*/
|
|
1178
|
-
|
|
1179
|
-
/**
|
|
1180
|
-
* Spec §6: "Readers SHOULD verify it and MUST report, not repair, a mismatch."
|
|
1181
|
-
*
|
|
1182
|
-
* Nothing did. `verifyIntegrity` existed and `replay` called it; `pull` wrote a run to disk and
|
|
1183
|
-
* said `pull.done`. A truncated download, a proxy that re-encoded the stream, an archive that lost
|
|
1184
|
-
* a byte — every one of them landed silently, and the first sign would be a replay that diverged
|
|
1185
|
-
* for no reason anyone could name.
|
|
1186
|
-
*
|
|
1187
|
-
* Checked on the STAGED copy, before the swap: a corrupt transfer must not be what replaces a local
|
|
1188
|
-
* run that `--force` merely asked to update.
|
|
1189
|
-
*/
|
|
1190
|
-
async function verifyStaged(staging: string, runId: string): Promise<string | undefined> {
|
|
1191
|
-
const manifestPath = join(staging, 'manifest.json');
|
|
1192
|
-
const raw = await readFile(manifestPath, 'utf8').catch(() => undefined);
|
|
1193
|
-
if (raw === undefined) return undefined;
|
|
1194
|
-
let expected: unknown;
|
|
1195
|
-
try {
|
|
1196
|
-
expected = (JSON.parse(raw) as { integrity?: { events_sha256?: unknown } }).integrity
|
|
1197
|
-
?.events_sha256;
|
|
1198
|
-
} catch {
|
|
1199
|
-
throw new Error(`${runId}: the manifest that arrived is not JSON`);
|
|
1200
|
-
}
|
|
1201
|
-
// An unsealed run — one whose recorder crashed — has no root to check. Spec §6 describes the
|
|
1202
|
-
// root as written "at the moment the run ended", so its absence is a state, not a failure.
|
|
1203
|
-
if (typeof expected !== 'string') return undefined;
|
|
1204
|
-
const actual = await sha256File(join(staging, 'events.jsonl'));
|
|
1205
|
-
if (actual !== expected) {
|
|
1206
|
-
throw new Error(
|
|
1207
|
-
`${runId}: events.jsonl does not match the integrity root in its own manifest ` +
|
|
1208
|
-
`(manifest ${expected.slice(0, 16)}…, file ${actual.slice(0, 16)}…). Nothing was ` +
|
|
1209
|
-
'replaced. Pull it again; if it persists the copy on the gateway is damaged.',
|
|
1210
|
-
);
|
|
1211
|
-
}
|
|
1212
|
-
return actual;
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
/** Every event, in order, with keys sorted deeply — so two serialisations of one run compare equal. */
|
|
1216
|
-
async function canonicalEvents(dir: string): Promise<string | undefined> {
|
|
1217
|
-
const raw = await readFile(join(dir, 'events.jsonl'), 'utf8').catch(() => undefined);
|
|
1218
|
-
if (raw === undefined) return undefined;
|
|
1219
|
-
const sortDeep = (v: unknown): unknown => {
|
|
1220
|
-
if (Array.isArray(v)) return v.map(sortDeep);
|
|
1221
|
-
if (v === null || typeof v !== 'object') return v;
|
|
1222
|
-
const out: Record<string, unknown> = {};
|
|
1223
|
-
for (const k of Object.keys(v as Record<string, unknown>).sort())
|
|
1224
|
-
out[k] = sortDeep((v as Record<string, unknown>)[k]);
|
|
1225
|
-
return out;
|
|
1226
|
-
};
|
|
1227
|
-
try {
|
|
1228
|
-
return raw
|
|
1229
|
-
.split('\n')
|
|
1230
|
-
.filter((l) => l.trim().length > 0)
|
|
1231
|
-
.map((l) => JSON.stringify(sortDeep(JSON.parse(l))))
|
|
1232
|
-
.join('\n');
|
|
1233
|
-
} catch {
|
|
1234
|
-
return undefined;
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
/**
|
|
1239
|
-
* Whether the copy that arrived is the copy that was pushed.
|
|
1240
|
-
*
|
|
1241
|
-
* A gateway is free to store the trace however it likes, and this one re-serialises it: Go's
|
|
1242
|
-
* `encoding/json` sorts the keys of a map and escapes `<`, `>` and `&`, so the bytes come back
|
|
1243
|
-
* different and the root in the manifest is the root of THOSE bytes. Both copies are internally
|
|
1244
|
-
* consistent, and neither is wrong — but the digest no longer tells you the two are the same run,
|
|
1245
|
-
* which is the one question a digest is for.
|
|
1246
|
-
*
|
|
1247
|
-
* So say which it is. Identical content under a different serialisation is worth a line; content
|
|
1248
|
-
* that actually differs is worth a loud one.
|
|
1249
|
-
*/
|
|
1250
|
-
async function reportAgainstLocal(
|
|
1251
|
-
out: Output,
|
|
1252
|
-
runId: string,
|
|
1253
|
-
localDir: string,
|
|
1254
|
-
stagedDir: string,
|
|
1255
|
-
stagedRoot: string | undefined,
|
|
1256
|
-
): Promise<void> {
|
|
1257
|
-
const localRaw = await readFile(join(localDir, 'manifest.json'), 'utf8').catch(() => undefined);
|
|
1258
|
-
if (localRaw === undefined || stagedRoot === undefined) return;
|
|
1259
|
-
let localRoot: unknown;
|
|
1260
|
-
try {
|
|
1261
|
-
localRoot = (JSON.parse(localRaw) as { integrity?: { events_sha256?: unknown } }).integrity
|
|
1262
|
-
?.events_sha256;
|
|
1263
|
-
} catch {
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
if (typeof localRoot !== 'string' || localRoot === stagedRoot) return;
|
|
1267
|
-
|
|
1268
|
-
const [a, b] = await Promise.all([canonicalEvents(localDir), canonicalEvents(stagedDir)]);
|
|
1269
|
-
const fields = {
|
|
1270
|
-
run: runId,
|
|
1271
|
-
local: `${localRoot.slice(0, 16)}…`,
|
|
1272
|
-
pulled: `${stagedRoot.slice(0, 16)}…`,
|
|
1273
|
-
};
|
|
1274
|
-
if (a !== undefined && b !== undefined && a === b) {
|
|
1275
|
-
out.warn('pull.reserialized', {
|
|
1276
|
-
...fields,
|
|
1277
|
-
why: 'same events, different bytes — the gateway stores its own serialisation and recomputes the root over it',
|
|
1278
|
-
effect: 'the two copies can no longer be compared by digest, though nothing was lost',
|
|
1279
|
-
});
|
|
1280
|
-
return;
|
|
1281
|
-
}
|
|
1282
|
-
out.warn('pull.differs', {
|
|
1283
|
-
...fields,
|
|
1284
|
-
why: 'the events themselves differ, not just how they were written',
|
|
1285
|
-
next: `agenticreplay show ${runId} # the copy that just replaced the local one`,
|
|
1286
|
-
});
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
export async function pullCommand(
|
|
1290
|
-
args: ParsedArgs,
|
|
1291
|
-
out: Output,
|
|
1292
|
-
cwd = process.cwd(),
|
|
1293
|
-
env: NodeJS.ProcessEnv = process.env,
|
|
1294
|
-
): Promise<void> {
|
|
1295
|
-
const { url, headers } = await resolveGateway(args, env, 'pull');
|
|
1296
|
-
const runKey = args.positionals[0];
|
|
1297
|
-
if (!runKey) {
|
|
1298
|
-
throw new Error('pull needs the run to fetch: `agenticreplay pull <run-id>`');
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
// RECOVER BEFORE THE NETWORK, NOT AFTER IT.
|
|
1302
|
-
//
|
|
1303
|
-
// The archive names its own run, so the authoritative recovery is the one below, keyed on the id
|
|
1304
|
-
// that came back. But a store left half-swapped by a killed process must not stay that way just
|
|
1305
|
-
// because THIS pull fails — an unreachable gateway, a 404, an empty archive — and the run in that
|
|
1306
|
-
// state is invisible to every other command, so nothing else would ever reclaim it. When the
|
|
1307
|
-
// selector is itself a run id (the common case: you pull the run you just failed to pull), this
|
|
1308
|
-
// heals it first and costs one stat. runDirFor rejects anything that is not a run id, which is
|
|
1309
|
-
// the path-traversal guard, so a selector that is not one simply skips this.
|
|
1310
|
-
// The store has to exist before anything can take a lock file inside it, so this runs ahead of
|
|
1311
|
-
// the early recovery rather than beside the staging code it also protects.
|
|
1312
|
-
await ensureRunsDir(cwd);
|
|
1313
|
-
|
|
1314
|
-
try {
|
|
1315
|
-
const early = runDirFor(cwd, runKey);
|
|
1316
|
-
await withRunLock(early, (stillHeld) => recoverInterruptedSwap(early, stillHeld));
|
|
1317
|
-
} catch {
|
|
1318
|
-
// Not a run id — the post-fetch recovery below is the one that matters anyway.
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
const res = await fetchPinned(`${url}${exportPath(runKey)}`, { headers });
|
|
1322
|
-
if (!res.ok) throw new Error(refusal(res.status, await res.text()));
|
|
1323
|
-
|
|
1324
|
-
// The gateway sets this when it could not store the recording whole. Pulling one is allowed —
|
|
1325
|
-
// half a trace still debugs — but every command downstream will read the result as if it were
|
|
1326
|
-
// complete, so the warning is not optional.
|
|
1327
|
-
if (res.headers.get('x-agenticreplay-run-truncated') === 'true') {
|
|
1328
|
-
out.warn('pull.truncated', {
|
|
1329
|
-
run: runKey,
|
|
1330
|
-
detail: 'the gateway stored this recording incompletely; events may be missing',
|
|
1331
|
-
});
|
|
1332
|
-
}
|
|
1333
|
-
|
|
1334
|
-
const entries = await readArchive(new Uint8Array(await res.arrayBuffer()));
|
|
1335
|
-
if (entries.length === 0) throw new Error(`the gateway returned an empty archive for ${runKey}`);
|
|
1336
|
-
|
|
1337
|
-
// The archive names its own run, and that name is what the local store keys on — not the
|
|
1338
|
-
// selector typed on the command line, which may be an abbreviation or the gateway's own key for
|
|
1339
|
-
// a run whose manifest calls it something else.
|
|
1340
|
-
const runId = entries[0]!.name.split('/')[0] ?? runKey;
|
|
1341
|
-
// runDirFor, not a join: its run-id pattern check IS the path-traversal guard (see its note in
|
|
1342
|
-
// packages/core/src/paths.ts), and the id here came off the wire. readArchive already refuses an
|
|
1343
|
-
// entry name that would escape, so this is the second of two independent checks on a value the
|
|
1344
|
-
// gateway chose — which is the right number for one that becomes a filesystem path.
|
|
1345
|
-
// (ensureRunsDir ran above, before the first lock.) THE STORE ON THE STORE'S OWN TERMS (codex round 3 P1).
|
|
1346
|
-
//
|
|
1347
|
-
// record, attach and replay all create `.agenticreplay/runs` through ensureRunsDir; pull wrote into it
|
|
1348
|
-
// with a bare recursive mkdir and inherited none of what that function is for. Two things were
|
|
1349
|
-
// lost, and both matter most in the case pull exists for — a fresh clone with no recording yet,
|
|
1350
|
-
// where pull is what creates the store:
|
|
1351
|
-
//
|
|
1352
|
-
// - the 0700 directory and 0600 files SECURITY.md promises. A default umask gives 0755/0644,
|
|
1353
|
-
// so a pulled trace — the gateway's copy of source, shell output and workspace snapshots —
|
|
1354
|
-
// was world-readable on a shared machine.
|
|
1355
|
-
// - `.agenticreplay/.gitignore` containing `*`, git's own idiom for a directory that excludes itself.
|
|
1356
|
-
// Without it the whole store lands in `git status` as untracked, one `git add -A` from being
|
|
1357
|
-
// committed and pushed. That is the accident ensureRunsDir was written to prevent.
|
|
1358
|
-
const dest = runDirFor(cwd, runId);
|
|
1359
|
-
|
|
1360
|
-
// Finish or roll back whatever a previous, interrupted pull of this run left behind, BEFORE
|
|
1361
|
-
// deciding whether the run exists — otherwise a run stranded by a crash reads as absent and the
|
|
1362
|
-
// stranded copy is never reclaimed.
|
|
1363
|
-
// ONE LOCK OVER RECOVERY, STAGING AND THE SWAP.
|
|
1364
|
-
//
|
|
1365
|
-
// These three steps are one critical section: recovery decides what exists, staging writes the
|
|
1366
|
-
// new copy under a name another pull would also use, and the swap moves both. Locking only the
|
|
1367
|
-
// swap would leave recovery free to delete what staging just wrote.
|
|
1368
|
-
await withRunLock(dest, async (stillHeld) => {
|
|
1369
|
-
await recoverInterruptedSwap(dest, stillHeld);
|
|
1370
|
-
|
|
1371
|
-
// AND THE DECISION THAT FOLLOWS IT BELONGS TO THIS PULL TOO. Recovery declining to act (above)
|
|
1372
|
-
// is not enough on its own: `existing` and the `--force` check below read state that, once the
|
|
1373
|
-
// lock has moved, describes the NEW holder's run. Asking here turns a resumed pull into a
|
|
1374
|
-
// clean "re-run the pull" rather than a confusing "already exists locally" about someone
|
|
1375
|
-
// else's copy — and stops it staging over them.
|
|
1376
|
-
if (!(await stillHeld())) throw lostTheLock();
|
|
1377
|
-
|
|
1378
|
-
const existing = await stat(dest).catch(() => undefined);
|
|
1379
|
-
if (existing && !args.bool('force')) {
|
|
1380
|
-
throw new Error(
|
|
1381
|
-
`${runId} already exists locally. Pass --force to replace it, or move it aside first.`,
|
|
1382
|
-
);
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
// STAGE, THEN SWAP — AND MAKE THE SWAP RECOVERABLE, not merely exception-safe.
|
|
1386
|
-
//
|
|
1387
|
-
// Deleting the old run and writing the new one in its place means anything that fails in between
|
|
1388
|
-
// leaves the run neither the old one nor the new one. The recording is the artifact, and it may
|
|
1389
|
-
// be the only copy of a crash someone spent a day reproducing; `--force` asks to REPLACE it,
|
|
1390
|
-
// which is not a licence to destroy it and then fail.
|
|
1391
|
-
//
|
|
1392
|
-
// Staging alone does not finish the job, because POSIX will not rename a directory over a
|
|
1393
|
-
// non-empty one: the old run must be moved aside first, so there is a window of two syscalls in
|
|
1394
|
-
// which `dest` does not exist. try/catch covers a thrown error and NOTHING ELSE — SIGKILL, ^C
|
|
1395
|
-
// and power loss all land in that window, and the earlier version of this code claimed otherwise.
|
|
1396
|
-
// Worse, the names were randomised, and neither matches RUN_ID_PATTERN (`run_[0-9a-f]{6,32}`
|
|
1397
|
-
// admits no `.`), so `list`, `show`, `gc`, `scrub` and `resolveRunSelector` all skip them: the
|
|
1398
|
-
// run had not moved, it had VANISHED, with a possibly secret-bearing copy stranded out of
|
|
1399
|
-
// scrub's reach and nothing that would ever sweep it.
|
|
1400
|
-
//
|
|
1401
|
-
// So the scratch names are DETERMINISTIC per destination, which is what makes the half-done
|
|
1402
|
-
// state recoverable rather than merely invisible, and `recoverInterruptedSwap` below runs before
|
|
1403
|
-
// every pull to finish or roll back whatever the last one left. Determinism costs one thing —
|
|
1404
|
-
// two concurrent pulls of the same run share the scratch names — and buys back the case the
|
|
1405
|
-
// reviewer named: a run that no command can reach again. Those two pulls already raced over
|
|
1406
|
-
// `dest` itself; a race is recoverable, a disappearance is not.
|
|
1407
|
-
const staging = `${dest}.incoming`;
|
|
1408
|
-
const retired = `${dest}.replaced`;
|
|
1409
|
-
// Declared out here so the catch can read it: whether WE moved the old run
|
|
1410
|
-
// aside decides whether the revert may move anything back.
|
|
1411
|
-
let movedAside = false;
|
|
1412
|
-
|
|
1413
|
-
try {
|
|
1414
|
-
await stageRunEntries(entries, runId, staging, stillHeld);
|
|
1415
|
-
|
|
1416
|
-
// Before the swap, never after: what fails verification must not be what replaced the run.
|
|
1417
|
-
const stagedRoot = await verifyStaged(staging, runId);
|
|
1418
|
-
if (existing) await reportAgainstLocal(out, runId, dest, staging, stagedRoot);
|
|
1419
|
-
|
|
1420
|
-
movedAside = await swapStagedRun({ dest, staging, retired, existing: !!existing }, stillHeld);
|
|
1421
|
-
} catch (err) {
|
|
1422
|
-
await revertStagedSwap(stillHeld, { dest, staging, retired, existing: movedAside });
|
|
1423
|
-
throw err;
|
|
1424
|
-
}
|
|
1425
|
-
await rm(retired, { recursive: true, force: true });
|
|
1426
|
-
});
|
|
1427
|
-
|
|
1428
|
-
out.phase('pull.done', { run: runId, files: entries.length, dir: dest });
|
|
1429
|
-
}
|