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
@@ -3,18 +3,147 @@
3
3
  *
4
4
  * Pull and push changes across the workspace:
5
5
  * - the .studiograph config repo (if it has a git remote)
6
- * - each entity collection that is a git repo with a remote
6
+ * - each entity folder that is a git repo with a remote
7
7
  *
8
8
  * Works with both GitHub remotes and the embedded git server.
9
9
  */
10
10
  import { Command } from 'commander';
11
11
  import { log, outro, text, password as passwordPrompt } from '@clack/prompts';
12
- import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs';
12
+ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'fs';
13
13
  import { join } from 'path';
14
14
  import { Workspace } from '../../core/workspace.js';
15
15
  import { AuthService } from '../../services/auth-service.js';
16
16
  import { ConnectorManager } from '../../mcp/connector-manager.js';
17
- import { gitPull, gitPush, gitPushWithCredentials, gitSetRemote, gitHasRemote } from '../../utils/git.js';
17
+ import { buildConfigBundle } from '../../core/secrets/bundle.js';
18
+ import { gitClone, gitPull, gitPush, gitPushWithCredentials, gitSetRemote, gitHasRemote } from '../../utils/git.js';
19
+ import { getStudiographToken, setStudiographToken, clearStudiographToken } from '../../core/user-config.js';
20
+ async function resolveRemoteAuth(base, _workspaceRoot, opts) {
21
+ // 1-2. Explicit token or env var
22
+ const explicitToken = opts.token || process.env.STUDIOGRAPH_TOKEN;
23
+ if (explicitToken) {
24
+ const token = explicitToken.trim();
25
+ return {
26
+ httpHeader: { 'Authorization': `Bearer ${token}` },
27
+ gitCredentials: { username: '_token_', password: token },
28
+ };
29
+ }
30
+ // 3. Explicit email/password or env vars
31
+ const email = opts.email || process.env.STUDIOGRAPH_EMAIL;
32
+ const password = opts.password || process.env.STUDIOGRAPH_PASSWORD;
33
+ if (email && password) {
34
+ const httpHeader = await loginForCookie(base, email, password);
35
+ return { httpHeader, gitCredentials: { username: email, password } };
36
+ }
37
+ // 4. Stored per-user token from ~/.studiograph/user.json
38
+ const storedToken = getStudiographToken(base);
39
+ if (storedToken) {
40
+ const httpHeader = { 'Authorization': `Bearer ${storedToken}` };
41
+ // Probe a cheap authenticated endpoint so a revoked / expired / rebuilt-DB
42
+ // token doesn't wedge push/pull. On 401, clear it and fall through to the
43
+ // interactive mint so users can recover without hand-editing user.json.
44
+ const probe = await fetch(`${base}/api/auth/tokens`, { headers: httpHeader }).catch(() => null);
45
+ if (probe?.ok) {
46
+ return { httpHeader, gitCredentials: { username: '_token_', password: storedToken } };
47
+ }
48
+ if (probe?.status === 401) {
49
+ clearStudiographToken(base);
50
+ log.info('Stored CLI token is no longer valid — signing in again.');
51
+ }
52
+ else if (probe) {
53
+ // Non-401 response (5xx, unreachable, etc.) → keep the token, use it;
54
+ // the real request will surface the underlying error.
55
+ return { httpHeader, gitCredentials: { username: '_token_', password: storedToken } };
56
+ }
57
+ }
58
+ // 5. Interactive prompts — then mint a token for future runs.
59
+ if (!process.stdin.isTTY) {
60
+ throw new Error('No credentials provided and stdin is not a TTY. Use --token, --email + --password, or set STUDIOGRAPH_TOKEN.');
61
+ }
62
+ const emailPrompt = await text({ message: 'Email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
63
+ if (typeof emailPrompt === 'symbol') {
64
+ outro('Cancelled');
65
+ process.exit(0);
66
+ }
67
+ const passPrompt = await passwordPrompt({ message: 'Password:' });
68
+ if (typeof passPrompt === 'symbol') {
69
+ outro('Cancelled');
70
+ process.exit(0);
71
+ }
72
+ const emailStr = String(emailPrompt);
73
+ const passStr = String(passPrompt);
74
+ const httpHeader = await loginForCookie(base, emailStr, passStr);
75
+ // Mint a CLI token and save it, so subsequent push/pull runs skip the prompt.
76
+ try {
77
+ const mintRes = await fetch(`${base}/api/auth/tokens`, {
78
+ method: 'POST',
79
+ headers: { ...httpHeader, 'Content-Type': 'application/json' },
80
+ body: JSON.stringify({ name: `cli-${process.platform}-${Date.now()}` }),
81
+ });
82
+ if (mintRes.ok) {
83
+ const body = await mintRes.json();
84
+ if (body.token) {
85
+ setStudiographToken(base, body.token);
86
+ log.info('Saved personal API token to ~/.studiograph/user.json for future runs');
87
+ }
88
+ }
89
+ }
90
+ catch { /* non-fatal — just means next run prompts again */ }
91
+ return { httpHeader, gitCredentials: { username: emailStr, password: passStr } };
92
+ }
93
+ async function loginForCookie(base, email, password) {
94
+ const loginRes = await fetch(`${base}/api/auth/login`, {
95
+ method: 'POST',
96
+ headers: { 'Content-Type': 'application/json' },
97
+ body: JSON.stringify({ email, password }),
98
+ });
99
+ if (!loginRes.ok) {
100
+ const body = await loginRes.json().catch(() => ({}));
101
+ throw new Error(`Login failed: ${body.error || loginRes.statusText}`);
102
+ }
103
+ const cookies = loginRes.headers.getSetCookie?.() ?? [];
104
+ const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
105
+ if (!tokenCookie) {
106
+ throw new Error('Login succeeded but no session cookie was returned');
107
+ }
108
+ return { 'Cookie': tokenCookie.split(';')[0] };
109
+ }
110
+ /**
111
+ * Login with email + password and return the raw JWT (extracted from the
112
+ * `__sg_token` cookie). Same endpoint as {@link loginForCookie} but pulls
113
+ * the bare token instead of a Cookie header — needed when callers want to
114
+ * persist the token for reuse (server-auth.json) or pass it as the
115
+ * password in HTTP Basic auth (git-http expects basic-auth, not cookies).
116
+ */
117
+ async function loginForJwt(base, email, password) {
118
+ const loginRes = await fetch(`${base}/api/auth/login`, {
119
+ method: 'POST',
120
+ headers: { 'Content-Type': 'application/json' },
121
+ body: JSON.stringify({ email, password }),
122
+ });
123
+ if (!loginRes.ok) {
124
+ const body = await loginRes.json().catch(() => ({}));
125
+ throw new Error(`Login failed: ${body.error || loginRes.statusText}`);
126
+ }
127
+ const cookies = loginRes.headers.getSetCookie?.() ?? [];
128
+ const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
129
+ if (!tokenCookie) {
130
+ throw new Error('Login succeeded but no session cookie was returned');
131
+ }
132
+ return tokenCookie.split(';')[0].replace('__sg_token=', '');
133
+ }
134
+ /**
135
+ * Persist a successful login to `<workspace>/.studiograph/server-auth.json`
136
+ * so future runs of the same command don't re-prompt for credentials. Mode
137
+ * 0600 — the JWT is bearer-equivalent. Mirrors the file format `studiograph
138
+ * join` and `studiograph clone` write so any tool that reads
139
+ * server-auth.json sees a consistent shape.
140
+ */
141
+ function persistServerAuth(workspaceRoot, serverUrl, email, jwtToken) {
142
+ const studiographDir = join(workspaceRoot, '.studiograph');
143
+ if (!existsSync(studiographDir))
144
+ mkdirSync(studiographDir, { recursive: true });
145
+ writeFileSync(join(studiographDir, 'server-auth.json'), JSON.stringify({ serverUrl, email, jwtToken }, null, 2), { encoding: 'utf-8', mode: 0o600 });
146
+ }
18
147
  async function getRepoEntries(workspace, workspaceRoot) {
19
148
  const entries = [];
20
149
  // The .studiograph config directory is itself a git repo (when GitHub-provisioned)
@@ -24,8 +153,8 @@ async function getRepoEntries(workspace, workspaceRoot) {
24
153
  }
25
154
  const config = await workspace.loadConfig();
26
155
  for (const repo of config.repos) {
27
- if (repo.private)
28
- continue; // private repos are local-only
156
+ if (repo.personal)
157
+ continue; // personal repos are local-only
29
158
  const repoPath = join(workspaceRoot, repo.path);
30
159
  if (!isGitRepo(repoPath) || !gitHasRemote(repoPath))
31
160
  continue;
@@ -42,7 +171,7 @@ function isGitRepo(path) {
42
171
  function logManualGuidance(entryPath) {
43
172
  log.info(` cd ${entryPath} && git pull --rebase`);
44
173
  }
45
- async function pullRemoteConfig(remoteUrl) {
174
+ async function pullRemoteConfig(remoteUrl, includeData = false, authOpts = {}) {
46
175
  const workspace = new Workspace();
47
176
  if (!workspace.isWorkspace()) {
48
177
  console.error('❌ Not a Studiograph workspace. Run `studiograph init` first.');
@@ -50,72 +179,50 @@ async function pullRemoteConfig(remoteUrl) {
50
179
  return;
51
180
  }
52
181
  const base = remoteUrl.replace(/\/+$/, '');
53
- // Prompt for admin credentials
54
- const email = await text({ message: 'Admin email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
55
- if (typeof email === 'symbol') {
56
- outro('Cancelled');
57
- process.exit(0);
58
- return;
59
- }
60
- const password = await passwordPrompt({ message: 'Password:' });
61
- if (typeof password === 'symbol') {
62
- outro('Cancelled');
63
- process.exit(0);
64
- return;
65
- }
66
- // Login to get session token
67
- log.info('Authenticating...');
68
- let token;
182
+ const workspaceRoot = workspace.getWorkspacePath();
183
+ const sgDir = join(workspaceRoot, '.studiograph');
184
+ // Resolve authentication (API key, email+password, env vars, or interactive prompts)
185
+ let auth;
69
186
  try {
70
- const loginRes = await fetch(`${base}/api/auth/login`, {
71
- method: 'POST',
72
- headers: { 'Content-Type': 'application/json' },
73
- body: JSON.stringify({ email, password }),
74
- });
75
- if (!loginRes.ok) {
76
- const body = await loginRes.json().catch(() => ({}));
77
- outro(`Login failed: ${body.error || loginRes.statusText}`);
78
- process.exit(1);
79
- return;
80
- }
81
- const cookies = loginRes.headers.getSetCookie?.() ?? [];
82
- const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
83
- if (!tokenCookie) {
84
- outro('Login succeeded but no session cookie was returned');
85
- process.exit(1);
86
- return;
87
- }
88
- token = tokenCookie.split(';')[0];
187
+ log.info('Authenticating...');
188
+ auth = await resolveRemoteAuth(base, workspaceRoot, authOpts);
89
189
  }
90
190
  catch (err) {
91
- outro(`Could not connect to ${base}: ${err.message}`);
191
+ outro(err.message);
92
192
  process.exit(1);
93
193
  return;
94
194
  }
95
195
  // Fetch config bundle (fall back to auth seed for older servers)
96
196
  log.info('Fetching workspace config...');
97
- const workspaceRoot = workspace.getWorkspacePath();
98
- const sgDir = join(workspaceRoot, '.studiograph');
99
197
  try {
100
198
  const bundleRes = await fetch(`${base}/api/config/bundle`, {
101
- headers: { 'Cookie': token },
199
+ headers: auth.httpHeader,
102
200
  });
103
201
  if (bundleRes.ok) {
104
202
  const bundle = await bundleRes.json();
105
- // 1. Auth seed
203
+ // 1. Auth seed — remote is authoritative for pull, so overwrite any
204
+ // local-shadow rows (e.g. post-clone setup-wizard credentials that
205
+ // would otherwise shadow the real production password_hash).
106
206
  writeFileSync(join(sgDir, 'auth-seed.json'), JSON.stringify(bundle.authSeed, null, 2), 'utf-8');
107
- const authService = new AuthService(sgDir);
108
- authService.applySeed();
207
+ // AuthService appends `.studiograph` to the path it's given —
208
+ // pass workspace root, not `sgDir`, or we end up with
209
+ // `.studiograph/.studiograph/auth.db` (disjoint from the running server).
210
+ const authService = new AuthService(workspaceRoot);
211
+ authService.applySeed({ mode: 'overwrite' });
109
212
  authService.close();
110
213
  log.success(`Team: ${bundle.authSeed.users.length} user${bundle.authSeed.users.length === 1 ? '' : 's'}`);
111
- // 2. Workspace config — merge: keep local-only fields (server_url), update shared fields
214
+ // 2. Workspace config — merge: keep local-only fields (server_url), update shared fields.
215
+ //
216
+ // Phase 9b: route through `workspace.writeConfig()` so this CLI
217
+ // pull path shares the same schema validator + dual-write seam as
218
+ // every other writer.
112
219
  if (bundle.workspace) {
113
220
  const local = await workspace.loadConfig().catch(() => ({}));
114
221
  const merged = { ...local, ...bundle.workspace };
115
222
  if (local.server_url)
116
223
  merged.server_url = local.server_url;
117
- writeFileSync(join(sgDir, 'workspace.json'), JSON.stringify(merged, null, 2), 'utf-8');
118
- log.success(`Workspace config: ${bundle.workspace.repos?.length ?? 0} collection${(bundle.workspace.repos?.length ?? 0) === 1 ? '' : 's'}`);
224
+ workspace.writeConfig(merged);
225
+ log.success(`Workspace config: ${bundle.workspace.repos?.length ?? 0} folder${(bundle.workspace.repos?.length ?? 0) === 1 ? '' : 's'}`);
119
226
  }
120
227
  // 3. ABOUT.md
121
228
  if (bundle.about !== null && bundle.about !== undefined) {
@@ -132,21 +239,33 @@ async function pullRemoteConfig(remoteUrl) {
132
239
  }
133
240
  log.success(`Sources: ${sourceNames.join(', ')}`);
134
241
  }
135
- // 5. Connectors (sanitized — no secrets)
242
+ // 5. Connectors (sanitized — no secrets).
243
+ //
244
+ // Phase 9b: route through `ConnectorManager.saveWorkspaceConfig` so
245
+ // every connector save runs the same schema validator + stripSecrets
246
+ // pass. The bundle is already sanitized server-side; the re-strip
247
+ // is idempotent and preserves the single-seam invariant.
136
248
  if (bundle.connectors && bundle.connectors.length > 0) {
137
- const connectorsDir = join(sgDir, 'connectors');
138
- mkdirSync(connectorsDir, { recursive: true });
139
249
  for (const conn of bundle.connectors) {
140
- writeFileSync(join(connectorsDir, `${conn.name}.json`), JSON.stringify(conn, null, 2), 'utf-8');
250
+ ConnectorManager.saveWorkspaceConfig(conn, workspaceRoot);
141
251
  }
142
252
  log.success(`Connectors: ${bundle.connectors.map(c => c.name).join(', ')}`);
143
253
  }
144
- outro(`Pulled config from ${base}`);
254
+ // Pull workspace data (markdown files) if requested
255
+ if (includeData) {
256
+ try {
257
+ await pullRemoteData(base, auth, workspaceRoot);
258
+ }
259
+ catch (err) {
260
+ log.error(`Data pull failed: ${err.message}`);
261
+ }
262
+ }
263
+ outro(`Pulled from ${base}${includeData ? ' (config + data)' : ' (config)'}`);
145
264
  }
146
265
  else if (bundleRes.status === 404) {
147
266
  // Older server — fall back to auth seed only
148
267
  log.info('Server does not support config bundle, falling back to auth seed...');
149
- const seedRes = await fetch(`${base}/api/auth/seed`, { headers: { 'Cookie': token } });
268
+ const seedRes = await fetch(`${base}/api/auth/seed`, { headers: auth.httpHeader });
150
269
  if (!seedRes.ok) {
151
270
  const body = await seedRes.json().catch(() => ({}));
152
271
  outro(`Failed to fetch seed: ${body.error || seedRes.statusText}`);
@@ -155,8 +274,9 @@ async function pullRemoteConfig(remoteUrl) {
155
274
  }
156
275
  const seed = await seedRes.json();
157
276
  writeFileSync(join(sgDir, 'auth-seed.json'), JSON.stringify(seed, null, 2), 'utf-8');
158
- const authService = new AuthService(sgDir);
159
- authService.applySeed();
277
+ // AuthService appends `.studiograph` — pass workspace root, not `sgDir`.
278
+ const authService = new AuthService(workspaceRoot);
279
+ authService.applySeed({ mode: 'overwrite' });
160
280
  authService.close();
161
281
  outro(`Pulled ${seed.users.length} user${seed.users.length === 1 ? '' : 's'} from ${base}`);
162
282
  }
@@ -167,17 +287,147 @@ async function pullRemoteConfig(remoteUrl) {
167
287
  }
168
288
  }
169
289
  catch (err) {
290
+ // Phase 9c: surface SchemaViolationError with its redaction-safe
291
+ // message (field path + classification, no values). The error class
292
+ // is detected by name to avoid pulling the schemas module into the
293
+ // CLI bundle import graph just for an instanceof check.
294
+ if (err?.name === 'SchemaViolationError' || err?.code === 'schema_violation') {
295
+ outro(`Schema violation:\n${err.message}`);
296
+ process.exit(1);
297
+ }
170
298
  outro(`Failed: ${err.message}`);
171
299
  process.exit(1);
172
300
  }
173
301
  }
302
+ // ─── Remote data pull (git-based) ───────────────────────────────────────────
303
+ // Clones or pulls each folder from the remote's embedded git HTTP server
304
+ // (/git/:repo). Uses git's native conflict detection — diverged folders
305
+ // are reported, not silently overwritten.
306
+ async function pullRemoteData(base, auth, workspaceRoot) {
307
+ // Reload config — it was just updated by pullRemoteConfig
308
+ const workspace = new Workspace(workspaceRoot);
309
+ const config = await workspace.loadConfig();
310
+ let cloned = 0, updated = 0, upToDate = 0, diverged = 0, errors = 0;
311
+ for (const repo of config.repos) {
312
+ if (repo.personal)
313
+ continue; // personal folders don't sync
314
+ const repoPath = join(workspaceRoot, repo.path);
315
+ const remoteUrl = `${base}/git/${repo.name}`;
316
+ // Clone if missing
317
+ if (!existsSync(join(repoPath, '.git'))) {
318
+ try {
319
+ if (existsSync(repoPath))
320
+ rmSync(repoPath, { recursive: true, force: true });
321
+ mkdirSync(repoPath, { recursive: true });
322
+ gitClone(remoteUrl, repoPath, { silent: true, credentials: auth.gitCredentials });
323
+ log.success(`${repo.name}: cloned`);
324
+ cloned++;
325
+ }
326
+ catch (err) {
327
+ log.error(`${repo.name}: clone failed — ${err.message}`);
328
+ errors++;
329
+ }
330
+ continue;
331
+ }
332
+ // Ensure remote points at the requested server (may have been cloned elsewhere)
333
+ try {
334
+ gitSetRemote(repoPath, remoteUrl);
335
+ }
336
+ catch { /* non-fatal */ }
337
+ try {
338
+ const result = gitPull(repoPath, { credentials: auth.gitCredentials });
339
+ if (result === 'updated') {
340
+ log.success(`${repo.name}: updated`);
341
+ updated++;
342
+ }
343
+ else if (result === 'up-to-date') {
344
+ upToDate++;
345
+ }
346
+ else {
347
+ log.warn(`${repo.name}: diverged — has local commits not on the server`);
348
+ log.info(` cd ${repoPath} && git pull --rebase`);
349
+ diverged++;
350
+ }
351
+ }
352
+ catch (err) {
353
+ log.error(`${repo.name}: ${err.message}`);
354
+ errors++;
355
+ }
356
+ }
357
+ log.info(`Data: ${cloned} cloned, ${updated} updated, ${upToDate} up to date${diverged ? `, ${diverged} diverged` : ''}${errors ? `, ${errors} failed` : ''}`);
358
+ if (diverged) {
359
+ throw new Error('One or more folders diverged — resolve conflicts and retry');
360
+ }
361
+ if (errors) {
362
+ throw new Error('One or more folders failed to pull');
363
+ }
364
+ }
365
+ // ─── Remote data push (git-based) ───────────────────────────────────────────
366
+ // Pushes each local folder to the remote's embedded git HTTP server.
367
+ // Uses git's native conflict detection — rejected pushes require a pull first.
368
+ async function pushRemoteData(base, auth, workspace, workspaceRoot) {
369
+ const config = await workspace.loadConfig();
370
+ let pushed = 0, nothingToPush = 0, created = 0, rejected = 0, errors = 0;
371
+ for (const repo of config.repos) {
372
+ if (repo.personal)
373
+ continue; // personal folders don't sync to a remote we don't control
374
+ const repoPath = join(workspaceRoot, repo.path);
375
+ if (!existsSync(join(repoPath, '.git'))) {
376
+ log.warn(`${repo.name}: not a git repo — skipping`);
377
+ continue;
378
+ }
379
+ try {
380
+ // Ensure folder exists on remote (idempotent; 409 means it already exists)
381
+ const status = await ensureServerFolder(base, repo.name, !!repo.personal, auth.httpHeader);
382
+ if (status === 'created') {
383
+ log.info(`${repo.name}: created on server`);
384
+ created++;
385
+ }
386
+ // Point origin at the remote's git server
387
+ gitSetRemote(repoPath, `${base}/git/${repo.name}`);
388
+ // Push with credentials
389
+ const result = gitPushWithCredentials(repoPath, auth.gitCredentials);
390
+ if (result === 'rejected') {
391
+ log.warn(`${repo.name}: push rejected — run \`studiograph pull --remote ${base} --data\` first`);
392
+ rejected++;
393
+ continue;
394
+ }
395
+ if (result === 'pushed') {
396
+ log.success(`${repo.name}: pushed`);
397
+ pushed++;
398
+ }
399
+ else {
400
+ nothingToPush++;
401
+ }
402
+ }
403
+ catch (err) {
404
+ log.error(`${repo.name}: ${err.message}`);
405
+ errors++;
406
+ }
407
+ }
408
+ log.info(`Data: ${pushed} pushed${created ? `, ${created} created` : ''}, ${nothingToPush} unchanged${rejected ? `, ${rejected} rejected` : ''}${errors ? `, ${errors} failed` : ''}`);
409
+ if (rejected) {
410
+ throw new Error('One or more folders were rejected — pull and retry');
411
+ }
412
+ if (errors) {
413
+ throw new Error('One or more folders failed to push');
414
+ }
415
+ }
174
416
  // ─── pull ─────────────────────────────────────────────────────────────────────
175
417
  export const pullCommand = new Command('pull')
176
418
  .description('Pull latest changes from remote across the workspace')
177
419
  .option('--remote <url>', 'Pull config from a remote Studiograph server')
420
+ .option('--data', 'Also pull workspace folder data (markdown files) from the remote server')
421
+ .option('--token <token>', 'Use a personal API token instead of email/password (also reads STUDIOGRAPH_TOKEN)')
422
+ .option('--email <email>', 'Email for non-interactive auth (also reads STUDIOGRAPH_EMAIL)')
423
+ .option('--password <password>', 'Password for non-interactive auth (also reads STUDIOGRAPH_PASSWORD)')
178
424
  .action(async (opts) => {
179
425
  if (opts.remote) {
180
- return pullRemoteConfig(opts.remote);
426
+ return pullRemoteConfig(opts.remote, opts.data, {
427
+ token: opts.token,
428
+ email: opts.email,
429
+ password: opts.password,
430
+ });
181
431
  }
182
432
  const workspace = new Workspace();
183
433
  if (!workspace.isWorkspace()) {
@@ -203,13 +453,21 @@ export const pullCommand = new Command('pull')
203
453
  else if (result === 'up-to-date') {
204
454
  log.info('.studiograph: already up to date');
205
455
  }
456
+ else {
457
+ // Diverged / any other non-clean state — surface it the same way
458
+ // the folder loop does so the user actually sees the problem
459
+ // instead of walking into a silent no-op.
460
+ log.warn('.studiograph: diverged — has local commits not on the server');
461
+ logManualGuidance(configPath);
462
+ hasConflict = true;
463
+ }
206
464
  }
207
465
  catch (error) {
208
466
  log.error(`.studiograph: ${error instanceof Error ? error.message : 'Unknown error'}`);
209
467
  hasError = true;
210
468
  }
211
469
  }
212
- // ── Step 2: reload config — picks up any new collections added server-side ─
470
+ // ── Step 2: reload config — picks up any new folders added server-side ─
213
471
  // Must use a fresh Workspace instance — loadConfig() caches this.config on
214
472
  // first call, so the original instance would return stale data after the pull.
215
473
  const freshWorkspace = new Workspace(workspaceRoot);
@@ -220,13 +478,12 @@ export const pullCommand = new Command('pull')
220
478
  freshWorkspace.writeConfig(config);
221
479
  }
222
480
  const serverUrl = (config.server_url ?? savedServerUrl)?.replace(/\/+$/, '');
223
- // ── Step 3: pull or clone each collection ────────────────────────────────
481
+ // ── Step 3: pull or clone each folder ────────────────────────────────
224
482
  // Resolve git credentials for the embedded server:
225
483
  // 1. Stored JWT from `studiograph join` — per-user access control (preferred)
226
- // 2. API key from auth-seed.json — admin access (fallback for workspace owners)
484
+ // 2. Stored personal API token from ~/.studiograph/user.json
227
485
  let serverGitCredentials;
228
486
  if (serverUrl) {
229
- // Try stored JWT first (saved by studiograph join)
230
487
  const serverAuthPath = join(workspaceRoot, '.studiograph', 'server-auth.json');
231
488
  if (existsSync(serverAuthPath)) {
232
489
  try {
@@ -237,29 +494,22 @@ export const pullCommand = new Command('pull')
237
494
  }
238
495
  catch { /* non-fatal */ }
239
496
  }
240
- // Fall back to API key (used by workspace owners who set up with `studiograph serve`)
241
497
  if (!serverGitCredentials) {
242
- try {
243
- const seedPath = join(workspaceRoot, '.studiograph', 'auth-seed.json');
244
- if (existsSync(seedPath)) {
245
- const seed = JSON.parse(readFileSync(seedPath, 'utf-8'));
246
- const apiKey = seed.apiKey;
247
- if (apiKey)
248
- serverGitCredentials = { username: '_apikey_', password: apiKey };
249
- }
498
+ const storedToken = getStudiographToken(serverUrl);
499
+ if (storedToken) {
500
+ serverGitCredentials = { username: '_token_', password: storedToken };
250
501
  }
251
- catch { /* non-fatal */ }
252
502
  }
253
503
  }
254
504
  for (const repo of config.repos) {
255
- if (repo.private)
505
+ if (repo.personal)
256
506
  continue;
257
507
  const repoPath = join(workspaceRoot, repo.path);
258
- // New collection — directory missing or exists but isn't a git repo (e.g. failed clone)
508
+ // New folder — directory missing or exists but isn't a git repo (e.g. failed clone)
259
509
  if (!isGitRepo(repoPath)) {
260
510
  const cloneUrl = serverUrl ? `${serverUrl}/git/${repo.name}` : null;
261
511
  if (!cloneUrl) {
262
- log.warn(`${repo.name}: new collection has no remote — skipping`);
512
+ log.warn(`${repo.name}: new folder has no remote — skipping`);
263
513
  continue;
264
514
  }
265
515
  try {
@@ -278,7 +528,7 @@ export const pullCommand = new Command('pull')
278
528
  }
279
529
  continue;
280
530
  }
281
- // Existing collection — pull if it has a remote
531
+ // Existing folder — pull if it has a remote
282
532
  if (!isGitRepo(repoPath) || !gitHasRemote(repoPath))
283
533
  continue;
284
534
  try {
@@ -300,12 +550,15 @@ export const pullCommand = new Command('pull')
300
550
  hasError = true;
301
551
  }
302
552
  }
303
- // Apply auth seed if it was updated by pulling .studiograph
553
+ // Apply auth seed if it was updated by pulling .studiograph.
554
+ // Overwrite mode: the seed file just came from the remote config repo
555
+ // and is authoritative over any local-shadow rows.
304
556
  const seedPath = join(workspaceRoot, '.studiograph', 'auth-seed.json');
305
557
  if (existsSync(seedPath)) {
306
558
  try {
307
- const authService = new AuthService(join(workspaceRoot, '.studiograph'));
308
- authService.applySeed();
559
+ // AuthService appends `.studiograph` pass workspace root.
560
+ const authService = new AuthService(workspaceRoot);
561
+ authService.applySeed({ mode: 'overwrite' });
309
562
  authService.close();
310
563
  }
311
564
  catch {
@@ -317,12 +570,12 @@ export const pullCommand = new Command('pull')
317
570
  process.exit(1);
318
571
  }
319
572
  else if (hasError) {
320
- outro('❌ Pull failed for one or more collections.');
573
+ outro('❌ Pull failed for one or more folders.');
321
574
  process.exit(1);
322
575
  }
323
576
  });
324
577
  // ─── Remote config push ─────────────────────────────────────────────────────
325
- async function pushRemoteConfig(remoteUrl) {
578
+ async function pushRemoteConfig(remoteUrl, includeData = false, authOpts = {}) {
326
579
  const workspace = new Workspace();
327
580
  if (!workspace.isWorkspace()) {
328
581
  console.error('❌ Not a Studiograph workspace. Run `studiograph init` first.');
@@ -332,45 +585,14 @@ async function pushRemoteConfig(remoteUrl) {
332
585
  const base = remoteUrl.replace(/\/+$/, '');
333
586
  const workspaceRoot = workspace.getWorkspacePath();
334
587
  const sgDir = join(workspaceRoot, '.studiograph');
335
- // Prompt for admin credentials
336
- const email = await text({ message: 'Admin email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
337
- if (typeof email === 'symbol') {
338
- outro('Cancelled');
339
- process.exit(0);
340
- return;
341
- }
342
- const password = await passwordPrompt({ message: 'Password:' });
343
- if (typeof password === 'symbol') {
344
- outro('Cancelled');
345
- process.exit(0);
346
- return;
347
- }
348
- // Login
349
- log.info('Authenticating...');
350
- let token;
588
+ // Resolve authentication (API key, email+password, env vars, or interactive prompts)
589
+ let auth;
351
590
  try {
352
- const loginRes = await fetch(`${base}/api/auth/login`, {
353
- method: 'POST',
354
- headers: { 'Content-Type': 'application/json' },
355
- body: JSON.stringify({ email, password }),
356
- });
357
- if (!loginRes.ok) {
358
- const body = await loginRes.json().catch(() => ({}));
359
- outro(`Login failed: ${body.error || loginRes.statusText}`);
360
- process.exit(1);
361
- return;
362
- }
363
- const cookies = loginRes.headers.getSetCookie?.() ?? [];
364
- const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
365
- if (!tokenCookie) {
366
- outro('Login succeeded but no session cookie was returned');
367
- process.exit(1);
368
- return;
369
- }
370
- token = tokenCookie.split(';')[0];
591
+ log.info('Authenticating...');
592
+ auth = await resolveRemoteAuth(base, workspaceRoot, authOpts);
371
593
  }
372
594
  catch (err) {
373
- outro(`Could not connect to ${base}: ${err.message}`);
595
+ outro(err.message);
374
596
  process.exit(1);
375
597
  return;
376
598
  }
@@ -402,13 +624,24 @@ async function pushRemoteConfig(remoteUrl) {
402
624
  }
403
625
  // Connectors (workspace-level, already sanitized)
404
626
  const connectors = ConnectorManager.loadWorkspaceConfigs(workspaceRoot);
405
- const bundle = { workspace: config, about, authSeed, sources, connectors };
627
+ // Phase 3: route the bundle through the same sanitizer the server's
628
+ // GET /api/config/bundle endpoint uses. CLI push and server export now
629
+ // produce byte-identical output for the same workspace state — bootstrap
630
+ // class fields (jwtSecret, deprecated apiKey) drop here so the POST
631
+ // endpoint's strict-reject doesn't bounce older client builds.
632
+ const bundle = buildConfigBundle({
633
+ workspace: config,
634
+ about,
635
+ authSeed: (authSeed ?? { users: [] }),
636
+ sources,
637
+ connectors: connectors,
638
+ });
406
639
  // Push to remote
407
640
  log.info('Pushing config...');
408
641
  try {
409
642
  const res = await fetch(`${base}/api/config/bundle`, {
410
643
  method: 'POST',
411
- headers: { 'Content-Type': 'application/json', 'Cookie': token },
644
+ headers: { ...auth.httpHeader, 'Content-Type': 'application/json' },
412
645
  body: JSON.stringify(bundle),
413
646
  });
414
647
  if (!res.ok) {
@@ -423,7 +656,16 @@ async function pushRemoteConfig(remoteUrl) {
423
656
  log.success(item);
424
657
  }
425
658
  }
426
- outro(`Pushed config to ${base}`);
659
+ // Push workspace data (markdown files) if requested
660
+ if (includeData) {
661
+ try {
662
+ await pushRemoteData(base, auth, workspace, workspaceRoot);
663
+ }
664
+ catch (err) {
665
+ log.error(`Data push failed: ${err.message}`);
666
+ }
667
+ }
668
+ outro(`Pushed to ${base}${includeData ? ' (config + data)' : ' (config)'}`);
427
669
  }
428
670
  catch (err) {
429
671
  outro(`Failed: ${err.message}`);
@@ -449,27 +691,42 @@ async function serverFetch(serverUrl, path, authHeader) {
449
691
  }
450
692
  return res.json();
451
693
  }
452
- async function ensureServerCollection(serverUrl, repoName, isPrivate, authHeader) {
694
+ async function ensureServerFolder(serverUrl, repoName, isPersonal, authHeader) {
695
+ const headers = { 'Content-Type': 'application/json' };
696
+ if (typeof authHeader === 'string') {
697
+ headers['Authorization'] = authHeader;
698
+ }
699
+ else {
700
+ Object.assign(headers, authHeader);
701
+ }
453
702
  const res = await fetch(`${serverUrl}/api/repos`, {
454
703
  method: 'POST',
455
- headers: { 'Authorization': authHeader, 'Content-Type': 'application/json' },
456
- body: JSON.stringify({ name: repoName, ...(isPrivate ? { private: true } : {}) }),
704
+ headers,
705
+ body: JSON.stringify({ name: repoName, ...(isPersonal ? { personal: true } : {}) }),
457
706
  });
458
707
  if (res.ok)
459
708
  return 'created';
460
709
  if (res.status === 409)
461
710
  return 'exists'; // already exists
462
711
  const body = await res.json().catch(() => ({}));
463
- throw new Error(body.error || `Failed to create collection "${repoName}": ${res.statusText}`);
712
+ throw new Error(body.error || `Failed to create folder "${repoName}": ${res.statusText}`);
464
713
  }
465
714
  // ─── push ─────────────────────────────────────────────────────────────────────
466
715
  export const pushCommand = new Command('push')
467
716
  .description('Push local commits to remote across the workspace')
468
- .argument('[collection]', 'Push a specific collection (default: all)')
717
+ .argument('[folder]', 'Push a specific folder (default: all)')
469
718
  .option('--remote <url>', 'Push config to a remote Studiograph server')
470
- .action(async (collection, opts) => {
719
+ .option('--data', 'Also push workspace folder data (markdown files) to the remote server')
720
+ .option('--token <token>', 'Use a personal API token instead of email/password (also reads STUDIOGRAPH_TOKEN)')
721
+ .option('--email <email>', 'Email for non-interactive auth (also reads STUDIOGRAPH_EMAIL)')
722
+ .option('--password <password>', 'Password for non-interactive auth (also reads STUDIOGRAPH_PASSWORD)')
723
+ .action(async (folder, opts) => {
471
724
  if (opts.remote) {
472
- return pushRemoteConfig(opts.remote);
725
+ return pushRemoteConfig(opts.remote, opts.data, {
726
+ token: opts.token,
727
+ email: opts.email,
728
+ password: opts.password,
729
+ });
473
730
  }
474
731
  const workspace = new Workspace();
475
732
  if (!workspace.isWorkspace()) {
@@ -480,12 +737,19 @@ export const pushCommand = new Command('push')
480
737
  const workspaceRoot = workspace.getWorkspacePath();
481
738
  const config = await workspace.loadConfig();
482
739
  const serverUrl = config.server_url?.replace(/\/+$/, '');
483
- // Build list of repos to push
484
- let repos = config.repos.filter(r => !r.private || serverUrl); // include private only when pushing to server
485
- if (collection) {
486
- const match = repos.find(r => r.name === collection);
740
+ // Build list of repos to push. Personal folders are included when
741
+ // pushing to a server they're per-user, but git-http
742
+ // (canAccessFolder → hasRepoAccess) gates by owner so only the owner
743
+ // ever succeeds. Server-side, personal folders are auto-provisioned
744
+ // on login by auth-api.ts#ensurePrivateFolder, so the per-folder
745
+ // ensureServerFolder() call is skipped for them below (the
746
+ // createSharedFolder path would reject `entries-<number>` as a
747
+ // reserved name even though the folder already exists).
748
+ let repos = config.repos.filter(r => !r.personal || serverUrl);
749
+ if (folder) {
750
+ const match = repos.find(r => r.name === folder);
487
751
  if (!match) {
488
- log.error(`Collection "${collection}" not found in workspace.`);
752
+ log.error(`Folder "${folder}" not found in workspace.`);
489
753
  process.exit(1);
490
754
  return;
491
755
  }
@@ -496,34 +760,44 @@ export const pushCommand = new Command('push')
496
760
  // Resolve credentials: JWT (per-user) → API key (admin) → prompt
497
761
  let authHeader;
498
762
  let gitCredentials;
499
- // 1. Stored JWT from `studiograph join` (per-user access control)
763
+ // 1. Stored JWT from `studiograph join` (per-user access control).
764
+ //
765
+ // Auth-header format note: the main API auth middleware (server/
766
+ // index.ts:215) accepts Basic only as `email:<password>` — it does
767
+ // NOT accept JWT-as-Basic-password. The git-http handler does
768
+ // (routes/git-http.ts authenticateBasic has explicit branches for
769
+ // `eyJ...` JWTs and `sg_...` tokens). So one stored JWT yields two
770
+ // different headers: `Bearer <jwt>` for API calls (serverFetch,
771
+ // ensureServerFolder) and Basic with JWT-as-password for git push
772
+ // (gitPushWithCredentials → askpass). Same logic for stored API
773
+ // tokens below.
500
774
  const pushServerAuthPath = join(workspaceRoot, '.studiograph', 'server-auth.json');
501
775
  try {
502
776
  if (existsSync(pushServerAuthPath)) {
503
777
  const sa = JSON.parse(readFileSync(pushServerAuthPath, 'utf-8'));
504
778
  if (sa.email && sa.jwtToken) {
505
- authHeader = makeBasicAuth(sa.email, sa.jwtToken);
779
+ authHeader = `Bearer ${sa.jwtToken}`;
506
780
  gitCredentials = { username: sa.email, password: sa.jwtToken };
507
781
  }
508
782
  }
509
783
  }
510
784
  catch { /* non-fatal */ }
511
- // 2. API key fallback (workspace owners who set up with `studiograph serve`)
512
- if (!authHeader) {
513
- try {
514
- const seedPathPush = join(workspaceRoot, '.studiograph', 'auth-seed.json');
515
- if (existsSync(seedPathPush)) {
516
- const seed = JSON.parse(readFileSync(seedPathPush, 'utf-8'));
517
- const pushApiKey = seed.apiKey;
518
- if (pushApiKey) {
519
- authHeader = makeBasicAuth('_apikey_', pushApiKey);
520
- gitCredentials = { username: '_apikey_', password: pushApiKey };
521
- }
522
- }
785
+ // 2. Stored personal API token fallback
786
+ if (!authHeader && serverUrl) {
787
+ const storedToken = getStudiographToken(serverUrl);
788
+ if (storedToken) {
789
+ authHeader = `Bearer ${storedToken}`;
790
+ gitCredentials = { username: '_token_', password: storedToken };
523
791
  }
524
- catch { /* non-fatal */ }
525
792
  }
526
- // 3. Interactive credential prompt as last resort
793
+ // 3. Interactive credential prompt as last resort. After successful
794
+ // auth, exchange the password for a JWT and persist it to
795
+ // server-auth.json so the next run skips the prompt entirely.
796
+ // Without this step, every push prompts again — the previous
797
+ // behavior used the typed password as Basic auth ad-hoc and never
798
+ // wrote the file (a real DX papercut surfaced after `studiograph
799
+ // clone` deleted server-auth.json or a Railway restart invalidated
800
+ // the JWT secret).
527
801
  if (!authHeader) {
528
802
  const email = await text({ message: 'Email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
529
803
  if (typeof email === 'symbol') {
@@ -537,8 +811,21 @@ export const pushCommand = new Command('push')
537
811
  process.exit(0);
538
812
  return;
539
813
  }
540
- authHeader = makeBasicAuth(String(email), String(pass));
541
- gitCredentials = { username: String(email), password: String(pass) };
814
+ try {
815
+ const jwtToken = await loginForJwt(serverUrl, String(email), String(pass));
816
+ persistServerAuth(workspaceRoot, serverUrl, String(email), jwtToken);
817
+ // Bearer for API calls; Basic with JWT-as-password for git push.
818
+ // See header-format note on the stored-JWT branch above.
819
+ authHeader = `Bearer ${jwtToken}`;
820
+ gitCredentials = { username: String(email), password: jwtToken };
821
+ }
822
+ catch (err) {
823
+ // Surface the underlying auth failure rather than silently
824
+ // falling through with bogus basic-auth that'll fail later.
825
+ outro(`Authentication failed: ${err.message}`);
826
+ process.exit(1);
827
+ return;
828
+ }
542
829
  }
543
830
  // All three branches above either set credentials or exit — this is a safety guard
544
831
  if (!authHeader || !gitCredentials) {
@@ -546,14 +833,60 @@ export const pushCommand = new Command('push')
546
833
  process.exit(1);
547
834
  return;
548
835
  }
549
- // Validate credentials
836
+ // Validate credentials. If a stored JWT or token has been
837
+ // invalidated (Railway restart that regenerated the JWT secret,
838
+ // server-side token revoke, etc.), fall through to the interactive
839
+ // prompt instead of exiting — typing email+password should always
840
+ // be a viable last resort. We bound the retry to one attempt so
841
+ // bad credentials don't loop forever.
842
+ let validated = false;
550
843
  try {
551
844
  await serverFetch(serverUrl, '/api/workspace', authHeader);
845
+ validated = true;
552
846
  }
553
847
  catch (err) {
554
- outro(`Authentication failed: ${err.message}`);
555
- process.exit(1);
556
- return;
848
+ // Stored credential failed. Clear it so the next run can't loop
849
+ // on the same stale value, then drop to a fresh prompt below.
850
+ try {
851
+ rmSync(pushServerAuthPath, { force: true });
852
+ }
853
+ catch { /* non-fatal */ }
854
+ }
855
+ if (!validated) {
856
+ log.warn('Stored credentials rejected — re-authenticate.');
857
+ const email = await text({ message: 'Email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
858
+ if (typeof email === 'symbol') {
859
+ outro('Cancelled');
860
+ process.exit(0);
861
+ return;
862
+ }
863
+ const pass = await passwordPrompt({ message: 'Password:' });
864
+ if (typeof pass === 'symbol') {
865
+ outro('Cancelled');
866
+ process.exit(0);
867
+ return;
868
+ }
869
+ try {
870
+ const jwtToken = await loginForJwt(serverUrl, String(email), String(pass));
871
+ persistServerAuth(workspaceRoot, serverUrl, String(email), jwtToken);
872
+ // Bearer for API calls; Basic with JWT-as-password for git push.
873
+ // See header-format note on the stored-JWT branch above.
874
+ authHeader = `Bearer ${jwtToken}`;
875
+ gitCredentials = { username: String(email), password: jwtToken };
876
+ }
877
+ catch (err) {
878
+ outro(`Authentication failed: ${err.message}`);
879
+ process.exit(1);
880
+ return;
881
+ }
882
+ try {
883
+ await serverFetch(serverUrl, '/api/workspace', authHeader);
884
+ }
885
+ catch (err) {
886
+ outro(`Authentication failed: ${err.message}`);
887
+ process.exit(1);
888
+ return;
889
+ }
557
890
  }
558
891
  let hasError = false;
559
892
  for (const repo of repos) {
@@ -562,11 +895,24 @@ export const pushCommand = new Command('push')
562
895
  log.warn(`${repo.name}: not a git repo, skipping`);
563
896
  continue;
564
897
  }
898
+ // Personal folders skip the /api/repos POST. Detection has TWO
899
+ // sources because `studiograph clone` strips the `personal: true`
900
+ // flag from cloned workspace.json (alongside r2_config and
901
+ // railway — see memory:studiograph_clone_strips_config). So we
902
+ // also infer from the reserved name pattern: anything matching
903
+ // `entries-<digit>` is owned by the user with that id and was
904
+ // auto-provisioned server-side via auth-api.ts#ensurePrivateFolder
905
+ // on login. The /api/repos path goes through createSharedFolder
906
+ // which rejects this exact pattern; the git push that follows
907
+ // hits git-http directly where canAccessFolder gates by owner.
908
+ const isPersonalByPattern = /^entries-\d+$/.test(repo.name);
909
+ const skipServerFolderEnsure = !!repo.personal || isPersonalByPattern;
565
910
  try {
566
- // Ensure collection exists on server
567
- const status = await ensureServerCollection(serverUrl, repo.name, !!repo.private, authHeader);
568
- if (status === 'created') {
569
- log.info(`${repo.name}: created on server`);
911
+ if (!skipServerFolderEnsure) {
912
+ const status = await ensureServerFolder(serverUrl, repo.name, false, authHeader);
913
+ if (status === 'created') {
914
+ log.info(`${repo.name}: created on server`);
915
+ }
570
916
  }
571
917
  // Set origin to server git URL
572
918
  gitSetRemote(repoPath, `${serverUrl}/git/${repo.name}`);
@@ -598,12 +944,12 @@ export const pushCommand = new Command('push')
598
944
  // Fallback: plain git push for repos that already have remotes
599
945
  const entries = await getRepoEntries(workspace, workspaceRoot);
600
946
  if (entries.length === 0) {
601
- log.info('No collections with remotes to push to. Use `studiograph join` to connect to a server.');
947
+ log.info('No folders with remotes to push to. Use `studiograph join` to connect to a server.');
602
948
  return;
603
949
  }
604
950
  let hasError = false;
605
951
  for (const entry of entries) {
606
- if (collection && entry.name !== collection)
952
+ if (folder && entry.name !== folder)
607
953
  continue;
608
954
  try {
609
955
  let result = gitPush(entry.path);
@@ -625,7 +971,7 @@ export const pushCommand = new Command('push')
625
971
  }
626
972
  }
627
973
  if (hasError) {
628
- outro('Push failed for one or more collections.');
974
+ outro('Push failed for one or more folders.');
629
975
  process.exit(1);
630
976
  }
631
977
  });