studiograph 1.3.48-next.13 → 1.3.48-next.131

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 (1008) hide show
  1. package/README.md +7 -7
  2. package/dist/agent/agent-pool.d.ts +27 -1
  3. package/dist/agent/agent-pool.js +55 -12
  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 +29 -2
  9. package/dist/agent/orchestrator.js +251 -38
  10. package/dist/agent/orchestrator.js.map +1 -1
  11. package/dist/agent/prompts/entity-types-section.d.ts +30 -0
  12. package/dist/agent/prompts/entity-types-section.js +83 -0
  13. package/dist/agent/prompts/entity-types-section.js.map +1 -0
  14. package/dist/agent/prompts/system.md +106 -47
  15. package/dist/agent/skill-loader.d.ts +30 -17
  16. package/dist/agent/skill-loader.js +63 -30
  17. package/dist/agent/skill-loader.js.map +1 -1
  18. package/dist/agent/skills/entity-schema.md +79 -343
  19. package/dist/agent/skills/interview/entity-templates.md +38 -37
  20. package/dist/agent/skills/interview/question-domains.md +54 -49
  21. package/dist/agent/skills/interview/skill.md +89 -14
  22. package/dist/agent/tools/capture-tools.d.ts +31 -0
  23. package/dist/agent/tools/capture-tools.js +40 -0
  24. package/dist/agent/tools/capture-tools.js.map +1 -0
  25. package/dist/agent/tools/folder-tools.d.ts +47 -0
  26. package/dist/agent/tools/folder-tools.js +249 -0
  27. package/dist/agent/tools/folder-tools.js.map +1 -0
  28. package/dist/agent/tools/fs-tools.d.ts +6 -5
  29. package/dist/agent/tools/fs-tools.js +5 -5
  30. package/dist/agent/tools/fs-tools.js.map +1 -1
  31. package/dist/agent/tools/graph-tools.d.ts +25 -72
  32. package/dist/agent/tools/graph-tools.js +362 -366
  33. package/dist/agent/tools/graph-tools.js.map +1 -1
  34. package/dist/agent/tools/history-tools.d.ts +95 -0
  35. package/dist/agent/tools/history-tools.js +461 -0
  36. package/dist/agent/tools/history-tools.js.map +1 -0
  37. package/dist/agent/tools/load-skill.d.ts +6 -5
  38. package/dist/agent/tools/load-skill.js +3 -3
  39. package/dist/agent/tools/load-skill.js.map +1 -1
  40. package/dist/agent/tools/message-tools.d.ts +13 -11
  41. package/dist/agent/tools/message-tools.js +31 -39
  42. package/dist/agent/tools/message-tools.js.map +1 -1
  43. package/dist/agent/tools/ops-tools.d.ts +5 -4
  44. package/dist/agent/tools/ops-tools.js +99 -212
  45. package/dist/agent/tools/ops-tools.js.map +1 -1
  46. package/dist/agent/tools/permission-tools.d.ts +39 -16
  47. package/dist/agent/tools/permission-tools.js +66 -41
  48. package/dist/agent/tools/permission-tools.js.map +1 -1
  49. package/dist/agent/tools/tool-loader.js +5 -4
  50. package/dist/agent/tools/tool-loader.js.map +1 -1
  51. package/dist/agent/tools/web-tools.js +58 -9
  52. package/dist/agent/tools/web-tools.js.map +1 -1
  53. package/dist/cli/commands/about.d.ts +1 -0
  54. package/dist/cli/commands/about.js +55 -3
  55. package/dist/cli/commands/about.js.map +1 -1
  56. package/dist/cli/commands/audit.d.ts +21 -0
  57. package/dist/cli/commands/audit.js +174 -0
  58. package/dist/cli/commands/audit.js.map +1 -0
  59. package/dist/cli/commands/clear.d.ts +5 -0
  60. package/dist/cli/commands/clear.js +144 -1
  61. package/dist/cli/commands/clear.js.map +1 -1
  62. package/dist/cli/commands/clone.d.ts +1 -1
  63. package/dist/cli/commands/clone.js +82 -23
  64. package/dist/cli/commands/clone.js.map +1 -1
  65. package/dist/cli/commands/deploy.js +79 -18
  66. package/dist/cli/commands/deploy.js.map +1 -1
  67. package/dist/cli/commands/folder.d.ts +11 -0
  68. package/dist/cli/commands/folder.js +186 -0
  69. package/dist/cli/commands/folder.js.map +1 -0
  70. package/dist/cli/commands/index.js +2 -2
  71. package/dist/cli/commands/index.js.map +1 -1
  72. package/dist/cli/commands/init.js +16 -14
  73. package/dist/cli/commands/init.js.map +1 -1
  74. package/dist/cli/commands/join.d.ts +1 -1
  75. package/dist/cli/commands/join.js +26 -14
  76. package/dist/cli/commands/join.js.map +1 -1
  77. package/dist/cli/commands/mcp.js +12 -4
  78. package/dist/cli/commands/mcp.js.map +1 -1
  79. package/dist/cli/commands/r2.d.ts +3 -0
  80. package/dist/cli/commands/r2.js +196 -1
  81. package/dist/cli/commands/r2.js.map +1 -1
  82. package/dist/cli/commands/redeploy.js +41 -1
  83. package/dist/cli/commands/redeploy.js.map +1 -1
  84. package/dist/cli/commands/secrets.d.ts +23 -0
  85. package/dist/cli/commands/secrets.js +256 -0
  86. package/dist/cli/commands/secrets.js.map +1 -0
  87. package/dist/cli/commands/serve.js +143 -24
  88. package/dist/cli/commands/serve.js.map +1 -1
  89. package/dist/cli/commands/start.js +140 -71
  90. package/dist/cli/commands/start.js.map +1 -1
  91. package/dist/cli/commands/sync.d.ts +1 -1
  92. package/dist/cli/commands/sync.js +509 -163
  93. package/dist/cli/commands/sync.js.map +1 -1
  94. package/dist/cli/commands/user.js +8 -24
  95. package/dist/cli/commands/user.js.map +1 -1
  96. package/dist/cli/index.js +8 -7
  97. package/dist/cli/index.js.map +1 -1
  98. package/dist/cli/railway-provisioning.d.ts +53 -0
  99. package/dist/cli/railway-provisioning.js +85 -0
  100. package/dist/cli/railway-provisioning.js.map +1 -0
  101. package/dist/cli/scaffolding.d.ts +4 -2
  102. package/dist/cli/scaffolding.js +42 -47
  103. package/dist/cli/scaffolding.js.map +1 -1
  104. package/dist/cli/setup-wizard.d.ts +30 -49
  105. package/dist/cli/setup-wizard.js +35 -38
  106. package/dist/cli/setup-wizard.js.map +1 -1
  107. package/dist/core/accent-palette.d.ts +22 -0
  108. package/dist/core/accent-palette.js +47 -0
  109. package/dist/core/accent-palette.js.map +1 -0
  110. package/dist/core/entity-body-templates.d.ts +21 -0
  111. package/dist/core/entity-body-templates.js +48 -0
  112. package/dist/core/entity-body-templates.js.map +1 -0
  113. package/dist/core/entity-types-catalog.d.ts +65 -0
  114. package/dist/core/entity-types-catalog.js +136 -0
  115. package/dist/core/entity-types-catalog.js.map +1 -0
  116. package/dist/core/feature-flags.d.ts +22 -0
  117. package/dist/core/feature-flags.js +15 -0
  118. package/dist/core/feature-flags.js.map +1 -0
  119. package/dist/core/features.d.ts +16 -0
  120. package/dist/core/features.js +48 -0
  121. package/dist/core/features.js.map +1 -0
  122. package/dist/core/folder-paths.d.ts +41 -0
  123. package/dist/core/folder-paths.js +95 -0
  124. package/dist/core/folder-paths.js.map +1 -0
  125. package/dist/core/folder-sidecar.d.ts +16 -0
  126. package/dist/core/folder-sidecar.js +45 -0
  127. package/dist/core/folder-sidecar.js.map +1 -0
  128. package/dist/core/graph.d.ts +471 -19
  129. package/dist/core/graph.js +1411 -284
  130. package/dist/core/graph.js.map +1 -1
  131. package/dist/core/schema-registry.js +1 -19
  132. package/dist/core/schema-registry.js.map +1 -1
  133. package/dist/core/schemas/connector.d.ts +67 -0
  134. package/dist/core/schemas/connector.js +100 -0
  135. package/dist/core/schemas/connector.js.map +1 -0
  136. package/dist/core/schemas/workspace.d.ts +122 -0
  137. package/dist/core/schemas/workspace.js +211 -0
  138. package/dist/core/schemas/workspace.js.map +1 -0
  139. package/dist/core/secrets/SecretStore.d.ts +77 -0
  140. package/dist/core/secrets/SecretStore.js +13 -0
  141. package/dist/core/secrets/SecretStore.js.map +1 -0
  142. package/dist/core/secrets/SettingsResolver.d.ts +54 -0
  143. package/dist/core/secrets/SettingsResolver.js +80 -0
  144. package/dist/core/secrets/SettingsResolver.js.map +1 -0
  145. package/dist/core/secrets/SettingsStore.d.ts +30 -0
  146. package/dist/core/secrets/SettingsStore.js +9 -0
  147. package/dist/core/secrets/SettingsStore.js.map +1 -0
  148. package/dist/core/secrets/SqliteEncryptedStore.d.ts +78 -0
  149. package/dist/core/secrets/SqliteEncryptedStore.js +581 -0
  150. package/dist/core/secrets/SqliteEncryptedStore.js.map +1 -0
  151. package/dist/core/secrets/audit.d.ts +36 -0
  152. package/dist/core/secrets/audit.js +60 -0
  153. package/dist/core/secrets/audit.js.map +1 -0
  154. package/dist/core/secrets/auth-db-migration.d.ts +129 -0
  155. package/dist/core/secrets/auth-db-migration.js +653 -0
  156. package/dist/core/secrets/auth-db-migration.js.map +1 -0
  157. package/dist/core/secrets/bundle.d.ts +141 -0
  158. package/dist/core/secrets/bundle.js +435 -0
  159. package/dist/core/secrets/bundle.js.map +1 -0
  160. package/dist/core/secrets/dual-write.d.ts +76 -0
  161. package/dist/core/secrets/dual-write.js +236 -0
  162. package/dist/core/secrets/dual-write.js.map +1 -0
  163. package/dist/core/secrets/encryption.d.ts +44 -0
  164. package/dist/core/secrets/encryption.js +97 -0
  165. package/dist/core/secrets/encryption.js.map +1 -0
  166. package/dist/core/secrets/importer.d.ts +94 -0
  167. package/dist/core/secrets/importer.js +319 -0
  168. package/dist/core/secrets/importer.js.map +1 -0
  169. package/dist/core/secrets/index.d.ts +49 -0
  170. package/dist/core/secrets/index.js +74 -0
  171. package/dist/core/secrets/index.js.map +1 -0
  172. package/dist/core/secrets/master-key.d.ts +38 -0
  173. package/dist/core/secrets/master-key.js +122 -0
  174. package/dist/core/secrets/master-key.js.map +1 -0
  175. package/dist/core/secrets/probes/anthropic.d.ts +98 -0
  176. package/dist/core/secrets/probes/anthropic.js +300 -0
  177. package/dist/core/secrets/probes/anthropic.js.map +1 -0
  178. package/dist/core/secrets/probes/brave.d.ts +9 -0
  179. package/dist/core/secrets/probes/brave.js +15 -0
  180. package/dist/core/secrets/probes/brave.js.map +1 -0
  181. package/dist/core/secrets/probes/r2.d.ts +15 -0
  182. package/dist/core/secrets/probes/r2.js +14 -0
  183. package/dist/core/secrets/probes/r2.js.map +1 -0
  184. package/dist/core/secrets/probes/voyage.d.ts +13 -0
  185. package/dist/core/secrets/probes/voyage.js +52 -0
  186. package/dist/core/secrets/probes/voyage.js.map +1 -0
  187. package/dist/core/secrets/read-flip.d.ts +59 -0
  188. package/dist/core/secrets/read-flip.js +87 -0
  189. package/dist/core/secrets/read-flip.js.map +1 -0
  190. package/dist/core/secrets/registry.d.ts +188 -0
  191. package/dist/core/secrets/registry.js +531 -0
  192. package/dist/core/secrets/registry.js.map +1 -0
  193. package/dist/core/types.d.ts +70 -483
  194. package/dist/core/types.js +6 -3
  195. package/dist/core/types.js.map +1 -1
  196. package/dist/core/user-config.d.ts +52 -12
  197. package/dist/core/user-config.js +119 -14
  198. package/dist/core/user-config.js.map +1 -1
  199. package/dist/core/validation.d.ts +603 -1409
  200. package/dist/core/validation.js +248 -146
  201. package/dist/core/validation.js.map +1 -1
  202. package/dist/core/workspace-manager.d.ts +35 -14
  203. package/dist/core/workspace-manager.js +105 -56
  204. package/dist/core/workspace-manager.js.map +1 -1
  205. package/dist/core/workspace.d.ts +19 -5
  206. package/dist/core/workspace.js +66 -39
  207. package/dist/core/workspace.js.map +1 -1
  208. package/dist/mcp/connector-manager.d.ts +16 -1
  209. package/dist/mcp/connector-manager.js +44 -5
  210. package/dist/mcp/connector-manager.js.map +1 -1
  211. package/dist/mcp/server.d.ts +11 -3
  212. package/dist/mcp/server.js +30 -5
  213. package/dist/mcp/server.js.map +1 -1
  214. package/dist/mcp/tools.d.ts +27 -2
  215. package/dist/mcp/tools.js +544 -113
  216. package/dist/mcp/tools.js.map +1 -1
  217. package/dist/server/__tests__/helpers/graph-api.d.ts +18 -0
  218. package/dist/server/__tests__/helpers/graph-api.js +16 -0
  219. package/dist/server/__tests__/helpers/graph-api.js.map +1 -0
  220. package/dist/server/commit-audit.d.ts +26 -0
  221. package/dist/server/commit-audit.js +30 -0
  222. package/dist/server/commit-audit.js.map +1 -0
  223. package/dist/server/index.d.ts +14 -3
  224. package/dist/server/index.js +385 -177
  225. package/dist/server/index.js.map +1 -1
  226. package/dist/server/middleware/sanitize.d.ts +46 -0
  227. package/dist/server/middleware/sanitize.js +171 -0
  228. package/dist/server/middleware/sanitize.js.map +1 -0
  229. package/dist/server/routes/asset-api.js +217 -65
  230. package/dist/server/routes/asset-api.js.map +1 -1
  231. package/dist/server/routes/audit-api.d.ts +24 -0
  232. package/dist/server/routes/audit-api.js +117 -0
  233. package/dist/server/routes/audit-api.js.map +1 -0
  234. package/dist/server/routes/auth-api.js +220 -44
  235. package/dist/server/routes/auth-api.js.map +1 -1
  236. package/dist/server/routes/capture-api.d.ts +10 -3
  237. package/dist/server/routes/capture-api.js +180 -24
  238. package/dist/server/routes/capture-api.js.map +1 -1
  239. package/dist/server/routes/chat.d.ts +4 -1
  240. package/dist/server/routes/chat.js +178 -46
  241. package/dist/server/routes/chat.js.map +1 -1
  242. package/dist/server/routes/config-api.d.ts +21 -0
  243. package/dist/server/routes/config-api.js +256 -0
  244. package/dist/server/routes/config-api.js.map +1 -0
  245. package/dist/server/routes/connectors-api.js +24 -18
  246. package/dist/server/routes/connectors-api.js.map +1 -1
  247. package/dist/server/routes/event-ingest-api.d.ts +15 -0
  248. package/dist/server/routes/event-ingest-api.js +125 -0
  249. package/dist/server/routes/event-ingest-api.js.map +1 -0
  250. package/dist/server/routes/features-api.d.ts +19 -0
  251. package/dist/server/routes/features-api.js +28 -0
  252. package/dist/server/routes/features-api.js.map +1 -0
  253. package/dist/server/routes/git-http.d.ts +2 -2
  254. package/dist/server/routes/git-http.js +69 -34
  255. package/dist/server/routes/git-http.js.map +1 -1
  256. package/dist/server/routes/graph-api-access.d.ts +35 -0
  257. package/dist/server/routes/graph-api-access.js +93 -0
  258. package/dist/server/routes/graph-api-access.js.map +1 -0
  259. package/dist/server/routes/graph-api.d.ts +3 -2
  260. package/dist/server/routes/graph-api.js +1014 -315
  261. package/dist/server/routes/graph-api.js.map +1 -1
  262. package/dist/server/routes/health.d.ts +18 -0
  263. package/dist/server/routes/health.js +74 -0
  264. package/dist/server/routes/health.js.map +1 -0
  265. package/dist/server/routes/insights-api.js +156 -33
  266. package/dist/server/routes/insights-api.js.map +1 -1
  267. package/dist/server/routes/mcp.d.ts +6 -3
  268. package/dist/server/routes/mcp.js +22 -6
  269. package/dist/server/routes/mcp.js.map +1 -1
  270. package/dist/server/routes/messages-api.d.ts +3 -3
  271. package/dist/server/routes/messages-api.js +308 -120
  272. package/dist/server/routes/messages-api.js.map +1 -1
  273. package/dist/server/routes/permissions-api.d.ts +9 -2
  274. package/dist/server/routes/permissions-api.js +87 -31
  275. package/dist/server/routes/permissions-api.js.map +1 -1
  276. package/dist/server/routes/secrets-api.d.ts +36 -0
  277. package/dist/server/routes/secrets-api.js +308 -0
  278. package/dist/server/routes/secrets-api.js.map +1 -0
  279. package/dist/server/routes/settings-api.d.ts +29 -0
  280. package/dist/server/routes/settings-api.js +180 -0
  281. package/dist/server/routes/settings-api.js.map +1 -0
  282. package/dist/server/routes/workspace-api.d.ts +2 -1
  283. package/dist/server/routes/workspace-api.js +131 -20
  284. package/dist/server/routes/workspace-api.js.map +1 -1
  285. package/dist/server/routes/ws.d.ts +3 -2
  286. package/dist/server/routes/ws.js +68 -18
  287. package/dist/server/routes/ws.js.map +1 -1
  288. package/dist/server/session-manager.d.ts +48 -5
  289. package/dist/server/session-manager.js +175 -11
  290. package/dist/server/session-manager.js.map +1 -1
  291. package/dist/server/ws-hub.d.ts +134 -22
  292. package/dist/server/ws-hub.js +0 -0
  293. package/dist/server/ws-hub.js.map +1 -1
  294. package/dist/server/yjs-manager.d.ts +107 -7
  295. package/dist/server/yjs-manager.js +444 -38
  296. package/dist/server/yjs-manager.js.map +1 -1
  297. package/dist/server/yjs-persistence.d.ts +143 -0
  298. package/dist/server/yjs-persistence.js +543 -0
  299. package/dist/server/yjs-persistence.js.map +1 -0
  300. package/dist/server/yjs-text-diff.d.ts +32 -0
  301. package/dist/server/yjs-text-diff.js +61 -0
  302. package/dist/server/yjs-text-diff.js.map +1 -0
  303. package/dist/services/access-control.d.ts +53 -0
  304. package/dist/services/access-control.js +132 -0
  305. package/dist/services/access-control.js.map +1 -0
  306. package/dist/services/asset-upload-service.d.ts +53 -0
  307. package/dist/services/asset-upload-service.js +200 -0
  308. package/dist/services/asset-upload-service.js.map +1 -0
  309. package/dist/services/assets/base.d.ts +38 -0
  310. package/dist/services/assets/base.js +55 -0
  311. package/dist/services/assets/base.js.map +1 -1
  312. package/dist/services/assets/index.d.ts +41 -1
  313. package/dist/services/assets/index.js +65 -0
  314. package/dist/services/assets/index.js.map +1 -1
  315. package/dist/services/assets/local.d.ts +7 -1
  316. package/dist/services/assets/local.js +83 -0
  317. package/dist/services/assets/local.js.map +1 -1
  318. package/dist/services/assets/r2.d.ts +28 -1
  319. package/dist/services/assets/r2.js +75 -1
  320. package/dist/services/assets/r2.js.map +1 -1
  321. package/dist/services/auth-service.d.ts +184 -36
  322. package/dist/services/auth-service.js +763 -138
  323. package/dist/services/auth-service.js.map +1 -1
  324. package/dist/services/briefing.d.ts +1 -1
  325. package/dist/services/briefing.js +12 -35
  326. package/dist/services/briefing.js.map +1 -1
  327. package/dist/services/event-processor.d.ts +104 -0
  328. package/dist/services/event-processor.js +443 -0
  329. package/dist/services/event-processor.js.map +1 -0
  330. package/dist/services/folder-creation.d.ts +33 -0
  331. package/dist/services/folder-creation.js +103 -0
  332. package/dist/services/folder-creation.js.map +1 -0
  333. package/dist/services/git.d.ts +44 -0
  334. package/dist/services/git.js +162 -55
  335. package/dist/services/git.js.map +1 -1
  336. package/dist/services/heartbeat.d.ts +19 -12
  337. package/dist/services/heartbeat.js +162 -107
  338. package/dist/services/heartbeat.js.map +1 -1
  339. package/dist/services/import-service.d.ts +37 -2
  340. package/dist/services/import-service.js +222 -123
  341. package/dist/services/import-service.js.map +1 -1
  342. package/dist/services/lint-service.js +7 -14
  343. package/dist/services/lint-service.js.map +1 -1
  344. package/dist/services/markdown.js +6 -2
  345. package/dist/services/markdown.js.map +1 -1
  346. package/dist/services/message-service.d.ts +62 -21
  347. package/dist/services/message-service.js +160 -43
  348. package/dist/services/message-service.js.map +1 -1
  349. package/dist/services/personal-folder.d.ts +40 -0
  350. package/dist/services/personal-folder.js +101 -0
  351. package/dist/services/personal-folder.js.map +1 -0
  352. package/dist/services/vector-service.d.ts +73 -3
  353. package/dist/services/vector-service.js +106 -7
  354. package/dist/services/vector-service.js.map +1 -1
  355. package/dist/services/workspace-access.d.ts +106 -0
  356. package/dist/services/workspace-access.js +149 -0
  357. package/dist/services/workspace-access.js.map +1 -0
  358. package/dist/utils/git.js +3 -3
  359. package/dist/utils/git.js.map +1 -1
  360. package/dist/utils/log.d.ts +42 -0
  361. package/dist/utils/log.js +137 -0
  362. package/dist/utils/log.js.map +1 -0
  363. package/dist/utils/preflight.js +2 -2
  364. package/dist/utils/preflight.js.map +1 -1
  365. package/dist/utils/version-checker.d.ts +4 -1
  366. package/dist/utils/version-checker.js +8 -8
  367. package/dist/utils/version-checker.js.map +1 -1
  368. package/dist/web/_app/immutable/assets/0.Bp6xXZUi.css +2 -0
  369. package/dist/web/_app/immutable/assets/11.DlIf1mKh.css +1 -0
  370. package/dist/web/_app/immutable/assets/12.Dmlt28l2.css +1 -0
  371. package/dist/web/_app/immutable/assets/13.CmLrbzZp.css +1 -0
  372. package/dist/web/_app/immutable/assets/2.oo1ac0x_.css +1 -0
  373. package/dist/web/_app/immutable/assets/3.DJJsQzDb.css +1 -0
  374. package/dist/web/_app/immutable/assets/4.CZ-fNJ91.css +1 -0
  375. package/dist/web/_app/immutable/assets/AgentOverlay.BfWESlQU.css +1 -0
  376. package/dist/web/_app/immutable/assets/AssetManagerModal.ZfasE2L3.css +1 -0
  377. package/dist/web/_app/immutable/assets/CalendarView.CeNagvyK.css +1 -0
  378. package/dist/web/_app/immutable/assets/ChatPanel.po0gYtVH.css +1 -0
  379. package/dist/web/_app/immutable/assets/FolderMembersPanel.Bepw-r0F.css +1 -0
  380. package/dist/web/_app/immutable/assets/FolderMutationDialogs.BMRF6Z3z.css +1 -0
  381. package/dist/web/_app/immutable/assets/FolderPicker.B5KdvRYl.css +1 -0
  382. package/dist/web/_app/immutable/assets/GalleryView.Dy-qQjEc.css +1 -0
  383. package/dist/web/_app/immutable/assets/GraphView.BHnGIltS.css +1 -0
  384. package/dist/web/_app/immutable/assets/KanbanView.G3NZ0uHb.css +1 -0
  385. package/dist/web/_app/immutable/assets/SettingsDialog.tBn8y9DD.css +1 -0
  386. package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
  387. package/dist/web/_app/immutable/assets/TagFilter.DNipjifq.css +1 -0
  388. package/dist/web/_app/immutable/assets/TagPickerSheet.DJPuqnTg.css +1 -0
  389. package/dist/web/_app/immutable/assets/WorkspaceView.B9zA92UB.css +1 -0
  390. package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
  391. package/dist/web/_app/immutable/assets/dialog.BxVal_19.css +1 -0
  392. package/dist/web/_app/immutable/assets/dist.B5hGjnfj.css +1 -0
  393. package/dist/web/_app/immutable/assets/dist.DDCWxn3B.css +1 -0
  394. package/dist/web/_app/immutable/assets/dropdown-menu.BSsUUQ3o.css +1 -0
  395. package/dist/web/_app/immutable/assets/entity-row.Bl5FyNCt.css +1 -0
  396. package/dist/web/_app/immutable/assets/greeting.Bm7lTneV.css +1 -0
  397. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff +0 -0
  398. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2 +0 -0
  399. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff +0 -0
  400. package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2 +0 -0
  401. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CZTNEAuW.woff2 +0 -0
  402. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CsGl1sm0.woff +0 -0
  403. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2 +0 -0
  404. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff +0 -0
  405. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.BNK2_mGO.woff2 +0 -0
  406. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.DpEwFAQM.woff +0 -0
  407. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2 +0 -0
  408. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff +0 -0
  409. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff +0 -0
  410. package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2 +0 -0
  411. package/dist/web/_app/immutable/assets/inline-list.DORLo4xF.css +1 -0
  412. package/dist/web/_app/immutable/assets/notifications.clodJdp5.css +1 -0
  413. package/dist/web/_app/immutable/assets/radio-group.GJJRVPUJ.css +1 -0
  414. package/dist/web/_app/immutable/assets/select.D_AV992j.css +1 -0
  415. package/dist/web/_app/immutable/chunks/-KAQXGuI2.js +1 -0
  416. package/dist/web/_app/immutable/chunks/-wzwcH00.js +1 -0
  417. package/dist/web/_app/immutable/chunks/07l_1Zpm2.js +1 -0
  418. package/dist/web/_app/immutable/chunks/38oWKNzM2.js +6 -0
  419. package/dist/web/_app/immutable/chunks/54VmiJfH.js +1 -0
  420. package/dist/web/_app/immutable/chunks/6LRpFvjo.js +185 -0
  421. package/dist/web/_app/immutable/chunks/7R0Rp3Mz.js +1 -0
  422. package/dist/web/_app/immutable/chunks/9bCTHkeS.js +1 -0
  423. package/dist/web/_app/immutable/chunks/B-822WnD2.js +22 -0
  424. package/dist/web/_app/immutable/chunks/B0HUvliX2.js +2 -0
  425. package/dist/web/_app/immutable/chunks/B12eXGpE.js +1 -0
  426. package/dist/web/_app/immutable/chunks/B5af0X0p2.js +1 -0
  427. package/dist/web/_app/immutable/chunks/B6iYNwo72.js +1 -0
  428. package/dist/web/_app/immutable/chunks/B7EMtoAB.js +1 -0
  429. package/dist/web/_app/immutable/chunks/B7L4gmPR.js +2 -0
  430. package/dist/web/_app/immutable/chunks/B9qBGxh62.js +3 -0
  431. package/dist/web/_app/immutable/chunks/BDJYj9yi.js +2 -0
  432. package/dist/web/_app/immutable/chunks/BEpMEjHO.js +1 -0
  433. package/dist/web/_app/immutable/chunks/BErNpj-S2.js +1 -0
  434. package/dist/web/_app/immutable/chunks/BHBk4zfV.js +1 -0
  435. package/dist/web/_app/immutable/chunks/BHH-JGNF.js +1 -0
  436. package/dist/web/_app/immutable/chunks/BKe5wPiN.js +1 -0
  437. package/dist/web/_app/immutable/chunks/BNTlsKDJ.js +1 -0
  438. package/dist/web/_app/immutable/chunks/BOgcXgis2.js +1 -0
  439. package/dist/web/_app/immutable/chunks/BOyyDrjn2.js +1 -0
  440. package/dist/web/_app/immutable/chunks/BPR_ufQ0.js +41 -0
  441. package/dist/web/_app/immutable/chunks/BRcFsc6v.js +5 -0
  442. package/dist/web/_app/immutable/chunks/BT3KAag_.js +3 -0
  443. package/dist/web/_app/immutable/chunks/BX2T6xiZ.js +224 -0
  444. package/dist/web/_app/immutable/chunks/BZnJ8tbJ.js +1 -0
  445. package/dist/web/_app/immutable/chunks/Ba1Yzb7u.js +1 -0
  446. package/dist/web/_app/immutable/chunks/BcsvgA3B2.js +1 -0
  447. package/dist/web/_app/immutable/chunks/BfbS7rGT.js +1 -0
  448. package/dist/web/_app/immutable/chunks/BgagL41Z.js +1 -0
  449. package/dist/web/_app/immutable/chunks/BiUh0Sik.js +1 -0
  450. package/dist/web/_app/immutable/chunks/Biajc_oU.js +1 -0
  451. package/dist/web/_app/immutable/chunks/Bl9Pzopy.js +1 -0
  452. package/dist/web/_app/immutable/chunks/BmcU05mO.js +1 -0
  453. package/dist/web/_app/immutable/chunks/Bmgp0jlT.js +1 -0
  454. package/dist/web/_app/immutable/chunks/BmgyOoEp.js +1 -0
  455. package/dist/web/_app/immutable/chunks/Bq0-jBGC2.js +1 -0
  456. package/dist/web/_app/immutable/chunks/BqGj0_GS.js +1 -0
  457. package/dist/web/_app/immutable/chunks/Bsc9K3Pz.js +1 -0
  458. package/dist/web/_app/immutable/chunks/Bssb691Q.js +1 -0
  459. package/dist/web/_app/immutable/chunks/BuzQceOn.js +1 -0
  460. package/dist/web/_app/immutable/chunks/BzeVNab0.js +1 -0
  461. package/dist/web/_app/immutable/chunks/C-OaypFN.js +1 -0
  462. package/dist/web/_app/immutable/chunks/C0fjDjvE2.js +1 -0
  463. package/dist/web/_app/immutable/chunks/C0pTXwEX.js +2 -0
  464. package/dist/web/_app/immutable/chunks/C3Enww9L2.js +1 -0
  465. package/dist/web/_app/immutable/chunks/C3oa0Cks.js +1 -0
  466. package/dist/web/_app/immutable/chunks/CC-YWp-f.js +1 -0
  467. package/dist/web/_app/immutable/chunks/CGdKvXV92.js +1 -0
  468. package/dist/web/_app/immutable/chunks/CH0siYFL.js +1 -0
  469. package/dist/web/_app/immutable/chunks/CIchr8Tk2.js +1 -0
  470. package/dist/web/_app/immutable/chunks/CK_yXDQI.js +1 -0
  471. package/dist/web/_app/immutable/chunks/CLPtMig0.js +1 -0
  472. package/dist/web/_app/immutable/chunks/CLSxJmTj.js +2 -0
  473. package/dist/web/_app/immutable/chunks/CPQNcHIB.js +3 -0
  474. package/dist/web/_app/immutable/chunks/CPt2D5aU.js +1 -0
  475. package/dist/web/_app/immutable/chunks/CQ-2yccd.js +7 -0
  476. package/dist/web/_app/immutable/chunks/CS6VEwn7.js +1 -0
  477. package/dist/web/_app/immutable/chunks/CSGIGrrK.js +1 -0
  478. package/dist/web/_app/immutable/chunks/CSsDOIrk.js +1 -0
  479. package/dist/web/_app/immutable/chunks/CVXvEWhv2.js +1 -0
  480. package/dist/web/_app/immutable/chunks/CaChtuYU2.js +1 -0
  481. package/dist/web/_app/immutable/chunks/CbiwvM3R2.js +1 -0
  482. package/dist/web/_app/immutable/chunks/CdCuBMLm.js +156 -0
  483. package/dist/web/_app/immutable/chunks/CfqjDDMu.js +1 -0
  484. package/dist/web/_app/immutable/chunks/CjGzUnEF2.js +1 -0
  485. package/dist/web/_app/immutable/chunks/Cjgbiel7.js +1 -0
  486. package/dist/web/_app/immutable/chunks/ClNEskRf.js +1 -0
  487. package/dist/web/_app/immutable/chunks/CnqSKqA62.js +1 -0
  488. package/dist/web/_app/immutable/chunks/CqyqKPuh2.js +1 -0
  489. package/dist/web/_app/immutable/chunks/CrnX-oFV.js +1 -0
  490. package/dist/web/_app/immutable/chunks/CsGahE3a.js +1 -0
  491. package/dist/web/_app/immutable/chunks/CsXIliss.js +1 -0
  492. package/dist/web/_app/immutable/chunks/Ct3quP0F.js +1 -0
  493. package/dist/web/_app/immutable/chunks/CvZaxjRC.js +1 -0
  494. package/dist/web/_app/immutable/chunks/CwD4G56R.js +5 -0
  495. package/dist/web/_app/immutable/chunks/CxalqrMB.js +1 -0
  496. package/dist/web/_app/immutable/chunks/D1Ap3evT2.js +1 -0
  497. package/dist/web/_app/immutable/chunks/D7qgUfnr.js +2487 -0
  498. package/dist/web/_app/immutable/chunks/D9-_Euza2.js +1 -0
  499. package/dist/web/_app/immutable/chunks/DCCaoKt42.js +1 -0
  500. package/dist/web/_app/immutable/chunks/DDKweOZr2.js +23 -0
  501. package/dist/web/_app/immutable/chunks/DHeU-hHI2.js +2 -0
  502. package/dist/web/_app/immutable/chunks/DHepUItL.js +1 -0
  503. package/dist/web/_app/immutable/chunks/DL_KbCKq.js +8 -0
  504. package/dist/web/_app/immutable/chunks/DNtqqgv32.js +1 -0
  505. package/dist/web/_app/immutable/chunks/DRl7vwNC2.js +184 -0
  506. package/dist/web/_app/immutable/chunks/DTc5W_V6.js +1 -0
  507. package/dist/web/_app/immutable/chunks/DZetJu9k2.js +1 -0
  508. package/dist/web/_app/immutable/chunks/DaiJs3St.js +1 -0
  509. package/dist/web/_app/immutable/chunks/DhuJRrEX2.js +1 -0
  510. package/dist/web/_app/immutable/chunks/DiP2EplP.js +3 -0
  511. package/dist/web/_app/immutable/chunks/Dm25ot5x2.js +1 -0
  512. package/dist/web/_app/immutable/chunks/DqOcb9RX2.js +83 -0
  513. package/dist/web/_app/immutable/chunks/DrbUJCAE.js +1 -0
  514. package/dist/web/_app/immutable/chunks/Dt4HY2cT2.js +2 -0
  515. package/dist/web/_app/immutable/chunks/DtGUCMv8.js +6 -0
  516. package/dist/web/_app/immutable/chunks/Du2-B3c8.js +1 -0
  517. package/dist/web/_app/immutable/chunks/DwdkE4UD2.js +1 -0
  518. package/dist/web/_app/immutable/chunks/DxWesPbn.js +1 -0
  519. package/dist/web/_app/immutable/chunks/DyYZqUV72.js +1 -0
  520. package/dist/web/_app/immutable/chunks/HfUnhvrv2.js +1 -0
  521. package/dist/web/_app/immutable/chunks/Je8-BtCk2.js +1 -0
  522. package/dist/web/_app/immutable/chunks/LAN53VbP2.js +5 -0
  523. package/dist/web/_app/immutable/chunks/MSB7eA4_.js +1 -0
  524. package/dist/web/_app/immutable/chunks/NPe9WyW1.js +1 -0
  525. package/dist/web/_app/immutable/chunks/O6IzcxXJ.js +2 -0
  526. package/dist/web/_app/immutable/chunks/SXhc9rJW.js +1 -0
  527. package/dist/web/_app/immutable/chunks/TuBvdkhV2.js +1 -0
  528. package/dist/web/_app/immutable/chunks/U40J2SnU.js +1 -0
  529. package/dist/web/_app/immutable/chunks/VS3l21Gu.js +1 -0
  530. package/dist/web/_app/immutable/chunks/YEPEvlbU2.js +1 -0
  531. package/dist/web/_app/immutable/chunks/Z7TNRcgK.js +11 -0
  532. package/dist/web/_app/immutable/chunks/ZCekGjo6.js +5 -0
  533. package/dist/web/_app/immutable/chunks/_rnxQ655.js +4 -0
  534. package/dist/web/_app/immutable/chunks/dTXrX5Bw.js +2 -0
  535. package/dist/web/_app/immutable/chunks/gNXLhsdy.js +1 -0
  536. package/dist/web/_app/immutable/chunks/hKSTEN36.js +1 -0
  537. package/dist/web/_app/immutable/chunks/jZZTbzL5.js +1 -0
  538. package/dist/web/_app/immutable/chunks/l4FIBKss.js +1 -0
  539. package/dist/web/_app/immutable/chunks/l_4snZnh2.js +1 -0
  540. package/dist/web/_app/immutable/chunks/q6R6T-lK.js +1 -0
  541. package/dist/web/_app/immutable/chunks/qgprkMcL.js +1 -0
  542. package/dist/web/_app/immutable/chunks/rOisBLC62.js +14 -0
  543. package/dist/web/_app/immutable/chunks/t08TznXc2.js +1 -0
  544. package/dist/web/_app/immutable/chunks/t62M88qj.js +1 -0
  545. package/dist/web/_app/immutable/chunks/uCohGWC42.js +1 -0
  546. package/dist/web/_app/immutable/chunks/uqxmB78b.js +1 -0
  547. package/dist/web/_app/immutable/chunks/vwTMEIJQ.js +1 -0
  548. package/dist/web/_app/immutable/chunks/w1FCELam.js +64 -0
  549. package/dist/web/_app/immutable/chunks/zmjgin7A.js +1 -0
  550. package/dist/web/_app/immutable/chunks/zumDjcgJ.js +1 -0
  551. package/dist/web/_app/immutable/entry/app.B3JEO5sy.js +2 -0
  552. package/dist/web/_app/immutable/entry/start.Dk84vnrL.js +1 -0
  553. package/dist/web/_app/immutable/nodes/0.BKLFgYTV.js +2 -0
  554. package/dist/web/_app/immutable/nodes/1.Djf_1kN1.js +1 -0
  555. package/dist/web/_app/immutable/nodes/10.De6eGWLx.js +1 -0
  556. package/dist/web/_app/immutable/nodes/11.CDsfSRTw.js +1 -0
  557. package/dist/web/_app/immutable/nodes/12.BeKkKpkY.js +1 -0
  558. package/dist/web/_app/immutable/nodes/13.BcI8xwSy.js +1 -0
  559. package/dist/web/_app/immutable/nodes/2.ZMZ-QAZ7.js +106 -0
  560. package/dist/web/_app/immutable/nodes/3.C1ZiAfle.js +2 -0
  561. package/dist/web/_app/immutable/nodes/4.Chmqy9KF.js +2 -0
  562. package/dist/web/_app/immutable/nodes/5.Bpvr_Vcq.js +1 -0
  563. package/dist/web/_app/immutable/nodes/6.BHa_gOs3.js +1 -0
  564. package/dist/web/_app/immutable/nodes/7.D0hg4Eap.js +1 -0
  565. package/dist/web/_app/immutable/nodes/8.3ZUUxJqR.js +1 -0
  566. package/dist/web/_app/immutable/nodes/9.Ducy-oqR.js +1 -0
  567. package/dist/web/_app/version.json +1 -1
  568. package/dist/web/favicon-16.png +0 -0
  569. package/dist/web/favicon-180.png +0 -0
  570. package/dist/web/favicon-32.png +0 -0
  571. package/dist/web/favicon-48.png +0 -0
  572. package/dist/web/favicon-512.png +0 -0
  573. package/dist/web/favicon.ico +0 -0
  574. package/dist/web/favicon.svg +8 -0
  575. package/dist/web/index.html +64 -21
  576. package/dist/web/studiograph-logomark.svg +29 -0
  577. package/package.json +28 -14
  578. package/dist/agent/role-loader.d.ts +0 -24
  579. package/dist/agent/role-loader.js +0 -67
  580. package/dist/agent/role-loader.js.map +0 -1
  581. package/dist/agent/skills/enrich-entities.md +0 -136
  582. package/dist/agent/skills/obsidian-source-setup.md +0 -246
  583. package/dist/agent/skills/skill-loader.d.ts +0 -48
  584. package/dist/agent/skills/skill-loader.js +0 -166
  585. package/dist/agent/skills/skill-loader.js.map +0 -1
  586. package/dist/agent/skills/sync-configuration.md +0 -119
  587. package/dist/agent/skills/sync-setup.md +0 -82
  588. package/dist/agent/tools/sync-tools.d.ts +0 -35
  589. package/dist/agent/tools/sync-tools.js +0 -992
  590. package/dist/agent/tools/sync-tools.js.map +0 -1
  591. package/dist/auth/github.d.ts +0 -56
  592. package/dist/auth/github.js +0 -169
  593. package/dist/auth/github.js.map +0 -1
  594. package/dist/cli/commands/access.d.ts +0 -11
  595. package/dist/cli/commands/access.js +0 -156
  596. package/dist/cli/commands/access.js.map +0 -1
  597. package/dist/cli/commands/app.d.ts +0 -7
  598. package/dist/cli/commands/app.js +0 -268
  599. package/dist/cli/commands/app.js.map +0 -1
  600. package/dist/cli/commands/auth.d.ts +0 -10
  601. package/dist/cli/commands/auth.js +0 -79
  602. package/dist/cli/commands/auth.js.map +0 -1
  603. package/dist/cli/commands/collection.d.ts +0 -10
  604. package/dist/cli/commands/collection.js +0 -185
  605. package/dist/cli/commands/collection.js.map +0 -1
  606. package/dist/cli/commands/enrich.d.ts +0 -11
  607. package/dist/cli/commands/enrich.js +0 -135
  608. package/dist/cli/commands/enrich.js.map +0 -1
  609. package/dist/cli/commands/graphrag.d.ts +0 -12
  610. package/dist/cli/commands/graphrag.js +0 -122
  611. package/dist/cli/commands/graphrag.js.map +0 -1
  612. package/dist/cli/commands/members.d.ts +0 -11
  613. package/dist/cli/commands/members.js +0 -230
  614. package/dist/cli/commands/members.js.map +0 -1
  615. package/dist/cli/commands/org.d.ts +0 -10
  616. package/dist/cli/commands/org.js +0 -132
  617. package/dist/cli/commands/org.js.map +0 -1
  618. package/dist/cli/commands/provision.d.ts +0 -8
  619. package/dist/cli/commands/provision.js +0 -116
  620. package/dist/cli/commands/provision.js.map +0 -1
  621. package/dist/cli/commands/resolve.d.ts +0 -8
  622. package/dist/cli/commands/resolve.js +0 -85
  623. package/dist/cli/commands/resolve.js.map +0 -1
  624. package/dist/cli/commands/review.d.ts +0 -19
  625. package/dist/cli/commands/review.js +0 -128
  626. package/dist/cli/commands/review.js.map +0 -1
  627. package/dist/cli/commands/source.d.ts +0 -16
  628. package/dist/cli/commands/source.js +0 -159
  629. package/dist/cli/commands/source.js.map +0 -1
  630. package/dist/cli/commands/sync-collection.d.ts +0 -14
  631. package/dist/cli/commands/sync-collection.js +0 -355
  632. package/dist/cli/commands/sync-collection.js.map +0 -1
  633. package/dist/cli/commands/sync-entities.d.ts +0 -13
  634. package/dist/cli/commands/sync-entities.js +0 -242
  635. package/dist/cli/commands/sync-entities.js.map +0 -1
  636. package/dist/cli/commands/team.d.ts +0 -12
  637. package/dist/cli/commands/team.js +0 -185
  638. package/dist/cli/commands/team.js.map +0 -1
  639. package/dist/cli/sync-review-interactive.d.ts +0 -31
  640. package/dist/cli/sync-review-interactive.js +0 -393
  641. package/dist/cli/sync-review-interactive.js.map +0 -1
  642. package/dist/core/migration-runner.d.ts +0 -42
  643. package/dist/core/migration-runner.js +0 -232
  644. package/dist/core/migration-runner.js.map +0 -1
  645. package/dist/core/migration-types.d.ts +0 -101
  646. package/dist/core/migration-types.js +0 -21
  647. package/dist/core/migration-types.js.map +0 -1
  648. package/dist/core/migrations/20260219-formalize-memory-location.d.ts +0 -2
  649. package/dist/core/migrations/20260219-formalize-memory-location.js +0 -35
  650. package/dist/core/migrations/20260219-formalize-memory-location.js.map +0 -1
  651. package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +0 -12
  652. package/dist/core/migrations/20260220-add-workspace-metadata.js +0 -65
  653. package/dist/core/migrations/20260220-add-workspace-metadata.js.map +0 -1
  654. package/dist/core/migrations/20260220-add-workspace-readme.d.ts +0 -11
  655. package/dist/core/migrations/20260220-add-workspace-readme.js +0 -82
  656. package/dist/core/migrations/20260220-add-workspace-readme.js.map +0 -1
  657. package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +0 -9
  658. package/dist/core/migrations/20260220-migrate-yaml-to-json.js +0 -64
  659. package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +0 -1
  660. package/dist/core/migrations/index.d.ts +0 -11
  661. package/dist/core/migrations/index.js +0 -23
  662. package/dist/core/migrations/index.js.map +0 -1
  663. package/dist/integrations/asana.d.ts +0 -26
  664. package/dist/integrations/asana.js +0 -78
  665. package/dist/integrations/asana.js.map +0 -1
  666. package/dist/integrations/figma-local.d.ts +0 -16
  667. package/dist/integrations/figma-local.js +0 -10
  668. package/dist/integrations/figma-local.js.map +0 -1
  669. package/dist/integrations/figma.d.ts +0 -17
  670. package/dist/integrations/figma.js +0 -17
  671. package/dist/integrations/figma.js.map +0 -1
  672. package/dist/integrations/granola.d.ts +0 -24
  673. package/dist/integrations/granola.js +0 -60
  674. package/dist/integrations/granola.js.map +0 -1
  675. package/dist/integrations/linear.d.ts +0 -14
  676. package/dist/integrations/linear.js +0 -80
  677. package/dist/integrations/linear.js.map +0 -1
  678. package/dist/integrations/paper-local.d.ts +0 -14
  679. package/dist/integrations/paper-local.js +0 -10
  680. package/dist/integrations/paper-local.js.map +0 -1
  681. package/dist/integrations/paper.d.ts +0 -2
  682. package/dist/integrations/paper.js +0 -10
  683. package/dist/integrations/paper.js.map +0 -1
  684. package/dist/integrations/pipedrive.d.ts +0 -26
  685. package/dist/integrations/pipedrive.js +0 -97
  686. package/dist/integrations/pipedrive.js.map +0 -1
  687. package/dist/integrations/registry.d.ts +0 -8
  688. package/dist/integrations/registry.js +0 -7
  689. package/dist/integrations/registry.js.map +0 -1
  690. package/dist/integrations/types.d.ts +0 -43
  691. package/dist/integrations/types.js +0 -5
  692. package/dist/integrations/types.js.map +0 -1
  693. package/dist/lib/lib/utils.d.ts +0 -2
  694. package/dist/lib/lib/utils.js +0 -6
  695. package/dist/lib/lib/utils.js.map +0 -1
  696. package/dist/mcp/connectors/asana.d.ts +0 -2
  697. package/dist/mcp/connectors/asana.js +0 -20
  698. package/dist/mcp/connectors/asana.js.map +0 -1
  699. package/dist/mcp/connectors/definitions.d.ts +0 -45
  700. package/dist/mcp/connectors/definitions.js +0 -32
  701. package/dist/mcp/connectors/definitions.js.map +0 -1
  702. package/dist/mcp/connectors/figma.d.ts +0 -5
  703. package/dist/mcp/connectors/figma.js +0 -21
  704. package/dist/mcp/connectors/figma.js.map +0 -1
  705. package/dist/mcp/connectors/gdrive.d.ts +0 -2
  706. package/dist/mcp/connectors/gdrive.js +0 -20
  707. package/dist/mcp/connectors/gdrive.js.map +0 -1
  708. package/dist/mcp/connectors/granola.d.ts +0 -2
  709. package/dist/mcp/connectors/granola.js +0 -12
  710. package/dist/mcp/connectors/granola.js.map +0 -1
  711. package/dist/mcp/connectors/linear.d.ts +0 -2
  712. package/dist/mcp/connectors/linear.js +0 -19
  713. package/dist/mcp/connectors/linear.js.map +0 -1
  714. package/dist/mcp/connectors/obsidian.d.ts +0 -2
  715. package/dist/mcp/connectors/obsidian.js +0 -19
  716. package/dist/mcp/connectors/obsidian.js.map +0 -1
  717. package/dist/mcp/connectors/pipedrive.d.ts +0 -2
  718. package/dist/mcp/connectors/pipedrive.js +0 -20
  719. package/dist/mcp/connectors/pipedrive.js.map +0 -1
  720. package/dist/mcp/connectors/slack.d.ts +0 -2
  721. package/dist/mcp/connectors/slack.js +0 -21
  722. package/dist/mcp/connectors/slack.js.map +0 -1
  723. package/dist/mcp/server-oauth-provider.d.ts +0 -56
  724. package/dist/mcp/server-oauth-provider.js +0 -142
  725. package/dist/mcp/server-oauth-provider.js.map +0 -1
  726. package/dist/server/agents/agent-loader.d.ts +0 -16
  727. package/dist/server/agents/agent-loader.js +0 -175
  728. package/dist/server/agents/agent-loader.js.map +0 -1
  729. package/dist/server/agents/agent-runner.d.ts +0 -33
  730. package/dist/server/agents/agent-runner.js +0 -187
  731. package/dist/server/agents/agent-runner.js.map +0 -1
  732. package/dist/server/agents/agent-runtime.d.ts +0 -39
  733. package/dist/server/agents/agent-runtime.js +0 -214
  734. package/dist/server/agents/agent-runtime.js.map +0 -1
  735. package/dist/server/agents/base-agent.d.ts +0 -30
  736. package/dist/server/agents/base-agent.js +0 -88
  737. package/dist/server/agents/base-agent.js.map +0 -1
  738. package/dist/server/agents/executive-digest.d.ts +0 -16
  739. package/dist/server/agents/executive-digest.js +0 -115
  740. package/dist/server/agents/executive-digest.js.map +0 -1
  741. package/dist/server/agents/graph-steward.d.ts +0 -16
  742. package/dist/server/agents/graph-steward.js +0 -59
  743. package/dist/server/agents/graph-steward.js.map +0 -1
  744. package/dist/server/agents/meeting-followup.d.ts +0 -16
  745. package/dist/server/agents/meeting-followup.js +0 -88
  746. package/dist/server/agents/meeting-followup.js.map +0 -1
  747. package/dist/server/agents/pipeline-monitor.d.ts +0 -15
  748. package/dist/server/agents/pipeline-monitor.js +0 -86
  749. package/dist/server/agents/pipeline-monitor.js.map +0 -1
  750. package/dist/server/agents/types.d.ts +0 -81
  751. package/dist/server/agents/types.js +0 -41
  752. package/dist/server/agents/types.js.map +0 -1
  753. package/dist/server/chrome/chrome.css +0 -691
  754. package/dist/server/chrome/chrome.js +0 -374
  755. package/dist/server/collab-authority.d.ts +0 -70
  756. package/dist/server/collab-authority.js +0 -218
  757. package/dist/server/collab-authority.js.map +0 -1
  758. package/dist/server/collab.d.ts +0 -29
  759. package/dist/server/collab.js +0 -195
  760. package/dist/server/collab.js.map +0 -1
  761. package/dist/server/commit-scheduler.d.ts +0 -39
  762. package/dist/server/commit-scheduler.js +0 -113
  763. package/dist/server/commit-scheduler.js.map +0 -1
  764. package/dist/server/plugin-loader.d.ts +0 -53
  765. package/dist/server/plugin-loader.js +0 -155
  766. package/dist/server/plugin-loader.js.map +0 -1
  767. package/dist/server/routes/agents-api.d.ts +0 -10
  768. package/dist/server/routes/agents-api.js +0 -25
  769. package/dist/server/routes/agents-api.js.map +0 -1
  770. package/dist/server/routes/collab.d.ts +0 -6
  771. package/dist/server/routes/collab.js +0 -10
  772. package/dist/server/routes/collab.js.map +0 -1
  773. package/dist/server/routes/git-api.d.ts +0 -9
  774. package/dist/server/routes/git-api.js +0 -82
  775. package/dist/server/routes/git-api.js.map +0 -1
  776. package/dist/server/routes/meeting-ingest-api.d.ts +0 -14
  777. package/dist/server/routes/meeting-ingest-api.js +0 -98
  778. package/dist/server/routes/meeting-ingest-api.js.map +0 -1
  779. package/dist/server/routes/sync-api.d.ts +0 -26
  780. package/dist/server/routes/sync-api.js +0 -848
  781. package/dist/server/routes/sync-api.js.map +0 -1
  782. package/dist/server/routes/webhook.d.ts +0 -14
  783. package/dist/server/routes/webhook.js +0 -102
  784. package/dist/server/routes/webhook.js.map +0 -1
  785. package/dist/services/batch-processor.d.ts +0 -49
  786. package/dist/services/batch-processor.js +0 -166
  787. package/dist/services/batch-processor.js.map +0 -1
  788. package/dist/services/csv-service.d.ts +0 -36
  789. package/dist/services/csv-service.js +0 -143
  790. package/dist/services/csv-service.js.map +0 -1
  791. package/dist/services/github-provisioner.d.ts +0 -36
  792. package/dist/services/github-provisioner.js +0 -126
  793. package/dist/services/github-provisioner.js.map +0 -1
  794. package/dist/services/github-service.d.ts +0 -99
  795. package/dist/services/github-service.js +0 -310
  796. package/dist/services/github-service.js.map +0 -1
  797. package/dist/services/image-import-service.d.ts +0 -24
  798. package/dist/services/image-import-service.js +0 -108
  799. package/dist/services/image-import-service.js.map +0 -1
  800. package/dist/services/insights.d.ts +0 -38
  801. package/dist/services/insights.js +0 -269
  802. package/dist/services/insights.js.map +0 -1
  803. package/dist/services/meeting-processor.d.ts +0 -91
  804. package/dist/services/meeting-processor.js +0 -331
  805. package/dist/services/meeting-processor.js.map +0 -1
  806. package/dist/services/sync/collection-sync.d.ts +0 -60
  807. package/dist/services/sync/collection-sync.js +0 -509
  808. package/dist/services/sync/collection-sync.js.map +0 -1
  809. package/dist/services/sync/commit.d.ts +0 -60
  810. package/dist/services/sync/commit.js +0 -354
  811. package/dist/services/sync/commit.js.map +0 -1
  812. package/dist/services/sync/context-index.d.ts +0 -69
  813. package/dist/services/sync/context-index.js +0 -280
  814. package/dist/services/sync/context-index.js.map +0 -1
  815. package/dist/services/sync/data-fetcher.d.ts +0 -31
  816. package/dist/services/sync/data-fetcher.js +0 -12
  817. package/dist/services/sync/data-fetcher.js.map +0 -1
  818. package/dist/services/sync/derive.d.ts +0 -34
  819. package/dist/services/sync/derive.js +0 -164
  820. package/dist/services/sync/derive.js.map +0 -1
  821. package/dist/services/sync/enrichment-state.d.ts +0 -31
  822. package/dist/services/sync/enrichment-state.js +0 -63
  823. package/dist/services/sync/enrichment-state.js.map +0 -1
  824. package/dist/services/sync/enrichment.d.ts +0 -25
  825. package/dist/services/sync/enrichment.js +0 -121
  826. package/dist/services/sync/enrichment.js.map +0 -1
  827. package/dist/services/sync/entity-refresh.d.ts +0 -30
  828. package/dist/services/sync/entity-refresh.js +0 -275
  829. package/dist/services/sync/entity-refresh.js.map +0 -1
  830. package/dist/services/sync/frontmatter-extractor.d.ts +0 -40
  831. package/dist/services/sync/frontmatter-extractor.js +0 -279
  832. package/dist/services/sync/frontmatter-extractor.js.map +0 -1
  833. package/dist/services/sync/graph-match-state.d.ts +0 -33
  834. package/dist/services/sync/graph-match-state.js +0 -61
  835. package/dist/services/sync/graph-match-state.js.map +0 -1
  836. package/dist/services/sync/graph-match.d.ts +0 -53
  837. package/dist/services/sync/graph-match.js +0 -316
  838. package/dist/services/sync/graph-match.js.map +0 -1
  839. package/dist/services/sync/graphrag-client.d.ts +0 -43
  840. package/dist/services/sync/graphrag-client.js +0 -94
  841. package/dist/services/sync/graphrag-client.js.map +0 -1
  842. package/dist/services/sync/graphrag-config.d.ts +0 -16
  843. package/dist/services/sync/graphrag-config.js +0 -39
  844. package/dist/services/sync/graphrag-config.js.map +0 -1
  845. package/dist/services/sync/graphrag-context.d.ts +0 -14
  846. package/dist/services/sync/graphrag-context.js +0 -109
  847. package/dist/services/sync/graphrag-context.js.map +0 -1
  848. package/dist/services/sync/graphrag-indexer.d.ts +0 -30
  849. package/dist/services/sync/graphrag-indexer.js +0 -358
  850. package/dist/services/sync/graphrag-indexer.js.map +0 -1
  851. package/dist/services/sync/llm.d.ts +0 -32
  852. package/dist/services/sync/llm.js +0 -115
  853. package/dist/services/sync/llm.js.map +0 -1
  854. package/dist/services/sync/mcp-client.d.ts +0 -71
  855. package/dist/services/sync/mcp-client.js +0 -299
  856. package/dist/services/sync/mcp-client.js.map +0 -1
  857. package/dist/services/sync/model-factory.d.ts +0 -13
  858. package/dist/services/sync/model-factory.js +0 -38
  859. package/dist/services/sync/model-factory.js.map +0 -1
  860. package/dist/services/sync/name-quality.d.ts +0 -31
  861. package/dist/services/sync/name-quality.js +0 -60
  862. package/dist/services/sync/name-quality.js.map +0 -1
  863. package/dist/services/sync/output-schemas.d.ts +0 -92
  864. package/dist/services/sync/output-schemas.js +0 -43
  865. package/dist/services/sync/output-schemas.js.map +0 -1
  866. package/dist/services/sync/prompts.d.ts +0 -19
  867. package/dist/services/sync/prompts.js +0 -128
  868. package/dist/services/sync/prompts.js.map +0 -1
  869. package/dist/services/sync/reconciler.d.ts +0 -48
  870. package/dist/services/sync/reconciler.js +0 -294
  871. package/dist/services/sync/reconciler.js.map +0 -1
  872. package/dist/services/sync/rest-client.d.ts +0 -40
  873. package/dist/services/sync/rest-client.js +0 -100
  874. package/dist/services/sync/rest-client.js.map +0 -1
  875. package/dist/services/sync/source-config.d.ts +0 -67
  876. package/dist/services/sync/source-config.js +0 -304
  877. package/dist/services/sync/source-config.js.map +0 -1
  878. package/dist/services/sync/source-definitions/asana.d.ts +0 -14
  879. package/dist/services/sync/source-definitions/asana.js +0 -42
  880. package/dist/services/sync/source-definitions/asana.js.map +0 -1
  881. package/dist/services/sync/source-definitions/definitions.d.ts +0 -8
  882. package/dist/services/sync/source-definitions/definitions.js +0 -8
  883. package/dist/services/sync/source-definitions/definitions.js.map +0 -1
  884. package/dist/services/sync/source-definitions/gdrive.d.ts +0 -16
  885. package/dist/services/sync/source-definitions/gdrive.js +0 -68
  886. package/dist/services/sync/source-definitions/gdrive.js.map +0 -1
  887. package/dist/services/sync/source-definitions/granola.d.ts +0 -2
  888. package/dist/services/sync/source-definitions/granola.js +0 -21
  889. package/dist/services/sync/source-definitions/granola.js.map +0 -1
  890. package/dist/services/sync/source-definitions/linear.d.ts +0 -2
  891. package/dist/services/sync/source-definitions/linear.js +0 -62
  892. package/dist/services/sync/source-definitions/linear.js.map +0 -1
  893. package/dist/services/sync/source-definitions/obsidian.d.ts +0 -2
  894. package/dist/services/sync/source-definitions/obsidian.js +0 -55
  895. package/dist/services/sync/source-definitions/obsidian.js.map +0 -1
  896. package/dist/services/sync/source-definitions/pipedrive.d.ts +0 -2
  897. package/dist/services/sync/source-definitions/pipedrive.js +0 -43
  898. package/dist/services/sync/source-definitions/pipedrive.js.map +0 -1
  899. package/dist/services/sync/staging.d.ts +0 -53
  900. package/dist/services/sync/staging.js +0 -130
  901. package/dist/services/sync/staging.js.map +0 -1
  902. package/dist/services/sync/structured-extractor.d.ts +0 -57
  903. package/dist/services/sync/structured-extractor.js +0 -584
  904. package/dist/services/sync/structured-extractor.js.map +0 -1
  905. package/dist/services/sync/sync-runner.d.ts +0 -32
  906. package/dist/services/sync/sync-runner.js +0 -195
  907. package/dist/services/sync/sync-runner.js.map +0 -1
  908. package/dist/services/sync/sync-state.d.ts +0 -43
  909. package/dist/services/sync/sync-state.js +0 -154
  910. package/dist/services/sync/sync-state.js.map +0 -1
  911. package/dist/services/sync/types.d.ts +0 -381
  912. package/dist/services/sync/types.js +0 -8
  913. package/dist/services/sync/types.js.map +0 -1
  914. package/dist/services/sync/unstructured-extractor.d.ts +0 -27
  915. package/dist/services/sync/unstructured-extractor.js +0 -185
  916. package/dist/services/sync/unstructured-extractor.js.map +0 -1
  917. package/dist/utils/merge-resolver.d.ts +0 -59
  918. package/dist/utils/merge-resolver.js +0 -303
  919. package/dist/utils/merge-resolver.js.map +0 -1
  920. package/dist/utils/workspace-config.d.ts +0 -8
  921. package/dist/utils/workspace-config.js +0 -22
  922. package/dist/utils/workspace-config.js.map +0 -1
  923. package/dist/web/_app/immutable/assets/0.QUqBcyuu.css +0 -1
  924. package/dist/web/_app/immutable/assets/11.2jzI3cZY.css +0 -1
  925. package/dist/web/_app/immutable/assets/12.CT4xL4K3.css +0 -1
  926. package/dist/web/_app/immutable/assets/13.BUrHkYry.css +0 -1
  927. package/dist/web/_app/immutable/assets/2.5jNm7Pm1.css +0 -1
  928. package/dist/web/_app/immutable/assets/3.BxdqT7zi.css +0 -1
  929. package/dist/web/_app/immutable/assets/4.BjPwtpNd.css +0 -1
  930. package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
  931. package/dist/web/_app/immutable/assets/6.DXZr_rI_.css +0 -1
  932. package/dist/web/_app/immutable/assets/GraphView.D9ePpZez.css +0 -1
  933. package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
  934. package/dist/web/_app/immutable/assets/ViewToolbar.CZjsdjy4.css +0 -1
  935. package/dist/web/_app/immutable/assets/WorkspaceView.B-1DbivC.css +0 -1
  936. package/dist/web/_app/immutable/assets/wikilinks.CtSydmQl.css +0 -1
  937. package/dist/web/_app/immutable/chunks/3--t-YNA.js +0 -1
  938. package/dist/web/_app/immutable/chunks/5OU-4caN.js +0 -1
  939. package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
  940. package/dist/web/_app/immutable/chunks/B6FUcAv5.js +0 -1
  941. package/dist/web/_app/immutable/chunks/B9gDgSlp.js +0 -1
  942. package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
  943. package/dist/web/_app/immutable/chunks/BFtIWl5z.js +0 -1
  944. package/dist/web/_app/immutable/chunks/BHKpz6_7.js +0 -1
  945. package/dist/web/_app/immutable/chunks/BNfrhBeA.js +0 -1
  946. package/dist/web/_app/immutable/chunks/BgO5HlCg.js +0 -2
  947. package/dist/web/_app/immutable/chunks/BqnODQDb.js +0 -1
  948. package/dist/web/_app/immutable/chunks/BrebtJNG.js +0 -18
  949. package/dist/web/_app/immutable/chunks/BvIFhEn7.js +0 -2
  950. package/dist/web/_app/immutable/chunks/BvfdTHv8.js +0 -1
  951. package/dist/web/_app/immutable/chunks/BxGm65PH.js +0 -1
  952. package/dist/web/_app/immutable/chunks/BxyxnEKw.js +0 -1
  953. package/dist/web/_app/immutable/chunks/BygFIGq4.js +0 -1
  954. package/dist/web/_app/immutable/chunks/Bz0ZjVQE.js +0 -2
  955. package/dist/web/_app/immutable/chunks/C0LVZhvn.js +0 -1
  956. package/dist/web/_app/immutable/chunks/CIb_hHMy.js +0 -1
  957. package/dist/web/_app/immutable/chunks/CNKK6nZb.js +0 -1
  958. package/dist/web/_app/immutable/chunks/CQ5FjHZK.js +0 -1
  959. package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
  960. package/dist/web/_app/immutable/chunks/CX_61fY8.js +0 -5
  961. package/dist/web/_app/immutable/chunks/CYrVHOHA.js +0 -1
  962. package/dist/web/_app/immutable/chunks/CaEaeeKb.js +0 -1
  963. package/dist/web/_app/immutable/chunks/Ch6e_wpP.js +0 -1
  964. package/dist/web/_app/immutable/chunks/Ci4zzCVB.js +0 -2
  965. package/dist/web/_app/immutable/chunks/CknqBVQE.js +0 -1
  966. package/dist/web/_app/immutable/chunks/Cmfiirqp.js +0 -4
  967. package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
  968. package/dist/web/_app/immutable/chunks/CrFpCC6p.js +0 -1
  969. package/dist/web/_app/immutable/chunks/CxX8hcT6.js +0 -1
  970. package/dist/web/_app/immutable/chunks/D0T1ps1G.js +0 -1
  971. package/dist/web/_app/immutable/chunks/D2ZEj9xD.js +0 -1
  972. package/dist/web/_app/immutable/chunks/D3sy0IkA.js +0 -2
  973. package/dist/web/_app/immutable/chunks/DFYOFE3o.js +0 -1
  974. package/dist/web/_app/immutable/chunks/DHWoAC4y.js +0 -1
  975. package/dist/web/_app/immutable/chunks/DYYBfXU3.js +0 -1
  976. package/dist/web/_app/immutable/chunks/DiNPRA8T.js +0 -1
  977. package/dist/web/_app/immutable/chunks/DkjsqHkM.js +0 -1
  978. package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
  979. package/dist/web/_app/immutable/chunks/DpMCynC3.js +0 -1
  980. package/dist/web/_app/immutable/chunks/DqrybUuA.js +0 -1
  981. package/dist/web/_app/immutable/chunks/DsnmJJEf.js +0 -1
  982. package/dist/web/_app/immutable/chunks/KyjzlWRN.js +0 -2
  983. package/dist/web/_app/immutable/chunks/O9MAeAgV.js +0 -5
  984. package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
  985. package/dist/web/_app/immutable/chunks/SKSQ4m85.js +0 -2
  986. package/dist/web/_app/immutable/chunks/WEBTyD-H.js +0 -1
  987. package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
  988. package/dist/web/_app/immutable/chunks/bBXT5iJP.js +0 -1
  989. package/dist/web/_app/immutable/chunks/vxEtkL8z.js +0 -1
  990. package/dist/web/_app/immutable/chunks/wDIGUaoU.js +0 -3
  991. package/dist/web/_app/immutable/chunks/xkNhbnff.js +0 -1
  992. package/dist/web/_app/immutable/chunks/zoVX1Zab.js +0 -1
  993. package/dist/web/_app/immutable/entry/app.GfE4z2GO.js +0 -2
  994. package/dist/web/_app/immutable/entry/start.H-LFJK9u.js +0 -1
  995. package/dist/web/_app/immutable/nodes/0.Bwi7tTNC.js +0 -2
  996. package/dist/web/_app/immutable/nodes/1.DgNJPEWk.js +0 -1
  997. package/dist/web/_app/immutable/nodes/10.BW_XCD2O.js +0 -1
  998. package/dist/web/_app/immutable/nodes/11.DM7RX3Ms.js +0 -1
  999. package/dist/web/_app/immutable/nodes/12.DKgssZo8.js +0 -1
  1000. package/dist/web/_app/immutable/nodes/13.DCdmTre-.js +0 -1
  1001. package/dist/web/_app/immutable/nodes/2.DOA5QBVG.js +0 -266
  1002. package/dist/web/_app/immutable/nodes/3.bpoHQwAI.js +0 -5
  1003. package/dist/web/_app/immutable/nodes/4.ye0Vy7A1.js +0 -11
  1004. package/dist/web/_app/immutable/nodes/5.rxpnYrx_.js +0 -4
  1005. package/dist/web/_app/immutable/nodes/6.DP8HSxtc.js +0 -1
  1006. package/dist/web/_app/immutable/nodes/7.C1h4Bf-E.js +0 -1
  1007. package/dist/web/_app/immutable/nodes/8.BzmQ7S7Y.js +0 -1
  1008. package/dist/web/_app/immutable/nodes/9.CEakpXpF.js +0 -1
@@ -7,11 +7,13 @@
7
7
  * - Manage wikilinks
8
8
  * - Upload assets
9
9
  */
10
- import { Type as T } from '@sinclair/typebox';
10
+ import { Type as T } from 'typebox';
11
11
  import { ENTITY_SCHEMAS } from '../../core/validation.js';
12
12
  import { lintWorkspace } from '../../services/lint-service.js';
13
13
  import { findOrphans } from '../../services/orphan-service.js';
14
- import { isAdminOrOwner } from '../../services/auth-service.js';
14
+ import * as access from '../../services/access-control.js';
15
+ import { isCuratedEntityType } from '../../core/entity-types-catalog.js';
16
+ import { getAgentAllowedEntityTypes } from '../prompts/entity-types-section.js';
15
17
  /**
16
18
  * Helper to wrap tool results in AgentToolResult format
17
19
  */
@@ -31,139 +33,229 @@ function cleanData(data) {
31
33
  return rest;
32
34
  }
33
35
  /**
34
- * Per-request user context for collection access filtering.
35
- * When getCurrentUser returns a non-admin user, tools filter results
36
- * to only collections the user has been granted access to.
36
+ * Undo JSON-string escapes that sometimes leak into content when the LLM
37
+ * serializes markdown as a quoted string instead of raw text. Handles `\n`,
38
+ * `\t`, `\r`, `\"`, `\\` in a single pass so escape sequences aren't
39
+ * re-processed. Also strips stray surrounding quotes from a fully-quoted
40
+ * payload.
37
41
  */
38
- /** Check if a user can see a private repo (only the owner can). */
39
- function canSeePrivateRepo(repoConfig, user) {
40
- if (!repoConfig?.private)
41
- return true;
42
- if (!user)
43
- return !repoConfig.owner_id; // API key / open mode — only if no owner set
44
- if (!repoConfig.owner_id)
45
- return false; // Private without owner — hidden from all users
46
- return user.id === repoConfig.owner_id;
47
- }
48
- /** Check if the current user is an admin. Returns an error result if not. */
49
- function adminOnly(getUser) {
50
- const user = getUser();
51
- if (!user)
52
- return null; // API key / open mode → allow
53
- if (isAdminOrOwner(user.role))
54
- return null;
55
- return 'This operation requires admin access.';
42
+ function sanitizeLlmContent(content) {
43
+ if (!content)
44
+ return '';
45
+ const unescaped = content.replace(/\\([ntr"\\])/g, (_, c) => {
46
+ if (c === 'n')
47
+ return '\n';
48
+ if (c === 't')
49
+ return '\t';
50
+ if (c === 'r')
51
+ return '\r';
52
+ return c;
53
+ });
54
+ return unescaped.replace(/^"+|"+$/g, '');
56
55
  }
56
+ /**
57
+ * Per-request user context for folder access filtering.
58
+ * When getCurrentUser returns a user, tools filter results to only
59
+ * folders the user is a member of (via folder_access).
60
+ */
57
61
  function getAccessibleRepoNames(workspaceManager, getCurrentUser, authService) {
58
62
  const user = getCurrentUser();
59
63
  if (!user)
60
64
  return null; // API key / open mode → no filtering
61
65
  if (!authService)
62
66
  return null;
63
- const allRepos = workspaceManager.getAllRepoConfigs();
64
- if (isAdminOrOwner(user.role)) {
65
- // Admins/owners see all non-private + their own private repos
66
- const hidden = allRepos.filter(r => !canSeePrivateRepo(r, user)).map(r => r.name);
67
- if (hidden.length === 0)
68
- return null; // No filtering needed
69
- const visible = new Set(allRepos.filter(r => canSeePrivateRepo(r, user)).map(r => r.name));
70
- return visible;
71
- }
72
- const allowed = authService.getUserCollections(user.id);
73
- const visible = allRepos.filter(r => canSeePrivateRepo(r, user) && (r.private && r.owner_id === user.id || allowed.includes(r.name)));
74
- return new Set(visible.map(r => r.name));
67
+ // Delegate to the shared helper so personal-folder restrictions and
68
+ // owner-on-shared-folder semantics apply consistently with the HTTP layer.
69
+ return new Set(access.getAccessibleRepos(user, workspaceManager, authService).map(r => r.name));
75
70
  }
76
71
  function canAccessRepo(repoName, workspaceManager, getCurrentUser, authService) {
77
72
  const user = getCurrentUser();
78
- const repoConfig = workspaceManager.getRepoConfig(repoName);
79
- if (!canSeePrivateRepo(repoConfig, user))
80
- return false;
81
73
  if (!user)
82
74
  return true;
83
- if (repoConfig?.private && repoConfig?.owner_id === user.id)
84
- return true;
85
- if (isAdminOrOwner(user.role))
86
- return true;
87
75
  if (!authService)
88
76
  return true;
89
- return authService.getUserCollections(user.id).includes(repoName);
77
+ return access.hasRepoAccess(user, repoName, workspaceManager, authService);
90
78
  }
91
- export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation, getCurrentUser, authService) {
79
+ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation, getCurrentUser, authService,
80
+ /**
81
+ * Called after an entity's content is written to disk (create/update), so
82
+ * callers can push the new content into any active Y.Doc. Without this,
83
+ * agent edits bypass live editors and cause CRDT duplication on resync.
84
+ */
85
+ onContentSync,
86
+ /**
87
+ * Called at the start (`enter`) and end (`leave`) of any mutation tool
88
+ * call. Surfaces the active-agent chip in the sidebar via the WS hub. The
89
+ * orchestrator wires this through to wsHub.handleAgentActivity.
90
+ */
91
+ onAgentActivity) {
92
92
  const getUser = getCurrentUser ?? (() => null);
93
93
  const authSvc = authService ?? null;
94
- /** Resolve "private" or "entries" to the current user's actual private collection name. */
94
+ /**
95
+ * Resolve the identity to stamp on writes. If the tool call is running on
96
+ * behalf of a real user (chat / quick-capture from the web), credit them
97
+ * by their handle — a stable email-free slug. The fake-domain email keeps
98
+ * git commit metadata well-formed without putting real addresses into
99
+ * workspace history. Fall back to the orchestrator-level gitUser for
100
+ * unauthenticated contexts (CLI, tests, server-only automations).
101
+ */
102
+ function effectiveGitUser() {
103
+ const user = getUser();
104
+ if (user?.handle) {
105
+ return {
106
+ id: user.handle,
107
+ name: user.displayName ?? user.handle,
108
+ email: `${user.handle}@studiograph.local`,
109
+ };
110
+ }
111
+ return gitUser;
112
+ }
113
+ /** Resolve "private" or "entries" to the current user's actual private folder name. */
95
114
  function resolvePrivateRepo(repoName) {
96
115
  if (repoName !== 'private' && repoName !== 'entries')
97
116
  return repoName;
98
117
  const user = getUser();
99
118
  if (!user)
100
119
  return repoName;
101
- const privateRepo = workspaceManager.getUserPrivateRepo(user.id);
102
- return privateRepo?.name ?? repoName;
120
+ const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
121
+ return personalRepo?.name ?? repoName;
122
+ }
123
+ /**
124
+ * Eager skills are inlined into every system prompt for everyone with folder
125
+ * access. Creating one in a shared folder requires admin/owner so a rogue
126
+ * member can't bloat everyone's context. Eager skills in the user's own
127
+ * private folder are fine — they only bloat that user's own prompt.
128
+ * Returns an error string or null if the operation is allowed.
129
+ */
130
+ function checkEagerSkillPermission(entityType, data, repoName) {
131
+ if (entityType !== 'skill')
132
+ return null;
133
+ if (!data || data.loading !== 'eager')
134
+ return null;
135
+ const user = getUser();
136
+ if (!user)
137
+ return null; // non-authenticated contexts (CLI, tests) bypass
138
+ const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
139
+ if (personalRepo && personalRepo.name === repoName)
140
+ return null;
141
+ if (authSvc?.isFolderAdmin(user.id, repoName))
142
+ return null;
143
+ if (user.role === 'owner')
144
+ return null;
145
+ return `Creating an eager skill in a shared folder requires folder admin or workspace owner. Save this skill to your private folder (repo: "private") or set loading to "on-demand".`;
146
+ }
147
+ // Compute the set of entity types the agent is allowed to create in this
148
+ // workspace: the full canonical catalog plus any custom types defined via
149
+ // schema_extensions. The launch-time allowlist was removed — the catalog
150
+ // now grows with the user via the New Entry picker's progressive disclosure.
151
+ const builtinTypeKeys = new Set(Object.keys(ENTITY_SCHEMAS));
152
+ const customWorkspaceTypes = workspaceManager.getSchemaRegistry().getAllTypes()
153
+ .filter(t => !builtinTypeKeys.has(t));
154
+ const agentAllowedTypes = getAgentAllowedEntityTypes(customWorkspaceTypes);
155
+ const agentAllowedTypeSet = new Set(agentAllowedTypes);
156
+ function rejectDisallowedCreateType(entityType) {
157
+ if (agentAllowedTypeSet.has(entityType))
158
+ return null;
159
+ if (entityType === 'asset') {
160
+ // The schema enum already excludes `asset` (see
161
+ // getAgentAllowedEntityTypes). This is the runtime defense-in-depth
162
+ // path for clients that bypass the enum.
163
+ return wrapToolResult({
164
+ success: false,
165
+ error: 'Asset entries cannot be created via create_entity — they require a binary blob plus a sidecar text file. Use the import_file tool with a local file path, or have the user upload via the workspace import dialog.',
166
+ });
167
+ }
168
+ const hint = isCuratedEntityType(entityType)
169
+ ? '' // shouldn't happen for any other curated type — they're all allowed
170
+ : ` Allowed types: ${agentAllowedTypes.join(', ')}.`;
171
+ return wrapToolResult({
172
+ success: false,
173
+ error: `Entry type "${entityType}" is not a known canonical or workspace custom type.${hint}`,
174
+ });
103
175
  }
104
176
  return [
105
177
  // Create entity
106
178
  {
107
179
  name: 'create_entity',
108
180
  label: 'Create Entry',
109
- description: 'Create a new entry in a collection. Always validate required fields before calling. Collection is auto-resolved for app-defined entry types.',
181
+ description: 'Create a new entry in a folder. Always validate required fields before calling. Folder is auto-resolved for app-defined entry types.',
110
182
  parameters: T.Object({
111
- repo: T.Optional(T.String({ description: 'Collection name (auto-resolved for app entity types)' })),
112
- entityType: T.String({ description: 'Entity type (project, client, decision, etc.)' }),
183
+ repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
184
+ entityType: T.Union(agentAllowedTypes.map(t => T.Literal(t)), { description: `Entity type. Must be one of: ${agentAllowedTypes.join(', ')}.` }),
113
185
  entityId: T.String({ description: 'Unique entity ID in kebab-case' }),
114
186
  data: T.Object({}, { description: 'Entity data (YAML frontmatter)', additionalProperties: true }),
115
187
  content: T.Optional(T.String({ description: 'Markdown content (optional)' })),
188
+ folder_path: T.Optional(T.String({ description: 'Repo-relative subfolder for the entry (e.g. "clients/acme"). Omit to land at repo root. Parent folders are auto-created.' })),
116
189
  commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
117
190
  }),
118
191
  execute: async (toolCallId, params) => {
119
192
  try {
193
+ // Defense in depth: LLMs occasionally pass strings that don't match the
194
+ // enum schema. Runtime check ensures the launch allowlist is enforced
195
+ // even if the schema layer is bypassed.
196
+ const typeRejection = rejectDisallowedCreateType(params.entityType);
197
+ if (typeRejection)
198
+ return typeRejection;
120
199
  let repoName = params.repo;
121
200
  if (!repoName) {
122
- repoName = workspaceManager.getAppForEntityType(params.entityType);
123
- if (!repoName)
124
- return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
201
+ return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
125
202
  }
126
203
  repoName = resolvePrivateRepo(repoName);
127
204
  if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
128
- return wrapToolResult({ success: false, error: `Collection "${repoName}" not found` });
205
+ return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
129
206
  }
207
+ const eagerError = checkEagerSkillPermission(params.entityType, params.data, repoName);
208
+ if (eagerError)
209
+ return wrapToolResult({ success: false, error: eagerError });
130
210
  const graph = workspaceManager.getGraph(repoName);
131
211
  // Workspace-level dedup: warn if an entity with this ID already exists elsewhere
132
212
  const existing = workspaceManager.findEntityById(params.entityId);
133
213
  if (existing && existing.repoName !== repoName) {
134
- return wrapToolResult({ success: false, error: `An entity with ID "${params.entityId}" already exists in the "${existing.repoName}" collection (type: ${existing.data?.entity_type}). Use a unique ID or link to the existing entity with [[${params.entityId}]].` });
214
+ return wrapToolResult({ success: false, error: `An entity with ID "${params.entityId}" already exists in the "${existing.repoName}" folder (type: ${existing.data?.entity_type}). Use a unique ID or link to the existing entity with [[${params.entityId}]].` });
135
215
  }
136
216
  // Add timestamps and user info
217
+ const actor = effectiveGitUser();
137
218
  const now = new Date().toISOString();
138
219
  const dataWithMeta = {
139
220
  ...params.data,
140
221
  entity_id: params.entityId,
141
222
  created_at: now,
142
223
  updated_at: now,
143
- created_by: gitUser.id,
144
- updated_by: gitUser.id,
224
+ created_by: actor.id,
225
+ updated_by: actor.id,
145
226
  };
146
- // Sanitize LLM JSON output: double-escaped newlines and stray quotes
147
- let sanitizedContent = (params.content || '').replace(/\\n/g, '\n').replace(/^"+|"+$/g, '');
148
- const entity = await graph.create({
149
- entityType: params.entityType,
150
- entityId: params.entityId,
151
- data: dataWithMeta,
152
- content: sanitizedContent,
153
- commitMessage: params.commitMessage,
154
- });
155
- onMutation?.({ action: 'created', repo: repoName, entityType: params.entityType, entityId: params.entityId });
156
- return wrapToolResult({
157
- success: true,
158
- entity: {
159
- entityId: entity.id,
160
- entityType: entity.entityType,
161
- repo: repoName,
162
- path: entity.path,
163
- data: cleanData(entity.data),
164
- },
165
- message: `Created ${params.entityType}: ${params.entityId} in ${repoName}. Auto-committed — ready to push.`,
166
- });
227
+ const sanitizedContent = sanitizeLlmContent(params.content);
228
+ // Surface a live "<user>'s agent is acting" chip in the sidebar for
229
+ // the duration of the mutation. `leave` is always emitted via the
230
+ // inner finally so a thrown error doesn't leave the chip stuck.
231
+ onAgentActivity?.('enter', repoName);
232
+ try {
233
+ const entity = await graph.create({
234
+ entityType: params.entityType,
235
+ entityId: params.entityId,
236
+ data: dataWithMeta,
237
+ content: sanitizedContent,
238
+ commitMessage: params.commitMessage,
239
+ user: actor,
240
+ folderPath: params.folder_path,
241
+ });
242
+ onContentSync?.(repoName, params.entityType, params.entityId);
243
+ onMutation?.({ action: 'created', repo: repoName, entityType: params.entityType, entityId: params.entityId });
244
+ return wrapToolResult({
245
+ success: true,
246
+ entity: {
247
+ entityId: entity.id,
248
+ entityType: entity.entityType,
249
+ repo: repoName,
250
+ path: entity.path,
251
+ data: cleanData(entity.data),
252
+ },
253
+ message: `Created ${params.entityType}: ${params.entityId} in ${repoName}. Auto-committed — ready to push.`,
254
+ });
255
+ }
256
+ finally {
257
+ onAgentActivity?.('leave', repoName);
258
+ }
167
259
  }
168
260
  catch (error) {
169
261
  return wrapToolResult({
@@ -179,7 +271,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
179
271
  label: 'Get Entry',
180
272
  description: 'Retrieve full entry details. Use repo, entityType, entityId from search/list results. entityType is optional — if omitted it is read from the file.',
181
273
  parameters: T.Object({
182
- repo: T.String({ description: 'Collection name' }),
274
+ repo: T.String({ description: 'Folder name' }),
183
275
  entityType: T.Optional(T.String({ description: 'Entity type (optional — resolved from frontmatter if omitted)' })),
184
276
  entityId: T.String({ description: 'Entity ID' }),
185
277
  }),
@@ -187,12 +279,25 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
187
279
  try {
188
280
  const repo = resolvePrivateRepo(params.repo);
189
281
  if (!canAccessRepo(repo, workspaceManager, getUser, authSvc)) {
190
- return wrapToolResult({ success: false, error: `Collection "${repo}" not found` });
282
+ return wrapToolResult({ success: false, error: `Folder "${repo}" not found` });
191
283
  }
192
284
  const graph = workspaceManager.getGraph(repo);
193
- const entity = params.entityType
194
- ? graph.get(params.entityType, params.entityId)
195
- : graph.getById(params.entityId);
285
+ // If the agent passes the wrong entityType (e.g. based on stale
286
+ // search results), graph.get computes the wrong filesystem path
287
+ // and throws. Fall back to getById, which scans all type subdirs
288
+ // under the folder and resolves the actual location.
289
+ let entity;
290
+ if (params.entityType) {
291
+ try {
292
+ entity = graph.get(params.entityType, params.entityId);
293
+ }
294
+ catch {
295
+ entity = graph.getById(params.entityId);
296
+ }
297
+ }
298
+ else {
299
+ entity = graph.getById(params.entityId);
300
+ }
196
301
  return wrapToolResult({
197
302
  success: true,
198
303
  entity: {
@@ -218,9 +323,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
218
323
  {
219
324
  name: 'update_entity',
220
325
  label: 'Update Entry',
221
- description: 'Update an existing entry. Collection is auto-resolved for app-defined types.',
326
+ description: 'Update an existing entry. Folder is auto-resolved for app-defined types.',
222
327
  parameters: T.Object({
223
- repo: T.Optional(T.String({ description: 'Collection name (auto-resolved for app entity types)' })),
328
+ repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
224
329
  entityType: T.String({ description: 'Entity type' }),
225
330
  entityId: T.String({ description: 'Entity ID' }),
226
331
  data: T.Optional(T.Object({}, { description: 'Updated data fields', additionalProperties: true })),
@@ -231,44 +336,58 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
231
336
  try {
232
337
  let repoName = params.repo;
233
338
  if (!repoName) {
234
- repoName = workspaceManager.getAppForEntityType(params.entityType);
235
- if (!repoName)
236
- return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
339
+ return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
237
340
  }
238
341
  repoName = resolvePrivateRepo(repoName);
239
342
  if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
240
- return wrapToolResult({ success: false, error: `Collection "${repoName}" not found` });
343
+ return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
241
344
  }
345
+ const eagerError = checkEagerSkillPermission(params.entityType, params.data, repoName);
346
+ if (eagerError)
347
+ return wrapToolResult({ success: false, error: eagerError });
242
348
  const graph = workspaceManager.getGraph(repoName);
243
349
  // Add update metadata
350
+ const actor = effectiveGitUser();
244
351
  const dataWithMeta = params.data
245
352
  ? {
246
353
  ...params.data,
247
354
  updated_at: new Date().toISOString(),
248
- updated_by: gitUser.id,
355
+ updated_by: actor.id,
249
356
  }
250
357
  : undefined;
251
- // Sanitize LLM JSON output: double-escaped newlines and stray quotes
252
358
  const sanitizedContent = params.content !== undefined
253
- ? params.content.replace(/\\n/g, '\n').replace(/^"+|"+$/g, '') : params.content;
254
- const entity = await graph.update({
255
- entityType: params.entityType,
256
- entityId: params.entityId,
257
- data: dataWithMeta,
258
- content: sanitizedContent,
259
- commitMessage: params.commitMessage,
260
- });
261
- onMutation?.({ action: 'updated', repo: repoName, entityType: params.entityType, entityId: params.entityId });
262
- return wrapToolResult({
263
- success: true,
264
- entity: {
265
- entityId: entity.id,
266
- entityType: entity.entityType,
267
- repo: repoName,
268
- data: cleanData(entity.data),
269
- },
270
- message: `Updated ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
271
- });
359
+ ? sanitizeLlmContent(params.content)
360
+ : params.content;
361
+ onAgentActivity?.('enter', repoName);
362
+ try {
363
+ const entity = await graph.update({
364
+ entityType: params.entityType,
365
+ entityId: params.entityId,
366
+ data: dataWithMeta,
367
+ content: sanitizedContent,
368
+ commitMessage: params.commitMessage,
369
+ user: actor,
370
+ });
371
+ // Only sync Y.Doc when the body was actually rewritten. Pure
372
+ // metadata edits don't touch content and shouldn't thrash.
373
+ if (sanitizedContent !== undefined) {
374
+ onContentSync?.(repoName, params.entityType, params.entityId);
375
+ }
376
+ onMutation?.({ action: 'updated', repo: repoName, entityType: params.entityType, entityId: params.entityId });
377
+ return wrapToolResult({
378
+ success: true,
379
+ entity: {
380
+ entityId: entity.id,
381
+ entityType: entity.entityType,
382
+ repo: repoName,
383
+ data: cleanData(entity.data),
384
+ },
385
+ message: `Updated ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
386
+ });
387
+ }
388
+ finally {
389
+ onAgentActivity?.('leave', repoName);
390
+ }
272
391
  }
273
392
  catch (error) {
274
393
  return wrapToolResult({
@@ -282,9 +401,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
282
401
  {
283
402
  name: 'delete_entity',
284
403
  label: 'Delete Entry',
285
- description: 'Delete an entry. Use with caution! Collection is auto-resolved for app-defined types.',
404
+ description: 'Delete an entry. Use with caution! Folder is auto-resolved for app-defined types.',
286
405
  parameters: T.Object({
287
- repo: T.Optional(T.String({ description: 'Collection name (auto-resolved for app entity types)' })),
406
+ repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
288
407
  entityType: T.String({ description: 'Entity type' }),
289
408
  entityId: T.String({ description: 'Entity ID' }),
290
409
  commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
@@ -293,21 +412,25 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
293
412
  try {
294
413
  let repoName = params.repo;
295
414
  if (!repoName) {
296
- repoName = workspaceManager.getAppForEntityType(params.entityType);
297
- if (!repoName)
298
- return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
415
+ return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
299
416
  }
300
417
  repoName = resolvePrivateRepo(repoName);
301
418
  if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
302
- return wrapToolResult({ success: false, error: `Collection "${repoName}" not found` });
419
+ return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
303
420
  }
304
421
  const graph = workspaceManager.getGraph(repoName);
305
- await graph.delete(params.entityType, params.entityId, params.commitMessage);
306
- onMutation?.({ action: 'deleted', repo: repoName, entityType: params.entityType, entityId: params.entityId });
307
- return wrapToolResult({
308
- success: true,
309
- message: `Deleted ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
310
- });
422
+ onAgentActivity?.('enter', repoName);
423
+ try {
424
+ await graph.delete(params.entityType, params.entityId, params.commitMessage);
425
+ onMutation?.({ action: 'deleted', repo: repoName, entityType: params.entityType, entityId: params.entityId });
426
+ return wrapToolResult({
427
+ success: true,
428
+ message: `Deleted ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
429
+ });
430
+ }
431
+ finally {
432
+ onAgentActivity?.('leave', repoName);
433
+ }
311
434
  }
312
435
  catch (error) {
313
436
  return wrapToolResult({
@@ -321,46 +444,93 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
321
444
  {
322
445
  name: 'import_file',
323
446
  label: 'Import File',
324
- description: 'Import a local file as a Studiograph entry. Supports .md and .txt (→ note) and .csv (→ dataset). The file is read from the local filesystem and converted to an entry with appropriate frontmatter.',
447
+ description: 'Import a local file as a Studiograph entry. Text formats become typed entries (.md/.txt → note, .csv → dataset). Binary formats (PDF, images, design files, video, audio, archives) become asset entries.',
325
448
  parameters: T.Object({
326
449
  path: T.String({ description: 'Absolute path or ~/relative path to the file' }),
327
- collection: T.String({ description: 'Target collection name' }),
328
- entityType: T.Optional(T.String({ description: 'Override entity type (default: auto-detect from extension)' })),
450
+ folder: T.String({ description: 'Target folder name' }),
451
+ entityType: T.Optional(T.String({ description: 'Override entity type (default: auto-detect from extension; ignored for asset uploads)' })),
329
452
  entityId: T.Optional(T.String({ description: 'Override entity ID (default: from filename)' })),
330
453
  }),
331
454
  execute: async (toolCallId, params) => {
332
455
  try {
333
- if (!canAccessRepo(params.collection, workspaceManager, getUser, authSvc)) {
334
- return wrapToolResult({ success: false, error: `Collection "${params.collection}" not found` });
456
+ if (!canAccessRepo(params.folder, workspaceManager, getUser, authSvc)) {
457
+ return wrapToolResult({ success: false, error: `Folder "${params.folder}" not found` });
335
458
  }
336
459
  const { readFileSync, existsSync } = await import('fs');
337
- const { resolve } = await import('path');
460
+ const { resolve, basename, sep } = await import('path');
338
461
  const { homedir } = await import('os');
339
462
  const { importFile, isSupportedFile } = await import('../../services/import-service.js');
463
+ const { isAssetUploadExtension } = await import('../../services/assets/base.js');
464
+ const { uploadAsset } = await import('../../services/asset-upload-service.js');
340
465
  const filePath = params.path.startsWith('~/')
341
466
  ? resolve(homedir(), params.path.slice(2))
342
467
  : resolve(params.path);
343
468
  if (!existsSync(filePath)) {
344
469
  return wrapToolResult({ success: false, error: `File not found: ${filePath}` });
345
470
  }
471
+ const graph = workspaceManager.getGraph(params.folder);
472
+ const fname = basename(filePath);
473
+ // Path-exfil guard: the agent reads bytes off disk and uploads
474
+ // them as a workspace asset, accessible via /api/assets/* by any
475
+ // folder member. Without an allowlist, an LLM prompt injection in
476
+ // an imported note can ask the agent to grab ~/.ssh/id_rsa, .env
477
+ // files, kubeconfigs, etc. by renaming them to a permitted
478
+ // extension. Restrict to roots a user would plausibly drop files
479
+ // from: the workspace itself, ~/Downloads, ~/Documents.
480
+ const home = homedir();
481
+ const workspaceRoot = graph.getWorkspaceRoot();
482
+ const allowedRoots = [
483
+ workspaceRoot,
484
+ resolve(home, 'Downloads'),
485
+ resolve(home, 'Documents'),
486
+ ].filter((r) => Boolean(r)).map(r => r.endsWith(sep) ? r : r + sep);
487
+ const isInAllowedRoot = allowedRoots.some(root => filePath === root.slice(0, -1) || filePath.startsWith(root));
488
+ if (!isInAllowedRoot) {
489
+ return wrapToolResult({
490
+ success: false,
491
+ error: `Path "${filePath}" is outside the import allowlist. Files must live under the workspace, ~/Downloads, or ~/Documents.`,
492
+ });
493
+ }
494
+ // Binary extensions → asset wrapper. The text-import path doesn't
495
+ // know how to handle .indd / .pptx / etc. and would either reject
496
+ // them or (for .pdf) mistakenly land them as a `note` entity with
497
+ // extracted body text. Route to uploadAsset for parity with the
498
+ // web import dispatcher.
499
+ if (isAssetUploadExtension(fname)) {
500
+ const buffer = readFileSync(filePath);
501
+ const result = await uploadAsset({
502
+ graph,
503
+ filename: fname,
504
+ buffer,
505
+ workspacePath: graph.getWorkspaceRoot(),
506
+ });
507
+ onMutation?.({ action: 'created', repo: params.folder, entityType: 'asset', entityId: result.entityId });
508
+ return wrapToolResult({
509
+ success: true,
510
+ entityType: 'asset',
511
+ entityId: result.entityId,
512
+ asset_kind: result.asset_kind,
513
+ asset_size: result.asset_size,
514
+ pages: result.pages,
515
+ message: `Imported ${fname} as asset/${result.entityId} in ${params.folder}`,
516
+ });
517
+ }
346
518
  if (!isSupportedFile(filePath)) {
347
- return wrapToolResult({ success: false, error: `Unsupported file type. Supported: .md, .txt, .csv` });
519
+ return wrapToolResult({ success: false, error: `Unsupported file type for ${fname}` });
348
520
  }
349
- const graph = workspaceManager.getGraph(params.collection);
350
521
  const content = readFileSync(filePath);
351
- const { basename } = await import('path');
352
- const result = await importFile(graph, basename(filePath), content, {
522
+ const result = await importFile(graph, fname, content, {
353
523
  entityType: params.entityType,
354
524
  entityId: params.entityId,
355
525
  });
356
526
  if (result.status === 'created') {
357
- onMutation?.({ action: 'created', repo: params.collection, entityType: result.entityType, entityId: result.entityId });
527
+ onMutation?.({ action: 'created', repo: params.folder, entityType: result.entityType, entityId: result.entityId });
358
528
  }
359
529
  return wrapToolResult({
360
530
  success: result.status === 'created',
361
531
  ...result,
362
532
  message: result.status === 'created'
363
- ? `Imported ${basename(filePath)} as ${result.entityType}/${result.entityId} in ${params.collection}`
533
+ ? `Imported ${fname} as ${result.entityType}/${result.entityId} in ${params.folder}`
364
534
  : result.error,
365
535
  });
366
536
  }
@@ -376,9 +546,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
376
546
  {
377
547
  name: 'rename_entity',
378
548
  label: 'Rename Entry',
379
- description: 'Rename an entry by changing its ID. Preserves all data, content, and source_ref. The old ID will no longer exist. Collection is auto-resolved for app-defined types.',
549
+ description: 'Rename an entry by changing its ID. Preserves all data, content, and source_ref. The old ID will no longer exist. Folder is auto-resolved for app-defined types.',
380
550
  parameters: T.Object({
381
- repo: T.Optional(T.String({ description: 'Collection name (auto-resolved for app entity types)' })),
551
+ repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
382
552
  entityType: T.String({ description: 'Entity type' }),
383
553
  oldId: T.String({ description: 'Current entity ID' }),
384
554
  newId: T.String({ description: 'New entity ID (kebab-case)' }),
@@ -387,13 +557,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
387
557
  try {
388
558
  let repoName = params.repo;
389
559
  if (!repoName) {
390
- repoName = workspaceManager.getAppForEntityType(params.entityType);
391
- if (!repoName)
392
- return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
560
+ return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
393
561
  }
394
562
  repoName = resolvePrivateRepo(repoName);
395
563
  if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
396
- return wrapToolResult({ success: false, error: `Collection "${repoName}" not found` });
564
+ return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
397
565
  }
398
566
  const graph = workspaceManager.getGraph(repoName);
399
567
  const result = await graph.rename(params.entityType, params.oldId, params.newId);
@@ -413,41 +581,41 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
413
581
  }
414
582
  },
415
583
  },
416
- // Move entity between repos
584
+ // Transfer entity across repos (cross-repo move). Distinct from
585
+ // folder-tools' `move_entity`, which relocates within one repo.
417
586
  {
418
- name: 'move_entity',
419
- label: 'Move Entry',
420
- description: 'Move an entry from one collection to another (admin only). Preserves all data, content, and wikilinks.',
587
+ name: 'transfer_entity',
588
+ label: 'Transfer Entry',
589
+ description: 'Move an entry from one repo to another. Preserves all data, content, and wikilinks. Requires access to both folders. For relocating within the same repo (folder_path change), use move_entity instead.',
421
590
  parameters: T.Object({
422
- sourceRepo: T.String({ description: 'Source collection name' }),
423
- targetRepo: T.String({ description: 'Target collection name' }),
591
+ sourceRepo: T.String({ description: 'Source repo name' }),
592
+ targetRepo: T.String({ description: 'Target repo name' }),
424
593
  entityType: T.String({ description: 'Entity type' }),
425
594
  entityId: T.String({ description: 'Entity ID' }),
426
595
  commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
427
596
  }),
428
597
  execute: async (toolCallId, params) => {
429
598
  try {
430
- const denied = adminOnly(getUser);
431
- if (denied)
432
- return wrapToolResult({ success: false, error: denied });
433
599
  if (!canAccessRepo(params.sourceRepo, workspaceManager, getUser, authSvc)) {
434
- return wrapToolResult({ success: false, error: `Collection "${params.sourceRepo}" not found` });
600
+ return wrapToolResult({ success: false, error: `Folder "${params.sourceRepo}" not found` });
435
601
  }
436
602
  if (!canAccessRepo(params.targetRepo, workspaceManager, getUser, authSvc)) {
437
- return wrapToolResult({ success: false, error: `Collection "${params.targetRepo}" not found` });
603
+ return wrapToolResult({ success: false, error: `Folder "${params.targetRepo}" not found` });
438
604
  }
439
605
  const sourceGraph = workspaceManager.getGraph(params.sourceRepo);
440
606
  const targetGraph = workspaceManager.getGraph(params.targetRepo);
441
607
  // Read the full entity from source
442
608
  const entity = sourceGraph.get(params.entityType, params.entityId);
443
609
  // Create in target repo
610
+ const actor = effectiveGitUser();
444
611
  const now = new Date().toISOString();
445
612
  await targetGraph.create({
446
613
  entityType: params.entityType,
447
614
  entityId: params.entityId,
448
- data: { ...entity.data, updated_at: now, updated_by: gitUser.id },
615
+ data: { ...entity.data, updated_at: now, updated_by: actor.id },
449
616
  content: entity.document.content || '',
450
617
  commitMessage: params.commitMessage || `Move ${params.entityType} ${params.entityId} from ${params.sourceRepo} to ${params.targetRepo}`,
618
+ user: actor,
451
619
  });
452
620
  // Delete from source repo
453
621
  await sourceGraph.delete(params.entityType, params.entityId, `Move ${params.entityType} ${params.entityId} to ${params.targetRepo}`);
@@ -470,11 +638,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
470
638
  {
471
639
  name: 'search_entities',
472
640
  label: 'Search Entries',
473
- description: 'Search for entries across collections with filters.',
641
+ description: 'Search for entries across folders with filters.',
474
642
  parameters: T.Object({
475
643
  query: T.Optional(T.String({ description: 'Search query (full-text)' })),
476
644
  entityType: T.Optional(T.String({ description: 'Filter by entity type' })),
477
- repoNames: T.Optional(T.Array(T.String(), { description: 'Limit to specific collections' })),
645
+ repoNames: T.Optional(T.Array(T.String(), { description: 'Limit to specific folders' })),
478
646
  visibility: T.Optional(T.Array(T.String(), { description: 'Filter by visibility (public, team, admin, restricted)' })),
479
647
  tags: T.Optional(T.Array(T.String(), { description: 'Filter by tags' })),
480
648
  dateRange: T.Optional(T.Object({
@@ -486,7 +654,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
486
654
  }),
487
655
  execute: async (toolCallId, params) => {
488
656
  try {
489
- // Scope search to accessible collections
657
+ // Scope search to accessible folders
490
658
  const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
491
659
  let repoNames = params.repoNames?.map((r) => resolvePrivateRepo(r));
492
660
  if (allowed) {
@@ -535,7 +703,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
535
703
  execute: async (toolCallId, params) => {
536
704
  try {
537
705
  let results = workspaceManager.list(params.entityType, params.limit);
538
- // Filter to accessible collections
706
+ // Filter to accessible folders
539
707
  const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
540
708
  if (allowed) {
541
709
  results = results.filter(r => allowed.has(r.repoName));
@@ -563,9 +731,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
563
731
  {
564
732
  name: 'get_related',
565
733
  label: 'Get Related Entries',
566
- description: 'Get entries related to a given entry via wikilinks (cross-collection supported). Pass repo, entityType, entityId from search/list results.',
734
+ description: 'Get entries related to a given entry via wikilinks (cross-folder supported). Pass repo, entityType, entityId from search/list results.',
567
735
  parameters: T.Object({
568
- repo: T.String({ description: 'Collection name' }),
736
+ repo: T.String({ description: 'Folder name' }),
569
737
  entityType: T.String({ description: 'Entity type' }),
570
738
  entityId: T.String({ description: 'Entity ID' }),
571
739
  }),
@@ -573,10 +741,10 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
573
741
  try {
574
742
  const repo = resolvePrivateRepo(params.repo);
575
743
  if (!canAccessRepo(repo, workspaceManager, getUser, authSvc)) {
576
- return wrapToolResult({ success: false, error: `Collection "${repo}" not found` });
744
+ return wrapToolResult({ success: false, error: `Folder "${repo}" not found` });
577
745
  }
578
746
  let related = workspaceManager.getRelated(repo, params.entityType, params.entityId);
579
- // Filter cross-collection results to accessible repos
747
+ // Filter cross-folder results to accessible repos
580
748
  const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
581
749
  if (allowed) {
582
750
  related = related.filter(r => allowed.has(r.repoName));
@@ -604,19 +772,19 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
604
772
  {
605
773
  name: 'get_backlinks',
606
774
  label: 'Get Backlinks',
607
- description: 'Get entries that link to a given entry (cross-collection supported). Pass repo, entityType, entityId from search/list results.',
775
+ description: 'Get entries that link to a given entry (cross-folder supported). Pass repo, entityType, entityId from search/list results.',
608
776
  parameters: T.Object({
609
- repo: T.String({ description: 'Collection name' }),
777
+ repo: T.String({ description: 'Folder name' }),
610
778
  entityType: T.String({ description: 'Entity type' }),
611
779
  entityId: T.String({ description: 'Entity ID' }),
612
780
  }),
613
781
  execute: async (toolCallId, params) => {
614
782
  try {
615
783
  if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
616
- return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
784
+ return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
617
785
  }
618
786
  let backlinks = workspaceManager.getBacklinks(params.repo, params.entityType, params.entityId);
619
- // Filter cross-collection results to accessible repos
787
+ // Filter cross-folder results to accessible repos
620
788
  const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
621
789
  if (allowed) {
622
790
  backlinks = backlinks.filter(r => allowed.has(r.repoName));
@@ -644,16 +812,16 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
644
812
  {
645
813
  name: 'validate_wikilinks',
646
814
  label: 'Validate Wikilinks',
647
- description: 'Validate all wikilinks in an entry (checks same collection and cross-collection)',
815
+ description: 'Validate all wikilinks in an entry (checks same folder and cross-folder)',
648
816
  parameters: T.Object({
649
- repo: T.String({ description: 'Collection name' }),
817
+ repo: T.String({ description: 'Folder name' }),
650
818
  entityType: T.String({ description: 'Entity type' }),
651
819
  entityId: T.String({ description: 'Entity ID' }),
652
820
  }),
653
821
  execute: async (toolCallId, params) => {
654
822
  try {
655
823
  if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
656
- return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
824
+ return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
657
825
  }
658
826
  const validation = workspaceManager.validateWikilinks(params.repo, params.entityType, params.entityId);
659
827
  return wrapToolResult({
@@ -688,7 +856,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
688
856
  const summary = workspaceManager.getSummary();
689
857
  const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
690
858
  if (allowed) {
691
- // Filter summary to accessible collections only
859
+ // Filter summary to accessible folders only
692
860
  const filteredByRepo = {};
693
861
  let filteredTotal = 0;
694
862
  for (const [repo, count] of Object.entries(summary.entitiesByRepo)) {
@@ -700,19 +868,19 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
700
868
  return wrapToolResult({
701
869
  success: true,
702
870
  summary: {
703
- totalCollections: allowed.size,
871
+ totalFolders: allowed.size,
704
872
  totalEntities: filteredTotal,
705
- entitiesByCollection: filteredByRepo,
873
+ entitiesByFolder: filteredByRepo,
706
874
  },
707
875
  });
708
876
  }
709
877
  return wrapToolResult({
710
878
  success: true,
711
879
  summary: {
712
- totalCollections: summary.totalRepos,
880
+ totalFolders: summary.totalRepos,
713
881
  totalEntities: summary.totalEntities,
714
882
  entitiesByType: summary.entitiesByType,
715
- entitiesByCollection: summary.entitiesByRepo,
883
+ entitiesByFolder: summary.entitiesByRepo,
716
884
  },
717
885
  });
718
886
  }
@@ -724,11 +892,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
724
892
  }
725
893
  },
726
894
  },
727
- // List collections
895
+ // List folders
728
896
  {
729
897
  name: 'list_repos',
730
- label: 'List Collections',
731
- description: 'List all collections in the workspace',
898
+ label: 'List Folders',
899
+ description: 'List all folders in the workspace',
732
900
  parameters: T.Object({}),
733
901
  execute: async (toolCallId, params) => {
734
902
  try {
@@ -740,12 +908,12 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
740
908
  return wrapToolResult({
741
909
  success: true,
742
910
  count: repos.length,
743
- collections: repos.map(r => ({
911
+ folders: repos.map(r => ({
744
912
  name: r.name,
745
913
  type: r.type,
746
914
  description: r.description,
747
915
  path: r.path,
748
- private: r.private || false,
916
+ personal: r.personal || false,
749
917
  })),
750
918
  });
751
919
  }
@@ -757,40 +925,35 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
757
925
  }
758
926
  },
759
927
  },
760
- // Create a new collection
928
+ // Create a new folder
761
929
  {
762
- name: 'create_collection',
763
- label: 'Create Collection',
764
- description: 'Create a new collection in the workspace. A collection is a git-backed container for entries. Private collections are only visible to the creating user.',
930
+ name: 'create_folder',
931
+ label: 'Create Folder',
932
+ description: 'Create a new shared folder in the workspace. Folders are git-backed containers for entries. New folders are shared with teammates who have access; the creator is granted admin. Every user already has a personal "My Entries" folder auto-provisioned — do not use this tool to create another one.',
765
933
  parameters: T.Object({
766
- name: T.String({ description: 'Collection name in kebab-case (e.g., "client-projects")' }),
767
- description: T.Optional(T.String({ description: 'Short description of the collection' })),
768
- private: T.Optional(T.Boolean({ description: 'If true, creates a private collection visible only to you' })),
934
+ name: T.String({ description: 'Folder name in kebab-case (e.g., "client-projects")' }),
935
+ description: T.Optional(T.String({ description: 'Short description of the folder' })),
769
936
  }),
770
937
  execute: async (toolCallId, params) => {
771
938
  try {
772
939
  const user = getUser();
773
- // Non-private collections require admin; private collections can be created by anyone
774
- if (!params.private && user && !isAdminOrOwner(user.role)) {
775
- return wrapToolResult({ success: false, error: 'Only admins can create collections' });
776
- }
777
940
  if (!/^[a-z0-9][a-z0-9-]*$/.test(params.name)) {
778
- return wrapToolResult({ success: false, error: 'Collection name must be kebab-case (lowercase letters, numbers, hyphens)' });
941
+ return wrapToolResult({ success: false, error: 'Folder name must be kebab-case (lowercase letters, numbers, hyphens)' });
779
942
  }
780
943
  const { Workspace } = await import('../../core/workspace.js');
781
944
  const workspace = new Workspace(workspacePath);
782
945
  const repo = await workspace.registerRepo({
783
946
  name: params.name,
784
947
  description: params.description,
785
- private: params.private,
786
- ...(params.private && user ? { owner_id: user.id } : {}),
948
+ owner_id: user?.id,
787
949
  });
788
- // Reload workspace manager to pick up the new collection
789
950
  workspaceManager.reloadConfig();
790
- onMutation?.({ action: 'created', repo: repo.name, entityType: '_collection', entityId: repo.name });
951
+ if (user && authSvc)
952
+ authSvc.grantFolderAccess(user.id, repo.name, 'admin');
953
+ onMutation?.({ action: 'created', repo: repo.name, entityType: '_folder', entityId: repo.name });
791
954
  return wrapToolResult({
792
955
  success: true,
793
- collection: { name: repo.name, path: repo.path, description: repo.description },
956
+ folder: { name: repo.name, path: repo.path, description: repo.description },
794
957
  });
795
958
  }
796
959
  catch (error) {
@@ -798,81 +961,6 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
798
961
  }
799
962
  },
800
963
  },
801
- // Query dataset rows
802
- {
803
- name: 'query_dataset',
804
- label: 'Query Dataset',
805
- description: 'Query rows from a dataset entity with optional filtering',
806
- parameters: T.Object({
807
- repo: T.String({ description: 'Collection name' }),
808
- entityId: T.String({ description: 'Dataset entity ID' }),
809
- filter: T.Optional(T.Object({}, { description: 'Filter conditions (column: value or { gte, lte, contains })', additionalProperties: true })),
810
- limit: T.Optional(T.Number({ description: 'Max rows to return' })),
811
- }),
812
- execute: async (toolCallId, params) => {
813
- try {
814
- if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
815
- return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
816
- }
817
- const graph = workspaceManager.getGraph(params.repo);
818
- const entity = graph.get('dataset', params.entityId);
819
- const schema = entity.data.schema;
820
- let rows = graph.getDatasetRows(params.entityId, params.filter);
821
- const total = rows.length;
822
- if (params.limit && params.limit > 0) {
823
- rows = rows.slice(0, params.limit);
824
- }
825
- return wrapToolResult({
826
- success: true,
827
- rows,
828
- total,
829
- schema,
830
- });
831
- }
832
- catch (error) {
833
- return wrapToolResult({
834
- success: false,
835
- error: error instanceof Error ? error.message : 'Unknown error',
836
- });
837
- }
838
- },
839
- },
840
- // Append rows to dataset
841
- {
842
- name: 'append_rows',
843
- label: 'Append Rows',
844
- description: 'Append rows to a dataset entity',
845
- parameters: T.Object({
846
- repo: T.String({ description: 'Collection name' }),
847
- entityId: T.String({ description: 'Dataset entity ID' }),
848
- rows: T.Array(T.Object({}, { additionalProperties: true }), { description: 'Rows to append' }),
849
- commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
850
- }),
851
- execute: async (toolCallId, params) => {
852
- try {
853
- if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
854
- return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
855
- }
856
- const graph = workspaceManager.getGraph(params.repo);
857
- // Get current row count before appending
858
- const beforeRows = graph.getDatasetRows(params.entityId);
859
- await graph.appendDatasetRows(params.entityId, params.rows, params.commitMessage);
860
- const afterRows = graph.getDatasetRows(params.entityId);
861
- return wrapToolResult({
862
- success: true,
863
- rowsAdded: afterRows.length - beforeRows.length,
864
- totalRows: afterRows.length,
865
- message: `Appended ${afterRows.length - beforeRows.length} row(s) to dataset: ${params.entityId}`,
866
- });
867
- }
868
- catch (error) {
869
- return wrapToolResult({
870
- success: false,
871
- error: error instanceof Error ? error.message : 'Unknown error',
872
- });
873
- }
874
- },
875
- },
876
964
  // Get entity schema
877
965
  {
878
966
  name: 'get_entity_schema',
@@ -919,15 +1007,15 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
919
1007
  {
920
1008
  name: 'lint_entities',
921
1009
  label: 'Lint Entries',
922
- description: 'Check for missing recommended fields across entries. Returns incomplete entries with their missing fields. Use to discover entries that need enrichment. Optionally filter by collection or entry type.',
1010
+ description: 'Check for missing recommended fields across entries. Returns incomplete entries with their missing fields. Use to discover entries that need enrichment. Optionally filter by folder or entry type.',
923
1011
  parameters: T.Object({
924
- repo: T.Optional(T.String({ description: 'Optional: limit to specific collection' })),
1012
+ repo: T.Optional(T.String({ description: 'Optional: limit to specific folder' })),
925
1013
  entityType: T.Optional(T.String({ description: 'Optional: limit to specific entity type (e.g. "project", "deal")' })),
926
1014
  }),
927
1015
  execute: async (toolCallId, params) => {
928
1016
  try {
929
1017
  if (params.repo && !canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
930
- return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
1018
+ return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
931
1019
  }
932
1020
  let issues = await lintWorkspace(workspaceManager, {
933
1021
  repo: params.repo,
@@ -977,11 +1065,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
977
1065
  parameters: T.Object({
978
1066
  entityTypes: T.Optional(T.Array(T.String(), { description: 'Entity types to check (e.g. ["person", "client"])' })),
979
1067
  minAgeDays: T.Optional(T.Number({ description: 'Only flag entities older than N days' })),
980
- repos: T.Optional(T.Array(T.String(), { description: 'Collection names to scan (default: all)' })),
1068
+ repos: T.Optional(T.Array(T.String(), { description: 'Folder names to scan (default: all)' })),
981
1069
  }),
982
1070
  execute: async (toolCallId, params) => {
983
1071
  try {
984
- // Scope to accessible collections
1072
+ // Scope to accessible folders
985
1073
  const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
986
1074
  let repos = params.repos;
987
1075
  if (allowed) {
@@ -1032,98 +1120,6 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
1032
1120
  });
1033
1121
  },
1034
1122
  },
1035
- // ── View Management Tools ──
1036
- {
1037
- name: 'list_views',
1038
- label: 'List Views',
1039
- description: 'List the current user\'s saved views.',
1040
- parameters: T.Object({}),
1041
- execute: async () => {
1042
- if (!authSvc)
1043
- return wrapToolResult({ success: false, error: 'Auth service not available' });
1044
- const userId = getUser()?.id ?? 0;
1045
- const views = authSvc.getUserViews(userId);
1046
- return wrapToolResult({ views });
1047
- },
1048
- },
1049
- {
1050
- name: 'create_view',
1051
- label: 'Create View',
1052
- description: 'Create a new saved view for the current user. Views appear as tabs in the toolbar.',
1053
- parameters: T.Object({
1054
- name: T.String({ description: 'View name (e.g. "My Tasks", "Open Projects")' }),
1055
- selectedType: T.Optional(T.String({ description: 'Entity type filter (e.g. "task", "project"). Omit for all types.' })),
1056
- groupBy: T.Optional(T.String({ description: 'Column key to group by (e.g. "status", "priority")' })),
1057
- }),
1058
- execute: async (_toolCallId, params) => {
1059
- if (!authSvc)
1060
- return wrapToolResult({ success: false, error: 'Auth service not available' });
1061
- const userId = getUser()?.id ?? 0;
1062
- const config = {
1063
- selectedType: params.selectedType ?? null,
1064
- groupBy: params.groupBy ?? null,
1065
- sortKey: 'name',
1066
- sortAsc: true,
1067
- filters: { text: {}, enum: {}, date: {} },
1068
- };
1069
- const view = authSvc.createUserView(userId, params.name, 'list', config);
1070
- return wrapToolResult({
1071
- success: true,
1072
- view: { id: view.id, name: view.name, viewType: view.viewType, config: view.config },
1073
- message: `Created view "${params.name}". It will appear as a tab in the toolbar.`,
1074
- });
1075
- },
1076
- },
1077
- {
1078
- name: 'update_view',
1079
- label: 'Update View',
1080
- description: 'Update an existing saved view\'s name or configuration.',
1081
- parameters: T.Object({
1082
- id: T.Number({ description: 'View ID' }),
1083
- name: T.Optional(T.String({ description: 'New view name' })),
1084
- selectedType: T.Optional(T.String({ description: 'Entity type filter (use "all" to clear)' })),
1085
- groupBy: T.Optional(T.String({ description: 'Column key to group by (use "none" to clear)' })),
1086
- }),
1087
- execute: async (_toolCallId, params) => {
1088
- if (!authSvc)
1089
- return wrapToolResult({ success: false, error: 'Auth service not available' });
1090
- const userId = getUser()?.id ?? 0;
1091
- const existing = authSvc.getUserView(params.id, userId);
1092
- if (!existing)
1093
- return wrapToolResult({ success: false, error: `View ${params.id} not found` });
1094
- const fields = {};
1095
- if (params.name)
1096
- fields.name = params.name;
1097
- if (params.selectedType !== undefined || params.groupBy !== undefined) {
1098
- const config = { ...existing.config };
1099
- if (params.selectedType !== undefined)
1100
- config.selectedType = params.selectedType === 'all' ? null : params.selectedType;
1101
- if (params.groupBy !== undefined)
1102
- config.groupBy = params.groupBy === 'none' ? null : params.groupBy;
1103
- fields.config = config;
1104
- }
1105
- authSvc.updateUserView(params.id, userId, fields);
1106
- return wrapToolResult({ success: true, message: `Updated view "${existing.name}".` });
1107
- },
1108
- },
1109
- {
1110
- name: 'delete_view',
1111
- label: 'Delete View',
1112
- description: 'Delete a saved view.',
1113
- parameters: T.Object({
1114
- id: T.Number({ description: 'View ID to delete' }),
1115
- }),
1116
- execute: async (_toolCallId, params) => {
1117
- if (!authSvc)
1118
- return wrapToolResult({ success: false, error: 'Auth service not available' });
1119
- const userId = getUser()?.id ?? 0;
1120
- const existing = authSvc.getUserView(params.id, userId);
1121
- if (!existing)
1122
- return wrapToolResult({ success: false, error: `View ${params.id} not found` });
1123
- authSvc.deleteUserView(params.id, userId);
1124
- return wrapToolResult({ success: true, message: `Deleted view "${existing.name}".` });
1125
- },
1126
- },
1127
1123
  // Mark onboarding complete
1128
1124
  {
1129
1125
  name: 'mark_onboarded',