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,133 @@
|
|
|
1
|
+
import pg from 'pg';
|
|
2
|
+
export class PostgreSQLDriver {
|
|
3
|
+
pool = null;
|
|
4
|
+
async connect(params) {
|
|
5
|
+
if (params.connection_string) {
|
|
6
|
+
this.pool = new pg.Pool({ connectionString: params.connection_string, max: 5 });
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
this.pool = new pg.Pool({
|
|
10
|
+
host: params.host || 'localhost',
|
|
11
|
+
port: params.port || 5432,
|
|
12
|
+
user: params.username || 'postgres',
|
|
13
|
+
password: params.password || '',
|
|
14
|
+
database: params.database || 'postgres',
|
|
15
|
+
max: 5,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
// Test connection
|
|
19
|
+
const client = await this.pool.connect();
|
|
20
|
+
client.release();
|
|
21
|
+
}
|
|
22
|
+
async disconnect() {
|
|
23
|
+
if (this.pool) {
|
|
24
|
+
await this.pool.end();
|
|
25
|
+
this.pool = null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
isConnected() {
|
|
29
|
+
return this.pool !== null;
|
|
30
|
+
}
|
|
31
|
+
async query(sql, limit = 100) {
|
|
32
|
+
if (!this.pool)
|
|
33
|
+
throw new Error('Not connected');
|
|
34
|
+
const start = Date.now();
|
|
35
|
+
const result = await this.pool.query(sql);
|
|
36
|
+
const elapsed = Date.now() - start;
|
|
37
|
+
const rows = result.rows || [];
|
|
38
|
+
const columns = result.fields?.map(f => f.name) || (rows.length > 0 ? Object.keys(rows[0]) : []);
|
|
39
|
+
const truncated = rows.length > limit;
|
|
40
|
+
return {
|
|
41
|
+
columns,
|
|
42
|
+
rows: rows.slice(0, limit),
|
|
43
|
+
row_count: result.rowCount ?? rows.length,
|
|
44
|
+
execution_time_ms: elapsed,
|
|
45
|
+
truncated,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async getTables() {
|
|
49
|
+
if (!this.pool)
|
|
50
|
+
throw new Error('Not connected');
|
|
51
|
+
const result = await this.pool.query(`
|
|
52
|
+
SELECT
|
|
53
|
+
t.table_name AS name,
|
|
54
|
+
t.table_type AS type,
|
|
55
|
+
pg_total_relation_size(quote_ident(t.table_schema) || '.' || quote_ident(t.table_name))::bigint AS size_bytes,
|
|
56
|
+
s.n_live_tup AS row_count
|
|
57
|
+
FROM information_schema.tables t
|
|
58
|
+
LEFT JOIN pg_stat_user_tables s ON s.relname = t.table_name AND s.schemaname = t.table_schema
|
|
59
|
+
WHERE t.table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
60
|
+
ORDER BY t.table_name
|
|
61
|
+
`);
|
|
62
|
+
return result.rows.map(r => ({
|
|
63
|
+
name: r.name,
|
|
64
|
+
type: r.type === 'BASE TABLE' ? 'table' : r.type?.toLowerCase(),
|
|
65
|
+
row_count: parseInt(r.row_count) || undefined,
|
|
66
|
+
size_bytes: parseInt(r.size_bytes) || undefined,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
async describeTable(table) {
|
|
70
|
+
if (!this.pool)
|
|
71
|
+
throw new Error('Not connected');
|
|
72
|
+
// Columns
|
|
73
|
+
const cols = await this.pool.query(`
|
|
74
|
+
SELECT
|
|
75
|
+
c.column_name, c.data_type, c.is_nullable, c.column_default,
|
|
76
|
+
CASE WHEN pk.column_name IS NOT NULL THEN true ELSE false END AS is_pk
|
|
77
|
+
FROM information_schema.columns c
|
|
78
|
+
LEFT JOIN (
|
|
79
|
+
SELECT ku.column_name
|
|
80
|
+
FROM information_schema.table_constraints tc
|
|
81
|
+
JOIN information_schema.key_column_usage ku ON tc.constraint_name = ku.constraint_name
|
|
82
|
+
WHERE tc.table_name = $1 AND tc.constraint_type = 'PRIMARY KEY'
|
|
83
|
+
) pk ON pk.column_name = c.column_name
|
|
84
|
+
WHERE c.table_name = $1 AND c.table_schema NOT IN ('information_schema', 'pg_catalog')
|
|
85
|
+
ORDER BY c.ordinal_position
|
|
86
|
+
`, [table]);
|
|
87
|
+
const columns = cols.rows.map(r => ({
|
|
88
|
+
name: r.column_name,
|
|
89
|
+
type: r.data_type,
|
|
90
|
+
nullable: r.is_nullable === 'YES',
|
|
91
|
+
default_value: r.column_default || undefined,
|
|
92
|
+
primary_key: r.is_pk,
|
|
93
|
+
}));
|
|
94
|
+
// Indexes
|
|
95
|
+
const idxResult = await this.pool.query(`
|
|
96
|
+
SELECT indexname AS name, indexdef
|
|
97
|
+
FROM pg_indexes
|
|
98
|
+
WHERE tablename = $1 AND schemaname NOT IN ('information_schema', 'pg_catalog')
|
|
99
|
+
`, [table]);
|
|
100
|
+
const indexes = idxResult.rows.map(r => ({
|
|
101
|
+
name: r.name,
|
|
102
|
+
columns: (r.indexdef.match(/\(([^)]+)\)/)?.[1] || '').split(',').map((s) => s.trim()),
|
|
103
|
+
unique: /UNIQUE/i.test(r.indexdef),
|
|
104
|
+
}));
|
|
105
|
+
// Foreign keys
|
|
106
|
+
const fkResult = await this.pool.query(`
|
|
107
|
+
SELECT
|
|
108
|
+
kcu.column_name AS column,
|
|
109
|
+
ccu.table_name AS ref_table,
|
|
110
|
+
ccu.column_name AS ref_column
|
|
111
|
+
FROM information_schema.table_constraints tc
|
|
112
|
+
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
|
|
113
|
+
JOIN information_schema.constraint_column_usage ccu ON tc.constraint_name = ccu.constraint_name
|
|
114
|
+
WHERE tc.table_name = $1 AND tc.constraint_type = 'FOREIGN KEY'
|
|
115
|
+
`, [table]);
|
|
116
|
+
return {
|
|
117
|
+
table,
|
|
118
|
+
columns,
|
|
119
|
+
indexes,
|
|
120
|
+
foreign_keys: fkResult.rows.map(r => ({
|
|
121
|
+
column: r.column,
|
|
122
|
+
ref_table: r.ref_table,
|
|
123
|
+
ref_column: r.ref_column,
|
|
124
|
+
})),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async getDatabases() {
|
|
128
|
+
if (!this.pool)
|
|
129
|
+
throw new Error('Not connected');
|
|
130
|
+
const result = await this.pool.query(`SELECT datname FROM pg_database WHERE datistemplate = false ORDER BY datname`);
|
|
131
|
+
return result.rows.map(r => r.datname);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConnectionParams, DatabaseDriver, QueryResult, TableInfo, SchemaInfo } from '../types.js';
|
|
2
|
+
export declare class RedisDriver implements DatabaseDriver {
|
|
3
|
+
private client;
|
|
4
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
5
|
+
disconnect(): Promise<void>;
|
|
6
|
+
isConnected(): boolean;
|
|
7
|
+
query(command: string, limit?: number): Promise<QueryResult>;
|
|
8
|
+
getTables(): Promise<TableInfo[]>;
|
|
9
|
+
describeTable(pattern: string): Promise<SchemaInfo>;
|
|
10
|
+
getDatabases(): Promise<string[]>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import RedisLib from 'ioredis';
|
|
2
|
+
const Redis = RedisLib.Redis || RedisLib;
|
|
3
|
+
export class RedisDriver {
|
|
4
|
+
client = null;
|
|
5
|
+
async connect(params) {
|
|
6
|
+
if (params.connection_string) {
|
|
7
|
+
this.client = new Redis(params.connection_string, { lazyConnect: true });
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
this.client = new Redis({
|
|
11
|
+
host: params.host || 'localhost',
|
|
12
|
+
port: params.port || 6379,
|
|
13
|
+
password: params.password || undefined,
|
|
14
|
+
db: params.database ? parseInt(params.database) : 0,
|
|
15
|
+
lazyConnect: true,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
await this.client.connect();
|
|
19
|
+
}
|
|
20
|
+
async disconnect() {
|
|
21
|
+
if (this.client) {
|
|
22
|
+
this.client.disconnect();
|
|
23
|
+
this.client = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
isConnected() {
|
|
27
|
+
return this.client !== null && this.client.status === 'ready';
|
|
28
|
+
}
|
|
29
|
+
async query(command, limit = 100) {
|
|
30
|
+
if (!this.client)
|
|
31
|
+
throw new Error('Not connected');
|
|
32
|
+
const start = Date.now();
|
|
33
|
+
const parts = command.trim().split(/\s+/);
|
|
34
|
+
const cmd = parts[0].toUpperCase();
|
|
35
|
+
const args = parts.slice(1);
|
|
36
|
+
const result = await this.client.call(cmd, ...args);
|
|
37
|
+
const elapsed = Date.now() - start;
|
|
38
|
+
// Format result based on type
|
|
39
|
+
if (Array.isArray(result)) {
|
|
40
|
+
// KEYS, SCAN results, etc
|
|
41
|
+
const rows = result.slice(0, limit).map((v, i) => ({ index: i, value: typeof v === 'object' ? JSON.stringify(v) : String(v) }));
|
|
42
|
+
return { columns: ['index', 'value'], rows, row_count: result.length, execution_time_ms: elapsed, truncated: result.length > limit };
|
|
43
|
+
}
|
|
44
|
+
if (result !== null && typeof result === 'object') {
|
|
45
|
+
const entries = Object.entries(result).slice(0, limit);
|
|
46
|
+
const rows = entries.map(([k, v]) => ({ key: k, value: String(v) }));
|
|
47
|
+
return { columns: ['key', 'value'], rows, row_count: entries.length, execution_time_ms: elapsed };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
columns: ['result'],
|
|
51
|
+
rows: [{ result: result === null ? '(nil)' : String(result) }],
|
|
52
|
+
row_count: 1,
|
|
53
|
+
execution_time_ms: elapsed,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async getTables() {
|
|
57
|
+
if (!this.client)
|
|
58
|
+
throw new Error('Not connected');
|
|
59
|
+
const dbSize = await this.client.dbsize();
|
|
60
|
+
// Get a sample of keys
|
|
61
|
+
const keys = await this.client.keys('*');
|
|
62
|
+
const sample = keys.slice(0, 100);
|
|
63
|
+
// Group by prefix (before first :)
|
|
64
|
+
const prefixes = new Map();
|
|
65
|
+
for (const key of sample) {
|
|
66
|
+
const prefix = key.includes(':') ? key.split(':')[0] + ':*' : key;
|
|
67
|
+
prefixes.set(prefix, (prefixes.get(prefix) || 0) + 1);
|
|
68
|
+
}
|
|
69
|
+
return [
|
|
70
|
+
{ name: `(${dbSize} total keys)`, type: 'keyspace', row_count: dbSize },
|
|
71
|
+
...[...prefixes.entries()].map(([name, count]) => ({ name, type: 'pattern', row_count: count })),
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
async describeTable(pattern) {
|
|
75
|
+
if (!this.client)
|
|
76
|
+
throw new Error('Not connected');
|
|
77
|
+
// For Redis, "describe" a key pattern by sampling
|
|
78
|
+
const keys = await this.client.keys(pattern.replace('*', '') + '*');
|
|
79
|
+
const sample = keys.slice(0, 10);
|
|
80
|
+
const columns = [];
|
|
81
|
+
for (const key of sample) {
|
|
82
|
+
const type = await this.client.type(key);
|
|
83
|
+
const ttl = await this.client.ttl(key);
|
|
84
|
+
columns.push({ name: key, type: `${type} (TTL: ${ttl === -1 ? 'none' : ttl + 's'})`, nullable: false });
|
|
85
|
+
}
|
|
86
|
+
return { table: pattern, columns, indexes: [], foreign_keys: [] };
|
|
87
|
+
}
|
|
88
|
+
async getDatabases() {
|
|
89
|
+
return Array.from({ length: 16 }, (_, i) => String(i));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ConnectionParams, DatabaseDriver, QueryResult, TableInfo, SchemaInfo } from '../types.js';
|
|
2
|
+
export declare class SQLiteDriver implements DatabaseDriver {
|
|
3
|
+
private db;
|
|
4
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
5
|
+
disconnect(): Promise<void>;
|
|
6
|
+
isConnected(): boolean;
|
|
7
|
+
query(sql: string, limit?: number): Promise<QueryResult>;
|
|
8
|
+
getTables(): Promise<TableInfo[]>;
|
|
9
|
+
describeTable(table: string): Promise<SchemaInfo>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
export class SQLiteDriver {
|
|
3
|
+
db = null;
|
|
4
|
+
async connect(params) {
|
|
5
|
+
const file = params.filename || params.database;
|
|
6
|
+
if (!file)
|
|
7
|
+
throw new Error('filename is required for SQLite');
|
|
8
|
+
const isReadonly = params._readonly === true;
|
|
9
|
+
this.db = new Database(file, { readonly: isReadonly });
|
|
10
|
+
if (!isReadonly) {
|
|
11
|
+
this.db.pragma('journal_mode = WAL');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async disconnect() {
|
|
15
|
+
if (this.db) {
|
|
16
|
+
this.db.close();
|
|
17
|
+
this.db = null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
isConnected() {
|
|
21
|
+
return this.db !== null;
|
|
22
|
+
}
|
|
23
|
+
async query(sql, limit = 100) {
|
|
24
|
+
if (!this.db)
|
|
25
|
+
throw new Error('Not connected');
|
|
26
|
+
const start = Date.now();
|
|
27
|
+
const trimmed = sql.trim();
|
|
28
|
+
const isSelect = /^(SELECT|PRAGMA|EXPLAIN|WITH)\b/i.test(trimmed);
|
|
29
|
+
if (isSelect) {
|
|
30
|
+
const stmt = this.db.prepare(sql);
|
|
31
|
+
const rows = stmt.all();
|
|
32
|
+
const elapsed = Date.now() - start;
|
|
33
|
+
const columns = rows.length > 0 ? Object.keys(rows[0]) : [];
|
|
34
|
+
const truncated = rows.length > limit;
|
|
35
|
+
return {
|
|
36
|
+
columns,
|
|
37
|
+
rows: rows.slice(0, limit),
|
|
38
|
+
row_count: rows.length,
|
|
39
|
+
execution_time_ms: elapsed,
|
|
40
|
+
truncated,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const result = this.db.prepare(sql).run();
|
|
45
|
+
const elapsed = Date.now() - start;
|
|
46
|
+
return {
|
|
47
|
+
columns: ['changes', 'lastInsertRowid'],
|
|
48
|
+
rows: [{ changes: result.changes, lastInsertRowid: Number(result.lastInsertRowid) }],
|
|
49
|
+
row_count: result.changes,
|
|
50
|
+
execution_time_ms: elapsed,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async getTables() {
|
|
55
|
+
if (!this.db)
|
|
56
|
+
throw new Error('Not connected');
|
|
57
|
+
const tables = this.db.prepare(`
|
|
58
|
+
SELECT name, type FROM sqlite_master
|
|
59
|
+
WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
|
|
60
|
+
ORDER BY name
|
|
61
|
+
`).all();
|
|
62
|
+
return tables.map(t => {
|
|
63
|
+
let row_count;
|
|
64
|
+
try {
|
|
65
|
+
const cnt = this.db.prepare(`SELECT COUNT(*) as c FROM "${t.name}"`).get();
|
|
66
|
+
row_count = cnt?.c;
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
69
|
+
return { name: t.name, type: t.type, row_count };
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async describeTable(table) {
|
|
73
|
+
if (!this.db)
|
|
74
|
+
throw new Error('Not connected');
|
|
75
|
+
const cols = this.db.prepare(`PRAGMA table_info("${table}")`).all();
|
|
76
|
+
const columns = cols.map(c => ({
|
|
77
|
+
name: c.name,
|
|
78
|
+
type: c.type,
|
|
79
|
+
nullable: !c.notnull,
|
|
80
|
+
default_value: c.dflt_value || undefined,
|
|
81
|
+
primary_key: !!c.pk,
|
|
82
|
+
}));
|
|
83
|
+
const idxList = this.db.prepare(`PRAGMA index_list("${table}")`).all();
|
|
84
|
+
const indexes = idxList.map(idx => {
|
|
85
|
+
const idxInfo = this.db.prepare(`PRAGMA index_info("${idx.name}")`).all();
|
|
86
|
+
return {
|
|
87
|
+
name: idx.name,
|
|
88
|
+
columns: idxInfo.map(i => i.name),
|
|
89
|
+
unique: !!idx.unique,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
const fks = this.db.prepare(`PRAGMA foreign_key_list("${table}")`).all();
|
|
93
|
+
const foreign_keys = fks.map(fk => ({
|
|
94
|
+
column: fk.from,
|
|
95
|
+
ref_table: fk.table,
|
|
96
|
+
ref_column: fk.to,
|
|
97
|
+
}));
|
|
98
|
+
return { table, columns, indexes, foreign_keys };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WebSocketServer } from 'ws';
|
|
2
|
+
import type { IncomingMessage } from 'http';
|
|
3
|
+
import type { Duplex } from 'stream';
|
|
4
|
+
export declare function isDatabaseWsUpgrade(url: string): boolean;
|
|
5
|
+
export declare function handleDatabaseWsUpgrade(wss: WebSocketServer, req: IncomingMessage, socket: Duplex, head: Buffer): void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { connectionManager } from './connection-manager.js';
|
|
2
|
+
const WS_PATH_RE = /^\/ws\/database-query\/([^/?]+)/;
|
|
3
|
+
const BATCH_SIZE = 100;
|
|
4
|
+
const KEEPALIVE_INTERVAL_MS = 30_000;
|
|
5
|
+
export function isDatabaseWsUpgrade(url) {
|
|
6
|
+
return WS_PATH_RE.test(url);
|
|
7
|
+
}
|
|
8
|
+
export function handleDatabaseWsUpgrade(wss, req, socket, head) {
|
|
9
|
+
const match = (req.url ?? '').match(WS_PATH_RE);
|
|
10
|
+
if (!match) {
|
|
11
|
+
socket.destroy();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const connectionId = decodeURIComponent(match[1]);
|
|
15
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
16
|
+
wss.emit('connection', ws, req);
|
|
17
|
+
setupQuerySocket(ws, connectionId);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function send(ws, data) {
|
|
21
|
+
if (ws.readyState === ws.OPEN) {
|
|
22
|
+
ws.send(JSON.stringify(data));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function setupQuerySocket(ws, connectionId) {
|
|
26
|
+
const keepAlive = setInterval(() => {
|
|
27
|
+
if (ws.readyState === ws.OPEN) {
|
|
28
|
+
ws.ping();
|
|
29
|
+
}
|
|
30
|
+
}, KEEPALIVE_INTERVAL_MS);
|
|
31
|
+
ws.on('close', () => {
|
|
32
|
+
clearInterval(keepAlive);
|
|
33
|
+
});
|
|
34
|
+
ws.on('message', async (raw) => {
|
|
35
|
+
let msg;
|
|
36
|
+
try {
|
|
37
|
+
msg = JSON.parse(typeof raw === 'string' ? raw : raw.toString('utf-8'));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
send(ws, { type: 'error', message: 'Invalid JSON' });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (msg.type !== 'query' || typeof msg.query !== 'string') {
|
|
44
|
+
send(ws, { type: 'error', message: 'Expected message of type "query" with a "query" string field' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const limit = typeof msg.limit === 'number' && msg.limit > 0 ? msg.limit : undefined;
|
|
48
|
+
try {
|
|
49
|
+
const startTime = performance.now();
|
|
50
|
+
const result = await connectionManager.query(connectionId, msg.query, limit);
|
|
51
|
+
const executionTimeMs = Math.round(performance.now() - startTime);
|
|
52
|
+
// Send column names first
|
|
53
|
+
send(ws, { type: 'columns', columns: result.columns });
|
|
54
|
+
// Send rows in batches
|
|
55
|
+
const rows = result.rows;
|
|
56
|
+
let batchNumber = 0;
|
|
57
|
+
for (let offset = 0; offset < rows.length; offset += BATCH_SIZE) {
|
|
58
|
+
const batch = rows.slice(offset, offset + BATCH_SIZE);
|
|
59
|
+
send(ws, { type: 'rows', rows: batch, batch: batchNumber });
|
|
60
|
+
batchNumber++;
|
|
61
|
+
}
|
|
62
|
+
// Send completion message
|
|
63
|
+
send(ws, {
|
|
64
|
+
type: 'complete',
|
|
65
|
+
row_count: result.row_count,
|
|
66
|
+
execution_time_ms: executionTimeMs,
|
|
67
|
+
truncated: result.truncated ?? false,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
72
|
+
send(ws, { type: 'error', message });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export type DbType = 'postgresql' | 'mysql' | 'mariadb' | 'sqlite' | 'redis' | 'mongodb' | 'elasticsearch' | 'opensearch' | 'clickhouse' | 'cockroachdb' | 'cassandra' | 'scylladb' | 'neo4j' | 'influxdb' | 'memcached';
|
|
2
|
+
export type DiscoverySource = 'local' | 'container' | 'manual' | 'ssh';
|
|
3
|
+
export interface ConnectionParams {
|
|
4
|
+
host?: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
username?: string;
|
|
7
|
+
password?: string;
|
|
8
|
+
database?: string;
|
|
9
|
+
filename?: string;
|
|
10
|
+
connection_string?: string;
|
|
11
|
+
/** SSH tunnel: Atoo Studio SSH connection ID */
|
|
12
|
+
ssh_connection_id?: string;
|
|
13
|
+
/** SSH tunnel: remote host (default 127.0.0.1) */
|
|
14
|
+
ssh_remote_host?: string;
|
|
15
|
+
/** SSH tunnel: remote port (defaults to the DB's default port) */
|
|
16
|
+
ssh_remote_port?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface DiscoveredDatabase {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
db_type: DbType;
|
|
22
|
+
source: DiscoverySource;
|
|
23
|
+
params: ConnectionParams;
|
|
24
|
+
/** e.g. container name, file path */
|
|
25
|
+
source_detail?: string;
|
|
26
|
+
connected?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface QueryResult {
|
|
29
|
+
columns: string[];
|
|
30
|
+
rows: Record<string, any>[];
|
|
31
|
+
row_count: number;
|
|
32
|
+
execution_time_ms: number;
|
|
33
|
+
truncated?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface TableInfo {
|
|
36
|
+
name: string;
|
|
37
|
+
type?: string;
|
|
38
|
+
row_count?: number;
|
|
39
|
+
size_bytes?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ColumnInfo {
|
|
42
|
+
name: string;
|
|
43
|
+
type: string;
|
|
44
|
+
nullable: boolean;
|
|
45
|
+
default_value?: string;
|
|
46
|
+
primary_key?: boolean;
|
|
47
|
+
comment?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface SchemaInfo {
|
|
50
|
+
table: string;
|
|
51
|
+
columns: ColumnInfo[];
|
|
52
|
+
indexes?: {
|
|
53
|
+
name: string;
|
|
54
|
+
columns: string[];
|
|
55
|
+
unique: boolean;
|
|
56
|
+
}[];
|
|
57
|
+
foreign_keys?: {
|
|
58
|
+
column: string;
|
|
59
|
+
ref_table: string;
|
|
60
|
+
ref_column: string;
|
|
61
|
+
}[];
|
|
62
|
+
}
|
|
63
|
+
export interface DatabaseDriver {
|
|
64
|
+
connect(params: ConnectionParams): Promise<void>;
|
|
65
|
+
disconnect(): Promise<void>;
|
|
66
|
+
isConnected(): boolean;
|
|
67
|
+
query(sql: string, limit?: number): Promise<QueryResult>;
|
|
68
|
+
getTables(): Promise<TableInfo[]>;
|
|
69
|
+
describeTable(table: string): Promise<SchemaInfo>;
|
|
70
|
+
getDatabases?(): Promise<string[]>;
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export { toWireMessages, tryParseContextUsageWire } from './wire.js';
|
|
3
|
+
export type { WireMessage, WireUserMessage, WireAssistantMessage, WireThinking, WireToolUse, WireToolRequest, WireQuestion, WireQuestionItem, WirePlanApproval, WireStatusUpdate, WireContextUsage, WireSystemMessage, WireResult, WireAttachment, } from './wire.js';
|