studiograph 1.3.48-next.2 → 1.3.48-next.201

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 (1157) hide show
  1. package/README.md +26 -16
  2. package/dist/agent/agent-pool.d.ts +117 -0
  3. package/dist/agent/agent-pool.js +287 -0
  4. package/dist/agent/agent-pool.js.map +1 -0
  5. package/dist/agent/followups.d.ts +34 -0
  6. package/dist/agent/followups.js +52 -0
  7. package/dist/agent/followups.js.map +1 -0
  8. package/dist/agent/orchestrator.d.ts +113 -22
  9. package/dist/agent/orchestrator.js +574 -181
  10. package/dist/agent/orchestrator.js.map +1 -1
  11. package/dist/agent/prompts/entity-types-section.d.ts +34 -0
  12. package/dist/agent/prompts/entity-types-section.js +76 -0
  13. package/dist/agent/prompts/entity-types-section.js.map +1 -0
  14. package/dist/agent/prompts/system.md +147 -69
  15. package/dist/agent/skill-loader.d.ts +30 -17
  16. package/dist/agent/skill-loader.js +63 -30
  17. package/dist/agent/skill-loader.js.map +1 -1
  18. package/dist/agent/skills/entity-schema.md +77 -433
  19. package/dist/agent/skills/interview/entity-templates.md +193 -0
  20. package/dist/agent/skills/interview/question-domains.md +391 -0
  21. package/dist/agent/skills/interview/skill.md +204 -0
  22. package/dist/agent/skills/schema-rules.md +54 -0
  23. package/dist/agent/tools/capture-tools.d.ts +31 -0
  24. package/dist/agent/tools/capture-tools.js +40 -0
  25. package/dist/agent/tools/capture-tools.js.map +1 -0
  26. package/dist/agent/tools/folder-tools.d.ts +47 -0
  27. package/dist/agent/tools/folder-tools.js +249 -0
  28. package/dist/agent/tools/folder-tools.js.map +1 -0
  29. package/dist/agent/tools/fs-tools.d.ts +7 -6
  30. package/dist/agent/tools/fs-tools.js +5 -4
  31. package/dist/agent/tools/fs-tools.js.map +1 -1
  32. package/dist/agent/tools/graph-tools.d.ts +21 -58
  33. package/dist/agent/tools/graph-tools.js +664 -333
  34. package/dist/agent/tools/graph-tools.js.map +1 -1
  35. package/dist/agent/tools/history-tools.d.ts +95 -0
  36. package/dist/agent/tools/history-tools.js +461 -0
  37. package/dist/agent/tools/history-tools.js.map +1 -0
  38. package/dist/agent/tools/load-skill.d.ts +6 -5
  39. package/dist/agent/tools/load-skill.js +3 -3
  40. package/dist/agent/tools/load-skill.js.map +1 -1
  41. package/dist/agent/tools/ops-tools.d.ts +5 -4
  42. package/dist/agent/tools/ops-tools.js +130 -236
  43. package/dist/agent/tools/ops-tools.js.map +1 -1
  44. package/dist/agent/tools/permission-tools.d.ts +87 -17
  45. package/dist/agent/tools/permission-tools.js +233 -38
  46. package/dist/agent/tools/permission-tools.js.map +1 -1
  47. package/dist/agent/tools/tool-loader.js +5 -4
  48. package/dist/agent/tools/tool-loader.js.map +1 -1
  49. package/dist/agent/tools/web-tools.js +58 -9
  50. package/dist/agent/tools/web-tools.js.map +1 -1
  51. package/dist/cli/commands/about.d.ts +1 -0
  52. package/dist/cli/commands/about.js +55 -3
  53. package/dist/cli/commands/about.js.map +1 -1
  54. package/dist/cli/commands/admin/audit-workspace.d.ts +23 -0
  55. package/dist/cli/commands/admin/audit-workspace.js +133 -0
  56. package/dist/cli/commands/admin/audit-workspace.js.map +1 -0
  57. package/dist/cli/commands/admin/audit.d.ts +21 -0
  58. package/dist/cli/commands/admin/audit.js +174 -0
  59. package/dist/cli/commands/admin/audit.js.map +1 -0
  60. package/dist/cli/commands/admin/backup.d.ts +54 -0
  61. package/dist/cli/commands/admin/backup.js +207 -0
  62. package/dist/cli/commands/admin/backup.js.map +1 -0
  63. package/dist/cli/commands/admin/folder.d.ts +11 -0
  64. package/dist/cli/commands/admin/folder.js +186 -0
  65. package/dist/cli/commands/admin/folder.js.map +1 -0
  66. package/dist/cli/commands/admin/index.d.ts +16 -0
  67. package/dist/cli/commands/admin/index.js +46 -0
  68. package/dist/cli/commands/admin/index.js.map +1 -0
  69. package/dist/cli/commands/admin/migrate-assets.d.ts +53 -0
  70. package/dist/cli/commands/admin/migrate-assets.js +184 -0
  71. package/dist/cli/commands/admin/migrate-assets.js.map +1 -0
  72. package/dist/cli/commands/admin/migrate.d.ts +56 -0
  73. package/dist/cli/commands/admin/migrate.js +263 -0
  74. package/dist/cli/commands/admin/migrate.js.map +1 -0
  75. package/dist/cli/commands/admin/restore.d.ts +24 -0
  76. package/dist/cli/commands/admin/restore.js +228 -0
  77. package/dist/cli/commands/admin/restore.js.map +1 -0
  78. package/dist/cli/commands/admin/secrets.d.ts +23 -0
  79. package/dist/cli/commands/admin/secrets.js +256 -0
  80. package/dist/cli/commands/admin/secrets.js.map +1 -0
  81. package/dist/cli/commands/admin/settings.d.ts +28 -0
  82. package/dist/cli/commands/admin/settings.js +284 -0
  83. package/dist/cli/commands/admin/settings.js.map +1 -0
  84. package/dist/cli/commands/admin/token.d.ts +42 -0
  85. package/dist/cli/commands/admin/token.js +126 -0
  86. package/dist/cli/commands/admin/token.js.map +1 -0
  87. package/dist/cli/commands/admin/transfer-ownership.d.ts +15 -0
  88. package/dist/cli/commands/admin/transfer-ownership.js +106 -0
  89. package/dist/cli/commands/admin/transfer-ownership.js.map +1 -0
  90. package/dist/cli/commands/admin/user.d.ts +11 -0
  91. package/dist/cli/commands/admin/user.js +187 -0
  92. package/dist/cli/commands/admin/user.js.map +1 -0
  93. package/dist/cli/commands/clone.d.ts +25 -3
  94. package/dist/cli/commands/clone.js +142 -36
  95. package/dist/cli/commands/clone.js.map +1 -1
  96. package/dist/cli/commands/commit.d.ts +1 -1
  97. package/dist/cli/commands/commit.js +24 -11
  98. package/dist/cli/commands/commit.js.map +1 -1
  99. package/dist/cli/commands/config.d.ts +23 -107
  100. package/dist/cli/commands/config.js +52 -260
  101. package/dist/cli/commands/config.js.map +1 -1
  102. package/dist/cli/commands/connector.d.ts +10 -13
  103. package/dist/cli/commands/connector.js +16 -58
  104. package/dist/cli/commands/connector.js.map +1 -1
  105. package/dist/cli/commands/deploy.js +215 -68
  106. package/dist/cli/commands/deploy.js.map +1 -1
  107. package/dist/cli/commands/index.js +2 -2
  108. package/dist/cli/commands/index.js.map +1 -1
  109. package/dist/cli/commands/init.js +10 -30
  110. package/dist/cli/commands/init.js.map +1 -1
  111. package/dist/cli/commands/mcp.js +12 -4
  112. package/dist/cli/commands/mcp.js.map +1 -1
  113. package/dist/cli/commands/orphans.js +14 -30
  114. package/dist/cli/commands/orphans.js.map +1 -1
  115. package/dist/cli/commands/r2.d.ts +3 -0
  116. package/dist/cli/commands/r2.js +223 -204
  117. package/dist/cli/commands/r2.js.map +1 -1
  118. package/dist/cli/commands/redeploy.js +65 -12
  119. package/dist/cli/commands/redeploy.js.map +1 -1
  120. package/dist/cli/commands/reset.d.ts +22 -6
  121. package/dist/cli/commands/reset.js +142 -63
  122. package/dist/cli/commands/reset.js.map +1 -1
  123. package/dist/cli/commands/serve.js +218 -24
  124. package/dist/cli/commands/serve.js.map +1 -1
  125. package/dist/cli/commands/sync.d.ts +1 -1
  126. package/dist/cli/commands/sync.js +372 -202
  127. package/dist/cli/commands/sync.js.map +1 -1
  128. package/dist/cli/crypto-bundle.d.ts +39 -0
  129. package/dist/cli/crypto-bundle.js +94 -0
  130. package/dist/cli/crypto-bundle.js.map +1 -0
  131. package/dist/cli/index.js +24 -35
  132. package/dist/cli/index.js.map +1 -1
  133. package/dist/cli/railway-pin.d.ts +68 -0
  134. package/dist/cli/railway-pin.js +96 -0
  135. package/dist/cli/railway-pin.js.map +1 -0
  136. package/dist/cli/railway-provisioning.d.ts +53 -0
  137. package/dist/cli/railway-provisioning.js +85 -0
  138. package/dist/cli/railway-provisioning.js.map +1 -0
  139. package/dist/cli/setup-wizard.d.ts +33 -52
  140. package/dist/cli/setup-wizard.js +43 -68
  141. package/dist/cli/setup-wizard.js.map +1 -1
  142. package/dist/core/accent-palette.d.ts +22 -0
  143. package/dist/core/accent-palette.js +47 -0
  144. package/dist/core/accent-palette.js.map +1 -0
  145. package/dist/core/cell-anchor.d.ts +29 -0
  146. package/dist/core/cell-anchor.js +53 -0
  147. package/dist/core/cell-anchor.js.map +1 -0
  148. package/dist/core/comment-anchor.d.ts +41 -0
  149. package/dist/core/comment-anchor.js +147 -0
  150. package/dist/core/comment-anchor.js.map +1 -0
  151. package/dist/core/commit-messages.d.ts +57 -0
  152. package/dist/core/commit-messages.js +85 -0
  153. package/dist/core/commit-messages.js.map +1 -0
  154. package/dist/core/embeds.d.ts +77 -0
  155. package/dist/core/embeds.js +147 -0
  156. package/dist/core/embeds.js.map +1 -0
  157. package/dist/core/entity-body-templates.d.ts +21 -0
  158. package/dist/core/entity-body-templates.js +53 -0
  159. package/dist/core/entity-body-templates.js.map +1 -0
  160. package/dist/core/entity-types-catalog.d.ts +65 -0
  161. package/dist/core/entity-types-catalog.js +140 -0
  162. package/dist/core/entity-types-catalog.js.map +1 -0
  163. package/dist/core/folder-paths.d.ts +41 -0
  164. package/dist/core/folder-paths.js +95 -0
  165. package/dist/core/folder-paths.js.map +1 -0
  166. package/dist/core/folder-sidecar.d.ts +36 -0
  167. package/dist/core/folder-sidecar.js +91 -0
  168. package/dist/core/folder-sidecar.js.map +1 -0
  169. package/dist/core/format-registry.d.ts +170 -0
  170. package/dist/core/format-registry.js +404 -0
  171. package/dist/core/format-registry.js.map +1 -0
  172. package/dist/core/graph.d.ts +731 -14
  173. package/dist/core/graph.js +2202 -315
  174. package/dist/core/graph.js.map +1 -1
  175. package/dist/core/history-diff.d.ts +35 -0
  176. package/dist/core/history-diff.js +114 -0
  177. package/dist/core/history-diff.js.map +1 -0
  178. package/dist/core/refs.d.ts +41 -0
  179. package/dist/core/refs.js +80 -0
  180. package/dist/core/refs.js.map +1 -0
  181. package/dist/core/schema-registry.d.ts +82 -0
  182. package/dist/core/schema-registry.js +238 -0
  183. package/dist/core/schema-registry.js.map +1 -1
  184. package/dist/core/schemas/connector.d.ts +67 -0
  185. package/dist/core/schemas/connector.js +100 -0
  186. package/dist/core/schemas/connector.js.map +1 -0
  187. package/dist/core/schemas/workspace.d.ts +122 -0
  188. package/dist/core/schemas/workspace.js +211 -0
  189. package/dist/core/schemas/workspace.js.map +1 -0
  190. package/dist/core/secrets/SecretStore.d.ts +77 -0
  191. package/dist/core/secrets/SecretStore.js +13 -0
  192. package/dist/core/secrets/SecretStore.js.map +1 -0
  193. package/dist/core/secrets/SettingsResolver.d.ts +54 -0
  194. package/dist/core/secrets/SettingsResolver.js +80 -0
  195. package/dist/core/secrets/SettingsResolver.js.map +1 -0
  196. package/dist/core/secrets/SettingsStore.d.ts +30 -0
  197. package/dist/core/secrets/SettingsStore.js +9 -0
  198. package/dist/core/secrets/SettingsStore.js.map +1 -0
  199. package/dist/core/secrets/SqliteEncryptedStore.d.ts +90 -0
  200. package/dist/core/secrets/SqliteEncryptedStore.js +598 -0
  201. package/dist/core/secrets/SqliteEncryptedStore.js.map +1 -0
  202. package/dist/core/secrets/audit.d.ts +36 -0
  203. package/dist/core/secrets/audit.js +60 -0
  204. package/dist/core/secrets/audit.js.map +1 -0
  205. package/dist/core/secrets/auth-db-migration.d.ts +129 -0
  206. package/dist/core/secrets/auth-db-migration.js +653 -0
  207. package/dist/core/secrets/auth-db-migration.js.map +1 -0
  208. package/dist/core/secrets/bundle.d.ts +141 -0
  209. package/dist/core/secrets/bundle.js +435 -0
  210. package/dist/core/secrets/bundle.js.map +1 -0
  211. package/dist/core/secrets/dual-write.d.ts +81 -0
  212. package/dist/core/secrets/dual-write.js +247 -0
  213. package/dist/core/secrets/dual-write.js.map +1 -0
  214. package/dist/core/secrets/encryption.d.ts +44 -0
  215. package/dist/core/secrets/encryption.js +97 -0
  216. package/dist/core/secrets/encryption.js.map +1 -0
  217. package/dist/core/secrets/index.d.ts +49 -0
  218. package/dist/core/secrets/index.js +74 -0
  219. package/dist/core/secrets/index.js.map +1 -0
  220. package/dist/core/secrets/master-key.d.ts +38 -0
  221. package/dist/core/secrets/master-key.js +122 -0
  222. package/dist/core/secrets/master-key.js.map +1 -0
  223. package/dist/core/secrets/probes/anthropic.d.ts +98 -0
  224. package/dist/core/secrets/probes/anthropic.js +300 -0
  225. package/dist/core/secrets/probes/anthropic.js.map +1 -0
  226. package/dist/core/secrets/probes/brave.d.ts +9 -0
  227. package/dist/core/secrets/probes/brave.js +15 -0
  228. package/dist/core/secrets/probes/brave.js.map +1 -0
  229. package/dist/core/secrets/probes/r2.d.ts +15 -0
  230. package/dist/core/secrets/probes/r2.js +14 -0
  231. package/dist/core/secrets/probes/r2.js.map +1 -0
  232. package/dist/core/secrets/probes/tavily.d.ts +18 -0
  233. package/dist/core/secrets/probes/tavily.js +58 -0
  234. package/dist/core/secrets/probes/tavily.js.map +1 -0
  235. package/dist/core/secrets/probes/voyage.d.ts +13 -0
  236. package/dist/core/secrets/probes/voyage.js +52 -0
  237. package/dist/core/secrets/probes/voyage.js.map +1 -0
  238. package/dist/core/secrets/r2-structural-migration.d.ts +39 -0
  239. package/dist/core/secrets/r2-structural-migration.js +109 -0
  240. package/dist/core/secrets/r2-structural-migration.js.map +1 -0
  241. package/dist/core/secrets/read-flip.d.ts +59 -0
  242. package/dist/core/secrets/read-flip.js +87 -0
  243. package/dist/core/secrets/read-flip.js.map +1 -0
  244. package/dist/core/secrets/registry.d.ts +188 -0
  245. package/dist/core/secrets/registry.js +616 -0
  246. package/dist/core/secrets/registry.js.map +1 -0
  247. package/dist/core/types.d.ts +80 -475
  248. package/dist/core/types.js +27 -3
  249. package/dist/core/types.js.map +1 -1
  250. package/dist/core/user-config.d.ts +75 -7
  251. package/dist/core/user-config.js +155 -7
  252. package/dist/core/user-config.js.map +1 -1
  253. package/dist/core/validation.d.ts +731 -1790
  254. package/dist/core/validation.js +442 -228
  255. package/dist/core/validation.js.map +1 -1
  256. package/dist/core/workspace-manager.d.ts +89 -12
  257. package/dist/core/workspace-manager.js +225 -73
  258. package/dist/core/workspace-manager.js.map +1 -1
  259. package/dist/core/workspace.d.ts +19 -5
  260. package/dist/core/workspace.js +69 -35
  261. package/dist/core/workspace.js.map +1 -1
  262. package/dist/mcp/comment-virtual-entity.d.ts +36 -0
  263. package/dist/mcp/comment-virtual-entity.js +71 -0
  264. package/dist/mcp/comment-virtual-entity.js.map +1 -0
  265. package/dist/mcp/connector-manager.d.ts +94 -13
  266. package/dist/mcp/connector-manager.js +283 -62
  267. package/dist/mcp/connector-manager.js.map +1 -1
  268. package/dist/mcp/oauth-provider.d.ts +27 -33
  269. package/dist/mcp/oauth-provider.js +65 -134
  270. package/dist/mcp/oauth-provider.js.map +1 -1
  271. package/dist/mcp/oauth-registry.d.ts +62 -0
  272. package/dist/mcp/oauth-registry.js +85 -0
  273. package/dist/mcp/oauth-registry.js.map +1 -0
  274. package/dist/mcp/server.d.ts +11 -3
  275. package/dist/mcp/server.js +30 -5
  276. package/dist/mcp/server.js.map +1 -1
  277. package/dist/mcp/state-signer.d.ts +62 -0
  278. package/dist/mcp/state-signer.js +205 -0
  279. package/dist/mcp/state-signer.js.map +1 -0
  280. package/dist/mcp/tools.d.ts +35 -2
  281. package/dist/mcp/tools.js +1361 -112
  282. package/dist/mcp/tools.js.map +1 -1
  283. package/dist/server/__tests__/helpers/graph-api.d.ts +16 -0
  284. package/dist/server/__tests__/helpers/graph-api.js +16 -0
  285. package/dist/server/__tests__/helpers/graph-api.js.map +1 -0
  286. package/dist/server/asset-index-queue.d.ts +96 -0
  287. package/dist/server/asset-index-queue.js +191 -0
  288. package/dist/server/asset-index-queue.js.map +1 -0
  289. package/dist/server/body-write-coordinator.d.ts +151 -0
  290. package/dist/server/body-write-coordinator.js +161 -0
  291. package/dist/server/body-write-coordinator.js.map +1 -0
  292. package/dist/server/cloud-billing-flow.d.ts +32 -0
  293. package/dist/server/cloud-billing-flow.js +75 -0
  294. package/dist/server/cloud-billing-flow.js.map +1 -0
  295. package/dist/server/commit-audit.d.ts +26 -0
  296. package/dist/server/commit-audit.js +30 -0
  297. package/dist/server/commit-audit.js.map +1 -0
  298. package/dist/server/index.d.ts +22 -3
  299. package/dist/server/index.js +622 -198
  300. package/dist/server/index.js.map +1 -1
  301. package/dist/server/middleware/sanitize.d.ts +46 -0
  302. package/dist/server/middleware/sanitize.js +171 -0
  303. package/dist/server/middleware/sanitize.js.map +1 -0
  304. package/dist/server/routes/asset-api.d.ts +31 -0
  305. package/dist/server/routes/asset-api.js +593 -0
  306. package/dist/server/routes/asset-api.js.map +1 -0
  307. package/dist/server/routes/audit-api.d.ts +24 -0
  308. package/dist/server/routes/audit-api.js +117 -0
  309. package/dist/server/routes/audit-api.js.map +1 -0
  310. package/dist/server/routes/auth-api.d.ts +3 -2
  311. package/dist/server/routes/auth-api.js +573 -39
  312. package/dist/server/routes/auth-api.js.map +1 -1
  313. package/dist/server/routes/capture-api.d.ts +18 -0
  314. package/dist/server/routes/capture-api.js +257 -0
  315. package/dist/server/routes/capture-api.js.map +1 -0
  316. package/dist/server/routes/chat-sessions-api.d.ts +9 -0
  317. package/dist/server/routes/chat-sessions-api.js +121 -0
  318. package/dist/server/routes/chat-sessions-api.js.map +1 -0
  319. package/dist/server/routes/chat.d.ts +12 -1
  320. package/dist/server/routes/chat.js +318 -88
  321. package/dist/server/routes/chat.js.map +1 -1
  322. package/dist/server/routes/comments-api.d.ts +15 -0
  323. package/dist/server/routes/comments-api.js +444 -0
  324. package/dist/server/routes/comments-api.js.map +1 -0
  325. package/dist/server/routes/config-api.d.ts +21 -0
  326. package/dist/server/routes/config-api.js +256 -0
  327. package/dist/server/routes/config-api.js.map +1 -0
  328. package/dist/server/routes/connectors-api.d.ts +17 -0
  329. package/dist/server/routes/connectors-api.js +410 -0
  330. package/dist/server/routes/connectors-api.js.map +1 -0
  331. package/dist/server/routes/event-ingest-api.d.ts +15 -0
  332. package/dist/server/routes/event-ingest-api.js +125 -0
  333. package/dist/server/routes/event-ingest-api.js.map +1 -0
  334. package/dist/server/routes/git-http.d.ts +3 -3
  335. package/dist/server/routes/git-http.js +86 -38
  336. package/dist/server/routes/git-http.js.map +1 -1
  337. package/dist/server/routes/graph-api-access.d.ts +57 -0
  338. package/dist/server/routes/graph-api-access.js +112 -0
  339. package/dist/server/routes/graph-api-access.js.map +1 -0
  340. package/dist/server/routes/graph-api.d.ts +1 -1
  341. package/dist/server/routes/graph-api.js +1529 -263
  342. package/dist/server/routes/graph-api.js.map +1 -1
  343. package/dist/server/routes/health.d.ts +18 -0
  344. package/dist/server/routes/health.js +74 -0
  345. package/dist/server/routes/health.js.map +1 -0
  346. package/dist/server/routes/import-batch.d.ts +24 -0
  347. package/dist/server/routes/import-batch.js +33 -0
  348. package/dist/server/routes/import-batch.js.map +1 -0
  349. package/dist/server/routes/insights-api.d.ts +9 -2
  350. package/dist/server/routes/insights-api.js +384 -38
  351. package/dist/server/routes/insights-api.js.map +1 -1
  352. package/dist/server/routes/mcp.d.ts +7 -3
  353. package/dist/server/routes/mcp.js +22 -6
  354. package/dist/server/routes/mcp.js.map +1 -1
  355. package/dist/server/routes/oauth-api.d.ts +67 -0
  356. package/dist/server/routes/oauth-api.js +421 -0
  357. package/dist/server/routes/oauth-api.js.map +1 -0
  358. package/dist/server/routes/permissions-api.d.ts +9 -2
  359. package/dist/server/routes/permissions-api.js +87 -30
  360. package/dist/server/routes/permissions-api.js.map +1 -1
  361. package/dist/server/routes/r2-api.d.ts +25 -0
  362. package/dist/server/routes/r2-api.js +276 -0
  363. package/dist/server/routes/r2-api.js.map +1 -0
  364. package/dist/server/routes/secrets-api.d.ts +36 -0
  365. package/dist/server/routes/secrets-api.js +308 -0
  366. package/dist/server/routes/secrets-api.js.map +1 -0
  367. package/dist/server/routes/settings-api.d.ts +29 -0
  368. package/dist/server/routes/settings-api.js +180 -0
  369. package/dist/server/routes/settings-api.js.map +1 -0
  370. package/dist/server/routes/share-api.d.ts +32 -0
  371. package/dist/server/routes/share-api.js +234 -0
  372. package/dist/server/routes/share-api.js.map +1 -0
  373. package/dist/server/routes/url-api.d.ts +7 -0
  374. package/dist/server/routes/url-api.js +74 -0
  375. package/dist/server/routes/url-api.js.map +1 -0
  376. package/dist/server/routes/views-api.js +75 -7
  377. package/dist/server/routes/views-api.js.map +1 -1
  378. package/dist/server/routes/workspace-api.d.ts +2 -1
  379. package/dist/server/routes/workspace-api.js +129 -35
  380. package/dist/server/routes/workspace-api.js.map +1 -1
  381. package/dist/server/routes/ws.d.ts +2 -1
  382. package/dist/server/routes/ws.js +68 -16
  383. package/dist/server/routes/ws.js.map +1 -1
  384. package/dist/server/session-manager.d.ts +48 -5
  385. package/dist/server/session-manager.js +182 -15
  386. package/dist/server/session-manager.js.map +1 -1
  387. package/dist/server/ws-hub.d.ts +138 -14
  388. package/dist/server/ws-hub.js +0 -0
  389. package/dist/server/ws-hub.js.map +1 -1
  390. package/dist/server/yjs-manager.d.ts +285 -7
  391. package/dist/server/yjs-manager.js +907 -36
  392. package/dist/server/yjs-manager.js.map +1 -1
  393. package/dist/server/yjs-persistence.d.ts +165 -0
  394. package/dist/server/yjs-persistence.js +557 -0
  395. package/dist/server/yjs-persistence.js.map +1 -0
  396. package/dist/server/yjs-text-diff.d.ts +32 -0
  397. package/dist/server/yjs-text-diff.js +61 -0
  398. package/dist/server/yjs-text-diff.js.map +1 -0
  399. package/dist/services/access-control.d.ts +73 -0
  400. package/dist/services/access-control.js +165 -0
  401. package/dist/services/access-control.js.map +1 -0
  402. package/dist/services/asset-caption-service.d.ts +102 -0
  403. package/dist/services/asset-caption-service.js +184 -0
  404. package/dist/services/asset-caption-service.js.map +1 -0
  405. package/dist/services/asset-delete-authz.d.ts +31 -0
  406. package/dist/services/asset-delete-authz.js +61 -0
  407. package/dist/services/asset-delete-authz.js.map +1 -0
  408. package/dist/services/asset-finalize-service.d.ts +58 -0
  409. package/dist/services/asset-finalize-service.js +207 -0
  410. package/dist/services/asset-finalize-service.js.map +1 -0
  411. package/dist/services/asset-import-service.d.ts +111 -0
  412. package/dist/services/asset-import-service.js +394 -0
  413. package/dist/services/asset-import-service.js.map +1 -0
  414. package/dist/services/asset-index-sweep.d.ts +92 -0
  415. package/dist/services/asset-index-sweep.js +258 -0
  416. package/dist/services/asset-index-sweep.js.map +1 -0
  417. package/dist/services/asset-lifecycle-check.d.ts +22 -0
  418. package/dist/services/asset-lifecycle-check.js +80 -0
  419. package/dist/services/asset-lifecycle-check.js.map +1 -0
  420. package/dist/services/asset-listing.d.ts +72 -0
  421. package/dist/services/asset-listing.js +321 -0
  422. package/dist/services/asset-listing.js.map +1 -0
  423. package/dist/services/asset-presign-service.d.ts +68 -0
  424. package/dist/services/asset-presign-service.js +124 -0
  425. package/dist/services/asset-presign-service.js.map +1 -0
  426. package/dist/services/asset-sidecar-service.d.ts +30 -0
  427. package/dist/services/asset-sidecar-service.js +96 -0
  428. package/dist/services/asset-sidecar-service.js.map +1 -0
  429. package/dist/services/asset-upload-errors.d.ts +41 -0
  430. package/dist/services/asset-upload-errors.js +45 -0
  431. package/dist/services/asset-upload-errors.js.map +1 -0
  432. package/dist/services/asset-upload-service.d.ts +74 -0
  433. package/dist/services/asset-upload-service.js +244 -0
  434. package/dist/services/asset-upload-service.js.map +1 -0
  435. package/dist/services/asset-upload-token.d.ts +58 -0
  436. package/dist/services/asset-upload-token.js +75 -0
  437. package/dist/services/asset-upload-token.js.map +1 -0
  438. package/dist/services/assets/asset-index-service.d.ts +127 -0
  439. package/dist/services/assets/asset-index-service.js +227 -0
  440. package/dist/services/assets/asset-index-service.js.map +1 -0
  441. package/dist/services/assets/base.d.ts +118 -1
  442. package/dist/services/assets/base.js +77 -1
  443. package/dist/services/assets/base.js.map +1 -1
  444. package/dist/services/assets/index.d.ts +103 -1
  445. package/dist/services/assets/index.js +192 -0
  446. package/dist/services/assets/index.js.map +1 -1
  447. package/dist/services/assets/local.d.ts +16 -1
  448. package/dist/services/assets/local.js +110 -1
  449. package/dist/services/assets/local.js.map +1 -1
  450. package/dist/services/assets/r2-sync.d.ts +88 -0
  451. package/dist/services/assets/r2-sync.js +412 -0
  452. package/dist/services/assets/r2-sync.js.map +1 -0
  453. package/dist/services/assets/r2.d.ts +87 -1
  454. package/dist/services/assets/r2.js +203 -1
  455. package/dist/services/assets/r2.js.map +1 -1
  456. package/dist/services/auth-service.d.ts +350 -36
  457. package/dist/services/auth-service.js +1179 -140
  458. package/dist/services/auth-service.js.map +1 -1
  459. package/dist/services/bookmark-import-service.d.ts +49 -0
  460. package/dist/services/bookmark-import-service.js +250 -0
  461. package/dist/services/bookmark-import-service.js.map +1 -0
  462. package/dist/services/chat-session-service.d.ts +96 -0
  463. package/dist/services/chat-session-service.js +316 -0
  464. package/dist/services/chat-session-service.js.map +1 -0
  465. package/dist/services/cloud-inference-billing.d.ts +64 -0
  466. package/dist/services/cloud-inference-billing.js +313 -0
  467. package/dist/services/cloud-inference-billing.js.map +1 -0
  468. package/dist/services/comment-service.d.ts +97 -0
  469. package/dist/services/comment-service.js +341 -0
  470. package/dist/services/comment-service.js.map +1 -0
  471. package/dist/services/convert-service.d.ts +64 -0
  472. package/dist/services/convert-service.js +68 -0
  473. package/dist/services/convert-service.js.map +1 -0
  474. package/dist/services/csv-service.d.ts +22 -17
  475. package/dist/services/csv-service.js +55 -92
  476. package/dist/services/csv-service.js.map +1 -1
  477. package/dist/services/entity-mutations.d.ts +210 -0
  478. package/dist/services/entity-mutations.js +377 -0
  479. package/dist/services/entity-mutations.js.map +1 -0
  480. package/dist/services/event-processor.d.ts +104 -0
  481. package/dist/services/event-processor.js +441 -0
  482. package/dist/services/event-processor.js.map +1 -0
  483. package/dist/services/extract/docx.d.ts +1 -0
  484. package/dist/services/extract/docx.js +233 -0
  485. package/dist/services/extract/docx.js.map +1 -0
  486. package/dist/services/extract/index.d.ts +9 -0
  487. package/dist/services/extract/index.js +10 -0
  488. package/dist/services/extract/index.js.map +1 -0
  489. package/dist/services/extract/pdf.d.ts +13 -0
  490. package/dist/services/extract/pdf.js +69 -0
  491. package/dist/services/extract/pdf.js.map +1 -0
  492. package/dist/services/folder-creation.d.ts +33 -0
  493. package/dist/services/folder-creation.js +103 -0
  494. package/dist/services/folder-creation.js.map +1 -0
  495. package/dist/services/git.d.ts +54 -0
  496. package/dist/services/git.js +188 -54
  497. package/dist/services/git.js.map +1 -1
  498. package/dist/services/graph-maintenance.d.ts +42 -0
  499. package/dist/services/graph-maintenance.js +143 -0
  500. package/dist/services/graph-maintenance.js.map +1 -0
  501. package/dist/services/import-service.d.ts +58 -3
  502. package/dist/services/import-service.js +316 -100
  503. package/dist/services/import-service.js.map +1 -1
  504. package/dist/services/lint-service.js +10 -17
  505. package/dist/services/lint-service.js.map +1 -1
  506. package/dist/services/markdown.d.ts +12 -1
  507. package/dist/services/markdown.js +77 -9
  508. package/dist/services/markdown.js.map +1 -1
  509. package/dist/services/memory-service.d.ts +22 -14
  510. package/dist/services/memory-service.js +53 -35
  511. package/dist/services/memory-service.js.map +1 -1
  512. package/dist/services/mention-detector.d.ts +23 -0
  513. package/dist/services/mention-detector.js +47 -0
  514. package/dist/services/mention-detector.js.map +1 -0
  515. package/dist/services/model-capabilities.d.ts +41 -0
  516. package/dist/services/model-capabilities.js +107 -0
  517. package/dist/services/model-capabilities.js.map +1 -0
  518. package/dist/services/notification-broadcast.d.ts +32 -0
  519. package/dist/services/notification-broadcast.js +38 -0
  520. package/dist/services/notification-broadcast.js.map +1 -0
  521. package/dist/services/notification-service.d.ts +41 -0
  522. package/dist/services/notification-service.js +100 -0
  523. package/dist/services/notification-service.js.map +1 -0
  524. package/dist/services/oauth-server-store.d.ts +147 -0
  525. package/dist/services/oauth-server-store.js +319 -0
  526. package/dist/services/oauth-server-store.js.map +1 -0
  527. package/dist/services/orphan-service.js +2 -2
  528. package/dist/services/orphan-service.js.map +1 -1
  529. package/dist/services/personal-folder.d.ts +40 -0
  530. package/dist/services/personal-folder.js +101 -0
  531. package/dist/services/personal-folder.js.map +1 -0
  532. package/dist/services/share-link-service.d.ts +57 -0
  533. package/dist/services/share-link-service.js +142 -0
  534. package/dist/services/share-link-service.js.map +1 -0
  535. package/dist/services/user-person-bridge.d.ts +136 -0
  536. package/dist/services/user-person-bridge.js +340 -0
  537. package/dist/services/user-person-bridge.js.map +1 -0
  538. package/dist/services/vector-service.d.ts +260 -6
  539. package/dist/services/vector-service.js +574 -31
  540. package/dist/services/vector-service.js.map +1 -1
  541. package/dist/services/workspace-access.d.ts +108 -0
  542. package/dist/services/workspace-access.js +149 -0
  543. package/dist/services/workspace-access.js.map +1 -0
  544. package/dist/services/workspace-assets-folder.d.ts +46 -0
  545. package/dist/services/workspace-assets-folder.js +75 -0
  546. package/dist/services/workspace-assets-folder.js.map +1 -0
  547. package/dist/utils/git.d.ts +17 -2
  548. package/dist/utils/git.js +23 -7
  549. package/dist/utils/git.js.map +1 -1
  550. package/dist/utils/log.d.ts +42 -0
  551. package/dist/utils/log.js +137 -0
  552. package/dist/utils/log.js.map +1 -0
  553. package/dist/utils/preflight.js +2 -2
  554. package/dist/utils/preflight.js.map +1 -1
  555. package/dist/utils/version-checker.d.ts +12 -19
  556. package/dist/utils/version-checker.js +14 -104
  557. package/dist/utils/version-checker.js.map +1 -1
  558. package/dist/web/_app/immutable/assets/0.BZHoBJEc.css +2 -0
  559. package/dist/web/_app/immutable/assets/12.DlIf1mKh.css +1 -0
  560. package/dist/web/_app/immutable/assets/13.7d-Q37wc.css +1 -0
  561. package/dist/web/_app/immutable/assets/14.BwBFdc1D.css +1 -0
  562. package/dist/web/_app/immutable/assets/15.CmLrbzZp.css +1 -0
  563. package/dist/web/_app/immutable/assets/16.B0GwXar3.css +1 -0
  564. package/dist/web/_app/immutable/assets/2.C9Vt4JHy.css +1 -0
  565. package/dist/web/_app/immutable/assets/3.BFvgCYSk.css +1 -0
  566. package/dist/web/_app/immutable/assets/4.OmdYF47-.css +1 -0
  567. package/dist/web/_app/immutable/assets/5.C6MySjPq.css +1 -0
  568. package/dist/web/_app/immutable/assets/BulkActionsBar.Bx7nxMjH.css +1 -0
  569. package/dist/web/_app/immutable/assets/CalendarView.lBCvS3X5.css +1 -0
  570. package/dist/web/_app/immutable/assets/CodeMirrorEditor.D6hf2pNJ.css +1 -0
  571. package/dist/web/_app/immutable/assets/CopyField.DVGZtw4U.css +1 -0
  572. package/dist/web/_app/immutable/assets/FolderMembersPanel.DX1oBeF_.css +1 -0
  573. package/dist/web/_app/immutable/assets/FolderMutationDialogs.D2B7KrRn.css +1 -0
  574. package/dist/web/_app/immutable/assets/FolderPicker.B5KdvRYl.css +1 -0
  575. package/dist/web/_app/immutable/assets/GalleryView.CF48FWYQ.css +1 -0
  576. package/dist/web/_app/immutable/assets/GraphView.BJtGL9py.css +1 -0
  577. package/dist/web/_app/immutable/assets/KanbanView.BOaI5KFL.css +1 -0
  578. package/dist/web/_app/immutable/assets/Link.vV0ne105.css +1 -0
  579. package/dist/web/_app/immutable/assets/Markdown.BqgpZCv5.css +1 -0
  580. package/dist/web/_app/immutable/assets/Rail.f8lsriOT.css +1 -0
  581. package/dist/web/_app/immutable/assets/SettingsDialog.DwMus2u2.css +1 -0
  582. package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
  583. package/dist/web/_app/immutable/assets/StopFilledAlt.fNlDN65D.css +1 -0
  584. package/dist/web/_app/immutable/assets/TimelineView.DriOGAKB.css +1 -0
  585. package/dist/web/_app/immutable/assets/WorkspaceView.u5VdwRR6.css +1 -0
  586. package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
  587. package/dist/web/_app/immutable/assets/checkbox.DK0MgYgb.css +1 -0
  588. package/dist/web/_app/immutable/assets/dist.DDCWxn3B.css +1 -0
  589. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff +0 -0
  590. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2 +0 -0
  591. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff +0 -0
  592. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2 +0 -0
  593. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CZTNEAuW.woff2 +0 -0
  594. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CsGl1sm0.woff +0 -0
  595. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2 +0 -0
  596. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff +0 -0
  597. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.BNK2_mGO.woff2 +0 -0
  598. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.DpEwFAQM.woff +0 -0
  599. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2 +0 -0
  600. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff +0 -0
  601. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff +0 -0
  602. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2 +0 -0
  603. package/dist/web/_app/immutable/assets/inline-list.cqga56xT.css +1 -0
  604. package/dist/web/_app/immutable/assets/list-columns.DiLB0G5L.css +1 -0
  605. package/dist/web/_app/immutable/assets/select.BFL238eD.css +1 -0
  606. package/dist/web/_app/immutable/assets/sheet.4rY4hpfJ.css +1 -0
  607. package/dist/web/_app/immutable/chunks/2oYV6q4R.js +2 -0
  608. package/dist/web/_app/immutable/chunks/4XSri7g0.js +1 -0
  609. package/dist/web/_app/immutable/chunks/4iaT0dG72.js +1 -0
  610. package/dist/web/_app/immutable/chunks/5_TKU9QS2.js +1 -0
  611. package/dist/web/_app/immutable/chunks/8Yh26Z9_2.js +1 -0
  612. package/dist/web/_app/immutable/chunks/Atl8xKOm.js +2 -0
  613. package/dist/web/_app/immutable/chunks/B-Z_xZy_.js +4 -0
  614. package/dist/web/_app/immutable/chunks/B0pk0Lyx.js +1 -0
  615. package/dist/web/_app/immutable/chunks/B1RnjnNt.js +1 -0
  616. package/dist/web/_app/immutable/chunks/B2n86UNJ.js +1 -0
  617. package/dist/web/_app/immutable/chunks/B318GEUB2.js +1 -0
  618. package/dist/web/_app/immutable/chunks/B6Lt-qaJ.js +1 -0
  619. package/dist/web/_app/immutable/chunks/B8yrQWxT2.js +1 -0
  620. package/dist/web/_app/immutable/chunks/BADt8daH.js +2 -0
  621. package/dist/web/_app/immutable/chunks/BBGt-XQo.js +3 -0
  622. package/dist/web/_app/immutable/chunks/BDIUHcEz.js +1 -0
  623. package/dist/web/_app/immutable/chunks/BDSuq3KH.js +1 -0
  624. package/dist/web/_app/immutable/chunks/BGiLU5VN.js +1 -0
  625. package/dist/web/_app/immutable/chunks/BJgOZTHR.js +1 -0
  626. package/dist/web/_app/immutable/chunks/BOSiTh-42.js +1 -0
  627. package/dist/web/_app/immutable/chunks/BPxcCdjn.js +1 -0
  628. package/dist/web/_app/immutable/chunks/BVPNAzAK.js +1 -0
  629. package/dist/web/_app/immutable/chunks/BcOvJgjM.js +1 -0
  630. package/dist/web/_app/immutable/chunks/BdYQewoD.js +1 -0
  631. package/dist/web/_app/immutable/chunks/BfCWIy8t.js +8 -0
  632. package/dist/web/_app/immutable/chunks/BgRT-K6w.js +5 -0
  633. package/dist/web/_app/immutable/chunks/BibveGGd.js +1 -0
  634. package/dist/web/_app/immutable/chunks/BmM5VZ4W.js +1 -0
  635. package/dist/web/_app/immutable/chunks/BnIYzuS1.js +66 -0
  636. package/dist/web/_app/immutable/chunks/BoDmwOTJ.js +1 -0
  637. package/dist/web/_app/immutable/chunks/BoglwbZW.js +1 -0
  638. package/dist/web/_app/immutable/chunks/Bqm_YrIg2.js +23 -0
  639. package/dist/web/_app/immutable/chunks/BtMRrdc4.js +2 -0
  640. package/dist/web/_app/immutable/chunks/C-AnzvKr.js +7 -0
  641. package/dist/web/_app/immutable/chunks/C1Y3tUpz.js +1 -0
  642. package/dist/web/_app/immutable/chunks/C6VZhhwF.js +1 -0
  643. package/dist/web/_app/immutable/chunks/C8IMrD4G2.js +3 -0
  644. package/dist/web/_app/immutable/chunks/CAXXrbj52.js +1 -0
  645. package/dist/web/_app/immutable/chunks/CB-0u-Pc2.js +1 -0
  646. package/dist/web/_app/immutable/chunks/CEniyZ1Z2.js +6 -0
  647. package/dist/web/_app/immutable/chunks/CJhElIkU2.js +1 -0
  648. package/dist/web/_app/immutable/chunks/CK8tIaYT.js +1 -0
  649. package/dist/web/_app/immutable/chunks/CM8uYli8.js +1 -0
  650. package/dist/web/_app/immutable/chunks/CTzjJm_m2.js +1 -0
  651. package/dist/web/_app/immutable/chunks/CUXqa1nn2.js +1 -0
  652. package/dist/web/_app/immutable/chunks/CY0iY_WO.js +1 -0
  653. package/dist/web/_app/immutable/chunks/CbCfNNV_2.js +2692 -0
  654. package/dist/web/_app/immutable/chunks/CbuGIyDu2.js +22 -0
  655. package/dist/web/_app/immutable/chunks/CcRGXA-t.js +1 -0
  656. package/dist/web/_app/immutable/chunks/CcXmQaYs2.js +1 -0
  657. package/dist/web/_app/immutable/chunks/CcaQuaSt2.js +1 -0
  658. package/dist/web/_app/immutable/chunks/CoHaBDpN2.js +2 -0
  659. package/dist/web/_app/immutable/chunks/Cvbd3myc2.js +14 -0
  660. package/dist/web/_app/immutable/chunks/D20C1thX2.js +1 -0
  661. package/dist/web/_app/immutable/chunks/D3JoMtWC.js +7 -0
  662. package/dist/web/_app/immutable/chunks/D3ch71s_.js +1 -0
  663. package/dist/web/_app/immutable/chunks/D4xXlMEU.js +2 -0
  664. package/dist/web/_app/immutable/chunks/D5GipQqN2.js +1 -0
  665. package/dist/web/_app/immutable/chunks/D9TyJuu_.js +1 -0
  666. package/dist/web/_app/immutable/chunks/DBFijAmG.js +1 -0
  667. package/dist/web/_app/immutable/chunks/DHLjkH7T.js +1 -0
  668. package/dist/web/_app/immutable/chunks/DIfdPIt_2.js +1 -0
  669. package/dist/web/_app/immutable/chunks/DO_sw49q2.js +1 -0
  670. package/dist/web/_app/immutable/chunks/DP69PpIj.js +1 -0
  671. package/dist/web/_app/immutable/chunks/DQ3HSZMs.js +2 -0
  672. package/dist/web/_app/immutable/chunks/DQMWa2t7.js +1 -0
  673. package/dist/web/_app/immutable/chunks/DT0wzK622.js +1 -0
  674. package/dist/web/_app/immutable/chunks/DTnEJArL.js +1 -0
  675. package/dist/web/_app/immutable/chunks/DToS-G202.js +1 -0
  676. package/dist/web/_app/immutable/chunks/DZcU6mGe2.js +1 -0
  677. package/dist/web/_app/immutable/chunks/DbslMybD.js +1 -0
  678. package/dist/web/_app/immutable/chunks/DcGThsSF.js +1 -0
  679. package/dist/web/_app/immutable/chunks/DcPrzUMJ.js +1 -0
  680. package/dist/web/_app/immutable/chunks/De0g5qop2.js +1 -0
  681. package/dist/web/_app/immutable/chunks/DimS8dbZ2.js +1 -0
  682. package/dist/web/_app/immutable/chunks/DjuqhOjF.js +1 -0
  683. package/dist/web/_app/immutable/chunks/Dk6sAhpo.js +3 -0
  684. package/dist/web/_app/immutable/chunks/Dl6cnwyk.js +1 -0
  685. package/dist/web/_app/immutable/chunks/DnIQzIOz.js +1 -0
  686. package/dist/web/_app/immutable/chunks/DnXYAo60.js +1 -0
  687. package/dist/web/_app/immutable/chunks/DnrImJan.js +1 -0
  688. package/dist/web/_app/immutable/chunks/Dpuq25vu2.js +1 -0
  689. package/dist/web/_app/immutable/chunks/DrMZDWru.js +1 -0
  690. package/dist/web/_app/immutable/chunks/DsVOtl0N.js +1 -0
  691. package/dist/web/_app/immutable/chunks/DuTXsWdP.js +2 -0
  692. package/dist/web/_app/immutable/chunks/Dw-frCfE.js +1 -0
  693. package/dist/web/_app/immutable/chunks/Dz34u8Ie2.js +185 -0
  694. package/dist/web/_app/immutable/chunks/DzcFeQZU2.js +2 -0
  695. package/dist/web/_app/immutable/chunks/DzrRTvug.js +1 -0
  696. package/dist/web/_app/immutable/chunks/G5oUVQa92.js +1 -0
  697. package/dist/web/_app/immutable/chunks/HyhOhoeq2.js +2 -0
  698. package/dist/web/_app/immutable/chunks/J5nb9xxj.js +1 -0
  699. package/dist/web/_app/immutable/chunks/JCjEwqH9.js +1 -0
  700. package/dist/web/_app/immutable/chunks/JN_nsXUm2.js +1 -0
  701. package/dist/web/_app/immutable/chunks/JS2_GaB1.js +1 -0
  702. package/dist/web/_app/immutable/chunks/MtI6dyxu.js +1 -0
  703. package/dist/web/_app/immutable/chunks/N6vnY5Si2.js +1 -0
  704. package/dist/web/_app/immutable/chunks/PcEbaKam.js +2 -0
  705. package/dist/web/_app/immutable/chunks/VTYhCLh9.js +2 -0
  706. package/dist/web/_app/immutable/chunks/Wowi_89k.js +5 -0
  707. package/dist/web/_app/immutable/chunks/Y_asqJqs2.js +83 -0
  708. package/dist/web/_app/immutable/chunks/Yhg5Q4MT.js +1 -0
  709. package/dist/web/_app/immutable/chunks/f_eYccPf2.js +1 -0
  710. package/dist/web/_app/immutable/chunks/hm_8RsuL.js +1 -0
  711. package/dist/web/_app/immutable/chunks/iPCkjliu.js +3 -0
  712. package/dist/web/_app/immutable/chunks/j2AvgZGz.js +1 -0
  713. package/dist/web/_app/immutable/chunks/kNaey6uv.js +1 -0
  714. package/dist/web/_app/immutable/chunks/l1761xxj.js +1 -0
  715. package/dist/web/_app/immutable/chunks/liGRFQqV2.js +184 -0
  716. package/dist/web/_app/immutable/chunks/lq1kR86d.js +1 -0
  717. package/dist/web/_app/immutable/chunks/mIykYR4F2.js +1 -0
  718. package/dist/web/_app/immutable/chunks/rbhlO_t8.js +1 -0
  719. package/dist/web/_app/immutable/chunks/tJpAwaTl.js +1 -0
  720. package/dist/web/_app/immutable/chunks/tcegdii0.js +2 -0
  721. package/dist/web/_app/immutable/chunks/u8G2EUvz2.js +224 -0
  722. package/dist/web/_app/immutable/chunks/vgsM0KTm2.js +1 -0
  723. package/dist/web/_app/immutable/chunks/xcGI4fuV.js +1 -0
  724. package/dist/web/_app/immutable/chunks/xihTtKlq.js +1 -0
  725. package/dist/web/_app/immutable/chunks/yEYlhV9G2.js +1 -0
  726. package/dist/web/_app/immutable/entry/app.DSf_XGp8.js +2 -0
  727. package/dist/web/_app/immutable/entry/start.B7ScfxPc.js +1 -0
  728. package/dist/web/_app/immutable/nodes/0.BMSOOETY.js +2 -0
  729. package/dist/web/_app/immutable/nodes/1.B0lBUpHt.js +1 -0
  730. package/dist/web/_app/immutable/nodes/10.DmDbUH1j.js +1 -0
  731. package/dist/web/_app/immutable/nodes/11.gwY7gZdR.js +1 -0
  732. package/dist/web/_app/immutable/nodes/12.BpGHSr2y.js +1 -0
  733. package/dist/web/_app/immutable/nodes/13.Bf178QF_.js +1 -0
  734. package/dist/web/_app/immutable/nodes/14.D_x8-nk9.js +1 -0
  735. package/dist/web/_app/immutable/nodes/15.DY4XeagL.js +1 -0
  736. package/dist/web/_app/immutable/nodes/16.DPqftx8x.js +77 -0
  737. package/dist/web/_app/immutable/nodes/2.OM2LGRpi.js +109 -0
  738. package/dist/web/_app/immutable/nodes/3.e8ZoPCmC.js +6 -0
  739. package/dist/web/_app/immutable/nodes/4.BdYR1hNQ.js +11 -0
  740. package/dist/web/_app/immutable/nodes/5.B8sOFna9.js +5 -0
  741. package/dist/web/_app/immutable/nodes/6.L1BbYsmo.js +1 -0
  742. package/dist/web/_app/immutable/nodes/7.B7zoemJD.js +1 -0
  743. package/dist/web/_app/immutable/nodes/8.B1VtnfMK.js +1 -0
  744. package/dist/web/_app/immutable/nodes/9.BE3VCQzk.js +1 -0
  745. package/dist/web/_app/version.json +1 -1
  746. package/dist/web/favicon-16.png +0 -0
  747. package/dist/web/favicon-180.png +0 -0
  748. package/dist/web/favicon-32.png +0 -0
  749. package/dist/web/favicon-48.png +0 -0
  750. package/dist/web/favicon-512.png +0 -0
  751. package/dist/web/favicon.ico +0 -0
  752. package/dist/web/favicon.svg +8 -0
  753. package/dist/web/index.html +58 -19
  754. package/dist/web/studiograph-logomark.svg +29 -0
  755. package/package.json +38 -14
  756. package/dist/agent/skills/enrich-entities.md +0 -136
  757. package/dist/agent/skills/obsidian-source-setup.md +0 -246
  758. package/dist/agent/skills/skill-loader.d.ts +0 -48
  759. package/dist/agent/skills/skill-loader.js +0 -166
  760. package/dist/agent/skills/skill-loader.js.map +0 -1
  761. package/dist/agent/skills/sync-configuration.md +0 -119
  762. package/dist/agent/skills/sync-setup.md +0 -82
  763. package/dist/agent/tools/sync-tools.d.ts +0 -35
  764. package/dist/agent/tools/sync-tools.js +0 -992
  765. package/dist/agent/tools/sync-tools.js.map +0 -1
  766. package/dist/auth/github.d.ts +0 -56
  767. package/dist/auth/github.js +0 -169
  768. package/dist/auth/github.js.map +0 -1
  769. package/dist/cli/commands/access.d.ts +0 -11
  770. package/dist/cli/commands/access.js +0 -156
  771. package/dist/cli/commands/access.js.map +0 -1
  772. package/dist/cli/commands/app.d.ts +0 -7
  773. package/dist/cli/commands/app.js +0 -268
  774. package/dist/cli/commands/app.js.map +0 -1
  775. package/dist/cli/commands/auth.d.ts +0 -10
  776. package/dist/cli/commands/auth.js +0 -79
  777. package/dist/cli/commands/auth.js.map +0 -1
  778. package/dist/cli/commands/clear.d.ts +0 -5
  779. package/dist/cli/commands/clear.js +0 -36
  780. package/dist/cli/commands/clear.js.map +0 -1
  781. package/dist/cli/commands/collection.d.ts +0 -10
  782. package/dist/cli/commands/collection.js +0 -187
  783. package/dist/cli/commands/collection.js.map +0 -1
  784. package/dist/cli/commands/enrich.d.ts +0 -11
  785. package/dist/cli/commands/enrich.js +0 -135
  786. package/dist/cli/commands/enrich.js.map +0 -1
  787. package/dist/cli/commands/graphrag.d.ts +0 -12
  788. package/dist/cli/commands/graphrag.js +0 -122
  789. package/dist/cli/commands/graphrag.js.map +0 -1
  790. package/dist/cli/commands/join.d.ts +0 -9
  791. package/dist/cli/commands/join.js +0 -255
  792. package/dist/cli/commands/join.js.map +0 -1
  793. package/dist/cli/commands/members.d.ts +0 -11
  794. package/dist/cli/commands/members.js +0 -230
  795. package/dist/cli/commands/members.js.map +0 -1
  796. package/dist/cli/commands/org.d.ts +0 -10
  797. package/dist/cli/commands/org.js +0 -132
  798. package/dist/cli/commands/org.js.map +0 -1
  799. package/dist/cli/commands/provision.d.ts +0 -8
  800. package/dist/cli/commands/provision.js +0 -116
  801. package/dist/cli/commands/provision.js.map +0 -1
  802. package/dist/cli/commands/resolve.d.ts +0 -8
  803. package/dist/cli/commands/resolve.js +0 -85
  804. package/dist/cli/commands/resolve.js.map +0 -1
  805. package/dist/cli/commands/review.d.ts +0 -19
  806. package/dist/cli/commands/review.js +0 -128
  807. package/dist/cli/commands/review.js.map +0 -1
  808. package/dist/cli/commands/source.d.ts +0 -16
  809. package/dist/cli/commands/source.js +0 -159
  810. package/dist/cli/commands/source.js.map +0 -1
  811. package/dist/cli/commands/start.d.ts +0 -7
  812. package/dist/cli/commands/start.js +0 -589
  813. package/dist/cli/commands/start.js.map +0 -1
  814. package/dist/cli/commands/sync-collection.d.ts +0 -14
  815. package/dist/cli/commands/sync-collection.js +0 -355
  816. package/dist/cli/commands/sync-collection.js.map +0 -1
  817. package/dist/cli/commands/sync-entities.d.ts +0 -13
  818. package/dist/cli/commands/sync-entities.js +0 -242
  819. package/dist/cli/commands/sync-entities.js.map +0 -1
  820. package/dist/cli/commands/team.d.ts +0 -12
  821. package/dist/cli/commands/team.js +0 -185
  822. package/dist/cli/commands/team.js.map +0 -1
  823. package/dist/cli/commands/update.d.ts +0 -8
  824. package/dist/cli/commands/update.js +0 -155
  825. package/dist/cli/commands/update.js.map +0 -1
  826. package/dist/cli/commands/user.d.ts +0 -7
  827. package/dist/cli/commands/user.js +0 -153
  828. package/dist/cli/commands/user.js.map +0 -1
  829. package/dist/cli/scaffolding.d.ts +0 -12
  830. package/dist/cli/scaffolding.js +0 -397
  831. package/dist/cli/scaffolding.js.map +0 -1
  832. package/dist/cli/sync-review-interactive.d.ts +0 -31
  833. package/dist/cli/sync-review-interactive.js +0 -393
  834. package/dist/cli/sync-review-interactive.js.map +0 -1
  835. package/dist/core/migration-runner.d.ts +0 -42
  836. package/dist/core/migration-runner.js +0 -232
  837. package/dist/core/migration-runner.js.map +0 -1
  838. package/dist/core/migration-types.d.ts +0 -101
  839. package/dist/core/migration-types.js +0 -21
  840. package/dist/core/migration-types.js.map +0 -1
  841. package/dist/core/migrations/20260219-formalize-memory-location.d.ts +0 -2
  842. package/dist/core/migrations/20260219-formalize-memory-location.js +0 -35
  843. package/dist/core/migrations/20260219-formalize-memory-location.js.map +0 -1
  844. package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +0 -12
  845. package/dist/core/migrations/20260220-add-workspace-metadata.js +0 -65
  846. package/dist/core/migrations/20260220-add-workspace-metadata.js.map +0 -1
  847. package/dist/core/migrations/20260220-add-workspace-readme.d.ts +0 -11
  848. package/dist/core/migrations/20260220-add-workspace-readme.js +0 -82
  849. package/dist/core/migrations/20260220-add-workspace-readme.js.map +0 -1
  850. package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +0 -9
  851. package/dist/core/migrations/20260220-migrate-yaml-to-json.js +0 -64
  852. package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +0 -1
  853. package/dist/core/migrations/index.d.ts +0 -11
  854. package/dist/core/migrations/index.js +0 -23
  855. package/dist/core/migrations/index.js.map +0 -1
  856. package/dist/integrations/asana.d.ts +0 -26
  857. package/dist/integrations/asana.js +0 -78
  858. package/dist/integrations/asana.js.map +0 -1
  859. package/dist/integrations/figma-local.d.ts +0 -16
  860. package/dist/integrations/figma-local.js +0 -10
  861. package/dist/integrations/figma-local.js.map +0 -1
  862. package/dist/integrations/figma.d.ts +0 -17
  863. package/dist/integrations/figma.js +0 -17
  864. package/dist/integrations/figma.js.map +0 -1
  865. package/dist/integrations/granola.d.ts +0 -24
  866. package/dist/integrations/granola.js +0 -60
  867. package/dist/integrations/granola.js.map +0 -1
  868. package/dist/integrations/linear.d.ts +0 -14
  869. package/dist/integrations/linear.js +0 -80
  870. package/dist/integrations/linear.js.map +0 -1
  871. package/dist/integrations/paper-local.d.ts +0 -14
  872. package/dist/integrations/paper-local.js +0 -10
  873. package/dist/integrations/paper-local.js.map +0 -1
  874. package/dist/integrations/paper.d.ts +0 -2
  875. package/dist/integrations/paper.js +0 -10
  876. package/dist/integrations/paper.js.map +0 -1
  877. package/dist/integrations/pipedrive.d.ts +0 -26
  878. package/dist/integrations/pipedrive.js +0 -97
  879. package/dist/integrations/pipedrive.js.map +0 -1
  880. package/dist/integrations/registry.d.ts +0 -15
  881. package/dist/integrations/registry.js +0 -27
  882. package/dist/integrations/registry.js.map +0 -1
  883. package/dist/integrations/types.d.ts +0 -38
  884. package/dist/integrations/types.js +0 -9
  885. package/dist/integrations/types.js.map +0 -1
  886. package/dist/lib/lib/utils.d.ts +0 -2
  887. package/dist/lib/lib/utils.js +0 -6
  888. package/dist/lib/lib/utils.js.map +0 -1
  889. package/dist/mcp/connectors/asana.d.ts +0 -2
  890. package/dist/mcp/connectors/asana.js +0 -20
  891. package/dist/mcp/connectors/asana.js.map +0 -1
  892. package/dist/mcp/connectors/definitions.d.ts +0 -45
  893. package/dist/mcp/connectors/definitions.js +0 -32
  894. package/dist/mcp/connectors/definitions.js.map +0 -1
  895. package/dist/mcp/connectors/figma.d.ts +0 -5
  896. package/dist/mcp/connectors/figma.js +0 -21
  897. package/dist/mcp/connectors/figma.js.map +0 -1
  898. package/dist/mcp/connectors/gdrive.d.ts +0 -2
  899. package/dist/mcp/connectors/gdrive.js +0 -20
  900. package/dist/mcp/connectors/gdrive.js.map +0 -1
  901. package/dist/mcp/connectors/granola.d.ts +0 -2
  902. package/dist/mcp/connectors/granola.js +0 -12
  903. package/dist/mcp/connectors/granola.js.map +0 -1
  904. package/dist/mcp/connectors/linear.d.ts +0 -2
  905. package/dist/mcp/connectors/linear.js +0 -19
  906. package/dist/mcp/connectors/linear.js.map +0 -1
  907. package/dist/mcp/connectors/obsidian.d.ts +0 -2
  908. package/dist/mcp/connectors/obsidian.js +0 -19
  909. package/dist/mcp/connectors/obsidian.js.map +0 -1
  910. package/dist/mcp/connectors/pipedrive.d.ts +0 -2
  911. package/dist/mcp/connectors/pipedrive.js +0 -20
  912. package/dist/mcp/connectors/pipedrive.js.map +0 -1
  913. package/dist/mcp/connectors/slack.d.ts +0 -2
  914. package/dist/mcp/connectors/slack.js +0 -21
  915. package/dist/mcp/connectors/slack.js.map +0 -1
  916. package/dist/mcp/server-oauth-provider.d.ts +0 -56
  917. package/dist/mcp/server-oauth-provider.js +0 -142
  918. package/dist/mcp/server-oauth-provider.js.map +0 -1
  919. package/dist/server/chrome/chrome.css +0 -691
  920. package/dist/server/chrome/chrome.js +0 -374
  921. package/dist/server/collab-authority.d.ts +0 -70
  922. package/dist/server/collab-authority.js +0 -218
  923. package/dist/server/collab-authority.js.map +0 -1
  924. package/dist/server/collab.d.ts +0 -29
  925. package/dist/server/collab.js +0 -195
  926. package/dist/server/collab.js.map +0 -1
  927. package/dist/server/commit-scheduler.d.ts +0 -39
  928. package/dist/server/commit-scheduler.js +0 -113
  929. package/dist/server/commit-scheduler.js.map +0 -1
  930. package/dist/server/plugin-loader.d.ts +0 -53
  931. package/dist/server/plugin-loader.js +0 -155
  932. package/dist/server/plugin-loader.js.map +0 -1
  933. package/dist/server/routes/collab.d.ts +0 -6
  934. package/dist/server/routes/collab.js +0 -10
  935. package/dist/server/routes/collab.js.map +0 -1
  936. package/dist/server/routes/git-api.d.ts +0 -9
  937. package/dist/server/routes/git-api.js +0 -82
  938. package/dist/server/routes/git-api.js.map +0 -1
  939. package/dist/server/routes/meeting-ingest-api.d.ts +0 -15
  940. package/dist/server/routes/meeting-ingest-api.js +0 -323
  941. package/dist/server/routes/meeting-ingest-api.js.map +0 -1
  942. package/dist/server/routes/sync-api.d.ts +0 -26
  943. package/dist/server/routes/sync-api.js +0 -814
  944. package/dist/server/routes/sync-api.js.map +0 -1
  945. package/dist/server/routes/webhook.d.ts +0 -14
  946. package/dist/server/routes/webhook.js +0 -102
  947. package/dist/server/routes/webhook.js.map +0 -1
  948. package/dist/services/github-provisioner.d.ts +0 -36
  949. package/dist/services/github-provisioner.js +0 -126
  950. package/dist/services/github-provisioner.js.map +0 -1
  951. package/dist/services/github-service.d.ts +0 -99
  952. package/dist/services/github-service.js +0 -310
  953. package/dist/services/github-service.js.map +0 -1
  954. package/dist/services/insights.d.ts +0 -38
  955. package/dist/services/insights.js +0 -246
  956. package/dist/services/insights.js.map +0 -1
  957. package/dist/services/sync/collection-sync.d.ts +0 -60
  958. package/dist/services/sync/collection-sync.js +0 -509
  959. package/dist/services/sync/collection-sync.js.map +0 -1
  960. package/dist/services/sync/commit.d.ts +0 -60
  961. package/dist/services/sync/commit.js +0 -354
  962. package/dist/services/sync/commit.js.map +0 -1
  963. package/dist/services/sync/context-index.d.ts +0 -69
  964. package/dist/services/sync/context-index.js +0 -280
  965. package/dist/services/sync/context-index.js.map +0 -1
  966. package/dist/services/sync/data-fetcher.d.ts +0 -31
  967. package/dist/services/sync/data-fetcher.js +0 -12
  968. package/dist/services/sync/data-fetcher.js.map +0 -1
  969. package/dist/services/sync/derive.d.ts +0 -34
  970. package/dist/services/sync/derive.js +0 -164
  971. package/dist/services/sync/derive.js.map +0 -1
  972. package/dist/services/sync/enrichment-state.d.ts +0 -31
  973. package/dist/services/sync/enrichment-state.js +0 -63
  974. package/dist/services/sync/enrichment-state.js.map +0 -1
  975. package/dist/services/sync/enrichment.d.ts +0 -25
  976. package/dist/services/sync/enrichment.js +0 -121
  977. package/dist/services/sync/enrichment.js.map +0 -1
  978. package/dist/services/sync/entity-refresh.d.ts +0 -30
  979. package/dist/services/sync/entity-refresh.js +0 -275
  980. package/dist/services/sync/entity-refresh.js.map +0 -1
  981. package/dist/services/sync/frontmatter-extractor.d.ts +0 -40
  982. package/dist/services/sync/frontmatter-extractor.js +0 -279
  983. package/dist/services/sync/frontmatter-extractor.js.map +0 -1
  984. package/dist/services/sync/graph-match-state.d.ts +0 -33
  985. package/dist/services/sync/graph-match-state.js +0 -61
  986. package/dist/services/sync/graph-match-state.js.map +0 -1
  987. package/dist/services/sync/graph-match.d.ts +0 -53
  988. package/dist/services/sync/graph-match.js +0 -316
  989. package/dist/services/sync/graph-match.js.map +0 -1
  990. package/dist/services/sync/graphrag-client.d.ts +0 -43
  991. package/dist/services/sync/graphrag-client.js +0 -94
  992. package/dist/services/sync/graphrag-client.js.map +0 -1
  993. package/dist/services/sync/graphrag-config.d.ts +0 -16
  994. package/dist/services/sync/graphrag-config.js +0 -39
  995. package/dist/services/sync/graphrag-config.js.map +0 -1
  996. package/dist/services/sync/graphrag-context.d.ts +0 -14
  997. package/dist/services/sync/graphrag-context.js +0 -109
  998. package/dist/services/sync/graphrag-context.js.map +0 -1
  999. package/dist/services/sync/graphrag-indexer.d.ts +0 -30
  1000. package/dist/services/sync/graphrag-indexer.js +0 -358
  1001. package/dist/services/sync/graphrag-indexer.js.map +0 -1
  1002. package/dist/services/sync/llm.d.ts +0 -32
  1003. package/dist/services/sync/llm.js +0 -115
  1004. package/dist/services/sync/llm.js.map +0 -1
  1005. package/dist/services/sync/mcp-client.d.ts +0 -71
  1006. package/dist/services/sync/mcp-client.js +0 -299
  1007. package/dist/services/sync/mcp-client.js.map +0 -1
  1008. package/dist/services/sync/model-factory.d.ts +0 -13
  1009. package/dist/services/sync/model-factory.js +0 -38
  1010. package/dist/services/sync/model-factory.js.map +0 -1
  1011. package/dist/services/sync/name-quality.d.ts +0 -31
  1012. package/dist/services/sync/name-quality.js +0 -60
  1013. package/dist/services/sync/name-quality.js.map +0 -1
  1014. package/dist/services/sync/output-schemas.d.ts +0 -92
  1015. package/dist/services/sync/output-schemas.js +0 -43
  1016. package/dist/services/sync/output-schemas.js.map +0 -1
  1017. package/dist/services/sync/prompts.d.ts +0 -19
  1018. package/dist/services/sync/prompts.js +0 -128
  1019. package/dist/services/sync/prompts.js.map +0 -1
  1020. package/dist/services/sync/reconciler.d.ts +0 -48
  1021. package/dist/services/sync/reconciler.js +0 -294
  1022. package/dist/services/sync/reconciler.js.map +0 -1
  1023. package/dist/services/sync/rest-client.d.ts +0 -40
  1024. package/dist/services/sync/rest-client.js +0 -100
  1025. package/dist/services/sync/rest-client.js.map +0 -1
  1026. package/dist/services/sync/source-config.d.ts +0 -67
  1027. package/dist/services/sync/source-config.js +0 -304
  1028. package/dist/services/sync/source-config.js.map +0 -1
  1029. package/dist/services/sync/source-definitions/asana.d.ts +0 -14
  1030. package/dist/services/sync/source-definitions/asana.js +0 -42
  1031. package/dist/services/sync/source-definitions/asana.js.map +0 -1
  1032. package/dist/services/sync/source-definitions/definitions.d.ts +0 -8
  1033. package/dist/services/sync/source-definitions/definitions.js +0 -8
  1034. package/dist/services/sync/source-definitions/definitions.js.map +0 -1
  1035. package/dist/services/sync/source-definitions/gdrive.d.ts +0 -16
  1036. package/dist/services/sync/source-definitions/gdrive.js +0 -68
  1037. package/dist/services/sync/source-definitions/gdrive.js.map +0 -1
  1038. package/dist/services/sync/source-definitions/granola.d.ts +0 -2
  1039. package/dist/services/sync/source-definitions/granola.js +0 -21
  1040. package/dist/services/sync/source-definitions/granola.js.map +0 -1
  1041. package/dist/services/sync/source-definitions/linear.d.ts +0 -2
  1042. package/dist/services/sync/source-definitions/linear.js +0 -62
  1043. package/dist/services/sync/source-definitions/linear.js.map +0 -1
  1044. package/dist/services/sync/source-definitions/obsidian.d.ts +0 -2
  1045. package/dist/services/sync/source-definitions/obsidian.js +0 -55
  1046. package/dist/services/sync/source-definitions/obsidian.js.map +0 -1
  1047. package/dist/services/sync/source-definitions/pipedrive.d.ts +0 -2
  1048. package/dist/services/sync/source-definitions/pipedrive.js +0 -43
  1049. package/dist/services/sync/source-definitions/pipedrive.js.map +0 -1
  1050. package/dist/services/sync/staging.d.ts +0 -53
  1051. package/dist/services/sync/staging.js +0 -130
  1052. package/dist/services/sync/staging.js.map +0 -1
  1053. package/dist/services/sync/structured-extractor.d.ts +0 -57
  1054. package/dist/services/sync/structured-extractor.js +0 -584
  1055. package/dist/services/sync/structured-extractor.js.map +0 -1
  1056. package/dist/services/sync/sync-runner.d.ts +0 -32
  1057. package/dist/services/sync/sync-runner.js +0 -195
  1058. package/dist/services/sync/sync-runner.js.map +0 -1
  1059. package/dist/services/sync/sync-state.d.ts +0 -43
  1060. package/dist/services/sync/sync-state.js +0 -154
  1061. package/dist/services/sync/sync-state.js.map +0 -1
  1062. package/dist/services/sync/types.d.ts +0 -381
  1063. package/dist/services/sync/types.js +0 -8
  1064. package/dist/services/sync/types.js.map +0 -1
  1065. package/dist/services/sync/unstructured-extractor.d.ts +0 -27
  1066. package/dist/services/sync/unstructured-extractor.js +0 -185
  1067. package/dist/services/sync/unstructured-extractor.js.map +0 -1
  1068. package/dist/utils/merge-resolver.d.ts +0 -59
  1069. package/dist/utils/merge-resolver.js +0 -303
  1070. package/dist/utils/merge-resolver.js.map +0 -1
  1071. package/dist/utils/workspace-config.d.ts +0 -8
  1072. package/dist/utils/workspace-config.js +0 -22
  1073. package/dist/utils/workspace-config.js.map +0 -1
  1074. package/dist/web/_app/immutable/assets/0.DdizXOKi.css +0 -1
  1075. package/dist/web/_app/immutable/assets/10.BUrHkYry.css +0 -1
  1076. package/dist/web/_app/immutable/assets/2.n7-yW_Fs.css +0 -1
  1077. package/dist/web/_app/immutable/assets/3.BtaZagnv.css +0 -1
  1078. package/dist/web/_app/immutable/assets/4.DT7X0x5S.css +0 -1
  1079. package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
  1080. package/dist/web/_app/immutable/assets/6.CquhUpOu.css +0 -1
  1081. package/dist/web/_app/immutable/assets/7.CjbDRbuG.css +0 -1
  1082. package/dist/web/_app/immutable/assets/8.S1QdUGNM.css +0 -1
  1083. package/dist/web/_app/immutable/assets/9.CT4xL4K3.css +0 -1
  1084. package/dist/web/_app/immutable/assets/Copy.FS8bdfxr.css +0 -1
  1085. package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
  1086. package/dist/web/_app/immutable/assets/ViewToolbar.D-QW2oKe.css +0 -1
  1087. package/dist/web/_app/immutable/assets/index.D6tMDJWk.css +0 -1
  1088. package/dist/web/_app/immutable/chunks/-iaeBIWN.js +0 -1
  1089. package/dist/web/_app/immutable/chunks/37NdyH6G.js +0 -32
  1090. package/dist/web/_app/immutable/chunks/4Hhzb6pv.js +0 -1
  1091. package/dist/web/_app/immutable/chunks/72bZS3G9.js +0 -1
  1092. package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
  1093. package/dist/web/_app/immutable/chunks/B340SUKR.js +0 -1
  1094. package/dist/web/_app/immutable/chunks/B3Z4_Sps.js +0 -1
  1095. package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
  1096. package/dist/web/_app/immutable/chunks/BPWYOQXG.js +0 -1
  1097. package/dist/web/_app/immutable/chunks/BR77jbfR.js +0 -1
  1098. package/dist/web/_app/immutable/chunks/BS2rFAVq.js +0 -1
  1099. package/dist/web/_app/immutable/chunks/BSsDC_p4.js +0 -1
  1100. package/dist/web/_app/immutable/chunks/BTX2Jr8_.js +0 -1
  1101. package/dist/web/_app/immutable/chunks/Bq_KShUL.js +0 -4
  1102. package/dist/web/_app/immutable/chunks/Bsacq2UX.js +0 -1
  1103. package/dist/web/_app/immutable/chunks/ByunV8un.js +0 -1
  1104. package/dist/web/_app/immutable/chunks/BzPu-Eht.js +0 -1
  1105. package/dist/web/_app/immutable/chunks/C7VoTosa.js +0 -2
  1106. package/dist/web/_app/immutable/chunks/CDV5Q7RN.js +0 -1
  1107. package/dist/web/_app/immutable/chunks/CGc1sIb_.js +0 -1
  1108. package/dist/web/_app/immutable/chunks/CJ8__CWt.js +0 -1
  1109. package/dist/web/_app/immutable/chunks/CJUKmosC.js +0 -5
  1110. package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
  1111. package/dist/web/_app/immutable/chunks/CT6oIU-C.js +0 -1
  1112. package/dist/web/_app/immutable/chunks/CTRxNfZk.js +0 -1
  1113. package/dist/web/_app/immutable/chunks/CWQRQXxy.js +0 -1
  1114. package/dist/web/_app/immutable/chunks/CX87mIM8.js +0 -1
  1115. package/dist/web/_app/immutable/chunks/CXH6iFbA.js +0 -1
  1116. package/dist/web/_app/immutable/chunks/CX_61fY8.js +0 -5
  1117. package/dist/web/_app/immutable/chunks/CYrVHOHA.js +0 -1
  1118. package/dist/web/_app/immutable/chunks/CdeYcEuU.js +0 -1
  1119. package/dist/web/_app/immutable/chunks/CmCtpZ1Y.js +0 -1
  1120. package/dist/web/_app/immutable/chunks/Cpsr8-Xy.js +0 -1
  1121. package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
  1122. package/dist/web/_app/immutable/chunks/CrdV0ttd.js +0 -1
  1123. package/dist/web/_app/immutable/chunks/CscoF-YL.js +0 -18
  1124. package/dist/web/_app/immutable/chunks/Cx4YdFMk.js +0 -1
  1125. package/dist/web/_app/immutable/chunks/D7ZqAKi9.js +0 -3
  1126. package/dist/web/_app/immutable/chunks/DGbA7IXh.js +0 -2
  1127. package/dist/web/_app/immutable/chunks/DTZE-yoq.js +0 -2
  1128. package/dist/web/_app/immutable/chunks/DbbB6Up5.js +0 -1
  1129. package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
  1130. package/dist/web/_app/immutable/chunks/DtM5cEDu.js +0 -1
  1131. package/dist/web/_app/immutable/chunks/Eqahi7_S.js +0 -2
  1132. package/dist/web/_app/immutable/chunks/O9Eb9k00.js +0 -1
  1133. package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
  1134. package/dist/web/_app/immutable/chunks/QF8MAmnc.js +0 -1
  1135. package/dist/web/_app/immutable/chunks/UjzxCpxn.js +0 -1
  1136. package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
  1137. package/dist/web/_app/immutable/chunks/Y90OgS-9.js +0 -1
  1138. package/dist/web/_app/immutable/chunks/cLyZlkXv.js +0 -1
  1139. package/dist/web/_app/immutable/chunks/iDtAARVW.js +0 -2
  1140. package/dist/web/_app/immutable/chunks/oC_W7W7p.js +0 -1
  1141. package/dist/web/_app/immutable/chunks/rJdWIgh-.js +0 -1
  1142. package/dist/web/_app/immutable/chunks/tvOsokaa.js +0 -1
  1143. package/dist/web/_app/immutable/chunks/uLEXaPwE.js +0 -1
  1144. package/dist/web/_app/immutable/chunks/vSaooFHB.js +0 -1
  1145. package/dist/web/_app/immutable/entry/app.BeUKh4sD.js +0 -2
  1146. package/dist/web/_app/immutable/entry/start.CZJnFuQn.js +0 -1
  1147. package/dist/web/_app/immutable/nodes/0.DyF_RsLg.js +0 -2
  1148. package/dist/web/_app/immutable/nodes/1.7iDQmMPh.js +0 -1
  1149. package/dist/web/_app/immutable/nodes/10.Btl8d8HT.js +0 -1
  1150. package/dist/web/_app/immutable/nodes/2.LDRE62jN.js +0 -168
  1151. package/dist/web/_app/immutable/nodes/3.BaW1XB1x.js +0 -1
  1152. package/dist/web/_app/immutable/nodes/4.D0Q8kpkI.js +0 -12
  1153. package/dist/web/_app/immutable/nodes/5.n7j2UG9h.js +0 -4
  1154. package/dist/web/_app/immutable/nodes/6.DQYxR0iy.js +0 -2
  1155. package/dist/web/_app/immutable/nodes/7.BsURvFAp.js +0 -2
  1156. package/dist/web/_app/immutable/nodes/8.CsiErG0p.js +0 -1
  1157. package/dist/web/_app/immutable/nodes/9.CnN6OZgC.js +0 -1
@@ -4,89 +4,290 @@
4
4
  * Hosts:
5
5
  * - Graph API (read-only REST over WorkspaceManager)
6
6
  * - Agent chat via POST /api/chat and SSE GET /api/chat/stream
7
- * - App plugins mounted via PluginLoader
7
+ * - Static web UI (SvelteKit build) with SPA fallback
8
8
  */
9
9
  import Fastify from 'fastify';
10
10
  import cookie from '@fastify/cookie';
11
11
  import cors from '@fastify/cors';
12
+ import rateLimit from '@fastify/rate-limit';
12
13
  import websocket from '@fastify/websocket';
14
+ import { sanitize } from './middleware/sanitize.js';
13
15
  import { existsSync, readFileSync, createReadStream, statSync } from 'fs';
14
- import { join, extname } from 'path';
16
+ import { join, extname, resolve, sep } from 'path';
15
17
  import { Workspace } from '../core/workspace.js';
16
18
  import { AgentOrchestrator } from '../agent/orchestrator.js';
17
- import { PluginLoader, MIME_TYPES } from './plugin-loader.js';
18
19
  import { registerGraphApiRoutes } from './routes/graph-api.js';
19
20
  import { registerChatRoutes } from './routes/chat.js';
20
21
  import { registerWorkspaceApiRoutes } from './routes/workspace-api.js';
22
+ import { registerHealthApiRoutes } from './routes/health.js';
21
23
  import { registerPermissionsApiRoutes } from './routes/permissions-api.js';
22
24
  import { registerAuthApiRoutes } from './routes/auth-api.js';
23
25
  import { registerGitHttpRoutes } from './routes/git-http.js';
24
- import { registerSyncApiRoutes } from './routes/sync-api.js';
25
26
  import { registerViewsApiRoutes } from './routes/views-api.js';
26
27
  import { registerInsightsApiRoutes } from './routes/insights-api.js';
27
28
  import { registerMcpRoutes } from './routes/mcp.js';
28
- import { registerMeetingIngestRoutes } from './routes/meeting-ingest-api.js';
29
- import { AuthService } from '../services/auth-service.js';
29
+ import { registerConnectorsApiRoutes } from './routes/connectors-api.js';
30
+ import { registerOAuthApiRoutes, resolveCanonicalBaseUrl } from './routes/oauth-api.js';
31
+ import { registerAssetApiRoutes } from './routes/asset-api.js';
32
+ import { registerR2ApiRoutes } from './routes/r2-api.js';
33
+ import multipart from '@fastify/multipart';
34
+ import { registerEventIngestRoutes } from './routes/event-ingest-api.js';
35
+ import { registerCaptureRoutes } from './routes/capture-api.js';
36
+ import { registerUrlRoutes } from './routes/url-api.js';
37
+ import { registerConfigApiRoutes } from './routes/config-api.js';
38
+ import { registerSettingsApiRoutes } from './routes/settings-api.js';
39
+ import { registerSecretsApiRoutes } from './routes/secrets-api.js';
40
+ import { registerAuditApiRoutes } from './routes/audit-api.js';
41
+ import { registerCommentsApiRoutes } from './routes/comments-api.js';
42
+ import { registerChatSessionsApiRoutes } from './routes/chat-sessions-api.js';
43
+ import { registerShareApiRoutes } from './routes/share-api.js';
44
+ import { AuthService, isWorkspaceOwner } from '../services/auth-service.js';
30
45
  import { MemoryService } from '../services/memory-service.js';
46
+ import { CommentService } from '../services/comment-service.js';
47
+ import { ChatSessionService } from '../services/chat-session-service.js';
48
+ import { ShareLinkService } from '../services/share-link-service.js';
49
+ import { NotificationService } from '../services/notification-service.js';
31
50
  import { WsHub } from './ws-hub.js';
32
51
  import { registerWsRoute } from './routes/ws.js';
33
52
  import { SessionManager } from './session-manager.js';
53
+ import { AssetIndexQueue } from './asset-index-queue.js';
34
54
  import { YjsManager } from './yjs-manager.js';
55
+ import { YjsPersistence, acquireYjsStateLock } from './yjs-persistence.js';
56
+ import { BodyWriteCoordinator } from './body-write-coordinator.js';
57
+ import { ensurePersonalFolder } from '../services/personal-folder.js';
58
+ import { loadUserConfig, resolveProvider, resolveModelId, resolveApiKey } from '../core/user-config.js';
59
+ /** Ensure every user has a personal "My Folder" folder + admin access on it (idempotent). */
60
+ async function ensureAllPersonalFolders(authService, workspacePath, workspaceManager) {
61
+ const users = authService.listUsers();
62
+ const workspace = new Workspace(workspacePath);
63
+ for (const user of users) {
64
+ try {
65
+ await ensurePersonalFolder(workspace, authService, user);
66
+ }
67
+ catch { /* non-fatal — skip and let the user re-authenticate */ }
68
+ }
69
+ workspaceManager.reloadConfig();
70
+ }
71
+ /** MIME types for static file serving (web UI assets). */
72
+ const MIME_TYPES = {
73
+ '.html': 'text/html',
74
+ '.css': 'text/css',
75
+ '.js': 'application/javascript',
76
+ '.mjs': 'application/javascript',
77
+ '.json': 'application/json',
78
+ '.png': 'image/png',
79
+ '.jpg': 'image/jpeg',
80
+ '.jpeg': 'image/jpeg',
81
+ '.gif': 'image/gif',
82
+ '.svg': 'image/svg+xml',
83
+ '.ico': 'image/x-icon',
84
+ '.woff': 'font/woff',
85
+ '.woff2': 'font/woff2',
86
+ '.ttf': 'font/ttf',
87
+ '.otf': 'font/otf',
88
+ '.webp': 'image/webp',
89
+ '.avif': 'image/avif',
90
+ '.mp4': 'video/mp4',
91
+ '.webm': 'video/webm',
92
+ };
93
+ export function resolveStaticFilePath(webDir, urlPath) {
94
+ let decodedPath;
95
+ try {
96
+ decodedPath = decodeURIComponent(urlPath);
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ const filePath = decodedPath === '/' ? '/index.html' : decodedPath;
102
+ const webRoot = resolve(webDir);
103
+ const fullPath = resolve(webRoot, `.${filePath}`);
104
+ if (fullPath !== webRoot && !fullPath.startsWith(webRoot + sep)) {
105
+ return null;
106
+ }
107
+ return fullPath;
108
+ }
109
+ function normalizeOrigin(value) {
110
+ if (!value)
111
+ return null;
112
+ try {
113
+ return new URL(value).origin;
114
+ }
115
+ catch {
116
+ return null;
117
+ }
118
+ }
119
+ export function buildAllowedCorsOrigins(workspaceConfig, port) {
120
+ const rawOrigins = [];
121
+ const envOrigins = process.env.STUDIOGRAPH_CORS_ORIGINS;
122
+ if (envOrigins)
123
+ rawOrigins.push(...envOrigins.split(',').map(o => o.trim()).filter(Boolean));
124
+ const configured = workspaceConfig.cors_origins;
125
+ if (Array.isArray(configured)) {
126
+ rawOrigins.push(...configured.filter((o) => typeof o === 'string'));
127
+ }
128
+ else if (typeof configured === 'string') {
129
+ rawOrigins.push(...configured.split(',').map(o => o.trim()).filter(Boolean));
130
+ }
131
+ const serverUrl = workspaceConfig.server_url;
132
+ if (typeof serverUrl === 'string')
133
+ rawOrigins.push(serverUrl);
134
+ rawOrigins.push(`http://localhost:${port}`, `http://127.0.0.1:${port}`, `http://[::1]:${port}`);
135
+ return new Set(rawOrigins.map(normalizeOrigin).filter((o) => Boolean(o)));
136
+ }
137
+ export function isCorsOriginAllowed(origin, allowedOrigins) {
138
+ if (!origin)
139
+ return true;
140
+ const normalized = normalizeOrigin(origin);
141
+ return Boolean(normalized && allowedOrigins.has(normalized));
142
+ }
143
+ function isTruthyEnv(value) {
144
+ return Boolean(value && ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase()));
145
+ }
35
146
  /**
36
147
  * Auth middleware — validates JWT cookie or Authorization: Bearer <key> header.
37
148
  * When users exist in the auth database, all routes require authentication
38
149
  * (except auth endpoints and static assets). When no users exist, everything
39
150
  * is open (backward compatible).
40
151
  */
41
- function createAuthHook(apiKeys, authService) {
152
+ export function createAuthHook(authService, workspaceConfig) {
42
153
  return async (req, reply) => {
43
154
  // Always allow auth endpoints
44
155
  if (req.url.startsWith('/api/auth/'))
45
156
  return;
46
- // OAuth callbacks identify the user via the state parameter, not cookies
157
+ // Managed Cloud login handoff verifies its own short-lived token.
158
+ if (req.url.startsWith('/api/cloud/auth/'))
159
+ return;
160
+ // OAuth callbacks and claims identify the user via state/claim code, not cookies
47
161
  if (req.url.startsWith('/api/oauth/callback/'))
48
162
  return;
163
+ if (req.url.startsWith('/api/oauth/claim/'))
164
+ return;
165
+ // OAuth authorization-server discovery + token endpoints are
166
+ // unauthenticated by spec (the client has no user yet). They are
167
+ // rate-limited + validated in oauth-api.ts. NOT /oauth/authorize — that
168
+ // one must run as the logged-in user (handled explicitly below, above the
169
+ // HTML-GET bypass which would otherwise skip cookie resolution).
170
+ if (req.url.startsWith('/.well-known/oauth-'))
171
+ return;
172
+ if (req.url.startsWith('/oauth/token') ||
173
+ req.url.startsWith('/oauth/register') ||
174
+ req.url.startsWith('/oauth/revoke'))
175
+ return;
176
+ if (req.url.startsWith('/oauth/authorize')) {
177
+ const cookieTok = req.cookies?.['__sg_token'];
178
+ // Resolve the session cookie, but REFUSE an OAuth access token here — a
179
+ // cookie is a browser-session surface and must never carry an
180
+ // authorization-server-issued token (see the cookie branch below).
181
+ const c = cookieTok ? authService.verifyTokenWithClaims(cookieTok) : null;
182
+ if (c && !c.oauth) {
183
+ req.user = c.user;
184
+ return;
185
+ }
186
+ // Not logged in: bounce a browser GET to login (carrying the authorize
187
+ // URL as returnTo); refuse a POST.
188
+ if (req.method === 'GET') {
189
+ return reply.redirect(`/login?returnTo=${encodeURIComponent(req.url)}`);
190
+ }
191
+ return reply.status(401).send({ error: 'login_required' });
192
+ }
49
193
  // Git HTTP routes have their own Basic Auth
50
194
  if (req.url.startsWith('/git/'))
51
195
  return;
52
196
  // WebSocket route handles its own auth
53
197
  if (req.url.startsWith('/ws'))
54
198
  return;
55
- // Allow static assets (JS, CSS, fonts, images) — needed for login page
56
- if (req.url.startsWith('/_app/') || req.url.startsWith('/api/chrome/'))
199
+ // Allow static assets (JS, CSS, fonts, images) — needed for login page.
200
+ // Covers SvelteKit-bundled output under /_app/ and root-level public
201
+ // files (favicon.ico, studiograph-logomark.svg, …) identified by a file
202
+ // extension on a non-API GET.
203
+ if (req.url.startsWith('/_app/'))
204
+ return;
205
+ // Public share surface: the two read-only routes are authorized by the
206
+ // opaque token (verified in share-api.ts), not a session. Scope the bypass
207
+ // to EXACTLY the public read + asset shapes so a future /api/share/* route
208
+ // isn't accidentally public. Allow HEAD as well as GET — the asset route is
209
+ // registered for both (image preflights / link unfurlers issue HEAD). The
210
+ // mint route is POST /api/repos/... and stays fully authed.
211
+ if ((req.method === 'GET' || req.method === 'HEAD') &&
212
+ /^\/api\/share\/[^/]+(\/asset\/[^/]+\/[^/]+)?$/.test(req.url.split('?')[0]))
213
+ return;
214
+ if (req.method === 'GET' &&
215
+ !req.url.startsWith('/api/') &&
216
+ extname(req.url.split('?')[0]).length > 1)
57
217
  return;
58
218
  // Allow HTML page requests (SPA routing) — the app handles auth client-side
59
219
  if (req.method === 'GET' && req.headers.accept?.includes('text/html'))
60
220
  return;
61
- // If no users configured, allow everything (open mode)
62
- if (!authService.hasUsers()) {
63
- // Still check API keys for programmatic routes if configured
64
- if (apiKeys.length > 0) {
65
- const authHeader = req.headers['authorization'];
66
- const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : undefined;
67
- if (bearer && apiKeys.includes(bearer))
68
- return;
69
- // For non-API routes (i.e. browser requests), allow without auth
70
- if (!req.url.startsWith('/api/') || req.url.startsWith('/api/auth/'))
71
- return;
72
- // For API routes without a bearer token, allow if no users exist
73
- }
221
+ // If no users configured, allow everything in local open mode. Managed
222
+ // Cloud workspaces still require auth before the first user handoff lands.
223
+ if (!authService.hasUsers() && !isTruthyEnv(process.env.STUDIOGRAPH_MANAGED_AUTH))
74
224
  return;
75
- }
76
- // Check JWT cookie (web UI sessions)
225
+ // Check JWT cookie (web UI sessions).
226
+ //
227
+ // Security: resolve with verifyTokenWithClaims and REJECT OAuth access
228
+ // tokens (`oauth:true`). OAuth tokens are JWTs signed with the same
229
+ // jwtSecret, so the legacy verifyToken() would accept one supplied as a
230
+ // cookie and return a fully-privileged session — bypassing the MCP-only
231
+ // audience scoping enforced on the Bearer path below. A session cookie is
232
+ // a web-UI surface and must never carry an authorization-server token.
77
233
  const jwtToken = req.cookies?.['__sg_token'];
78
234
  if (jwtToken) {
79
- const user = authService.verifyToken(jwtToken);
80
- if (user) {
81
- req.user = user;
235
+ const claims = authService.verifyTokenWithClaims(jwtToken);
236
+ if (claims && !claims.oauth) {
237
+ req.user = claims.user;
82
238
  return;
83
239
  }
84
240
  }
85
- // Check Bearer token (API clients, MCP)
241
+ // Check Bearer token (API clients, MCP, CLI): JWT → per-user API token.
242
+ // Both yield a user identity. There is no shared workspace key — every
243
+ // caller must be identifiable so access control can enforce per-folder rules.
86
244
  const authHeader = req.headers['authorization'];
87
245
  const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : undefined;
88
- if (bearer && apiKeys.includes(bearer))
89
- return;
246
+ if (bearer) {
247
+ const claims = authService.verifyTokenWithClaims(bearer);
248
+ if (claims) {
249
+ if (claims.oauth) {
250
+ // OAuth access tokens are confined to the MCP surface. Reject them on
251
+ // the rest of the REST API so a leaked connector token can't drive the
252
+ // whole product (least privilege — sg_ tokens stay full).
253
+ const path = req.url.split('?')[0];
254
+ const mcpScoped = path === '/mcp' || path.startsWith('/mcp/') || path.startsWith('/oauth/');
255
+ if (!mcpScoped) {
256
+ return reply.status(403).send({ error: 'insufficient_scope' });
257
+ }
258
+ // Enforce the token audience: it must be bound to THIS server's /mcp
259
+ // resource. Without this, any JWT signed with the workspace secret +
260
+ // `oauth:true` would be accepted regardless of the `aud` it was minted
261
+ // for (stale/wrong-resource/host-spoofed tokens).
262
+ let expectedAud = null;
263
+ try {
264
+ expectedAud = `${resolveCanonicalBaseUrl(workspaceConfig, req)}/mcp`;
265
+ }
266
+ catch {
267
+ expectedAud = null;
268
+ }
269
+ if (!expectedAud || claims.aud !== expectedAud) {
270
+ return reply.status(403).send({ error: 'insufficient_scope', error_description: 'token audience mismatch' });
271
+ }
272
+ // Label the integration for agent-activity attribution (parity with
273
+ // the api-token name path below). cid is the stable client_id.
274
+ if (claims.cid) {
275
+ const client = authService.oauthServer.getClient(claims.cid);
276
+ req.apiTokenName = client?.client_name ?? 'OAuth client';
277
+ }
278
+ }
279
+ req.user = claims.user;
280
+ return;
281
+ }
282
+ const tokenMeta = authService.verifyApiTokenWithMeta(bearer);
283
+ if (tokenMeta) {
284
+ req.user = tokenMeta.user;
285
+ // Stash the token's user-set name so downstream surfaces (MCP, agent
286
+ // activity) can label the integration. Absent for cookie/JWT auth.
287
+ req.apiTokenName = tokenMeta.tokenName;
288
+ return;
289
+ }
290
+ }
90
291
  // Check Basic Auth (CLI join command)
91
292
  if (authHeader?.startsWith('Basic ')) {
92
293
  try {
@@ -102,25 +303,158 @@ function createAuthHook(apiKeys, authService) {
102
303
  }
103
304
  catch { /* fall through to 401 */ }
104
305
  }
306
+ // MCP OAuth discovery: an unauthenticated /mcp request gets a
307
+ // WWW-Authenticate header pointing at the protected-resource metadata, so
308
+ // an MCP client (Claude Chat/Cowork) knows to begin the OAuth flow.
309
+ if (req.url.startsWith('/mcp')) {
310
+ // Best-effort: if no canonical issuer is pinned (fails closed in prod),
311
+ // skip the discovery hint rather than 500 the 401.
312
+ try {
313
+ const base = resolveCanonicalBaseUrl(workspaceConfig, req);
314
+ reply.header('WWW-Authenticate', `Bearer resource_metadata="${base}/.well-known/oauth-protected-resource"`);
315
+ }
316
+ catch { /* issuer unconfigured — omit discovery header */ }
317
+ }
105
318
  return reply.status(401).send({ error: 'Unauthorized' });
106
319
  };
107
320
  }
321
+ /**
322
+ * Phase 11 — preSerialization payload sanitizer.
323
+ *
324
+ * The API has many routes that respond with `{ error: err.message }` from a
325
+ * catch block. Those messages can carry upstream provider errors, git
326
+ * stderr (with embedded credentials), or other free-form text that we
327
+ * don't want surfacing in HTTP responses. Walk the response payload,
328
+ * sanitize any string value at a "message" / "error" / "detail" key,
329
+ * and leave structured fields (status codes, IDs, classification flags)
330
+ * alone.
331
+ *
332
+ * Conservatively, we ONLY redact at keys that conventionally carry
333
+ * free-form text. Arbitrary string fields (entity names, IDs, etc.) are
334
+ * left untouched so we don't garble legitimate content. The Fastify
335
+ * logger sanitization (above) handles log-line redaction independently;
336
+ * this hook focuses on the wire response.
337
+ */
338
+ const FREEFORM_ERROR_KEYS = new Set(['error', 'message', 'detail', 'stack', 'description', 'error_description']);
339
+ function sanitizeResponsePayload(value) {
340
+ if (typeof value === 'string')
341
+ return sanitize(value);
342
+ if (Array.isArray(value))
343
+ return value.map(sanitizeResponsePayload);
344
+ if (value && typeof value === 'object') {
345
+ const out = {};
346
+ for (const [k, v] of Object.entries(value)) {
347
+ if (FREEFORM_ERROR_KEYS.has(k) && typeof v === 'string') {
348
+ out[k] = sanitize(v);
349
+ }
350
+ else if (v && typeof v === 'object') {
351
+ out[k] = sanitizeResponsePayload(v);
352
+ }
353
+ else {
354
+ out[k] = v;
355
+ }
356
+ }
357
+ return out;
358
+ }
359
+ return value;
360
+ }
108
361
  export async function createServer(config) {
362
+ // Phase 11: every Fastify log line flows through sanitize() before
363
+ // reaching stdout. A thin Writable wrapper passes each chunk through
364
+ // the redactor; pino accepts any `stream` with a `write()` method.
365
+ // STUDIOGRAPH_LOG_RAW=1 disables redaction for local debugging.
366
+ const shouldRedactFastifyLogs = process.env.STUDIOGRAPH_LOG_RAW !== '1' &&
367
+ (process.env.NODE_ENV === 'production' || !!process.env.RAILWAY_ENVIRONMENT);
368
+ const redactingStream = {
369
+ write(chunk) {
370
+ const out = shouldRedactFastifyLogs ? sanitize(chunk) : chunk;
371
+ process.stdout.write(out);
372
+ },
373
+ };
109
374
  const fastify = Fastify({
110
375
  logger: process.env.STUDIOGRAPH_LOG === '1'
111
- ? true
112
- : { level: 'warn' },
376
+ ? { stream: redactingStream }
377
+ : { level: 'warn', stream: redactingStream },
113
378
  bodyLimit: 10 * 1024 * 1024, // 10 MB — entities can be large (e.g. meeting transcripts)
114
379
  });
380
+ // Phase 11: sanitize uncaught errors before serialization so neither
381
+ // err.message nor err.stack echoes upstream secrets. Stable error
382
+ // codes (err.code) pass through; we only redact freeform text.
383
+ fastify.setErrorHandler((error, _req, reply) => {
384
+ const sanitizedMsg = shouldRedactFastifyLogs ? sanitize(error.message) : error.message;
385
+ const status = error.statusCode ?? 500;
386
+ fastify.log.error({
387
+ err: { message: sanitizedMsg, code: error.code },
388
+ });
389
+ reply.status(status).send({
390
+ statusCode: status,
391
+ code: error.code,
392
+ error: status >= 500 ? 'Internal Server Error' : (error.name || 'Error'),
393
+ message: status >= 500 ? 'An internal error occurred.' : sanitizedMsg,
394
+ });
395
+ });
396
+ // Phase 11: pre-serialization hook scans every response body for
397
+ // freeform error/message strings and runs them through sanitize().
398
+ // This catches the many `reply.status(4xx).send({ error: err.message })`
399
+ // call sites scattered across the API routes — without this, an
400
+ // upstream provider error or git remote error would echo through to
401
+ // the API consumer with embedded credentials. Stable error codes pass
402
+ // through unchanged. Only kicks in when redaction is enabled.
403
+ if (shouldRedactFastifyLogs) {
404
+ fastify.addHook('preSerialization', async (_req, _reply, payload) => {
405
+ if (!payload || typeof payload !== 'object')
406
+ return payload;
407
+ return sanitizeResponsePayload(payload);
408
+ });
409
+ }
115
410
  // CORS
411
+ const allowedCorsOrigins = buildAllowedCorsOrigins(config.workspaceConfig, config.port);
116
412
  await fastify.register(cors, {
117
- origin: true,
413
+ origin: (origin, cb) => {
414
+ cb(null, isCorsOriginAllowed(origin, allowedCorsOrigins));
415
+ },
118
416
  credentials: true,
119
417
  });
120
418
  // Cookie support for web UI session auth
121
419
  await fastify.register(cookie);
122
- // WebSocket support for real-time notifications
123
- await fastify.register(websocket);
420
+ // WebSocket support for real-time notifications.
421
+ //
422
+ // perMessageDeflate is enabled here on purpose. Our origin would otherwise
423
+ // leave compression off (ws lib default), but Railway's edge proxy
424
+ // negotiates `permessage-deflate` with the browser anyway and does its own
425
+ // inflate/deflate layer in the middle — which Safari/WebKit mis-decodes,
426
+ // producing truncated buffers and `RangeError: Length out of range of buffer`
427
+ // inside Yjs's varint reader, followed by WS disconnect loops.
428
+ //
429
+ // Negotiating compression at the origin forces end-to-end deflate (Node's
430
+ // zlib ↔ browser) and prevents the proxy from inserting its own layer.
431
+ // `noContextTakeover` on both sides keeps each frame independently
432
+ // decompressible, which avoids cross-frame state bugs that have historically
433
+ // hit Safari.
434
+ await fastify.register(websocket, {
435
+ options: {
436
+ perMessageDeflate: {
437
+ threshold: 1024,
438
+ serverNoContextTakeover: true,
439
+ clientNoContextTakeover: true,
440
+ },
441
+ },
442
+ });
443
+ // Multipart support for file uploads (images, assets)
444
+ await fastify.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } });
445
+ // Global rate-limit registration with a permissive default; individual
446
+ // routes opt into tighter limits via `config: { rateLimit: ... }`. Today
447
+ // only comment mutations apply tight limits — keeps the runtime in
448
+ // place without changing the rest of the API's request-rate behaviour.
449
+ await fastify.register(rateLimit, {
450
+ global: false,
451
+ max: 1000,
452
+ timeWindow: '1 minute',
453
+ keyGenerator: (req) => {
454
+ const u = req.user;
455
+ return u?.id ? `u:${u.id}` : (req.ip ?? 'unknown');
456
+ },
457
+ });
124
458
  fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, (req, body, done) => {
125
459
  try {
126
460
  req.rawBody = body;
@@ -130,6 +464,21 @@ export async function createServer(config) {
130
464
  done(err, undefined);
131
465
  }
132
466
  });
467
+ // application/x-www-form-urlencoded — the OAuth token + consent POSTs use
468
+ // form encoding (RFC 6749). Parsed inline to avoid pulling in a dependency
469
+ // just for two endpoints; mirrors the hand-rolled JSON parser above.
470
+ fastify.addContentTypeParser('application/x-www-form-urlencoded', { parseAs: 'string' }, (_req, body, done) => {
471
+ try {
472
+ const params = new URLSearchParams(body);
473
+ const obj = {};
474
+ for (const [k, v] of params)
475
+ obj[k] = v;
476
+ done(null, obj);
477
+ }
478
+ catch (err) {
479
+ done(err, undefined);
480
+ }
481
+ });
133
482
  // Git Smart HTTP binary content types — pass raw stream through (no parsing)
134
483
  for (const gitType of [
135
484
  'application/x-git-upload-pack-request',
@@ -139,104 +488,182 @@ export async function createServer(config) {
139
488
  done(null); // Don't consume the body — the route handler pipes req.raw directly
140
489
  });
141
490
  }
142
- // Initialize auth service, WebSocket hub, session manager, and collab server
143
- const authService = new AuthService(config.workspacePath);
144
- // Ensure API key is committed to auth-seed.json so `studiograph pull` can use it
145
- authService.syncApiKeyToSeed();
146
- const wsHub = new WsHub();
491
+ // Initialize auth service, WebSocket hub, session manager, and collab server.
492
+ // Phase 8: when the boot path provided master-key options, hand them through
493
+ // so OAuth tokens + per-user secret prefs use the encrypted column path.
494
+ const authService = new AuthService(config.workspacePath, config.authCryptoOptions);
495
+ // Ensure all users have their personal "My Folder" folder
496
+ await ensureAllPersonalFolders(authService, config.workspacePath, config.workspaceManager);
497
+ const { getCurrentVersion } = await import('../utils/version-checker.js');
498
+ const wsHub = new WsHub(getCurrentVersion());
499
+ const commentService = new CommentService(config.workspacePath);
500
+ const chatSessionService = new ChatSessionService(config.workspacePath);
501
+ const shareLinkService = new ShareLinkService(config.workspacePath);
502
+ const notificationService = new NotificationService(config.workspacePath);
147
503
  const sessionManager = new SessionManager(config.workspaceManager, wsHub);
148
- const yjsManager = new YjsManager(config.workspaceManager);
504
+ // Recover any dirty repos before accepting requests. Replays persisted
505
+ // pending commits from a previous process AND sweeps every working tree
506
+ // for uncommitted state. Catches anything dropped by a crash, OOM, or
507
+ // hard restart. Logs and continues on failure — recovery is best-effort
508
+ // and must never block server startup.
509
+ try {
510
+ await sessionManager.recoverOnBoot();
511
+ }
512
+ catch (err) {
513
+ console.warn('[server] sessionManager.recoverOnBoot failed:', err.message);
514
+ }
515
+ // Live asset-index drain: captions new image uploads and re-extracts document
516
+ // sidecars while the server runs, instead of only at boot (a tenant can run
517
+ // for weeks between deploys). Config (model/key/gate/repos) is resolved fresh
518
+ // each drain so a Settings change takes effect without a restart. Web upload
519
+ // + MCP finalize call `enqueue()` after the asset entity exists.
520
+ const assetIndexQueue = new AssetIndexQueue({
521
+ workspaceManager: config.workspaceManager,
522
+ resolveConfig: () => {
523
+ const userConfig = loadUserConfig();
524
+ // Read the LIVE workspace config from the WorkspaceManager, NOT the boot
525
+ // snapshot (config.workspaceConfig). reloadConfig() refreshes both the
526
+ // repo list (so a folder auto-created at runtime — e.g. the shared
527
+ // "Assets" store on first inline/presign upload — is visible to the
528
+ // sweep) and the captioning gate (so toggling it in workspace.json takes
529
+ // effect without a restart). Model/key already resolve store-first.
530
+ const wsConfig = config.workspaceManager.getConfig();
531
+ const apiKey = resolveApiKey(userConfig, wsConfig);
532
+ return {
533
+ repos: config.workspaceManager.getAllRepoConfigs(),
534
+ captionConfig: apiKey
535
+ ? { provider: resolveProvider(userConfig, wsConfig), modelId: resolveModelId(userConfig, wsConfig), apiKey }
536
+ : null,
537
+ captioningEnabled: wsConfig.captioning?.enabled ?? true,
538
+ };
539
+ },
540
+ log: (msg) => console.warn(`[asset-index] ${msg}`),
541
+ });
542
+ assetIndexQueue.start();
543
+ // Single chokepoint: VectorService fires onAssetPending exactly when a fresh
544
+ // indexable image is seeded `pending` (every upload path funnels through
545
+ // ensureInitialAssetIndexState). Registering here replaces per-call-site
546
+ // enqueue wiring and covers web + MCP + agent import_file uniformly.
547
+ config.workspaceManager.vectorService?.setOnAssetPending((repo, entityId) => assetIndexQueue.enqueue(repo, entityId));
548
+ // Boot recovery: drain anything a prior process left queued AND re-derive the
549
+ // full unfinished set in LanceDB (legacy assets, a mid-flight crash). Fire-and-
550
+ // forget — it can take minutes on a large gallery and must not block listen().
551
+ void assetIndexQueue.recoverOnBoot().catch((err) => {
552
+ console.warn('[asset-index] recoverOnBoot failed (non-fatal):', err instanceof Error ? err.message : err);
553
+ });
554
+ // Persistence layer: durable Y.Doc snapshot store across server restarts.
555
+ // Lives at `<workspace>/.studiograph/yjs-state/` — gitignored binary state
556
+ // separate from the .md files (which remain canonical for git, MCP, agents).
557
+ // See yjs-persistence.ts for the file format and concurrency model.
558
+ const yjsStateDir = join(config.workspacePath, '.studiograph', 'yjs-state');
559
+ // Single-instance lock. Throws if another studiograph server is already
560
+ // running against this workspace. We don't support horizontal scaling today
561
+ // (no shared Yjs pubsub), so the safe default is to fail fast on misuse
562
+ // rather than silently corrupt snapshots via concurrent writers.
563
+ const releaseYjsLock = acquireYjsStateLock(yjsStateDir);
564
+ const yjsPersistence = new YjsPersistence(yjsStateDir);
565
+ const yjsManager = new YjsManager(config.workspaceManager, yjsPersistence);
566
+ // Yjs configuration startup log. Surfacing the flags at boot lets operators
567
+ // verify the configuration without reading source. The fail-closed guards
568
+ // (`assertWritable`, 412 convergence gate) prevent silent data corruption
569
+ // regardless of how the flags are set, but `broadcast=off` while clients
570
+ // are connected degrades UX, so we warn explicitly.
571
+ const broadcastEnabled = process.env.STUDIOGRAPH_YJS_BROADCAST !== '0';
572
+ const allowDegradedWrites = process.env.STUDIOGRAPH_ALLOW_DEGRADED_WRITES === '1';
573
+ console.log(`[yjs] config: broadcast=${broadcastEnabled ? 'on' : 'OFF'} ` +
574
+ `allow-degraded-writes=${allowDegradedWrites ? 'on' : 'off'}`);
575
+ if (!broadcastEnabled && !allowDegradedWrites) {
576
+ console.warn('[yjs] STUDIOGRAPH_YJS_BROADCAST=0 without STUDIOGRAPH_ALLOW_DEGRADED_WRITES=1: ' +
577
+ 'server-side body writes will REFUSE while clients are connected. ' +
578
+ 'This is the fail-closed kill-switch path — intentional during incident response, ' +
579
+ 'misconfiguration otherwise.');
580
+ }
581
+ // Wire the Yjs persistence layer to follow structural .md mutations.
582
+ // delete / rename / changeType all change a doc's identity (path on disk
583
+ // and its docName), so the snapshot file has to move with it. Without
584
+ // these hooks, snapshots leak (orphaned files for deleted entities) or
585
+ // serve stale state at the new identity (ghost content after a rename).
586
+ config.workspaceManager.setPersistenceCallbacks({
587
+ onDelete: (repo, entityType, entityId) => yjsPersistence.delete(`${repo}/${entityType}/${entityId}`),
588
+ onRename: (repo, entityType, oldId, newId) => yjsPersistence.rename(`${repo}/${entityType}/${oldId}`, `${repo}/${entityType}/${newId}`),
589
+ onChangeType: (repo, entityId, fromType, toType) => yjsPersistence.rename(`${repo}/${fromType}/${entityId}`, `${repo}/${toType}/${entityId}`),
590
+ });
591
+ // Body-write coordinator owns the single critical section for every body
592
+ // write (autosave PUT + MCP / agent / event-processor server-writes). Holds
593
+ // the per-doc lock, base-hash precondition, atomic disk write, commit +
594
+ // dirty recovery, post-commit applyAgentContent broadcast, and
595
+ // mdRevisionHash bookkeeping. Replaces the previous nine-callback shape on
596
+ // graph.update.
597
+ const bodyWriteCoordinator = new BodyWriteCoordinator({
598
+ // Narrow commit hook — keeps the coordinator from reaching back
599
+ // through WorkspaceManager. No-op when the repo has no GitService.
600
+ commit: async (coords, actor, message) => {
601
+ const gitService = config.workspaceManager.getGraph(coords.repo).getGitService();
602
+ if (!gitService)
603
+ return;
604
+ const tx = gitService.createTransaction();
605
+ tx.add({
606
+ operation: 'update',
607
+ entityType: coords.entityType,
608
+ entityId: coords.entityId,
609
+ filePath: coords.entityPath,
610
+ });
611
+ await tx.commit(actor, message);
612
+ },
613
+ }, yjsManager, sessionManager);
614
+ config.workspaceManager.setBodyWriteCoordinator(bodyWriteCoordinator);
149
615
  // Register auth API routes (before the auth hook so they are always accessible)
150
- await registerAuthApiRoutes(fastify, authService, config.workspaceConfig.team_name);
616
+ await registerAuthApiRoutes(fastify, authService, config.workspacePath, config.workspaceManager, config.workspaceConfig.team_name);
151
617
  // Auth hook — applied to all routes
152
- const authHook = createAuthHook(config.apiKeys, authService);
618
+ const authHook = createAuthHook(authService, config.workspaceConfig);
153
619
  fastify.addHook('preHandler', authHook);
154
620
  // Register WebSocket route (real-time change notifications + cursor broadcasting)
155
- await registerWsRoute(fastify, wsHub, authService, yjsManager);
156
- // Register graph API routes (with per-collection access filtering)
621
+ await registerWsRoute(fastify, wsHub, authService, config.workspaceManager, yjsManager);
622
+ // Register graph API routes (with per-folder access filtering)
157
623
  await registerGraphApiRoutes(fastify, config.workspaceManager, authService, wsHub, sessionManager);
158
624
  // Register workspace API routes (git operations)
159
- await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser);
160
- // Register permissions API routes (self-hosted collection access)
625
+ await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser, authService);
626
+ // Register health endpoints (per-repo dirty status)
627
+ await registerHealthApiRoutes(fastify, config.workspaceManager, sessionManager);
628
+ // Register config + workspace data API routes (for `studiograph push/pull --remote`)
629
+ await registerConfigApiRoutes(fastify, config.workspaceManager, config.workspacePath, authService);
630
+ // Register Phase 7 settings/secrets/audit API routes. Owner-only via
631
+ // isWorkspaceOwner() inside each handler.
632
+ await registerSettingsApiRoutes(fastify, authService);
633
+ await registerSecretsApiRoutes(fastify, authService);
634
+ await registerAuditApiRoutes(fastify, authService);
635
+ // Register comments API + notifications feed (Comments-First Phase 1).
636
+ // The getAgent closure resolves the orchestrator lazily — it's
637
+ // initialised below at line ~613, AFTER routes register, so route
638
+ // handlers can't capture it eagerly. The closure binding to the outer
639
+ // `agent` variable picks up the value once the orchestrator is alive.
640
+ await registerCommentsApiRoutes(fastify, commentService, notificationService, authService, wsHub, config.workspaceManager, () => agent);
641
+ // Register chat-session persistence routes (cross-device agent history)
642
+ await registerChatSessionsApiRoutes(fastify, chatSessionService);
643
+ // Register permissions API routes (self-hosted folder access)
161
644
  await registerPermissionsApiRoutes(fastify, authService, config.workspaceManager, wsHub);
645
+ // Messages API routes registered after agent init (below) so @agent invocation works
646
+ // Register connectors API routes (MCP connector management + OAuth)
647
+ await registerConnectorsApiRoutes(fastify, authService, config.workspacePath);
648
+ // Register OAuth 2.0 authorization-server routes (Claude Chat/Cowork connect)
649
+ await registerOAuthApiRoutes(fastify, authService, config.workspaceConfig);
650
+ // Register asset upload routes (image upload to R2/local)
651
+ await registerAssetApiRoutes(fastify, config.workspaceManager, authService);
652
+ // Register public share-link routes (mint authed; read + asset public)
653
+ await registerShareApiRoutes(fastify, config.workspaceManager, authService, shareLinkService);
654
+ // Register R2 management routes (bucket creation, local-asset sync, status)
655
+ await registerR2ApiRoutes(fastify, config.workspaceManager, authService, config.gitUser);
162
656
  // Register git Smart HTTP routes (clone/fetch/push with Basic Auth)
163
657
  await registerGitHttpRoutes(fastify, config.workspaceManager, authService, config.workspacePath, wsHub);
164
- // Register sync API routes (collection-scoped sync)
165
- await registerSyncApiRoutes(fastify, config.workspaceManager, authService, config.workspacePath, wsHub);
166
658
  // Register views API routes (per-user saved views)
167
659
  await registerViewsApiRoutes(fastify, authService, config.workspaceManager);
168
660
  // Register insights + preferences API routes
169
- // Build core tool metadata once from actual tool factories
170
- const coreToolMeta = [];
171
- try {
172
- const { createGraphTools } = await import('../agent/tools/graph-tools.js');
173
- const { createSyncTools } = await import('../agent/tools/sync-tools.js');
174
- const { createOpsTools } = await import('../agent/tools/ops-tools.js');
175
- const dummyUser = { id: '0', name: 'system', email: 'system' };
176
- const allTools = [
177
- ...createGraphTools(config.workspaceManager, dummyUser, config.workspacePath, undefined, undefined, () => null, authService),
178
- ...createSyncTools(config.workspacePath, config.workspaceConfig),
179
- ...createOpsTools(config.workspacePath, config.workspaceConfig),
180
- ];
181
- for (const t of allTools) {
182
- if (t.name && t.description) {
183
- coreToolMeta.push({ name: t.name, description: t.description });
184
- }
185
- }
186
- }
187
- catch (err) {
188
- console.warn('[insights] Failed to build tool metadata:', err);
189
- }
190
- const getToolsForUser = (userId) => {
191
- const tools = [...coreToolMeta];
192
- // Add connector tools based on user's actually connected services
193
- try {
194
- const connectedConnectors = authService.getUserConnectedConnectors(userId);
195
- for (const c of connectedConnectors) {
196
- tools.push({ name: `${c.connector_name}_connector`, description: `Connected ${c.connector_name} integration — can sync and access ${c.connector_name} data` });
197
- }
198
- }
199
- catch { /* no connector tools */ }
200
- return tools;
201
- };
202
- await registerInsightsApiRoutes(fastify, config.workspaceManager, authService, config.workspacePath, wsHub, getToolsForUser);
203
- // Register meeting ingest API (Chrome extension + other capture tools)
204
- await registerMeetingIngestRoutes(fastify, config.workspaceManager, authService, wsHub);
661
+ await registerInsightsApiRoutes(fastify, config.workspaceManager, authService, config.workspacePath, wsHub, chatSessionService);
662
+ // Register event ingest API (meeting capture from desktop and external sources)
663
+ await registerEventIngestRoutes(fastify, config.workspaceManager, authService, wsHub, yjsManager);
205
664
  // Register MCP Streamable HTTP endpoint
206
- await registerMcpRoutes(fastify, config.workspaceManager, authService);
207
- // Serve chrome assets (shared header/footer for app editors)
208
- const chromeDir = join(import.meta.dirname, 'chrome');
209
- if (existsSync(chromeDir)) {
210
- const CHROME_MIME = { '.js': 'application/javascript', '.css': 'text/css' };
211
- fastify.get('/api/chrome/:file', async (req, reply) => {
212
- const file = req.params.file;
213
- if (file.includes('..') || file.includes('/')) {
214
- return reply.status(400).send({ error: 'Invalid path' });
215
- }
216
- const filePath = join(chromeDir, file);
217
- if (!existsSync(filePath) || !statSync(filePath).isFile()) {
218
- return reply.status(404).send({ error: 'Not found' });
219
- }
220
- const ext = extname(filePath).toLowerCase();
221
- reply.type(CHROME_MIME[ext] || 'application/octet-stream');
222
- reply.header('Cache-Control', 'public, max-age=300');
223
- return reply.send(createReadStream(filePath));
224
- });
225
- }
226
- // Discover installed apps and collect their skill/tool dirs
227
- const loader = new PluginLoader();
228
- const manifests = loader.loadApps(config.appsDir);
229
- const appSkillsDirs = [];
230
- const appToolsDirs = [];
231
- for (const manifest of manifests) {
232
- const skillsDir = loader.getSkillsDir(config.appsDir, manifest);
233
- if (skillsDir)
234
- appSkillsDirs.push(skillsDir);
235
- const toolsDir = loader.getToolsDir(config.appsDir, manifest);
236
- if (toolsDir)
237
- appToolsDirs.push(toolsDir);
238
- }
239
- // Initialize memory service and agent — non-fatal so the server can still serve graph API and apps
665
+ await registerMcpRoutes(fastify, config.workspaceManager, authService, wsHub, commentService);
666
+ // Initialize memory service and agent non-fatal so the server can still serve graph API
240
667
  const memoryService = new MemoryService();
241
668
  let agent = null;
242
669
  try {
@@ -245,12 +672,18 @@ export async function createServer(config) {
245
672
  workspacePath: config.workspacePath,
246
673
  workspaceConfig: config.workspaceConfig,
247
674
  gitUser: config.gitUser,
248
- skillsDirs: appSkillsDirs,
249
- toolsDirs: appToolsDirs,
250
675
  recentMemory,
251
676
  workspaceManager: config.workspaceManager,
677
+ // Share the route-level AuthService. Without this the orchestrator
678
+ // constructs its own crypto-less copy and (a) errors when reading
679
+ // encrypted oauth_tokens rows, (b) subscribes to a different
680
+ // pubsub than the one the OAuth callback fires on — so per-user
681
+ // OAuth state changes never invalidate the agent pool.
682
+ authService,
252
683
  });
253
- await registerChatRoutes(fastify, agent, memoryService);
684
+ await registerChatRoutes(fastify, agent, wsHub, authService, memoryService);
685
+ await registerCaptureRoutes(fastify, agent);
686
+ await registerUrlRoutes(fastify);
254
687
  }
255
688
  catch (err) {
256
689
  fastify.log.warn(`Agent not available: ${err.message ?? err} — chat routes will return setup message`);
@@ -268,55 +701,22 @@ export async function createServer(config) {
268
701
  return reply.status(503).send({ error: 'The AI agent is not configured yet. Please set the API key for your model provider in the server environment variables and restart.' });
269
702
  });
270
703
  }
271
- // GET /api/apps — list installed app manifests with resolved entity type names
272
- const resolvedApps = manifests.map(m => {
273
- let entityTypes = [];
274
- try {
275
- const etPath = join(config.appsDir, m.name, m.entityTypes);
276
- if (existsSync(etPath)) {
277
- const raw = JSON.parse(readFileSync(etPath, 'utf-8'));
278
- if (Array.isArray(raw)) {
279
- entityTypes = raw.map((item) => item.name).filter(Boolean);
280
- }
281
- }
282
- }
283
- catch {
284
- // gracefully degrade — return empty array
285
- }
286
- return { name: m.name, version: m.version, description: m.description, mountPath: m.mountPath, entityTypes };
287
- });
288
- fastify.get('/api/apps', async (_req, reply) => {
289
- return reply.send(resolvedApps);
290
- });
291
704
  // GET /api/workspace — workspace metadata
292
705
  fastify.get('/api/workspace', async (_req, reply) => {
293
706
  const workspace = new Workspace(config.workspacePath);
294
707
  const about = workspace.loadAbout();
295
- return reply.send({ name: config.workspaceConfig.team_name, about, accent_color: config.workspaceConfig.accent_color ?? null });
708
+ return reply.send({ name: config.workspaceConfig.team_name, about });
296
709
  });
297
- // PUT /api/workspace — update workspace identity (admin only)
710
+ // PUT /api/workspace — update workspace identity (owner only)
298
711
  fastify.put('/api/workspace', async (req, reply) => {
299
712
  const user = req.user;
300
- if (user && user.role !== 'admin') {
301
- return reply.status(403).send({ error: 'Admin access required' });
713
+ if (user && !isWorkspaceOwner(user.role)) {
714
+ return reply.status(403).send({ error: 'Workspace owner access required' });
302
715
  }
303
- const { name, about, accent_color } = req.body ?? {};
716
+ const { name, about } = req.body ?? {};
304
717
  const workspace = new Workspace(config.workspacePath);
305
- let configChanged = false;
306
718
  if (typeof name === 'string' && name.trim()) {
307
719
  config.workspaceConfig.team_name = name.trim();
308
- configChanged = true;
309
- }
310
- if (accent_color !== undefined) {
311
- if (accent_color === null) {
312
- delete config.workspaceConfig.accent_color;
313
- }
314
- else {
315
- config.workspaceConfig.accent_color = accent_color;
316
- }
317
- configChanged = true;
318
- }
319
- if (configChanged) {
320
720
  workspace.writeConfig(config.workspaceConfig);
321
721
  }
322
722
  if (typeof about === 'string') {
@@ -324,28 +724,38 @@ export async function createServer(config) {
324
724
  }
325
725
  return reply.send({ success: true });
326
726
  });
327
- // GET /api/workspace/mcp-config — MCP client configuration snippet (admin only)
727
+ // GET /api/workspace/mcp-config — MCP client configuration snippet.
728
+ // Returns a template with `<your-token-here>` in the Authorization header;
729
+ // the frontend fills it in after the user mints a personal token via
730
+ // POST /api/auth/tokens. We never embed a shared key here because doing so
731
+ // would leak a workspace-wide credential and re-introduce the bug the
732
+ // per-user-token model exists to solve.
328
733
  fastify.get('/api/workspace/mcp-config', async (req, reply) => {
329
- const user = req.user;
330
- if (user && user.role !== 'admin') {
331
- return reply.status(403).send({ error: 'Admin access required' });
734
+ // Prefer the pinned canonical URL so the connect URL shown in Settings
735
+ // matches the OAuth issuer/resource. Fall back to the request origin when
736
+ // none is configured (local dev / unpinned), rather than failing closed
737
+ // this endpoint is informational, not a security boundary.
738
+ let baseUrl;
739
+ try {
740
+ baseUrl = resolveCanonicalBaseUrl(config.workspaceConfig, req);
741
+ }
742
+ catch {
743
+ const proto = req.headers['x-forwarded-proto'] === 'https' ? 'https' : (req.protocol ?? 'http');
744
+ const host = req.headers['x-forwarded-host'] || req.headers.host || 'localhost';
745
+ baseUrl = `${proto}://${host}`;
332
746
  }
333
- const proto = req.headers['x-forwarded-proto'] === 'https' ? 'https' : (req.protocol ?? 'http');
334
- const host = req.headers['x-forwarded-host'] || req.headers.host || 'localhost';
335
- const baseUrl = `${proto}://${host}`;
336
- const apiKey = authService.getApiKey();
337
747
  const mcpConfig = {
338
748
  mcpServers: {
339
749
  studiograph: {
340
750
  type: 'streamable-http',
341
751
  url: `${baseUrl}/mcp`,
342
752
  headers: {
343
- Authorization: `Bearer ${apiKey}`,
753
+ Authorization: 'Bearer <your-token-here>',
344
754
  },
345
755
  },
346
756
  },
347
757
  };
348
- return reply.send({ config: mcpConfig });
758
+ return reply.send({ config: mcpConfig, url: `${baseUrl}/mcp` });
349
759
  });
350
760
  // DELETE /api/memory — clear all agent memory files
351
761
  fastify.delete('/api/memory', async (_req, reply) => {
@@ -357,19 +767,6 @@ export async function createServer(config) {
357
767
  const count = agent?.clearSessions() ?? 0;
358
768
  return reply.send({ cleared: count });
359
769
  });
360
- // Mount app plugins
361
- for (const manifest of manifests) {
362
- try {
363
- await loader.mountPlugin(fastify, manifest, config.appsDir, {
364
- workspaceManager: config.workspaceManager,
365
- gitUser: config.gitUser,
366
- });
367
- fastify.log.info(`Mounted app "${manifest.name}" at ${manifest.mountPath}`);
368
- }
369
- catch (err) {
370
- fastify.log.error(err, `Failed to mount app "${manifest.name}"`);
371
- }
372
- }
373
770
  // Serve web UI static files from dist/web/ with SPA fallback
374
771
  // When running via tsx from source, import.meta.dirname is src/server/ so ../web doesn't exist.
375
772
  // Fall back to dist/web/ relative to project root.
@@ -377,12 +774,34 @@ export async function createServer(config) {
377
774
  const webDir = existsSync(webDirCandidate) ? webDirCandidate : join(import.meta.dirname, '..', '..', 'dist', 'web');
378
775
  if (existsSync(webDir)) {
379
776
  const indexPath = join(webDir, 'index.html');
380
- // SPA fallback for app routes: if an app plugin returns a JSON error for a
381
- // browser GET request, serve the SPA instead. This happens when the browser
382
- // refreshes a URL like /documents/document/doc-123 — the app's greedy route
383
- // catches it but fails because the params don't match its expectations.
777
+ // SPA fallback: if any API route returns a JSON error for a browser GET,
778
+ // serve the SPA instead so client-side routing can handle the URL.
384
779
  // Read fresh from disk each time so rebuilds take effect without server restart.
385
780
  const readIndexHtml = () => readFileSync(indexPath);
781
+ /**
782
+ * Cache policy for static assets:
783
+ * - `/_app/immutable/*` are content-hashed by SvelteKit, so the URL
784
+ * changes every time the file does — safe to cache forever.
785
+ * - `index.html` (and the SPA fallback) MUST revalidate every load,
786
+ * otherwise stale HTML keeps pointing at expired immutable hashes.
787
+ * - Other root assets (favicons, og images, etc.) get a modest TTL.
788
+ *
789
+ * Without these headers the upstream CDN (Fastly in front of Railway)
790
+ * forwards almost every request to origin, producing multi-second
791
+ * TTFB on cold edges and a 3-5s "black screen" while the SPA bundle
792
+ * loads.
793
+ */
794
+ function setStaticCacheHeader(reply, urlPath) {
795
+ if (urlPath.startsWith('/_app/immutable/')) {
796
+ reply.header('Cache-Control', 'public, max-age=31536000, immutable');
797
+ }
798
+ else if (urlPath === '/' || urlPath === '/index.html' || !extname(urlPath)) {
799
+ reply.header('Cache-Control', 'no-cache');
800
+ }
801
+ else {
802
+ reply.header('Cache-Control', 'public, max-age=3600');
803
+ }
804
+ }
386
805
  fastify.addHook('onSend', async (request, reply, payload) => {
387
806
  if (reply.sent)
388
807
  return payload;
@@ -393,23 +812,24 @@ export async function createServer(config) {
393
812
  typeof ct === 'string' && ct.includes('application/json')) {
394
813
  reply.removeHeader('content-length');
395
814
  reply.code(200).type('text/html');
815
+ reply.header('Cache-Control', 'no-cache');
396
816
  return readIndexHtml();
397
817
  }
398
818
  return payload;
399
819
  });
400
- // Use setNotFoundHandler so app plugins and API routes take priority
820
+ // Use setNotFoundHandler so API routes take priority over SPA fallback
401
821
  fastify.setNotFoundHandler(async (req, reply) => {
402
822
  const urlPath = req.url.split('?')[0];
403
- const filePath = urlPath === '/' ? '/index.html' : urlPath;
404
- const fullPath = join(webDir, filePath);
823
+ const fullPath = resolveStaticFilePath(webDir, urlPath);
824
+ if (!fullPath) {
825
+ return reply.status(400).send({ error: 'Invalid path' });
826
+ }
405
827
  // Serve the file if it exists (and is a file, not directory)
406
828
  if (existsSync(fullPath) && statSync(fullPath).isFile()) {
407
- if (fullPath.includes('..')) {
408
- return reply.status(400).send({ error: 'Invalid path' });
409
- }
410
829
  const ext = extname(fullPath).toLowerCase();
411
830
  const contentType = MIME_TYPES[ext] || 'application/octet-stream';
412
831
  reply.type(contentType);
832
+ setStaticCacheHeader(reply, urlPath);
413
833
  return reply.send(createReadStream(fullPath));
414
834
  }
415
835
  // SPA fallback — serve index.html for client-side routing.
@@ -419,18 +839,22 @@ export async function createServer(config) {
419
839
  const hasFileExt = extname(urlPath).length > 1;
420
840
  if (req.method === 'GET' && !hasFileExt && existsSync(indexPath)) {
421
841
  reply.type('text/html');
842
+ reply.header('Cache-Control', 'no-cache');
422
843
  return reply.send(createReadStream(indexPath));
423
844
  }
424
845
  return reply.status(404).send({ error: 'Not found' });
425
846
  });
426
847
  fastify.log.info('Web UI enabled — serving from dist/web/');
427
848
  }
428
- // Graceful shutdown — flush pending git commits before server closes
849
+ // Graceful shutdown — sessionManager.shutdown() flushes pending commits
850
+ // BEFORE tearing down the timer (the old destroy()-only path could lose
851
+ // dirty sessions if called without an explicit flush).
429
852
  fastify.addHook('onClose', async () => {
430
- await sessionManager.flushAll();
431
- sessionManager.destroy();
432
- yjsManager.destroy();
853
+ await sessionManager.shutdown();
854
+ await assetIndexQueue.shutdown();
855
+ await yjsManager.destroy();
433
856
  wsHub.destroy();
857
+ releaseYjsLock();
434
858
  });
435
859
  return fastify;
436
860
  }