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,307 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { getFileTree } from './fs-browser.js';
|
|
4
|
+
import * as gitOps from './git-ops.js';
|
|
5
|
+
import { store } from '../state/store.js';
|
|
6
|
+
import { db } from '../state/db.js';
|
|
7
|
+
// Debounce interval for filesystem events (ms)
|
|
8
|
+
const DEBOUNCE_MS = 500;
|
|
9
|
+
const watches = new Map();
|
|
10
|
+
function broadcastToStatus(msg) {
|
|
11
|
+
const data = JSON.stringify(msg);
|
|
12
|
+
for (const ws of store.statusClients) {
|
|
13
|
+
if (ws.readyState === 1)
|
|
14
|
+
ws.send(data);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function handleFileChange(entry) {
|
|
18
|
+
if (entry.debounceTimer)
|
|
19
|
+
clearTimeout(entry.debounceTimer);
|
|
20
|
+
entry.debounceTimer = setTimeout(async () => {
|
|
21
|
+
entry.debounceTimer = null;
|
|
22
|
+
try {
|
|
23
|
+
const files = await getFileTree(entry.projectPath, 0, false, 1);
|
|
24
|
+
broadcastToStatus({
|
|
25
|
+
type: 'project_files_changed',
|
|
26
|
+
projectId: entry.projectId,
|
|
27
|
+
projectPath: entry.projectPath,
|
|
28
|
+
files,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
console.error(`[project-watcher] Error reading file tree for ${entry.projectId}:`, err);
|
|
33
|
+
}
|
|
34
|
+
// Also refresh git status — working tree changes affect git status
|
|
35
|
+
if (entry.gitWatcher) {
|
|
36
|
+
handleGitChange(entry);
|
|
37
|
+
}
|
|
38
|
+
}, DEBOUNCE_MS);
|
|
39
|
+
}
|
|
40
|
+
async function handleGitChange(entry) {
|
|
41
|
+
if (entry.gitDebounceTimer)
|
|
42
|
+
clearTimeout(entry.gitDebounceTimer);
|
|
43
|
+
entry.gitDebounceTimer = setTimeout(async () => {
|
|
44
|
+
entry.gitDebounceTimer = null;
|
|
45
|
+
try {
|
|
46
|
+
const [status, branches, stashes, remotes] = await Promise.all([
|
|
47
|
+
gitOps.gitStatus(entry.projectPath),
|
|
48
|
+
gitOps.gitBranches(entry.projectPath),
|
|
49
|
+
gitOps.gitStashList(entry.projectPath),
|
|
50
|
+
gitOps.gitRemotes(entry.projectPath),
|
|
51
|
+
]);
|
|
52
|
+
let commits = [];
|
|
53
|
+
try {
|
|
54
|
+
commits = await gitOps.gitLog(entry.projectPath, undefined, 30);
|
|
55
|
+
}
|
|
56
|
+
catch { }
|
|
57
|
+
// Also refresh file tree — git operations (revert, checkout, stash) change working tree
|
|
58
|
+
try {
|
|
59
|
+
const files = await getFileTree(entry.projectPath, 0, false, 1);
|
|
60
|
+
broadcastToStatus({
|
|
61
|
+
type: 'project_files_changed',
|
|
62
|
+
projectId: entry.projectId,
|
|
63
|
+
projectPath: entry.projectPath,
|
|
64
|
+
files,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch { }
|
|
68
|
+
broadcastToStatus({
|
|
69
|
+
type: 'project_git_changed',
|
|
70
|
+
projectId: entry.projectId,
|
|
71
|
+
projectPath: entry.projectPath,
|
|
72
|
+
gitChanges: status,
|
|
73
|
+
gitLog: {
|
|
74
|
+
branches: branches.branches,
|
|
75
|
+
currentBranch: branches.currentBranch,
|
|
76
|
+
remotes,
|
|
77
|
+
commits,
|
|
78
|
+
},
|
|
79
|
+
stashes,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.error(`[project-watcher] Error reading git data for ${entry.projectId}:`, err);
|
|
84
|
+
}
|
|
85
|
+
}, DEBOUNCE_MS);
|
|
86
|
+
}
|
|
87
|
+
// Reconcile worktree-linked projects: read .git/worktrees/ subdirectories and
|
|
88
|
+
// ensure each worktree has a corresponding child project in the DB.
|
|
89
|
+
function handleWorktreesChange(entry) {
|
|
90
|
+
if (entry.worktreesDebounceTimer)
|
|
91
|
+
clearTimeout(entry.worktreesDebounceTimer);
|
|
92
|
+
entry.worktreesDebounceTimer = setTimeout(() => {
|
|
93
|
+
entry.worktreesDebounceTimer = null;
|
|
94
|
+
reconcileWorktrees(entry.projectId, entry.projectPath);
|
|
95
|
+
}, DEBOUNCE_MS);
|
|
96
|
+
}
|
|
97
|
+
export function reconcileWorktrees(projectId, projectPath) {
|
|
98
|
+
const worktreesDir = path.join(projectPath, '.git', 'worktrees');
|
|
99
|
+
const discoveredPaths = new Map(); // wtPath -> branch
|
|
100
|
+
if (fs.existsSync(worktreesDir)) {
|
|
101
|
+
try {
|
|
102
|
+
const entries = fs.readdirSync(worktreesDir, { withFileTypes: true });
|
|
103
|
+
for (const ent of entries) {
|
|
104
|
+
if (!ent.isDirectory())
|
|
105
|
+
continue;
|
|
106
|
+
const wtDir = path.join(worktreesDir, ent.name);
|
|
107
|
+
// Read gitdir to find the worktree path
|
|
108
|
+
const gitdirFile = path.join(wtDir, 'gitdir');
|
|
109
|
+
if (!fs.existsSync(gitdirFile))
|
|
110
|
+
continue;
|
|
111
|
+
try {
|
|
112
|
+
const gitdirContent = fs.readFileSync(gitdirFile, 'utf8').trim();
|
|
113
|
+
// gitdir points to <worktree-path>/.git — so the worktree path is the parent
|
|
114
|
+
const wtPath = path.dirname(gitdirContent);
|
|
115
|
+
// Read branch from HEAD
|
|
116
|
+
let branch = ent.name;
|
|
117
|
+
const headFile = path.join(wtDir, 'HEAD');
|
|
118
|
+
if (fs.existsSync(headFile)) {
|
|
119
|
+
const headContent = fs.readFileSync(headFile, 'utf8').trim();
|
|
120
|
+
const match = headContent.match(/^ref: refs\/heads\/(.+)$/);
|
|
121
|
+
if (match)
|
|
122
|
+
branch = match[1];
|
|
123
|
+
}
|
|
124
|
+
discoveredPaths.set(wtPath, branch);
|
|
125
|
+
}
|
|
126
|
+
catch { }
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch { }
|
|
130
|
+
}
|
|
131
|
+
// Get existing child projects
|
|
132
|
+
const existingChildren = db.getChildProjects(projectId);
|
|
133
|
+
const existingPaths = new Set(existingChildren.map(c => c.path));
|
|
134
|
+
// Get environments this parent is linked to (so we can link new children too)
|
|
135
|
+
const parentEnvs = db.getEnvironmentsForProject(projectId);
|
|
136
|
+
// Record all discovered worktree paths in history (idempotent)
|
|
137
|
+
for (const [wtPath] of discoveredPaths) {
|
|
138
|
+
db.recordWorktreePath(projectId, wtPath);
|
|
139
|
+
}
|
|
140
|
+
// Add new worktrees as child projects
|
|
141
|
+
for (const [wtPath, branch] of discoveredPaths) {
|
|
142
|
+
if (existingPaths.has(wtPath))
|
|
143
|
+
continue;
|
|
144
|
+
console.log(`[project-watcher] Discovered new worktree: ${wtPath} (${branch})`);
|
|
145
|
+
const childProject = db.createProject(branch, wtPath, { parentProjectId: projectId });
|
|
146
|
+
// Link to same environments as parent
|
|
147
|
+
for (const env of parentEnvs) {
|
|
148
|
+
db.linkProject(childProject.id, env.id);
|
|
149
|
+
}
|
|
150
|
+
// Start watching the child project
|
|
151
|
+
watchProject(childProject.id, wtPath);
|
|
152
|
+
// Notify frontend
|
|
153
|
+
broadcastToStatus({ type: 'worktrees_changed', parentProjectId: projectId });
|
|
154
|
+
}
|
|
155
|
+
// Remove child projects whose worktree no longer exists
|
|
156
|
+
for (const child of existingChildren) {
|
|
157
|
+
if (!discoveredPaths.has(child.path)) {
|
|
158
|
+
console.log(`[project-watcher] Worktree removed: ${child.path}`);
|
|
159
|
+
unwatchProject(child.id);
|
|
160
|
+
db.deleteProject(child.id);
|
|
161
|
+
broadcastToStatus({ type: 'worktrees_changed', parentProjectId: projectId });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function startWorktreesWatcher(entry) {
|
|
166
|
+
const worktreesDir = path.join(entry.projectPath, '.git', 'worktrees');
|
|
167
|
+
if (!fs.existsSync(worktreesDir))
|
|
168
|
+
return null;
|
|
169
|
+
try {
|
|
170
|
+
const watcher = fs.watch(worktreesDir, (_eventType, _filename) => {
|
|
171
|
+
const e = watches.get(entry.projectId);
|
|
172
|
+
if (e)
|
|
173
|
+
handleWorktreesChange(e);
|
|
174
|
+
});
|
|
175
|
+
watcher.on('error', () => { });
|
|
176
|
+
return watcher;
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export function watchProject(projectId, projectPath) {
|
|
183
|
+
// Already watching
|
|
184
|
+
if (watches.has(projectId))
|
|
185
|
+
return;
|
|
186
|
+
try {
|
|
187
|
+
const watcher = fs.watch(projectPath, { recursive: true }, (_eventType, filename) => {
|
|
188
|
+
if (!filename)
|
|
189
|
+
return;
|
|
190
|
+
// Skip .git directory changes - handled by git watcher
|
|
191
|
+
if (filename.startsWith('.git' + path.sep) || filename === '.git')
|
|
192
|
+
return;
|
|
193
|
+
const entry = watches.get(projectId);
|
|
194
|
+
if (entry)
|
|
195
|
+
handleFileChange(entry);
|
|
196
|
+
});
|
|
197
|
+
let gitWatcher = null;
|
|
198
|
+
const gitPath = path.join(projectPath, '.git');
|
|
199
|
+
if (fs.existsSync(gitPath)) {
|
|
200
|
+
const stat = fs.statSync(gitPath);
|
|
201
|
+
if (stat.isDirectory()) {
|
|
202
|
+
// Normal project with .git directory
|
|
203
|
+
try {
|
|
204
|
+
gitWatcher = fs.watch(gitPath, { recursive: true }, (_eventType, filename) => {
|
|
205
|
+
const entry = watches.get(projectId);
|
|
206
|
+
if (!entry)
|
|
207
|
+
return;
|
|
208
|
+
handleGitChange(entry);
|
|
209
|
+
// If change is in the worktrees/ subdir or worktrees dir was created/removed, reconcile
|
|
210
|
+
if (filename && (filename === 'worktrees' || filename.startsWith('worktrees' + path.sep))) {
|
|
211
|
+
// Start worktrees watcher if it doesn't exist yet
|
|
212
|
+
if (!entry.worktreesWatcher) {
|
|
213
|
+
entry.worktreesWatcher = startWorktreesWatcher(entry);
|
|
214
|
+
}
|
|
215
|
+
handleWorktreesChange(entry);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
gitWatcher.on('error', () => { });
|
|
219
|
+
}
|
|
220
|
+
catch { }
|
|
221
|
+
}
|
|
222
|
+
else if (stat.isFile()) {
|
|
223
|
+
// Worktree project with .git file pointing to main repo
|
|
224
|
+
try {
|
|
225
|
+
const content = fs.readFileSync(gitPath, 'utf8').trim();
|
|
226
|
+
const match = content.match(/^gitdir:\s*(.+)$/);
|
|
227
|
+
if (match) {
|
|
228
|
+
const gitDir = path.resolve(projectPath, match[1]);
|
|
229
|
+
if (fs.existsSync(gitDir)) {
|
|
230
|
+
gitWatcher = fs.watch(gitDir, { recursive: true }, () => {
|
|
231
|
+
const entry = watches.get(projectId);
|
|
232
|
+
if (entry)
|
|
233
|
+
handleGitChange(entry);
|
|
234
|
+
});
|
|
235
|
+
gitWatcher.on('error', () => { });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch { }
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const entry = {
|
|
243
|
+
watcher,
|
|
244
|
+
gitWatcher,
|
|
245
|
+
worktreesWatcher: null,
|
|
246
|
+
debounceTimer: null,
|
|
247
|
+
gitDebounceTimer: null,
|
|
248
|
+
worktreesDebounceTimer: null,
|
|
249
|
+
projectId,
|
|
250
|
+
projectPath,
|
|
251
|
+
};
|
|
252
|
+
watches.set(projectId, entry);
|
|
253
|
+
// Start worktrees watcher if .git/worktrees/ already exists
|
|
254
|
+
entry.worktreesWatcher = startWorktreesWatcher(entry);
|
|
255
|
+
// Initial reconciliation of worktrees
|
|
256
|
+
const gitPath2 = path.join(projectPath, '.git');
|
|
257
|
+
if (fs.existsSync(gitPath2) && fs.statSync(gitPath2).isDirectory()) {
|
|
258
|
+
reconcileWorktrees(projectId, projectPath);
|
|
259
|
+
}
|
|
260
|
+
watcher.on('error', () => {
|
|
261
|
+
unwatchProject(projectId);
|
|
262
|
+
});
|
|
263
|
+
console.log(`[project-watcher] Watching ${projectPath} (project ${projectId})`);
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
console.error(`[project-watcher] Failed to watch ${projectPath}:`, err);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
export function unwatchProject(projectId) {
|
|
270
|
+
const entry = watches.get(projectId);
|
|
271
|
+
if (!entry)
|
|
272
|
+
return;
|
|
273
|
+
if (entry.debounceTimer)
|
|
274
|
+
clearTimeout(entry.debounceTimer);
|
|
275
|
+
if (entry.gitDebounceTimer)
|
|
276
|
+
clearTimeout(entry.gitDebounceTimer);
|
|
277
|
+
if (entry.worktreesDebounceTimer)
|
|
278
|
+
clearTimeout(entry.worktreesDebounceTimer);
|
|
279
|
+
try {
|
|
280
|
+
entry.watcher.close();
|
|
281
|
+
}
|
|
282
|
+
catch { }
|
|
283
|
+
try {
|
|
284
|
+
entry.gitWatcher?.close();
|
|
285
|
+
}
|
|
286
|
+
catch { }
|
|
287
|
+
try {
|
|
288
|
+
entry.worktreesWatcher?.close();
|
|
289
|
+
}
|
|
290
|
+
catch { }
|
|
291
|
+
watches.delete(projectId);
|
|
292
|
+
console.log(`[project-watcher] Stopped watching project ${projectId}`);
|
|
293
|
+
}
|
|
294
|
+
export function watchEnvironmentProjects(envId) {
|
|
295
|
+
const projects = db.getProjectsForEnvironment(envId);
|
|
296
|
+
for (const proj of projects) {
|
|
297
|
+
watchProject(proj.id, proj.path);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
export function unwatchAll() {
|
|
301
|
+
for (const id of Array.from(watches.keys())) {
|
|
302
|
+
unwatchProject(id);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
export function isWatching(projectId) {
|
|
306
|
+
return watches.has(projectId);
|
|
307
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface FileNode {
|
|
2
|
+
name: string;
|
|
3
|
+
type: 'file' | 'dir';
|
|
4
|
+
children?: FileNode[];
|
|
5
|
+
}
|
|
6
|
+
export declare function getRemoteFileTree(connId: string, dirPath: string, depth?: number): Promise<FileNode[]>;
|
|
7
|
+
export declare function readRemoteFileContent(connId: string, filePath: string): Promise<{
|
|
8
|
+
content: string;
|
|
9
|
+
lang: string;
|
|
10
|
+
}>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { sshManager } from './ssh-manager.js';
|
|
3
|
+
const SKIP_DIRS = new Set(['.git', 'node_modules', '.next', '.nuxt', 'dist', 'build', '__pycache__', '.venv', 'venv', '.cache', '.parcel-cache', 'coverage', '.svn', '.hg']);
|
|
4
|
+
const MAX_DEPTH = 8;
|
|
5
|
+
const MAX_ENTRIES = 2000;
|
|
6
|
+
export async function getRemoteFileTree(connId, dirPath, depth = 0) {
|
|
7
|
+
if (depth > MAX_DEPTH)
|
|
8
|
+
return [];
|
|
9
|
+
let entries;
|
|
10
|
+
try {
|
|
11
|
+
entries = await sshManager.sftpReaddir(connId, dirPath);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const result = [];
|
|
17
|
+
let count = 0;
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
if (count >= MAX_ENTRIES)
|
|
20
|
+
break;
|
|
21
|
+
if (entry.type === 'dir') {
|
|
22
|
+
if (SKIP_DIRS.has(entry.name))
|
|
23
|
+
continue;
|
|
24
|
+
const children = await getRemoteFileTree(connId, path.posix.join(dirPath, entry.name), depth + 1);
|
|
25
|
+
result.push({ name: entry.name, type: 'dir', children });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
result.push({ name: entry.name, type: 'file' });
|
|
29
|
+
}
|
|
30
|
+
count++;
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
const EXT_LANG_MAP = {
|
|
35
|
+
ts: 'typescript', tsx: 'typescript', js: 'javascript', jsx: 'javascript',
|
|
36
|
+
py: 'python', rs: 'rust', go: 'go', java: 'java', c: 'c', cpp: 'cpp', h: 'c',
|
|
37
|
+
cs: 'csharp', rb: 'ruby', php: 'php', swift: 'swift', kt: 'kotlin',
|
|
38
|
+
json: 'json', yaml: 'yaml', yml: 'yaml', toml: 'toml', xml: 'xml',
|
|
39
|
+
md: 'markdown', html: 'html', css: 'css', scss: 'scss', less: 'less',
|
|
40
|
+
sql: 'sql', sh: 'shell', bash: 'shell', zsh: 'shell',
|
|
41
|
+
dockerfile: 'dockerfile', makefile: 'makefile',
|
|
42
|
+
astro: 'html', vue: 'html', svelte: 'html',
|
|
43
|
+
};
|
|
44
|
+
export async function readRemoteFileContent(connId, filePath) {
|
|
45
|
+
const content = await sshManager.sftpReadFile(connId, filePath);
|
|
46
|
+
const ext = path.extname(filePath).toLowerCase().replace('.', '');
|
|
47
|
+
const basename = path.basename(filePath).toLowerCase();
|
|
48
|
+
const lang = EXT_LANG_MAP[ext] || EXT_LANG_MAP[basename] || 'plaintext';
|
|
49
|
+
return { content, lang };
|
|
50
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export declare function gitInit(connId: string, cwd: string): Promise<void>;
|
|
2
|
+
export declare function gitClone(connId: string, url: string, dest: string): Promise<void>;
|
|
3
|
+
export declare function gitStatus(connId: string, cwd: string): Promise<{
|
|
4
|
+
status: string;
|
|
5
|
+
file: string;
|
|
6
|
+
staged: boolean;
|
|
7
|
+
indexStatus: string;
|
|
8
|
+
workTreeStatus: string;
|
|
9
|
+
oldPath: string | undefined;
|
|
10
|
+
}[]>;
|
|
11
|
+
export declare function gitLog(connId: string, cwd: string, branch?: string, count?: number): Promise<{
|
|
12
|
+
hash: string;
|
|
13
|
+
fullHash: string;
|
|
14
|
+
msg: string;
|
|
15
|
+
fullMessage: string;
|
|
16
|
+
author: string;
|
|
17
|
+
date: string;
|
|
18
|
+
files: never[];
|
|
19
|
+
merge: boolean;
|
|
20
|
+
}[]>;
|
|
21
|
+
export declare function gitCommitFiles(connId: string, cwd: string, hash: string): Promise<{
|
|
22
|
+
path: string;
|
|
23
|
+
status: string;
|
|
24
|
+
additions: number;
|
|
25
|
+
deletions: number;
|
|
26
|
+
}[]>;
|
|
27
|
+
export declare function gitBranches(connId: string, cwd: string): Promise<{
|
|
28
|
+
branches: string[];
|
|
29
|
+
currentBranch: string;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function gitCheckout(connId: string, cwd: string, branch: string): Promise<void>;
|
|
32
|
+
export declare function gitCommit(connId: string, cwd: string, message: string): Promise<void>;
|
|
33
|
+
export declare function gitPush(connId: string, cwd: string): Promise<void>;
|
|
34
|
+
export declare function gitStash(connId: string, cwd: string): Promise<void>;
|
|
35
|
+
export declare function gitStashList(connId: string, cwd: string): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
}[]>;
|
|
39
|
+
export declare function gitStashApply(connId: string, cwd: string, id: string): Promise<void>;
|
|
40
|
+
export declare function gitStashDrop(connId: string, cwd: string, id: string): Promise<void>;
|
|
41
|
+
export declare function gitCreateBranch(connId: string, cwd: string, name: string): Promise<void>;
|
|
42
|
+
export declare function gitFetch(connId: string, cwd: string): Promise<void>;
|
|
43
|
+
export declare function gitRemotes(connId: string, cwd: string): Promise<{
|
|
44
|
+
name: string;
|
|
45
|
+
url: string;
|
|
46
|
+
type: string;
|
|
47
|
+
}[]>;
|
|
48
|
+
export declare function gitAddRemote(connId: string, cwd: string, name: string, url: string): Promise<void>;
|
|
49
|
+
export declare function gitRemoveRemote(connId: string, cwd: string, name: string): Promise<void>;
|
|
50
|
+
export declare function gitEditRemote(connId: string, cwd: string, name: string, url: string): Promise<void>;
|
|
51
|
+
export declare function gitDiff(connId: string, cwd: string, file?: string): Promise<string>;
|
|
52
|
+
export declare function gitRevert(connId: string, cwd: string, file?: string): Promise<void>;
|
|
53
|
+
export declare function gitUnstageFile(connId: string, cwd: string, file: string): Promise<void>;
|
|
54
|
+
export declare function gitStageFile(connId: string, cwd: string, file: string): Promise<void>;
|
|
55
|
+
export declare function gitShowFile(connId: string, cwd: string, file: string, ref?: string): Promise<string>;
|
|
56
|
+
export declare function gitBlame(connId: string, cwd: string, file: string): Promise<string>;
|
|
57
|
+
export declare function gitFileLog(connId: string, cwd: string, file: string): Promise<{
|
|
58
|
+
hash: string;
|
|
59
|
+
author: string;
|
|
60
|
+
date: string;
|
|
61
|
+
msg: string;
|
|
62
|
+
}[]>;
|
|
63
|
+
export declare function gitWorktreeList(connId: string, cwd: string): Promise<{
|
|
64
|
+
path: string;
|
|
65
|
+
head: string;
|
|
66
|
+
branch: string;
|
|
67
|
+
bare?: boolean;
|
|
68
|
+
}[]>;
|
|
69
|
+
export declare function gitWorktreeAdd(connId: string, cwd: string, wtPath: string, branch?: string, newBranch?: boolean): Promise<void>;
|
|
70
|
+
export declare function gitWorktreeRemove(connId: string, cwd: string, worktreePath: string): Promise<void>;
|
|
71
|
+
export declare function gitBranchDelete(connId: string, cwd: string, branch: string): Promise<void>;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { sshManager } from './ssh-manager.js';
|
|
2
|
+
function shellEscape(s) {
|
|
3
|
+
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
4
|
+
}
|
|
5
|
+
async function git(connId, args, cwd) {
|
|
6
|
+
const escapedArgs = args.map(a => shellEscape(a)).join(' ');
|
|
7
|
+
return sshManager.exec(connId, `git ${escapedArgs}`, { cwd });
|
|
8
|
+
}
|
|
9
|
+
export async function gitInit(connId, cwd) {
|
|
10
|
+
await git(connId, ['init'], cwd);
|
|
11
|
+
}
|
|
12
|
+
export async function gitClone(connId, url, dest) {
|
|
13
|
+
await sshManager.exec(connId, `git clone ${shellEscape(url)} ${shellEscape(dest)}`);
|
|
14
|
+
}
|
|
15
|
+
export async function gitStatus(connId, cwd) {
|
|
16
|
+
const output = await git(connId, ['status', '--porcelain', '-uall', '-M'], cwd);
|
|
17
|
+
return output.split('\n').filter(Boolean).map(line => {
|
|
18
|
+
const x = line[0];
|
|
19
|
+
const y = line[1];
|
|
20
|
+
const rest = line.substring(3);
|
|
21
|
+
let file = rest;
|
|
22
|
+
let oldPath;
|
|
23
|
+
if (x === 'R' || y === 'R') {
|
|
24
|
+
const arrowIdx = rest.indexOf(' -> ');
|
|
25
|
+
if (arrowIdx >= 0) {
|
|
26
|
+
file = rest.substring(0, arrowIdx);
|
|
27
|
+
oldPath = rest.substring(arrowIdx + 4);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let status = (x + y).trim() || '?';
|
|
31
|
+
const staged = x !== ' ' && x !== '?' && x !== '!';
|
|
32
|
+
return { status, file, staged, indexStatus: x, workTreeStatus: y, oldPath };
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export async function gitLog(connId, cwd, branch, count = 30) {
|
|
36
|
+
const SEP = '---GIT-LOG-SEP---';
|
|
37
|
+
const args = ['log', `--format=${SEP}%n%H%n%h%n%an%n%ar%n%s%n%B`, '-n', String(count)];
|
|
38
|
+
if (branch)
|
|
39
|
+
args.push(branch);
|
|
40
|
+
const output = await git(connId, args, cwd);
|
|
41
|
+
const entries = output.split(SEP).filter(e => e.trim());
|
|
42
|
+
return entries.map(entry => {
|
|
43
|
+
const lines = entry.trim().split('\n');
|
|
44
|
+
const fullHash = lines[0] || '';
|
|
45
|
+
const hash = lines[1] || '';
|
|
46
|
+
const author = lines[2] || '';
|
|
47
|
+
const date = lines[3] || '';
|
|
48
|
+
const msg = lines[4] || '';
|
|
49
|
+
const fullMessage = lines.slice(5).join('\n').trim() || msg;
|
|
50
|
+
const isMerge = msg.toLowerCase().startsWith('merge');
|
|
51
|
+
return { hash, fullHash, msg, fullMessage, author, date, files: [], merge: isMerge };
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export async function gitCommitFiles(connId, cwd, hash) {
|
|
55
|
+
const output = await git(connId, ['diff-tree', '--no-commit-id', '-r', '--name-status', hash], cwd);
|
|
56
|
+
return output.trim().split('\n').filter(Boolean).map(line => {
|
|
57
|
+
const parts = line.split('\t');
|
|
58
|
+
const statusChar = parts[0]?.[0] || 'M';
|
|
59
|
+
const filePath = parts[1] || '';
|
|
60
|
+
const statusMap = { A: 'A', M: 'M', D: 'D', R: 'R', C: 'C' };
|
|
61
|
+
return { path: filePath, status: statusMap[statusChar] || 'M', additions: 0, deletions: 0 };
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export async function gitBranches(connId, cwd) {
|
|
65
|
+
const output = await git(connId, ['branch', '-a', '--no-color'], cwd);
|
|
66
|
+
const branches = [];
|
|
67
|
+
let currentBranch = '';
|
|
68
|
+
output.split('\n').filter(Boolean).forEach(line => {
|
|
69
|
+
const trimmed = line.trim();
|
|
70
|
+
if (trimmed.startsWith('* ')) {
|
|
71
|
+
currentBranch = trimmed.substring(2);
|
|
72
|
+
branches.push(currentBranch);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
branches.push(trimmed);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return { branches, currentBranch };
|
|
79
|
+
}
|
|
80
|
+
export async function gitCheckout(connId, cwd, branch) {
|
|
81
|
+
await git(connId, ['checkout', branch], cwd);
|
|
82
|
+
}
|
|
83
|
+
export async function gitCommit(connId, cwd, message) {
|
|
84
|
+
await git(connId, ['add', '-A'], cwd);
|
|
85
|
+
await git(connId, ['commit', '-m', message], cwd);
|
|
86
|
+
}
|
|
87
|
+
export async function gitPush(connId, cwd) {
|
|
88
|
+
await git(connId, ['push'], cwd);
|
|
89
|
+
}
|
|
90
|
+
export async function gitStash(connId, cwd) {
|
|
91
|
+
await git(connId, ['stash', 'push'], cwd);
|
|
92
|
+
}
|
|
93
|
+
export async function gitStashList(connId, cwd) {
|
|
94
|
+
const output = await git(connId, ['stash', 'list'], cwd);
|
|
95
|
+
return output.split('\n').filter(Boolean).map((line, i) => ({
|
|
96
|
+
id: `stash@{${i}}`,
|
|
97
|
+
name: line,
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
export async function gitStashApply(connId, cwd, id) {
|
|
101
|
+
await git(connId, ['stash', 'apply', id], cwd);
|
|
102
|
+
}
|
|
103
|
+
export async function gitStashDrop(connId, cwd, id) {
|
|
104
|
+
await git(connId, ['stash', 'drop', id], cwd);
|
|
105
|
+
}
|
|
106
|
+
export async function gitCreateBranch(connId, cwd, name) {
|
|
107
|
+
await git(connId, ['checkout', '-b', name], cwd);
|
|
108
|
+
}
|
|
109
|
+
export async function gitFetch(connId, cwd) {
|
|
110
|
+
await git(connId, ['fetch', '--all'], cwd);
|
|
111
|
+
}
|
|
112
|
+
export async function gitRemotes(connId, cwd) {
|
|
113
|
+
const output = await git(connId, ['remote', '-v'], cwd);
|
|
114
|
+
const remotes = [];
|
|
115
|
+
const seen = new Set();
|
|
116
|
+
output.split('\n').filter(Boolean).forEach(line => {
|
|
117
|
+
const parts = line.split(/\s+/);
|
|
118
|
+
const name = parts[0];
|
|
119
|
+
const url = parts[1];
|
|
120
|
+
if (!seen.has(name)) {
|
|
121
|
+
seen.add(name);
|
|
122
|
+
remotes.push({ name, url, type: url.includes('@') ? 'ssh' : 'https' });
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
return remotes;
|
|
126
|
+
}
|
|
127
|
+
export async function gitAddRemote(connId, cwd, name, url) {
|
|
128
|
+
await git(connId, ['remote', 'add', name, url], cwd);
|
|
129
|
+
}
|
|
130
|
+
export async function gitRemoveRemote(connId, cwd, name) {
|
|
131
|
+
await git(connId, ['remote', 'remove', name], cwd);
|
|
132
|
+
}
|
|
133
|
+
export async function gitEditRemote(connId, cwd, name, url) {
|
|
134
|
+
await git(connId, ['remote', 'set-url', name, url], cwd);
|
|
135
|
+
}
|
|
136
|
+
export async function gitDiff(connId, cwd, file) {
|
|
137
|
+
const args = ['diff'];
|
|
138
|
+
if (file)
|
|
139
|
+
args.push('--', file);
|
|
140
|
+
return await git(connId, args, cwd);
|
|
141
|
+
}
|
|
142
|
+
export async function gitRevert(connId, cwd, file) {
|
|
143
|
+
if (file) {
|
|
144
|
+
await git(connId, ['checkout', '--', file], cwd);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
await git(connId, ['checkout', '.'], cwd);
|
|
148
|
+
await git(connId, ['clean', '-fd'], cwd);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export async function gitUnstageFile(connId, cwd, file) {
|
|
152
|
+
await git(connId, ['reset', 'HEAD', '--', file], cwd);
|
|
153
|
+
}
|
|
154
|
+
export async function gitStageFile(connId, cwd, file) {
|
|
155
|
+
await git(connId, ['add', file], cwd);
|
|
156
|
+
}
|
|
157
|
+
export async function gitShowFile(connId, cwd, file, ref = 'HEAD') {
|
|
158
|
+
return await git(connId, ['show', `${ref}:${file}`], cwd);
|
|
159
|
+
}
|
|
160
|
+
export async function gitBlame(connId, cwd, file) {
|
|
161
|
+
return await git(connId, ['blame', '--porcelain', file], cwd);
|
|
162
|
+
}
|
|
163
|
+
export async function gitFileLog(connId, cwd, file) {
|
|
164
|
+
const output = await git(connId, ['log', '--format=%h|%an|%ar|%s', '-n', '20', '--follow', '--', file], cwd);
|
|
165
|
+
return output.split('\n').filter(Boolean).map(line => {
|
|
166
|
+
const [hash, author, date, ...msgParts] = line.split('|');
|
|
167
|
+
return { hash, author, date, msg: msgParts.join('|') };
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
export async function gitWorktreeList(connId, cwd) {
|
|
171
|
+
const output = await git(connId, ['worktree', 'list', '--porcelain'], cwd);
|
|
172
|
+
const worktrees = [];
|
|
173
|
+
let current = {};
|
|
174
|
+
for (const line of output.split('\n')) {
|
|
175
|
+
if (line.startsWith('worktree ')) {
|
|
176
|
+
if (current.path)
|
|
177
|
+
worktrees.push(current);
|
|
178
|
+
current = { path: line.substring(9) };
|
|
179
|
+
}
|
|
180
|
+
else if (line.startsWith('HEAD ')) {
|
|
181
|
+
current.head = line.substring(5);
|
|
182
|
+
}
|
|
183
|
+
else if (line.startsWith('branch ')) {
|
|
184
|
+
current.branch = line.substring(7).replace('refs/heads/', '');
|
|
185
|
+
}
|
|
186
|
+
else if (line === 'bare') {
|
|
187
|
+
current.bare = true;
|
|
188
|
+
}
|
|
189
|
+
else if (line === 'detached') {
|
|
190
|
+
current.branch = '(detached)';
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (current.path)
|
|
194
|
+
worktrees.push(current);
|
|
195
|
+
return worktrees;
|
|
196
|
+
}
|
|
197
|
+
export async function gitWorktreeAdd(connId, cwd, wtPath, branch, newBranch) {
|
|
198
|
+
const args = ['worktree', 'add'];
|
|
199
|
+
if (newBranch && branch) {
|
|
200
|
+
args.push('-b', branch, wtPath);
|
|
201
|
+
}
|
|
202
|
+
else if (branch) {
|
|
203
|
+
args.push(wtPath, branch);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
args.push(wtPath);
|
|
207
|
+
}
|
|
208
|
+
await git(connId, args, cwd);
|
|
209
|
+
}
|
|
210
|
+
export async function gitWorktreeRemove(connId, cwd, worktreePath) {
|
|
211
|
+
await git(connId, ['worktree', 'remove', worktreePath], cwd);
|
|
212
|
+
}
|
|
213
|
+
export async function gitBranchDelete(connId, cwd, branch) {
|
|
214
|
+
await git(connId, ['branch', '-D', branch], cwd);
|
|
215
|
+
}
|