studiograph 1.1.3 → 1.2.0-beta.10

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 (356) hide show
  1. package/README.md +2 -8
  2. package/dist/agent/orchestrator.d.ts +53 -0
  3. package/dist/agent/orchestrator.js +197 -12
  4. package/dist/agent/orchestrator.js.map +1 -1
  5. package/dist/agent/prompts/system.md +43 -11
  6. package/dist/agent/skill-loader.d.ts +48 -0
  7. package/dist/agent/skill-loader.js +166 -0
  8. package/dist/agent/skill-loader.js.map +1 -0
  9. package/dist/agent/skills/{bundled/enrich-entities.md → enrich-entities.md} +12 -0
  10. package/dist/agent/skills/entity-schema.md +502 -0
  11. package/dist/agent/skills/obsidian-source-setup.md +246 -0
  12. package/dist/agent/skills/sync-configuration.md +144 -0
  13. package/dist/agent/skills/sync-setup.md +84 -0
  14. package/dist/agent/tools/connector-tools.d.ts +37 -0
  15. package/dist/agent/tools/connector-tools.js +132 -0
  16. package/dist/agent/tools/connector-tools.js.map +1 -0
  17. package/dist/agent/tools/fs-tools.d.ts +39 -0
  18. package/dist/agent/tools/fs-tools.js +106 -0
  19. package/dist/agent/tools/fs-tools.js.map +1 -0
  20. package/dist/agent/tools/graph-tools.d.ts +33 -1
  21. package/dist/agent/tools/graph-tools.js +192 -44
  22. package/dist/agent/tools/graph-tools.js.map +1 -1
  23. package/dist/agent/tools/load-skill.d.ts +1 -1
  24. package/dist/agent/tools/load-skill.js +1 -1
  25. package/dist/agent/tools/load-skill.js.map +1 -1
  26. package/dist/agent/tools/ops-tools.d.ts +24 -0
  27. package/dist/agent/tools/ops-tools.js +542 -0
  28. package/dist/agent/tools/ops-tools.js.map +1 -0
  29. package/dist/agent/tools/sync-tools.d.ts +33 -0
  30. package/dist/agent/tools/sync-tools.js +947 -0
  31. package/dist/agent/tools/sync-tools.js.map +1 -0
  32. package/dist/auth/github.d.ts +11 -8
  33. package/dist/auth/github.js +56 -75
  34. package/dist/auth/github.js.map +1 -1
  35. package/dist/cli/colors.d.ts +54 -0
  36. package/dist/cli/colors.js +133 -0
  37. package/dist/cli/colors.js.map +1 -0
  38. package/dist/cli/commands/app.js +121 -18
  39. package/dist/cli/commands/app.js.map +1 -1
  40. package/dist/cli/commands/auth.d.ts +1 -1
  41. package/dist/cli/commands/auth.js +26 -10
  42. package/dist/cli/commands/auth.js.map +1 -1
  43. package/dist/cli/commands/clone.d.ts +9 -0
  44. package/dist/cli/commands/clone.js +167 -0
  45. package/dist/cli/commands/clone.js.map +1 -0
  46. package/dist/cli/commands/commit.d.ts +8 -0
  47. package/dist/cli/commands/commit.js +44 -0
  48. package/dist/cli/commands/commit.js.map +1 -0
  49. package/dist/cli/commands/connector.js +10 -2
  50. package/dist/cli/commands/connector.js.map +1 -1
  51. package/dist/cli/commands/deploy.d.ts +4 -6
  52. package/dist/cli/commands/deploy.js +292 -115
  53. package/dist/cli/commands/deploy.js.map +1 -1
  54. package/dist/cli/commands/enrich.d.ts +11 -0
  55. package/dist/cli/commands/enrich.js +135 -0
  56. package/dist/cli/commands/enrich.js.map +1 -0
  57. package/dist/cli/commands/graphrag.d.ts +12 -0
  58. package/dist/cli/commands/graphrag.js +122 -0
  59. package/dist/cli/commands/graphrag.js.map +1 -0
  60. package/dist/cli/commands/init.js +29 -196
  61. package/dist/cli/commands/init.js.map +1 -1
  62. package/dist/cli/commands/join.js +23 -3
  63. package/dist/cli/commands/join.js.map +1 -1
  64. package/dist/cli/commands/orphans.d.ts +8 -0
  65. package/dist/cli/commands/orphans.js +125 -0
  66. package/dist/cli/commands/orphans.js.map +1 -0
  67. package/dist/cli/commands/provision.js +11 -7
  68. package/dist/cli/commands/provision.js.map +1 -1
  69. package/dist/cli/commands/r2.js +8 -2
  70. package/dist/cli/commands/r2.js.map +1 -1
  71. package/dist/cli/commands/redeploy.d.ts +9 -0
  72. package/dist/cli/commands/redeploy.js +203 -0
  73. package/dist/cli/commands/redeploy.js.map +1 -0
  74. package/dist/cli/commands/reset.d.ts +12 -0
  75. package/dist/cli/commands/reset.js +137 -0
  76. package/dist/cli/commands/reset.js.map +1 -0
  77. package/dist/cli/commands/resolve.d.ts +8 -0
  78. package/dist/cli/commands/resolve.js +85 -0
  79. package/dist/cli/commands/resolve.js.map +1 -0
  80. package/dist/cli/commands/review.d.ts +19 -0
  81. package/dist/cli/commands/review.js +128 -0
  82. package/dist/cli/commands/review.js.map +1 -0
  83. package/dist/cli/commands/serve.js +55 -8
  84. package/dist/cli/commands/serve.js.map +1 -1
  85. package/dist/cli/commands/source.d.ts +16 -0
  86. package/dist/cli/commands/source.js +159 -0
  87. package/dist/cli/commands/source.js.map +1 -0
  88. package/dist/cli/commands/start.js +307 -55
  89. package/dist/cli/commands/start.js.map +1 -1
  90. package/dist/cli/commands/sync-entities.d.ts +13 -0
  91. package/dist/cli/commands/sync-entities.js +242 -0
  92. package/dist/cli/commands/sync-entities.js.map +1 -0
  93. package/dist/cli/commands/sync.js +81 -5
  94. package/dist/cli/commands/sync.js.map +1 -1
  95. package/dist/cli/index.js +45 -9
  96. package/dist/cli/index.js.map +1 -1
  97. package/dist/cli/scaffolding.d.ts +2 -1
  98. package/dist/cli/scaffolding.js +38 -23
  99. package/dist/cli/scaffolding.js.map +1 -1
  100. package/dist/cli/setup-wizard.d.ts +30 -0
  101. package/dist/cli/setup-wizard.js +244 -0
  102. package/dist/cli/setup-wizard.js.map +1 -0
  103. package/dist/cli/sync-review-interactive.d.ts +31 -0
  104. package/dist/cli/sync-review-interactive.js +393 -0
  105. package/dist/cli/sync-review-interactive.js.map +1 -0
  106. package/dist/cli/theme.d.ts +31 -0
  107. package/dist/cli/theme.js +116 -0
  108. package/dist/cli/theme.js.map +1 -0
  109. package/dist/core/graph.d.ts +40 -12
  110. package/dist/core/graph.js +344 -104
  111. package/dist/core/graph.js.map +1 -1
  112. package/dist/core/migration-runner.d.ts +4 -1
  113. package/dist/core/migration-runner.js +14 -3
  114. package/dist/core/migration-runner.js.map +1 -1
  115. package/dist/core/types.d.ts +2 -4
  116. package/dist/core/types.js +1 -2
  117. package/dist/core/types.js.map +1 -1
  118. package/dist/core/user-config.d.ts +12 -0
  119. package/dist/core/user-config.js.map +1 -1
  120. package/dist/core/workspace-manager.d.ts +6 -1
  121. package/dist/core/workspace-manager.js +29 -4
  122. package/dist/core/workspace-manager.js.map +1 -1
  123. package/dist/core/workspace.d.ts +13 -5
  124. package/dist/core/workspace.js +115 -33
  125. package/dist/core/workspace.js.map +1 -1
  126. package/dist/lib/lib/utils.d.ts +2 -0
  127. package/dist/lib/lib/utils.js +6 -0
  128. package/dist/lib/lib/utils.js.map +1 -0
  129. package/dist/mcp/connector-manager.d.ts +7 -3
  130. package/dist/mcp/connector-manager.js +61 -16
  131. package/dist/mcp/connector-manager.js.map +1 -1
  132. package/dist/mcp/connectors/asana.d.ts +2 -0
  133. package/dist/mcp/connectors/asana.js +20 -0
  134. package/dist/mcp/connectors/asana.js.map +1 -0
  135. package/dist/mcp/connectors/definitions.d.ts +3 -1
  136. package/dist/mcp/connectors/definitions.js +19 -127
  137. package/dist/mcp/connectors/definitions.js.map +1 -1
  138. package/dist/mcp/connectors/figma.d.ts +5 -0
  139. package/dist/mcp/connectors/figma.js +21 -0
  140. package/dist/mcp/connectors/figma.js.map +1 -0
  141. package/dist/mcp/connectors/gdrive.d.ts +2 -0
  142. package/dist/mcp/connectors/gdrive.js +20 -0
  143. package/dist/mcp/connectors/gdrive.js.map +1 -0
  144. package/dist/mcp/connectors/granola.d.ts +2 -0
  145. package/dist/mcp/connectors/granola.js +12 -0
  146. package/dist/mcp/connectors/granola.js.map +1 -0
  147. package/dist/mcp/connectors/linear.d.ts +2 -0
  148. package/dist/mcp/connectors/linear.js +19 -0
  149. package/dist/mcp/connectors/linear.js.map +1 -0
  150. package/dist/mcp/connectors/obsidian.d.ts +2 -0
  151. package/dist/mcp/connectors/obsidian.js +19 -0
  152. package/dist/mcp/connectors/obsidian.js.map +1 -0
  153. package/dist/mcp/connectors/pipedrive.d.ts +2 -0
  154. package/dist/mcp/connectors/pipedrive.js +20 -0
  155. package/dist/mcp/connectors/pipedrive.js.map +1 -0
  156. package/dist/mcp/connectors/slack.d.ts +2 -0
  157. package/dist/mcp/connectors/slack.js +21 -0
  158. package/dist/mcp/connectors/slack.js.map +1 -0
  159. package/dist/mcp/oauth-provider.d.ts +41 -0
  160. package/dist/mcp/oauth-provider.js +160 -0
  161. package/dist/mcp/oauth-provider.js.map +1 -0
  162. package/dist/server/index.js +97 -11
  163. package/dist/server/index.js.map +1 -1
  164. package/dist/server/plugin-loader.d.ts +8 -0
  165. package/dist/server/plugin-loader.js +54 -2
  166. package/dist/server/plugin-loader.js.map +1 -1
  167. package/dist/server/routes/chat.d.ts +3 -2
  168. package/dist/server/routes/chat.js +67 -16
  169. package/dist/server/routes/chat.js.map +1 -1
  170. package/dist/server/routes/git-api.d.ts +9 -0
  171. package/dist/server/routes/git-api.js +82 -0
  172. package/dist/server/routes/git-api.js.map +1 -0
  173. package/dist/server/routes/graph-api.d.ts +2 -2
  174. package/dist/server/routes/graph-api.js +164 -3
  175. package/dist/server/routes/graph-api.js.map +1 -1
  176. package/dist/server/routes/workspace-api.d.ts +9 -0
  177. package/dist/server/routes/workspace-api.js +170 -0
  178. package/dist/server/routes/workspace-api.js.map +1 -0
  179. package/dist/services/assets/base.d.ts +2 -2
  180. package/dist/services/assets/base.js +4 -4
  181. package/dist/services/assets/base.js.map +1 -1
  182. package/dist/services/assets/index.d.ts +6 -6
  183. package/dist/services/assets/index.js +12 -12
  184. package/dist/services/assets/index.js.map +1 -1
  185. package/dist/services/git.d.ts +31 -0
  186. package/dist/services/git.js +92 -3
  187. package/dist/services/git.js.map +1 -1
  188. package/dist/services/github-provisioner.d.ts +8 -3
  189. package/dist/services/github-provisioner.js +35 -8
  190. package/dist/services/github-provisioner.js.map +1 -1
  191. package/dist/services/lint-service.js +8 -1
  192. package/dist/services/lint-service.js.map +1 -1
  193. package/dist/services/markdown.js +3 -3
  194. package/dist/services/markdown.js.map +1 -1
  195. package/dist/services/memory-service.d.ts +1 -1
  196. package/dist/services/memory-service.js +2 -3
  197. package/dist/services/memory-service.js.map +1 -1
  198. package/dist/services/orphan-service.d.ts +31 -0
  199. package/dist/services/orphan-service.js +100 -0
  200. package/dist/services/orphan-service.js.map +1 -0
  201. package/dist/services/sync/commit.d.ts +60 -0
  202. package/dist/services/sync/commit.js +370 -0
  203. package/dist/services/sync/commit.js.map +1 -0
  204. package/dist/services/sync/context-index.d.ts +69 -0
  205. package/dist/services/sync/context-index.js +280 -0
  206. package/dist/services/sync/context-index.js.map +1 -0
  207. package/dist/services/sync/derive.d.ts +34 -0
  208. package/dist/services/sync/derive.js +164 -0
  209. package/dist/services/sync/derive.js.map +1 -0
  210. package/dist/services/sync/enrichment-state.d.ts +31 -0
  211. package/dist/services/sync/enrichment-state.js +63 -0
  212. package/dist/services/sync/enrichment-state.js.map +1 -0
  213. package/dist/services/sync/enrichment.d.ts +25 -0
  214. package/dist/services/sync/enrichment.js +121 -0
  215. package/dist/services/sync/enrichment.js.map +1 -0
  216. package/dist/services/sync/frontmatter-extractor.d.ts +40 -0
  217. package/dist/services/sync/frontmatter-extractor.js +273 -0
  218. package/dist/services/sync/frontmatter-extractor.js.map +1 -0
  219. package/dist/services/sync/graph-match-state.d.ts +33 -0
  220. package/dist/services/sync/graph-match-state.js +61 -0
  221. package/dist/services/sync/graph-match-state.js.map +1 -0
  222. package/dist/services/sync/graph-match.d.ts +53 -0
  223. package/dist/services/sync/graph-match.js +316 -0
  224. package/dist/services/sync/graph-match.js.map +1 -0
  225. package/dist/services/sync/graphrag-client.d.ts +43 -0
  226. package/dist/services/sync/graphrag-client.js +94 -0
  227. package/dist/services/sync/graphrag-client.js.map +1 -0
  228. package/dist/services/sync/graphrag-config.d.ts +16 -0
  229. package/dist/services/sync/graphrag-config.js +39 -0
  230. package/dist/services/sync/graphrag-config.js.map +1 -0
  231. package/dist/services/sync/graphrag-context.d.ts +14 -0
  232. package/dist/services/sync/graphrag-context.js +109 -0
  233. package/dist/services/sync/graphrag-context.js.map +1 -0
  234. package/dist/services/sync/graphrag-indexer.d.ts +30 -0
  235. package/dist/services/sync/graphrag-indexer.js +358 -0
  236. package/dist/services/sync/graphrag-indexer.js.map +1 -0
  237. package/dist/services/sync/llm.d.ts +32 -0
  238. package/dist/services/sync/llm.js +115 -0
  239. package/dist/services/sync/llm.js.map +1 -0
  240. package/dist/services/sync/mcp-client.d.ts +59 -0
  241. package/dist/services/sync/mcp-client.js +285 -0
  242. package/dist/services/sync/mcp-client.js.map +1 -0
  243. package/dist/services/sync/model-factory.d.ts +10 -0
  244. package/dist/services/sync/model-factory.js +24 -0
  245. package/dist/services/sync/model-factory.js.map +1 -0
  246. package/dist/services/sync/name-quality.d.ts +31 -0
  247. package/dist/services/sync/name-quality.js +60 -0
  248. package/dist/services/sync/name-quality.js.map +1 -0
  249. package/dist/services/sync/output-schemas.d.ts +92 -0
  250. package/dist/services/sync/output-schemas.js +43 -0
  251. package/dist/services/sync/output-schemas.js.map +1 -0
  252. package/dist/services/sync/prompts.d.ts +19 -0
  253. package/dist/services/sync/prompts.js +128 -0
  254. package/dist/services/sync/prompts.js.map +1 -0
  255. package/dist/services/sync/reconciler.d.ts +48 -0
  256. package/dist/services/sync/reconciler.js +295 -0
  257. package/dist/services/sync/reconciler.js.map +1 -0
  258. package/dist/services/sync/source-config.d.ts +45 -0
  259. package/dist/services/sync/source-config.js +208 -0
  260. package/dist/services/sync/source-config.js.map +1 -0
  261. package/dist/services/sync/source-definitions/asana.d.ts +15 -0
  262. package/dist/services/sync/source-definitions/asana.js +48 -0
  263. package/dist/services/sync/source-definitions/asana.js.map +1 -0
  264. package/dist/services/sync/source-definitions/definitions.d.ts +21 -0
  265. package/dist/services/sync/source-definitions/definitions.js +26 -0
  266. package/dist/services/sync/source-definitions/definitions.js.map +1 -0
  267. package/dist/services/sync/source-definitions/gdrive.d.ts +16 -0
  268. package/dist/services/sync/source-definitions/gdrive.js +68 -0
  269. package/dist/services/sync/source-definitions/gdrive.js.map +1 -0
  270. package/dist/services/sync/source-definitions/granola.d.ts +2 -0
  271. package/dist/services/sync/source-definitions/granola.js +28 -0
  272. package/dist/services/sync/source-definitions/granola.js.map +1 -0
  273. package/dist/services/sync/source-definitions/linear.d.ts +2 -0
  274. package/dist/services/sync/source-definitions/linear.js +60 -0
  275. package/dist/services/sync/source-definitions/linear.js.map +1 -0
  276. package/dist/services/sync/source-definitions/obsidian.d.ts +2 -0
  277. package/dist/services/sync/source-definitions/obsidian.js +55 -0
  278. package/dist/services/sync/source-definitions/obsidian.js.map +1 -0
  279. package/dist/services/sync/source-definitions/pipedrive.d.ts +2 -0
  280. package/dist/services/sync/source-definitions/pipedrive.js +52 -0
  281. package/dist/services/sync/source-definitions/pipedrive.js.map +1 -0
  282. package/dist/services/sync/staging.d.ts +53 -0
  283. package/dist/services/sync/staging.js +131 -0
  284. package/dist/services/sync/staging.js.map +1 -0
  285. package/dist/services/sync/structured-extractor.d.ts +49 -0
  286. package/dist/services/sync/structured-extractor.js +344 -0
  287. package/dist/services/sync/structured-extractor.js.map +1 -0
  288. package/dist/services/sync/sync-runner.d.ts +32 -0
  289. package/dist/services/sync/sync-runner.js +195 -0
  290. package/dist/services/sync/sync-runner.js.map +1 -0
  291. package/dist/services/sync/sync-state.d.ts +43 -0
  292. package/dist/services/sync/sync-state.js +154 -0
  293. package/dist/services/sync/sync-state.js.map +1 -0
  294. package/dist/services/sync/types.d.ts +203 -0
  295. package/dist/services/sync/types.js +8 -0
  296. package/dist/services/sync/types.js.map +1 -0
  297. package/dist/services/sync/unstructured-extractor.d.ts +29 -0
  298. package/dist/services/sync/unstructured-extractor.js +197 -0
  299. package/dist/services/sync/unstructured-extractor.js.map +1 -0
  300. package/dist/services/vector-service.d.ts +11 -0
  301. package/dist/services/vector-service.js +42 -0
  302. package/dist/services/vector-service.js.map +1 -1
  303. package/dist/utils/git.d.ts +31 -4
  304. package/dist/utils/git.js +65 -7
  305. package/dist/utils/git.js.map +1 -1
  306. package/dist/utils/merge-resolver.d.ts +60 -0
  307. package/dist/utils/merge-resolver.js +304 -0
  308. package/dist/utils/merge-resolver.js.map +1 -0
  309. package/dist/utils/preflight.d.ts +2 -1
  310. package/dist/utils/preflight.js +8 -1
  311. package/dist/utils/preflight.js.map +1 -1
  312. package/dist/utils/workspace-config.d.ts +8 -0
  313. package/dist/utils/workspace-config.js +22 -0
  314. package/dist/utils/workspace-config.js.map +1 -0
  315. package/dist/web/_app/env.js +1 -0
  316. package/dist/web/_app/immutable/assets/0.BwJV4fvl.css +1 -0
  317. package/dist/web/_app/immutable/assets/2.DRHi7ABa.css +1 -0
  318. package/dist/web/_app/immutable/assets/3.CnAQdPKU.css +1 -0
  319. package/dist/web/_app/immutable/assets/4.BG92MufE.css +1 -0
  320. package/dist/web/_app/immutable/assets/5.CfrQIPYs.css +1 -0
  321. package/dist/web/_app/immutable/assets/ChatPanel.BNzaCFTL.css +1 -0
  322. package/dist/web/_app/immutable/assets/editor.D6Rjo7RE.css +1 -0
  323. package/dist/web/_app/immutable/chunks/4QY4j-jX.js +1 -0
  324. package/dist/web/_app/immutable/chunks/B4G4uWkV.js +1 -0
  325. package/dist/web/_app/immutable/chunks/BB_5th5W.js +3383 -0
  326. package/dist/web/_app/immutable/chunks/CUzqHQY_.js +1 -0
  327. package/dist/web/_app/immutable/chunks/CYrVHOHA.js +1 -0
  328. package/dist/web/_app/immutable/chunks/CksE5s8n.js +1 -0
  329. package/dist/web/_app/immutable/chunks/CqkleIqs.js +1 -0
  330. package/dist/web/_app/immutable/chunks/D0JBkEPE.js +86 -0
  331. package/dist/web/_app/immutable/chunks/D2K5GzLj.js +1 -0
  332. package/dist/web/_app/immutable/chunks/DEkoussQ.js +2 -0
  333. package/dist/web/_app/immutable/chunks/DW-KmHRi.js +1 -0
  334. package/dist/web/_app/immutable/chunks/DcCr4z9k.js +1 -0
  335. package/dist/web/_app/immutable/chunks/Dg2wWwJu.js +2 -0
  336. package/dist/web/_app/immutable/chunks/Dh_H7Owr.js +18 -0
  337. package/dist/web/_app/immutable/chunks/DnlgZ_Tk.js +5 -0
  338. package/dist/web/_app/immutable/chunks/DtVH--hH.js +6 -0
  339. package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +1 -0
  340. package/dist/web/_app/immutable/chunks/SBEriEQR.js +1 -0
  341. package/dist/web/_app/immutable/chunks/WSUKABI_.js +1 -0
  342. package/dist/web/_app/immutable/chunks/YTERt3Ul.js +6 -0
  343. package/dist/web/_app/immutable/chunks/m_R7HatS.js +1 -0
  344. package/dist/web/_app/immutable/chunks/vlmEnjfO.js +1 -0
  345. package/dist/web/_app/immutable/entry/app.B9pwpU_x.js +2 -0
  346. package/dist/web/_app/immutable/entry/start.CDuNCEco.js +1 -0
  347. package/dist/web/_app/immutable/nodes/0.YEQhw1us.js +1 -0
  348. package/dist/web/_app/immutable/nodes/1.CvmHhpRy.js +1 -0
  349. package/dist/web/_app/immutable/nodes/2.c5k1r7dq.js +1 -0
  350. package/dist/web/_app/immutable/nodes/3.B24tcdLK.js +1 -0
  351. package/dist/web/_app/immutable/nodes/4.kX2m5Pp9.js +16 -0
  352. package/dist/web/_app/immutable/nodes/5.DELt6wTD.js +2 -0
  353. package/dist/web/_app/version.json +1 -0
  354. package/dist/web/index.html +41 -0
  355. package/package.json +21 -7
  356. /package/dist/agent/skills/{bundled/gather-context.md → gather-context.md} +0 -0
@@ -9,11 +9,15 @@
9
9
  */
10
10
  import Fastify from 'fastify';
11
11
  import cors from '@fastify/cors';
12
+ import { existsSync, readFileSync, createReadStream, statSync } from 'fs';
13
+ import { join, extname } from 'path';
12
14
  import { AgentOrchestrator } from '../agent/orchestrator.js';
13
- import { PluginLoader } from './plugin-loader.js';
15
+ import { PluginLoader, MIME_TYPES } from './plugin-loader.js';
14
16
  import { registerGraphApiRoutes } from './routes/graph-api.js';
15
17
  import { registerChatRoutes } from './routes/chat.js';
16
18
  import { registerWebhookRoutes } from './routes/webhook.js';
19
+ import { registerWorkspaceApiRoutes } from './routes/workspace-api.js';
20
+ import { MemoryService } from '../services/memory-service.js';
17
21
  /**
18
22
  * Auth middleware — validates Authorization: Bearer <key> header.
19
23
  * Applied to all write-adjacent or sensitive routes.
@@ -49,12 +53,17 @@ export async function createServer(config) {
49
53
  const authHook = requireApiKey(config.apiKeys);
50
54
  fastify.addHook('preHandler', async (req, reply) => {
51
55
  const protectedPaths = ['/api/chat', '/webhooks/'];
52
- if (protectedPaths.some(p => req.url.startsWith(p))) {
56
+ const protectedPostPaths = ['/api/commit', '/api/push', '/api/pull', '/api/revert'];
57
+ const isWriteRoute = req.method === 'PUT' && req.url.startsWith('/api/repos/');
58
+ const isProtectedPost = req.method === 'POST' && protectedPostPaths.some(p => req.url.startsWith(p));
59
+ if (isWriteRoute || isProtectedPost || protectedPaths.some(p => req.url.startsWith(p))) {
53
60
  await authHook(req, reply);
54
61
  }
55
62
  });
56
63
  // Register graph API routes (unauthenticated read-only)
57
64
  await registerGraphApiRoutes(fastify, config.workspaceManager);
65
+ // Register workspace API routes (git operations)
66
+ await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser);
58
67
  // Discover installed apps and collect their skill/tool dirs
59
68
  const loader = new PluginLoader();
60
69
  const manifests = loader.loadApps(config.appsDir);
@@ -68,17 +77,49 @@ export async function createServer(config) {
68
77
  if (toolsDir)
69
78
  appToolsDirs.push(toolsDir);
70
79
  }
71
- // Initialize agent — skills/tools dirs are resolved before agent starts
72
- const agent = new AgentOrchestrator({
73
- workspacePath: config.workspacePath,
74
- workspaceConfig: config.workspaceConfig,
75
- gitUser: config.gitUser,
76
- skillsDirs: appSkillsDirs,
77
- toolsDirs: appToolsDirs,
78
- });
79
- await registerChatRoutes(fastify, agent);
80
+ // Initialize memory service and agent — non-fatal so the server can still serve graph API and apps
81
+ const memoryService = new MemoryService();
82
+ try {
83
+ const recentMemory = memoryService.loadRecentMemory();
84
+ const agent = new AgentOrchestrator({
85
+ workspacePath: config.workspacePath,
86
+ workspaceConfig: config.workspaceConfig,
87
+ gitUser: config.gitUser,
88
+ skillsDirs: appSkillsDirs,
89
+ toolsDirs: appToolsDirs,
90
+ recentMemory,
91
+ });
92
+ await registerChatRoutes(fastify, agent, memoryService);
93
+ }
94
+ catch (err) {
95
+ fastify.log.warn(`Agent not available: ${err.message ?? err} — chat routes disabled`);
96
+ }
80
97
  // GitHub webhook route
81
98
  await registerWebhookRoutes(fastify, config.workspaceManager, config.webhookSecret);
99
+ // GET /api/apps — list installed app manifests with resolved entity type names
100
+ const resolvedApps = manifests.map(m => {
101
+ let entityTypes = [];
102
+ try {
103
+ const etPath = join(config.appsDir, m.name, m.entityTypes);
104
+ if (existsSync(etPath)) {
105
+ const raw = JSON.parse(readFileSync(etPath, 'utf-8'));
106
+ if (Array.isArray(raw)) {
107
+ entityTypes = raw.map((item) => item.name).filter(Boolean);
108
+ }
109
+ }
110
+ }
111
+ catch {
112
+ // gracefully degrade — return empty array
113
+ }
114
+ return { name: m.name, version: m.version, description: m.description, mountPath: m.mountPath, entityTypes };
115
+ });
116
+ fastify.get('/api/apps', async (_req, reply) => {
117
+ return reply.send(resolvedApps);
118
+ });
119
+ // GET /api/workspace — workspace metadata (name, etc.)
120
+ fastify.get('/api/workspace', async (_req, reply) => {
121
+ return reply.send({ name: config.workspaceConfig.team_name });
122
+ });
82
123
  // Mount app plugins
83
124
  for (const manifest of manifests) {
84
125
  try {
@@ -92,6 +133,51 @@ export async function createServer(config) {
92
133
  fastify.log.error(err, `Failed to mount app "${manifest.name}"`);
93
134
  }
94
135
  }
136
+ // Serve web UI static files from dist/web/ with SPA fallback
137
+ const webDir = join(import.meta.dirname, '..', 'web');
138
+ if (existsSync(webDir)) {
139
+ const indexPath = join(webDir, 'index.html');
140
+ // SPA fallback for app routes: if an app plugin returns a JSON error for a
141
+ // browser GET request, serve the SPA instead. This happens when the browser
142
+ // refreshes a URL like /documents/document/doc-123 — the app's greedy route
143
+ // catches it but fails because the params don't match its expectations.
144
+ const indexHtml = readFileSync(indexPath);
145
+ fastify.addHook('onSend', async (request, reply, payload) => {
146
+ const ct = reply.getHeader('content-type');
147
+ if (request.method === 'GET' &&
148
+ reply.statusCode >= 400 &&
149
+ request.headers.accept?.includes('text/html') &&
150
+ typeof ct === 'string' && ct.includes('application/json')) {
151
+ reply.removeHeader('content-length');
152
+ reply.code(200).type('text/html');
153
+ return indexHtml;
154
+ }
155
+ return payload;
156
+ });
157
+ // Use setNotFoundHandler so app plugins and API routes take priority
158
+ fastify.setNotFoundHandler(async (req, reply) => {
159
+ const urlPath = req.url.split('?')[0];
160
+ const filePath = urlPath === '/' ? '/index.html' : urlPath;
161
+ const fullPath = join(webDir, filePath);
162
+ // Serve the file if it exists (and is a file, not directory)
163
+ if (existsSync(fullPath) && statSync(fullPath).isFile()) {
164
+ if (fullPath.includes('..')) {
165
+ return reply.status(400).send({ error: 'Invalid path' });
166
+ }
167
+ const ext = extname(fullPath).toLowerCase();
168
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
169
+ reply.type(contentType);
170
+ return reply.send(createReadStream(fullPath));
171
+ }
172
+ // SPA fallback — serve index.html for client-side routing
173
+ if (existsSync(indexPath)) {
174
+ reply.type('text/html');
175
+ return reply.send(createReadStream(indexPath));
176
+ }
177
+ return reply.status(404).send({ error: 'Not found' });
178
+ });
179
+ fastify.log.info('Web UI enabled — serving from dist/web/');
180
+ }
95
181
  return fastify;
96
182
  }
97
183
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,12 @@
3
3
  *
4
4
  * Scans .studiograph/apps/ for installed apps, parses their manifests,
5
5
  * and mounts their Fastify plugins under the declared mountPath.
6
+ * Also serves static assets from each app's static/ directory.
6
7
  */
7
8
  import type { FastifyInstance } from 'fastify';
8
9
  import { WorkspaceManager } from '../core/workspace-manager.js';
9
10
  import { GitUser } from '../services/git.js';
11
+ export declare const MIME_TYPES: Record<string, string>;
10
12
  export interface AppManifest {
11
13
  name: string;
12
14
  version: string;
@@ -29,8 +31,14 @@ export declare class PluginLoader {
29
31
  * Return the tools directory for a given app, if it exists.
30
32
  */
31
33
  getToolsDir(appsDir: string, manifest: AppManifest): string | null;
34
+ /**
35
+ * Return the static assets directory for a given app, if it exists.
36
+ */
37
+ getStaticDir(appsDir: string, manifest: AppManifest): string | null;
32
38
  /**
33
39
  * Dynamically import and register a plugin under its mountPath.
40
+ * Also mounts a static file handler at {mountPath}/static/* if the
41
+ * app has a static/ directory.
34
42
  */
35
43
  mountPlugin(fastify: FastifyInstance, manifest: AppManifest, appDir: string, opts: {
36
44
  workspaceManager: WorkspaceManager;
@@ -3,9 +3,31 @@
3
3
  *
4
4
  * Scans .studiograph/apps/ for installed apps, parses their manifests,
5
5
  * and mounts their Fastify plugins under the declared mountPath.
6
+ * Also serves static assets from each app's static/ directory.
6
7
  */
7
- import { existsSync, readdirSync, readFileSync } from 'fs';
8
- import { join } from 'path';
8
+ import { existsSync, readdirSync, readFileSync, createReadStream } from 'fs';
9
+ import { join, extname } from 'path';
10
+ export const MIME_TYPES = {
11
+ '.html': 'text/html',
12
+ '.css': 'text/css',
13
+ '.js': 'application/javascript',
14
+ '.mjs': 'application/javascript',
15
+ '.json': 'application/json',
16
+ '.png': 'image/png',
17
+ '.jpg': 'image/jpeg',
18
+ '.jpeg': 'image/jpeg',
19
+ '.gif': 'image/gif',
20
+ '.svg': 'image/svg+xml',
21
+ '.ico': 'image/x-icon',
22
+ '.woff': 'font/woff',
23
+ '.woff2': 'font/woff2',
24
+ '.ttf': 'font/ttf',
25
+ '.otf': 'font/otf',
26
+ '.webp': 'image/webp',
27
+ '.avif': 'image/avif',
28
+ '.mp4': 'video/mp4',
29
+ '.webm': 'video/webm',
30
+ };
9
31
  export class PluginLoader {
10
32
  /**
11
33
  * Scan appsDir for installed apps and return their manifests.
@@ -70,8 +92,17 @@ export class PluginLoader {
70
92
  const dir = join(appsDir, manifest.name, 'tools');
71
93
  return existsSync(dir) ? dir : null;
72
94
  }
95
+ /**
96
+ * Return the static assets directory for a given app, if it exists.
97
+ */
98
+ getStaticDir(appsDir, manifest) {
99
+ const dir = join(appsDir, manifest.name, 'static');
100
+ return existsSync(dir) ? dir : null;
101
+ }
73
102
  /**
74
103
  * Dynamically import and register a plugin under its mountPath.
104
+ * Also mounts a static file handler at {mountPath}/static/* if the
105
+ * app has a static/ directory.
75
106
  */
76
107
  async mountPlugin(fastify, manifest, appDir, opts) {
77
108
  const pluginPath = join(appDir, manifest.name, manifest.plugin);
@@ -84,12 +115,33 @@ export class PluginLoader {
84
115
  if (typeof pluginFn !== 'function') {
85
116
  throw new Error(`Plugin at ${pluginPath} does not export a function`);
86
117
  }
118
+ const staticDir = this.getStaticDir(appDir, manifest);
87
119
  await fastify.register(pluginFn, {
88
120
  prefix: manifest.mountPath,
89
121
  workspaceManager: opts.workspaceManager,
90
122
  gitUser: opts.gitUser,
91
123
  appsDir: appDir,
124
+ staticDir,
92
125
  });
126
+ // Mount static file handler if app has a static/ directory
127
+ if (staticDir) {
128
+ await fastify.register(async (instance) => {
129
+ instance.get('/*', async (req, reply) => {
130
+ const filePath = req.params['*'];
131
+ if (!filePath || filePath.includes('..')) {
132
+ return reply.status(400).send({ error: 'Invalid path' });
133
+ }
134
+ const fullPath = join(staticDir, filePath);
135
+ if (!existsSync(fullPath)) {
136
+ return reply.status(404).send({ error: 'Not found' });
137
+ }
138
+ const ext = extname(fullPath).toLowerCase();
139
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
140
+ reply.type(contentType);
141
+ return reply.send(createReadStream(fullPath));
142
+ });
143
+ }, { prefix: `${manifest.mountPath}/static` });
144
+ }
93
145
  }
94
146
  }
95
147
  //# sourceMappingURL=plugin-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../../src/server/plugin-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin-loader.js","sourceRoot":"","sources":["../../src/server/plugin-loader.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,11 @@
2
2
  * Chat / Agent SSE routes
3
3
  *
4
4
  * POST /api/chat — send a message, await full response
5
- * GET /api/chat/stream — SSE stream of agent events (future)
5
+ * POST /api/chat/stream — SSE stream of agent events with session persistence
6
6
  *
7
7
  * Single agent instance per server process (single-user v1).
8
8
  */
9
9
  import type { FastifyInstance } from 'fastify';
10
10
  import { AgentOrchestrator } from '../../agent/orchestrator.js';
11
- export declare function registerChatRoutes(fastify: FastifyInstance, agent: AgentOrchestrator): Promise<void>;
11
+ import type { MemoryService } from '../../services/memory-service.js';
12
+ export declare function registerChatRoutes(fastify: FastifyInstance, agent: AgentOrchestrator, memoryService?: MemoryService): Promise<void>;
@@ -2,11 +2,11 @@
2
2
  * Chat / Agent SSE routes
3
3
  *
4
4
  * POST /api/chat — send a message, await full response
5
- * GET /api/chat/stream — SSE stream of agent events (future)
5
+ * POST /api/chat/stream — SSE stream of agent events with session persistence
6
6
  *
7
7
  * Single agent instance per server process (single-user v1).
8
8
  */
9
- export async function registerChatRoutes(fastify, agent) {
9
+ export async function registerChatRoutes(fastify, agent, memoryService) {
10
10
  // POST /api/chat — send message, get full response
11
11
  fastify.post('/api/chat', async (req, reply) => {
12
12
  const { message } = req.body;
@@ -22,11 +22,20 @@ export async function registerChatRoutes(fastify, agent) {
22
22
  return reply.status(500).send({ error: err.message || 'Agent error' });
23
23
  }
24
24
  });
25
- // GET /api/chat/stream — SSE stream of agent events
26
- fastify.get('/api/chat/stream', async (req, reply) => {
27
- const { message } = req.query;
28
- if (!message || !message.trim()) {
29
- return reply.status(400).send({ error: 'message query param is required' });
25
+ // POST /api/chat/stream — SSE stream of agent events
26
+ fastify.post('/api/chat/stream', async (req, reply) => {
27
+ const { message, context, sessionId, history } = req.body;
28
+ if (!message || typeof message !== 'string' || !message.trim()) {
29
+ return reply.status(400).send({ error: 'message is required' });
30
+ }
31
+ // Switch agent to the requested session (restores prior conversation)
32
+ if (sessionId) {
33
+ try {
34
+ await agent.switchSession(sessionId, history);
35
+ }
36
+ catch (err) {
37
+ fastify.log.warn(`Session switch failed: ${err.message}`);
38
+ }
30
39
  }
31
40
  // Set SSE headers
32
41
  reply.raw.setHeader('Content-Type', 'text/event-stream');
@@ -37,27 +46,69 @@ export async function registerChatRoutes(fastify, agent) {
37
46
  reply.raw.write(`data: ${JSON.stringify(data)}\n\n`);
38
47
  };
39
48
  try {
49
+ // Hook highlight callback so highlight_entities tool sends SSE events
50
+ agent.setHighlightCallback((ids) => {
51
+ sendEvent({ type: 'highlight', entityIds: ids });
52
+ });
53
+ // Hook mutation callback so create/update/delete send SSE events
54
+ agent.setMutationCallback((m) => {
55
+ sendEvent({ type: 'mutation', action: m.action, repo: m.repo, entityType: m.entityType, entityId: m.entityId });
56
+ });
40
57
  // Subscribe to agent events before sending message
41
- const unsubscribe = agent.agent?.subscribe?.((event) => {
58
+ let hasContent = false;
59
+ let needsTurnSep = false;
60
+ const rawAgent = agent.getAgent();
61
+ const unsubscribe = rawAgent.subscribe((event) => {
42
62
  if (event.type === 'message_update') {
43
63
  const msgEvent = event.assistantMessageEvent;
44
64
  if (msgEvent?.type === 'text_delta') {
65
+ if (needsTurnSep && hasContent) {
66
+ sendEvent({ type: 'token', text: '\n\n' });
67
+ }
68
+ needsTurnSep = false;
69
+ hasContent = true;
45
70
  sendEvent({ type: 'token', text: msgEvent.delta });
46
71
  }
47
72
  }
48
- else if (event.type === 'tool_start') {
49
- sendEvent({ type: 'tool_start', name: event.name });
50
- }
51
- else if (event.type === 'tool_end') {
52
- sendEvent({ type: 'tool_end', name: event.name });
73
+ else if (event.type === 'message_end') {
74
+ if (event.message?.role === 'assistant') {
75
+ needsTurnSep = true;
76
+ // Extract tool names from the completed assistant message
77
+ for (const block of event.message.content ?? []) {
78
+ if (block.type === 'toolCall' && block.name) {
79
+ sendEvent({ type: 'tool_start', name: block.name });
80
+ }
81
+ }
82
+ }
53
83
  }
54
84
  });
55
- const response = await agent.chat(message);
56
- if (unsubscribe)
57
- unsubscribe();
85
+ const fullMessage = context
86
+ ? `[Currently viewing: ${context}]\n\n${message}`
87
+ : message;
88
+ const response = await agent.chat(fullMessage);
89
+ unsubscribe();
90
+ agent.setHighlightCallback(null);
91
+ agent.setMutationCallback(null);
92
+ // Persist session to disk after response
93
+ if (sessionId) {
94
+ try {
95
+ agent.saveSession();
96
+ }
97
+ catch { /* non-fatal */ }
98
+ }
99
+ // Write brief entry to today's daily memory
100
+ if (memoryService && response.content) {
101
+ try {
102
+ const snippet = `User: ${message.slice(0, 100)}${message.length > 100 ? '…' : ''}\nAgent: ${response.content.slice(0, 200)}${response.content.length > 200 ? '…' : ''}`;
103
+ memoryService.saveSessionSummary(snippet, { source: 'web-chat', sessionId });
104
+ }
105
+ catch { /* non-fatal */ }
106
+ }
58
107
  sendEvent({ type: 'done', message: response.content });
59
108
  }
60
109
  catch (err) {
110
+ agent.setHighlightCallback(null);
111
+ agent.setMutationCallback(null);
61
112
  sendEvent({ type: 'error', message: err.message || 'Agent error' });
62
113
  }
63
114
  reply.raw.end();
@@ -1 +1 @@
1
- {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/server/routes/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/server/routes/chat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAwB,EACxB,KAAwB,EACxB,aAA6B;IAE7B,mDAAmD;IACnD,OAAO,CAAC,IAAI,CACV,WAAW,EACX,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACnB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QAE7B,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/D,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC,CACF,CAAC;IAEF,qDAAqD;IACrD,OAAO,CAAC,IAAI,CACV,kBAAkB,EAClB,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;QACnB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QAE1D,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/D,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,CAAC;QAClE,CAAC;QAED,sEAAsE;QACtE,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChD,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;QACzD,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QACjD,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAChD,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAEzB,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;YACjC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvD,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,sEAAsE;YACtE,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAa,EAAE,EAAE;gBAC3C,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;YAEH,iEAAiE;YACjE,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC9B,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAClH,CAAC,CAAC,CAAC;YAEH,mDAAmD;YACnD,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAU,EAAE,EAAE;gBACpD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;oBACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,qBAAqB,CAAC;oBAC7C,IAAI,QAAQ,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;wBACpC,IAAI,YAAY,IAAI,UAAU,EAAE,CAAC;4BAC/B,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;wBAC7C,CAAC;wBACD,YAAY,GAAG,KAAK,CAAC;wBACrB,UAAU,GAAG,IAAI,CAAC;wBAClB,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;oBACrD,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;oBACxC,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;wBACxC,YAAY,GAAG,IAAI,CAAC;wBACpB,0DAA0D;wBAC1D,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;4BAChD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gCAC5C,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;4BACtD,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,OAAO;gBACzB,CAAC,CAAC,uBAAuB,OAAO,QAAQ,OAAO,EAAE;gBACjD,CAAC,CAAC,OAAO,CAAC;YACZ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAE/C,WAAW,EAAE,CAAC;YACd,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEhC,yCAAyC;YACzC,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC;oBAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;YACxD,CAAC;YAED,4CAA4C;YAC5C,IAAI,aAAa,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,SAAS,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACxK,aAAa,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC/E,CAAC;gBAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;YAC7B,CAAC;YAED,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAChC,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IAClB,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Git API routes
3
+ *
4
+ * Status, commit, and pull operations across workspace repos.
5
+ * All routes are protected by auth.
6
+ */
7
+ import type { FastifyInstance } from 'fastify';
8
+ import { WorkspaceManager } from '../../core/workspace-manager.js';
9
+ export declare function registerGitApiRoutes(fastify: FastifyInstance, workspaceManager: WorkspaceManager, workspacePath: string): Promise<void>;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Git API routes
3
+ *
4
+ * Status, commit, and pull operations across workspace repos.
5
+ * All routes are protected by auth.
6
+ */
7
+ import { spawnSync } from 'child_process';
8
+ import { commitRepos } from '../../services/sync/commit.js';
9
+ export async function registerGitApiRoutes(fastify, workspaceManager, workspacePath) {
10
+ // GET /api/git/status — per-repo git status
11
+ fastify.get('/api/git/status', async (_req, reply) => {
12
+ const repoConfigs = workspaceManager.getAllRepoConfigs();
13
+ const statuses = [];
14
+ for (const config of repoConfigs) {
15
+ try {
16
+ const graph = workspaceManager.getGraph(config.name);
17
+ const git = graph.gitService;
18
+ if (!git)
19
+ continue;
20
+ const status = git.getStatus();
21
+ // Get current branch
22
+ const branchResult = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
23
+ cwd: config.path,
24
+ encoding: 'utf-8',
25
+ });
26
+ const branch = branchResult.stdout?.trim() || 'main';
27
+ statuses.push({
28
+ repo: config.name,
29
+ branch,
30
+ ...status,
31
+ totalChanges: status.modified.length + status.added.length + status.deleted.length + status.untracked.length,
32
+ });
33
+ }
34
+ catch {
35
+ // Skip repos that don't have git
36
+ }
37
+ }
38
+ return reply.send(statuses);
39
+ });
40
+ // POST /api/git/commit — commit all repos
41
+ fastify.post('/api/git/commit', async (req, reply) => {
42
+ const { message } = req.body ?? {};
43
+ try {
44
+ await commitRepos(workspacePath, undefined, {
45
+ messagePrefix: message,
46
+ });
47
+ return reply.send({ success: true });
48
+ }
49
+ catch (err) {
50
+ return reply.status(500).send({ error: err.message });
51
+ }
52
+ });
53
+ // POST /api/git/pull — pull all repos
54
+ fastify.post('/api/git/pull', async (_req, reply) => {
55
+ const repoConfigs = workspaceManager.getAllRepoConfigs();
56
+ const results = [];
57
+ for (const config of repoConfigs) {
58
+ try {
59
+ const result = spawnSync('git', ['pull', '--rebase', '--autostash'], {
60
+ cwd: config.path,
61
+ encoding: 'utf-8',
62
+ timeout: 30000,
63
+ });
64
+ if (result.status === 0) {
65
+ results.push({ repo: config.name, success: true });
66
+ }
67
+ else {
68
+ results.push({
69
+ repo: config.name,
70
+ success: false,
71
+ message: result.stderr?.trim() || 'Pull failed',
72
+ });
73
+ }
74
+ }
75
+ catch (err) {
76
+ results.push({ repo: config.name, success: false, message: err.message });
77
+ }
78
+ }
79
+ return reply.send({ results });
80
+ });
81
+ }
82
+ //# sourceMappingURL=git-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-api.js","sourceRoot":"","sources":["../../../src/server/routes/git-api.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Graph API routes
3
3
  *
4
- * Read-only REST façade over WorkspaceManager.
5
- * All writes go through the agent (/api/chat).
4
+ * REST façade over WorkspaceManager.
5
+ * Read endpoints are unauthenticated; write endpoints require auth.
6
6
  */
7
7
  import type { FastifyInstance } from 'fastify';
8
8
  import { WorkspaceManager } from '../../core/workspace-manager.js';