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.
Files changed (408) hide show
  1. package/LICENSE +21 -0
  2. package/README.github.md +322 -0
  3. package/README.md +112 -0
  4. package/README.npm.md +112 -0
  5. package/bin/atoo-studio.js +90 -0
  6. package/dist/src/agents/claude-code-terminal/adapter.d.ts +42 -0
  7. package/dist/src/agents/claude-code-terminal/adapter.js +166 -0
  8. package/dist/src/agents/claude-code-terminal/index.d.ts +13 -0
  9. package/dist/src/agents/claude-code-terminal/index.js +45 -0
  10. package/dist/src/agents/claude-code-terminal/spawner.d.ts +9 -0
  11. package/dist/src/agents/claude-code-terminal/spawner.js +37 -0
  12. package/dist/src/agents/claude-code-terminal-chatro/adapter.d.ts +51 -0
  13. package/dist/src/agents/claude-code-terminal-chatro/adapter.js +301 -0
  14. package/dist/src/agents/claude-code-terminal-chatro/index.d.ts +13 -0
  15. package/dist/src/agents/claude-code-terminal-chatro/index.js +45 -0
  16. package/dist/src/agents/claude-code-terminal-chatro/jsonl-watcher.d.ts +67 -0
  17. package/dist/src/agents/claude-code-terminal-chatro/jsonl-watcher.js +431 -0
  18. package/dist/src/agents/claude-code-terminal-chatro/spawner.d.ts +9 -0
  19. package/dist/src/agents/claude-code-terminal-chatro/spawner.js +37 -0
  20. package/dist/src/agents/codex-terminal/adapter.d.ts +40 -0
  21. package/dist/src/agents/codex-terminal/adapter.js +160 -0
  22. package/dist/src/agents/codex-terminal/index.d.ts +13 -0
  23. package/dist/src/agents/codex-terminal/index.js +47 -0
  24. package/dist/src/agents/codex-terminal/spawner.d.ts +9 -0
  25. package/dist/src/agents/codex-terminal/spawner.js +56 -0
  26. package/dist/src/agents/codex-terminal-chatro/adapter.d.ts +58 -0
  27. package/dist/src/agents/codex-terminal-chatro/adapter.js +266 -0
  28. package/dist/src/agents/codex-terminal-chatro/index.d.ts +13 -0
  29. package/dist/src/agents/codex-terminal-chatro/index.js +50 -0
  30. package/dist/src/agents/codex-terminal-chatro/jsonl-watcher.d.ts +36 -0
  31. package/dist/src/agents/codex-terminal-chatro/jsonl-watcher.js +205 -0
  32. package/dist/src/agents/codex-terminal-chatro/spawner.d.ts +9 -0
  33. package/dist/src/agents/codex-terminal-chatro/spawner.js +57 -0
  34. package/dist/src/agents/lib/chain-builder.d.ts +21 -0
  35. package/dist/src/agents/lib/chain-builder.js +139 -0
  36. package/dist/src/agents/lib/claude/fs-sessions.d.ts +31 -0
  37. package/dist/src/agents/lib/claude/fs-sessions.js +329 -0
  38. package/dist/src/agents/lib/claude/jsonl-writer.d.ts +32 -0
  39. package/dist/src/agents/lib/claude/jsonl-writer.js +342 -0
  40. package/dist/src/agents/lib/claude/workspace-trust.d.ts +1 -0
  41. package/dist/src/agents/lib/claude/workspace-trust.js +29 -0
  42. package/dist/src/agents/lib/codex/fs-sessions.d.ts +34 -0
  43. package/dist/src/agents/lib/codex/fs-sessions.js +255 -0
  44. package/dist/src/agents/lib/codex/jsonl-mapper.d.ts +11 -0
  45. package/dist/src/agents/lib/codex/jsonl-mapper.js +154 -0
  46. package/dist/src/agents/lib/codex/jsonl-writer.d.ts +8 -0
  47. package/dist/src/agents/lib/codex/jsonl-writer.js +440 -0
  48. package/dist/src/agents/lib/fs-tracking.d.ts +36 -0
  49. package/dist/src/agents/lib/fs-tracking.js +109 -0
  50. package/dist/src/agents/lib/pty-activity-tracker.d.ts +37 -0
  51. package/dist/src/agents/lib/pty-activity-tracker.js +105 -0
  52. package/dist/src/agents/lib/session-id-utils.d.ts +46 -0
  53. package/dist/src/agents/lib/session-id-utils.js +147 -0
  54. package/dist/src/agents/lib/session-precreate.d.ts +17 -0
  55. package/dist/src/agents/lib/session-precreate.js +177 -0
  56. package/dist/src/agents/registry.d.ts +72 -0
  57. package/dist/src/agents/registry.js +337 -0
  58. package/dist/src/agents/types.d.ts +135 -0
  59. package/dist/src/agents/types.js +1 -0
  60. package/dist/src/auth/crypto-key.d.ts +6 -0
  61. package/dist/src/auth/crypto-key.js +45 -0
  62. package/dist/src/auth/middleware.d.ts +18 -0
  63. package/dist/src/auth/middleware.js +54 -0
  64. package/dist/src/auth/password.d.ts +2 -0
  65. package/dist/src/auth/password.js +12 -0
  66. package/dist/src/auth/session.d.ts +10 -0
  67. package/dist/src/auth/session.js +33 -0
  68. package/dist/src/auth/totp.d.ts +12 -0
  69. package/dist/src/auth/totp.js +61 -0
  70. package/dist/src/auth/webauthn.d.ts +6 -0
  71. package/dist/src/auth/webauthn.js +117 -0
  72. package/dist/src/config.d.ts +10 -0
  73. package/dist/src/config.js +16 -0
  74. package/dist/src/database/connection-manager.d.ts +25 -0
  75. package/dist/src/database/connection-manager.js +211 -0
  76. package/dist/src/database/discovery/container.d.ts +6 -0
  77. package/dist/src/database/discovery/container.js +226 -0
  78. package/dist/src/database/discovery/env-parser.d.ts +9 -0
  79. package/dist/src/database/discovery/env-parser.js +525 -0
  80. package/dist/src/database/discovery/local-files.d.ts +6 -0
  81. package/dist/src/database/discovery/local-files.js +58 -0
  82. package/dist/src/database/discovery/port-scan.d.ts +7 -0
  83. package/dist/src/database/discovery/port-scan.js +61 -0
  84. package/dist/src/database/drivers/cassandra.d.ts +12 -0
  85. package/dist/src/database/drivers/cassandra.js +91 -0
  86. package/dist/src/database/drivers/clickhouse.d.ts +11 -0
  87. package/dist/src/database/drivers/clickhouse.js +127 -0
  88. package/dist/src/database/drivers/elasticsearch.d.ts +12 -0
  89. package/dist/src/database/drivers/elasticsearch.js +169 -0
  90. package/dist/src/database/drivers/influxdb.d.ts +14 -0
  91. package/dist/src/database/drivers/influxdb.js +194 -0
  92. package/dist/src/database/drivers/memcached.d.ts +11 -0
  93. package/dist/src/database/drivers/memcached.js +117 -0
  94. package/dist/src/database/drivers/mongodb.d.ts +12 -0
  95. package/dist/src/database/drivers/mongodb.js +128 -0
  96. package/dist/src/database/drivers/mysql.d.ts +11 -0
  97. package/dist/src/database/drivers/mysql.js +112 -0
  98. package/dist/src/database/drivers/neo4j.d.ts +11 -0
  99. package/dist/src/database/drivers/neo4j.js +158 -0
  100. package/dist/src/database/drivers/postgresql.d.ts +11 -0
  101. package/dist/src/database/drivers/postgresql.js +133 -0
  102. package/dist/src/database/drivers/redis.d.ts +11 -0
  103. package/dist/src/database/drivers/redis.js +91 -0
  104. package/dist/src/database/drivers/sqlite.d.ts +10 -0
  105. package/dist/src/database/drivers/sqlite.js +100 -0
  106. package/dist/src/database/query-stream.d.ts +5 -0
  107. package/dist/src/database/query-stream.js +75 -0
  108. package/dist/src/database/types.d.ts +71 -0
  109. package/dist/src/database/types.js +1 -0
  110. package/dist/src/events/index.d.ts +3 -0
  111. package/dist/src/events/index.js +3 -0
  112. package/dist/src/events/types.d.ts +214 -0
  113. package/dist/src/events/types.js +22 -0
  114. package/dist/src/events/wire.d.ts +114 -0
  115. package/dist/src/events/wire.js +296 -0
  116. package/dist/src/fs-monitor-types.d.ts +24 -0
  117. package/dist/src/fs-monitor-types.js +1 -0
  118. package/dist/src/fs-monitor.d.ts +80 -0
  119. package/dist/src/fs-monitor.js +637 -0
  120. package/dist/src/handlers/auth.d.ts +1 -0
  121. package/dist/src/handlers/auth.js +170 -0
  122. package/dist/src/handlers/changes.d.ts +1 -0
  123. package/dist/src/handlers/changes.js +203 -0
  124. package/dist/src/handlers/containers.d.ts +12 -0
  125. package/dist/src/handlers/containers.js +379 -0
  126. package/dist/src/handlers/databases.d.ts +3 -0
  127. package/dist/src/handlers/databases.js +327 -0
  128. package/dist/src/handlers/environments.d.ts +3 -0
  129. package/dist/src/handlers/environments.js +286 -0
  130. package/dist/src/handlers/github.d.ts +1 -0
  131. package/dist/src/handlers/github.js +153 -0
  132. package/dist/src/handlers/projects.d.ts +1 -0
  133. package/dist/src/handlers/projects.js +895 -0
  134. package/dist/src/handlers/ssh.d.ts +1 -0
  135. package/dist/src/handlers/ssh.js +162 -0
  136. package/dist/src/handlers/users.d.ts +1 -0
  137. package/dist/src/handlers/users.js +195 -0
  138. package/dist/src/index.d.ts +1 -0
  139. package/dist/src/index.js +228 -0
  140. package/dist/src/mcp/config.d.ts +32 -0
  141. package/dist/src/mcp/config.js +227 -0
  142. package/dist/src/mcp/server.d.ts +1 -0
  143. package/dist/src/mcp/server.js +574 -0
  144. package/dist/src/serial/cuse-device.d.ts +19 -0
  145. package/dist/src/serial/cuse-device.js +260 -0
  146. package/dist/src/serial/manager.d.ts +63 -0
  147. package/dist/src/serial/manager.js +206 -0
  148. package/dist/src/serial/pty-pair.d.ts +16 -0
  149. package/dist/src/serial/pty-pair.js +68 -0
  150. package/dist/src/services/fs-browser.d.ts +14 -0
  151. package/dist/src/services/fs-browser.js +98 -0
  152. package/dist/src/services/git-ops.d.ts +78 -0
  153. package/dist/src/services/git-ops.js +288 -0
  154. package/dist/src/services/github-ops.d.ts +104 -0
  155. package/dist/src/services/github-ops.js +192 -0
  156. package/dist/src/services/obfuscation.d.ts +2 -0
  157. package/dist/src/services/obfuscation.js +16 -0
  158. package/dist/src/services/preview/headless-backend.d.ts +62 -0
  159. package/dist/src/services/preview/headless-backend.js +698 -0
  160. package/dist/src/services/preview/injected-scripts.d.ts +9 -0
  161. package/dist/src/services/preview/injected-scripts.js +232 -0
  162. package/dist/src/services/preview/preview-backend.d.ts +92 -0
  163. package/dist/src/services/preview/preview-backend.js +15 -0
  164. package/dist/src/services/preview/universal-setter.d.ts +7 -0
  165. package/dist/src/services/preview/universal-setter.js +46 -0
  166. package/dist/src/services/preview-manager.d.ts +50 -0
  167. package/dist/src/services/preview-manager.js +216 -0
  168. package/dist/src/services/project-watcher.d.ts +6 -0
  169. package/dist/src/services/project-watcher.js +307 -0
  170. package/dist/src/services/remote-fs-browser.d.ts +11 -0
  171. package/dist/src/services/remote-fs-browser.js +50 -0
  172. package/dist/src/services/remote-git-ops.d.ts +71 -0
  173. package/dist/src/services/remote-git-ops.js +215 -0
  174. package/dist/src/services/session-search.d.ts +56 -0
  175. package/dist/src/services/session-search.js +303 -0
  176. package/dist/src/services/ssh-manager.d.ts +44 -0
  177. package/dist/src/services/ssh-manager.js +359 -0
  178. package/dist/src/session-writer.d.ts +9 -0
  179. package/dist/src/session-writer.js +66 -0
  180. package/dist/src/spawner.d.ts +56 -0
  181. package/dist/src/spawner.js +135 -0
  182. package/dist/src/state/db.d.ts +214 -0
  183. package/dist/src/state/db.js +897 -0
  184. package/dist/src/state/store.d.ts +37 -0
  185. package/dist/src/state/store.js +108 -0
  186. package/dist/src/state/types.d.ts +13 -0
  187. package/dist/src/state/types.js +1 -0
  188. package/dist/src/web/devtools-proxy.d.ts +7 -0
  189. package/dist/src/web/devtools-proxy.js +176 -0
  190. package/dist/src/web/port-proxy.d.ts +15 -0
  191. package/dist/src/web/port-proxy.js +124 -0
  192. package/dist/src/web/preview-ws.d.ts +5 -0
  193. package/dist/src/web/preview-ws.js +207 -0
  194. package/dist/src/web/server.d.ts +6 -0
  195. package/dist/src/web/server.js +1694 -0
  196. package/dist/src/ws/agent-ws.d.ts +5 -0
  197. package/dist/src/ws/agent-ws.js +93 -0
  198. package/frontend/dist/assets/_basePickBy-B-LibQ4-.js +1 -0
  199. package/frontend/dist/assets/_baseUniq-CprifHap.js +1 -0
  200. package/frontend/dist/assets/_createAssigner-ByDUqGii.js +1 -0
  201. package/frontend/dist/assets/abap-DuT-3z4x.js +1 -0
  202. package/frontend/dist/assets/addon-fit-CxQet2ja.js +1 -0
  203. package/frontend/dist/assets/addon-web-links-D_jRkPIl.js +1 -0
  204. package/frontend/dist/assets/apex-B-em86xX.js +1 -0
  205. package/frontend/dist/assets/api-SUPuHhSY.js +2 -0
  206. package/frontend/dist/assets/arc-Z0_eVteO.js +1 -0
  207. package/frontend/dist/assets/architecture-PBZL5I3N-hvVXGhqd.js +1 -0
  208. package/frontend/dist/assets/architectureDiagram-2XIMDMQ5-DiHPxX4j.js +36 -0
  209. package/frontend/dist/assets/array-CwG8vNfn.js +1 -0
  210. package/frontend/dist/assets/auth-store-R7eW5SVu.js +1 -0
  211. package/frontend/dist/assets/azcli-Bg9wQloi.js +1 -0
  212. package/frontend/dist/assets/bat-BM46z99L.js +1 -0
  213. package/frontend/dist/assets/bicep-DcBsJUfh.js +2 -0
  214. package/frontend/dist/assets/blockDiagram-WCTKOSBZ-C40u_hLo.js +132 -0
  215. package/frontend/dist/assets/c4Diagram-IC4MRINW-Ct7LjWFQ.js +10 -0
  216. package/frontend/dist/assets/cameligo-zw7JTtim.js +1 -0
  217. package/frontend/dist/assets/channel-ClCsE6HN.js +1 -0
  218. package/frontend/dist/assets/chunk-4BX2VUAB-zZ6P90VO.js +1 -0
  219. package/frontend/dist/assets/chunk-55IACEB6-DXllTDQl.js +1 -0
  220. package/frontend/dist/assets/chunk-7E7YKBS2-7zRaOLjj.js +1 -0
  221. package/frontend/dist/assets/chunk-7R4GIKGN-Csst1274.js +80 -0
  222. package/frontend/dist/assets/chunk-C72U2L5F-_JbQPbLN.js +1 -0
  223. package/frontend/dist/assets/chunk-CFjPhJqf.js +1 -0
  224. package/frontend/dist/assets/chunk-EGIJ26TM-B--aFyPw.js +1 -0
  225. package/frontend/dist/assets/chunk-FMBD7UC4-DVR34RNb.js +15 -0
  226. package/frontend/dist/assets/chunk-GEFDOKGD-CnmN6cC8.js +2 -0
  227. package/frontend/dist/assets/chunk-JSJVCQXG-CWxHBzeJ.js +1 -0
  228. package/frontend/dist/assets/chunk-KX2RTZJC-DkRk56s7.js +1 -0
  229. package/frontend/dist/assets/chunk-KYZI473N-DCCsG2dK.js +53 -0
  230. package/frontend/dist/assets/chunk-L3YUKLVL-C-DkZTMr.js +1 -0
  231. package/frontend/dist/assets/chunk-MX3YWQON-OUdzv5sZ.js +1 -0
  232. package/frontend/dist/assets/chunk-NQ4KR5QH-Bpu9FsM7.js +220 -0
  233. package/frontend/dist/assets/chunk-O4XLMI2P-BMLK6_ib.js +7 -0
  234. package/frontend/dist/assets/chunk-OZEHJAEY-CNNiJtG0.js +1 -0
  235. package/frontend/dist/assets/chunk-PQ6SQG4A-evVHD3KM.js +1 -0
  236. package/frontend/dist/assets/chunk-PU5JKC2W-DPFTYuvl.js +70 -0
  237. package/frontend/dist/assets/chunk-QZHKN3VN-JRdddPvu.js +1 -0
  238. package/frontend/dist/assets/chunk-R5LLSJPH-CHQzVVOV.js +1 -0
  239. package/frontend/dist/assets/chunk-WL4C6EOR-BNFU6IIi.js +189 -0
  240. package/frontend/dist/assets/chunk-XIRO2GV7-98T93G85.js +1 -0
  241. package/frontend/dist/assets/chunk-XZSTWKYB-BcW3cyNp.js +94 -0
  242. package/frontend/dist/assets/chunk-YBOYWFTD-BgKO1qAJ.js +1 -0
  243. package/frontend/dist/assets/classDiagram-VBA2DB6C-DikXzgcD.js +1 -0
  244. package/frontend/dist/assets/classDiagram-v2-RAHNMMFH-D7E3tQUK.js +1 -0
  245. package/frontend/dist/assets/clojure-FspFoNNQ.js +1 -0
  246. package/frontend/dist/assets/clone-mOXuZa7C.js +1 -0
  247. package/frontend/dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  248. package/frontend/dist/assets/coffee-13n8Bk2W.js +1 -0
  249. package/frontend/dist/assets/cose-bilkent-S5V4N54A-zUOWQqLe.js +1 -0
  250. package/frontend/dist/assets/cpp-BVm2xGEs.js +1 -0
  251. package/frontend/dist/assets/csharp-D2kAWmUm.js +1 -0
  252. package/frontend/dist/assets/csp-Ezvgpf0e.js +1 -0
  253. package/frontend/dist/assets/css-CYxRwcFy.js +3 -0
  254. package/frontend/dist/assets/css.worker-Cd5h-ZOL.js +89 -0
  255. package/frontend/dist/assets/cssMode-CrXej49V.js +1 -0
  256. package/frontend/dist/assets/cypher-jg3SGErc.js +1 -0
  257. package/frontend/dist/assets/cytoscape.esm-kyyvzxNV.js +321 -0
  258. package/frontend/dist/assets/dagre-DH4bgZO7.js +1 -0
  259. package/frontend/dist/assets/dagre-KLK3FWXG-DNSqDkwT.js +4 -0
  260. package/frontend/dist/assets/dart-179jqhK4.js +1 -0
  261. package/frontend/dist/assets/defaultLocale-Dda4OpKy.js +1 -0
  262. package/frontend/dist/assets/diagram-E7M64L7V-RqPNT5Vs.js +24 -0
  263. package/frontend/dist/assets/diagram-IFDJBPK2-B-5NRyaE.js +43 -0
  264. package/frontend/dist/assets/diagram-P4PSJMXO-BrP69Hk0.js +24 -0
  265. package/frontend/dist/assets/dist-CU_Nb1G5.js +1 -0
  266. package/frontend/dist/assets/dockerfile-CIAtSGxS.js +1 -0
  267. package/frontend/dist/assets/ecl-CGVKfDxD.js +1 -0
  268. package/frontend/dist/assets/editor-Br_kD0ds.css +1 -0
  269. package/frontend/dist/assets/editor.api2-YXkDn0Gm.js +872 -0
  270. package/frontend/dist/assets/editor.main-fBaXZjJ0.js +6 -0
  271. package/frontend/dist/assets/elixir-BZ-6w0y3.js +1 -0
  272. package/frontend/dist/assets/erDiagram-INFDFZHY-BYiB9NYg.js +70 -0
  273. package/frontend/dist/assets/flow9-CVuOjTMv.js +1 -0
  274. package/frontend/dist/assets/flowDiagram-PKNHOUZH-Cwq47rsR.js +162 -0
  275. package/frontend/dist/assets/freemarker2-DM-pztJU.js +3 -0
  276. package/frontend/dist/assets/fsharp-q0pGJYr6.js +1 -0
  277. package/frontend/dist/assets/ganttDiagram-A5KZAMGK-Dnx3szD9.js +292 -0
  278. package/frontend/dist/assets/gitGraph-HDMCJU4V-COlTQ7bA.js +1 -0
  279. package/frontend/dist/assets/gitGraphDiagram-K3NZZRJ6-BaUxboNc.js +65 -0
  280. package/frontend/dist/assets/go-dzSPfdEO.js +1 -0
  281. package/frontend/dist/assets/graphlib-kEFlkt3U.js +1 -0
  282. package/frontend/dist/assets/graphql-CG4OUoEV.js +1 -0
  283. package/frontend/dist/assets/handlebars-BbK53Vec.js +1 -0
  284. package/frontend/dist/assets/hcl-Cy14JPk3.js +1 -0
  285. package/frontend/dist/assets/html-DYtTQNOG.js +1 -0
  286. package/frontend/dist/assets/html.worker-BjVEKLoU.js +502 -0
  287. package/frontend/dist/assets/htmlMode-C6GTouth.js +1 -0
  288. package/frontend/dist/assets/index-DMLxes_u.js +157 -0
  289. package/frontend/dist/assets/index-DmzeqkB1.css +1 -0
  290. package/frontend/dist/assets/info-3K5VOQVL-DBtHyA4C.js +1 -0
  291. package/frontend/dist/assets/infoDiagram-LFFYTUFH-yBXLgMPI.js +2 -0
  292. package/frontend/dist/assets/ini-Pbg8HGVD.js +1 -0
  293. package/frontend/dist/assets/init-D6KNwrax.js +1 -0
  294. package/frontend/dist/assets/ishikawaDiagram-PHBUUO56-Bld4two_.js +70 -0
  295. package/frontend/dist/assets/java-BmVu6Qrl.js +1 -0
  296. package/frontend/dist/assets/javascript-PbfQEdcJ.js +1 -0
  297. package/frontend/dist/assets/journeyDiagram-4ABVD52K-4HyMd4R2.js +139 -0
  298. package/frontend/dist/assets/json.worker-DqU5Wxnl.js +58 -0
  299. package/frontend/dist/assets/jsonMode-CASsGppE.js +7 -0
  300. package/frontend/dist/assets/julia-3cGnieBq.js +1 -0
  301. package/frontend/dist/assets/kanban-definition-K7BYSVSG-DpgsZmpG.js +89 -0
  302. package/frontend/dist/assets/katex-CEw3x5bf.js +261 -0
  303. package/frontend/dist/assets/kotlin-BuWkVcfV.js +1 -0
  304. package/frontend/dist/assets/less-CJ_VPy2C.js +2 -0
  305. package/frontend/dist/assets/lexon-BygAuZPu.js +1 -0
  306. package/frontend/dist/assets/line-CA_wh_TY.js +1 -0
  307. package/frontend/dist/assets/linear-BAcLW45z.js +1 -0
  308. package/frontend/dist/assets/liquid-kz84dle6.js +1 -0
  309. package/frontend/dist/assets/lspLanguageFeatures-C7hAHFn1.js +4 -0
  310. package/frontend/dist/assets/lua-C8Xs3dCx.js +1 -0
  311. package/frontend/dist/assets/m3-DTJeKBk4.js +1 -0
  312. package/frontend/dist/assets/markdown-QCgx8JqZ.js +1 -0
  313. package/frontend/dist/assets/math-D0YcMJAn.js +1 -0
  314. package/frontend/dist/assets/mdx-yRw0ap-E.js +1 -0
  315. package/frontend/dist/assets/mermaid-parser.core-DAeTodBQ.js +4 -0
  316. package/frontend/dist/assets/mindmap-definition-YRQLILUH-CoNlFyVl.js +68 -0
  317. package/frontend/dist/assets/mips-DopWaYgE.js +1 -0
  318. package/frontend/dist/assets/monaco.contribution-DeY0Qei-.js +2 -0
  319. package/frontend/dist/assets/msdax-BDis4ARV.js +1 -0
  320. package/frontend/dist/assets/mysql-BV6MLsOI.js +1 -0
  321. package/frontend/dist/assets/objective-c-B1UuzKs6.js +1 -0
  322. package/frontend/dist/assets/ordinal-jM7S0YHN.js +1 -0
  323. package/frontend/dist/assets/packet-RMMSAZCW-FF6-Tmai.js +1 -0
  324. package/frontend/dist/assets/pascal-BkvESCrc.js +1 -0
  325. package/frontend/dist/assets/pascaligo-lTy0kZYr.js +1 -0
  326. package/frontend/dist/assets/path-DNPd7Py7.js +1 -0
  327. package/frontend/dist/assets/perl-CrtUPXLV.js +1 -0
  328. package/frontend/dist/assets/pgsql-B9IbNWx2.js +1 -0
  329. package/frontend/dist/assets/php-CXvQBY2p.js +1 -0
  330. package/frontend/dist/assets/pie-UPGHQEXC-CFvXY2o-.js +1 -0
  331. package/frontend/dist/assets/pieDiagram-SKSYHLDU-CM_hbCcn.js +30 -0
  332. package/frontend/dist/assets/pla-DxBxuqWu.js +1 -0
  333. package/frontend/dist/assets/postiats-OkEuT5YF.js +1 -0
  334. package/frontend/dist/assets/powerquery-CMx5Tq4K.js +1 -0
  335. package/frontend/dist/assets/powershell-CstRxrEc.js +1 -0
  336. package/frontend/dist/assets/preload-helper-D4M6sveU.js +1 -0
  337. package/frontend/dist/assets/protobuf-Bx0Z-uRj.js +2 -0
  338. package/frontend/dist/assets/pug--W8vanWl.js +1 -0
  339. package/frontend/dist/assets/python-DA0rnlw3.js +1 -0
  340. package/frontend/dist/assets/qsharp-CRtr0YbN.js +1 -0
  341. package/frontend/dist/assets/quadrantDiagram-337W2JSQ-B3n3IUhC.js +7 -0
  342. package/frontend/dist/assets/r-C6E1d6iv.js +1 -0
  343. package/frontend/dist/assets/radar-KQ55EAFF-MPZu7SdX.js +1 -0
  344. package/frontend/dist/assets/razor-yd73uata.js +1 -0
  345. package/frontend/dist/assets/redis-Dx13voP3.js +1 -0
  346. package/frontend/dist/assets/redshift-D66HwlyV.js +1 -0
  347. package/frontend/dist/assets/requirementDiagram-Z7DCOOCP-CorP7L7F.js +73 -0
  348. package/frontend/dist/assets/restructuredtext-DQT2NKJ2.js +1 -0
  349. package/frontend/dist/assets/rough.esm-DxAX5Vpo.js +1 -0
  350. package/frontend/dist/assets/ruby-iFXI8hwH.js +1 -0
  351. package/frontend/dist/assets/rust-CSKiei34.js +1 -0
  352. package/frontend/dist/assets/sankeyDiagram-WA2Y5GQK-RDx6Bd-B.js +10 -0
  353. package/frontend/dist/assets/sb-Bo3ttdP2.js +1 -0
  354. package/frontend/dist/assets/scala-BC1D-Nxp.js +1 -0
  355. package/frontend/dist/assets/scheme-Z4OAo4Lv.js +1 -0
  356. package/frontend/dist/assets/scss-BvrdPs6B.js +3 -0
  357. package/frontend/dist/assets/sequenceDiagram-2WXFIKYE-JMqJSFq6.js +145 -0
  358. package/frontend/dist/assets/shell-Bh_aCyF-.js +1 -0
  359. package/frontend/dist/assets/solidity-CWHj6tSe.js +1 -0
  360. package/frontend/dist/assets/sophia-raoNtKtm.js +1 -0
  361. package/frontend/dist/assets/sparql-XzmoGnue.js +1 -0
  362. package/frontend/dist/assets/sql-BD0i9Gvg.js +1 -0
  363. package/frontend/dist/assets/src-Bn-kKzs7.js +1 -0
  364. package/frontend/dist/assets/st-DtVKyms6.js +1 -0
  365. package/frontend/dist/assets/stateDiagram-RAJIS63D-CgFfENdy.js +1 -0
  366. package/frontend/dist/assets/stateDiagram-v2-FVOUBMTO-C4Hh2P-U.js +1 -0
  367. package/frontend/dist/assets/swift--UZs77wT.js +1 -0
  368. package/frontend/dist/assets/systemverilog-CDnBSWUd.js +1 -0
  369. package/frontend/dist/assets/tcl-DdCEuTHZ.js +1 -0
  370. package/frontend/dist/assets/timeline-definition-YZTLITO2-BnatPBR5.js +61 -0
  371. package/frontend/dist/assets/treemap-KZPCXAKY-qb1Pl9la.js +1 -0
  372. package/frontend/dist/assets/ts.worker-DyPAEIuH.js +67719 -0
  373. package/frontend/dist/assets/tsMode-iuvyEpyO.js +11 -0
  374. package/frontend/dist/assets/twig-SSL-Altf.js +1 -0
  375. package/frontend/dist/assets/typescript-17918Hud.js +1 -0
  376. package/frontend/dist/assets/typespec-BT7S0ETg.js +1 -0
  377. package/frontend/dist/assets/vb-CrIgucua.js +1 -0
  378. package/frontend/dist/assets/vennDiagram-LZ73GAT5-DygS4Zzd.js +34 -0
  379. package/frontend/dist/assets/wgsl-BeKc3oEp.js +298 -0
  380. package/frontend/dist/assets/workers-DTfwKVoM.js +1 -0
  381. package/frontend/dist/assets/xml-CBMr_Wbw.js +1 -0
  382. package/frontend/dist/assets/xterm-BrP-ENHg.css +1 -0
  383. package/frontend/dist/assets/xterm-CBX2m0YM.js +36 -0
  384. package/frontend/dist/assets/xychartDiagram-JWTSCODW-D6wY1Jwd.js +7 -0
  385. package/frontend/dist/assets/yaml-CTjCH7Bv.js +1 -0
  386. package/frontend/dist/fonts/inter-300.ttf +0 -0
  387. package/frontend/dist/fonts/inter-400.ttf +0 -0
  388. package/frontend/dist/fonts/inter-500.ttf +0 -0
  389. package/frontend/dist/fonts/inter-600.ttf +0 -0
  390. package/frontend/dist/fonts/inter-700.ttf +0 -0
  391. package/frontend/dist/index.html +49 -0
  392. package/frontend/dist/logo_192x192.png +0 -0
  393. package/frontend/dist/logo_32x32.png +0 -0
  394. package/frontend/dist/logo_512x512.png +0 -0
  395. package/frontend/dist/logo_64x64.png +0 -0
  396. package/frontend/dist/logobg_192x192.png +0 -0
  397. package/frontend/dist/logobg_512x512.png +0 -0
  398. package/frontend/dist/logobg_64x64.png +0 -0
  399. package/frontend/dist/manifest.json +25 -0
  400. package/frontend/dist/sw.js +22 -0
  401. package/package.json +74 -7
  402. package/preload/Makefile +12 -0
  403. package/preload/atoo-studio-preload.c +647 -0
  404. package/preload/atoo-studio-preload.so +0 -0
  405. package/setup-cuse.sh +260 -0
  406. package/setup.sh +81 -0
  407. package/src/serial/native/binding.gyp +10 -0
  408. package/src/serial/native/pty_pair.c +222 -0
package/setup-cuse.sh ADDED
@@ -0,0 +1,260 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Setup CUSE (Character device in Userspace) for virtual serial port support.
5
+ # This enables DTR/RTS control signal forwarding for tools like esptool.py.
6
+ #
7
+ # Must be run as root. Only needed once per system.
8
+ #
9
+ # Requirements:
10
+ # - Linux VM or bare-metal (NOT a container — see below)
11
+ # - Root access
12
+ # - gcc, pkg-config
13
+ #
14
+ # Container note (LXC/Docker):
15
+ # CUSE requires kernel module loading and /dev device creation, which
16
+ # containers cannot do. If running inside a container:
17
+ # 1. On the HOST: modprobe cuse && chmod 0666 /dev/cuse
18
+ # 2. Pass /dev/cuse into the container:
19
+ # - LXC: lxc.mount.entry: /dev/cuse dev/cuse none bind,create=file 0 0
20
+ # - Docker: docker run --device /dev/cuse ...
21
+ # 3. LXC must be PRIVILEGED (unprivileged containers cannot create device nodes)
22
+ # 4. Then run this script inside the container (skip modprobe step)
23
+ #
24
+ # If you're on an unprivileged LXC container, CUSE won't work.
25
+ # Use a VM instead, or rely on the PTY fallback (BOOT button for flashing).
26
+
27
+ if [ "$(id -u)" -ne 0 ]; then
28
+ echo "Error: This script must be run as root (sudo $0)"
29
+ exit 1
30
+ fi
31
+
32
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
33
+ NATIVE_DIR="$SCRIPT_DIR/src/serial/native"
34
+ BUILD_DIR="$NATIVE_DIR/build/Release"
35
+ # Install to ~/.atoo-studio/bin/ so node-gyp rebuilds don't wipe capabilities/suid
36
+ INSTALL_USER="${SUDO_USER:-$(logname 2>/dev/null || echo root)}"
37
+ INSTALL_HOME="$(eval echo "~$INSTALL_USER")"
38
+ INSTALL_DIR="$INSTALL_HOME/.atoo-studio/bin"
39
+
40
+ echo "=== Setting up CUSE for atoo-studio ==="
41
+
42
+ # Detect container environment
43
+ VIRT=""
44
+ if command -v systemd-detect-virt &>/dev/null; then
45
+ VIRT="$(systemd-detect-virt -c 2>/dev/null || true)"
46
+ elif [ -f /proc/1/cgroup ]; then
47
+ if grep -qE 'lxc|docker|containerd' /proc/1/environ 2>/dev/null || \
48
+ grep -qE '/lxc/|/docker/' /proc/1/cgroup 2>/dev/null; then
49
+ VIRT="container"
50
+ fi
51
+ fi
52
+ # Also check for /.dockerenv
53
+ if [ -f /.dockerenv ]; then
54
+ VIRT="docker"
55
+ fi
56
+
57
+ IS_CONTAINER=false
58
+ case "$VIRT" in
59
+ lxc|lxc-libvirt|docker|podman|container)
60
+ IS_CONTAINER=true
61
+ ;;
62
+ esac
63
+
64
+ if [ "$IS_CONTAINER" = true ]; then
65
+ echo ""
66
+ echo " Container detected: $VIRT"
67
+ echo ""
68
+ echo " CUSE requires kernel-level access that containers don't have."
69
+ echo " You need to set this up on the HOST first:"
70
+ echo ""
71
+ echo " 1. On the host, load the cuse kernel module:"
72
+ echo " sudo modprobe cuse"
73
+ echo " echo cuse | sudo tee /etc/modules-load.d/cuse.conf"
74
+ echo ""
75
+ echo " 2. On the host, make /dev/cuse accessible:"
76
+ echo " sudo chmod 0666 /dev/cuse"
77
+ echo " # To persist across reboots, add a udev rule on the host:"
78
+ echo " echo 'KERNEL==\"cuse\", MODE=\"0666\"' | sudo tee /etc/udev/rules.d/99-cuse.rules"
79
+ echo " sudo udevadm control --reload-rules"
80
+ echo ""
81
+ if [ "$VIRT" = "lxc" ] || [ "$VIRT" = "lxc-libvirt" ]; then
82
+ echo " 3. Pass /dev/cuse into this LXC container and allow device creation."
83
+ echo " Add to the container config (e.g. /etc/pve/lxc/<ID>.conf):"
84
+ echo ""
85
+ echo " lxc.cgroup2.devices.allow: a"
86
+ echo " lxc.mount.entry: /dev/cuse dev/cuse none bind,create=file 0 0"
87
+ echo ""
88
+ echo " Important: The LXC container MUST be privileged (unprivileged: 0)."
89
+ echo " CUSE creates device nodes in /dev which unprivileged containers"
90
+ echo " cannot do. Switching an existing container from unprivileged to"
91
+ echo " privileged can break file ownership — it's easier to create a"
92
+ echo " new privileged container if needed."
93
+ echo ""
94
+ echo " 'devices.allow: a' is also required because CUSE creates device"
95
+ echo " nodes (/dev/ttyVS*) with dynamically assigned major/minor numbers."
96
+ echo " On a VM or bare-metal, none of this is needed."
97
+ echo ""
98
+ echo " 4. Restart the container, then re-run this script."
99
+ elif [ "$VIRT" = "docker" ] || [ "$VIRT" = "podman" ]; then
100
+ echo " 3. Run the container with --device /dev/cuse"
101
+ echo " docker run --device /dev/cuse ..."
102
+ echo ""
103
+ echo " 4. Re-run this script inside the container."
104
+ else
105
+ echo " 3. Pass /dev/cuse into this container and re-run this script."
106
+ fi
107
+ echo ""
108
+
109
+ # Check if /dev/cuse was already passed through
110
+ if [ -e /dev/cuse ]; then
111
+ echo " /dev/cuse is available — host setup appears done. Continuing..."
112
+ echo ""
113
+
114
+ # Verify /dev/cuse is actually accessible
115
+ if [ ! -w /dev/cuse ]; then
116
+ echo " Error: /dev/cuse exists but is not writable."
117
+ echo " On the HOST, run: sudo chmod 0666 /dev/cuse"
118
+ echo " Or add a udev rule (see instructions above)."
119
+ exit 1
120
+ fi
121
+ else
122
+ echo " /dev/cuse is NOT available. Complete the host setup above first."
123
+ echo ""
124
+ echo " Note: Without CUSE, atoo-studio will still work using PTY fallback,"
125
+ echo " but DTR/RTS control signals won't be forwarded. You'll need to"
126
+ echo " use the BOOT button on your device when flashing."
127
+ exit 1
128
+ fi
129
+ fi
130
+
131
+ # 1. Ensure build tools are available (gcc, pkg-config)
132
+ MISSING_PKGS=()
133
+ command -v gcc &>/dev/null || MISSING_PKGS+=(gcc)
134
+ command -v pkg-config &>/dev/null || MISSING_PKGS+=(pkg-config)
135
+
136
+ if [ ${#MISSING_PKGS[@]} -gt 0 ]; then
137
+ echo "Installing missing build tools: ${MISSING_PKGS[*]}..."
138
+ if command -v apt-get &>/dev/null; then
139
+ apt-get install -y "${MISSING_PKGS[@]}"
140
+ elif command -v dnf &>/dev/null; then
141
+ # pkg-config is pkgconf-pkg-config on Fedora/RHEL
142
+ DNF_PKGS=("${MISSING_PKGS[@]/pkg-config/pkgconf-pkg-config}")
143
+ dnf install -y "${DNF_PKGS[@]}"
144
+ elif command -v pacman &>/dev/null; then
145
+ PAC_PKGS=("${MISSING_PKGS[@]/pkg-config/pkgconf}")
146
+ pacman -S --noconfirm "${PAC_PKGS[@]}"
147
+ else
148
+ echo "Error: Missing ${MISSING_PKGS[*]}. Install them manually."
149
+ exit 1
150
+ fi
151
+ fi
152
+
153
+ # 2. Install libfuse3-dev if needed
154
+ if ! pkg-config --exists fuse3 2>/dev/null; then
155
+ echo "Installing libfuse3-dev..."
156
+ if command -v apt-get &>/dev/null; then
157
+ apt-get install -y libfuse3-dev || true
158
+ # Verify it actually installed despite possible unrelated dpkg errors
159
+ if ! pkg-config --exists fuse3 2>/dev/null; then
160
+ echo "Error: libfuse3-dev failed to install."
161
+ exit 1
162
+ fi
163
+ elif command -v dnf &>/dev/null; then
164
+ dnf install -y fuse3-devel
165
+ elif command -v pacman &>/dev/null; then
166
+ pacman -S --noconfirm fuse3
167
+ else
168
+ echo "Error: Could not install libfuse3-dev. Install it manually."
169
+ exit 1
170
+ fi
171
+ fi
172
+
173
+ # 3. Load cuse kernel module (skip in containers — must be done on host)
174
+ if [ "$IS_CONTAINER" = true ]; then
175
+ if [ ! -e /dev/cuse ]; then
176
+ echo "Error: /dev/cuse not available. Load cuse module on the host first."
177
+ exit 1
178
+ fi
179
+ echo "Container mode: skipping modprobe (using host-provided /dev/cuse)"
180
+ else
181
+ if ! lsmod | grep -q '^cuse '; then
182
+ echo "Loading cuse kernel module..."
183
+ if ! modprobe cuse 2>/dev/null; then
184
+ echo ""
185
+ echo "Error: Failed to load cuse kernel module."
186
+ echo ""
187
+ echo "Possible causes:"
188
+ echo " - Module not available in your kernel ($(uname -r))"
189
+ echo " Try: apt-get install linux-modules-extra-$(uname -r)"
190
+ echo " Or rebuild kernel with CONFIG_CUSE=m"
191
+ echo " - Running inside a container (modprobe is restricted)"
192
+ echo ""
193
+ echo "Without CUSE, atoo-studio will use PTY fallback (no DTR/RTS signals)."
194
+ echo "You'll need to use the BOOT button on your device when flashing."
195
+ exit 1
196
+ fi
197
+ fi
198
+
199
+ # Persist across reboots
200
+ if [ -d /etc/modules-load.d ]; then
201
+ echo "cuse" > /etc/modules-load.d/atoo-studio-cuse.conf
202
+ echo "Persisted cuse module load to /etc/modules-load.d/atoo-studio-cuse.conf"
203
+ fi
204
+ fi
205
+
206
+ # 4. Build the CUSE serial helper
207
+ echo "Building cuse_serial..."
208
+ mkdir -p "$BUILD_DIR"
209
+ gcc -Wall -Wextra -O2 \
210
+ "$NATIVE_DIR/cuse_serial.c" \
211
+ -o "$BUILD_DIR/cuse_serial" \
212
+ $(pkg-config --cflags --libs fuse3) \
213
+ -lpthread
214
+
215
+ echo "Built: $BUILD_DIR/cuse_serial"
216
+
217
+ # 5. Install to ~/.atoo-studio/bin/ so node-gyp rebuilds don't wipe capabilities
218
+ echo "Installing cuse_serial to $INSTALL_DIR/ ..."
219
+ mkdir -p "$INSTALL_DIR"
220
+ cp "$BUILD_DIR/cuse_serial" "$INSTALL_DIR/cuse_serial"
221
+
222
+ # 6. Set capability so it can create /dev/ entries without full root
223
+ echo "Setting CAP_SYS_ADMIN capability on cuse_serial..."
224
+ if setcap cap_sys_admin+ep "$INSTALL_DIR/cuse_serial" 2>/dev/null; then
225
+ echo "Capability set. cuse_serial can run without root."
226
+ else
227
+ echo ""
228
+ echo " Warning: setcap failed (common in LXC/Docker containers)."
229
+ echo " The cuse_serial binary will need to run as root."
230
+ echo ""
231
+ echo " To allow non-root usage, set the suid bit instead:"
232
+ echo " sudo chown root:root $INSTALL_DIR/cuse_serial"
233
+ echo " sudo chmod u+s $INSTALL_DIR/cuse_serial"
234
+ echo ""
235
+ echo " Or run atoo-studio itself as root (not recommended)."
236
+ echo ""
237
+
238
+ # In container mode, set suid as fallback since setcap doesn't work
239
+ if [ "$IS_CONTAINER" = true ]; then
240
+ echo " Applying suid fallback for container environment..."
241
+ chown root:root "$INSTALL_DIR/cuse_serial"
242
+ chmod u+s "$INSTALL_DIR/cuse_serial"
243
+ echo " Done: suid bit set on cuse_serial."
244
+ fi
245
+ fi
246
+
247
+ # 7. Add udev rule so the created /dev/ttyVS* devices are world-accessible
248
+ if command -v udevadm &>/dev/null; then
249
+ UDEV_RULE="/etc/udev/rules.d/99-atoo-studio-serial.rules"
250
+ echo 'KERNEL=="ttyVS[0-9]*", MODE="0666"' > "$UDEV_RULE"
251
+ udevadm control --reload-rules 2>/dev/null || true
252
+ echo "Installed udev rule: $UDEV_RULE"
253
+ else
254
+ echo "Warning: udevadm not found. /dev/ttyVS* devices may need manual chmod."
255
+ fi
256
+
257
+ echo ""
258
+ echo "=== CUSE setup complete ==="
259
+ echo "Virtual serial devices (/dev/ttyVS*) will now support DTR/RTS control signals."
260
+ echo "No reboot required."
package/setup.sh ADDED
@@ -0,0 +1,81 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Install system dependencies for atoo-studio (headless mode).
5
+ # Must be run as root (sudo ./setup.sh).
6
+ #
7
+ # NOTE: If using Docker preview mode (docker/preview/build.sh), these
8
+ # system deps are not needed — everything runs inside the container.
9
+ # Only ffmpeg is still useful on the host for encoding screen recordings.
10
+
11
+ echo "=== atoo-studio system setup ==="
12
+
13
+ if [ "$(uname -s)" = "Darwin" ]; then
14
+ # --- macOS ---
15
+ # Puppeteer bundles Chromium and macOS has all required system libs.
16
+ # Only ffmpeg is needed for screen recording support.
17
+ echo ""
18
+ echo "Installing ffmpeg for screen recording support..."
19
+
20
+ if command -v brew &>/dev/null; then
21
+ brew install ffmpeg
22
+ else
23
+ echo "Error: Homebrew not found. Install it from https://brew.sh"
24
+ echo "Then re-run this script, or install ffmpeg manually."
25
+ exit 1
26
+ fi
27
+
28
+ echo ""
29
+ echo "=== Setup complete ==="
30
+ echo "You can now run: npx atoo-studio"
31
+ exit 0
32
+ fi
33
+
34
+ # --- Linux ---
35
+ if [ "$(id -u)" -ne 0 ]; then
36
+ echo "Error: This script must be run as root (sudo $0)"
37
+ exit 1
38
+ fi
39
+
40
+ # --- Chrome / Puppeteer dependencies ---
41
+ echo ""
42
+ echo "Installing Chrome dependencies for browser preview..."
43
+
44
+ CHROME_PKGS=(
45
+ libatk1.0-0 libatk-bridge2.0-0 libcups2 libatspi2.0-0
46
+ libxcomposite1 libxdamage1 libxfixes3 libxrandr2
47
+ libgbm1 libcairo2 libpango-1.0-0
48
+ )
49
+
50
+ # ffmpeg is used for encoding screen recordings to WebM
51
+ RECORDING_PKGS=(
52
+ ffmpeg
53
+ )
54
+
55
+ if command -v apt-get &>/dev/null; then
56
+ # libasound2 was renamed to libasound2t64 in Ubuntu 24.04+
57
+ if apt-cache show libasound2t64 &>/dev/null 2>&1; then
58
+ CHROME_PKGS+=(libasound2t64)
59
+ else
60
+ CHROME_PKGS+=(libasound2)
61
+ fi
62
+ apt-get install -y "${CHROME_PKGS[@]}" "${RECORDING_PKGS[@]}"
63
+ elif command -v dnf &>/dev/null; then
64
+ dnf install -y atk at-spi2-atk cups-libs libXcomposite libXdamage \
65
+ libXfixes libXrandr mesa-libgbm cairo pango alsa-lib \
66
+ ffmpeg
67
+ elif command -v pacman &>/dev/null; then
68
+ pacman -S --noconfirm atk at-spi2-atk libcups libxcomposite libxdamage \
69
+ libxfixes libxrandr mesa cairo pango alsa-lib \
70
+ ffmpeg
71
+ else
72
+ echo "Error: No supported package manager found (apt-get, dnf, pacman)."
73
+ echo "Install Chrome dependencies manually."
74
+ exit 1
75
+ fi
76
+
77
+ echo "All dependencies installed (Chrome libs, ffmpeg)."
78
+
79
+ echo ""
80
+ echo "=== Setup complete ==="
81
+ echo "You can now run: npx atoo-studio"
@@ -0,0 +1,10 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "pty_pair",
5
+ "sources": ["pty_pair.c"],
6
+ "cflags": ["-Wall", "-Wextra", "-O2"],
7
+ "defines": ["_GNU_SOURCE"]
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,222 @@
1
+ #ifndef _GNU_SOURCE
2
+ #define _GNU_SOURCE
3
+ #endif
4
+ #include <node_api.h>
5
+ #include <stdlib.h>
6
+ #include <stdio.h>
7
+ #include <string.h>
8
+ #include <unistd.h>
9
+ #include <fcntl.h>
10
+ #include <errno.h>
11
+ #include <termios.h>
12
+ #include <sys/ioctl.h>
13
+
14
+ // Helper: throw JS error and return NULL
15
+ #define NAPI_THROW(env, msg) do { \
16
+ napi_throw_error(env, NULL, msg); \
17
+ return NULL; \
18
+ } while (0)
19
+
20
+ #define NAPI_CHECK(env, status) do { \
21
+ if ((status) != napi_ok) { \
22
+ napi_throw_error(env, NULL, "N-API call failed"); \
23
+ return NULL; \
24
+ } \
25
+ } while (0)
26
+
27
+ // createPtyPair() -> { masterFd: number, slavePath: string }
28
+ static napi_value CreatePtyPair(napi_env env, napi_callback_info info) {
29
+ (void)info;
30
+
31
+ // Open the PTY master
32
+ int master_fd = posix_openpt(O_RDWR | O_NOCTTY);
33
+ if (master_fd < 0) {
34
+ char buf[256];
35
+ snprintf(buf, sizeof(buf), "posix_openpt failed: %s", strerror(errno));
36
+ NAPI_THROW(env, buf);
37
+ }
38
+
39
+ if (grantpt(master_fd) < 0) {
40
+ close(master_fd);
41
+ NAPI_THROW(env, "grantpt failed");
42
+ }
43
+
44
+ if (unlockpt(master_fd) < 0) {
45
+ close(master_fd);
46
+ NAPI_THROW(env, "unlockpt failed");
47
+ }
48
+
49
+ char *slave_name = ptsname(master_fd);
50
+ if (!slave_name) {
51
+ close(master_fd);
52
+ NAPI_THROW(env, "ptsname failed");
53
+ }
54
+
55
+ // Open slave briefly to configure raw mode, then close
56
+ int slave_fd = open(slave_name, O_RDWR | O_NOCTTY);
57
+ if (slave_fd >= 0) {
58
+ struct termios tio;
59
+ if (tcgetattr(slave_fd, &tio) == 0) {
60
+ cfmakeraw(&tio);
61
+ tcsetattr(slave_fd, TCSANOW, &tio);
62
+ }
63
+ close(slave_fd);
64
+ }
65
+
66
+ // Also set raw mode on master side
67
+ struct termios mtio;
68
+ if (tcgetattr(master_fd, &mtio) == 0) {
69
+ cfmakeraw(&mtio);
70
+ tcsetattr(master_fd, TCSANOW, &mtio);
71
+ }
72
+
73
+ // Set master fd to non-blocking
74
+ int flags = fcntl(master_fd, F_GETFL);
75
+ if (flags >= 0) {
76
+ fcntl(master_fd, F_SETFL, flags | O_NONBLOCK);
77
+ }
78
+
79
+ // Build result object
80
+ napi_value result, fd_val, path_val;
81
+ NAPI_CHECK(env, napi_create_object(env, &result));
82
+ NAPI_CHECK(env, napi_create_int32(env, master_fd, &fd_val));
83
+ NAPI_CHECK(env, napi_create_string_utf8(env, slave_name, NAPI_AUTO_LENGTH, &path_val));
84
+ NAPI_CHECK(env, napi_set_named_property(env, result, "masterFd", fd_val));
85
+ NAPI_CHECK(env, napi_set_named_property(env, result, "slavePath", path_val));
86
+
87
+ return result;
88
+ }
89
+
90
+ // getModemBits(masterFd: number) -> { dtr: boolean, rts: boolean }
91
+ static napi_value GetModemBits(napi_env env, napi_callback_info info) {
92
+ size_t argc = 1;
93
+ napi_value argv[1];
94
+ NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
95
+
96
+ if (argc < 1) NAPI_THROW(env, "getModemBits requires masterFd argument");
97
+
98
+ int32_t fd;
99
+ NAPI_CHECK(env, napi_get_value_int32(env, argv[0], &fd));
100
+
101
+ int bits = 0;
102
+ if (ioctl(fd, TIOCMGET, &bits) < 0) {
103
+ // PTYs may not support TIOCMGET — return defaults
104
+ bits = 0;
105
+ }
106
+
107
+ napi_value result, dtr_val, rts_val;
108
+ NAPI_CHECK(env, napi_create_object(env, &result));
109
+ NAPI_CHECK(env, napi_get_boolean(env, (bits & TIOCM_DTR) != 0, &dtr_val));
110
+ NAPI_CHECK(env, napi_get_boolean(env, (bits & TIOCM_RTS) != 0, &rts_val));
111
+ NAPI_CHECK(env, napi_set_named_property(env, result, "dtr", dtr_val));
112
+ NAPI_CHECK(env, napi_set_named_property(env, result, "rts", rts_val));
113
+
114
+ return result;
115
+ }
116
+
117
+ // setModemBits(masterFd: number, dtr: boolean, rts: boolean) -> void
118
+ // Used to set modem bits on the master (so slave-side tools see them)
119
+ static napi_value SetModemBits(napi_env env, napi_callback_info info) {
120
+ size_t argc = 3;
121
+ napi_value argv[3];
122
+ NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
123
+
124
+ if (argc < 3) NAPI_THROW(env, "setModemBits requires (masterFd, dtr, rts)");
125
+
126
+ int32_t fd;
127
+ bool dtr, rts;
128
+ NAPI_CHECK(env, napi_get_value_int32(env, argv[0], &fd));
129
+ NAPI_CHECK(env, napi_get_value_bool(env, argv[1], &dtr));
130
+ NAPI_CHECK(env, napi_get_value_bool(env, argv[2], &rts));
131
+
132
+ int bits = 0;
133
+ if (dtr) bits |= TIOCM_DTR;
134
+ if (rts) bits |= TIOCM_RTS;
135
+
136
+ ioctl(fd, TIOCMSET, &bits); // May fail on PTYs - that's OK
137
+
138
+ return NULL;
139
+ }
140
+
141
+ // readMaster(masterFd: number, buffer: Buffer) -> number (bytes read, 0 if EAGAIN, -1 if closed)
142
+ static napi_value ReadMaster(napi_env env, napi_callback_info info) {
143
+ size_t argc = 2;
144
+ napi_value argv[2];
145
+ NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
146
+
147
+ if (argc < 2) NAPI_THROW(env, "readMaster requires (masterFd, buffer)");
148
+
149
+ int32_t fd;
150
+ NAPI_CHECK(env, napi_get_value_int32(env, argv[0], &fd));
151
+
152
+ void *buf;
153
+ size_t buf_len;
154
+ NAPI_CHECK(env, napi_get_buffer_info(env, argv[1], &buf, &buf_len));
155
+
156
+ ssize_t n = read(fd, buf, buf_len);
157
+ int32_t result_val;
158
+ if (n < 0) {
159
+ result_val = (errno == EAGAIN || errno == EWOULDBLOCK) ? 0 : -1;
160
+ } else {
161
+ result_val = (int32_t)n;
162
+ }
163
+
164
+ napi_value result;
165
+ NAPI_CHECK(env, napi_create_int32(env, result_val, &result));
166
+ return result;
167
+ }
168
+
169
+ // writeMaster(masterFd: number, buffer: Buffer, length: number) -> number (bytes written)
170
+ static napi_value WriteMaster(napi_env env, napi_callback_info info) {
171
+ size_t argc = 3;
172
+ napi_value argv[3];
173
+ NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
174
+
175
+ if (argc < 3) NAPI_THROW(env, "writeMaster requires (masterFd, buffer, length)");
176
+
177
+ int32_t fd, length;
178
+ NAPI_CHECK(env, napi_get_value_int32(env, argv[0], &fd));
179
+
180
+ void *buf;
181
+ size_t buf_len;
182
+ NAPI_CHECK(env, napi_get_buffer_info(env, argv[1], &buf, &buf_len));
183
+ NAPI_CHECK(env, napi_get_value_int32(env, argv[2], &length));
184
+
185
+ size_t to_write = (size_t)length < buf_len ? (size_t)length : buf_len;
186
+ ssize_t n = write(fd, buf, to_write);
187
+
188
+ napi_value result;
189
+ NAPI_CHECK(env, napi_create_int32(env, n < 0 ? -1 : (int32_t)n, &result));
190
+ return result;
191
+ }
192
+
193
+ // closeFd(fd: number) -> void
194
+ static napi_value CloseFd(napi_env env, napi_callback_info info) {
195
+ size_t argc = 1;
196
+ napi_value argv[1];
197
+ NAPI_CHECK(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
198
+
199
+ if (argc < 1) NAPI_THROW(env, "closeFd requires fd argument");
200
+
201
+ int32_t fd;
202
+ NAPI_CHECK(env, napi_get_value_int32(env, argv[0], &fd));
203
+
204
+ close(fd);
205
+ return NULL;
206
+ }
207
+
208
+ // Module init
209
+ static napi_value Init(napi_env env, napi_value exports) {
210
+ napi_property_descriptor props[] = {
211
+ {"createPtyPair", NULL, CreatePtyPair, NULL, NULL, NULL, napi_default, NULL},
212
+ {"getModemBits", NULL, GetModemBits, NULL, NULL, NULL, napi_default, NULL},
213
+ {"setModemBits", NULL, SetModemBits, NULL, NULL, NULL, napi_default, NULL},
214
+ {"readMaster", NULL, ReadMaster, NULL, NULL, NULL, napi_default, NULL},
215
+ {"writeMaster", NULL, WriteMaster, NULL, NULL, NULL, napi_default, NULL},
216
+ {"closeFd", NULL, CloseFd, NULL, NULL, NULL, napi_default, NULL},
217
+ };
218
+ NAPI_CHECK(env, napi_define_properties(env, exports, sizeof(props) / sizeof(props[0]), props));
219
+ return exports;
220
+ }
221
+
222
+ NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)