airaknit 1.1.2-rc.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +84 -0
- package/README.md +202 -0
- package/bin/airaknit +9 -0
- package/bin/airaknit-project +14 -0
- package/bin/kanna +9 -0
- package/dist/client/assets/CompactSummaryMessage-Yw0BDWEJ.js +1 -0
- package/dist/client/assets/ExitPlanModeMessage-DIdkQ4uF.js +1 -0
- package/dist/client/assets/LocalFilePreviewDialog-DQx2eiCc.js +3 -0
- package/dist/client/assets/LocalProjectsSection-C4xlWkgS.js +1 -0
- package/dist/client/assets/TextMessage-B5G39DEJ.js +1 -0
- package/dist/client/assets/UserMessage-CIkWk-0L.js +1 -0
- package/dist/client/assets/_basePickBy-CVrAFfnZ.js +1 -0
- package/dist/client/assets/_baseUniq-JL-aaF4P.js +1 -0
- package/dist/client/assets/arc-B07zg7ol.js +1 -0
- package/dist/client/assets/architecture-YZFGNWBL-PSLVJL3p.js +1 -0
- package/dist/client/assets/architectureDiagram-Q4EWVU46-DfWIF1G_.js +36 -0
- package/dist/client/assets/array-BGFCBI0e.js +1 -0
- package/dist/client/assets/blockDiagram-DXYQGD6D-CzwIeo_B.js +132 -0
- package/dist/client/assets/bundle-mjs-BDE2gWbQ.js +1 -0
- package/dist/client/assets/button-DO50qOGv.js +1 -0
- package/dist/client/assets/c4Diagram-AHTNJAMY-CR8DCQRE.js +10 -0
- package/dist/client/assets/channel-Dj-UUfaF.js +1 -0
- package/dist/client/assets/chunk-2KRD3SAO-dznP-cn8.js +1 -0
- package/dist/client/assets/chunk-336JU56O-Dqss5Vu6.js +2 -0
- package/dist/client/assets/chunk-426QAEUC-CEKis_0_.js +1 -0
- package/dist/client/assets/chunk-4BX2VUAB-BYOv0Gm1.js +1 -0
- package/dist/client/assets/chunk-4TB4RGXK-BxzubH5S.js +206 -0
- package/dist/client/assets/chunk-55IACEB6-BSlTj03a.js +1 -0
- package/dist/client/assets/chunk-5FUZZQ4R-9Au93Bi1.js +62 -0
- package/dist/client/assets/chunk-5PVQY5BW-BhksHFEZ.js +2 -0
- package/dist/client/assets/chunk-67CJDMHE-BFwhz-8t.js +1 -0
- package/dist/client/assets/chunk-7N4EOEYR-BDUPds87.js +1 -0
- package/dist/client/assets/chunk-AA7GKIK3-CEWTdyXO.js +1 -0
- package/dist/client/assets/chunk-BO2N2NFS-D0LvxnhU.js +103 -0
- package/dist/client/assets/chunk-BSJP7CBP-BNJnK6sq.js +1 -0
- package/dist/client/assets/chunk-Bj-mKKzh.js +1 -0
- package/dist/client/assets/chunk-CIAEETIT-CYhfoCeN.js +1 -0
- package/dist/client/assets/chunk-EDXVE4YY-C5ovJLc0.js +1 -0
- package/dist/client/assets/chunk-ENJZ2VHE-HOhYaeGr.js +10 -0
- package/dist/client/assets/chunk-FMBD7UC4-BLCiKcAQ.js +15 -0
- package/dist/client/assets/chunk-FOC6F5B3-B6GtY2ek.js +1 -0
- package/dist/client/assets/chunk-ICPOFSXX-DPoIZoC5.js +122 -0
- package/dist/client/assets/chunk-K5T4RW27-BsKN63rv.js +94 -0
- package/dist/client/assets/chunk-KGLVRYIC-BUGn9uuY.js +1 -0
- package/dist/client/assets/chunk-LIHQZDEY-DhaZyo03.js +1 -0
- package/dist/client/assets/chunk-ORNJ4GCN-DlpeeJyi.js +1 -0
- package/dist/client/assets/chunk-OYMX7WX6-Dc9q7aYA.js +231 -0
- package/dist/client/assets/chunk-QZHKN3VN-BEdrPoSb.js +1 -0
- package/dist/client/assets/chunk-U2HBQHQK-CIB3Bjjd.js +70 -0
- package/dist/client/assets/chunk-X2U36JSP-CtB-o8Yp.js +1 -0
- package/dist/client/assets/chunk-XPW4576I-C6iHhX_8.js +32 -0
- package/dist/client/assets/chunk-YZCP3GAM-CTmKr6ZH.js +1 -0
- package/dist/client/assets/chunk-ZZ45TVLE-BgU8A2RF.js +1 -0
- package/dist/client/assets/classDiagram-6PBFFD2Q-Bqk5e679.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-6pSaZOkC.js +1 -0
- package/dist/client/assets/client-BrKWI4CM.js +1 -0
- package/dist/client/assets/client-CGgNRU9w.js +1 -0
- package/dist/client/assets/client-DMSLRzg9.js +6 -0
- package/dist/client/assets/clone-DWcL7whJ.js +1 -0
- package/dist/client/assets/cose-bilkent-S5V4N54A-CrV5wsV_.js +1 -0
- package/dist/client/assets/cytoscape.esm--aLzKuep.js +321 -0
- package/dist/client/assets/dagre-CuRxWcrj.js +1 -0
- package/dist/client/assets/dagre-KV5264BT-BIDiVnkA.js +4 -0
- package/dist/client/assets/defaultLocale-CRZydyG6.js +1 -0
- package/dist/client/assets/diagram-5BDNPKRD-i1kjKRCB.js +10 -0
- package/dist/client/assets/diagram-G4DWMVQ6-9ZSLuhbl.js +24 -0
- package/dist/client/assets/diagram-MMDJMWI5-B4_CUjgv.js +43 -0
- package/dist/client/assets/diagram-TYMM5635-Ct5eTGS8.js +24 -0
- package/dist/client/assets/dist-CuB4kiSK.js +1 -0
- package/dist/client/assets/erDiagram-SMLLAGMA-Cy38ercc.js +85 -0
- package/dist/client/assets/flowDiagram-DWJPFMVM-CZKuYl0V.js +162 -0
- package/dist/client/assets/ganttDiagram-T4ZO3ILL-DLPjCh7a.js +292 -0
- package/dist/client/assets/gitGraph-7Q5UKJZL-DqbrtEp9.js +1 -0
- package/dist/client/assets/gitGraphDiagram-UUTBAWPF-BoRBkDhQ.js +106 -0
- package/dist/client/assets/graphlib-BcQ6qlQh.js +1 -0
- package/dist/client/assets/highlighted-body-OFNGDK62-BEpBVDTX.js +1 -0
- package/dist/client/assets/index-CetCiuqP.js +105 -0
- package/dist/client/assets/index-N29Mip7A.css +1 -0
- package/dist/client/assets/info-OMHHGYJF-D98DRBJX.js +1 -0
- package/dist/client/assets/infoDiagram-42DDH7IO-BAcdTWbt.js +2 -0
- package/dist/client/assets/init-B8gtcn7T.js +1 -0
- package/dist/client/assets/isArrayLikeObject-D8SJFmkN.js +1 -0
- package/dist/client/assets/isEmpty-BF3YX5Jk.js +1 -0
- package/dist/client/assets/ishikawaDiagram-UXIWVN3A-Ynu2VKdC.js +70 -0
- package/dist/client/assets/journeyDiagram-VCZTEJTY-BjfhQaN3.js +139 -0
- package/dist/client/assets/jsx-runtime-CyI9ICYU.js +1 -0
- package/dist/client/assets/kanban-definition-6JOO6SKY-JLXH9zUJ.js +89 -0
- package/dist/client/assets/katex-B94qP8b6.js +265 -0
- package/dist/client/assets/lib--QVjyxmL.js +29 -0
- package/dist/client/assets/lib-B6rgJiZ9.js +1 -0
- package/dist/client/assets/line-DCrYfLBn.js +1 -0
- package/dist/client/assets/linear-_4upLmeo.js +1 -0
- package/dist/client/assets/mermaid-GHXKKRXX-rwJHYUmW.js +1 -0
- package/dist/client/assets/mermaid-parser.core-KZinfW8o.js +4 -0
- package/dist/client/assets/mermaid.core-QqY9gSNe.js +11 -0
- package/dist/client/assets/mindmap-definition-QFDTVHPH-TWgHDAzp.js +96 -0
- package/dist/client/assets/ordinal-CCj7PWgZ.js +1 -0
- package/dist/client/assets/packet-4T2RLAQJ-DEvfkn3F.js +1 -0
- package/dist/client/assets/path-DZF-JdEe.js +1 -0
- package/dist/client/assets/pie-ZZUOXDRM-72e6WVjb.js +1 -0
- package/dist/client/assets/pieDiagram-DEJITSTG-Cl8PCsoj.js +30 -0
- package/dist/client/assets/preload-helper-rov5CBGT.js +1 -0
- package/dist/client/assets/pty-client-DZ27IS00.js +1 -0
- package/dist/client/assets/ptyInstancesStore-D9ag7SYd.js +1 -0
- package/dist/client/assets/quadrantDiagram-34T5L4WZ-CHyVGp9E.js +7 -0
- package/dist/client/assets/radar-PYXPWWZC-Cp7xd_EY.js +1 -0
- package/dist/client/assets/react-CClhXMB2.js +1 -0
- package/dist/client/assets/react-Dd6D81m0.js +1 -0
- package/dist/client/assets/react-dom--G6_6fQ_.js +1 -0
- package/dist/client/assets/requirementDiagram-MS252O5E-DaanG2iM.js +84 -0
- package/dist/client/assets/rough.esm-BsmKo2S5.js +1 -0
- package/dist/client/assets/sankeyDiagram-XADWPNL6-B_fhLY36.js +10 -0
- package/dist/client/assets/sequenceDiagram-FGHM5R23-C5FNrveI.js +157 -0
- package/dist/client/assets/src-DeTlMJAU.js +1 -0
- package/dist/client/assets/stateDiagram-FHFEXIEX-nTTcdjjQ.js +1 -0
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Dw0632j_.js +1 -0
- package/dist/client/assets/timeline-definition-GMOUNBTQ-DkQV1yP8.js +120 -0
- package/dist/client/assets/treeView-SZITEDCU-ZLIgC7_K.js +1 -0
- package/dist/client/assets/treemap-W4RFUUIX-BqaMbB6N.js +1 -0
- package/dist/client/assets/uiIdentityOverlay-Ba7GNj7m.js +1 -0
- package/dist/client/assets/vennDiagram-DHZGUBPP-DbZ2xgs6.js +34 -0
- package/dist/client/assets/wardley-RL74JXVD-DXQS8zf4.js +1 -0
- package/dist/client/assets/wardleyDiagram-NUSXRM2D-BzCJ6MAu.js +20 -0
- package/dist/client/assets/xychartDiagram-5P7HB3ND-BSlFecop.js +7 -0
- package/dist/client/favicon.png +0 -0
- package/dist/client/favicon.svg +15 -0
- package/dist/client/fonts/body-medium.woff2 +0 -0
- package/dist/client/fonts/body-regular-italic.woff2 +0 -0
- package/dist/client/fonts/body-regular.woff2 +0 -0
- package/dist/client/fonts/body-semibold.woff2 +0 -0
- package/dist/client/index.html +31 -0
- package/dist/client/manifest.webmanifest +12 -0
- package/dist/client/sw.js +32 -0
- package/package.json +122 -0
- package/src/nats/auth-callout/callout-config.test.ts +93 -0
- package/src/nats/auth-callout/callout-config.ts +109 -0
- package/src/nats/auth-callout/callout.integration.test.ts +332 -0
- package/src/nats/auth-callout/keys.ts +103 -0
- package/src/nats/auth-callout/responder.ts +241 -0
- package/src/nats/auth-callout/scope-policy.test.ts +159 -0
- package/src/nats/auth-callout/scope-policy.ts +210 -0
- package/src/nats/auth-callout/token.test.ts +163 -0
- package/src/nats/auth-callout/token.ts +157 -0
- package/src/nats/nats-daemon-callout.ts +194 -0
- package/src/nats/nats-daemon.test.ts +77 -0
- package/src/nats/nats-daemon.ts +50 -0
- package/src/nats/nats-token.test.ts +61 -0
- package/src/nats/nats-token.ts +59 -0
- package/src/runner/coordination-mcp-integration.test.ts +134 -0
- package/src/runner/nats-coordination-client.test.ts +49 -0
- package/src/runner/nats-coordination-client.ts +94 -0
- package/src/runner/runner-agent.test.ts +469 -0
- package/src/runner/runner-agent.ts +453 -0
- package/src/runner/runner-credential.test.ts +93 -0
- package/src/runner/runner-credential.ts +82 -0
- package/src/runner/runner-nats.test.ts +495 -0
- package/src/runner/runner-nats.ts +323 -0
- package/src/runner/runner-pair.test.ts +107 -0
- package/src/runner/runner-pair.ts +81 -0
- package/src/runner/runner.test.ts +135 -0
- package/src/runner/runner.ts +212 -0
- package/src/runner/turn-factories.test.ts +97 -0
- package/src/runner/turn-factories.ts +475 -0
- package/src/server/agent-config-journey.test.ts +106 -0
- package/src/server/agent.ts +8 -0
- package/src/server/auto-continue/auth-error-detector.ts +66 -0
- package/src/server/auto-continue/limit-detector.ts +194 -0
- package/src/server/bm25.test.ts +92 -0
- package/src/server/bm25.ts +101 -0
- package/src/server/chat-events-jetstream.test.ts +135 -0
- package/src/server/claude-harness.ts +360 -0
- package/src/server/claude-pty/agent-normalizers.ts +309 -0
- package/src/server/claude-pty/auth.test.ts +38 -0
- package/src/server/claude-pty/auth.ts +32 -0
- package/src/server/claude-pty/claude-session-registry.adapter.ts +81 -0
- package/src/server/claude-pty/claude-session-registry.test.ts +149 -0
- package/src/server/claude-pty/driver.test.ts +902 -0
- package/src/server/claude-pty/driver.ts +807 -0
- package/src/server/claude-pty/jsonl-path.adapter.ts +57 -0
- package/src/server/claude-pty/jsonl-path.test.ts +114 -0
- package/src/server/claude-pty/jsonl-to-event.test.ts +241 -0
- package/src/server/claude-pty/jsonl-to-event.ts +174 -0
- package/src/server/claude-pty/output-ring.test.ts +35 -0
- package/src/server/claude-pty/output-ring.ts +25 -0
- package/src/server/claude-pty/parity-matrix.test.ts +227 -0
- package/src/server/claude-pty/pid-registry.adapter.ts +135 -0
- package/src/server/claude-pty/pid-registry.test.ts +122 -0
- package/src/server/claude-pty/preflight/binary-fingerprint.adapter.ts +20 -0
- package/src/server/claude-pty/preflight/binary-fingerprint.test.ts +32 -0
- package/src/server/claude-pty/pty-instance-registry.test.ts +177 -0
- package/src/server/claude-pty/pty-instance-registry.ts +166 -0
- package/src/server/claude-pty/pty-memory-sampler.adapter.test.ts +103 -0
- package/src/server/claude-pty/pty-memory-sampler.adapter.ts +85 -0
- package/src/server/claude-pty/pty-process.adapter.ts +66 -0
- package/src/server/claude-pty/pty-process.test.ts +49 -0
- package/src/server/claude-pty/resolve-binary.adapter.ts +106 -0
- package/src/server/claude-pty/resolve-binary.test.ts +118 -0
- package/src/server/claude-pty/runtime-dir.adapter.ts +19 -0
- package/src/server/claude-pty/settings-writer.adapter.ts +27 -0
- package/src/server/claude-pty/settings-writer.test.ts +22 -0
- package/src/server/claude-pty/smoke-test-io.adapter.ts +28 -0
- package/src/server/claude-pty/smoke-test.test.ts +191 -0
- package/src/server/claude-pty/smoke-test.ts +185 -0
- package/src/server/claude-pty/subagent-orchestrator.ts +887 -0
- package/src/server/claude-pty/tool-callback.ts +274 -0
- package/src/server/claude-pty/tui-control.test.ts +272 -0
- package/src/server/claude-pty/tui-control.ts +182 -0
- package/src/server/claude-pty/tui-source.adapter.test.ts +360 -0
- package/src/server/claude-pty/tui-source.adapter.ts +343 -0
- package/src/server/claude-pty/tunnel-gateway.ts +12 -0
- package/src/server/claude-pty-mcp/canonical-args.ts +15 -0
- package/src/server/claude-pty-mcp/fs-stat.adapter.ts +8 -0
- package/src/server/claude-pty-mcp/history-primer.ts +90 -0
- package/src/server/claude-pty-mcp/http-server.adapter.ts +33 -0
- package/src/server/claude-pty-mcp/mcp-http.ts +177 -0
- package/src/server/claude-pty-mcp/mcp.ts +412 -0
- package/src/server/claude-pty-mcp/mention-parser.ts +25 -0
- package/src/server/claude-pty-mcp/paths.ts +24 -0
- package/src/server/claude-pty-mcp/permission-gate.ts +243 -0
- package/src/server/claude-pty-mcp/terminal-pid-registry.adapter.ts +107 -0
- package/src/server/claude-pty-mcp/tools/ask-user-question.test.ts +119 -0
- package/src/server/claude-pty-mcp/tools/ask-user-question.ts +61 -0
- package/src/server/claude-pty-mcp/tools/bash.adapter.ts +76 -0
- package/src/server/claude-pty-mcp/tools/bash.test.ts +56 -0
- package/src/server/claude-pty-mcp/tools/delegate-subagent.test.ts +155 -0
- package/src/server/claude-pty-mcp/tools/delegate-subagent.ts +111 -0
- package/src/server/claude-pty-mcp/tools/edit.adapter.ts +95 -0
- package/src/server/claude-pty-mcp/tools/edit.test.ts +93 -0
- package/src/server/claude-pty-mcp/tools/exit-plan-mode.test.ts +61 -0
- package/src/server/claude-pty-mcp/tools/exit-plan-mode.ts +50 -0
- package/src/server/claude-pty-mcp/tools/glob.adapter.ts +86 -0
- package/src/server/claude-pty-mcp/tools/glob.test.ts +61 -0
- package/src/server/claude-pty-mcp/tools/grep.adapter.ts +126 -0
- package/src/server/claude-pty-mcp/tools/grep.test.ts +62 -0
- package/src/server/claude-pty-mcp/tools/read.adapter.ts +58 -0
- package/src/server/claude-pty-mcp/tools/read.test.ts +62 -0
- package/src/server/claude-pty-mcp/tools/tool-callback-shim.ts +42 -0
- package/src/server/claude-pty-mcp/tools/webfetch.test.ts +81 -0
- package/src/server/claude-pty-mcp/tools/webfetch.ts +82 -0
- package/src/server/claude-pty-mcp/tools/websearch.test.ts +40 -0
- package/src/server/claude-pty-mcp/tools/websearch.ts +42 -0
- package/src/server/claude-pty-mcp/tools/write.adapter.ts +60 -0
- package/src/server/claude-pty-mcp/tools/write.test.ts +52 -0
- package/src/server/claude-pty-mcp/uploads.adapter.ts +98 -0
- package/src/server/claude-pty-mcp/uploads.ts +38 -0
- package/src/server/claude-turn.test.ts +176 -0
- package/src/server/cli-runtime.test.ts +456 -0
- package/src/server/cli-runtime.ts +374 -0
- package/src/server/cli-supervisor.ts +81 -0
- package/src/server/cli.ts +78 -0
- package/src/server/client-log-forwarder.test.ts +74 -0
- package/src/server/client-log-forwarder.ts +75 -0
- package/src/server/codex-app-server-protocol.ts +449 -0
- package/src/server/codex-app-server.test.ts +2990 -0
- package/src/server/codex-app-server.ts +1713 -0
- package/src/server/coordination-integration.test.ts +63 -0
- package/src/server/coordination-mcp.test.ts +149 -0
- package/src/server/coordination-mcp.ts +197 -0
- package/src/server/delegation-coordinator.test.ts +675 -0
- package/src/server/delegation-coordinator.ts +454 -0
- package/src/server/discovery.test.ts +211 -0
- package/src/server/discovery.ts +301 -0
- package/src/server/event-store-agent-config.test.ts +124 -0
- package/src/server/event-store-coordination.test.ts +149 -0
- package/src/server/event-store-profile.test.ts +132 -0
- package/src/server/event-store-repo.test.ts +154 -0
- package/src/server/event-store-runner-team.test.ts +104 -0
- package/src/server/event-store.test.ts +342 -0
- package/src/server/event-store.ts +2208 -0
- package/src/server/events.ts +379 -0
- package/src/server/extension-router.test.ts +183 -0
- package/src/server/extension-router.ts +114 -0
- package/src/server/extensions/agents/server.test.ts +191 -0
- package/src/server/extensions/agents/server.ts +108 -0
- package/src/server/extensions/c3/server.test.ts +284 -0
- package/src/server/extensions/c3/server.ts +212 -0
- package/src/server/extensions/code/server.test.ts +200 -0
- package/src/server/extensions/code/server.ts +150 -0
- package/src/server/extensions.config.ts +10 -0
- package/src/server/external-open.ts +69 -0
- package/src/server/generate-fork-context.ts +58 -0
- package/src/server/generate-merge-context.test.ts +290 -0
- package/src/server/generate-merge-context.ts +141 -0
- package/src/server/generate-title.ts +36 -0
- package/src/server/git-clone-policy.test.ts +138 -0
- package/src/server/git-clone-policy.ts +27 -0
- package/src/server/harness-types.ts +1 -0
- package/src/server/journey-verification.test.ts +640 -0
- package/src/server/journey-verification.ts +195 -0
- package/src/server/machine-name.ts +22 -0
- package/src/server/nats-auth.test.ts +92 -0
- package/src/server/nats-auth.ts +6 -0
- package/src/server/nats-bind-guard.test.ts +71 -0
- package/src/server/nats-bind-guard.ts +42 -0
- package/src/server/nats-bridge.test.ts +141 -0
- package/src/server/nats-bridge.ts +111 -0
- package/src/server/nats-connector.test.ts +56 -0
- package/src/server/nats-connector.ts +71 -0
- package/src/server/nats-daemon-manager.test.ts +76 -0
- package/src/server/nats-daemon-manager.ts +174 -0
- package/src/server/nats-publisher.test.ts +356 -0
- package/src/server/nats-publisher.ts +271 -0
- package/src/server/nats-responders.test.ts +1018 -0
- package/src/server/nats-responders.ts +925 -0
- package/src/server/nats-streams.test.ts +112 -0
- package/src/server/nats-streams.ts +129 -0
- package/src/server/oauth-pool/oauth-responders.ts +185 -0
- package/src/server/oauth-pool/oauth-settings-store.ts +173 -0
- package/src/server/oauth-pool/oauth-token-pool.ts +303 -0
- package/src/server/orchestration.test.ts +1063 -0
- package/src/server/orchestration.ts +716 -0
- package/src/server/pairing-endpoints.test.ts +171 -0
- package/src/server/pairing-store.test.ts +154 -0
- package/src/server/pairing-store.ts +124 -0
- package/src/server/paths.ts +27 -0
- package/src/server/pr3-liveness.test.ts +252 -0
- package/src/server/process-utils.ts +10 -0
- package/src/server/project-cli.ts +180 -0
- package/src/server/provider-catalog.test.ts +177 -0
- package/src/server/provider-catalog.ts +146 -0
- package/src/server/pty-responders.ts +345 -0
- package/src/server/push-notifications.test.ts +234 -0
- package/src/server/push-notifications.ts +188 -0
- package/src/server/quick-response.test.ts +196 -0
- package/src/server/quick-response.ts +154 -0
- package/src/server/read-models-agent-config.test.ts +59 -0
- package/src/server/read-models-coordination.test.ts +69 -0
- package/src/server/read-models.test.ts +332 -0
- package/src/server/read-models.ts +258 -0
- package/src/server/repo-journey.test.ts +96 -0
- package/src/server/repo-manager.test.ts +118 -0
- package/src/server/repo-manager.ts +97 -0
- package/src/server/repo-status.test.ts +54 -0
- package/src/server/repo-status.ts +82 -0
- package/src/server/restart.test.ts +27 -0
- package/src/server/restart.ts +30 -0
- package/src/server/runner-incompatible-gate.test.ts +383 -0
- package/src/server/runner-manager.test.ts +72 -0
- package/src/server/runner-manager.ts +312 -0
- package/src/server/runner-pairing-urls.test.ts +59 -0
- package/src/server/runner-pairing-urls.ts +67 -0
- package/src/server/runner-proxy.test.ts +456 -0
- package/src/server/runner-proxy.ts +494 -0
- package/src/server/runner-router.test.ts +429 -0
- package/src/server/runner-router.ts +212 -0
- package/src/server/runner-routing.test.ts +584 -0
- package/src/server/runtime-registry.test.ts +436 -0
- package/src/server/runtime-registry.ts +307 -0
- package/src/server/sandbox-health.test.ts +127 -0
- package/src/server/sandbox-health.ts +94 -0
- package/src/server/sandbox-journey.test.ts +232 -0
- package/src/server/sandbox-manager.test.ts +146 -0
- package/src/server/sandbox-manager.ts +159 -0
- package/src/server/server.test.ts +287 -0
- package/src/server/server.ts +1108 -0
- package/src/server/session-discovery.test.ts +129 -0
- package/src/server/session-discovery.ts +475 -0
- package/src/server/session-index.test.ts +362 -0
- package/src/server/session-index.ts +119 -0
- package/src/server/session-seed.ts +288 -0
- package/src/server/share.test.ts +108 -0
- package/src/server/share.ts +113 -0
- package/src/server/skill-discovery.test.ts +201 -0
- package/src/server/skill-discovery.ts +77 -0
- package/src/server/storage/test-helpers.ts +67 -0
- package/src/server/terminal-manager.test.ts +309 -0
- package/src/server/terminal-manager.ts +354 -0
- package/src/server/transcript-consumer.test.ts +339 -0
- package/src/server/transcript-consumer.ts +162 -0
- package/src/server/transcript-search.test.ts +193 -0
- package/src/server/transcript-search.ts +83 -0
- package/src/server/transcript-utils.ts +52 -0
- package/src/server/update-manager.test.ts +107 -0
- package/src/server/update-manager.ts +230 -0
- package/src/server/workflow-engine.test.ts +251 -0
- package/src/server/workflow-engine.ts +169 -0
- package/src/server/workflow-mcp.ts +49 -0
- package/src/server/workflow-store.test.ts +155 -0
- package/src/server/workflow-store.ts +139 -0
- package/src/server/workspace-agent-integration.test.ts +167 -0
- package/src/server/workspace-agent-routes.test.ts +127 -0
- package/src/server/workspace-agent-routes.ts +89 -0
- package/src/server/workspace-agent.test.ts +103 -0
- package/src/server/workspace-agent.ts +102 -0
- package/src/server/workspace-cli.test.ts +79 -0
- package/src/server/workspace-config-manager.test.ts +109 -0
- package/src/server/workspace-config-manager.ts +83 -0
- package/src/server/workspace-directory-policy.test.ts +109 -0
- package/src/server/workspace-directory-policy.ts +56 -0
- package/src/shared/agent-config-types.ts +25 -0
- package/src/shared/branding.test.ts +42 -0
- package/src/shared/branding.ts +54 -0
- package/src/shared/compression.test.ts +85 -0
- package/src/shared/compression.ts +42 -0
- package/src/shared/coordination-store.test.ts +24 -0
- package/src/shared/coordination-store.ts +26 -0
- package/src/shared/dev-ports.test.ts +84 -0
- package/src/shared/dev-ports.ts +100 -0
- package/src/shared/extension-types.ts +45 -0
- package/src/shared/fork-presets.ts +54 -0
- package/src/shared/harness-types.test.ts +15 -0
- package/src/shared/harness-types.ts +21 -0
- package/src/shared/log-sink.test.ts +112 -0
- package/src/shared/log-sink.ts +185 -0
- package/src/shared/mention-pattern.ts +7 -0
- package/src/shared/merge-presets.ts +41 -0
- package/src/shared/nats-subjects.test.ts +61 -0
- package/src/shared/nats-subjects.ts +131 -0
- package/src/shared/permission-policy.ts +136 -0
- package/src/shared/ports.ts +3 -0
- package/src/shared/preset-types.ts +15 -0
- package/src/shared/profile-types.ts +49 -0
- package/src/shared/projectFileUrl.ts +36 -0
- package/src/shared/protocol.ts +153 -0
- package/src/shared/pty-instance.ts +43 -0
- package/src/shared/puggy/diagnostics/result.ts +18 -0
- package/src/shared/puggy/expressions/evaluate.ts +292 -0
- package/src/shared/puggy/index.test.ts +101 -0
- package/src/shared/puggy/index.ts +69 -0
- package/src/shared/puggy/parser/ast.ts +110 -0
- package/src/shared/puggy/parser/parser.ts +624 -0
- package/src/shared/puggy/renderer/html.ts +447 -0
- package/src/shared/runner-protocol.test.ts +277 -0
- package/src/shared/runner-protocol.ts +210 -0
- package/src/shared/runner-team-types.ts +73 -0
- package/src/shared/runtime-types.ts +48 -0
- package/src/shared/sandbox-types.ts +53 -0
- package/src/shared/tailwind-build.test.ts +12 -0
- package/src/shared/tinkaria-system-prompt.ts +101 -0
- package/src/shared/tools.test.ts +335 -0
- package/src/shared/tools.ts +397 -0
- package/src/shared/transcript-entries.ts +27 -0
- package/src/shared/transcript-render.test.ts +225 -0
- package/src/shared/transcript-render.ts +467 -0
- package/src/shared/types.ts +1031 -0
- package/src/shared/vite-config.test.ts +47 -0
- package/src/shared/web-context.test.ts +110 -0
- package/src/shared/web-context.ts +76 -0
- package/src/shared/workflow-types.ts +51 -0
- package/src/shared/workspace-types.ts +100 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { describe, test, expect } from "bun:test"
|
|
2
|
+
import {
|
|
3
|
+
toLogLine,
|
|
4
|
+
serializeBatch,
|
|
5
|
+
createLogShipper,
|
|
6
|
+
installConsoleTee,
|
|
7
|
+
type LogLine,
|
|
8
|
+
type LogSinkBase,
|
|
9
|
+
} from "./log-sink"
|
|
10
|
+
|
|
11
|
+
const base: LogSinkBase = { source: "backend", component: "server", host: "h", pid: 42 }
|
|
12
|
+
|
|
13
|
+
describe("toLogLine", () => {
|
|
14
|
+
test("joins string args into _msg and stamps fields", () => {
|
|
15
|
+
const at = new Date("2026-05-27T10:00:00.000Z")
|
|
16
|
+
const line = toLogLine("warn", ["[tinkaria]", "boom", 7], base, at)
|
|
17
|
+
expect(line).toEqual({
|
|
18
|
+
_time: "2026-05-27T10:00:00.000Z",
|
|
19
|
+
_msg: "[tinkaria] boom 7",
|
|
20
|
+
level: "warn",
|
|
21
|
+
source: "backend",
|
|
22
|
+
component: "server",
|
|
23
|
+
host: "h",
|
|
24
|
+
pid: 42,
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test("serializes Error args to stack/message, objects to JSON", () => {
|
|
29
|
+
const line = toLogLine("error", [new Error("nope"), { a: 1 }], base)
|
|
30
|
+
expect(line._msg).toContain("nope")
|
|
31
|
+
expect(line._msg).toContain('{"a":1}')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test("does not throw on circular objects", () => {
|
|
35
|
+
const circular: Record<string, unknown> = {}
|
|
36
|
+
circular.self = circular
|
|
37
|
+
const line = toLogLine("info", [circular], base)
|
|
38
|
+
expect(typeof line._msg).toBe("string")
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe("serializeBatch", () => {
|
|
43
|
+
test("produces newline-delimited JSON", () => {
|
|
44
|
+
const lines: LogLine[] = [
|
|
45
|
+
toLogLine("info", ["a"], base, new Date("2026-05-27T10:00:00Z")),
|
|
46
|
+
toLogLine("info", ["b"], base, new Date("2026-05-27T10:00:01Z")),
|
|
47
|
+
]
|
|
48
|
+
const out = serializeBatch(lines)
|
|
49
|
+
expect(out.split("\n")).toHaveLength(2)
|
|
50
|
+
expect(JSON.parse(out.split("\n")[0])._msg).toBe("a")
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
describe("createLogShipper", () => {
|
|
55
|
+
test("POSTs ndjson to /insert/jsonline with stream fields, and swallows fetch errors", async () => {
|
|
56
|
+
const calls: { url: string; body: string }[] = []
|
|
57
|
+
const fetchFn = (async (url: string, init?: RequestInit) => {
|
|
58
|
+
calls.push({ url, body: String(init?.body) })
|
|
59
|
+
return new Response(null, { status: 204 })
|
|
60
|
+
}) as unknown as typeof fetch
|
|
61
|
+
|
|
62
|
+
const shipper = createLogShipper({ url: "http://127.0.0.1:9428/", base, fetchFn })
|
|
63
|
+
shipper.add(toLogLine("info", ["one"], base))
|
|
64
|
+
shipper.add(toLogLine("info", ["two"], base))
|
|
65
|
+
await shipper.flush()
|
|
66
|
+
shipper.stop()
|
|
67
|
+
|
|
68
|
+
expect(calls).toHaveLength(1)
|
|
69
|
+
expect(calls[0].url).toBe("http://127.0.0.1:9428/insert/jsonline?_stream_fields=source,component")
|
|
70
|
+
expect(calls[0].body.split("\n")).toHaveLength(2)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test("flush with empty buffer makes no request", async () => {
|
|
74
|
+
let n = 0
|
|
75
|
+
const fetchFn = (async () => { n++; return new Response(null) }) as unknown as typeof fetch
|
|
76
|
+
const shipper = createLogShipper({ url: "http://x", base, fetchFn })
|
|
77
|
+
await shipper.flush()
|
|
78
|
+
shipper.stop()
|
|
79
|
+
expect(n).toBe(0)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test("fetch rejection is swallowed (no throw)", async () => {
|
|
83
|
+
const fetchFn = (async () => { throw new Error("network down") }) as unknown as typeof fetch
|
|
84
|
+
const shipper = createLogShipper({ url: "http://x", base, fetchFn })
|
|
85
|
+
shipper.add(toLogLine("error", ["x"], base))
|
|
86
|
+
await expect(shipper.flush()).resolves.toBeUndefined()
|
|
87
|
+
shipper.stop()
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
describe("installConsoleTee", () => {
|
|
92
|
+
test("no-op when VICTORIALOGS_URL unset (console unchanged)", () => {
|
|
93
|
+
const before = console.warn
|
|
94
|
+
const uninstall = installConsoleTee({} as NodeJS.ProcessEnv, "server")
|
|
95
|
+
expect(console.warn).toBe(before)
|
|
96
|
+
uninstall()
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test("when set, tees but still calls the original console method", () => {
|
|
100
|
+
const seen: unknown[][] = []
|
|
101
|
+
const origWarn = console.warn
|
|
102
|
+
console.warn = ((...a: unknown[]) => seen.push(a)) as typeof console.warn
|
|
103
|
+
const uninstall = installConsoleTee(
|
|
104
|
+
{ VICTORIALOGS_URL: "http://127.0.0.1:9428" } as unknown as NodeJS.ProcessEnv,
|
|
105
|
+
"server",
|
|
106
|
+
)
|
|
107
|
+
console.warn("hello", 1)
|
|
108
|
+
expect(seen).toEqual([["hello", 1]]) // original still invoked
|
|
109
|
+
uninstall()
|
|
110
|
+
console.warn = origWarn
|
|
111
|
+
})
|
|
112
|
+
})
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend log sink → VictoriaLogs (observability, decision 0012).
|
|
3
|
+
*
|
|
4
|
+
* Tees `console.*` output to VictoriaLogs' JSON-stream ingest API
|
|
5
|
+
* (`POST /insert/jsonline`) in addition to normal stdout. Used by both the
|
|
6
|
+
* server (`cli.ts`) and the runner (`runner.ts`) processes.
|
|
7
|
+
*
|
|
8
|
+
* Design constraints:
|
|
9
|
+
* - **Never break the app.** All shipping is fire-and-forget; a down or slow
|
|
10
|
+
* VictoriaLogs must not throw into, block, or crash the host process.
|
|
11
|
+
* - **Opt-in.** Disabled unless `VICTORIALOGS_URL` is set, so default runs are
|
|
12
|
+
* byte-identical to before.
|
|
13
|
+
* - **No deps.** Plain `fetch` + a small in-memory batch.
|
|
14
|
+
*
|
|
15
|
+
* Pure helpers (`toLogLine`, `serializeBatch`) are exported for unit tests.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export type LogLevel = "debug" | "info" | "warn" | "error"
|
|
19
|
+
|
|
20
|
+
/** One VictoriaLogs jsonline record. `_time`/`_msg` are VL's default time/msg fields. */
|
|
21
|
+
export interface LogLine {
|
|
22
|
+
_time: string
|
|
23
|
+
_msg: string
|
|
24
|
+
level: LogLevel
|
|
25
|
+
source: string
|
|
26
|
+
component: string
|
|
27
|
+
host: string
|
|
28
|
+
pid: number
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface LogSinkBase {
|
|
32
|
+
source: string // "backend"
|
|
33
|
+
component: string // "server" | "runner"
|
|
34
|
+
host: string
|
|
35
|
+
pid: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Flatten console arguments into a single message string (no throwing on cycles). */
|
|
39
|
+
function stringifyArgs(args: unknown[]): string {
|
|
40
|
+
return args
|
|
41
|
+
.map((a) => {
|
|
42
|
+
if (typeof a === "string") return a
|
|
43
|
+
if (a instanceof Error) return a.stack ?? `${a.name}: ${a.message}`
|
|
44
|
+
try {
|
|
45
|
+
return JSON.stringify(a)
|
|
46
|
+
} catch {
|
|
47
|
+
return String(a)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
.join(" ")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Build a single VL record from a console call. Pure. */
|
|
54
|
+
export function toLogLine(
|
|
55
|
+
level: LogLevel,
|
|
56
|
+
args: unknown[],
|
|
57
|
+
base: LogSinkBase,
|
|
58
|
+
now: Date = new Date(),
|
|
59
|
+
): LogLine {
|
|
60
|
+
return {
|
|
61
|
+
_time: now.toISOString(),
|
|
62
|
+
_msg: stringifyArgs(args),
|
|
63
|
+
level,
|
|
64
|
+
source: base.source,
|
|
65
|
+
component: base.component,
|
|
66
|
+
host: base.host,
|
|
67
|
+
pid: base.pid,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Serialize a batch as newline-delimited JSON for `/insert/jsonline`. Pure. */
|
|
72
|
+
export function serializeBatch(lines: LogLine[]): string {
|
|
73
|
+
return lines.map((l) => JSON.stringify(l)).join("\n")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface LogShipperOptions {
|
|
77
|
+
url: string
|
|
78
|
+
base: LogSinkBase
|
|
79
|
+
flushIntervalMs?: number
|
|
80
|
+
maxBatch?: number
|
|
81
|
+
/** Injectable for tests. */
|
|
82
|
+
fetchFn?: typeof fetch
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface LogShipper {
|
|
86
|
+
add(line: LogLine): void
|
|
87
|
+
flush(): Promise<void>
|
|
88
|
+
stop(): void
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Batching shipper. Buffers records and POSTs them to VictoriaLogs on an
|
|
93
|
+
* interval or when the buffer is full. All network errors are swallowed.
|
|
94
|
+
*/
|
|
95
|
+
export function createLogShipper(opts: LogShipperOptions): LogShipper {
|
|
96
|
+
const flushIntervalMs = opts.flushIntervalMs ?? 2000
|
|
97
|
+
const maxBatch = opts.maxBatch ?? 500
|
|
98
|
+
const doFetch = opts.fetchFn ?? fetch
|
|
99
|
+
const endpoint = `${opts.url.replace(/\/$/, "")}/insert/jsonline?_stream_fields=source,component`
|
|
100
|
+
|
|
101
|
+
let buffer: LogLine[] = []
|
|
102
|
+
let timer: ReturnType<typeof setInterval> | null = null
|
|
103
|
+
|
|
104
|
+
async function flush(): Promise<void> {
|
|
105
|
+
if (buffer.length === 0) return
|
|
106
|
+
const batch = buffer
|
|
107
|
+
buffer = []
|
|
108
|
+
try {
|
|
109
|
+
await doFetch(endpoint, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: { "Content-Type": "application/x-ndjson" },
|
|
112
|
+
body: serializeBatch(batch),
|
|
113
|
+
})
|
|
114
|
+
} catch {
|
|
115
|
+
// Drop on failure — observability must never back-pressure the app.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function add(line: LogLine): void {
|
|
120
|
+
buffer.push(line)
|
|
121
|
+
if (buffer.length >= maxBatch) void flush()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
timer = setInterval(() => void flush(), flushIntervalMs)
|
|
125
|
+
// Don't keep the event loop alive just for log flushing.
|
|
126
|
+
if (typeof timer === "object" && timer && "unref" in timer) {
|
|
127
|
+
;(timer as { unref: () => void }).unref()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
add,
|
|
132
|
+
flush,
|
|
133
|
+
stop() {
|
|
134
|
+
if (timer) clearInterval(timer)
|
|
135
|
+
timer = null
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Tee `console.{debug,info,warn,error,log}` to VictoriaLogs while preserving the
|
|
142
|
+
* original stdout behavior. No-op (returns a no-op uninstaller) when
|
|
143
|
+
* `VICTORIALOGS_URL` is not set. Returns an uninstall function.
|
|
144
|
+
*/
|
|
145
|
+
export function installConsoleTee(env: NodeJS.ProcessEnv, component: string): () => void {
|
|
146
|
+
const url = env.VICTORIALOGS_URL?.trim()
|
|
147
|
+
if (!url) return () => {}
|
|
148
|
+
|
|
149
|
+
const base: LogSinkBase = {
|
|
150
|
+
source: "backend",
|
|
151
|
+
component,
|
|
152
|
+
host: env.HOSTNAME || "unknown",
|
|
153
|
+
pid: typeof process !== "undefined" ? process.pid : 0,
|
|
154
|
+
}
|
|
155
|
+
const shipper = createLogShipper({ url, base })
|
|
156
|
+
|
|
157
|
+
const levels: Array<[keyof Console, LogLevel]> = [
|
|
158
|
+
["debug", "debug"],
|
|
159
|
+
["info", "info"],
|
|
160
|
+
["log", "info"],
|
|
161
|
+
["warn", "warn"],
|
|
162
|
+
["error", "error"],
|
|
163
|
+
]
|
|
164
|
+
const originals = new Map<keyof Console, (...a: unknown[]) => void>()
|
|
165
|
+
|
|
166
|
+
for (const [method, level] of levels) {
|
|
167
|
+
const original = console[method] as (...a: unknown[]) => void
|
|
168
|
+
originals.set(method, original)
|
|
169
|
+
;(console[method] as unknown) = (...args: unknown[]) => {
|
|
170
|
+
try {
|
|
171
|
+
shipper.add(toLogLine(level, args, base))
|
|
172
|
+
} catch {
|
|
173
|
+
// never let logging shipping break a console call
|
|
174
|
+
}
|
|
175
|
+
original(...args)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return () => {
|
|
180
|
+
for (const [method, original] of originals) {
|
|
181
|
+
;(console[method] as unknown) = original
|
|
182
|
+
}
|
|
183
|
+
shipper.stop()
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Single source of truth for `@agent/<name>` mention parsing.
|
|
2
|
+
// Server is authoritative; the client uses this for picker chips only.
|
|
3
|
+
export const AGENT_MENTION_PATTERN = "(^|[\\s\\n\\t])@agent/([a-z0-9_-]+)"
|
|
4
|
+
|
|
5
|
+
export function createAgentMentionRegex(): RegExp {
|
|
6
|
+
return new RegExp(AGENT_MENTION_PATTERN, "gi")
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type PresetDefinition, getPreset } from "./preset-types"
|
|
2
|
+
|
|
3
|
+
export type MergePresetDefinition = PresetDefinition
|
|
4
|
+
|
|
5
|
+
export const MERGE_PRESETS: readonly MergePresetDefinition[] = [
|
|
6
|
+
{
|
|
7
|
+
id: "synthesis",
|
|
8
|
+
label: "Synthesis",
|
|
9
|
+
description: "Combine findings and decisions into a unified understanding.",
|
|
10
|
+
defaultIntent: "Synthesize these sessions into a unified understanding. Extract the key findings, decisions, and constraints from each, resolve any contradictions, and frame the merged context as a single coherent brief for the next step.",
|
|
11
|
+
generatorHint: "Bias toward a cohesive narrative that resolves contradictions and surfaces the strongest decisions from each source session.",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: "compare_decide",
|
|
15
|
+
label: "Compare & decide",
|
|
16
|
+
description: "Compare approaches explored in different sessions and surface trade-offs.",
|
|
17
|
+
defaultIntent: "Compare the approaches explored across these sessions. Surface the trade-offs, identify which constraints each approach satisfies or violates, and frame the merged context to support a clear decision.",
|
|
18
|
+
generatorHint: "Emphasize trade-offs, differences in assumptions, and decision criteria. Present approaches side-by-side.",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "consolidate_progress",
|
|
22
|
+
label: "Consolidate progress",
|
|
23
|
+
description: "Merge partial work from several sessions into a single next-step brief.",
|
|
24
|
+
defaultIntent: "Consolidate the progress from these sessions into a single next-step brief. Identify what was completed, what remains, and any blockers or dependencies across the sessions.",
|
|
25
|
+
generatorHint: "Prioritize what was accomplished, what's left to do, and any cross-session dependencies or blockers.",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "knowledge_base",
|
|
29
|
+
label: "Knowledge base",
|
|
30
|
+
description: "Extract and unify learned patterns, constraints, and decisions.",
|
|
31
|
+
defaultIntent: "Extract and unify the learned patterns, constraints, and key decisions from these sessions. Organize them as a reference brief that can guide future work without re-reading the originals.",
|
|
32
|
+
generatorHint: "Bias toward structured reference content: patterns, constraints, conventions, and decisions. Avoid execution steps.",
|
|
33
|
+
},
|
|
34
|
+
] as const
|
|
35
|
+
|
|
36
|
+
export const MAX_MERGE_SESSIONS = 5
|
|
37
|
+
export const DEFAULT_MERGE_PRESET_ID = MERGE_PRESETS[0]!.id
|
|
38
|
+
|
|
39
|
+
export function getMergePreset(id?: string | null): MergePresetDefinition | null {
|
|
40
|
+
return getPreset(MERGE_PRESETS, id)
|
|
41
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, test, expect } from "bun:test"
|
|
2
|
+
import {
|
|
3
|
+
snapshotSubject,
|
|
4
|
+
terminalEventSubject,
|
|
5
|
+
commandSubject,
|
|
6
|
+
ALL_SNAPSHOTS,
|
|
7
|
+
ALL_TERMINAL_EVENTS,
|
|
8
|
+
ALL_COMMANDS,
|
|
9
|
+
} from "./nats-subjects"
|
|
10
|
+
|
|
11
|
+
describe("snapshotSubject", () => {
|
|
12
|
+
test("sidebar", () => {
|
|
13
|
+
expect(snapshotSubject({ type: "sidebar" })).toBe("runtime.snap.sidebar")
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test("local-workspaces", () => {
|
|
17
|
+
expect(snapshotSubject({ type: "local-workspaces" })).toBe("runtime.snap.local-workspaces")
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test("update", () => {
|
|
21
|
+
expect(snapshotSubject({ type: "update" })).toBe("runtime.snap.update")
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test("chat with chatId", () => {
|
|
25
|
+
expect(snapshotSubject({ type: "chat", chatId: "abc-123" })).toBe("runtime.snap.chat.abc-123")
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test("terminal with terminalId", () => {
|
|
29
|
+
expect(snapshotSubject({ type: "terminal", terminalId: "term-456" })).toBe("runtime.snap.terminal.term-456")
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe("terminalEventSubject", () => {
|
|
34
|
+
test("generates correct subject", () => {
|
|
35
|
+
expect(terminalEventSubject("term-789")).toBe("runtime.evt.terminal.term-789")
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
describe("commandSubject", () => {
|
|
40
|
+
test("generates correct subject", () => {
|
|
41
|
+
expect(commandSubject("chat.send")).toBe("runtime.cmd.chat.send")
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test("system commands", () => {
|
|
45
|
+
expect(commandSubject("system.ping")).toBe("runtime.cmd.system.ping")
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe("wildcards", () => {
|
|
50
|
+
test("ALL_SNAPSHOTS", () => {
|
|
51
|
+
expect(ALL_SNAPSHOTS).toBe("runtime.snap.>")
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test("ALL_TERMINAL_EVENTS", () => {
|
|
55
|
+
expect(ALL_TERMINAL_EVENTS).toBe("runtime.evt.terminal.>")
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test("ALL_COMMANDS", () => {
|
|
59
|
+
expect(ALL_COMMANDS).toBe("runtime.cmd.>")
|
|
60
|
+
})
|
|
61
|
+
})
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { SubscriptionTopic } from "./protocol"
|
|
2
|
+
|
|
3
|
+
const PREFIX = "runtime"
|
|
4
|
+
const SNAP_PREFIX = `${PREFIX}.snap.`
|
|
5
|
+
|
|
6
|
+
/** Map a subscription topic to a KV key (also the subject suffix after `runtime.snap.`) */
|
|
7
|
+
export function snapshotKvKey(topic: SubscriptionTopic): string {
|
|
8
|
+
switch (topic.type) {
|
|
9
|
+
case "chat": return `chat.${topic.chatId}`
|
|
10
|
+
case "terminal": return `terminal.${topic.terminalId}`
|
|
11
|
+
case "orchestration": return `orchestration.${topic.chatId}`
|
|
12
|
+
case "workspace": return `workspace.${topic.workspaceId}`
|
|
13
|
+
case "agent-config": return `agent-config.${topic.workspaceId}`
|
|
14
|
+
case "repos": return `repos.${topic.workspaceId}`
|
|
15
|
+
case "workflow-runs": return `workflow-runs.${topic.workspaceId}`
|
|
16
|
+
case "sandbox-status": return `sandbox-status.${topic.workspaceId}`
|
|
17
|
+
default: return topic.type
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function snapshotSubject(topic: SubscriptionTopic): string {
|
|
22
|
+
return `${SNAP_PREFIX}${snapshotKvKey(topic)}`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function terminalEventSubject(terminalId: string): string {
|
|
26
|
+
return `${PREFIX}.evt.terminal.${terminalId}`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function chatMessageSubject(chatId: string): string {
|
|
30
|
+
return `${PREFIX}.evt.chat.${chatId}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function commandSubject(commandType: string): string {
|
|
34
|
+
return `${PREFIX}.cmd.${commandType}`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Wildcard: all snapshot subjects */
|
|
38
|
+
export const ALL_SNAPSHOTS = `${SNAP_PREFIX}>`
|
|
39
|
+
|
|
40
|
+
/** Wildcard: all terminal events */
|
|
41
|
+
export const ALL_TERMINAL_EVENTS = `${PREFIX}.evt.terminal.>`
|
|
42
|
+
|
|
43
|
+
/** Wildcard: all chat message events */
|
|
44
|
+
export const ALL_CHAT_MESSAGE_EVENTS = `${PREFIX}.evt.chat.>`
|
|
45
|
+
|
|
46
|
+
/** Wildcard: all commands */
|
|
47
|
+
export const ALL_COMMANDS = `${PREFIX}.cmd.>`
|
|
48
|
+
|
|
49
|
+
/** JetStream stream name for chat message events */
|
|
50
|
+
export const CHAT_MESSAGE_EVENTS_STREAM_NAME = "KANNA_CHAT_MESSAGE_EVENTS"
|
|
51
|
+
|
|
52
|
+
/** KV bucket name for snapshot caching */
|
|
53
|
+
export const KV_BUCKET = "runtime_snapshots"
|
|
54
|
+
|
|
55
|
+
/** JetStream stream name for workspace coordination events */
|
|
56
|
+
export const WORKSPACE_COORDINATION_EVENTS_STREAM_NAME = "KANNA_WORKSPACE_COORDINATION_EVENTS"
|
|
57
|
+
|
|
58
|
+
/** Subject for workspace coordination events */
|
|
59
|
+
export function workspaceCoordinationEventSubject(workspaceId: string): string {
|
|
60
|
+
return `${PREFIX}.evt.workspace.${workspaceId}`
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Wildcard: all workspace coordination events */
|
|
64
|
+
export const ALL_WORKSPACE_COORDINATION_EVENTS = `${PREFIX}.evt.workspace.>`
|
|
65
|
+
|
|
66
|
+
/** JetStream stream name for workflow run events */
|
|
67
|
+
export const WORKFLOW_RUN_EVENTS_STREAM_NAME = "KANNA_WORKFLOW_RUN_EVENTS"
|
|
68
|
+
|
|
69
|
+
/** Subject for workflow run events */
|
|
70
|
+
export function workflowRunEventSubject(workspaceId: string): string {
|
|
71
|
+
return `${PREFIX}.evt.workflow.${workspaceId}`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Wildcard: all workflow run events */
|
|
75
|
+
export const ALL_WORKFLOW_RUN_EVENTS = `${PREFIX}.evt.workflow.>`
|
|
76
|
+
|
|
77
|
+
/** JetStream stream name for sandbox events */
|
|
78
|
+
export const SANDBOX_EVENTS_STREAM_NAME = "KANNA_SANDBOX_EVENTS"
|
|
79
|
+
|
|
80
|
+
/** Subject for sandbox events */
|
|
81
|
+
export function sandboxEventSubject(workspaceId: string): string {
|
|
82
|
+
return `${PREFIX}.evt.sandbox.${workspaceId}`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Wildcard: all sandbox events */
|
|
86
|
+
export const ALL_SANDBOX_EVENTS = `${PREFIX}.evt.sandbox.>`
|
|
87
|
+
|
|
88
|
+
// === claude-pty subjects ===
|
|
89
|
+
|
|
90
|
+
export type PtyCommandType =
|
|
91
|
+
| "pty.spawn"
|
|
92
|
+
| "pty.input"
|
|
93
|
+
| "pty.resize"
|
|
94
|
+
| "pty.cancel"
|
|
95
|
+
| "pty.exit"
|
|
96
|
+
| "pty.snapshot"
|
|
97
|
+
|
|
98
|
+
export function ptyCommandSubject(commandType: PtyCommandType): string {
|
|
99
|
+
return `${PREFIX}.cmd.${commandType}`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function ptyDeltaSubject(): string {
|
|
103
|
+
return `${PREFIX}.evt.pty.delta`
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function ptyInstanceEventSubject(chatId: string): string {
|
|
107
|
+
return `${PREFIX}.evt.pty.${chatId}`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const ALL_PTY_COMMANDS = `${PREFIX}.cmd.pty.>`
|
|
111
|
+
export const ALL_PTY_EVENTS = `${PREFIX}.evt.pty.>`
|
|
112
|
+
|
|
113
|
+
// === oauth pool subjects ===
|
|
114
|
+
|
|
115
|
+
export type OAuthCommandType =
|
|
116
|
+
| "oauth.list"
|
|
117
|
+
| "oauth.add"
|
|
118
|
+
| "oauth.remove"
|
|
119
|
+
| "oauth.update"
|
|
120
|
+
| "oauth.setConcurrencyDefault"
|
|
121
|
+
|
|
122
|
+
export function oauthCommandSubject(commandType: OAuthCommandType): string {
|
|
123
|
+
return `${PREFIX}.cmd.${commandType}`
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function oauthChangedSubject(): string {
|
|
127
|
+
return `${PREFIX}.evt.oauth.changed`
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const ALL_OAUTH_COMMANDS = `${PREFIX}.cmd.oauth.>`
|
|
131
|
+
export const ALL_OAUTH_EVENTS = `${PREFIX}.evt.oauth.>`
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
export type ToolRequestStatus =
|
|
2
|
+
| "pending"
|
|
3
|
+
| "answered"
|
|
4
|
+
| "timeout"
|
|
5
|
+
| "canceled"
|
|
6
|
+
| "session_closed"
|
|
7
|
+
| "arg_mismatch"
|
|
8
|
+
|
|
9
|
+
export const POLICY_TERMINAL_STATUSES: ReadonlySet<ToolRequestStatus> = new Set([
|
|
10
|
+
"answered",
|
|
11
|
+
"timeout",
|
|
12
|
+
"canceled",
|
|
13
|
+
"session_closed",
|
|
14
|
+
"arg_mismatch",
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
export type PolicyVerdict = "auto-allow" | "auto-deny" | "ask"
|
|
18
|
+
|
|
19
|
+
export interface BashGateConfig {
|
|
20
|
+
autoAllowVerbs: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ToolRule {
|
|
24
|
+
tool: string
|
|
25
|
+
/** ECMAScript regex source — no delimiters or flags, passed to `new RegExp(pattern)`. */
|
|
26
|
+
pattern: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ChatPermissionPolicy {
|
|
30
|
+
defaultAction: "ask" | "auto-allow" | "auto-deny"
|
|
31
|
+
bash: BashGateConfig
|
|
32
|
+
readPathDeny: string[]
|
|
33
|
+
/** Paths the model cannot write or edit. Enforced for mcp__kanna__write and mcp__kanna__edit. */
|
|
34
|
+
writePathDeny: string[]
|
|
35
|
+
toolDenyList: ToolRule[]
|
|
36
|
+
toolAllowList: ToolRule[]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Per-chat policy override. Only set fields override the global policy
|
|
41
|
+
* defaults. Persisted on `ChatRecord.policyOverride` and merged in
|
|
42
|
+
* `AgentCoordinator` before forwarding to the session.
|
|
43
|
+
*
|
|
44
|
+
* `readPathDeny` / `writePathDeny` REPLACE the default list when provided
|
|
45
|
+
* (so the user can both add and remove entries deliberately).
|
|
46
|
+
*/
|
|
47
|
+
export interface ChatPermissionPolicyOverride {
|
|
48
|
+
defaultAction?: ChatPermissionPolicy["defaultAction"]
|
|
49
|
+
readPathDeny?: string[]
|
|
50
|
+
writePathDeny?: string[]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function mergePolicyOverride(
|
|
54
|
+
base: ChatPermissionPolicy,
|
|
55
|
+
override: ChatPermissionPolicyOverride | null | undefined,
|
|
56
|
+
): ChatPermissionPolicy {
|
|
57
|
+
if (!override) return base
|
|
58
|
+
return {
|
|
59
|
+
...base,
|
|
60
|
+
defaultAction: override.defaultAction ?? base.defaultAction,
|
|
61
|
+
readPathDeny: override.readPathDeny ?? base.readPathDeny,
|
|
62
|
+
writePathDeny: override.writePathDeny ?? base.writePathDeny,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ToolRequestDecision {
|
|
67
|
+
kind: "allow" | "deny" | "answer"
|
|
68
|
+
payload?: unknown
|
|
69
|
+
reason?: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface ToolRequest {
|
|
73
|
+
id: string
|
|
74
|
+
chatId: string
|
|
75
|
+
sessionId: string
|
|
76
|
+
toolUseId: string
|
|
77
|
+
toolName: string
|
|
78
|
+
arguments: Record<string, unknown> // MCP tool arguments — arbitrary MCP tool args, unknown shape by design
|
|
79
|
+
canonicalArgsHash: string
|
|
80
|
+
policyVerdict: PolicyVerdict
|
|
81
|
+
status: ToolRequestStatus
|
|
82
|
+
decision?: ToolRequestDecision
|
|
83
|
+
mismatchReason?: string
|
|
84
|
+
createdAt: number
|
|
85
|
+
resolvedAt?: number
|
|
86
|
+
expiresAt: number
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const POLICY_DEFAULT: ChatPermissionPolicy = {
|
|
90
|
+
defaultAction: "ask",
|
|
91
|
+
bash: {
|
|
92
|
+
autoAllowVerbs: ["ls", "pwd", "git status", "git diff", "git log"],
|
|
93
|
+
},
|
|
94
|
+
readPathDeny: [
|
|
95
|
+
"~/.ssh",
|
|
96
|
+
"~/.aws",
|
|
97
|
+
"~/.gcp",
|
|
98
|
+
"~/.config/gh",
|
|
99
|
+
"~/.claude",
|
|
100
|
+
"~/.kanna",
|
|
101
|
+
"~/Library/Keychains",
|
|
102
|
+
"/etc/shadow",
|
|
103
|
+
"/etc/sudoers",
|
|
104
|
+
"~/.gnupg",
|
|
105
|
+
"~/.gitconfig",
|
|
106
|
+
"**/.git/config",
|
|
107
|
+
"~/.npmrc",
|
|
108
|
+
"~/.netrc",
|
|
109
|
+
"~/.docker/config.json",
|
|
110
|
+
"**/.env",
|
|
111
|
+
"**/.env.*",
|
|
112
|
+
"**/credentials*",
|
|
113
|
+
"**/*.pem",
|
|
114
|
+
"**/*.key",
|
|
115
|
+
"**/id_rsa*",
|
|
116
|
+
"**/id_ed25519*",
|
|
117
|
+
],
|
|
118
|
+
writePathDeny: [
|
|
119
|
+
"/etc/**",
|
|
120
|
+
"/usr/**",
|
|
121
|
+
"/System/**",
|
|
122
|
+
"~/.ssh/**",
|
|
123
|
+
"~/.aws/**",
|
|
124
|
+
"~/.config/gh/**",
|
|
125
|
+
"~/.claude/**",
|
|
126
|
+
"~/.kanna/**",
|
|
127
|
+
"~/.gnupg/**",
|
|
128
|
+
"~/.gitconfig",
|
|
129
|
+
"**/.git/config",
|
|
130
|
+
],
|
|
131
|
+
toolDenyList: [
|
|
132
|
+
{ tool: "mcp__kanna__bash", pattern: "rm\\s+-rf\\s+(/|~|\\$HOME)(?:\\b|$|\\s)" },
|
|
133
|
+
{ tool: "mcp__kanna__bash", pattern: "git\\s+push\\b.*--force" },
|
|
134
|
+
],
|
|
135
|
+
toolAllowList: [],
|
|
136
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PresetDefinition {
|
|
2
|
+
id: string
|
|
3
|
+
label: string
|
|
4
|
+
description: string
|
|
5
|
+
defaultIntent: string
|
|
6
|
+
generatorHint: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getPreset<T extends PresetDefinition>(
|
|
10
|
+
presets: readonly T[],
|
|
11
|
+
id?: string | null,
|
|
12
|
+
): T | null {
|
|
13
|
+
if (!id) return null
|
|
14
|
+
return presets.find((preset) => preset.id === id) ?? null
|
|
15
|
+
}
|