studiograph 1.3.48-next.21 → 1.3.48-next.211

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 (966) hide show
  1. package/README.md +26 -16
  2. package/dist/agent/agent-pool.d.ts +87 -3
  3. package/dist/agent/agent-pool.js +188 -15
  4. package/dist/agent/agent-pool.js.map +1 -1
  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 +101 -4
  9. package/dist/agent/orchestrator.js +464 -66
  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 +112 -54
  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/artifact-canvas/skill.md +152 -0
  19. package/dist/agent/skills/entity-schema.md +75 -431
  20. package/dist/agent/skills/interview/entity-templates.md +38 -37
  21. package/dist/agent/skills/interview/question-domains.md +54 -49
  22. package/dist/agent/skills/interview/skill.md +84 -16
  23. package/dist/agent/skills/schema-rules.md +28 -28
  24. package/dist/agent/tools/artifact-tools.d.ts +124 -0
  25. package/dist/agent/tools/artifact-tools.js +207 -0
  26. package/dist/agent/tools/artifact-tools.js.map +1 -0
  27. package/dist/agent/tools/capture-tools.d.ts +31 -0
  28. package/dist/agent/tools/capture-tools.js +40 -0
  29. package/dist/agent/tools/capture-tools.js.map +1 -0
  30. package/dist/agent/tools/folder-tools.d.ts +47 -0
  31. package/dist/agent/tools/folder-tools.js +249 -0
  32. package/dist/agent/tools/folder-tools.js.map +1 -0
  33. package/dist/agent/tools/fs-tools.d.ts +6 -5
  34. package/dist/agent/tools/fs-tools.js +5 -5
  35. package/dist/agent/tools/fs-tools.js.map +1 -1
  36. package/dist/agent/tools/graph-tools.d.ts +48 -72
  37. package/dist/agent/tools/graph-tools.js +852 -329
  38. package/dist/agent/tools/graph-tools.js.map +1 -1
  39. package/dist/agent/tools/history-tools.d.ts +95 -0
  40. package/dist/agent/tools/history-tools.js +461 -0
  41. package/dist/agent/tools/history-tools.js.map +1 -0
  42. package/dist/agent/tools/load-skill.d.ts +6 -5
  43. package/dist/agent/tools/load-skill.js +3 -3
  44. package/dist/agent/tools/load-skill.js.map +1 -1
  45. package/dist/agent/tools/ops-tools.d.ts +5 -4
  46. package/dist/agent/tools/ops-tools.js +130 -236
  47. package/dist/agent/tools/ops-tools.js.map +1 -1
  48. package/dist/agent/tools/permission-tools.d.ts +87 -17
  49. package/dist/agent/tools/permission-tools.js +233 -43
  50. package/dist/agent/tools/permission-tools.js.map +1 -1
  51. package/dist/agent/tools/tool-loader.js +5 -4
  52. package/dist/agent/tools/tool-loader.js.map +1 -1
  53. package/dist/agent/tools/web-tools.js +58 -9
  54. package/dist/agent/tools/web-tools.js.map +1 -1
  55. package/dist/cli/commands/about.d.ts +1 -0
  56. package/dist/cli/commands/about.js +55 -3
  57. package/dist/cli/commands/about.js.map +1 -1
  58. package/dist/cli/commands/admin/audit-workspace.d.ts +23 -0
  59. package/dist/cli/commands/admin/audit-workspace.js +133 -0
  60. package/dist/cli/commands/admin/audit-workspace.js.map +1 -0
  61. package/dist/cli/commands/admin/audit.d.ts +21 -0
  62. package/dist/cli/commands/admin/audit.js +174 -0
  63. package/dist/cli/commands/admin/audit.js.map +1 -0
  64. package/dist/cli/commands/admin/backup.d.ts +54 -0
  65. package/dist/cli/commands/admin/backup.js +207 -0
  66. package/dist/cli/commands/admin/backup.js.map +1 -0
  67. package/dist/cli/commands/admin/folder.d.ts +11 -0
  68. package/dist/cli/commands/{collection.js → admin/folder.js} +33 -32
  69. package/dist/cli/commands/admin/folder.js.map +1 -0
  70. package/dist/cli/commands/admin/index.d.ts +16 -0
  71. package/dist/cli/commands/admin/index.js +46 -0
  72. package/dist/cli/commands/admin/index.js.map +1 -0
  73. package/dist/cli/commands/admin/migrate-assets.d.ts +53 -0
  74. package/dist/cli/commands/admin/migrate-assets.js +184 -0
  75. package/dist/cli/commands/admin/migrate-assets.js.map +1 -0
  76. package/dist/cli/commands/admin/migrate.d.ts +56 -0
  77. package/dist/cli/commands/admin/migrate.js +263 -0
  78. package/dist/cli/commands/admin/migrate.js.map +1 -0
  79. package/dist/cli/commands/admin/restore.d.ts +24 -0
  80. package/dist/cli/commands/admin/restore.js +228 -0
  81. package/dist/cli/commands/admin/restore.js.map +1 -0
  82. package/dist/cli/commands/admin/secrets.d.ts +23 -0
  83. package/dist/cli/commands/admin/secrets.js +256 -0
  84. package/dist/cli/commands/admin/secrets.js.map +1 -0
  85. package/dist/cli/commands/admin/settings.d.ts +28 -0
  86. package/dist/cli/commands/admin/settings.js +284 -0
  87. package/dist/cli/commands/admin/settings.js.map +1 -0
  88. package/dist/cli/commands/admin/token.d.ts +42 -0
  89. package/dist/cli/commands/admin/token.js +126 -0
  90. package/dist/cli/commands/admin/token.js.map +1 -0
  91. package/dist/cli/commands/admin/transfer-ownership.d.ts +15 -0
  92. package/dist/cli/commands/admin/transfer-ownership.js +106 -0
  93. package/dist/cli/commands/admin/transfer-ownership.js.map +1 -0
  94. package/dist/cli/commands/admin/user.d.ts +11 -0
  95. package/dist/cli/commands/admin/user.js +187 -0
  96. package/dist/cli/commands/admin/user.js.map +1 -0
  97. package/dist/cli/commands/clone.d.ts +25 -3
  98. package/dist/cli/commands/clone.js +142 -36
  99. package/dist/cli/commands/clone.js.map +1 -1
  100. package/dist/cli/commands/config.d.ts +23 -107
  101. package/dist/cli/commands/config.js +52 -260
  102. package/dist/cli/commands/config.js.map +1 -1
  103. package/dist/cli/commands/connector.d.ts +10 -13
  104. package/dist/cli/commands/connector.js +16 -58
  105. package/dist/cli/commands/connector.js.map +1 -1
  106. package/dist/cli/commands/deploy.js +215 -68
  107. package/dist/cli/commands/deploy.js.map +1 -1
  108. package/dist/cli/commands/index.js +5 -1
  109. package/dist/cli/commands/index.js.map +1 -1
  110. package/dist/cli/commands/init.js +10 -30
  111. package/dist/cli/commands/init.js.map +1 -1
  112. package/dist/cli/commands/mcp.js +54 -6
  113. package/dist/cli/commands/mcp.js.map +1 -1
  114. package/dist/cli/commands/r2.d.ts +3 -0
  115. package/dist/cli/commands/r2.js +223 -204
  116. package/dist/cli/commands/r2.js.map +1 -1
  117. package/dist/cli/commands/redeploy.js +65 -12
  118. package/dist/cli/commands/redeploy.js.map +1 -1
  119. package/dist/cli/commands/reset.d.ts +22 -6
  120. package/dist/cli/commands/reset.js +132 -34
  121. package/dist/cli/commands/reset.js.map +1 -1
  122. package/dist/cli/commands/serve.js +231 -26
  123. package/dist/cli/commands/serve.js.map +1 -1
  124. package/dist/cli/commands/sync.d.ts +1 -1
  125. package/dist/cli/commands/sync.js +237 -227
  126. package/dist/cli/commands/sync.js.map +1 -1
  127. package/dist/cli/crypto-bundle.d.ts +39 -0
  128. package/dist/cli/crypto-bundle.js +94 -0
  129. package/dist/cli/crypto-bundle.js.map +1 -0
  130. package/dist/cli/index.js +24 -26
  131. package/dist/cli/index.js.map +1 -1
  132. package/dist/cli/railway-pin.d.ts +68 -0
  133. package/dist/cli/railway-pin.js +96 -0
  134. package/dist/cli/railway-pin.js.map +1 -0
  135. package/dist/cli/railway-provisioning.d.ts +53 -0
  136. package/dist/cli/railway-provisioning.js +85 -0
  137. package/dist/cli/railway-provisioning.js.map +1 -0
  138. package/dist/cli/setup-wizard.d.ts +30 -49
  139. package/dist/cli/setup-wizard.js +39 -40
  140. package/dist/cli/setup-wizard.js.map +1 -1
  141. package/dist/core/accent-palette.d.ts +22 -0
  142. package/dist/core/accent-palette.js +47 -0
  143. package/dist/core/accent-palette.js.map +1 -0
  144. package/dist/core/artifact-asset-urls.d.ts +51 -0
  145. package/dist/core/artifact-asset-urls.js +79 -0
  146. package/dist/core/artifact-asset-urls.js.map +1 -0
  147. package/dist/core/artifact-bundle.d.ts +69 -0
  148. package/dist/core/artifact-bundle.js +305 -0
  149. package/dist/core/artifact-bundle.js.map +1 -0
  150. package/dist/core/artifact-escape.d.ts +5 -0
  151. package/dist/core/artifact-escape.js +26 -0
  152. package/dist/core/artifact-escape.js.map +1 -0
  153. package/dist/core/artifact-export.d.ts +17 -0
  154. package/dist/core/artifact-export.js +529 -0
  155. package/dist/core/artifact-export.js.map +1 -0
  156. package/dist/core/cell-anchor.d.ts +29 -0
  157. package/dist/core/cell-anchor.js +53 -0
  158. package/dist/core/cell-anchor.js.map +1 -0
  159. package/dist/core/comment-anchor.d.ts +41 -0
  160. package/dist/core/comment-anchor.js +147 -0
  161. package/dist/core/comment-anchor.js.map +1 -0
  162. package/dist/core/commit-messages.d.ts +57 -0
  163. package/dist/core/commit-messages.js +85 -0
  164. package/dist/core/commit-messages.js.map +1 -0
  165. package/dist/core/embeds.d.ts +96 -0
  166. package/dist/core/embeds.js +196 -0
  167. package/dist/core/embeds.js.map +1 -0
  168. package/dist/core/entity-body-templates.d.ts +21 -0
  169. package/dist/core/entity-body-templates.js +67 -0
  170. package/dist/core/entity-body-templates.js.map +1 -0
  171. package/dist/core/entity-types-catalog.d.ts +65 -0
  172. package/dist/core/entity-types-catalog.js +142 -0
  173. package/dist/core/entity-types-catalog.js.map +1 -0
  174. package/dist/core/field-library.d.ts +62 -0
  175. package/dist/core/field-library.js +129 -0
  176. package/dist/core/field-library.js.map +1 -0
  177. package/dist/core/folder-paths.d.ts +41 -0
  178. package/dist/core/folder-paths.js +95 -0
  179. package/dist/core/folder-paths.js.map +1 -0
  180. package/dist/core/folder-sidecar.d.ts +36 -0
  181. package/dist/core/folder-sidecar.js +91 -0
  182. package/dist/core/folder-sidecar.js.map +1 -0
  183. package/dist/core/format-registry.d.ts +170 -0
  184. package/dist/core/format-registry.js +412 -0
  185. package/dist/core/format-registry.js.map +1 -0
  186. package/dist/core/graph.d.ts +773 -14
  187. package/dist/core/graph.js +2269 -308
  188. package/dist/core/graph.js.map +1 -1
  189. package/dist/core/history-diff.d.ts +35 -0
  190. package/dist/core/history-diff.js +114 -0
  191. package/dist/core/history-diff.js.map +1 -0
  192. package/dist/core/refs.d.ts +41 -0
  193. package/dist/core/refs.js +80 -0
  194. package/dist/core/refs.js.map +1 -0
  195. package/dist/core/schema-registry.d.ts +66 -0
  196. package/dist/core/schema-registry.js +198 -37
  197. package/dist/core/schema-registry.js.map +1 -1
  198. package/dist/core/schemas/connector.d.ts +67 -0
  199. package/dist/core/schemas/connector.js +100 -0
  200. package/dist/core/schemas/connector.js.map +1 -0
  201. package/dist/core/schemas/workspace.d.ts +122 -0
  202. package/dist/core/schemas/workspace.js +211 -0
  203. package/dist/core/schemas/workspace.js.map +1 -0
  204. package/dist/core/secrets/SecretStore.d.ts +77 -0
  205. package/dist/core/secrets/SecretStore.js +13 -0
  206. package/dist/core/secrets/SecretStore.js.map +1 -0
  207. package/dist/core/secrets/SettingsResolver.d.ts +54 -0
  208. package/dist/core/secrets/SettingsResolver.js +80 -0
  209. package/dist/core/secrets/SettingsResolver.js.map +1 -0
  210. package/dist/core/secrets/SettingsStore.d.ts +30 -0
  211. package/dist/core/secrets/SettingsStore.js +9 -0
  212. package/dist/core/secrets/SettingsStore.js.map +1 -0
  213. package/dist/core/secrets/SqliteEncryptedStore.d.ts +90 -0
  214. package/dist/core/secrets/SqliteEncryptedStore.js +598 -0
  215. package/dist/core/secrets/SqliteEncryptedStore.js.map +1 -0
  216. package/dist/core/secrets/audit.d.ts +36 -0
  217. package/dist/core/secrets/audit.js +60 -0
  218. package/dist/core/secrets/audit.js.map +1 -0
  219. package/dist/core/secrets/auth-db-migration.d.ts +129 -0
  220. package/dist/core/secrets/auth-db-migration.js +653 -0
  221. package/dist/core/secrets/auth-db-migration.js.map +1 -0
  222. package/dist/core/secrets/bundle.d.ts +141 -0
  223. package/dist/core/secrets/bundle.js +435 -0
  224. package/dist/core/secrets/bundle.js.map +1 -0
  225. package/dist/core/secrets/dual-write.d.ts +81 -0
  226. package/dist/core/secrets/dual-write.js +247 -0
  227. package/dist/core/secrets/dual-write.js.map +1 -0
  228. package/dist/core/secrets/encryption.d.ts +44 -0
  229. package/dist/core/secrets/encryption.js +97 -0
  230. package/dist/core/secrets/encryption.js.map +1 -0
  231. package/dist/core/secrets/index.d.ts +49 -0
  232. package/dist/core/secrets/index.js +74 -0
  233. package/dist/core/secrets/index.js.map +1 -0
  234. package/dist/core/secrets/master-key.d.ts +38 -0
  235. package/dist/core/secrets/master-key.js +122 -0
  236. package/dist/core/secrets/master-key.js.map +1 -0
  237. package/dist/core/secrets/probes/anthropic.d.ts +98 -0
  238. package/dist/core/secrets/probes/anthropic.js +300 -0
  239. package/dist/core/secrets/probes/anthropic.js.map +1 -0
  240. package/dist/core/secrets/probes/brave.d.ts +9 -0
  241. package/dist/core/secrets/probes/brave.js +15 -0
  242. package/dist/core/secrets/probes/brave.js.map +1 -0
  243. package/dist/core/secrets/probes/r2.d.ts +15 -0
  244. package/dist/core/secrets/probes/r2.js +14 -0
  245. package/dist/core/secrets/probes/r2.js.map +1 -0
  246. package/dist/core/secrets/probes/tavily.d.ts +18 -0
  247. package/dist/core/secrets/probes/tavily.js +58 -0
  248. package/dist/core/secrets/probes/tavily.js.map +1 -0
  249. package/dist/core/secrets/probes/voyage.d.ts +13 -0
  250. package/dist/core/secrets/probes/voyage.js +52 -0
  251. package/dist/core/secrets/probes/voyage.js.map +1 -0
  252. package/dist/core/secrets/r2-structural-migration.d.ts +39 -0
  253. package/dist/core/secrets/r2-structural-migration.js +109 -0
  254. package/dist/core/secrets/r2-structural-migration.js.map +1 -0
  255. package/dist/core/secrets/read-flip.d.ts +59 -0
  256. package/dist/core/secrets/read-flip.js +87 -0
  257. package/dist/core/secrets/read-flip.js.map +1 -0
  258. package/dist/core/secrets/registry.d.ts +188 -0
  259. package/dist/core/secrets/registry.js +616 -0
  260. package/dist/core/secrets/registry.js.map +1 -0
  261. package/dist/core/types.d.ts +77 -483
  262. package/dist/core/types.js +25 -3
  263. package/dist/core/types.js.map +1 -1
  264. package/dist/core/user-config.d.ts +75 -12
  265. package/dist/core/user-config.js +155 -14
  266. package/dist/core/user-config.js.map +1 -1
  267. package/dist/core/validation.d.ts +786 -1373
  268. package/dist/core/validation.js +458 -147
  269. package/dist/core/validation.js.map +1 -1
  270. package/dist/core/workspace-manager.d.ts +87 -14
  271. package/dist/core/workspace-manager.js +222 -94
  272. package/dist/core/workspace-manager.js.map +1 -1
  273. package/dist/core/workspace.d.ts +19 -5
  274. package/dist/core/workspace.js +67 -39
  275. package/dist/core/workspace.js.map +1 -1
  276. package/dist/mcp/comment-virtual-entity.d.ts +36 -0
  277. package/dist/mcp/comment-virtual-entity.js +71 -0
  278. package/dist/mcp/comment-virtual-entity.js.map +1 -0
  279. package/dist/mcp/connector-manager.d.ts +72 -2
  280. package/dist/mcp/connector-manager.js +211 -32
  281. package/dist/mcp/connector-manager.js.map +1 -1
  282. package/dist/mcp/oauth-provider.d.ts +0 -5
  283. package/dist/mcp/oauth-provider.js +10 -22
  284. package/dist/mcp/oauth-provider.js.map +1 -1
  285. package/dist/mcp/oauth-registry.d.ts +46 -8
  286. package/dist/mcp/oauth-registry.js +52 -13
  287. package/dist/mcp/oauth-registry.js.map +1 -1
  288. package/dist/mcp/server-discovery.d.ts +73 -0
  289. package/dist/mcp/server-discovery.js +164 -0
  290. package/dist/mcp/server-discovery.js.map +1 -0
  291. package/dist/mcp/server.d.ts +24 -3
  292. package/dist/mcp/server.js +53 -10
  293. package/dist/mcp/server.js.map +1 -1
  294. package/dist/mcp/state-signer.d.ts +62 -0
  295. package/dist/mcp/state-signer.js +205 -0
  296. package/dist/mcp/state-signer.js.map +1 -0
  297. package/dist/mcp/stdio-proxy.d.ts +67 -0
  298. package/dist/mcp/stdio-proxy.js +149 -0
  299. package/dist/mcp/stdio-proxy.js.map +1 -0
  300. package/dist/mcp/tools.d.ts +65 -2
  301. package/dist/mcp/tools.js +1772 -124
  302. package/dist/mcp/tools.js.map +1 -1
  303. package/dist/server/__tests__/helpers/graph-api.d.ts +16 -0
  304. package/dist/server/__tests__/helpers/graph-api.js +16 -0
  305. package/dist/server/__tests__/helpers/graph-api.js.map +1 -0
  306. package/dist/server/artifact-asset-mint.d.ts +41 -0
  307. package/dist/server/artifact-asset-mint.js +59 -0
  308. package/dist/server/artifact-asset-mint.js.map +1 -0
  309. package/dist/server/asset-index-queue.d.ts +98 -0
  310. package/dist/server/asset-index-queue.js +193 -0
  311. package/dist/server/asset-index-queue.js.map +1 -0
  312. package/dist/server/body-write-coordinator.d.ts +161 -0
  313. package/dist/server/body-write-coordinator.js +182 -0
  314. package/dist/server/body-write-coordinator.js.map +1 -0
  315. package/dist/server/cloud-billing-flow.d.ts +32 -0
  316. package/dist/server/cloud-billing-flow.js +75 -0
  317. package/dist/server/cloud-billing-flow.js.map +1 -0
  318. package/dist/server/commit-audit.d.ts +26 -0
  319. package/dist/server/commit-audit.js +30 -0
  320. package/dist/server/commit-audit.js.map +1 -0
  321. package/dist/server/index.d.ts +29 -3
  322. package/dist/server/index.js +657 -269
  323. package/dist/server/index.js.map +1 -1
  324. package/dist/server/middleware/sanitize.d.ts +46 -0
  325. package/dist/server/middleware/sanitize.js +182 -0
  326. package/dist/server/middleware/sanitize.js.map +1 -0
  327. package/dist/server/routes/artifact-export-api.d.ts +11 -0
  328. package/dist/server/routes/artifact-export-api.js +159 -0
  329. package/dist/server/routes/artifact-export-api.js.map +1 -0
  330. package/dist/server/routes/asset-api.d.ts +76 -1
  331. package/dist/server/routes/asset-api.js +761 -61
  332. package/dist/server/routes/asset-api.js.map +1 -1
  333. package/dist/server/routes/audit-api.d.ts +24 -0
  334. package/dist/server/routes/audit-api.js +117 -0
  335. package/dist/server/routes/audit-api.js.map +1 -0
  336. package/dist/server/routes/auth-api.js +532 -63
  337. package/dist/server/routes/auth-api.js.map +1 -1
  338. package/dist/server/routes/capture-api.d.ts +10 -3
  339. package/dist/server/routes/capture-api.js +213 -25
  340. package/dist/server/routes/capture-api.js.map +1 -1
  341. package/dist/server/routes/chat-sessions-api.d.ts +13 -0
  342. package/dist/server/routes/chat-sessions-api.js +455 -0
  343. package/dist/server/routes/chat-sessions-api.js.map +1 -0
  344. package/dist/server/routes/chat.d.ts +35 -1
  345. package/dist/server/routes/chat.js +699 -54
  346. package/dist/server/routes/chat.js.map +1 -1
  347. package/dist/server/routes/comments-api.d.ts +15 -0
  348. package/dist/server/routes/comments-api.js +444 -0
  349. package/dist/server/routes/comments-api.js.map +1 -0
  350. package/dist/server/routes/config-api.d.ts +3 -2
  351. package/dist/server/routes/config-api.js +179 -49
  352. package/dist/server/routes/config-api.js.map +1 -1
  353. package/dist/server/routes/connectors-api.js +177 -42
  354. package/dist/server/routes/connectors-api.js.map +1 -1
  355. package/dist/server/routes/event-ingest-api.d.ts +15 -0
  356. package/dist/server/routes/{meeting-ingest-api.js → event-ingest-api.js} +35 -20
  357. package/dist/server/routes/event-ingest-api.js.map +1 -0
  358. package/dist/server/routes/field-library-api.d.ts +28 -0
  359. package/dist/server/routes/field-library-api.js +126 -0
  360. package/dist/server/routes/field-library-api.js.map +1 -0
  361. package/dist/server/routes/git-http.d.ts +2 -2
  362. package/dist/server/routes/git-http.js +86 -39
  363. package/dist/server/routes/git-http.js.map +1 -1
  364. package/dist/server/routes/graph-api-access.d.ts +57 -0
  365. package/dist/server/routes/graph-api-access.js +112 -0
  366. package/dist/server/routes/graph-api-access.js.map +1 -0
  367. package/dist/server/routes/graph-api.d.ts +1 -1
  368. package/dist/server/routes/graph-api.js +1455 -325
  369. package/dist/server/routes/graph-api.js.map +1 -1
  370. package/dist/server/routes/health.d.ts +18 -0
  371. package/dist/server/routes/health.js +74 -0
  372. package/dist/server/routes/health.js.map +1 -0
  373. package/dist/server/routes/import-batch.d.ts +24 -0
  374. package/dist/server/routes/import-batch.js +33 -0
  375. package/dist/server/routes/import-batch.js.map +1 -0
  376. package/dist/server/routes/insights-api.d.ts +9 -2
  377. package/dist/server/routes/insights-api.js +355 -61
  378. package/dist/server/routes/insights-api.js.map +1 -1
  379. package/dist/server/routes/mcp.d.ts +7 -3
  380. package/dist/server/routes/mcp.js +24 -8
  381. package/dist/server/routes/mcp.js.map +1 -1
  382. package/dist/server/routes/oauth-api.d.ts +67 -0
  383. package/dist/server/routes/oauth-api.js +421 -0
  384. package/dist/server/routes/oauth-api.js.map +1 -0
  385. package/dist/server/routes/permissions-api.d.ts +9 -2
  386. package/dist/server/routes/permissions-api.js +87 -31
  387. package/dist/server/routes/permissions-api.js.map +1 -1
  388. package/dist/server/routes/r2-api.d.ts +25 -0
  389. package/dist/server/routes/r2-api.js +276 -0
  390. package/dist/server/routes/r2-api.js.map +1 -0
  391. package/dist/server/routes/secrets-api.d.ts +36 -0
  392. package/dist/server/routes/secrets-api.js +308 -0
  393. package/dist/server/routes/secrets-api.js.map +1 -0
  394. package/dist/server/routes/settings-api.d.ts +29 -0
  395. package/dist/server/routes/settings-api.js +180 -0
  396. package/dist/server/routes/settings-api.js.map +1 -0
  397. package/dist/server/routes/share-api.d.ts +32 -0
  398. package/dist/server/routes/share-api.js +234 -0
  399. package/dist/server/routes/share-api.js.map +1 -0
  400. package/dist/server/routes/views-api.js +51 -0
  401. package/dist/server/routes/views-api.js.map +1 -1
  402. package/dist/server/routes/workspace-api.d.ts +2 -1
  403. package/dist/server/routes/workspace-api.js +142 -23
  404. package/dist/server/routes/workspace-api.js.map +1 -1
  405. package/dist/server/routes/ws.d.ts +3 -2
  406. package/dist/server/routes/ws.js +68 -17
  407. package/dist/server/routes/ws.js.map +1 -1
  408. package/dist/server/session-manager.d.ts +48 -5
  409. package/dist/server/session-manager.js +182 -14
  410. package/dist/server/session-manager.js.map +1 -1
  411. package/dist/server/ws-hub.d.ts +124 -37
  412. package/dist/server/ws-hub.js +0 -0
  413. package/dist/server/ws-hub.js.map +1 -1
  414. package/dist/server/yjs-manager.d.ts +278 -7
  415. package/dist/server/yjs-manager.js +830 -38
  416. package/dist/server/yjs-manager.js.map +1 -1
  417. package/dist/server/yjs-persistence.d.ts +165 -0
  418. package/dist/server/yjs-persistence.js +557 -0
  419. package/dist/server/yjs-persistence.js.map +1 -0
  420. package/dist/server/yjs-text-diff.d.ts +32 -0
  421. package/dist/server/yjs-text-diff.js +61 -0
  422. package/dist/server/yjs-text-diff.js.map +1 -0
  423. package/dist/services/access-control.d.ts +73 -0
  424. package/dist/services/access-control.js +165 -0
  425. package/dist/services/access-control.js.map +1 -0
  426. package/dist/services/artifact-asset-token.d.ts +69 -0
  427. package/dist/services/artifact-asset-token.js +94 -0
  428. package/dist/services/artifact-asset-token.js.map +1 -0
  429. package/dist/services/artifact-library-sources.d.ts +3 -0
  430. package/dist/services/artifact-library-sources.js +44 -0
  431. package/dist/services/artifact-library-sources.js.map +1 -0
  432. package/dist/services/artifact-render-export.d.ts +97 -0
  433. package/dist/services/artifact-render-export.js +467 -0
  434. package/dist/services/artifact-render-export.js.map +1 -0
  435. package/dist/services/asset-caption-service.d.ts +103 -0
  436. package/dist/services/asset-caption-service.js +186 -0
  437. package/dist/services/asset-caption-service.js.map +1 -0
  438. package/dist/services/asset-delete-authz.d.ts +31 -0
  439. package/dist/services/asset-delete-authz.js +61 -0
  440. package/dist/services/asset-delete-authz.js.map +1 -0
  441. package/dist/services/asset-finalize-service.d.ts +58 -0
  442. package/dist/services/asset-finalize-service.js +216 -0
  443. package/dist/services/asset-finalize-service.js.map +1 -0
  444. package/dist/services/asset-import-service.d.ts +111 -0
  445. package/dist/services/asset-import-service.js +394 -0
  446. package/dist/services/asset-import-service.js.map +1 -0
  447. package/dist/services/asset-index-sweep.d.ts +95 -0
  448. package/dist/services/asset-index-sweep.js +249 -0
  449. package/dist/services/asset-index-sweep.js.map +1 -0
  450. package/dist/services/asset-lifecycle-check.d.ts +22 -0
  451. package/dist/services/asset-lifecycle-check.js +80 -0
  452. package/dist/services/asset-lifecycle-check.js.map +1 -0
  453. package/dist/services/asset-listing.d.ts +72 -0
  454. package/dist/services/asset-listing.js +321 -0
  455. package/dist/services/asset-listing.js.map +1 -0
  456. package/dist/services/asset-presign-service.d.ts +68 -0
  457. package/dist/services/asset-presign-service.js +124 -0
  458. package/dist/services/asset-presign-service.js.map +1 -0
  459. package/dist/services/asset-sidecar-service.d.ts +28 -0
  460. package/dist/services/asset-sidecar-service.js +79 -0
  461. package/dist/services/asset-sidecar-service.js.map +1 -0
  462. package/dist/services/asset-upload-errors.d.ts +41 -0
  463. package/dist/services/asset-upload-errors.js +45 -0
  464. package/dist/services/asset-upload-errors.js.map +1 -0
  465. package/dist/services/asset-upload-service.d.ts +56 -0
  466. package/dist/services/asset-upload-service.js +200 -0
  467. package/dist/services/asset-upload-service.js.map +1 -0
  468. package/dist/services/asset-upload-token.d.ts +58 -0
  469. package/dist/services/asset-upload-token.js +75 -0
  470. package/dist/services/asset-upload-token.js.map +1 -0
  471. package/dist/services/assets/asset-index-service.d.ts +127 -0
  472. package/dist/services/assets/asset-index-service.js +227 -0
  473. package/dist/services/assets/asset-index-service.js.map +1 -0
  474. package/dist/services/assets/base.d.ts +128 -2
  475. package/dist/services/assets/base.js +98 -1
  476. package/dist/services/assets/base.js.map +1 -1
  477. package/dist/services/assets/index.d.ts +114 -1
  478. package/dist/services/assets/index.js +221 -0
  479. package/dist/services/assets/index.js.map +1 -1
  480. package/dist/services/assets/local.d.ts +16 -1
  481. package/dist/services/assets/local.js +110 -1
  482. package/dist/services/assets/local.js.map +1 -1
  483. package/dist/services/assets/r2-sync.d.ts +88 -0
  484. package/dist/services/assets/r2-sync.js +412 -0
  485. package/dist/services/assets/r2-sync.js.map +1 -0
  486. package/dist/services/assets/r2.d.ts +87 -1
  487. package/dist/services/assets/r2.js +203 -1
  488. package/dist/services/assets/r2.js.map +1 -1
  489. package/dist/services/auth-service.d.ts +312 -45
  490. package/dist/services/auth-service.js +1011 -195
  491. package/dist/services/auth-service.js.map +1 -1
  492. package/dist/services/chat-session-service.d.ts +188 -0
  493. package/dist/services/chat-session-service.js +512 -0
  494. package/dist/services/chat-session-service.js.map +1 -0
  495. package/dist/services/cloud-inference-billing.d.ts +64 -0
  496. package/dist/services/cloud-inference-billing.js +313 -0
  497. package/dist/services/cloud-inference-billing.js.map +1 -0
  498. package/dist/services/comment-service.d.ts +97 -0
  499. package/dist/services/comment-service.js +341 -0
  500. package/dist/services/comment-service.js.map +1 -0
  501. package/dist/services/comment-virtual-entity.d.ts +36 -0
  502. package/dist/services/comment-virtual-entity.js +71 -0
  503. package/dist/services/comment-virtual-entity.js.map +1 -0
  504. package/dist/services/convert-service.d.ts +64 -0
  505. package/dist/services/convert-service.js +68 -0
  506. package/dist/services/convert-service.js.map +1 -0
  507. package/dist/services/csv-service.d.ts +22 -17
  508. package/dist/services/csv-service.js +55 -92
  509. package/dist/services/csv-service.js.map +1 -1
  510. package/dist/services/entity-mutations.d.ts +213 -0
  511. package/dist/services/entity-mutations.js +380 -0
  512. package/dist/services/entity-mutations.js.map +1 -0
  513. package/dist/services/{meeting-processor.d.ts → event-processor.d.ts} +15 -8
  514. package/dist/services/{meeting-processor.js → event-processor.js} +124 -65
  515. package/dist/services/event-processor.js.map +1 -0
  516. package/dist/services/extract/docx.d.ts +1 -0
  517. package/dist/services/extract/docx.js +233 -0
  518. package/dist/services/extract/docx.js.map +1 -0
  519. package/dist/services/extract/index.d.ts +9 -0
  520. package/dist/services/extract/index.js +10 -0
  521. package/dist/services/extract/index.js.map +1 -0
  522. package/dist/services/extract/pdf.d.ts +13 -0
  523. package/dist/services/extract/pdf.js +69 -0
  524. package/dist/services/extract/pdf.js.map +1 -0
  525. package/dist/services/folder-creation.d.ts +33 -0
  526. package/dist/services/folder-creation.js +103 -0
  527. package/dist/services/folder-creation.js.map +1 -0
  528. package/dist/services/git.d.ts +58 -0
  529. package/dist/services/git.js +194 -55
  530. package/dist/services/git.js.map +1 -1
  531. package/dist/services/graph-maintenance.js +4 -4
  532. package/dist/services/graph-maintenance.js.map +1 -1
  533. package/dist/services/import-service.d.ts +51 -2
  534. package/dist/services/import-service.js +254 -107
  535. package/dist/services/import-service.js.map +1 -1
  536. package/dist/services/lint-service.js +10 -17
  537. package/dist/services/lint-service.js.map +1 -1
  538. package/dist/services/markdown.d.ts +12 -1
  539. package/dist/services/markdown.js +77 -9
  540. package/dist/services/markdown.js.map +1 -1
  541. package/dist/services/mention-detector.d.ts +23 -0
  542. package/dist/services/mention-detector.js +47 -0
  543. package/dist/services/mention-detector.js.map +1 -0
  544. package/dist/services/model-capabilities.d.ts +41 -0
  545. package/dist/services/model-capabilities.js +107 -0
  546. package/dist/services/model-capabilities.js.map +1 -0
  547. package/dist/services/notification-broadcast.d.ts +32 -0
  548. package/dist/services/notification-broadcast.js +38 -0
  549. package/dist/services/notification-broadcast.js.map +1 -0
  550. package/dist/services/notification-service.d.ts +41 -0
  551. package/dist/services/notification-service.js +100 -0
  552. package/dist/services/notification-service.js.map +1 -0
  553. package/dist/services/oauth-server-store.d.ts +147 -0
  554. package/dist/services/oauth-server-store.js +319 -0
  555. package/dist/services/oauth-server-store.js.map +1 -0
  556. package/dist/services/orphan-service.js +2 -2
  557. package/dist/services/orphan-service.js.map +1 -1
  558. package/dist/services/personal-folder.d.ts +40 -0
  559. package/dist/services/personal-folder.js +101 -0
  560. package/dist/services/personal-folder.js.map +1 -0
  561. package/dist/services/scratch-asset-promote.d.ts +57 -0
  562. package/dist/services/scratch-asset-promote.js +95 -0
  563. package/dist/services/scratch-asset-promote.js.map +1 -0
  564. package/dist/services/scratch-attachment-service.d.ts +196 -0
  565. package/dist/services/scratch-attachment-service.js +347 -0
  566. package/dist/services/scratch-attachment-service.js.map +1 -0
  567. package/dist/services/share-link-service.d.ts +57 -0
  568. package/dist/services/share-link-service.js +142 -0
  569. package/dist/services/share-link-service.js.map +1 -0
  570. package/dist/services/user-person-bridge.d.ts +136 -0
  571. package/dist/services/user-person-bridge.js +340 -0
  572. package/dist/services/user-person-bridge.js.map +1 -0
  573. package/dist/services/vector-service.d.ts +282 -5
  574. package/dist/services/vector-service.js +585 -29
  575. package/dist/services/vector-service.js.map +1 -1
  576. package/dist/services/workspace-access.d.ts +108 -0
  577. package/dist/services/workspace-access.js +149 -0
  578. package/dist/services/workspace-access.js.map +1 -0
  579. package/dist/services/workspace-assets-folder.d.ts +46 -0
  580. package/dist/services/workspace-assets-folder.js +75 -0
  581. package/dist/services/workspace-assets-folder.js.map +1 -0
  582. package/dist/utils/git.d.ts +17 -2
  583. package/dist/utils/git.js +23 -7
  584. package/dist/utils/git.js.map +1 -1
  585. package/dist/utils/log.d.ts +42 -0
  586. package/dist/utils/log.js +137 -0
  587. package/dist/utils/log.js.map +1 -0
  588. package/dist/utils/preflight.js +2 -2
  589. package/dist/utils/preflight.js.map +1 -1
  590. package/dist/utils/version-checker.d.ts +12 -19
  591. package/dist/utils/version-checker.js +14 -104
  592. package/dist/utils/version-checker.js.map +1 -1
  593. package/dist/web/_app/immutable/assets/0.Bs_z3Z86.css +2 -0
  594. package/dist/web/_app/immutable/assets/12.DlIf1mKh.css +1 -0
  595. package/dist/web/_app/immutable/assets/14.7d-Q37wc.css +1 -0
  596. package/dist/web/_app/immutable/assets/15.BwBFdc1D.css +1 -0
  597. package/dist/web/_app/immutable/assets/16.CmLrbzZp.css +1 -0
  598. package/dist/web/_app/immutable/assets/17.DcuK5ZVm.css +1 -0
  599. package/dist/web/_app/immutable/assets/2.DATnR31c.css +1 -0
  600. package/dist/web/_app/immutable/assets/3.Cz4H8n_O.css +1 -0
  601. package/dist/web/_app/immutable/assets/4.aDHteTDy.css +1 -0
  602. package/dist/web/_app/immutable/assets/6.CF1i5Bon.css +1 -0
  603. package/dist/web/_app/immutable/assets/ArtifactEntityView.C4ooklFD.css +1 -0
  604. package/dist/web/_app/immutable/assets/AssetLibraryPicker.BOFW0MvF.css +1 -0
  605. package/dist/web/_app/immutable/assets/BulkActionsBar.cmKvHzRK.css +1 -0
  606. package/dist/web/_app/immutable/assets/CalendarView.lBCvS3X5.css +1 -0
  607. package/dist/web/_app/immutable/assets/CodeMirrorEditor.D6hf2pNJ.css +1 -0
  608. package/dist/web/_app/immutable/assets/CopyField.DVGZtw4U.css +1 -0
  609. package/dist/web/_app/immutable/assets/FolderMembersPanel.kiYnDFHu.css +1 -0
  610. package/dist/web/_app/immutable/assets/FolderMutationDialogs.BMRF6Z3z.css +1 -0
  611. package/dist/web/_app/immutable/assets/FolderPicker.Cp46GHe2.css +1 -0
  612. package/dist/web/_app/immutable/assets/GalleryView.WBGxxUQc.css +1 -0
  613. package/dist/web/_app/immutable/assets/GraphView.BJtGL9py.css +1 -0
  614. package/dist/web/_app/immutable/assets/KanbanView.BOaI5KFL.css +1 -0
  615. package/dist/web/_app/immutable/assets/Link.vV0ne105.css +1 -0
  616. package/dist/web/_app/immutable/assets/Markdown.BZnsSOSf.css +1 -0
  617. package/dist/web/_app/immutable/assets/Rail.ilusFgD4.css +1 -0
  618. package/dist/web/_app/immutable/assets/SettingsDialog.D7-BO6S_.css +1 -0
  619. package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
  620. package/dist/web/_app/immutable/assets/StopFilledAlt.fNlDN65D.css +1 -0
  621. package/dist/web/_app/immutable/assets/TimelineView.xAZBJhHw.css +1 -0
  622. package/dist/web/_app/immutable/assets/WorkspaceView.C8ErUJAY.css +1 -0
  623. package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
  624. package/dist/web/_app/immutable/assets/history-summary.LpmHXasl.css +1 -0
  625. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff +0 -0
  626. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2 +0 -0
  627. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff +0 -0
  628. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2 +0 -0
  629. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CZTNEAuW.woff2 +0 -0
  630. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CsGl1sm0.woff +0 -0
  631. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2 +0 -0
  632. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff +0 -0
  633. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.BNK2_mGO.woff2 +0 -0
  634. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.DpEwFAQM.woff +0 -0
  635. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2 +0 -0
  636. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff +0 -0
  637. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff +0 -0
  638. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2 +0 -0
  639. package/dist/web/_app/immutable/assets/inline-list.cqga56xT.css +1 -0
  640. package/dist/web/_app/immutable/assets/list-columns.BgnafZ4K.css +1 -0
  641. package/dist/web/_app/immutable/assets/realtime.DDCWxn3B.css +1 -0
  642. package/dist/web/_app/immutable/assets/select.B90KUqR4.css +1 -0
  643. package/dist/web/_app/immutable/assets/sheet.RF9RBmml.css +1 -0
  644. package/dist/web/_app/immutable/chunks/22qYtvr82.js +1 -0
  645. package/dist/web/_app/immutable/chunks/2f1VclTm.js +1 -0
  646. package/dist/web/_app/immutable/chunks/4xgUPoGj2.js +2 -0
  647. package/dist/web/_app/immutable/chunks/5CYQk4xR.js +1 -0
  648. package/dist/web/_app/immutable/chunks/6S9WOky52.js +1 -0
  649. package/dist/web/_app/immutable/chunks/9K8VREGP.js +1 -0
  650. package/dist/web/_app/immutable/chunks/B-n5q6ku.js +1 -0
  651. package/dist/web/_app/immutable/chunks/B0p2fSEV2.js +1 -0
  652. package/dist/web/_app/immutable/chunks/B2oi87jG.js +2 -0
  653. package/dist/web/_app/immutable/chunks/B5Rb52QU.js +1 -0
  654. package/dist/web/_app/immutable/chunks/B6Lt-qaJ.js +1 -0
  655. package/dist/web/_app/immutable/chunks/B6O-q2CN.js +1 -0
  656. package/dist/web/_app/immutable/chunks/B6qeIQZz.js +2 -0
  657. package/dist/web/_app/immutable/chunks/B9KfEsQw2.js +1 -0
  658. package/dist/web/_app/immutable/chunks/BB-RSeXQ.js +1 -0
  659. package/dist/web/_app/immutable/chunks/BCQQzpbj.js +1 -0
  660. package/dist/web/_app/immutable/chunks/BGdzd-Tc.js +1 -0
  661. package/dist/web/_app/immutable/chunks/BLs1h0Rh2.js +1 -0
  662. package/dist/web/_app/immutable/chunks/BPzV_xOS2.js +1 -0
  663. package/dist/web/_app/immutable/chunks/BT2C6q8n.js +1 -0
  664. package/dist/web/_app/immutable/chunks/BUesbLq2.js +1 -0
  665. package/dist/web/_app/immutable/chunks/BUrnwOw4.js +2 -0
  666. package/dist/web/_app/immutable/chunks/BV-iCKqa.js +1 -0
  667. package/dist/web/_app/immutable/chunks/BVCJtXyc.js +1 -0
  668. package/dist/web/_app/immutable/chunks/BY9a3GSt.js +6 -0
  669. package/dist/web/_app/immutable/chunks/BZi3uKF4.js +1 -0
  670. package/dist/web/_app/immutable/chunks/BbfHGU9n2.js +1 -0
  671. package/dist/web/_app/immutable/chunks/Bbqu2-5G2.js +1 -0
  672. package/dist/web/_app/immutable/chunks/BbsX1Slr.js +3 -0
  673. package/dist/web/_app/immutable/chunks/BcwjqHaZ2.js +1 -0
  674. package/dist/web/_app/immutable/chunks/BizeEpTx.js +2 -0
  675. package/dist/web/_app/immutable/chunks/BlgjVmFM2.js +14 -0
  676. package/dist/web/_app/immutable/chunks/BocSRgv12.js +1 -0
  677. package/dist/web/_app/immutable/chunks/BojBYqc3.js +1 -0
  678. package/dist/web/_app/immutable/chunks/BpCG9m962.js +1 -0
  679. package/dist/web/_app/immutable/chunks/BqvnBg_y.js +1 -0
  680. package/dist/web/_app/immutable/chunks/BsT0J1QD.js +1 -0
  681. package/dist/web/_app/immutable/chunks/BsW72fyR2.js +1 -0
  682. package/dist/web/_app/immutable/chunks/Bti_XKwx.js +2692 -0
  683. package/dist/web/_app/immutable/chunks/Bua97Had2.js +2 -0
  684. package/dist/web/_app/immutable/chunks/BuhW5Fr0.js +689 -0
  685. package/dist/web/_app/immutable/chunks/Bx74EEyn2.js +1 -0
  686. package/dist/web/_app/immutable/chunks/BxPN0T61.js +1 -0
  687. package/dist/web/_app/immutable/chunks/Bz9lrgGs.js +1 -0
  688. package/dist/web/_app/immutable/chunks/BzaxZ6j12.js +1 -0
  689. package/dist/web/_app/immutable/chunks/C1B4xDs0.js +1 -0
  690. package/dist/web/_app/immutable/chunks/C1trcC8M.js +7 -0
  691. package/dist/web/_app/immutable/chunks/C9tvkk7Y2.js +22 -0
  692. package/dist/web/_app/immutable/chunks/CBQjdDZf.js +1 -0
  693. package/dist/web/_app/immutable/chunks/CDeazMFW2.js +2 -0
  694. package/dist/web/_app/immutable/chunks/CEahbtnP.js +1 -0
  695. package/dist/web/_app/immutable/chunks/CGjVCd0e.js +8 -0
  696. package/dist/web/_app/immutable/chunks/CICK9maP.js +1 -0
  697. package/dist/web/_app/immutable/chunks/CIoNEHQ82.js +184 -0
  698. package/dist/web/_app/immutable/chunks/CP8_U450.js +1 -0
  699. package/dist/web/_app/immutable/chunks/CQ1eQ93t2.js +6 -0
  700. package/dist/web/_app/immutable/chunks/CUFQMEBn2.js +1 -0
  701. package/dist/web/_app/immutable/chunks/CYEYDNwO2.js +1 -0
  702. package/dist/web/_app/immutable/chunks/CYyIP7kP2.js +66 -0
  703. package/dist/web/_app/immutable/chunks/CZgFaimi2.js +83 -0
  704. package/dist/web/_app/immutable/chunks/CZqvCTCv.js +1 -0
  705. package/dist/web/_app/immutable/chunks/CcI9jYBV.js +1 -0
  706. package/dist/web/_app/immutable/chunks/CcWaWbrI2.js +1 -0
  707. package/dist/web/_app/immutable/chunks/CdtzRVZK.js +1 -0
  708. package/dist/web/_app/immutable/chunks/CfYG72Hc.js +1 -0
  709. package/dist/web/_app/immutable/chunks/Ch1kmm3J2.js +1 -0
  710. package/dist/web/_app/immutable/chunks/CmSSN61R2.js +1 -0
  711. package/dist/web/_app/immutable/chunks/Cqm5wAin.js +1 -0
  712. package/dist/web/_app/immutable/chunks/CuYPXpWU.js +1 -0
  713. package/dist/web/_app/immutable/chunks/CvSEodTA.js +1 -0
  714. package/dist/web/_app/immutable/chunks/CvqqrTrj.js +1 -0
  715. package/dist/web/_app/immutable/chunks/CwAmWt6h.js +1 -0
  716. package/dist/web/_app/immutable/chunks/CwP3Oa7F.js +1 -0
  717. package/dist/web/_app/immutable/chunks/CyTluew1.js +2 -0
  718. package/dist/web/_app/immutable/chunks/CzXdOgVl2.js +7 -0
  719. package/dist/web/_app/immutable/chunks/D0IAituJ.js +1 -0
  720. package/dist/web/_app/immutable/chunks/D0W7c6Sg.js +185 -0
  721. package/dist/web/_app/immutable/chunks/D0rBhnqB2.js +1 -0
  722. package/dist/web/_app/immutable/chunks/D1-GZSN1.js +1 -0
  723. package/dist/web/_app/immutable/chunks/D1yvtriI.js +1 -0
  724. package/dist/web/_app/immutable/chunks/D25NMRpl.js +1 -0
  725. package/dist/web/_app/immutable/chunks/D8wZ2xul.js +4 -0
  726. package/dist/web/_app/immutable/chunks/DA3HEX3X.js +1 -0
  727. package/dist/web/_app/immutable/chunks/DD9wj4ca2.js +1 -0
  728. package/dist/web/_app/immutable/chunks/DJ1YeiJL2.js +1 -0
  729. package/dist/web/_app/immutable/chunks/DKFZnpVC.js +5 -0
  730. package/dist/web/_app/immutable/chunks/DKJl40hl.js +1 -0
  731. package/dist/web/_app/immutable/chunks/DPUVu0T0.js +1 -0
  732. package/dist/web/_app/immutable/chunks/DQMWa2t7.js +1 -0
  733. package/dist/web/_app/immutable/chunks/DXsFrDer2.js +1 -0
  734. package/dist/web/_app/immutable/chunks/DYc5KW3F.js +1 -0
  735. package/dist/web/_app/immutable/chunks/DZcTwXBW.js +1 -0
  736. package/dist/web/_app/immutable/chunks/DcPrzUMJ.js +1 -0
  737. package/dist/web/_app/immutable/chunks/DdPO8kRu2.js +2 -0
  738. package/dist/web/_app/immutable/chunks/DeOXyJZw2.js +1 -0
  739. package/dist/web/_app/immutable/chunks/DfufUFR1.js +2 -0
  740. package/dist/web/_app/immutable/chunks/DiQg3ing.js +1 -0
  741. package/dist/web/_app/immutable/chunks/DjIqa1_y.js +2 -0
  742. package/dist/web/_app/immutable/chunks/DkJ1dkxV2.js +1 -0
  743. package/dist/web/_app/immutable/chunks/Dl63IUnH2.js +224 -0
  744. package/dist/web/_app/immutable/chunks/DmFdD6zT.js +1 -0
  745. package/dist/web/_app/immutable/chunks/Dn3R8S-U.js +1 -0
  746. package/dist/web/_app/immutable/chunks/DpNr1GQ2.js +1 -0
  747. package/dist/web/_app/immutable/chunks/DpVNDHXz.js +2 -0
  748. package/dist/web/_app/immutable/chunks/DuxziNnw.js +1 -0
  749. package/dist/web/_app/immutable/chunks/Dv3A3Wcj.js +1 -0
  750. package/dist/web/_app/immutable/chunks/FuiJnZG0.js +1 -0
  751. package/dist/web/_app/immutable/chunks/Izkulod7.js +1 -0
  752. package/dist/web/_app/immutable/chunks/KZY6ongq2.js +2 -0
  753. package/dist/web/_app/immutable/chunks/LYL8znYR2.js +23 -0
  754. package/dist/web/_app/immutable/chunks/PhN6tXuJ2.js +1 -0
  755. package/dist/web/_app/immutable/chunks/PyLyCpuL.js +1 -0
  756. package/dist/web/_app/immutable/chunks/RK4gCWN0.js +2 -0
  757. package/dist/web/_app/immutable/chunks/VsBngTf4.js +2 -0
  758. package/dist/web/_app/immutable/chunks/XcWejFm_.js +5 -0
  759. package/dist/web/_app/immutable/chunks/al_nidE9.js +1 -0
  760. package/dist/web/_app/immutable/chunks/e50-izZO2.js +1 -0
  761. package/dist/web/_app/immutable/chunks/hG-QCarB.js +1 -0
  762. package/dist/web/_app/immutable/chunks/hStvCHkX.js +1 -0
  763. package/dist/web/_app/immutable/chunks/iJVY9p0y.js +3 -0
  764. package/dist/web/_app/immutable/chunks/kNaey6uv.js +1 -0
  765. package/dist/web/_app/immutable/chunks/pIXNe0C1.js +1 -0
  766. package/dist/web/_app/immutable/chunks/pNSRq_1B.js +2 -0
  767. package/dist/web/_app/immutable/chunks/qwr5boV8.js +1 -0
  768. package/dist/web/_app/immutable/chunks/rjjyuGhb.js +1 -0
  769. package/dist/web/_app/immutable/chunks/sg-T-FoN.js +1 -0
  770. package/dist/web/_app/immutable/chunks/uBgoVlsx.js +3 -0
  771. package/dist/web/_app/immutable/chunks/ulshNz6x.js +2 -0
  772. package/dist/web/_app/immutable/chunks/xY0c-UfG.js +3 -0
  773. package/dist/web/_app/immutable/chunks/xeNvx4Bl2.js +1 -0
  774. package/dist/web/_app/immutable/chunks/xihTtKlq.js +1 -0
  775. package/dist/web/_app/immutable/entry/app.pNUW-q4U.js +2 -0
  776. package/dist/web/_app/immutable/entry/start.DxGtIGG_.js +1 -0
  777. package/dist/web/_app/immutable/nodes/0.D6ZCY_R6.js +2 -0
  778. package/dist/web/_app/immutable/nodes/1.BryH3TNr.js +1 -0
  779. package/dist/web/_app/immutable/nodes/10.CMZMvR17.js +1 -0
  780. package/dist/web/_app/immutable/nodes/11.QHx_JShx.js +1 -0
  781. package/dist/web/_app/immutable/nodes/12.CiRWbb4X.js +1 -0
  782. package/dist/web/_app/immutable/nodes/13.CYrHXCA8.js +1 -0
  783. package/dist/web/_app/immutable/nodes/14.K18eIE5Z.js +1 -0
  784. package/dist/web/_app/immutable/nodes/15.DxgnZ61h.js +1 -0
  785. package/dist/web/_app/immutable/nodes/16.Dn6iuWIo.js +1 -0
  786. package/dist/web/_app/immutable/nodes/17.viwS7vTR.js +77 -0
  787. package/dist/web/_app/immutable/nodes/2.BQkQ_uUM.js +122 -0
  788. package/dist/web/_app/immutable/nodes/3.B4pqXsqq.js +6 -0
  789. package/dist/web/_app/immutable/nodes/4.CKXEgIAP.js +11 -0
  790. package/dist/web/_app/immutable/nodes/5.A2TASl4Q.js +1 -0
  791. package/dist/web/_app/immutable/nodes/6.DaIRO3SI.js +6 -0
  792. package/dist/web/_app/immutable/nodes/7.ga2UvFm-.js +1 -0
  793. package/dist/web/_app/immutable/nodes/8.BTEWT81u.js +1 -0
  794. package/dist/web/_app/immutable/nodes/9.BVxo0E0c.js +1 -0
  795. package/dist/web/_app/version.json +1 -1
  796. package/dist/web/favicon-16.png +0 -0
  797. package/dist/web/favicon-180.png +0 -0
  798. package/dist/web/favicon-32.png +0 -0
  799. package/dist/web/favicon-48.png +0 -0
  800. package/dist/web/favicon-512.png +0 -0
  801. package/dist/web/favicon.ico +0 -0
  802. package/dist/web/favicon.svg +8 -0
  803. package/dist/web/index.html +56 -21
  804. package/dist/web/studiograph-logomark.svg +29 -0
  805. package/package.json +35 -14
  806. package/dist/agent/skills/enrich-entities.md +0 -136
  807. package/dist/agent/skills/sync-configuration.md +0 -119
  808. package/dist/agent/skills/sync-setup.md +0 -82
  809. package/dist/agent/tools/message-tools.d.ts +0 -42
  810. package/dist/agent/tools/message-tools.js +0 -106
  811. package/dist/agent/tools/message-tools.js.map +0 -1
  812. package/dist/cli/commands/app.d.ts +0 -7
  813. package/dist/cli/commands/app.js +0 -268
  814. package/dist/cli/commands/app.js.map +0 -1
  815. package/dist/cli/commands/clear.d.ts +0 -5
  816. package/dist/cli/commands/clear.js +0 -36
  817. package/dist/cli/commands/clear.js.map +0 -1
  818. package/dist/cli/commands/collection.d.ts +0 -10
  819. package/dist/cli/commands/collection.js.map +0 -1
  820. package/dist/cli/commands/join.d.ts +0 -9
  821. package/dist/cli/commands/join.js +0 -255
  822. package/dist/cli/commands/join.js.map +0 -1
  823. package/dist/cli/commands/start.d.ts +0 -7
  824. package/dist/cli/commands/start.js +0 -584
  825. package/dist/cli/commands/start.js.map +0 -1
  826. package/dist/cli/commands/update.d.ts +0 -8
  827. package/dist/cli/commands/update.js +0 -155
  828. package/dist/cli/commands/update.js.map +0 -1
  829. package/dist/cli/commands/user.d.ts +0 -7
  830. package/dist/cli/commands/user.js +0 -175
  831. package/dist/cli/commands/user.js.map +0 -1
  832. package/dist/cli/scaffolding.d.ts +0 -12
  833. package/dist/cli/scaffolding.js +0 -397
  834. package/dist/cli/scaffolding.js.map +0 -1
  835. package/dist/integrations/registry.d.ts +0 -8
  836. package/dist/integrations/registry.js +0 -7
  837. package/dist/integrations/registry.js.map +0 -1
  838. package/dist/integrations/types.d.ts +0 -43
  839. package/dist/integrations/types.js +0 -5
  840. package/dist/integrations/types.js.map +0 -1
  841. package/dist/lib/lib/utils.d.ts +0 -2
  842. package/dist/lib/lib/utils.js +0 -6
  843. package/dist/lib/lib/utils.js.map +0 -1
  844. package/dist/server/chrome/chrome.css +0 -691
  845. package/dist/server/chrome/chrome.js +0 -374
  846. package/dist/server/commit-scheduler.d.ts +0 -39
  847. package/dist/server/commit-scheduler.js +0 -113
  848. package/dist/server/commit-scheduler.js.map +0 -1
  849. package/dist/server/plugin-loader.d.ts +0 -53
  850. package/dist/server/plugin-loader.js +0 -155
  851. package/dist/server/plugin-loader.js.map +0 -1
  852. package/dist/server/routes/meeting-ingest-api.d.ts +0 -14
  853. package/dist/server/routes/meeting-ingest-api.js.map +0 -1
  854. package/dist/server/routes/messages-api.d.ts +0 -15
  855. package/dist/server/routes/messages-api.js +0 -385
  856. package/dist/server/routes/messages-api.js.map +0 -1
  857. package/dist/services/batch-processor.d.ts +0 -49
  858. package/dist/services/batch-processor.js +0 -166
  859. package/dist/services/batch-processor.js.map +0 -1
  860. package/dist/services/briefing.d.ts +0 -26
  861. package/dist/services/briefing.js +0 -230
  862. package/dist/services/briefing.js.map +0 -1
  863. package/dist/services/heartbeat.d.ts +0 -28
  864. package/dist/services/heartbeat.js +0 -183
  865. package/dist/services/heartbeat.js.map +0 -1
  866. package/dist/services/image-import-service.d.ts +0 -24
  867. package/dist/services/image-import-service.js +0 -108
  868. package/dist/services/image-import-service.js.map +0 -1
  869. package/dist/services/insights.d.ts +0 -38
  870. package/dist/services/insights.js +0 -269
  871. package/dist/services/insights.js.map +0 -1
  872. package/dist/services/meeting-processor.js.map +0 -1
  873. package/dist/services/message-service.d.ts +0 -68
  874. package/dist/services/message-service.js +0 -220
  875. package/dist/services/message-service.js.map +0 -1
  876. package/dist/utils/workspace-config.d.ts +0 -8
  877. package/dist/utils/workspace-config.js +0 -22
  878. package/dist/utils/workspace-config.js.map +0 -1
  879. package/dist/web/_app/immutable/assets/0.uPSqtsC5.css +0 -1
  880. package/dist/web/_app/immutable/assets/11.2jzI3cZY.css +0 -1
  881. package/dist/web/_app/immutable/assets/12.CT4xL4K3.css +0 -1
  882. package/dist/web/_app/immutable/assets/13.BUrHkYry.css +0 -1
  883. package/dist/web/_app/immutable/assets/2.DpQWr6q6.css +0 -1
  884. package/dist/web/_app/immutable/assets/3.BxdqT7zi.css +0 -1
  885. package/dist/web/_app/immutable/assets/4.DdNqjd0T.css +0 -1
  886. package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
  887. package/dist/web/_app/immutable/assets/6.DXZr_rI_.css +0 -1
  888. package/dist/web/_app/immutable/assets/GraphView.D9ePpZez.css +0 -1
  889. package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
  890. package/dist/web/_app/immutable/assets/ViewToolbar.BWE03S64.css +0 -1
  891. package/dist/web/_app/immutable/assets/WorkspaceView.CgGDi_Zb.css +0 -1
  892. package/dist/web/_app/immutable/assets/wikilinks.CzMBkUMB.css +0 -1
  893. package/dist/web/_app/immutable/chunks/-jG4Obyh.js +0 -4
  894. package/dist/web/_app/immutable/chunks/2nrc8f_O.js +0 -1
  895. package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
  896. package/dist/web/_app/immutable/chunks/8Q3ZJIYu.js +0 -1
  897. package/dist/web/_app/immutable/chunks/B8ydT5xX.js +0 -2
  898. package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
  899. package/dist/web/_app/immutable/chunks/BEn6N5c2.js +0 -1
  900. package/dist/web/_app/immutable/chunks/BFNNbCAM.js +0 -1
  901. package/dist/web/_app/immutable/chunks/BFZZEUd5.js +0 -1
  902. package/dist/web/_app/immutable/chunks/BGk8kfOE.js +0 -2
  903. package/dist/web/_app/immutable/chunks/BIBCr278.js +0 -1
  904. package/dist/web/_app/immutable/chunks/BPCkkwqe.js +0 -1
  905. package/dist/web/_app/immutable/chunks/BhlvzGQx.js +0 -1
  906. package/dist/web/_app/immutable/chunks/BlMknQeF.js +0 -1
  907. package/dist/web/_app/immutable/chunks/BpjqrlCg.js +0 -1
  908. package/dist/web/_app/immutable/chunks/BrebtJNG.js +0 -18
  909. package/dist/web/_app/immutable/chunks/ByBZ7JIT.js +0 -1
  910. package/dist/web/_app/immutable/chunks/Bz0ZjVQE.js +0 -2
  911. package/dist/web/_app/immutable/chunks/BzJTZOK2.js +0 -1
  912. package/dist/web/_app/immutable/chunks/C0LVZhvn.js +0 -1
  913. package/dist/web/_app/immutable/chunks/C3uBrOS5.js +0 -1
  914. package/dist/web/_app/immutable/chunks/C8R1sDpW.js +0 -1
  915. package/dist/web/_app/immutable/chunks/CDRHrs0g.js +0 -1
  916. package/dist/web/_app/immutable/chunks/CN5_py1I.js +0 -1
  917. package/dist/web/_app/immutable/chunks/CPne482a.js +0 -1
  918. package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
  919. package/dist/web/_app/immutable/chunks/CWyU-seV.js +0 -1
  920. package/dist/web/_app/immutable/chunks/CX_61fY8.js +0 -5
  921. package/dist/web/_app/immutable/chunks/CYrVHOHA.js +0 -1
  922. package/dist/web/_app/immutable/chunks/ChsiIm-E.js +0 -1
  923. package/dist/web/_app/immutable/chunks/CojKppbh.js +0 -1
  924. package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
  925. package/dist/web/_app/immutable/chunks/CtYLtD7K.js +0 -1
  926. package/dist/web/_app/immutable/chunks/D-HDy5qS.js +0 -1
  927. package/dist/web/_app/immutable/chunks/D5aIYSkd.js +0 -1
  928. package/dist/web/_app/immutable/chunks/DBBXARVf.js +0 -1
  929. package/dist/web/_app/immutable/chunks/DFYOFE3o.js +0 -1
  930. package/dist/web/_app/immutable/chunks/DKaafS50.js +0 -1
  931. package/dist/web/_app/immutable/chunks/DUMOo1Pn.js +0 -1
  932. package/dist/web/_app/immutable/chunks/DWX9f6AF.js +0 -1
  933. package/dist/web/_app/immutable/chunks/DY8-EONP.js +0 -1
  934. package/dist/web/_app/immutable/chunks/DkoHPElM.js +0 -1
  935. package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
  936. package/dist/web/_app/immutable/chunks/DsnmJJEf.js +0 -1
  937. package/dist/web/_app/immutable/chunks/DujahU3W.js +0 -1
  938. package/dist/web/_app/immutable/chunks/FBn-ES5k.js +0 -1
  939. package/dist/web/_app/immutable/chunks/HQpwSOb3.js +0 -1
  940. package/dist/web/_app/immutable/chunks/KyjzlWRN.js +0 -2
  941. package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
  942. package/dist/web/_app/immutable/chunks/UwYfmrPx.js +0 -2
  943. package/dist/web/_app/immutable/chunks/W25ZVI8L.js +0 -2
  944. package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
  945. package/dist/web/_app/immutable/chunks/XjsuEnNE.js +0 -5
  946. package/dist/web/_app/immutable/chunks/ZD6ARAtb.js +0 -1
  947. package/dist/web/_app/immutable/chunks/pBTf4stg.js +0 -2
  948. package/dist/web/_app/immutable/chunks/rGIarcnp.js +0 -1
  949. package/dist/web/_app/immutable/chunks/vxEtkL8z.js +0 -1
  950. package/dist/web/_app/immutable/chunks/wDIGUaoU.js +0 -3
  951. package/dist/web/_app/immutable/entry/app.ZHiTM8WS.js +0 -2
  952. package/dist/web/_app/immutable/entry/start.C9-FfAVc.js +0 -1
  953. package/dist/web/_app/immutable/nodes/0.D92Orz8k.js +0 -2
  954. package/dist/web/_app/immutable/nodes/1.BMdyglM_.js +0 -1
  955. package/dist/web/_app/immutable/nodes/10.BilVDHSL.js +0 -1
  956. package/dist/web/_app/immutable/nodes/11.CS9E0Hic.js +0 -1
  957. package/dist/web/_app/immutable/nodes/12.D3BOxYzG.js +0 -1
  958. package/dist/web/_app/immutable/nodes/13.CClMKYtN.js +0 -1
  959. package/dist/web/_app/immutable/nodes/2.C8KKElPL.js +0 -267
  960. package/dist/web/_app/immutable/nodes/3.C5n5uiWU.js +0 -5
  961. package/dist/web/_app/immutable/nodes/4.DcGVvgiL.js +0 -11
  962. package/dist/web/_app/immutable/nodes/5.DxIjnFQO.js +0 -4
  963. package/dist/web/_app/immutable/nodes/6.lkh6kKLj.js +0 -1
  964. package/dist/web/_app/immutable/nodes/7.Bg7SbfhA.js +0 -1
  965. package/dist/web/_app/immutable/nodes/8.DcXWCNBE.js +0 -1
  966. package/dist/web/_app/immutable/nodes/9.Cefi8Jfm.js +0 -1
@@ -3,8 +3,14 @@
3
3
  *
4
4
  * Login, logout, session verification, and auth status endpoints.
5
5
  */
6
- import { isAdminOrOwner } from '../../services/auth-service.js';
6
+ import { createHmac, timingSafeEqual } from 'node:crypto';
7
+ import { isWorkspaceOwner } from '../../services/auth-service.js';
7
8
  import { Workspace } from '../../core/workspace.js';
9
+ import { ensurePersonalFolder, archivePersonalFolder } from '../../services/personal-folder.js';
10
+ import { ensureWorkspaceAssetsFolder } from '../../services/workspace-assets-folder.js';
11
+ import { authUserToGitUser, ensurePersonForUser, findPersonRefForUser, linkChosenPersonToUser, BridgeError } from '../../services/user-person-bridge.js';
12
+ import * as access from '../../services/access-control.js';
13
+ import { safeReturnTo } from './oauth-api.js';
8
14
  // ── Login rate limiting ──
9
15
  const MAX_ATTEMPTS = 5;
10
16
  const LOCKOUT_MS = 15 * 60 * 1000; // 15 minutes
@@ -37,53 +43,237 @@ export function recordFailedAttempt(email) {
37
43
  export function clearAttempts(email) {
38
44
  loginAttempts.delete(email.toLowerCase());
39
45
  }
40
- function requireAdmin(req, authService) {
46
+ function requireOwner(req, authService) {
41
47
  const token = req.cookies?.['__sg_token'];
42
48
  if (!token)
43
49
  return null;
44
50
  const user = authService.verifyToken(token);
45
- if (!user || !isAdminOrOwner(user.role))
51
+ if (!user || !isWorkspaceOwner(user.role))
46
52
  return null;
47
53
  return user;
48
54
  }
49
- /** Create the auto-provisioned private "My Entries" collection for a user. */
50
- async function ensurePrivateCollection(workspacePath, workspaceManager, user) {
51
- if (workspaceManager.getUserPrivateRepo(user.id))
52
- return; // already exists
53
- const workspace = new Workspace(workspacePath);
54
- await workspace.registerRepo({
55
- name: `entries-${user.id}`,
56
- display_name: 'My Entries',
57
- description: `Private entries for ${user.displayName}`,
58
- private: true,
59
- owner_id: user.id,
60
- });
61
- workspaceManager.reloadConfig();
55
+ /**
56
+ * Resolve the caller to an AuthUser. The global auth hook skips /api/auth/*
57
+ * so endpoints that need identity (like the token CRUD routes below) must
58
+ * look up credentials themselves.
59
+ *
60
+ * Accepted forms:
61
+ * - Cookie `__sg_token=<jwt>` (web UI)
62
+ * - `Authorization: Bearer <jwt>` (CLI with stored JWT)
63
+ * - `Authorization: Bearer <sg_…>` (CLI with API token)
64
+ *
65
+ * Mirrors the precedence the main API middleware uses elsewhere
66
+ * (src/server/index.ts) — needed so CLI commands like
67
+ * `studiograph admin transfer-ownership` can call /api/auth/* endpoints
68
+ * using the same Bearer sg_ token they use everywhere else.
69
+ */
70
+ function requireUser(req, authService) {
71
+ const cookieToken = req.cookies?.['__sg_token'];
72
+ if (cookieToken) {
73
+ const user = authService.verifyToken(cookieToken);
74
+ if (user)
75
+ return user;
76
+ }
77
+ const authHeader = req.headers?.authorization;
78
+ if (authHeader?.startsWith('Bearer ')) {
79
+ const bearer = authHeader.slice('Bearer '.length).trim();
80
+ if (bearer.startsWith('sg_')) {
81
+ return authService.verifyApiToken(bearer);
82
+ }
83
+ // Treat anything else as a JWT — verifyToken returns null on invalid input.
84
+ return authService.verifyToken(bearer);
85
+ }
86
+ return null;
87
+ }
88
+ function managedCloudAuthConfig() {
89
+ return {
90
+ enabled: parseBoolean(process.env.STUDIOGRAPH_MANAGED_AUTH),
91
+ cloudUrl: process.env.STUDIOGRAPH_CLOUD_URL?.trim() ?? '',
92
+ orgId: process.env.STUDIOGRAPH_CLOUD_ORG_ID?.trim() ?? '',
93
+ workspaceId: process.env.STUDIOGRAPH_CLOUD_WORKSPACE_ID?.trim() ?? '',
94
+ token: process.env.STUDIOGRAPH_CLOUD_TOKEN?.trim() ?? '',
95
+ };
96
+ }
97
+ function managedCloudLoginUrl(config) {
98
+ if (!config.cloudUrl || !config.orgId || !config.workspaceId)
99
+ return null;
100
+ const url = new URL('/auth/workspace', config.cloudUrl);
101
+ url.searchParams.set('orgId', config.orgId);
102
+ url.searchParams.set('workspaceId', config.workspaceId);
103
+ return url.toString();
104
+ }
105
+ function managedCloudLogoutUrl(config, returnTo) {
106
+ if (!config.cloudUrl)
107
+ return null;
108
+ const url = new URL('/auth/logout', config.cloudUrl);
109
+ if (returnTo)
110
+ url.searchParams.set('returnTo', returnTo);
111
+ return url.toString();
112
+ }
113
+ function requestOrigin(req) {
114
+ const rawHost = req.headers?.['x-forwarded-host'] ?? req.headers?.host;
115
+ const host = Array.isArray(rawHost) ? rawHost[0] : rawHost;
116
+ if (!host)
117
+ return null;
118
+ const rawProto = req.headers?.['x-forwarded-proto'];
119
+ const forwardedProto = Array.isArray(rawProto) ? rawProto[0] : rawProto;
120
+ const proto = typeof forwardedProto === 'string' && forwardedProto.trim()
121
+ ? forwardedProto.split(',')[0].trim()
122
+ : 'http';
123
+ return `${proto}://${host}`;
124
+ }
125
+ function managedLogoutReturnTo(req) {
126
+ const origin = requestOrigin(req);
127
+ if (!origin)
128
+ return null;
129
+ const url = new URL('/login', origin);
130
+ url.searchParams.set('managedLogout', '1');
131
+ return url.toString();
132
+ }
133
+ function verifyCloudLoginToken(token, secret) {
134
+ const [payloadPart, signaturePart] = token.split('.');
135
+ if (!payloadPart || !signaturePart || token.split('.').length !== 2) {
136
+ throw new Error('Malformed login token');
137
+ }
138
+ const expected = hmacBase64Url(payloadPart, secret);
139
+ if (!constantTimeEqual(signaturePart, expected)) {
140
+ throw new Error('Invalid login token signature');
141
+ }
142
+ const claims = JSON.parse(Buffer.from(payloadPart, 'base64url').toString('utf8'));
143
+ if (claims.iss !== 'studiograph-cloud' || claims.aud !== 'studiograph-runtime') {
144
+ throw new Error('Invalid login token audience');
145
+ }
146
+ if (!claims.orgId || !claims.workspaceId || !claims.userId || !claims.email || !claims.displayName || !claims.role) {
147
+ throw new Error('Incomplete login token');
148
+ }
149
+ if (!['owner', 'admin', 'member'].includes(claims.role)) {
150
+ throw new Error('Invalid login token role');
151
+ }
152
+ const now = Math.floor(Date.now() / 1000);
153
+ if (typeof claims.exp !== 'number' || claims.exp < now) {
154
+ throw new Error('Login token has expired');
155
+ }
156
+ if (typeof claims.iat !== 'number' || claims.iat > now + 60) {
157
+ throw new Error('Login token was issued in the future');
158
+ }
159
+ return claims;
160
+ }
161
+ function runtimeRoleForCloudRole(cloudRole, existing, authService) {
162
+ if (existing?.role === 'owner')
163
+ return 'owner';
164
+ if (cloudRole === 'owner')
165
+ return 'owner';
166
+ if (!authService.getOwner() && cloudRole === 'admin')
167
+ return 'owner';
168
+ return 'member';
169
+ }
170
+ function grantManagedWorkspaceAccess(authService, workspaceManager, user, cloudRole) {
171
+ const folderRole = cloudRole === 'owner' || cloudRole === 'admin' ? 'admin' : 'editor';
172
+ for (const repo of workspaceManager.getAllRepoConfigs()) {
173
+ if (repo.personal)
174
+ continue;
175
+ const currentRole = authService.getFolderRole(user.id, repo.name);
176
+ if (currentRole === 'admin')
177
+ continue;
178
+ if (currentRole !== folderRole)
179
+ authService.grantFolderAccess(user.id, repo.name, folderRole);
180
+ }
181
+ }
182
+ function hmacBase64Url(value, secret) {
183
+ return createHmac('sha256', secret).update(value).digest('base64url');
184
+ }
185
+ function constantTimeEqual(a, b) {
186
+ const left = Buffer.from(a);
187
+ const right = Buffer.from(b);
188
+ return left.length === right.length && timingSafeEqual(left, right);
189
+ }
190
+ function parseBoolean(value) {
191
+ if (!value)
192
+ return false;
193
+ return ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase());
62
194
  }
63
195
  export async function registerAuthApiRoutes(fastify, authService, workspacePath, workspaceManager, workspaceName) {
196
+ fastify.get('/api/cloud/auth/callback', async (req, reply) => {
197
+ const config = managedCloudAuthConfig();
198
+ if (!config.enabled)
199
+ return reply.status(404).send({ error: 'Managed cloud auth is not enabled' });
200
+ if (!config.token || !config.workspaceId) {
201
+ return reply.status(503).send({ error: 'Managed cloud auth is not configured' });
202
+ }
203
+ const { token } = req.query;
204
+ if (!token)
205
+ return reply.status(400).send({ error: 'Missing login token' });
206
+ try {
207
+ const claims = verifyCloudLoginToken(token, config.token);
208
+ if (claims.workspaceId !== config.workspaceId) {
209
+ return reply.status(403).send({ error: 'Login token was issued for a different workspace' });
210
+ }
211
+ if (config.orgId && claims.orgId !== config.orgId) {
212
+ return reply.status(403).send({ error: 'Login token was issued for a different organization' });
213
+ }
214
+ const existing = authService.findUserByEmail(claims.email);
215
+ const runtimeRole = runtimeRoleForCloudRole(claims.role, existing, authService);
216
+ const user = authService.upsertCloudManagedUser({
217
+ email: claims.email,
218
+ displayName: claims.displayName,
219
+ role: runtimeRole,
220
+ });
221
+ await ensurePersonalFolder(new Workspace(workspacePath), authService, user);
222
+ grantManagedWorkspaceAccess(authService, workspaceManager, user, claims.role);
223
+ workspaceManager.reloadConfig();
224
+ // No person auto-provisioning here: task assignment + "My Tasks" key on the
225
+ // account identity (`[[user:<id>]]`), so a person entity is optional and
226
+ // never a precondition. Users add a profile explicitly from Settings → Profile.
227
+ const secure = req.headers['x-forwarded-proto'] === 'https';
228
+ reply.setCookie('__sg_token', authService.createSessionToken(user), {
229
+ path: '/',
230
+ httpOnly: true,
231
+ sameSite: 'lax',
232
+ secure,
233
+ maxAge: 7 * 24 * 60 * 60,
234
+ });
235
+ // Honor a returnTo echoed back through the cloud round-trip (used by the
236
+ // OAuth authorize → /login bounce so consent resumes after cloud auth).
237
+ // safeReturnTo enforces same-origin: root-relative path only, rejecting
238
+ // absolute/protocol-relative URLs, backslash-normalized off-origin, and
239
+ // control chars.
240
+ const returnTo = safeReturnTo(req.query.returnTo);
241
+ return reply.redirect(returnTo);
242
+ }
243
+ catch (err) {
244
+ return reply.status(401).send({ error: err?.message || 'Invalid login token' });
245
+ }
246
+ });
64
247
  // ── Admin user management ──
65
- // GET /api/auth/users — list all users (admin only)
248
+ // GET /api/auth/users — list all users. Any authenticated caller: folder
249
+ // admins need this to populate the share-dialog "Add members" candidates,
250
+ // and the comment @-mention surface needs the same shape.
251
+ // Mutating endpoints below (POST/DELETE/PATCH) stay owner-only.
66
252
  fastify.get('/api/auth/users', async (req, reply) => {
67
- const admin = requireAdmin(req, authService);
68
- if (!admin)
69
- return reply.status(403).send({ error: 'Admin access required' });
253
+ const user = requireUser(req, authService);
254
+ if (!user)
255
+ return reply.status(401).send({ error: 'Authentication required' });
70
256
  return reply.send({ users: authService.listUsers() });
71
257
  });
72
258
  // POST /api/auth/users — create a new user (admin only)
73
259
  fastify.post('/api/auth/users', async (req, reply) => {
74
- const admin = requireAdmin(req, authService);
260
+ const admin = requireOwner(req, authService);
75
261
  if (!admin)
76
- return reply.status(403).send({ error: 'Admin access required' });
262
+ return reply.status(403).send({ error: 'Workspace owner access required' });
77
263
  const { email, password, displayName, role } = req.body;
78
264
  if (!email || !password) {
79
265
  return reply.status(400).send({ error: 'Email and password are required' });
80
266
  }
81
- if (role === 'owner') {
82
- return reply.status(400).send({ error: 'Cannot create additional owners' });
267
+ if (role && role !== 'owner' && role !== 'member') {
268
+ return reply.status(400).send({ error: `Invalid role "${role}" must be "owner" or "member"` });
83
269
  }
84
270
  try {
85
271
  const user = authService.createUser(email, password, displayName || email.split('@')[0], role || 'member');
86
- await ensurePrivateCollection(workspacePath, workspaceManager, user);
272
+ await ensurePersonalFolder(new Workspace(workspacePath), authService, user);
273
+ workspaceManager.reloadConfig();
274
+ // No person auto-provisioning: assignment + "My Tasks" key on the account
275
+ // identity (`[[user:<id>]]`), so a person entity is optional. Users add a
276
+ // profile to the graph explicitly from Settings → Profile.
87
277
  return reply.send({ user });
88
278
  }
89
279
  catch (err) {
@@ -92,9 +282,9 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
92
282
  });
93
283
  // DELETE /api/auth/users/:id — delete a user (admin only, cannot delete self or last admin)
94
284
  fastify.delete('/api/auth/users/:id', async (req, reply) => {
95
- const admin = requireAdmin(req, authService);
285
+ const admin = requireOwner(req, authService);
96
286
  if (!admin)
97
- return reply.status(403).send({ error: 'Admin access required' });
287
+ return reply.status(403).send({ error: 'Workspace owner access required' });
98
288
  const userId = parseInt(req.params.id, 10);
99
289
  if (isNaN(userId))
100
290
  return reply.status(400).send({ error: 'Invalid user ID' });
@@ -104,20 +294,111 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
104
294
  const target = users.find(u => u.id === userId);
105
295
  if (!target)
106
296
  return reply.status(404).send({ error: 'User not found' });
107
- if (target.role === 'owner') {
108
- return reply.status(400).send({ error: 'Cannot delete workspace owner. Transfer ownership first.' });
297
+ if (target.role === 'owner' && users.filter(u => u.role === 'owner').length <= 1) {
298
+ return reply.status(400).send({ error: 'Cannot delete the last workspace owner. Transfer ownership first.' });
299
+ }
300
+ // Transfer folders the target solely administers to the actor
301
+ // (the workspace owner performing this deletion) BEFORE the cascade
302
+ // delete — otherwise folder_access rows for those folders disappear
303
+ // and the folder is left with no admins.
304
+ //
305
+ // Personal folders (the target's "My Folder") are a sub-case: they
306
+ // transfer the same way, then get demoted to normal archive folders
307
+ // so the one-personal-folder-per-user invariant holds and the actor
308
+ // ends up with a plainly-named folder they own outright.
309
+ const workspace = new Workspace(workspacePath);
310
+ const preConfig = await workspace.loadConfig();
311
+ const targetPersonalFolders = preConfig.repos.filter(r => r.personal === true && r.owner_id === target.id);
312
+ const personalEntryCounts = new Map();
313
+ for (const p of targetPersonalFolders) {
314
+ try {
315
+ personalEntryCounts.set(p.name, workspaceManager.getGraph(p.name).listEntityIds().length);
316
+ }
317
+ catch {
318
+ personalEntryCounts.set(p.name, 0);
319
+ }
109
320
  }
110
- if (target.role === 'admin' && users.filter(u => u.role === 'admin').length <= 1) {
111
- return reply.status(400).send({ error: 'Cannot delete the last admin' });
321
+ const transferred = authService.transferFoldersOnDelete(target.id, admin.id);
322
+ // Capture the old name upfront: archivePersonalFolder mutates the
323
+ // RepoConfig in place (name/path change), so reading `p.name` after
324
+ // the await would return the new archive name.
325
+ const archived = [];
326
+ for (const p of targetPersonalFolders) {
327
+ const oldName = p.name;
328
+ if (!transferred.includes(oldName))
329
+ continue;
330
+ const { newName, newDisplayName } = await archivePersonalFolder(workspace, oldName, target.displayName, authService);
331
+ archived.push({
332
+ oldName,
333
+ newName,
334
+ newDisplayName,
335
+ entryCount: personalEntryCounts.get(oldName) ?? 0,
336
+ });
112
337
  }
113
338
  authService.deleteUser(target.email);
114
- return reply.send({ ok: true });
339
+ if (archived.length > 0)
340
+ workspaceManager.reloadConfig();
341
+ return reply.send({ ok: true, transferred, archived });
342
+ });
343
+ // GET /api/auth/users/:id/deletion-preview — show the actor what
344
+ // will transfer if they delete this user. Owner-gated. Returns entry
345
+ // counts and archive names so the confirmation UI can set expectations
346
+ // WITHOUT exposing the contents of the target's private folder. The
347
+ // preview is advisory; the DELETE endpoint is the source of truth.
348
+ fastify.get('/api/auth/users/:id/deletion-preview', async (req, reply) => {
349
+ const admin = requireOwner(req, authService);
350
+ if (!admin)
351
+ return reply.status(403).send({ error: 'Workspace owner access required' });
352
+ const userId = parseInt(req.params.id, 10);
353
+ if (isNaN(userId))
354
+ return reply.status(400).send({ error: 'Invalid user ID' });
355
+ if (admin.id === userId)
356
+ return reply.status(400).send({ error: 'Cannot preview deleting yourself' });
357
+ const target = authService.listUsers().find(u => u.id === userId);
358
+ if (!target)
359
+ return reply.status(404).send({ error: 'User not found' });
360
+ const workspace = new Workspace(workspacePath);
361
+ const config = await workspace.loadConfig();
362
+ // Mirror transferFoldersOnDelete's sole-admin rule so the preview
363
+ // matches the real delete. Personal folders are 1-member by nature,
364
+ // so they always qualify.
365
+ const targetAdminFolders = authService.getUserFolders(target.id)
366
+ .filter(f => authService.getFolderRole(target.id, f) === 'admin');
367
+ const soleAdminFolders = targetAdminFolders.filter(f => authService.getFolderAdmins(f).length === 1);
368
+ const date = new Date().toISOString().slice(0, 10);
369
+ const personalFolders = config.repos.filter(r => r.personal === true && r.owner_id === target.id && soleAdminFolders.includes(r.name));
370
+ const sharedSoleAdmin = soleAdminFolders.filter(f => !personalFolders.some(p => p.name === f));
371
+ const personal = personalFolders.map(p => {
372
+ let entryCount = 0;
373
+ try {
374
+ entryCount = workspaceManager.getGraph(p.name).listEntityIds().length;
375
+ }
376
+ catch { /* skip */ }
377
+ return {
378
+ entryCount,
379
+ newDisplayName: `Archive: ${target.displayName} (${date})`,
380
+ };
381
+ });
382
+ const shared = sharedSoleAdmin.map(f => {
383
+ const repo = config.repos.find(r => r.name === f);
384
+ let entryCount = 0;
385
+ try {
386
+ entryCount = workspaceManager.getGraph(f).listEntityIds().length;
387
+ }
388
+ catch { /* skip */ }
389
+ return {
390
+ name: f,
391
+ displayName: repo?.display_name ?? f,
392
+ entryCount,
393
+ };
394
+ });
395
+ return reply.send({ personal, shared });
115
396
  });
116
397
  // PATCH /api/auth/users/:id/password — reset a user's password (admin only)
117
398
  fastify.patch('/api/auth/users/:id/password', async (req, reply) => {
118
- const admin = requireAdmin(req, authService);
399
+ const admin = requireOwner(req, authService);
119
400
  if (!admin)
120
- return reply.status(403).send({ error: 'Admin access required' });
401
+ return reply.status(403).send({ error: 'Workspace owner access required' });
121
402
  const userId = parseInt(req.params.id, 10);
122
403
  if (isNaN(userId))
123
404
  return reply.status(400).send({ error: 'Invalid user ID' });
@@ -136,28 +417,99 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
136
417
  return reply.status(400).send({ error: err.message });
137
418
  }
138
419
  });
139
- // POST /api/auth/api-key/regenerateregenerate workspace API key (admin only)
140
- fastify.post('/api/auth/api-key/regenerate', async (req, reply) => {
141
- const admin = requireAdmin(req, authService);
420
+ // PATCH /api/auth/users/:idupdate a member's profile (owner only).
421
+ // Currently accepts `email` and `displayName`; mirrors the existing
422
+ // password-reset pattern (owner-gated, no user notification).
423
+ fastify.patch('/api/auth/users/:id', async (req, reply) => {
424
+ const admin = requireOwner(req, authService);
142
425
  if (!admin)
143
- return reply.status(403).send({ error: 'Admin access required' });
144
- const newKey = authService.regenerateApiKey();
145
- return reply.send({ apiKey: newKey });
426
+ return reply.status(403).send({ error: 'Workspace owner access required' });
427
+ const userId = parseInt(req.params.id, 10);
428
+ if (isNaN(userId))
429
+ return reply.status(400).send({ error: 'Invalid user ID' });
430
+ const { email, displayName } = req.body;
431
+ if (email === undefined && displayName === undefined) {
432
+ return reply.status(400).send({ error: 'Nothing to update' });
433
+ }
434
+ if (email !== undefined) {
435
+ const normalized = email.toLowerCase().trim();
436
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalized)) {
437
+ return reply.status(400).send({ error: 'Invalid email address' });
438
+ }
439
+ }
440
+ const target = authService.findUserById(userId);
441
+ if (!target)
442
+ return reply.status(404).send({ error: 'User not found' });
443
+ try {
444
+ const updated = authService.updateProfile(userId, { email, displayName });
445
+ return reply.send({ user: updated });
446
+ }
447
+ catch (err) {
448
+ // SQLite raises a UNIQUE constraint error on duplicate email.
449
+ if (String(err?.message ?? '').includes('UNIQUE')) {
450
+ return reply.status(409).send({ error: 'That email is already in use' });
451
+ }
452
+ return reply.status(400).send({ error: err.message });
453
+ }
454
+ });
455
+ // ── Per-user API tokens (used by MCP clients, CLI, and git HTTP) ──
456
+ // POST /api/auth/tokens — mint a new token for the authenticated user.
457
+ // Body: { name: string }. Returns the raw token once; only its hash is stored.
458
+ fastify.post('/api/auth/tokens', async (req, reply) => {
459
+ const user = requireUser(req, authService);
460
+ if (!user)
461
+ return reply.status(401).send({ error: 'Unauthorized' });
462
+ const { name } = (req.body ?? {});
463
+ if (!name || !name.trim()) {
464
+ return reply.status(400).send({ error: 'name is required' });
465
+ }
466
+ try {
467
+ const minted = authService.createApiToken(user.id, name);
468
+ return reply.status(201).send(minted);
469
+ }
470
+ catch (err) {
471
+ return reply.status(400).send({ error: err.message });
472
+ }
473
+ });
474
+ // GET /api/auth/tokens — list the authenticated user's tokens (metadata only).
475
+ fastify.get('/api/auth/tokens', async (req, reply) => {
476
+ const user = requireUser(req, authService);
477
+ if (!user)
478
+ return reply.status(401).send({ error: 'Unauthorized' });
479
+ return reply.send({ tokens: authService.listApiTokens(user.id) });
480
+ });
481
+ // DELETE /api/auth/tokens/:id — revoke one of the user's own tokens.
482
+ fastify.delete('/api/auth/tokens/:id', async (req, reply) => {
483
+ const user = requireUser(req, authService);
484
+ if (!user)
485
+ return reply.status(401).send({ error: 'Unauthorized' });
486
+ const tokenId = parseInt(req.params.id, 10);
487
+ if (isNaN(tokenId))
488
+ return reply.status(400).send({ error: 'Invalid token id' });
489
+ const ok = authService.revokeApiToken(tokenId, user.id);
490
+ if (!ok)
491
+ return reply.status(404).send({ error: 'Token not found' });
492
+ return reply.send({ ok: true });
146
493
  });
147
494
  // GET /api/auth/seed — export auth seed data (admin only, for remote pull)
495
+ // Phase 3: sanitized via the same registry-driven helper as
496
+ // /api/config/bundle. jwtSecret + deprecated apiKey are dropped before
497
+ // the response leaves the trust boundary.
148
498
  fastify.get('/api/auth/seed', async (req, reply) => {
149
- const admin = requireAdmin(req, authService);
499
+ const admin = requireOwner(req, authService);
150
500
  if (!admin)
151
- return reply.status(403).send({ error: 'Admin access required' });
152
- return reply.send(authService.getSeedData());
501
+ return reply.status(403).send({ error: 'Workspace owner access required' });
502
+ const { sanitizeAuthSeed } = await import('../../core/secrets/bundle.js');
503
+ return reply.send(sanitizeAuthSeed(authService.getSeedData()));
153
504
  });
154
- // POST /api/auth/transfer-ownership — transfer ownership to another user (owner only)
505
+ // POST /api/auth/transfer-ownership — transfer ownership to another user (owner only).
506
+ // Accepts cookie OR Bearer sg_ token via requireUser (the CLI calls this
507
+ // through `studiograph admin transfer-ownership`).
155
508
  fastify.post('/api/auth/transfer-ownership', async (req, reply) => {
156
- const token = req.cookies?.['__sg_token'];
157
- if (!token)
509
+ const user = requireUser(req, authService);
510
+ if (!user)
158
511
  return reply.status(401).send({ error: 'Unauthorized' });
159
- const user = authService.verifyToken(token);
160
- if (!user || user.role !== 'owner')
512
+ if (user.role !== 'owner')
161
513
  return reply.status(403).send({ error: 'Only the workspace owner can transfer ownership' });
162
514
  const { targetUserId } = req.body;
163
515
  if (!targetUserId)
@@ -172,6 +524,9 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
172
524
  });
173
525
  // POST /api/auth/login — authenticate and set session cookie
174
526
  fastify.post('/api/auth/login', async (req, reply) => {
527
+ if (managedCloudAuthConfig().enabled) {
528
+ return reply.status(403).send({ error: 'Use Studiograph Cloud to sign in to this managed workspace' });
529
+ }
175
530
  const { email, password } = req.body;
176
531
  if (!email || !password) {
177
532
  return reply.status(400).send({ error: 'Email and password are required' });
@@ -192,13 +547,17 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
192
547
  reply.setCookie('__sg_token', result.token, {
193
548
  path: '/',
194
549
  httpOnly: true,
195
- sameSite: 'strict',
550
+ // Lax (not Strict): sent on top-level GET navigations initiated cross-site
551
+ // — e.g. the OAuth /oauth/authorize redirect from Claude's connector — so an
552
+ // already-logged-in user isn't bounced to a redundant login. Still withheld
553
+ // on cross-site POSTs/subresources (the CSRF-dangerous cases).
554
+ sameSite: 'lax',
196
555
  secure,
197
556
  maxAge: 7 * 24 * 60 * 60, // 7 days
198
557
  });
199
558
  // Include the token in the response body when requested via
200
- // X-Return-Token header (used by Chrome extension and other
201
- // API clients that can't use cookies across origins).
559
+ // X-Return-Token header for API clients that can't use cookies
560
+ // across origins.
202
561
  const returnToken = req.headers['x-return-token'] === '1';
203
562
  return reply.send({
204
563
  user: result.user,
@@ -206,26 +565,107 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
206
565
  });
207
566
  });
208
567
  // POST /api/auth/logout — clear session cookie
209
- fastify.post('/api/auth/logout', async (_req, reply) => {
568
+ fastify.post('/api/auth/logout', async (req, reply) => {
569
+ const cloudAuth = managedCloudAuthConfig();
210
570
  reply.setCookie('__sg_token', '', {
211
571
  path: '/',
212
572
  httpOnly: true,
213
- sameSite: 'strict',
573
+ sameSite: 'lax',
214
574
  maxAge: 0,
215
575
  });
216
- return reply.send({ ok: true });
576
+ return reply.send({
577
+ ok: true,
578
+ logoutUrl: cloudAuth.enabled
579
+ ? managedCloudLogoutUrl(cloudAuth, managedLogoutReturnTo(req))
580
+ : undefined,
581
+ });
217
582
  });
218
- // GET /api/auth/me — verify current session
583
+ // GET /api/auth/me — verify current session. Also resolves the user's
584
+ // linked person entity (the auth↔person bridge) so the client gets both
585
+ // identifiers in one round-trip. `personRef` is null when the user has
586
+ // no linked entity (legacy, unprovisioned, or explicitly unlinked) OR
587
+ // when the linked entity lives in a repo the user no longer has read
588
+ // access to (would leak repo existence otherwise — see access-control).
219
589
  fastify.get('/api/auth/me', async (req, reply) => {
220
- const token = req.cookies?.['__sg_token'];
221
- if (!token) {
590
+ // Resolve from the cookie JWT OR Authorization: Bearer (JWT / sg_ API
591
+ // token) via the shared requireUser helper. The global auth hook skips
592
+ // /api/auth/*, so without this the boot session check only honored the
593
+ // web cookie and rejected API-token callers (CLI, automation, the
594
+ // headless browser) even though they authenticate everywhere else.
595
+ const user = requireUser(req, authService);
596
+ if (!user) {
222
597
  return reply.status(401).send({ error: 'Not authenticated' });
223
598
  }
224
- const user = authService.verifyToken(token);
225
- if (!user) {
599
+ const rawRef = findPersonRefForUser(workspaceManager, user.handle);
600
+ const personRef = rawRef && access.hasRepoAccess(user, rawRef.repo, workspaceManager, authService)
601
+ ? rawRef
602
+ : null;
603
+ return reply.send({ user, personRef });
604
+ });
605
+ // POST /api/auth/me/person-link — self-service link of the user↔person
606
+ // bridge for the CURRENT user. Two modes:
607
+ // - body `{ entityId }` → link that SPECIFIC person the user picked
608
+ // (the home CTA / Profile "which record is you?" picker).
609
+ // - no body → auto: email-match an existing record, else create one
610
+ // (ensurePersonForUser).
611
+ //
612
+ // Self-scoped — the user can only stamp THEIR OWN handle onto an UNLINKED
613
+ // person they can read — so it safely bypasses the owner-only gate that
614
+ // guards generic user_handle writes (that gate exists to stop a member
615
+ // claiming ANOTHER user's identity; linking yourself isn't that, and it
616
+ // confers no privileges — auth role comes from the account, not the entity).
617
+ fastify.post('/api/auth/me/person-link', async (req, reply) => {
618
+ const user = requireUser(req, authService);
619
+ if (!user)
226
620
  return reply.status(401).send({ error: 'Not authenticated' });
621
+ const chosenId = typeof req.body?.entityId === 'string' ? req.body.entityId.trim() : '';
622
+ // Idempotent / conflict: already linked?
623
+ const existing = findPersonRefForUser(workspaceManager, user.handle);
624
+ if (existing) {
625
+ // Same record (or no specific request) → no-op success. A DIFFERENT
626
+ // record → you're already linked; refuse rather than create a 2nd link.
627
+ if (!chosenId || existing.entityId === chosenId) {
628
+ return reply.send({ action: 'already-linked', personRef: existing });
629
+ }
630
+ return reply.status(409).send({
631
+ error: `Your account is already linked to ${existing.repo}/${existing.entityId}. Unlink it first to link a different record.`,
632
+ code: 'ALREADY_LINKED_ELSEWHERE',
633
+ });
634
+ }
635
+ // Mode 1 — link a specific, user-picked person.
636
+ if (chosenId) {
637
+ const target = workspaceManager.findEntityByTypeAndId('person', chosenId);
638
+ // Collapse "not found" and "can't read it" into one 404 so we don't leak
639
+ // the existence of records in folders the caller can't access.
640
+ if (!target || !access.hasRepoAccess(user, target.repoName, workspaceManager, authService)) {
641
+ return reply.status(404).send({ error: `No person entry "${chosenId}" you can link.`, code: 'PERSON_NOT_FOUND' });
642
+ }
643
+ try {
644
+ // Self-scoped link (own handle, unlinked target) — guards live in the
645
+ // bridge helper; it throws BridgeError on conflict.
646
+ await linkChosenPersonToUser(workspaceManager, user, { repo: target.repoName, entityId: chosenId }, authUserToGitUser(user));
647
+ return reply.send({ action: 'linked', personRef: { repo: target.repoName, entityId: chosenId } });
648
+ }
649
+ catch (err) {
650
+ if (err instanceof BridgeError)
651
+ return reply.status(409).send({ error: err.message, code: err.code, ...err.details });
652
+ return reply.status(500).send({ error: err?.message ?? 'Failed to link person record' });
653
+ }
654
+ }
655
+ // Mode 2 — auto (email-match an existing record, else create one).
656
+ try {
657
+ const r = await ensurePersonForUser(workspaceManager, authService, user, authUserToGitUser(user));
658
+ if (r.action === 'skipped') {
659
+ return reply.status(409).send({
660
+ error: `Could not create a person record (${r.reason}). Ask a workspace owner to designate a shared folder.`,
661
+ code: 'BRIDGE_SKIPPED',
662
+ });
663
+ }
664
+ return reply.send({ action: r.action, personRef: r.ref });
665
+ }
666
+ catch (err) {
667
+ return reply.status(500).send({ error: err?.message ?? 'Failed to link person record' });
227
668
  }
228
- return reply.send({ user });
229
669
  });
230
670
  // PATCH /api/auth/me — update current user's profile
231
671
  fastify.patch('/api/auth/me', async (req, reply) => {
@@ -250,15 +690,23 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
250
690
  return reply.send({ colors: authService.getAllAccentColors() });
251
691
  });
252
692
  // GET /api/auth/status — public endpoint for login page
253
- fastify.get('/api/auth/status', async (_req, reply) => {
693
+ fastify.get('/api/auth/status', async (req, reply) => {
694
+ const cloudAuth = managedCloudAuthConfig();
254
695
  return reply.send({
255
696
  authEnabled: authService.hasUsers(),
256
697
  userCount: authService.getUserCount(),
257
698
  workspaceName: workspaceName || undefined,
699
+ managedAuth: cloudAuth.enabled,
700
+ cloudUrl: cloudAuth.cloudUrl || undefined,
701
+ managedAuthLoginUrl: managedCloudLoginUrl(cloudAuth) || undefined,
702
+ managedAuthLogoutUrl: managedCloudLogoutUrl(cloudAuth, managedLogoutReturnTo(req)) || undefined,
258
703
  });
259
704
  });
260
705
  // POST /api/auth/setup — create the first admin account (only works when no users exist)
261
706
  fastify.post('/api/auth/setup', async (req, reply) => {
707
+ if (managedCloudAuthConfig().enabled) {
708
+ return reply.status(403).send({ error: 'Managed workspaces are set up from Studiograph Cloud' });
709
+ }
262
710
  if (authService.hasUsers()) {
263
711
  return reply.status(403).send({ error: 'Setup already completed' });
264
712
  }
@@ -268,7 +716,28 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
268
716
  }
269
717
  try {
270
718
  const user = authService.createUser(email, password, displayName || email.split('@')[0], 'owner');
271
- await ensurePrivateCollection(workspacePath, workspaceManager, user);
719
+ const setupWorkspace = new Workspace(workspacePath);
720
+ await ensurePersonalFolder(setupWorkspace, authService, user);
721
+ // Provision the reserved workspace-wide "Assets" store once, at first-run
722
+ // setup. Existing workspaces backfill lazily on first asset upload
723
+ // (resolveWorkspaceAssetsRepo) — never via a boot sweep.
724
+ await ensureWorkspaceAssetsFolder(setupWorkspace);
725
+ workspaceManager.reloadConfig();
726
+ // Grant the first owner folder-admin on every existing team folder.
727
+ // Without this, folders scaffolded by `studiograph init` before any
728
+ // user existed end up with zero folder_access rows, and
729
+ // `getAccessibleRepos()` filters them out of the sidebar — the first
730
+ // owner then sees an empty workspace despite the files being on disk.
731
+ // Personal folders are handled by ensurePersonalFolder above; skipping
732
+ // them here avoids granting the owner access to other users' personals.
733
+ for (const repo of workspaceManager.getAllRepoConfigs()) {
734
+ if (repo.personal)
735
+ continue;
736
+ authService.grantFolderAccess(user.id, repo.name, 'admin');
737
+ }
738
+ // No first-owner person auto-provisioning: assignment + "My Tasks" key on
739
+ // the account identity (`[[user:<id>]]`). The owner adds their profile to
740
+ // the graph explicitly from Settings → Profile if they want one.
272
741
  const result = authService.authenticate(email, password);
273
742
  if (!result) {
274
743
  return reply.status(500).send({ error: 'Failed to authenticate after setup' });
@@ -277,7 +746,7 @@ export async function registerAuthApiRoutes(fastify, authService, workspacePath,
277
746
  reply.setCookie('__sg_token', result.token, {
278
747
  path: '/',
279
748
  httpOnly: true,
280
- sameSite: 'strict',
749
+ sameSite: 'lax',
281
750
  secure,
282
751
  maxAge: 7 * 24 * 60 * 60,
283
752
  });