atoo-studio 0.0.1 → 0.0.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/LICENSE +21 -0
- package/README.github.md +322 -0
- package/README.md +112 -0
- package/README.npm.md +112 -0
- package/bin/atoo-studio.js +90 -0
- package/dist/src/agents/claude-code-terminal/adapter.d.ts +42 -0
- package/dist/src/agents/claude-code-terminal/adapter.js +166 -0
- package/dist/src/agents/claude-code-terminal/index.d.ts +13 -0
- package/dist/src/agents/claude-code-terminal/index.js +45 -0
- package/dist/src/agents/claude-code-terminal/spawner.d.ts +9 -0
- package/dist/src/agents/claude-code-terminal/spawner.js +37 -0
- package/dist/src/agents/claude-code-terminal-chatro/adapter.d.ts +51 -0
- package/dist/src/agents/claude-code-terminal-chatro/adapter.js +301 -0
- package/dist/src/agents/claude-code-terminal-chatro/index.d.ts +13 -0
- package/dist/src/agents/claude-code-terminal-chatro/index.js +45 -0
- package/dist/src/agents/claude-code-terminal-chatro/jsonl-watcher.d.ts +67 -0
- package/dist/src/agents/claude-code-terminal-chatro/jsonl-watcher.js +431 -0
- package/dist/src/agents/claude-code-terminal-chatro/spawner.d.ts +9 -0
- package/dist/src/agents/claude-code-terminal-chatro/spawner.js +37 -0
- package/dist/src/agents/codex-terminal/adapter.d.ts +40 -0
- package/dist/src/agents/codex-terminal/adapter.js +160 -0
- package/dist/src/agents/codex-terminal/index.d.ts +13 -0
- package/dist/src/agents/codex-terminal/index.js +47 -0
- package/dist/src/agents/codex-terminal/spawner.d.ts +9 -0
- package/dist/src/agents/codex-terminal/spawner.js +56 -0
- package/dist/src/agents/codex-terminal-chatro/adapter.d.ts +58 -0
- package/dist/src/agents/codex-terminal-chatro/adapter.js +266 -0
- package/dist/src/agents/codex-terminal-chatro/index.d.ts +13 -0
- package/dist/src/agents/codex-terminal-chatro/index.js +50 -0
- package/dist/src/agents/codex-terminal-chatro/jsonl-watcher.d.ts +36 -0
- package/dist/src/agents/codex-terminal-chatro/jsonl-watcher.js +205 -0
- package/dist/src/agents/codex-terminal-chatro/spawner.d.ts +9 -0
- package/dist/src/agents/codex-terminal-chatro/spawner.js +57 -0
- package/dist/src/agents/lib/chain-builder.d.ts +21 -0
- package/dist/src/agents/lib/chain-builder.js +139 -0
- package/dist/src/agents/lib/claude/fs-sessions.d.ts +31 -0
- package/dist/src/agents/lib/claude/fs-sessions.js +329 -0
- package/dist/src/agents/lib/claude/jsonl-writer.d.ts +32 -0
- package/dist/src/agents/lib/claude/jsonl-writer.js +342 -0
- package/dist/src/agents/lib/claude/workspace-trust.d.ts +1 -0
- package/dist/src/agents/lib/claude/workspace-trust.js +29 -0
- package/dist/src/agents/lib/codex/fs-sessions.d.ts +34 -0
- package/dist/src/agents/lib/codex/fs-sessions.js +255 -0
- package/dist/src/agents/lib/codex/jsonl-mapper.d.ts +11 -0
- package/dist/src/agents/lib/codex/jsonl-mapper.js +154 -0
- package/dist/src/agents/lib/codex/jsonl-writer.d.ts +8 -0
- package/dist/src/agents/lib/codex/jsonl-writer.js +440 -0
- package/dist/src/agents/lib/fs-tracking.d.ts +36 -0
- package/dist/src/agents/lib/fs-tracking.js +109 -0
- package/dist/src/agents/lib/pty-activity-tracker.d.ts +37 -0
- package/dist/src/agents/lib/pty-activity-tracker.js +105 -0
- package/dist/src/agents/lib/session-id-utils.d.ts +46 -0
- package/dist/src/agents/lib/session-id-utils.js +147 -0
- package/dist/src/agents/lib/session-precreate.d.ts +17 -0
- package/dist/src/agents/lib/session-precreate.js +177 -0
- package/dist/src/agents/registry.d.ts +72 -0
- package/dist/src/agents/registry.js +337 -0
- package/dist/src/agents/types.d.ts +135 -0
- package/dist/src/agents/types.js +1 -0
- package/dist/src/auth/crypto-key.d.ts +6 -0
- package/dist/src/auth/crypto-key.js +45 -0
- package/dist/src/auth/middleware.d.ts +18 -0
- package/dist/src/auth/middleware.js +54 -0
- package/dist/src/auth/password.d.ts +2 -0
- package/dist/src/auth/password.js +12 -0
- package/dist/src/auth/session.d.ts +10 -0
- package/dist/src/auth/session.js +33 -0
- package/dist/src/auth/totp.d.ts +12 -0
- package/dist/src/auth/totp.js +61 -0
- package/dist/src/auth/webauthn.d.ts +6 -0
- package/dist/src/auth/webauthn.js +117 -0
- package/dist/src/config.d.ts +10 -0
- package/dist/src/config.js +16 -0
- package/dist/src/database/connection-manager.d.ts +25 -0
- package/dist/src/database/connection-manager.js +211 -0
- package/dist/src/database/discovery/container.d.ts +6 -0
- package/dist/src/database/discovery/container.js +226 -0
- package/dist/src/database/discovery/env-parser.d.ts +9 -0
- package/dist/src/database/discovery/env-parser.js +525 -0
- package/dist/src/database/discovery/local-files.d.ts +6 -0
- package/dist/src/database/discovery/local-files.js +58 -0
- package/dist/src/database/discovery/port-scan.d.ts +7 -0
- package/dist/src/database/discovery/port-scan.js +61 -0
- package/dist/src/database/drivers/cassandra.d.ts +12 -0
- package/dist/src/database/drivers/cassandra.js +91 -0
- package/dist/src/database/drivers/clickhouse.d.ts +11 -0
- package/dist/src/database/drivers/clickhouse.js +127 -0
- package/dist/src/database/drivers/elasticsearch.d.ts +12 -0
- package/dist/src/database/drivers/elasticsearch.js +169 -0
- package/dist/src/database/drivers/influxdb.d.ts +14 -0
- package/dist/src/database/drivers/influxdb.js +194 -0
- package/dist/src/database/drivers/memcached.d.ts +11 -0
- package/dist/src/database/drivers/memcached.js +117 -0
- package/dist/src/database/drivers/mongodb.d.ts +12 -0
- package/dist/src/database/drivers/mongodb.js +128 -0
- package/dist/src/database/drivers/mysql.d.ts +11 -0
- package/dist/src/database/drivers/mysql.js +112 -0
- package/dist/src/database/drivers/neo4j.d.ts +11 -0
- package/dist/src/database/drivers/neo4j.js +158 -0
- package/dist/src/database/drivers/postgresql.d.ts +11 -0
- package/dist/src/database/drivers/postgresql.js +133 -0
- package/dist/src/database/drivers/redis.d.ts +11 -0
- package/dist/src/database/drivers/redis.js +91 -0
- package/dist/src/database/drivers/sqlite.d.ts +10 -0
- package/dist/src/database/drivers/sqlite.js +100 -0
- package/dist/src/database/query-stream.d.ts +5 -0
- package/dist/src/database/query-stream.js +75 -0
- package/dist/src/database/types.d.ts +71 -0
- package/dist/src/database/types.js +1 -0
- package/dist/src/events/index.d.ts +3 -0
- package/dist/src/events/index.js +3 -0
- package/dist/src/events/types.d.ts +214 -0
- package/dist/src/events/types.js +22 -0
- package/dist/src/events/wire.d.ts +114 -0
- package/dist/src/events/wire.js +296 -0
- package/dist/src/fs-monitor-types.d.ts +24 -0
- package/dist/src/fs-monitor-types.js +1 -0
- package/dist/src/fs-monitor.d.ts +80 -0
- package/dist/src/fs-monitor.js +637 -0
- package/dist/src/handlers/auth.d.ts +1 -0
- package/dist/src/handlers/auth.js +170 -0
- package/dist/src/handlers/changes.d.ts +1 -0
- package/dist/src/handlers/changes.js +203 -0
- package/dist/src/handlers/containers.d.ts +12 -0
- package/dist/src/handlers/containers.js +379 -0
- package/dist/src/handlers/databases.d.ts +3 -0
- package/dist/src/handlers/databases.js +327 -0
- package/dist/src/handlers/environments.d.ts +3 -0
- package/dist/src/handlers/environments.js +286 -0
- package/dist/src/handlers/github.d.ts +1 -0
- package/dist/src/handlers/github.js +153 -0
- package/dist/src/handlers/projects.d.ts +1 -0
- package/dist/src/handlers/projects.js +895 -0
- package/dist/src/handlers/ssh.d.ts +1 -0
- package/dist/src/handlers/ssh.js +162 -0
- package/dist/src/handlers/users.d.ts +1 -0
- package/dist/src/handlers/users.js +195 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +228 -0
- package/dist/src/mcp/config.d.ts +32 -0
- package/dist/src/mcp/config.js +227 -0
- package/dist/src/mcp/server.d.ts +1 -0
- package/dist/src/mcp/server.js +574 -0
- package/dist/src/serial/cuse-device.d.ts +19 -0
- package/dist/src/serial/cuse-device.js +260 -0
- package/dist/src/serial/manager.d.ts +63 -0
- package/dist/src/serial/manager.js +206 -0
- package/dist/src/serial/pty-pair.d.ts +16 -0
- package/dist/src/serial/pty-pair.js +68 -0
- package/dist/src/services/fs-browser.d.ts +14 -0
- package/dist/src/services/fs-browser.js +98 -0
- package/dist/src/services/git-ops.d.ts +78 -0
- package/dist/src/services/git-ops.js +288 -0
- package/dist/src/services/github-ops.d.ts +104 -0
- package/dist/src/services/github-ops.js +192 -0
- package/dist/src/services/obfuscation.d.ts +2 -0
- package/dist/src/services/obfuscation.js +16 -0
- package/dist/src/services/preview/headless-backend.d.ts +62 -0
- package/dist/src/services/preview/headless-backend.js +698 -0
- package/dist/src/services/preview/injected-scripts.d.ts +9 -0
- package/dist/src/services/preview/injected-scripts.js +232 -0
- package/dist/src/services/preview/preview-backend.d.ts +92 -0
- package/dist/src/services/preview/preview-backend.js +15 -0
- package/dist/src/services/preview/universal-setter.d.ts +7 -0
- package/dist/src/services/preview/universal-setter.js +46 -0
- package/dist/src/services/preview-manager.d.ts +50 -0
- package/dist/src/services/preview-manager.js +216 -0
- package/dist/src/services/project-watcher.d.ts +6 -0
- package/dist/src/services/project-watcher.js +307 -0
- package/dist/src/services/remote-fs-browser.d.ts +11 -0
- package/dist/src/services/remote-fs-browser.js +50 -0
- package/dist/src/services/remote-git-ops.d.ts +71 -0
- package/dist/src/services/remote-git-ops.js +215 -0
- package/dist/src/services/session-search.d.ts +56 -0
- package/dist/src/services/session-search.js +303 -0
- package/dist/src/services/ssh-manager.d.ts +44 -0
- package/dist/src/services/ssh-manager.js +359 -0
- package/dist/src/session-writer.d.ts +9 -0
- package/dist/src/session-writer.js +66 -0
- package/dist/src/spawner.d.ts +56 -0
- package/dist/src/spawner.js +135 -0
- package/dist/src/state/db.d.ts +214 -0
- package/dist/src/state/db.js +897 -0
- package/dist/src/state/store.d.ts +37 -0
- package/dist/src/state/store.js +108 -0
- package/dist/src/state/types.d.ts +13 -0
- package/dist/src/state/types.js +1 -0
- package/dist/src/web/devtools-proxy.d.ts +7 -0
- package/dist/src/web/devtools-proxy.js +176 -0
- package/dist/src/web/port-proxy.d.ts +15 -0
- package/dist/src/web/port-proxy.js +124 -0
- package/dist/src/web/preview-ws.d.ts +5 -0
- package/dist/src/web/preview-ws.js +207 -0
- package/dist/src/web/server.d.ts +6 -0
- package/dist/src/web/server.js +1694 -0
- package/dist/src/ws/agent-ws.d.ts +5 -0
- package/dist/src/ws/agent-ws.js +93 -0
- package/frontend/dist/assets/_basePickBy-B-LibQ4-.js +1 -0
- package/frontend/dist/assets/_baseUniq-CprifHap.js +1 -0
- package/frontend/dist/assets/_createAssigner-ByDUqGii.js +1 -0
- package/frontend/dist/assets/abap-DuT-3z4x.js +1 -0
- package/frontend/dist/assets/addon-fit-CxQet2ja.js +1 -0
- package/frontend/dist/assets/addon-web-links-D_jRkPIl.js +1 -0
- package/frontend/dist/assets/apex-B-em86xX.js +1 -0
- package/frontend/dist/assets/api-SUPuHhSY.js +2 -0
- package/frontend/dist/assets/arc-Z0_eVteO.js +1 -0
- package/frontend/dist/assets/architecture-PBZL5I3N-hvVXGhqd.js +1 -0
- package/frontend/dist/assets/architectureDiagram-2XIMDMQ5-DiHPxX4j.js +36 -0
- package/frontend/dist/assets/array-CwG8vNfn.js +1 -0
- package/frontend/dist/assets/auth-store-R7eW5SVu.js +1 -0
- package/frontend/dist/assets/azcli-Bg9wQloi.js +1 -0
- package/frontend/dist/assets/bat-BM46z99L.js +1 -0
- package/frontend/dist/assets/bicep-DcBsJUfh.js +2 -0
- package/frontend/dist/assets/blockDiagram-WCTKOSBZ-C40u_hLo.js +132 -0
- package/frontend/dist/assets/c4Diagram-IC4MRINW-Ct7LjWFQ.js +10 -0
- package/frontend/dist/assets/cameligo-zw7JTtim.js +1 -0
- package/frontend/dist/assets/channel-ClCsE6HN.js +1 -0
- package/frontend/dist/assets/chunk-4BX2VUAB-zZ6P90VO.js +1 -0
- package/frontend/dist/assets/chunk-55IACEB6-DXllTDQl.js +1 -0
- package/frontend/dist/assets/chunk-7E7YKBS2-7zRaOLjj.js +1 -0
- package/frontend/dist/assets/chunk-7R4GIKGN-Csst1274.js +80 -0
- package/frontend/dist/assets/chunk-C72U2L5F-_JbQPbLN.js +1 -0
- package/frontend/dist/assets/chunk-CFjPhJqf.js +1 -0
- package/frontend/dist/assets/chunk-EGIJ26TM-B--aFyPw.js +1 -0
- package/frontend/dist/assets/chunk-FMBD7UC4-DVR34RNb.js +15 -0
- package/frontend/dist/assets/chunk-GEFDOKGD-CnmN6cC8.js +2 -0
- package/frontend/dist/assets/chunk-JSJVCQXG-CWxHBzeJ.js +1 -0
- package/frontend/dist/assets/chunk-KX2RTZJC-DkRk56s7.js +1 -0
- package/frontend/dist/assets/chunk-KYZI473N-DCCsG2dK.js +53 -0
- package/frontend/dist/assets/chunk-L3YUKLVL-C-DkZTMr.js +1 -0
- package/frontend/dist/assets/chunk-MX3YWQON-OUdzv5sZ.js +1 -0
- package/frontend/dist/assets/chunk-NQ4KR5QH-Bpu9FsM7.js +220 -0
- package/frontend/dist/assets/chunk-O4XLMI2P-BMLK6_ib.js +7 -0
- package/frontend/dist/assets/chunk-OZEHJAEY-CNNiJtG0.js +1 -0
- package/frontend/dist/assets/chunk-PQ6SQG4A-evVHD3KM.js +1 -0
- package/frontend/dist/assets/chunk-PU5JKC2W-DPFTYuvl.js +70 -0
- package/frontend/dist/assets/chunk-QZHKN3VN-JRdddPvu.js +1 -0
- package/frontend/dist/assets/chunk-R5LLSJPH-CHQzVVOV.js +1 -0
- package/frontend/dist/assets/chunk-WL4C6EOR-BNFU6IIi.js +189 -0
- package/frontend/dist/assets/chunk-XIRO2GV7-98T93G85.js +1 -0
- package/frontend/dist/assets/chunk-XZSTWKYB-BcW3cyNp.js +94 -0
- package/frontend/dist/assets/chunk-YBOYWFTD-BgKO1qAJ.js +1 -0
- package/frontend/dist/assets/classDiagram-VBA2DB6C-DikXzgcD.js +1 -0
- package/frontend/dist/assets/classDiagram-v2-RAHNMMFH-D7E3tQUK.js +1 -0
- package/frontend/dist/assets/clojure-FspFoNNQ.js +1 -0
- package/frontend/dist/assets/clone-mOXuZa7C.js +1 -0
- package/frontend/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
- package/frontend/dist/assets/coffee-13n8Bk2W.js +1 -0
- package/frontend/dist/assets/cose-bilkent-S5V4N54A-zUOWQqLe.js +1 -0
- package/frontend/dist/assets/cpp-BVm2xGEs.js +1 -0
- package/frontend/dist/assets/csharp-D2kAWmUm.js +1 -0
- package/frontend/dist/assets/csp-Ezvgpf0e.js +1 -0
- package/frontend/dist/assets/css-CYxRwcFy.js +3 -0
- package/frontend/dist/assets/css.worker-Cd5h-ZOL.js +89 -0
- package/frontend/dist/assets/cssMode-CrXej49V.js +1 -0
- package/frontend/dist/assets/cypher-jg3SGErc.js +1 -0
- package/frontend/dist/assets/cytoscape.esm-kyyvzxNV.js +321 -0
- package/frontend/dist/assets/dagre-DH4bgZO7.js +1 -0
- package/frontend/dist/assets/dagre-KLK3FWXG-DNSqDkwT.js +4 -0
- package/frontend/dist/assets/dart-179jqhK4.js +1 -0
- package/frontend/dist/assets/defaultLocale-Dda4OpKy.js +1 -0
- package/frontend/dist/assets/diagram-E7M64L7V-RqPNT5Vs.js +24 -0
- package/frontend/dist/assets/diagram-IFDJBPK2-B-5NRyaE.js +43 -0
- package/frontend/dist/assets/diagram-P4PSJMXO-BrP69Hk0.js +24 -0
- package/frontend/dist/assets/dist-CU_Nb1G5.js +1 -0
- package/frontend/dist/assets/dockerfile-CIAtSGxS.js +1 -0
- package/frontend/dist/assets/ecl-CGVKfDxD.js +1 -0
- package/frontend/dist/assets/editor-Br_kD0ds.css +1 -0
- package/frontend/dist/assets/editor.api2-YXkDn0Gm.js +872 -0
- package/frontend/dist/assets/editor.main-fBaXZjJ0.js +6 -0
- package/frontend/dist/assets/elixir-BZ-6w0y3.js +1 -0
- package/frontend/dist/assets/erDiagram-INFDFZHY-BYiB9NYg.js +70 -0
- package/frontend/dist/assets/flow9-CVuOjTMv.js +1 -0
- package/frontend/dist/assets/flowDiagram-PKNHOUZH-Cwq47rsR.js +162 -0
- package/frontend/dist/assets/freemarker2-DM-pztJU.js +3 -0
- package/frontend/dist/assets/fsharp-q0pGJYr6.js +1 -0
- package/frontend/dist/assets/ganttDiagram-A5KZAMGK-Dnx3szD9.js +292 -0
- package/frontend/dist/assets/gitGraph-HDMCJU4V-COlTQ7bA.js +1 -0
- package/frontend/dist/assets/gitGraphDiagram-K3NZZRJ6-BaUxboNc.js +65 -0
- package/frontend/dist/assets/go-dzSPfdEO.js +1 -0
- package/frontend/dist/assets/graphlib-kEFlkt3U.js +1 -0
- package/frontend/dist/assets/graphql-CG4OUoEV.js +1 -0
- package/frontend/dist/assets/handlebars-BbK53Vec.js +1 -0
- package/frontend/dist/assets/hcl-Cy14JPk3.js +1 -0
- package/frontend/dist/assets/html-DYtTQNOG.js +1 -0
- package/frontend/dist/assets/html.worker-BjVEKLoU.js +502 -0
- package/frontend/dist/assets/htmlMode-C6GTouth.js +1 -0
- package/frontend/dist/assets/index-DMLxes_u.js +157 -0
- package/frontend/dist/assets/index-DmzeqkB1.css +1 -0
- package/frontend/dist/assets/info-3K5VOQVL-DBtHyA4C.js +1 -0
- package/frontend/dist/assets/infoDiagram-LFFYTUFH-yBXLgMPI.js +2 -0
- package/frontend/dist/assets/ini-Pbg8HGVD.js +1 -0
- package/frontend/dist/assets/init-D6KNwrax.js +1 -0
- package/frontend/dist/assets/ishikawaDiagram-PHBUUO56-Bld4two_.js +70 -0
- package/frontend/dist/assets/java-BmVu6Qrl.js +1 -0
- package/frontend/dist/assets/javascript-PbfQEdcJ.js +1 -0
- package/frontend/dist/assets/journeyDiagram-4ABVD52K-4HyMd4R2.js +139 -0
- package/frontend/dist/assets/json.worker-DqU5Wxnl.js +58 -0
- package/frontend/dist/assets/jsonMode-CASsGppE.js +7 -0
- package/frontend/dist/assets/julia-3cGnieBq.js +1 -0
- package/frontend/dist/assets/kanban-definition-K7BYSVSG-DpgsZmpG.js +89 -0
- package/frontend/dist/assets/katex-CEw3x5bf.js +261 -0
- package/frontend/dist/assets/kotlin-BuWkVcfV.js +1 -0
- package/frontend/dist/assets/less-CJ_VPy2C.js +2 -0
- package/frontend/dist/assets/lexon-BygAuZPu.js +1 -0
- package/frontend/dist/assets/line-CA_wh_TY.js +1 -0
- package/frontend/dist/assets/linear-BAcLW45z.js +1 -0
- package/frontend/dist/assets/liquid-kz84dle6.js +1 -0
- package/frontend/dist/assets/lspLanguageFeatures-C7hAHFn1.js +4 -0
- package/frontend/dist/assets/lua-C8Xs3dCx.js +1 -0
- package/frontend/dist/assets/m3-DTJeKBk4.js +1 -0
- package/frontend/dist/assets/markdown-QCgx8JqZ.js +1 -0
- package/frontend/dist/assets/math-D0YcMJAn.js +1 -0
- package/frontend/dist/assets/mdx-yRw0ap-E.js +1 -0
- package/frontend/dist/assets/mermaid-parser.core-DAeTodBQ.js +4 -0
- package/frontend/dist/assets/mindmap-definition-YRQLILUH-CoNlFyVl.js +68 -0
- package/frontend/dist/assets/mips-DopWaYgE.js +1 -0
- package/frontend/dist/assets/monaco.contribution-DeY0Qei-.js +2 -0
- package/frontend/dist/assets/msdax-BDis4ARV.js +1 -0
- package/frontend/dist/assets/mysql-BV6MLsOI.js +1 -0
- package/frontend/dist/assets/objective-c-B1UuzKs6.js +1 -0
- package/frontend/dist/assets/ordinal-jM7S0YHN.js +1 -0
- package/frontend/dist/assets/packet-RMMSAZCW-FF6-Tmai.js +1 -0
- package/frontend/dist/assets/pascal-BkvESCrc.js +1 -0
- package/frontend/dist/assets/pascaligo-lTy0kZYr.js +1 -0
- package/frontend/dist/assets/path-DNPd7Py7.js +1 -0
- package/frontend/dist/assets/perl-CrtUPXLV.js +1 -0
- package/frontend/dist/assets/pgsql-B9IbNWx2.js +1 -0
- package/frontend/dist/assets/php-CXvQBY2p.js +1 -0
- package/frontend/dist/assets/pie-UPGHQEXC-CFvXY2o-.js +1 -0
- package/frontend/dist/assets/pieDiagram-SKSYHLDU-CM_hbCcn.js +30 -0
- package/frontend/dist/assets/pla-DxBxuqWu.js +1 -0
- package/frontend/dist/assets/postiats-OkEuT5YF.js +1 -0
- package/frontend/dist/assets/powerquery-CMx5Tq4K.js +1 -0
- package/frontend/dist/assets/powershell-CstRxrEc.js +1 -0
- package/frontend/dist/assets/preload-helper-D4M6sveU.js +1 -0
- package/frontend/dist/assets/protobuf-Bx0Z-uRj.js +2 -0
- package/frontend/dist/assets/pug--W8vanWl.js +1 -0
- package/frontend/dist/assets/python-DA0rnlw3.js +1 -0
- package/frontend/dist/assets/qsharp-CRtr0YbN.js +1 -0
- package/frontend/dist/assets/quadrantDiagram-337W2JSQ-B3n3IUhC.js +7 -0
- package/frontend/dist/assets/r-C6E1d6iv.js +1 -0
- package/frontend/dist/assets/radar-KQ55EAFF-MPZu7SdX.js +1 -0
- package/frontend/dist/assets/razor-yd73uata.js +1 -0
- package/frontend/dist/assets/redis-Dx13voP3.js +1 -0
- package/frontend/dist/assets/redshift-D66HwlyV.js +1 -0
- package/frontend/dist/assets/requirementDiagram-Z7DCOOCP-CorP7L7F.js +73 -0
- package/frontend/dist/assets/restructuredtext-DQT2NKJ2.js +1 -0
- package/frontend/dist/assets/rough.esm-DxAX5Vpo.js +1 -0
- package/frontend/dist/assets/ruby-iFXI8hwH.js +1 -0
- package/frontend/dist/assets/rust-CSKiei34.js +1 -0
- package/frontend/dist/assets/sankeyDiagram-WA2Y5GQK-RDx6Bd-B.js +10 -0
- package/frontend/dist/assets/sb-Bo3ttdP2.js +1 -0
- package/frontend/dist/assets/scala-BC1D-Nxp.js +1 -0
- package/frontend/dist/assets/scheme-Z4OAo4Lv.js +1 -0
- package/frontend/dist/assets/scss-BvrdPs6B.js +3 -0
- package/frontend/dist/assets/sequenceDiagram-2WXFIKYE-JMqJSFq6.js +145 -0
- package/frontend/dist/assets/shell-Bh_aCyF-.js +1 -0
- package/frontend/dist/assets/solidity-CWHj6tSe.js +1 -0
- package/frontend/dist/assets/sophia-raoNtKtm.js +1 -0
- package/frontend/dist/assets/sparql-XzmoGnue.js +1 -0
- package/frontend/dist/assets/sql-BD0i9Gvg.js +1 -0
- package/frontend/dist/assets/src-Bn-kKzs7.js +1 -0
- package/frontend/dist/assets/st-DtVKyms6.js +1 -0
- package/frontend/dist/assets/stateDiagram-RAJIS63D-CgFfENdy.js +1 -0
- package/frontend/dist/assets/stateDiagram-v2-FVOUBMTO-C4Hh2P-U.js +1 -0
- package/frontend/dist/assets/swift--UZs77wT.js +1 -0
- package/frontend/dist/assets/systemverilog-CDnBSWUd.js +1 -0
- package/frontend/dist/assets/tcl-DdCEuTHZ.js +1 -0
- package/frontend/dist/assets/timeline-definition-YZTLITO2-BnatPBR5.js +61 -0
- package/frontend/dist/assets/treemap-KZPCXAKY-qb1Pl9la.js +1 -0
- package/frontend/dist/assets/ts.worker-DyPAEIuH.js +67719 -0
- package/frontend/dist/assets/tsMode-iuvyEpyO.js +11 -0
- package/frontend/dist/assets/twig-SSL-Altf.js +1 -0
- package/frontend/dist/assets/typescript-17918Hud.js +1 -0
- package/frontend/dist/assets/typespec-BT7S0ETg.js +1 -0
- package/frontend/dist/assets/vb-CrIgucua.js +1 -0
- package/frontend/dist/assets/vennDiagram-LZ73GAT5-DygS4Zzd.js +34 -0
- package/frontend/dist/assets/wgsl-BeKc3oEp.js +298 -0
- package/frontend/dist/assets/workers-DTfwKVoM.js +1 -0
- package/frontend/dist/assets/xml-CBMr_Wbw.js +1 -0
- package/frontend/dist/assets/xterm-BrP-ENHg.css +1 -0
- package/frontend/dist/assets/xterm-CBX2m0YM.js +36 -0
- package/frontend/dist/assets/xychartDiagram-JWTSCODW-D6wY1Jwd.js +7 -0
- package/frontend/dist/assets/yaml-CTjCH7Bv.js +1 -0
- package/frontend/dist/fonts/inter-300.ttf +0 -0
- package/frontend/dist/fonts/inter-400.ttf +0 -0
- package/frontend/dist/fonts/inter-500.ttf +0 -0
- package/frontend/dist/fonts/inter-600.ttf +0 -0
- package/frontend/dist/fonts/inter-700.ttf +0 -0
- package/frontend/dist/index.html +49 -0
- package/frontend/dist/logo_192x192.png +0 -0
- package/frontend/dist/logo_32x32.png +0 -0
- package/frontend/dist/logo_512x512.png +0 -0
- package/frontend/dist/logo_64x64.png +0 -0
- package/frontend/dist/logobg_192x192.png +0 -0
- package/frontend/dist/logobg_512x512.png +0 -0
- package/frontend/dist/logobg_64x64.png +0 -0
- package/frontend/dist/manifest.json +25 -0
- package/frontend/dist/sw.js +22 -0
- package/package.json +74 -7
- package/preload/Makefile +12 -0
- package/preload/atoo-studio-preload.c +647 -0
- package/preload/atoo-studio-preload.so +0 -0
- package/setup-cuse.sh +260 -0
- package/setup.sh +81 -0
- package/src/serial/native/binding.gyp +10 -0
- package/src/serial/native/pty_pair.c +222 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { Agent, AgentInitOptions, AgentSessionInfo, Attachment } from '../types.js';
|
|
3
|
+
import type { SessionEvent } from '../../events/types.js';
|
|
4
|
+
import type { WireMessage } from '../../events/wire.js';
|
|
5
|
+
/**
|
|
6
|
+
* Terminal-only Claude Code agent.
|
|
7
|
+
* Spawns a plain `claude` PTY — no MITM proxy, no MCP, no /remote-control,
|
|
8
|
+
* no message parsing, no /context workflow. The user interacts purely via the
|
|
9
|
+
* terminal xterm view.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ClaudeCodeTerminalAgent extends EventEmitter implements Agent {
|
|
12
|
+
readonly sessionId: string;
|
|
13
|
+
envId: string | null;
|
|
14
|
+
private status;
|
|
15
|
+
private mode;
|
|
16
|
+
private cwd;
|
|
17
|
+
private createdAt;
|
|
18
|
+
private destroyed;
|
|
19
|
+
private cliSessionId;
|
|
20
|
+
private activityTracker;
|
|
21
|
+
constructor(sessionId: string);
|
|
22
|
+
initialize(options: AgentInitOptions): Promise<void>;
|
|
23
|
+
destroy(): Promise<void>;
|
|
24
|
+
sendMessage(text: string, _attachments?: Attachment[]): void;
|
|
25
|
+
approve(_requestId: string, _updatedInput?: any): void;
|
|
26
|
+
deny(_requestId: string): void;
|
|
27
|
+
answerQuestion(_requestId: string, _answers: Record<string, string>): void;
|
|
28
|
+
setMode(_mode: string): void;
|
|
29
|
+
setModel(_model: string): void;
|
|
30
|
+
refreshContext(): void;
|
|
31
|
+
onFocused(): void;
|
|
32
|
+
onBlurred(): void;
|
|
33
|
+
sendKey(key: string): void;
|
|
34
|
+
getInfo(): AgentSessionInfo;
|
|
35
|
+
forkToResumable(_afterEventUuid: string, _fromEventUuid?: string, _targetDir?: string): string | null;
|
|
36
|
+
getMessages(): WireMessage[];
|
|
37
|
+
getEvents(): SessionEvent[];
|
|
38
|
+
getCliSessionId(): string | null;
|
|
39
|
+
getWireMessages(): WireMessage[];
|
|
40
|
+
private getCapabilities;
|
|
41
|
+
private setStatus;
|
|
42
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import { getProcessPid, getPty, killCliProcess } from '../../spawner.js';
|
|
4
|
+
import { spawnTerminalCliProcess } from './spawner.js';
|
|
5
|
+
import { initFileTracking } from '../lib/fs-tracking.js';
|
|
6
|
+
import { PtyActivityTracker } from '../lib/pty-activity-tracker.js';
|
|
7
|
+
import { precreateClaudeSession } from '../lib/session-precreate.js';
|
|
8
|
+
/**
|
|
9
|
+
* Terminal-only Claude Code agent.
|
|
10
|
+
* Spawns a plain `claude` PTY — no MITM proxy, no MCP, no /remote-control,
|
|
11
|
+
* no message parsing, no /context workflow. The user interacts purely via the
|
|
12
|
+
* terminal xterm view.
|
|
13
|
+
*/
|
|
14
|
+
export class ClaudeCodeTerminalAgent extends EventEmitter {
|
|
15
|
+
sessionId;
|
|
16
|
+
envId = null;
|
|
17
|
+
status = 'open';
|
|
18
|
+
mode = 'default';
|
|
19
|
+
cwd = null;
|
|
20
|
+
createdAt = Date.now();
|
|
21
|
+
destroyed = false;
|
|
22
|
+
cliSessionId = null;
|
|
23
|
+
activityTracker = null;
|
|
24
|
+
constructor(sessionId) {
|
|
25
|
+
super();
|
|
26
|
+
this.sessionId = sessionId;
|
|
27
|
+
}
|
|
28
|
+
async initialize(options) {
|
|
29
|
+
this.cwd = options.cwd || os.homedir();
|
|
30
|
+
if (options.skipPermissions) {
|
|
31
|
+
this.mode = 'bypassPermissions';
|
|
32
|
+
}
|
|
33
|
+
// Determine session UUID: use provided resume UUID, or pre-create a new one
|
|
34
|
+
const resumeUuid = options.resumeSessionUuid || precreateClaudeSession(this.cwd, options.initialMessage);
|
|
35
|
+
this.cliSessionId = resumeUuid;
|
|
36
|
+
try {
|
|
37
|
+
const { envId, preloadSessionId } = spawnTerminalCliProcess({
|
|
38
|
+
skipPermissions: options.skipPermissions,
|
|
39
|
+
cwd: this.cwd,
|
|
40
|
+
resumeSessionUuid: resumeUuid,
|
|
41
|
+
isChainContinuation: options.isChainContinuation,
|
|
42
|
+
});
|
|
43
|
+
this.envId = envId;
|
|
44
|
+
// Set up PTY activity tracking (burst detection → status events)
|
|
45
|
+
this.activityTracker = new PtyActivityTracker((status) => {
|
|
46
|
+
this.setStatus(status);
|
|
47
|
+
});
|
|
48
|
+
const pty = getPty(this.envId);
|
|
49
|
+
if (pty) {
|
|
50
|
+
pty.onData((data) => this.activityTracker?.onPtyData(data));
|
|
51
|
+
}
|
|
52
|
+
// Start file change detection (levels 1+2: LD_PRELOAD + inotify)
|
|
53
|
+
const pid = getProcessPid(this.envId);
|
|
54
|
+
if (pid) {
|
|
55
|
+
initFileTracking({
|
|
56
|
+
sessionId: this.cliSessionId,
|
|
57
|
+
cwd: this.cwd,
|
|
58
|
+
pid,
|
|
59
|
+
preloadSessionId,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
this.emit('ready');
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
this.emit('error', err);
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async destroy() {
|
|
70
|
+
if (this.destroyed)
|
|
71
|
+
return;
|
|
72
|
+
this.destroyed = true;
|
|
73
|
+
if (this.activityTracker) {
|
|
74
|
+
this.activityTracker.dispose();
|
|
75
|
+
this.activityTracker = null;
|
|
76
|
+
}
|
|
77
|
+
if (this.envId) {
|
|
78
|
+
killCliProcess(this.envId);
|
|
79
|
+
}
|
|
80
|
+
this.setStatus('exited');
|
|
81
|
+
this.emit('exit');
|
|
82
|
+
}
|
|
83
|
+
// Terminal-only: type message directly into the PTY
|
|
84
|
+
sendMessage(text, _attachments) {
|
|
85
|
+
if (!text || !this.envId)
|
|
86
|
+
return;
|
|
87
|
+
const pty = getPty(this.envId);
|
|
88
|
+
if (!pty)
|
|
89
|
+
return;
|
|
90
|
+
// Delay to let the CLI TUI initialize and show its prompt
|
|
91
|
+
setTimeout(() => {
|
|
92
|
+
const p = getPty(this.envId);
|
|
93
|
+
if (p)
|
|
94
|
+
p.write(text + '\n');
|
|
95
|
+
}, 2000);
|
|
96
|
+
}
|
|
97
|
+
approve(_requestId, _updatedInput) { }
|
|
98
|
+
deny(_requestId) { }
|
|
99
|
+
answerQuestion(_requestId, _answers) { }
|
|
100
|
+
setMode(_mode) { }
|
|
101
|
+
setModel(_model) { }
|
|
102
|
+
refreshContext() { }
|
|
103
|
+
onFocused() { this.activityTracker?.onFocused(); }
|
|
104
|
+
onBlurred() { this.activityTracker?.onBlurred(); }
|
|
105
|
+
sendKey(key) {
|
|
106
|
+
if (!this.envId)
|
|
107
|
+
return;
|
|
108
|
+
const pty = getPty(this.envId);
|
|
109
|
+
if (!pty)
|
|
110
|
+
return;
|
|
111
|
+
const KEY_MAP = {
|
|
112
|
+
escape: '\x1b',
|
|
113
|
+
};
|
|
114
|
+
const sequence = KEY_MAP[key];
|
|
115
|
+
if (sequence) {
|
|
116
|
+
pty.write(sequence);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
getInfo() {
|
|
120
|
+
return {
|
|
121
|
+
sessionId: this.sessionId,
|
|
122
|
+
agentType: 'claude-code-terminal',
|
|
123
|
+
agentMode: 'terminal',
|
|
124
|
+
status: this.status,
|
|
125
|
+
mode: this.mode,
|
|
126
|
+
cwd: this.cwd || undefined,
|
|
127
|
+
capabilities: this.getCapabilities(),
|
|
128
|
+
createdAt: this.createdAt,
|
|
129
|
+
cliSessionId: this.cliSessionId || undefined,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
forkToResumable(_afterEventUuid, _fromEventUuid, _targetDir) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
getMessages() {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
getEvents() {
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
getCliSessionId() {
|
|
142
|
+
return this.cliSessionId;
|
|
143
|
+
}
|
|
144
|
+
getWireMessages() {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
getCapabilities() {
|
|
148
|
+
return {
|
|
149
|
+
canChangeMode: false,
|
|
150
|
+
canChangeModel: false,
|
|
151
|
+
hasContextUsage: false,
|
|
152
|
+
canFork: false,
|
|
153
|
+
canResume: true,
|
|
154
|
+
hasTerminal: true,
|
|
155
|
+
hasFileTracking: true,
|
|
156
|
+
availableModes: [],
|
|
157
|
+
availableModels: [],
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
setStatus(status) {
|
|
161
|
+
if (this.status === status)
|
|
162
|
+
return;
|
|
163
|
+
this.status = status;
|
|
164
|
+
this.emit('status', status);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentFactory, Agent, AgentDescriptor, HistoricalSession } from '../types.js';
|
|
2
|
+
import type { SessionEvent } from '../../events/types.js';
|
|
3
|
+
export declare class ClaudeCodeTerminalAgentFactory implements AgentFactory {
|
|
4
|
+
agentType: string;
|
|
5
|
+
agentFamily: string;
|
|
6
|
+
create(sessionId: string): Agent;
|
|
7
|
+
getDescriptor(): AgentDescriptor;
|
|
8
|
+
getHistoricalSessions(): Promise<HistoricalSession[]>;
|
|
9
|
+
ownsSession(uuid: string): Promise<boolean>;
|
|
10
|
+
getSessionFilesForProject(cwds: string[]): Promise<string[]>;
|
|
11
|
+
readSessionEvents(uuid: string): Promise<SessionEvent[]>;
|
|
12
|
+
writeSessionForResume(events: SessionEvent[], targetUuid: string, directory: string): string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ClaudeCodeTerminalAgent } from './adapter.js';
|
|
2
|
+
import { fsSessionScanner } from '../lib/claude/fs-sessions.js';
|
|
3
|
+
import { writeForkedClaudeJsonl } from '../lib/claude/jsonl-writer.js';
|
|
4
|
+
export class ClaudeCodeTerminalAgentFactory {
|
|
5
|
+
agentType = 'claude-code-terminal';
|
|
6
|
+
agentFamily = 'claude';
|
|
7
|
+
create(sessionId) {
|
|
8
|
+
return new ClaudeCodeTerminalAgent(sessionId);
|
|
9
|
+
}
|
|
10
|
+
getDescriptor() {
|
|
11
|
+
return {
|
|
12
|
+
agentType: this.agentType,
|
|
13
|
+
agentFamily: this.agentFamily,
|
|
14
|
+
name: 'Claude Code',
|
|
15
|
+
mode: 'terminal',
|
|
16
|
+
iconUrl: `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#d97757" viewBox="0 0 16 16"><path d="m3.127 10.604 3.135-1.76.053-.153-.053-.085H6.11l-.525-.032-1.791-.048-1.554-.065-1.505-.08-.38-.081L0 7.832l.036-.234.32-.214.455.04 1.009.069 1.513.105 1.097.064 1.626.17h.259l.036-.105-.089-.065-.068-.064-1.566-1.062-1.695-1.121-.887-.646-.48-.327-.243-.306-.104-.67.435-.48.585.04.15.04.593.456 1.267.981 1.654 1.218.242.202.097-.068.012-.049-.109-.181-.9-1.626-.96-1.655-.428-.686-.113-.411a2 2 0 0 1-.068-.484l.496-.674L4.446 0l.662.089.279.242.411.94.666 1.48 1.033 2.014.302.597.162.553.06.17h.105v-.097l.085-1.134.157-1.392.154-1.792.052-.504.25-.605.497-.327.387.186.319.456-.045.294-.19 1.23-.37 1.93-.243 1.29h.142l.161-.16.654-.868 1.097-1.372.484-.545.565-.601.363-.287h.686l.505.751-.226.775-.707.895-.585.759-.839 1.13-.524.904.048.072.125-.012 1.897-.403 1.024-.186 1.223-.21.553.258.06.263-.218.536-1.307.323-1.533.307-2.284.54-.028.02.032.04 1.029.098.44.024h1.077l2.005.15.525.346.315.424-.053.323-.807.411-3.631-.863-.872-.218h-.12v.073l.726.71 1.331 1.202 1.667 1.55.084.383-.214.302-.226-.032-1.464-1.101-.565-.497-1.28-1.077h-.084v.113l.295.432 1.557 2.34.08.718-.112.234-.404.141-.444-.08-.911-1.28-.94-1.44-.759-1.291-.093.053-.448 4.821-.21.246-.484.186-.403-.307-.214-.496.214-.98.258-1.28.21-1.016.19-1.263.112-.42-.008-.028-.092.012-.953 1.307-1.448 1.957-1.146 1.227-.274.109-.477-.247.045-.44.266-.39 1.586-2.018.956-1.25.617-.723-.004-.105h-.036l-4.212 2.736-.75.096-.324-.302.04-.496.154-.162 1.267-.871z"/></svg>')}`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async getHistoricalSessions() {
|
|
20
|
+
const fsSessions = await fsSessionScanner.scan();
|
|
21
|
+
return fsSessions.map(s => ({
|
|
22
|
+
id: s.uuid,
|
|
23
|
+
agentType: this.agentType,
|
|
24
|
+
title: s.title,
|
|
25
|
+
directory: s.directory,
|
|
26
|
+
lastModified: s.lastModified,
|
|
27
|
+
eventCount: s.eventCount,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
async ownsSession(uuid) {
|
|
31
|
+
if (fsSessionScanner.getByUuid(uuid))
|
|
32
|
+
return true;
|
|
33
|
+
await fsSessionScanner.scan();
|
|
34
|
+
return !!fsSessionScanner.getByUuid(uuid);
|
|
35
|
+
}
|
|
36
|
+
async getSessionFilesForProject(cwds) {
|
|
37
|
+
return fsSessionScanner.getFilesForProject(cwds);
|
|
38
|
+
}
|
|
39
|
+
async readSessionEvents(uuid) {
|
|
40
|
+
return fsSessionScanner.readEvents(uuid);
|
|
41
|
+
}
|
|
42
|
+
writeSessionForResume(events, targetUuid, directory) {
|
|
43
|
+
return writeForkedClaudeJsonl(events, targetUuid, directory);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Terminal–specific spawn logic.
|
|
3
|
+
* Plain `claude` PTY with MCP, system prompt, and LD_PRELOAD for file tracking.
|
|
4
|
+
*/
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
7
|
+
import { spawnProcess } from '../../spawner.js';
|
|
8
|
+
import { ensureWorkspaceTrust } from '../lib/claude/workspace-trust.js';
|
|
9
|
+
import { getMcpConfigPath, MCP_SYSTEM_PROMPT, CHAIN_SYSTEM_PROMPT } from '../../mcp/config.js';
|
|
10
|
+
import { addPreloadEnv } from '../lib/fs-tracking.js';
|
|
11
|
+
export function spawnTerminalCliProcess(options) {
|
|
12
|
+
const cwd = options.cwd || process.env.HOME || os.homedir();
|
|
13
|
+
ensureWorkspaceTrust(cwd);
|
|
14
|
+
const systemPrompt = options.isChainContinuation
|
|
15
|
+
? MCP_SYSTEM_PROMPT + CHAIN_SYSTEM_PROMPT
|
|
16
|
+
: MCP_SYSTEM_PROMPT;
|
|
17
|
+
const mcpConfigPath = getMcpConfigPath(options.resumeSessionUuid);
|
|
18
|
+
const args = [];
|
|
19
|
+
if (options.skipPermissions)
|
|
20
|
+
args.push('--dangerously-skip-permissions');
|
|
21
|
+
args.push('--append-system-prompt', systemPrompt, '--mcp-config', mcpConfigPath);
|
|
22
|
+
if (options.resumeSessionUuid)
|
|
23
|
+
args.push('--resume', options.resumeSessionUuid);
|
|
24
|
+
const preloadSessionId = uuidv4();
|
|
25
|
+
const env = { ...process.env };
|
|
26
|
+
delete env.CLAUDECODE;
|
|
27
|
+
addPreloadEnv(env, preloadSessionId);
|
|
28
|
+
const { envId } = spawnProcess({
|
|
29
|
+
command: 'claude',
|
|
30
|
+
args,
|
|
31
|
+
cwd,
|
|
32
|
+
env,
|
|
33
|
+
preloadSessionId,
|
|
34
|
+
logPrefix: 'claude-terminal',
|
|
35
|
+
});
|
|
36
|
+
return { envId, preloadSessionId };
|
|
37
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import type { Agent, AgentInitOptions, AgentSessionInfo, Attachment } from '../types.js';
|
|
3
|
+
import type { SessionEvent } from '../../events/types.js';
|
|
4
|
+
import type { WireMessage } from '../../events/wire.js';
|
|
5
|
+
/**
|
|
6
|
+
* Terminal + Chat Read-Only agent.
|
|
7
|
+
* Spawns a plain `claude` PTY (like the terminal agent) but also watches
|
|
8
|
+
* the CLI's JSONL session file to stream messages into a read-only Chat UI.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ClaudeCodeTerminalChatROAgent extends EventEmitter implements Agent {
|
|
11
|
+
readonly sessionId: string;
|
|
12
|
+
envId: string | null;
|
|
13
|
+
private status;
|
|
14
|
+
private mode;
|
|
15
|
+
private activityTracker;
|
|
16
|
+
private cwd;
|
|
17
|
+
private createdAt;
|
|
18
|
+
private destroyed;
|
|
19
|
+
private jsonlWatcher;
|
|
20
|
+
private toolTracker;
|
|
21
|
+
private wireMessages;
|
|
22
|
+
private events;
|
|
23
|
+
private pendingToolUses;
|
|
24
|
+
private sidechainSessions;
|
|
25
|
+
private cliSessionId;
|
|
26
|
+
private resumeSessionUuid;
|
|
27
|
+
private preloadedUuids;
|
|
28
|
+
constructor(sessionId: string);
|
|
29
|
+
initialize(options: AgentInitOptions): Promise<void>;
|
|
30
|
+
destroy(): Promise<void>;
|
|
31
|
+
sendMessage(text: string, _attachments?: Attachment[]): void;
|
|
32
|
+
approve(_requestId: string, _updatedInput?: any): void;
|
|
33
|
+
deny(_requestId: string): void;
|
|
34
|
+
answerQuestion(_requestId: string, _answers: Record<string, string>): void;
|
|
35
|
+
setMode(_mode: string): void;
|
|
36
|
+
setModel(_model: string): void;
|
|
37
|
+
refreshContext(): void;
|
|
38
|
+
onFocused(): void;
|
|
39
|
+
onBlurred(): void;
|
|
40
|
+
sendKey(key: string): void;
|
|
41
|
+
getInfo(): AgentSessionInfo;
|
|
42
|
+
forkToResumable(afterEventUuid: string, fromEventUuid?: string, targetDir?: string): string | null;
|
|
43
|
+
getCliSessionId(): string | null;
|
|
44
|
+
getMessages(): WireMessage[];
|
|
45
|
+
getEvents(): SessionEvent[];
|
|
46
|
+
getWireMessages(): WireMessage[];
|
|
47
|
+
private loadHistoricalMessages;
|
|
48
|
+
private handleJsonlEvent;
|
|
49
|
+
private getCapabilities;
|
|
50
|
+
private setStatus;
|
|
51
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import { toWireMessages } from '../../events/wire.js';
|
|
4
|
+
import { forkEventsToResumable } from '../lib/claude/jsonl-writer.js';
|
|
5
|
+
import { getProcessPid, getPty, killCliProcess } from '../../spawner.js';
|
|
6
|
+
import { spawnTerminalCliProcess } from './spawner.js';
|
|
7
|
+
import { JsonlWatcher } from './jsonl-watcher.js';
|
|
8
|
+
import { fsSessionScanner } from '../lib/claude/fs-sessions.js';
|
|
9
|
+
import { initFileTracking, ToolResultFileTracker } from '../lib/fs-tracking.js';
|
|
10
|
+
import { PtyActivityTracker } from '../lib/pty-activity-tracker.js';
|
|
11
|
+
import { precreateClaudeSession } from '../lib/session-precreate.js';
|
|
12
|
+
/**
|
|
13
|
+
* Terminal + Chat Read-Only agent.
|
|
14
|
+
* Spawns a plain `claude` PTY (like the terminal agent) but also watches
|
|
15
|
+
* the CLI's JSONL session file to stream messages into a read-only Chat UI.
|
|
16
|
+
*/
|
|
17
|
+
export class ClaudeCodeTerminalChatROAgent extends EventEmitter {
|
|
18
|
+
sessionId;
|
|
19
|
+
envId = null;
|
|
20
|
+
status = 'open';
|
|
21
|
+
mode = 'default';
|
|
22
|
+
activityTracker = null;
|
|
23
|
+
cwd = null;
|
|
24
|
+
createdAt = Date.now();
|
|
25
|
+
destroyed = false;
|
|
26
|
+
jsonlWatcher = null;
|
|
27
|
+
toolTracker = null;
|
|
28
|
+
wireMessages = [];
|
|
29
|
+
events = []; // canonical event store
|
|
30
|
+
pendingToolUses = new Map();
|
|
31
|
+
sidechainSessions = new Map(); // sessionId → parentToolUseId
|
|
32
|
+
cliSessionId = null; // CLI's own session UUID (JSONL filename)
|
|
33
|
+
resumeSessionUuid = null; // Original session UUID for parent linking
|
|
34
|
+
preloadedUuids = new Set(); // UUIDs from pre-loaded historical events
|
|
35
|
+
constructor(sessionId) {
|
|
36
|
+
super();
|
|
37
|
+
this.sessionId = sessionId;
|
|
38
|
+
}
|
|
39
|
+
async initialize(options) {
|
|
40
|
+
this.cwd = options.cwd || os.homedir();
|
|
41
|
+
if (options.skipPermissions) {
|
|
42
|
+
this.mode = 'bypassPermissions';
|
|
43
|
+
}
|
|
44
|
+
// Determine session UUID: use provided resume UUID, or pre-create a new one
|
|
45
|
+
const resumeUuid = options.resumeSessionUuid || precreateClaudeSession(this.cwd, options.initialMessage);
|
|
46
|
+
this.cliSessionId = resumeUuid;
|
|
47
|
+
try {
|
|
48
|
+
// Pre-load historical messages for resume (before spawning CLI)
|
|
49
|
+
if (options.resumeSessionUuid) {
|
|
50
|
+
this.resumeSessionUuid = options.resumeSessionUuid;
|
|
51
|
+
await this.loadHistoricalMessages(options.resumeSessionUuid);
|
|
52
|
+
}
|
|
53
|
+
// Create JSONL watcher and start tailing the known file immediately
|
|
54
|
+
this.jsonlWatcher = new JsonlWatcher({
|
|
55
|
+
cwd: this.cwd,
|
|
56
|
+
resumeUuid: resumeUuid,
|
|
57
|
+
});
|
|
58
|
+
this.jsonlWatcher.on('event', (event, metadata) => {
|
|
59
|
+
this.handleJsonlEvent(event, metadata);
|
|
60
|
+
});
|
|
61
|
+
this.jsonlWatcher.on('error', (err) => {
|
|
62
|
+
console.error(`[terminal-chatro] JSONL watcher error:`, err.message);
|
|
63
|
+
});
|
|
64
|
+
// Spawn the terminal PTY — always with --resume since we pre-created the file
|
|
65
|
+
const { envId, preloadSessionId } = spawnTerminalCliProcess({
|
|
66
|
+
skipPermissions: options.skipPermissions,
|
|
67
|
+
cwd: this.cwd,
|
|
68
|
+
resumeSessionUuid: resumeUuid,
|
|
69
|
+
isChainContinuation: options.isChainContinuation,
|
|
70
|
+
});
|
|
71
|
+
this.envId = envId;
|
|
72
|
+
// Set up PTY activity tracking (burst detection → status events)
|
|
73
|
+
this.activityTracker = new PtyActivityTracker((status) => {
|
|
74
|
+
this.setStatus(status);
|
|
75
|
+
});
|
|
76
|
+
const pty = getPty(this.envId);
|
|
77
|
+
if (pty) {
|
|
78
|
+
pty.onData((data) => this.activityTracker?.onPtyData(data));
|
|
79
|
+
}
|
|
80
|
+
// Start file change detection (all 3 levels)
|
|
81
|
+
const pid = getProcessPid(this.envId);
|
|
82
|
+
if (pid) {
|
|
83
|
+
initFileTracking({
|
|
84
|
+
sessionId: this.cliSessionId,
|
|
85
|
+
cwd: this.cwd,
|
|
86
|
+
pid,
|
|
87
|
+
preloadSessionId,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
this.toolTracker = new ToolResultFileTracker(this.cliSessionId);
|
|
91
|
+
// Start tailing the known JSONL file — UUID is known, no discovery needed
|
|
92
|
+
this.jsonlWatcher.startTailingKnownUuid(resumeUuid);
|
|
93
|
+
this.emit('ready');
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
this.emit('error', err);
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async destroy() {
|
|
101
|
+
if (this.destroyed)
|
|
102
|
+
return;
|
|
103
|
+
this.destroyed = true;
|
|
104
|
+
if (this.activityTracker) {
|
|
105
|
+
this.activityTracker.dispose();
|
|
106
|
+
this.activityTracker = null;
|
|
107
|
+
}
|
|
108
|
+
if (this.jsonlWatcher) {
|
|
109
|
+
this.jsonlWatcher.stop();
|
|
110
|
+
this.jsonlWatcher = null;
|
|
111
|
+
}
|
|
112
|
+
if (this.envId) {
|
|
113
|
+
killCliProcess(this.envId);
|
|
114
|
+
}
|
|
115
|
+
this.setStatus('exited');
|
|
116
|
+
this.emit('exit');
|
|
117
|
+
}
|
|
118
|
+
// Terminal-only: type message directly into the PTY
|
|
119
|
+
sendMessage(text, _attachments) {
|
|
120
|
+
if (!text || !this.envId)
|
|
121
|
+
return;
|
|
122
|
+
const pty = getPty(this.envId);
|
|
123
|
+
if (!pty)
|
|
124
|
+
return;
|
|
125
|
+
setTimeout(() => {
|
|
126
|
+
const p = getPty(this.envId);
|
|
127
|
+
if (p)
|
|
128
|
+
p.write(text + '\n');
|
|
129
|
+
}, 2000);
|
|
130
|
+
}
|
|
131
|
+
approve(_requestId, _updatedInput) { }
|
|
132
|
+
deny(_requestId) { }
|
|
133
|
+
answerQuestion(_requestId, _answers) { }
|
|
134
|
+
setMode(_mode) { }
|
|
135
|
+
setModel(_model) { }
|
|
136
|
+
refreshContext() { }
|
|
137
|
+
onFocused() { this.activityTracker?.onFocused(); }
|
|
138
|
+
onBlurred() { this.activityTracker?.onBlurred(); }
|
|
139
|
+
sendKey(key) {
|
|
140
|
+
if (!this.envId)
|
|
141
|
+
return;
|
|
142
|
+
const pty = getPty(this.envId);
|
|
143
|
+
if (!pty)
|
|
144
|
+
return;
|
|
145
|
+
const KEY_MAP = {
|
|
146
|
+
escape: '\x1b',
|
|
147
|
+
};
|
|
148
|
+
const sequence = KEY_MAP[key];
|
|
149
|
+
if (sequence) {
|
|
150
|
+
pty.write(sequence);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
getInfo() {
|
|
154
|
+
return {
|
|
155
|
+
sessionId: this.sessionId,
|
|
156
|
+
agentType: 'claude-code-terminal-chatro',
|
|
157
|
+
agentMode: 'terminal+chatRO',
|
|
158
|
+
status: this.status,
|
|
159
|
+
mode: this.mode,
|
|
160
|
+
cwd: this.cwd || undefined,
|
|
161
|
+
capabilities: this.getCapabilities(),
|
|
162
|
+
createdAt: this.createdAt,
|
|
163
|
+
cliSessionId: this.cliSessionId || undefined,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
forkToResumable(afterEventUuid, fromEventUuid, targetDir) {
|
|
167
|
+
const dir = targetDir || this.cwd || os.homedir();
|
|
168
|
+
// Prefer the original resume UUID for parent linking — the CLI creates a new
|
|
169
|
+
// session UUID on --resume, but forks should link to the session the user sees.
|
|
170
|
+
const parentId = this.resumeSessionUuid || this.cliSessionId || this.sessionId;
|
|
171
|
+
return forkEventsToResumable(this.events, afterEventUuid, dir, parentId, fromEventUuid);
|
|
172
|
+
}
|
|
173
|
+
getCliSessionId() {
|
|
174
|
+
return this.cliSessionId;
|
|
175
|
+
}
|
|
176
|
+
getMessages() {
|
|
177
|
+
return this.wireMessages;
|
|
178
|
+
}
|
|
179
|
+
getEvents() {
|
|
180
|
+
return this.events;
|
|
181
|
+
}
|
|
182
|
+
getWireMessages() {
|
|
183
|
+
const wireToolUses = new Map();
|
|
184
|
+
const result = [];
|
|
185
|
+
for (const event of this.events) {
|
|
186
|
+
result.push(...toWireMessages(this.sessionId, event, wireToolUses));
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
async loadHistoricalMessages(uuid) {
|
|
191
|
+
try {
|
|
192
|
+
if (!fsSessionScanner.getByUuid(uuid)) {
|
|
193
|
+
fsSessionScanner.invalidate();
|
|
194
|
+
await fsSessionScanner.scan();
|
|
195
|
+
}
|
|
196
|
+
const historicalEvents = await fsSessionScanner.readEvents(uuid);
|
|
197
|
+
this.events.push(...historicalEvents);
|
|
198
|
+
// Track UUIDs so the JSONL watcher skips already-loaded events
|
|
199
|
+
for (const event of historicalEvents) {
|
|
200
|
+
if (event.uuid)
|
|
201
|
+
this.preloadedUuids.add(event.uuid);
|
|
202
|
+
}
|
|
203
|
+
// Replay events through toWireMessages for correlation
|
|
204
|
+
const historyToolUses = new Map();
|
|
205
|
+
for (const event of historicalEvents) {
|
|
206
|
+
const wireMsgs = toWireMessages(this.sessionId, event, historyToolUses);
|
|
207
|
+
for (const msg of wireMsgs) {
|
|
208
|
+
if (event.timestamp)
|
|
209
|
+
msg.timestamp = event.timestamp;
|
|
210
|
+
if (msg.type === 'tool_result' && !msg.isPending) {
|
|
211
|
+
const pendingIdx = this.wireMessages.findIndex(m => m.type === 'tool_result' && m.isPending && m.requestId === msg.requestId);
|
|
212
|
+
if (pendingIdx >= 0) {
|
|
213
|
+
this.wireMessages[pendingIdx] = msg;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
this.wireMessages.push(msg);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// Sync pendingToolUses with the history replay state
|
|
221
|
+
for (const [id, info] of historyToolUses) {
|
|
222
|
+
this.pendingToolUses.set(id, info);
|
|
223
|
+
}
|
|
224
|
+
console.log(`[terminal-chatro] Loaded ${this.wireMessages.length} historical messages for resume of ${uuid}`);
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
console.warn(`[terminal-chatro] Failed to load historical messages for ${uuid}:`, err.message);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
handleJsonlEvent(event, metadata) {
|
|
231
|
+
// Skip file-history-snapshot events
|
|
232
|
+
if (event.type === 'file-history-snapshot')
|
|
233
|
+
return;
|
|
234
|
+
// Skip events already loaded from historical pre-load
|
|
235
|
+
if (event.uuid && this.preloadedUuids.has(event.uuid))
|
|
236
|
+
return;
|
|
237
|
+
// Skip progress events from the main file when we're tailing the subagent's own file
|
|
238
|
+
// (progress events are condensed duplicates of the full subagent transcript)
|
|
239
|
+
if (!metadata && event.type === 'progress' && event.data?.agentId) {
|
|
240
|
+
if (this.jsonlWatcher && this.jsonlWatcher.tailedAgentIds.has(event.data.agentId)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Store the raw event as a SessionEvent
|
|
245
|
+
this.events.push(event);
|
|
246
|
+
// Level 3: detect file-modifying tool results
|
|
247
|
+
this.toolTracker?.processEvent(event);
|
|
248
|
+
// Track sidechain sessions (from main file events)
|
|
249
|
+
if (!metadata && event.isSidechain && event.parentUuid) {
|
|
250
|
+
if (event.sessionId) {
|
|
251
|
+
this.sidechainSessions.set(event.sessionId, event.parentUuid);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Determine sidechain parentToolUseId:
|
|
255
|
+
// 1. From subagent metadata (subagent file tailing)
|
|
256
|
+
// 2. From event's own isSidechain + parentUuid fields
|
|
257
|
+
// 3. From tracked sidechain sessions
|
|
258
|
+
const parentToolUseId = metadata
|
|
259
|
+
? metadata.parentToolUseID
|
|
260
|
+
: (event.isSidechain && event.parentUuid)
|
|
261
|
+
? event.parentUuid
|
|
262
|
+
: (event.sessionId && this.sidechainSessions.has(event.sessionId))
|
|
263
|
+
? this.sidechainSessions.get(event.sessionId)
|
|
264
|
+
: undefined;
|
|
265
|
+
const isSidechain = !!metadata || !!parentToolUseId;
|
|
266
|
+
const agentId = metadata?.agentId;
|
|
267
|
+
// Map JSONL event to WireMessages
|
|
268
|
+
const mapped = toWireMessages(this.sessionId, event, this.pendingToolUses);
|
|
269
|
+
for (const msg of mapped) {
|
|
270
|
+
// Tag sidechain messages
|
|
271
|
+
if (isSidechain && parentToolUseId) {
|
|
272
|
+
msg._sidechain = true;
|
|
273
|
+
msg._parentToolUseId = parentToolUseId;
|
|
274
|
+
}
|
|
275
|
+
if (agentId) {
|
|
276
|
+
msg._agentId = agentId;
|
|
277
|
+
}
|
|
278
|
+
this.wireMessages.push(msg);
|
|
279
|
+
this.emit('message', msg);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
getCapabilities() {
|
|
283
|
+
return {
|
|
284
|
+
canChangeMode: false,
|
|
285
|
+
canChangeModel: false,
|
|
286
|
+
hasContextUsage: false,
|
|
287
|
+
canFork: true,
|
|
288
|
+
canResume: true,
|
|
289
|
+
hasTerminal: true,
|
|
290
|
+
hasFileTracking: true,
|
|
291
|
+
availableModes: [],
|
|
292
|
+
availableModels: [],
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
setStatus(status) {
|
|
296
|
+
if (this.status === status)
|
|
297
|
+
return;
|
|
298
|
+
this.status = status;
|
|
299
|
+
this.emit('status', status);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentFactory, Agent, AgentDescriptor, HistoricalSession } from '../types.js';
|
|
2
|
+
import type { SessionEvent } from '../../events/types.js';
|
|
3
|
+
export declare class ClaudeCodeTerminalChatROAgentFactory implements AgentFactory {
|
|
4
|
+
agentType: string;
|
|
5
|
+
agentFamily: string;
|
|
6
|
+
create(sessionId: string): Agent;
|
|
7
|
+
getDescriptor(): AgentDescriptor;
|
|
8
|
+
getHistoricalSessions(): Promise<HistoricalSession[]>;
|
|
9
|
+
ownsSession(uuid: string): Promise<boolean>;
|
|
10
|
+
getSessionFilesForProject(cwds: string[]): Promise<string[]>;
|
|
11
|
+
readSessionEvents(uuid: string): Promise<SessionEvent[]>;
|
|
12
|
+
writeSessionForResume(events: SessionEvent[], targetUuid: string, directory: string): string;
|
|
13
|
+
}
|