@andrew.ng/symbion 0.1.0

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 (417) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/apps/daemon/dist/boot/menu.d.ts +11 -0
  4. package/apps/daemon/dist/boot/menu.d.ts.map +1 -0
  5. package/apps/daemon/dist/boot/menu.js +32 -0
  6. package/apps/daemon/dist/boot/menu.js.map +1 -0
  7. package/apps/daemon/dist/fs/folderPick.d.ts +13 -0
  8. package/apps/daemon/dist/fs/folderPick.d.ts.map +1 -0
  9. package/apps/daemon/dist/fs/folderPick.js +4 -0
  10. package/apps/daemon/dist/fs/folderPick.js.map +1 -0
  11. package/apps/daemon/dist/fs/listDir.d.ts +13 -0
  12. package/apps/daemon/dist/fs/listDir.d.ts.map +1 -0
  13. package/apps/daemon/dist/fs/listDir.js +121 -0
  14. package/apps/daemon/dist/fs/listDir.js.map +1 -0
  15. package/apps/daemon/dist/fs/readTargetFiles.d.ts +20 -0
  16. package/apps/daemon/dist/fs/readTargetFiles.d.ts.map +1 -0
  17. package/apps/daemon/dist/fs/readTargetFiles.js +76 -0
  18. package/apps/daemon/dist/fs/readTargetFiles.js.map +1 -0
  19. package/apps/daemon/dist/fs/writeFiles.d.ts +32 -0
  20. package/apps/daemon/dist/fs/writeFiles.d.ts.map +1 -0
  21. package/apps/daemon/dist/fs/writeFiles.js +93 -0
  22. package/apps/daemon/dist/fs/writeFiles.js.map +1 -0
  23. package/apps/daemon/dist/git/status.d.ts +11 -0
  24. package/apps/daemon/dist/git/status.d.ts.map +1 -0
  25. package/apps/daemon/dist/git/status.js +30 -0
  26. package/apps/daemon/dist/git/status.js.map +1 -0
  27. package/apps/daemon/dist/index.d.ts +2 -0
  28. package/apps/daemon/dist/index.d.ts.map +1 -0
  29. package/apps/daemon/dist/index.js +69 -0
  30. package/apps/daemon/dist/index.js.map +1 -0
  31. package/apps/daemon/dist/llm/anthropicProvider.d.ts +26 -0
  32. package/apps/daemon/dist/llm/anthropicProvider.d.ts.map +1 -0
  33. package/apps/daemon/dist/llm/anthropicProvider.js +90 -0
  34. package/apps/daemon/dist/llm/anthropicProvider.js.map +1 -0
  35. package/apps/daemon/dist/llm/geminiProvider.d.ts +25 -0
  36. package/apps/daemon/dist/llm/geminiProvider.d.ts.map +1 -0
  37. package/apps/daemon/dist/llm/geminiProvider.js +89 -0
  38. package/apps/daemon/dist/llm/geminiProvider.js.map +1 -0
  39. package/apps/daemon/dist/llm/installInstructions.d.ts +40 -0
  40. package/apps/daemon/dist/llm/installInstructions.d.ts.map +1 -0
  41. package/apps/daemon/dist/llm/installInstructions.js +80 -0
  42. package/apps/daemon/dist/llm/installInstructions.js.map +1 -0
  43. package/apps/daemon/dist/llm/ollamaProvider.d.ts +55 -0
  44. package/apps/daemon/dist/llm/ollamaProvider.d.ts.map +1 -0
  45. package/apps/daemon/dist/llm/ollamaProvider.js +213 -0
  46. package/apps/daemon/dist/llm/ollamaProvider.js.map +1 -0
  47. package/apps/daemon/dist/llm/openaiProvider.d.ts +25 -0
  48. package/apps/daemon/dist/llm/openaiProvider.d.ts.map +1 -0
  49. package/apps/daemon/dist/llm/openaiProvider.js +90 -0
  50. package/apps/daemon/dist/llm/openaiProvider.js.map +1 -0
  51. package/apps/daemon/dist/llm/providerStatus.d.ts +60 -0
  52. package/apps/daemon/dist/llm/providerStatus.d.ts.map +1 -0
  53. package/apps/daemon/dist/llm/providerStatus.js +88 -0
  54. package/apps/daemon/dist/llm/providerStatus.js.map +1 -0
  55. package/apps/daemon/dist/llm/registry.d.ts +14 -0
  56. package/apps/daemon/dist/llm/registry.d.ts.map +1 -0
  57. package/apps/daemon/dist/llm/registry.js +35 -0
  58. package/apps/daemon/dist/llm/registry.js.map +1 -0
  59. package/apps/daemon/dist/llm/remoteProvider.d.ts +25 -0
  60. package/apps/daemon/dist/llm/remoteProvider.d.ts.map +1 -0
  61. package/apps/daemon/dist/llm/remoteProvider.js +88 -0
  62. package/apps/daemon/dist/llm/remoteProvider.js.map +1 -0
  63. package/apps/daemon/dist/llm/secrets.d.ts +55 -0
  64. package/apps/daemon/dist/llm/secrets.d.ts.map +1 -0
  65. package/apps/daemon/dist/llm/secrets.js +167 -0
  66. package/apps/daemon/dist/llm/secrets.js.map +1 -0
  67. package/apps/daemon/dist/llm/types.d.ts +50 -0
  68. package/apps/daemon/dist/llm/types.d.ts.map +1 -0
  69. package/apps/daemon/dist/llm/types.js +16 -0
  70. package/apps/daemon/dist/llm/types.js.map +1 -0
  71. package/apps/daemon/dist/net/findOpenPort.d.ts +26 -0
  72. package/apps/daemon/dist/net/findOpenPort.d.ts.map +1 -0
  73. package/apps/daemon/dist/net/findOpenPort.js +37 -0
  74. package/apps/daemon/dist/net/findOpenPort.js.map +1 -0
  75. package/apps/daemon/dist/rpc/contract.d.ts +10 -0
  76. package/apps/daemon/dist/rpc/contract.d.ts.map +1 -0
  77. package/apps/daemon/dist/rpc/contract.js +2 -0
  78. package/apps/daemon/dist/rpc/contract.js.map +1 -0
  79. package/apps/daemon/dist/rpc/guard.d.ts +18 -0
  80. package/apps/daemon/dist/rpc/guard.d.ts.map +1 -0
  81. package/apps/daemon/dist/rpc/guard.js +75 -0
  82. package/apps/daemon/dist/rpc/guard.js.map +1 -0
  83. package/apps/daemon/dist/rpc/handlers.d.ts +118 -0
  84. package/apps/daemon/dist/rpc/handlers.d.ts.map +1 -0
  85. package/apps/daemon/dist/rpc/handlers.js +694 -0
  86. package/apps/daemon/dist/rpc/handlers.js.map +1 -0
  87. package/apps/daemon/dist/rpc/pathStyle.d.ts +27 -0
  88. package/apps/daemon/dist/rpc/pathStyle.d.ts.map +1 -0
  89. package/apps/daemon/dist/rpc/pathStyle.js +43 -0
  90. package/apps/daemon/dist/rpc/pathStyle.js.map +1 -0
  91. package/apps/daemon/dist/rpc/rpcError.d.ts +13 -0
  92. package/apps/daemon/dist/rpc/rpcError.d.ts.map +1 -0
  93. package/apps/daemon/dist/rpc/rpcError.js +16 -0
  94. package/apps/daemon/dist/rpc/rpcError.js.map +1 -0
  95. package/apps/daemon/dist/server.d.ts +18 -0
  96. package/apps/daemon/dist/server.d.ts.map +1 -0
  97. package/apps/daemon/dist/server.js +208 -0
  98. package/apps/daemon/dist/server.js.map +1 -0
  99. package/apps/daemon/dist/store/publishLog.d.ts +6 -0
  100. package/apps/daemon/dist/store/publishLog.d.ts.map +1 -0
  101. package/apps/daemon/dist/store/publishLog.js +27 -0
  102. package/apps/daemon/dist/store/publishLog.js.map +1 -0
  103. package/apps/daemon/dist/store/store.d.ts +35 -0
  104. package/apps/daemon/dist/store/store.d.ts.map +1 -0
  105. package/apps/daemon/dist/store/store.js +129 -0
  106. package/apps/daemon/dist/store/store.js.map +1 -0
  107. package/apps/daemon/dist/templates/githubFetch.d.ts +49 -0
  108. package/apps/daemon/dist/templates/githubFetch.d.ts.map +1 -0
  109. package/apps/daemon/dist/templates/githubFetch.js +168 -0
  110. package/apps/daemon/dist/templates/githubFetch.js.map +1 -0
  111. package/apps/web/out/404.html +1 -0
  112. package/apps/web/out/_next/static/IIw50lkv8jQuwHOBZJifS/_buildManifest.js +1 -0
  113. package/apps/web/out/_next/static/IIw50lkv8jQuwHOBZJifS/_ssgManifest.js +1 -0
  114. package/apps/web/out/_next/static/chunks/1dd3208c-6a745fea7bd2124a.js +1 -0
  115. package/apps/web/out/_next/static/chunks/426-deb95a16531d3b4b.js +25 -0
  116. package/apps/web/out/_next/static/chunks/528-6e64508688610bfe.js +2 -0
  117. package/apps/web/out/_next/static/chunks/656-fd1628581ad77b01.js +1 -0
  118. package/apps/web/out/_next/static/chunks/777-d587bc7cc0fc6be8.js +1 -0
  119. package/apps/web/out/_next/static/chunks/990-f2445c68c17fa077.js +1 -0
  120. package/apps/web/out/_next/static/chunks/app/_not-found/page-e0d77774c4eb9aef.js +1 -0
  121. package/apps/web/out/_next/static/chunks/app/layout-e5023aba6634ce53.js +1 -0
  122. package/apps/web/out/_next/static/chunks/app/page-a545c902535ac2e3.js +1 -0
  123. package/apps/web/out/_next/static/chunks/app/settings/page-a68ed4ae2ccb8840.js +1 -0
  124. package/apps/web/out/_next/static/chunks/app/templates/page-e5f0cefb905e5b72.js +1 -0
  125. package/apps/web/out/_next/static/chunks/baeaa4ff-28d2e32e4dd119b9.js +1 -0
  126. package/apps/web/out/_next/static/chunks/eb0351e1-329719bc902eaf71.js +1 -0
  127. package/apps/web/out/_next/static/chunks/framework-3664cab31236a9fa.js +1 -0
  128. package/apps/web/out/_next/static/chunks/main-app-d515c42ecb17b8e8.js +1 -0
  129. package/apps/web/out/_next/static/chunks/main-ff24788874d4ec1b.js +1 -0
  130. package/apps/web/out/_next/static/chunks/pages/_app-10a93ab5b7c32eb3.js +1 -0
  131. package/apps/web/out/_next/static/chunks/pages/_error-2d792b2a41857be4.js +1 -0
  132. package/apps/web/out/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  133. package/apps/web/out/_next/static/chunks/webpack-ae7ee8fe97fdceba.js +1 -0
  134. package/apps/web/out/_next/static/css/0a42edcfc2beb916.css +3 -0
  135. package/apps/web/out/_next/static/css/a275cc2b185e04f8.css +1 -0
  136. package/apps/web/out/_next/static/media/011e180705008d6f-s.woff2 +0 -0
  137. package/apps/web/out/_next/static/media/20535187d867b7b9-s.woff2 +0 -0
  138. package/apps/web/out/_next/static/media/26d4368bf94c0ec4-s.p.woff2 +0 -0
  139. package/apps/web/out/_next/static/media/2801417b65625cf5-s.woff2 +0 -0
  140. package/apps/web/out/_next/static/media/28793f5c5e3d822d-s.woff2 +0 -0
  141. package/apps/web/out/_next/static/media/5356a6a4f2c8c8d8-s.woff2 +0 -0
  142. package/apps/web/out/_next/static/media/58f386aa6b1a2a92-s.woff2 +0 -0
  143. package/apps/web/out/_next/static/media/73cb51aac9c97f90-s.woff2 +0 -0
  144. package/apps/web/out/_next/static/media/7b19b489dc6743ba-s.woff2 +0 -0
  145. package/apps/web/out/_next/static/media/7ba5fb2a8c88521c-s.woff2 +0 -0
  146. package/apps/web/out/_next/static/media/92eeb95d069020cc-s.woff2 +0 -0
  147. package/apps/web/out/_next/static/media/98e207f02528a563-s.p.woff2 +0 -0
  148. package/apps/web/out/_next/static/media/99dcf268bda04fe5-s.woff2 +0 -0
  149. package/apps/web/out/_next/static/media/b3bf17a9041d9433-s.woff2 +0 -0
  150. package/apps/web/out/_next/static/media/c9c3823090ec8b55-s.woff2 +0 -0
  151. package/apps/web/out/_next/static/media/d26bbd13d6b70f89-s.woff2 +0 -0
  152. package/apps/web/out/_next/static/media/d29838c109ef09b4-s.woff2 +0 -0
  153. package/apps/web/out/_next/static/media/d3ebbfd689654d3a-s.p.woff2 +0 -0
  154. package/apps/web/out/_next/static/media/db96af6b531dc71f-s.p.woff2 +0 -0
  155. package/apps/web/out/_next/static/media/e40af3453d7c920a-s.woff2 +0 -0
  156. package/apps/web/out/_next/static/media/ef4d5661765d0e49-s.woff2 +0 -0
  157. package/apps/web/out/index.html +1 -0
  158. package/apps/web/out/index.txt +6 -0
  159. package/apps/web/out/settings.html +1 -0
  160. package/apps/web/out/settings.txt +6 -0
  161. package/apps/web/out/templates.html +1 -0
  162. package/apps/web/out/templates.txt +6 -0
  163. package/bin/symbion.mjs +41 -0
  164. package/node_modules/@symbion/core/dist/adapters/claude.d.ts +3 -0
  165. package/node_modules/@symbion/core/dist/adapters/claude.d.ts.map +1 -0
  166. package/node_modules/@symbion/core/dist/adapters/claude.js +43 -0
  167. package/node_modules/@symbion/core/dist/adapters/claude.js.map +1 -0
  168. package/node_modules/@symbion/core/dist/adapters/codex.d.ts +3 -0
  169. package/node_modules/@symbion/core/dist/adapters/codex.d.ts.map +1 -0
  170. package/node_modules/@symbion/core/dist/adapters/codex.js +58 -0
  171. package/node_modules/@symbion/core/dist/adapters/codex.js.map +1 -0
  172. package/node_modules/@symbion/core/dist/adapters/registry.d.ts +5 -0
  173. package/node_modules/@symbion/core/dist/adapters/registry.d.ts.map +1 -0
  174. package/node_modules/@symbion/core/dist/adapters/registry.js +14 -0
  175. package/node_modules/@symbion/core/dist/adapters/registry.js.map +1 -0
  176. package/node_modules/@symbion/core/dist/adapters/types.d.ts +34 -0
  177. package/node_modules/@symbion/core/dist/adapters/types.d.ts.map +1 -0
  178. package/node_modules/@symbion/core/dist/adapters/types.js +2 -0
  179. package/node_modules/@symbion/core/dist/adapters/types.js.map +1 -0
  180. package/node_modules/@symbion/core/dist/diff/conflict.d.ts +19 -0
  181. package/node_modules/@symbion/core/dist/diff/conflict.d.ts.map +1 -0
  182. package/node_modules/@symbion/core/dist/diff/conflict.js +20 -0
  183. package/node_modules/@symbion/core/dist/diff/conflict.js.map +1 -0
  184. package/node_modules/@symbion/core/dist/diff/diff.d.ts +44 -0
  185. package/node_modules/@symbion/core/dist/diff/diff.d.ts.map +1 -0
  186. package/node_modules/@symbion/core/dist/diff/diff.js +124 -0
  187. package/node_modules/@symbion/core/dist/diff/diff.js.map +1 -0
  188. package/node_modules/@symbion/core/dist/generate/bodyPrompt.d.ts +27 -0
  189. package/node_modules/@symbion/core/dist/generate/bodyPrompt.d.ts.map +1 -0
  190. package/node_modules/@symbion/core/dist/generate/bodyPrompt.js +55 -0
  191. package/node_modules/@symbion/core/dist/generate/bodyPrompt.js.map +1 -0
  192. package/node_modules/@symbion/core/dist/generate/description.d.ts +18 -0
  193. package/node_modules/@symbion/core/dist/generate/description.d.ts.map +1 -0
  194. package/node_modules/@symbion/core/dist/generate/description.js +164 -0
  195. package/node_modules/@symbion/core/dist/generate/description.js.map +1 -0
  196. package/node_modules/@symbion/core/dist/index.d.ts +23 -0
  197. package/node_modules/@symbion/core/dist/index.d.ts.map +1 -0
  198. package/node_modules/@symbion/core/dist/index.js +24 -0
  199. package/node_modules/@symbion/core/dist/index.js.map +1 -0
  200. package/node_modules/@symbion/core/dist/ir/refs.d.ts +11 -0
  201. package/node_modules/@symbion/core/dist/ir/refs.d.ts.map +1 -0
  202. package/node_modules/@symbion/core/dist/ir/refs.js +25 -0
  203. package/node_modules/@symbion/core/dist/ir/refs.js.map +1 -0
  204. package/node_modules/@symbion/core/dist/ir/types.d.ts +107 -0
  205. package/node_modules/@symbion/core/dist/ir/types.d.ts.map +1 -0
  206. package/node_modules/@symbion/core/dist/ir/types.js +19 -0
  207. package/node_modules/@symbion/core/dist/ir/types.js.map +1 -0
  208. package/node_modules/@symbion/core/dist/ir/validate.d.ts +13 -0
  209. package/node_modules/@symbion/core/dist/ir/validate.d.ts.map +1 -0
  210. package/node_modules/@symbion/core/dist/ir/validate.js +114 -0
  211. package/node_modules/@symbion/core/dist/ir/validate.js.map +1 -0
  212. package/node_modules/@symbion/core/dist/parse/scan.d.ts +47 -0
  213. package/node_modules/@symbion/core/dist/parse/scan.d.ts.map +1 -0
  214. package/node_modules/@symbion/core/dist/parse/scan.js +109 -0
  215. package/node_modules/@symbion/core/dist/parse/scan.js.map +1 -0
  216. package/node_modules/@symbion/core/dist/render/frontmatter.d.ts +29 -0
  217. package/node_modules/@symbion/core/dist/render/frontmatter.d.ts.map +1 -0
  218. package/node_modules/@symbion/core/dist/render/frontmatter.js +99 -0
  219. package/node_modules/@symbion/core/dist/render/frontmatter.js.map +1 -0
  220. package/node_modules/@symbion/core/dist/render/marker.d.ts +30 -0
  221. package/node_modules/@symbion/core/dist/render/marker.d.ts.map +1 -0
  222. package/node_modules/@symbion/core/dist/render/marker.js +48 -0
  223. package/node_modules/@symbion/core/dist/render/marker.js.map +1 -0
  224. package/node_modules/@symbion/core/dist/render/render.d.ts +12 -0
  225. package/node_modules/@symbion/core/dist/render/render.d.ts.map +1 -0
  226. package/node_modules/@symbion/core/dist/render/render.js +10 -0
  227. package/node_modules/@symbion/core/dist/render/render.js.map +1 -0
  228. package/node_modules/@symbion/core/dist/runcommand/render.d.ts +13 -0
  229. package/node_modules/@symbion/core/dist/runcommand/render.d.ts.map +1 -0
  230. package/node_modules/@symbion/core/dist/runcommand/render.js +19 -0
  231. package/node_modules/@symbion/core/dist/runcommand/render.js.map +1 -0
  232. package/node_modules/@symbion/core/dist/templates/authorSource.d.ts +55 -0
  233. package/node_modules/@symbion/core/dist/templates/authorSource.d.ts.map +1 -0
  234. package/node_modules/@symbion/core/dist/templates/authorSource.js +24 -0
  235. package/node_modules/@symbion/core/dist/templates/authorSource.js.map +1 -0
  236. package/node_modules/@symbion/core/dist/templates/matchAuthorFolders.d.ts +28 -0
  237. package/node_modules/@symbion/core/dist/templates/matchAuthorFolders.d.ts.map +1 -0
  238. package/node_modules/@symbion/core/dist/templates/matchAuthorFolders.js +54 -0
  239. package/node_modules/@symbion/core/dist/templates/matchAuthorFolders.js.map +1 -0
  240. package/node_modules/@symbion/core/dist/templates/parseTemplate.d.ts +42 -0
  241. package/node_modules/@symbion/core/dist/templates/parseTemplate.d.ts.map +1 -0
  242. package/node_modules/@symbion/core/dist/templates/parseTemplate.js +56 -0
  243. package/node_modules/@symbion/core/dist/templates/parseTemplate.js.map +1 -0
  244. package/node_modules/@symbion/core/dist/templates/templateListItem.d.ts +39 -0
  245. package/node_modules/@symbion/core/dist/templates/templateListItem.d.ts.map +1 -0
  246. package/node_modules/@symbion/core/dist/templates/templateListItem.js +2 -0
  247. package/node_modules/@symbion/core/dist/templates/templateListItem.js.map +1 -0
  248. package/node_modules/@symbion/core/dist/util/sha256.d.ts +9 -0
  249. package/node_modules/@symbion/core/dist/util/sha256.d.ts.map +1 -0
  250. package/node_modules/@symbion/core/dist/util/sha256.js +91 -0
  251. package/node_modules/@symbion/core/dist/util/sha256.js.map +1 -0
  252. package/node_modules/@symbion/core/dist/version/semver.d.ts +18 -0
  253. package/node_modules/@symbion/core/dist/version/semver.d.ts.map +1 -0
  254. package/node_modules/@symbion/core/dist/version/semver.js +53 -0
  255. package/node_modules/@symbion/core/dist/version/semver.js.map +1 -0
  256. package/node_modules/@symbion/core/package.json +14 -0
  257. package/node_modules/@symbion/rpc-types/dist/index.d.ts +444 -0
  258. package/node_modules/@symbion/rpc-types/dist/index.d.ts.map +1 -0
  259. package/node_modules/@symbion/rpc-types/dist/index.js +2 -0
  260. package/node_modules/@symbion/rpc-types/dist/index.js.map +1 -0
  261. package/node_modules/@symbion/rpc-types/package.json +11 -0
  262. package/node_modules/yaml/dist/cli.d.ts +8 -0
  263. package/node_modules/yaml/dist/cli.mjs +201 -0
  264. package/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
  265. package/node_modules/yaml/dist/compose/compose-collection.js +90 -0
  266. package/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
  267. package/node_modules/yaml/dist/compose/compose-doc.js +45 -0
  268. package/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
  269. package/node_modules/yaml/dist/compose/compose-node.js +112 -0
  270. package/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
  271. package/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
  272. package/node_modules/yaml/dist/compose/composer.d.ts +63 -0
  273. package/node_modules/yaml/dist/compose/composer.js +224 -0
  274. package/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  275. package/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
  276. package/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  277. package/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
  278. package/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  279. package/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
  280. package/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
  281. package/node_modules/yaml/dist/compose/resolve-end.js +39 -0
  282. package/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  283. package/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
  284. package/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  285. package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +227 -0
  286. package/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
  287. package/node_modules/yaml/dist/compose/resolve-props.js +148 -0
  288. package/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  289. package/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
  290. package/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  291. package/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
  292. package/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  293. package/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
  294. package/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
  295. package/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
  296. package/node_modules/yaml/dist/doc/Document.d.ts +141 -0
  297. package/node_modules/yaml/dist/doc/Document.js +337 -0
  298. package/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
  299. package/node_modules/yaml/dist/doc/anchors.js +76 -0
  300. package/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
  301. package/node_modules/yaml/dist/doc/applyReviver.js +57 -0
  302. package/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
  303. package/node_modules/yaml/dist/doc/createNode.js +90 -0
  304. package/node_modules/yaml/dist/doc/directives.d.ts +49 -0
  305. package/node_modules/yaml/dist/doc/directives.js +178 -0
  306. package/node_modules/yaml/dist/errors.d.ts +21 -0
  307. package/node_modules/yaml/dist/errors.js +62 -0
  308. package/node_modules/yaml/dist/index.d.ts +25 -0
  309. package/node_modules/yaml/dist/index.js +50 -0
  310. package/node_modules/yaml/dist/log.d.ts +3 -0
  311. package/node_modules/yaml/dist/log.js +19 -0
  312. package/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
  313. package/node_modules/yaml/dist/nodes/Alias.js +118 -0
  314. package/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
  315. package/node_modules/yaml/dist/nodes/Collection.js +151 -0
  316. package/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
  317. package/node_modules/yaml/dist/nodes/Node.js +40 -0
  318. package/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
  319. package/node_modules/yaml/dist/nodes/Pair.js +39 -0
  320. package/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
  321. package/node_modules/yaml/dist/nodes/Scalar.js +27 -0
  322. package/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  323. package/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
  324. package/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  325. package/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
  326. package/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  327. package/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
  328. package/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
  329. package/node_modules/yaml/dist/nodes/identity.js +53 -0
  330. package/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
  331. package/node_modules/yaml/dist/nodes/toJS.js +39 -0
  332. package/node_modules/yaml/dist/options.d.ts +350 -0
  333. package/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
  334. package/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
  335. package/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
  336. package/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
  337. package/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
  338. package/node_modules/yaml/dist/parse/cst-visit.js +99 -0
  339. package/node_modules/yaml/dist/parse/cst.d.ts +109 -0
  340. package/node_modules/yaml/dist/parse/cst.js +112 -0
  341. package/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
  342. package/node_modules/yaml/dist/parse/lexer.js +723 -0
  343. package/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
  344. package/node_modules/yaml/dist/parse/line-counter.js +41 -0
  345. package/node_modules/yaml/dist/parse/parser.d.ts +84 -0
  346. package/node_modules/yaml/dist/parse/parser.js +980 -0
  347. package/node_modules/yaml/dist/public-api.d.ts +44 -0
  348. package/node_modules/yaml/dist/public-api.js +107 -0
  349. package/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
  350. package/node_modules/yaml/dist/schema/Schema.js +39 -0
  351. package/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
  352. package/node_modules/yaml/dist/schema/common/map.js +19 -0
  353. package/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
  354. package/node_modules/yaml/dist/schema/common/null.js +17 -0
  355. package/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
  356. package/node_modules/yaml/dist/schema/common/seq.js +19 -0
  357. package/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
  358. package/node_modules/yaml/dist/schema/common/string.js +16 -0
  359. package/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
  360. package/node_modules/yaml/dist/schema/core/bool.js +21 -0
  361. package/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
  362. package/node_modules/yaml/dist/schema/core/float.js +47 -0
  363. package/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
  364. package/node_modules/yaml/dist/schema/core/int.js +42 -0
  365. package/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
  366. package/node_modules/yaml/dist/schema/core/schema.js +25 -0
  367. package/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
  368. package/node_modules/yaml/dist/schema/json/schema.js +64 -0
  369. package/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
  370. package/node_modules/yaml/dist/schema/tags.d.ts +48 -0
  371. package/node_modules/yaml/dist/schema/tags.js +99 -0
  372. package/node_modules/yaml/dist/schema/types.d.ts +92 -0
  373. package/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  374. package/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
  375. package/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  376. package/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  377. package/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  378. package/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
  379. package/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  380. package/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
  381. package/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
  382. package/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
  383. package/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
  384. package/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  385. package/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  386. package/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  387. package/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  388. package/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
  389. package/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  390. package/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
  391. package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  392. package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  393. package/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  394. package/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
  395. package/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
  396. package/node_modules/yaml/dist/stringify/stringify.js +132 -0
  397. package/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  398. package/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
  399. package/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  400. package/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
  401. package/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  402. package/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
  403. package/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  404. package/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
  405. package/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  406. package/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
  407. package/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
  408. package/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
  409. package/node_modules/yaml/dist/test-events.d.ts +4 -0
  410. package/node_modules/yaml/dist/test-events.js +134 -0
  411. package/node_modules/yaml/dist/util.d.ts +16 -0
  412. package/node_modules/yaml/dist/util.js +28 -0
  413. package/node_modules/yaml/dist/visit.d.ts +102 -0
  414. package/node_modules/yaml/dist/visit.js +236 -0
  415. package/node_modules/yaml/package.json +20 -0
  416. package/node_modules/yaml/util.js +2 -0
  417. package/package.json +39 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Quanghuy128
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # Symbion
2
+
3
+ **Visual builder for AI-coding autoworkflows.** Define slash-commands and subagents once through a web UI, then export/sync them into any target repo's `.claude/` folder (and `AGENTS.md` for Codex) — instead of hand-writing `.md` pipeline files for every new project.
4
+
5
+ ## What problem this solves
6
+
7
+ AI-coding pipelines (analyze → design → plan → build → review → ship) are usually authored as a pile of hand-written `.md` files (`.claude/agents/*.md`, `.claude/commands/*.md`, `settings.json`, hooks). Every new repo means copy-pasting and re-tweaking those files by hand, with easy-to-miss frontmatter mistakes.
8
+
9
+ Symbion lets you define a workflow **once** as a canonical model (IR), then compiles it to whatever provider format you need and writes it safely into a target repo.
10
+
11
+ ## MVP scope (v1)
12
+
13
+ - **Project management** — register a local repo path, manage multiple projects from a sidebar.
14
+ - **Workflow / Agent builder** — form-based editor (with a raw Markdown tab) for slash-commands and subagents, matching real Claude Code frontmatter (`name`, `description`, `tools`, etc.) plus custom fields.
15
+ - **Dependency graph** — read-only visualization of how commands/agents reference each other (not a drag-and-drop executor).
16
+ - **Export / Upsert ("Xuất bản")** — render the canonical model into provider-specific files and safely write/update them in the target repo:
17
+ - **Claude Code**: `.claude/agents/*.md` + `.claude/commands/*.md`
18
+ - **Codex**: `AGENTS.md`
19
+ - **Diff preview + conflict detection** — every publish renders → diffs against disk → asks for confirmation. Hand-edited "managed" files are detected via a marker/hash and never silently overwritten.
20
+ - **Import** — parse an existing `.claude/` folder into the model, so you don't start from a blank canvas.
21
+ - **Copy run command** — generates a structured prompt/CLI command to paste and run manually. Actual workflow *execution* is deferred to v2.
22
+
23
+ Out of scope for v1: running workflows automatically, multi-project shared libraries, providers beyond Claude/Codex (Copilot/Gemini are planned as future adapters with no IR changes needed).
24
+
25
+ See [docs/loops/symbion-analyze.md](docs/loops/symbion-analyze.md), [symbion-design.md](docs/loops/symbion-design.md), and [symbion-STATE.md](docs/loops/symbion-STATE.md) for the full locked spec, design, and architecture.
26
+
27
+ ## Architecture
28
+
29
+ ```
30
+ apps/web Next.js UI — project sidebar, builder forms, dependency graph, publish dialog
31
+ apps/daemon Node process — the ONLY thing that touches disk/git. Exposes localhost RPC
32
+ packages/core Pure TS — canonical IR, render/parse, diff, marker/hash, provider adapters
33
+ ```
34
+
35
+ - `packages/core` has no filesystem/network imports — it's the compiler (IR ↔ Claude/Codex format).
36
+ - `apps/daemon` binds to `127.0.0.1` only, owns all reads/writes/git access, and is the sole place where side effects happen.
37
+ - `apps/web` is presentation only; every effect goes through a typed RPC call to the daemon.
38
+
39
+ ## Requirements
40
+
41
+ - Node.js >= 18
42
+ - npm
43
+
44
+ ## Installation
45
+
46
+ Install Symbion globally to use it as a CLI tool from any directory:
47
+
48
+ ```bash
49
+ npm install -g @andrew.ng/symbion
50
+ ```
51
+
52
+ Or add it as a project dependency and run it via `npx`:
53
+
54
+ ```bash
55
+ npm install @andrew.ng/symbion
56
+ npx symbion
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ Once installed, run:
62
+
63
+ ```bash
64
+ symbion
65
+ ```
66
+
67
+ This starts the local Symbion daemon and opens an interactive menu:
68
+
69
+ ```
70
+ 1) Web UI 2) Hide to Tray 3) Exit
71
+ ```
72
+
73
+ - **Web UI** opens the Symbion web app in your default browser, served
74
+ locally by the daemon (nothing is sent to any external server — Symbion
75
+ runs entirely on `127.0.0.1`).
76
+ - **Hide to Tray** keeps the daemon running in the background so you can
77
+ keep using your terminal.
78
+ - **Exit** shuts the daemon down.
79
+
80
+ Other commands:
81
+
82
+ ```bash
83
+ symbion --version # print the installed version
84
+ symbion --help # show usage help
85
+ ```
86
+
87
+ ## Running from a clone (contributing / local development)
88
+
89
+ ```bash
90
+ npm install
91
+ npm start
92
+ ```
93
+
94
+ `npm start` builds and boots the daemon, which prints a terminal menu:
95
+
96
+ ```
97
+ ========================================
98
+ Choose Interface (v0.1.0)
99
+ Server: http://localhost:<port>
100
+ ========================================
101
+ Web UI (Open in Browser)
102
+ Exit
103
+ ```
104
+
105
+ Pick **Web UI** to open the app in your browser at the printed `localhost` URL.
106
+
107
+ ### Development
108
+
109
+ ```bash
110
+ npm run dev:daemon # daemon in watch mode
111
+ npm run dev:web # Next.js dev server
112
+ ```
113
+
114
+ ### Tests
115
+
116
+ ```bash
117
+ npm test # all unit tests (vitest)
118
+ npm run test:core # packages/core only
119
+ npm run test:daemon # apps/daemon only
120
+ npm run test:e2e # build + Playwright end-to-end
121
+ ```
122
+
123
+ ## License
124
+
125
+ [MIT](LICENSE)
@@ -0,0 +1,11 @@
1
+ export type BootChoice = "web" | "terminal" | "tray" | "exit";
2
+ /**
3
+ * showBootMenu — S0 terminal boot menu. Compact single-line menu (Web UI /
4
+ * Hide to Tray / Exit). The stubbed "Terminal UI (coming soon)" option is
5
+ * hidden from the printed menu and the input mapping (not deleted from the
6
+ * `BootChoice` type — see the type above) so re-enabling it in v1.5 is a
7
+ * one-line change: re-add the menu-line text and an `if (choice === "2")
8
+ * return resolve("terminal")`-shaped branch with a renumber.
9
+ */
10
+ export declare function showBootMenu(url: string): Promise<BootChoice>;
11
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/boot/menu.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAK9D;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBnE"}
@@ -0,0 +1,32 @@
1
+ import { createInterface } from "node:readline";
2
+ const MENU_LINE = " 1) Web UI 2) Hide to Tray 3) Exit";
3
+ const PROMPT = " Chọn (1-3): ";
4
+ /**
5
+ * showBootMenu — S0 terminal boot menu. Compact single-line menu (Web UI /
6
+ * Hide to Tray / Exit). The stubbed "Terminal UI (coming soon)" option is
7
+ * hidden from the printed menu and the input mapping (not deleted from the
8
+ * `BootChoice` type — see the type above) so re-enabling it in v1.5 is a
9
+ * one-line change: re-add the menu-line text and an `if (choice === "2")
10
+ * return resolve("terminal")`-shaped branch with a renumber.
11
+ */
12
+ export async function showBootMenu(url) {
13
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
14
+ const ask = () => new Promise((resolve) => {
15
+ console.log(MENU_LINE);
16
+ rl.question(PROMPT, (answer) => {
17
+ const choice = answer.trim();
18
+ if (choice === "1")
19
+ return resolve("web");
20
+ if (choice === "2")
21
+ return resolve("tray");
22
+ if (choice === "3")
23
+ return resolve("exit");
24
+ console.log(" Lựa chọn không hợp lệ, thử lại.\n");
25
+ ask().then(resolve);
26
+ });
27
+ });
28
+ const choice = await ask();
29
+ rl.close();
30
+ return choice;
31
+ }
32
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/boot/menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAIhD,MAAM,SAAS,GAAG,yCAAyC,CAAC;AAC5D,MAAM,MAAM,GAAG,gBAAgB,CAAC;AAEhC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7E,MAAM,GAAG,GAAG,GAAwB,EAAE,CACpC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACtB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvB,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3C,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;YACnD,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;IAE3B,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * folderPick — best-effort native OS folder dialog. v1 has no native dialog
3
+ * dependency wired in (no Electron/Tauri shell); the typed-path fallback in the
4
+ * web UI is always available regardless, per STATE §8 #11 ("native OS dialog via
5
+ * daemon, typed-path fallback always available"). This stub always reports
6
+ * `cancelled` so the web UI deterministically falls back to the typed-path input.
7
+ */
8
+ export interface BrowseFolderResult {
9
+ path?: string;
10
+ cancelled: boolean;
11
+ }
12
+ export declare function browseFolder(_startPath?: string): Promise<BrowseFolderResult>;
13
+ //# sourceMappingURL=folderPick.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folderPick.d.ts","sourceRoot":"","sources":["../../src/fs/folderPick.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAEnF"}
@@ -0,0 +1,4 @@
1
+ export async function browseFolder(_startPath) {
2
+ return { cancelled: true };
3
+ }
4
+ //# sourceMappingURL=folderPick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folderPick.js","sourceRoot":"","sources":["../../src/fs/folderPick.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAmB;IACpD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ListDirResult, MakeDirResult } from "../rpc/contract.js";
2
+ /**
3
+ * listDir — read-only directory PICKER listing (subdirectories only, never files).
4
+ * See STATE §1.1 for the full behavior contract.
5
+ */
6
+ export declare function listDir(inputPath?: unknown): ListDirResult;
7
+ /**
8
+ * makeDir — create-folder-if-missing (mkdir -p semantics). See STATE §1.2 /
9
+ * Edge Cases §3.4 for why no resolveConfinedPath/project-root confinement
10
+ * applies here: there is no project root yet to confine to.
11
+ */
12
+ export declare function makeDir(path: unknown): MakeDirResult;
13
+ //# sourceMappingURL=listDir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listDir.d.ts","sourceRoot":"","sources":["../../src/fs/listDir.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAgB,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAErF;;;GAGG;AACH,wBAAgB,OAAO,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,aAAa,CA6E1D;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAyBpD"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * listDir / makeDir — the "browse/prepare a not-yet-a-project directory" pair
3
+ * (docs/loops/create-project-folder-browser-STATE.md §1.1/§1.2). Both are plain
4
+ * Node fs logic; they live in apps/daemon (never packages/core, which stays
5
+ * fs-free) and are intentionally NOT in writeFiles.ts, which is the
6
+ * render→diff→write pipeline for *managed* .claude/AGENTS.md files inside an
7
+ * *already-registered* project. listDir/makeDir operate upstream of all of
8
+ * that, before any project root exists.
9
+ */
10
+ import { accessSync, constants, existsSync, mkdirSync, readdirSync, realpathSync, statSync, } from "node:fs";
11
+ import { homedir } from "node:os";
12
+ import { dirname, isAbsolute } from "node:path";
13
+ import { RpcError } from "../rpc/rpcError.js";
14
+ import { splitAnySeparator } from "../rpc/pathStyle.js";
15
+ /**
16
+ * listDir — read-only directory PICKER listing (subdirectories only, never files).
17
+ * See STATE §1.1 for the full behavior contract.
18
+ */
19
+ export function listDir(inputPath) {
20
+ if (inputPath !== undefined && typeof inputPath !== "string") {
21
+ throw new RpcError("invalid-params", "Đường dẫn phải là đường dẫn tuyệt đối.");
22
+ }
23
+ const target = inputPath ?? homedir();
24
+ if (!isAbsolute(target)) {
25
+ throw new RpcError("invalid-params", "Đường dẫn phải là đường dẫn tuyệt đối.");
26
+ }
27
+ let resolved;
28
+ try {
29
+ resolved = realpathSync(target);
30
+ }
31
+ catch {
32
+ throw new RpcError("invalid-path", "Đường dẫn không tồn tại hoặc không phải thư mục.");
33
+ }
34
+ let stat;
35
+ try {
36
+ stat = statSync(resolved);
37
+ }
38
+ catch {
39
+ throw new RpcError("invalid-path", "Đường dẫn không tồn tại hoặc không phải thư mục.");
40
+ }
41
+ if (!stat.isDirectory()) {
42
+ throw new RpcError("invalid-path", "Đường dẫn không tồn tại hoặc không phải thư mục.");
43
+ }
44
+ const parentCandidate = dirname(resolved);
45
+ const parentPath = parentCandidate === resolved ? undefined : parentCandidate;
46
+ try {
47
+ accessSync(resolved, constants.R_OK);
48
+ }
49
+ catch {
50
+ return { path: resolved, parentPath, entries: [], denied: true };
51
+ }
52
+ let dirents;
53
+ try {
54
+ dirents = readdirSync(resolved, { withFileTypes: true });
55
+ }
56
+ catch {
57
+ // readdir itself failed despite passing accessSync (e.g. a race, or an ACL
58
+ // accessSync doesn't fully model) — treat the same as a denied listing.
59
+ return { path: resolved, parentPath, entries: [], denied: true };
60
+ }
61
+ const entries = [];
62
+ for (const dirent of dirents) {
63
+ const entryPath = `${resolved === "/" ? "" : resolved}/${dirent.name}`;
64
+ if (dirent.isSymbolicLink()) {
65
+ // Only include a symlink if its resolved target is itself a directory.
66
+ // Broken symlinks and symlinks-to-files are excluded entirely.
67
+ try {
68
+ const targetStat = statSync(entryPath);
69
+ if (!targetStat.isDirectory())
70
+ continue;
71
+ entries.push({ name: dirent.name, path: entryPath, isDir: true, isSymlink: true, unreadable: false });
72
+ }
73
+ catch {
74
+ // broken symlink -> exclude entirely (not a directory).
75
+ continue;
76
+ }
77
+ continue;
78
+ }
79
+ if (!dirent.isDirectory())
80
+ continue; // files are never shown
81
+ try {
82
+ // Per-entry stat to tolerate a single ACL'd child without failing the call.
83
+ statSync(entryPath);
84
+ entries.push({ name: dirent.name, path: entryPath, isDir: true, isSymlink: false, unreadable: false });
85
+ }
86
+ catch {
87
+ entries.push({ name: dirent.name, path: entryPath, isDir: false, isSymlink: false, unreadable: true });
88
+ }
89
+ }
90
+ entries.sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: "base" }));
91
+ return { path: resolved, parentPath, entries, denied: false };
92
+ }
93
+ /**
94
+ * makeDir — create-folder-if-missing (mkdir -p semantics). See STATE §1.2 /
95
+ * Edge Cases §3.4 for why no resolveConfinedPath/project-root confinement
96
+ * applies here: there is no project root yet to confine to.
97
+ */
98
+ export function makeDir(path) {
99
+ if (typeof path !== "string" || path.length === 0 || !isAbsolute(path)) {
100
+ throw new RpcError("invalid-params", "Đường dẫn phải là đường dẫn tuyệt đối.");
101
+ }
102
+ const segments = splitAnySeparator(path);
103
+ if (segments.includes("..")) {
104
+ throw new RpcError("invalid-params", `Đường dẫn chứa ".." không được phép: ${path}`);
105
+ }
106
+ if (existsSync(path)) {
107
+ const stat = statSync(path);
108
+ if (stat.isDirectory()) {
109
+ return { path, created: false };
110
+ }
111
+ throw new RpcError("path-is-file", "Đường dẫn đã tồn tại nhưng không phải là thư mục.");
112
+ }
113
+ try {
114
+ mkdirSync(path, { recursive: true });
115
+ }
116
+ catch (err) {
117
+ throw new RpcError("mkdir-failed", `Không thể tạo thư mục: ${err.message}`);
118
+ }
119
+ return { path, created: true };
120
+ }
121
+ //# sourceMappingURL=listDir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listDir.js","sourceRoot":"","sources":["../../src/fs/listDir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface OnDiskFile {
2
+ relPath: string;
3
+ content?: string;
4
+ isMergedTarget?: boolean;
5
+ }
6
+ /**
7
+ * readTargetFiles — read the on-disk content of a fixed list of relPaths (the
8
+ * relPaths a render pass is about to manage), for diffing. Absent files come
9
+ * back with `content: undefined` (status "new" downstream). `mergedTargetRelPaths`
10
+ * flags relPaths belonging to merged/lossy targets (e.g. AGENTS.md) whose render
11
+ * already spliced in any pre-existing foreign content (STATE §3.3).
12
+ */
13
+ export declare function readTargetFiles(projectRoot: string, relPaths: string[], mergedTargetRelPaths?: Set<string>): OnDiskFile[];
14
+ /** Read all files under `.claude/agents`, `.claude/commands`, `.claude/hooks`, `.claude/settings.json` for scanClaudeDir. */
15
+ export declare function readClaudeDirFilemap(projectRoot: string): Record<string, string>;
16
+ /** Read the existing AGENTS.md content (for Codex foreign-content preservation), or undefined if absent. */
17
+ export declare function readAgentsMd(projectRoot: string): string | undefined;
18
+ /** Extract the foreign (non-managed-region) portion of an existing AGENTS.md, for splicing. */
19
+ export declare function extractForeignAgentsMdContent(content: string | undefined): string | undefined;
20
+ //# sourceMappingURL=readTargetFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readTargetFiles.d.ts","sourceRoot":"","sources":["../../src/fs/readTargetFiles.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,oBAAoB,GAAE,GAAG,CAAC,MAAM,CAAa,GAC5C,UAAU,EAAE,CAad;AAED,6HAA6H;AAC7H,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BhF;AAED,4GAA4G;AAC5G,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQpE;AAED,+FAA+F;AAC/F,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAK7F"}
@@ -0,0 +1,76 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { resolveConfinedPath } from "../rpc/guard.js";
3
+ /**
4
+ * readTargetFiles — read the on-disk content of a fixed list of relPaths (the
5
+ * relPaths a render pass is about to manage), for diffing. Absent files come
6
+ * back with `content: undefined` (status "new" downstream). `mergedTargetRelPaths`
7
+ * flags relPaths belonging to merged/lossy targets (e.g. AGENTS.md) whose render
8
+ * already spliced in any pre-existing foreign content (STATE §3.3).
9
+ */
10
+ export function readTargetFiles(projectRoot, relPaths, mergedTargetRelPaths = new Set()) {
11
+ return relPaths.map((relPath) => {
12
+ const isMergedTarget = mergedTargetRelPaths.has(relPath);
13
+ try {
14
+ const absPath = resolveConfinedPath(projectRoot, relPath);
15
+ if (!existsSync(absPath)) {
16
+ return { relPath, isMergedTarget };
17
+ }
18
+ return { relPath, content: readFileSync(absPath, "utf-8"), isMergedTarget };
19
+ }
20
+ catch {
21
+ return { relPath, isMergedTarget };
22
+ }
23
+ });
24
+ }
25
+ /** Read all files under `.claude/agents`, `.claude/commands`, `.claude/hooks`, `.claude/settings.json` for scanClaudeDir. */
26
+ export function readClaudeDirFilemap(projectRoot) {
27
+ const filemap = {};
28
+ const readDir = (relDir) => {
29
+ const absDir = resolveConfinedPath(projectRoot, relDir);
30
+ if (!existsSync(absDir))
31
+ return;
32
+ for (const entry of readdirSync(absDir)) {
33
+ const relPath = `${relDir}/${entry}`;
34
+ const absPath = resolveConfinedPath(projectRoot, relPath);
35
+ if (statSync(absPath).isFile()) {
36
+ filemap[relPath] = readFileSync(absPath, "utf-8");
37
+ }
38
+ }
39
+ };
40
+ readDir(".claude/agents");
41
+ readDir(".claude/commands");
42
+ readDir(".claude/hooks");
43
+ const settingsRel = ".claude/settings.json";
44
+ try {
45
+ const absSettings = resolveConfinedPath(projectRoot, settingsRel);
46
+ if (existsSync(absSettings)) {
47
+ filemap[settingsRel] = readFileSync(absSettings, "utf-8");
48
+ }
49
+ }
50
+ catch {
51
+ // ignore
52
+ }
53
+ return filemap;
54
+ }
55
+ /** Read the existing AGENTS.md content (for Codex foreign-content preservation), or undefined if absent. */
56
+ export function readAgentsMd(projectRoot) {
57
+ try {
58
+ const absPath = resolveConfinedPath(projectRoot, "AGENTS.md");
59
+ if (!existsSync(absPath))
60
+ return undefined;
61
+ return readFileSync(absPath, "utf-8");
62
+ }
63
+ catch {
64
+ return undefined;
65
+ }
66
+ }
67
+ /** Extract the foreign (non-managed-region) portion of an existing AGENTS.md, for splicing. */
68
+ export function extractForeignAgentsMdContent(content) {
69
+ if (!content)
70
+ return undefined;
71
+ const startIdx = content.indexOf("<!-- managed-by: symbion region-start");
72
+ if (startIdx === -1)
73
+ return content; // entire file is foreign (no prior managed region)
74
+ return content.slice(0, startIdx).trimEnd();
75
+ }
76
+ //# sourceMappingURL=readTargetFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readTargetFiles.js","sourceRoot":"","sources":["../../src/fs/readTargetFiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { BackupRecord, PublishResult, TargetId } from "@symbion/core";
2
+ export interface WriteFileTask {
3
+ target: TargetId;
4
+ relPath: string;
5
+ content: string;
6
+ artifactId?: string;
7
+ contentHash: string;
8
+ /** "overwrite" required when the diff classified this file as a conflict. */
9
+ resolution?: "overwrite" | "keep";
10
+ /** true if computeDiff found this file already byte-identical on disk (skip silently). */
11
+ isSame?: boolean;
12
+ /** true if computeDiff found this file in conflict and no explicit resolution given. */
13
+ isUnresolvedConflict?: boolean;
14
+ }
15
+ export interface WriteFilesOptions {
16
+ projectRoot: string;
17
+ version: string;
18
+ backupBeforeWrite: boolean;
19
+ }
20
+ export interface WriteFilesOutcome {
21
+ results: PublishResult[];
22
+ backupDir: string;
23
+ backupRecord: BackupRecord;
24
+ }
25
+ /**
26
+ * writeFiles — backup-before-write + atomic temp->rename, per STATE §3.5/§3.7.
27
+ * Each file is processed independently; a failure on one file does not abort the batch
28
+ * (partial-failure handling, E10). Conflicts without an explicit "overwrite" resolution
29
+ * are skipped (never silently clobbered, E1).
30
+ */
31
+ export declare function writeFiles(tasks: WriteFileTask[], opts: WriteFilesOptions): WriteFilesOutcome;
32
+ //# sourceMappingURL=writeFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeFiles.d.ts","sourceRoot":"","sources":["../../src/fs/writeFiles.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG3E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAClC,0FAA0F;IAC1F,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,CA2F7F"}
@@ -0,0 +1,93 @@
1
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { rejectTraversalSegments, resolveConfinedPath } from "../rpc/guard.js";
4
+ /**
5
+ * writeFiles — backup-before-write + atomic temp->rename, per STATE §3.5/§3.7.
6
+ * Each file is processed independently; a failure on one file does not abort the batch
7
+ * (partial-failure handling, E10). Conflicts without an explicit "overwrite" resolution
8
+ * are skipped (never silently clobbered, E1).
9
+ */
10
+ export function writeFiles(tasks, opts) {
11
+ const backupDirRel = join(".symbion", "backups", opts.version);
12
+ const backupDirAbs = resolveConfinedPath(opts.projectRoot, backupDirRel);
13
+ if (opts.backupBeforeWrite) {
14
+ mkdirSync(backupDirAbs, { recursive: true });
15
+ }
16
+ const results = [];
17
+ const backupFiles = [];
18
+ for (const task of tasks) {
19
+ try {
20
+ rejectTraversalSegments(task.relPath);
21
+ const absPath = resolveConfinedPath(opts.projectRoot, task.relPath);
22
+ if (task.isSame) {
23
+ results.push({
24
+ target: task.target,
25
+ relPath: task.relPath,
26
+ action: "skipped-same",
27
+ artifactId: task.artifactId,
28
+ contentHash: task.contentHash,
29
+ });
30
+ continue;
31
+ }
32
+ if (task.isUnresolvedConflict && task.resolution !== "overwrite") {
33
+ results.push({
34
+ target: task.target,
35
+ relPath: task.relPath,
36
+ action: "skipped-conflict",
37
+ artifactId: task.artifactId,
38
+ });
39
+ continue;
40
+ }
41
+ const existedBefore = existsSync(absPath);
42
+ if (opts.backupBeforeWrite) {
43
+ if (existedBefore) {
44
+ const backupRelPath = task.relPath;
45
+ const backupAbsPath = resolveConfinedPath(backupDirAbs, backupRelPath);
46
+ mkdirSync(dirname(backupAbsPath), { recursive: true });
47
+ writeFileSync(backupAbsPath, readFileSync(absPath));
48
+ backupFiles.push({ relPath: task.relPath, existedBefore: true, backupRelPath });
49
+ }
50
+ else {
51
+ backupFiles.push({ relPath: task.relPath, existedBefore: false, backupRelPath: task.relPath });
52
+ }
53
+ }
54
+ mkdirSync(dirname(absPath), { recursive: true });
55
+ // Atomic write: temp file in the same dir, then rename over the target.
56
+ const tempPath = `${absPath}.symbion-tmp-${process.pid}-${Date.now()}`;
57
+ writeFileSync(tempPath, task.content, "utf-8");
58
+ renameSync(tempPath, absPath);
59
+ results.push({
60
+ target: task.target,
61
+ relPath: task.relPath,
62
+ action: existedBefore ? "updated" : "created",
63
+ artifactId: task.artifactId,
64
+ contentHash: task.contentHash,
65
+ });
66
+ }
67
+ catch (err) {
68
+ results.push({
69
+ target: task.target,
70
+ relPath: task.relPath,
71
+ action: "error",
72
+ artifactId: task.artifactId,
73
+ error: err.message,
74
+ });
75
+ }
76
+ }
77
+ if (backupFiles.length > 0) {
78
+ mkdirSync(backupDirAbs, { recursive: true });
79
+ const manifest = {
80
+ version: opts.version,
81
+ timestamp: new Date().toISOString(),
82
+ files: backupFiles,
83
+ };
84
+ writeFileSync(join(backupDirAbs, "manifest.json"), JSON.stringify(manifest, null, 2));
85
+ return { results, backupDir: backupDirRel, backupRecord: manifest };
86
+ }
87
+ return {
88
+ results,
89
+ backupDir: backupDirRel,
90
+ backupRecord: { version: opts.version, timestamp: new Date().toISOString(), files: [] },
91
+ };
92
+ }
93
+ //# sourceMappingURL=writeFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeFiles.js","sourceRoot":"","sources":["../../src/fs/writeFiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface GitStatusResult {
2
+ isRepo: boolean;
3
+ clean: boolean;
4
+ changedFiles: string[];
5
+ }
6
+ /**
7
+ * gitStatus — read-only `git status --porcelain` (git is advisory in v1: status only,
8
+ * never commits/branches, per STATE §8 #4 / CLAUDE.md).
9
+ */
10
+ export declare function gitStatus(repoPath: string): GitStatusResult;
11
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/git/status.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAqB3D"}