@xopcai/xopc 0.0.189 → 0.0.190

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 (347) hide show
  1. package/README.md +0 -3
  2. package/README.zh-CN.md +0 -3
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store-DTFKTPs8.js → activity-store-DstnJCS5.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DqO25Qe5.js → agent-avatar-dicebear-9vAbkroX.js} +1 -1
  7. package/dist/gateway/static/root/assets/agents-D1t4SfMQ.js +68 -0
  8. package/dist/gateway/static/root/assets/{api-DWeXfwVU.js → api-BTL9kayv.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-BRpV8PXG.js → app-management-settings-panel-DkFeIdBf.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-3ntKM9nQ.js → appearance-settings-Bxs8Fpaj.js} +1 -1
  11. package/dist/gateway/static/root/assets/apps-page-Cgrgu5OW.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-Df7Ycj_7.js → archive-plugin-Ch2RmLCC.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-UHgfZYtj.js → attachment-load-BhMQM_Ky.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-page-CtJxstKh.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-BJah99wE.js → binary-plugins-D6CqlymH.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-DNlY5KqF.js → block-editor-ClL6HEg9.js} +48 -48
  17. package/dist/gateway/static/root/assets/browser-settings-page-DW99iDmD.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-vyUfdzAd.js → browser-workflow-inputs-BYy48VhN.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-C1cKZjx-.js → browser-workflows-page-zgLibuMH.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-CHUrT9EB.js +7 -0
  21. package/dist/gateway/static/root/assets/capability-presets-api-BB8t4Ja7.js +1 -0
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Cycrv0YV.js +1 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-BGG2kpJB.js → channel-recipient-api-BThDGiO3.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-V96gPUAU.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-Cz7SAAkm.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-api-DS9ED-EL.js +1 -0
  27. package/dist/gateway/static/root/assets/connectors-page-BhlyQoQI.js +2 -0
  28. package/dist/gateway/static/root/assets/cron-expression-CkgsvhtW.js +2 -0
  29. package/dist/gateway/static/root/assets/{desktop-pet-BUuBEJuP.js → desktop-pet-Cv8rGhYW.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-BGfVIJM3.js → desktop-pet-settings-CIeJdwfV.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-DrQFfHH_.js → directory-picker-path-field-D8jXEiAY.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-CEnIFOX-.js → extension-debug-page-CCZ9u6TZ.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-CCqHbexs.js → extension-page-CV36ILRG.js} +1 -1
  34. package/dist/gateway/static/root/assets/extension-settings-page-IyQrSILY.js +1 -0
  35. package/dist/gateway/static/root/assets/{gateway-config-api-CgUE2Ii1.js → gateway-config-api-D4_r5iJM.js} +1 -1
  36. package/dist/gateway/static/root/assets/gateway-settings-CYlntpBH.js +1 -0
  37. package/dist/gateway/static/root/assets/{gateway-startup-retry-DxhKNiCF.js → gateway-startup-retry-EO9mKvzE.js} +1 -1
  38. package/dist/gateway/static/root/assets/heartbeat-settings-D4SyWob8.js +1 -0
  39. package/dist/gateway/static/root/assets/home-page-B2Kagoh8.js +3 -0
  40. package/dist/gateway/static/root/assets/{image-generation-api-DCFdc-HD.js → image-generation-api-Bu7PyVSh.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-CYT5DOzr.js +150 -0
  42. package/dist/gateway/static/root/assets/index-D6e3tPL-.css +1 -0
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Bf2VLtXW.js → keyboard-shortcuts-settings-BMhCuVBZ.js} +1 -1
  44. package/dist/gateway/static/root/assets/local-app-workbench-page-BHYbFjqy.js +2 -0
  45. package/dist/gateway/static/root/assets/{local-apps-page-Ca1RuI13.js → local-apps-page-ijIe7_y2.js} +1 -1
  46. package/dist/gateway/static/root/assets/locale-store-deR2zRaE.js +1 -0
  47. package/dist/gateway/static/root/assets/logs-page-IIn8Tess.js +2 -0
  48. package/dist/gateway/static/root/assets/{management-settings-B3Eop1zn.js → management-settings--V_fovKD.js} +1 -1
  49. package/dist/gateway/static/root/assets/{markdown-split-BGOYjgnM.js → markdown-split-Dt9-in6W.js} +1 -1
  50. package/dist/gateway/static/root/assets/{media-plugins-CT0txyM4.js → media-plugins-B3pj_iO0.js} +1 -1
  51. package/dist/gateway/static/root/assets/messages-B4XqB8I6.js +3 -0
  52. package/dist/gateway/static/root/assets/{notes-page-DfKgAe78.js → notes-page-DZ366lIT.js} +1 -1
  53. package/dist/gateway/static/root/assets/notes-workbench-S2sBVOLw.js +4 -0
  54. package/dist/gateway/static/root/assets/{page-tabs-DNrbCgmC.js → page-tabs-C5ge434C.js} +1 -1
  55. package/dist/gateway/static/root/assets/{preview-open-alternatives-BTqViDOR.js → preview-open-alternatives-BFa9DgSV.js} +1 -1
  56. package/dist/gateway/static/root/assets/{product-open-page-C_2L4_Iu.js → product-open-page-Dc9CcWdu.js} +1 -1
  57. package/dist/gateway/static/root/assets/project-detail-page-BilzoCJ7.js +1 -0
  58. package/dist/gateway/static/root/assets/projects-page-BoQUyacP.js +1 -0
  59. package/dist/gateway/static/root/assets/remote-access-hub-DUyUaCRF.js +1 -0
  60. package/dist/gateway/static/root/assets/{schema-form-BFLfkDGG.js → schema-form-B84DckWe.js} +1 -1
  61. package/dist/gateway/static/root/assets/sessions-page-Dzxlq1F0.js +1 -0
  62. package/dist/gateway/static/root/assets/settings-advanced-gate-TzwlZxU6.js +1 -0
  63. package/dist/gateway/static/root/assets/settings-form-section-Dp9itvdy.js +1 -0
  64. package/dist/gateway/static/root/assets/{settings-loading-skeleton-C9a-EbTZ.js → settings-loading-skeleton-CCtlhoy7.js} +1 -1
  65. package/dist/gateway/static/root/assets/{settings-page-DI9qDH5x.js → settings-page-DQmMKf8r.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-layout-D-LWQdI5.js → settings-page-layout-EQIOJa_L.js} +1 -1
  67. package/dist/gateway/static/root/assets/{setup-status-panel-CJwmPvgs.js → setup-status-panel-Cwi-SPja.js} +1 -1
  68. package/dist/gateway/static/root/assets/{share-preview-page-BKSMG9r5.js → share-preview-page-C4_B2jvf.js} +1 -1
  69. package/dist/gateway/static/root/assets/shares-settings-CkyuGlZK.js +1 -0
  70. package/dist/gateway/static/root/assets/skill-reload-api-BJCePQK5.js +1 -0
  71. package/dist/gateway/static/root/assets/skills-page-BYWLfmJi.js +2 -0
  72. package/dist/gateway/static/root/assets/{skills-page.utils-zsz2HIlZ.js → skills-page.utils-Jhm24i4h.js} +1 -1
  73. package/dist/gateway/static/root/assets/{system-settings-panel-IWNDBI1O.js → system-settings-panel-Dpx2ags2.js} +1 -1
  74. package/dist/gateway/static/root/assets/{task-detail-page-CgtK02kP.js → task-detail-page-DLAdxI6e.js} +1 -1
  75. package/dist/gateway/static/root/assets/{theme-store-BkJe7UDo.js → theme-store-DnBOcGXi.js} +1 -1
  76. package/dist/gateway/static/root/assets/{typed-models-lib-C07LGthO.js → typed-models-lib-DULmTHUB.js} +1 -1
  77. package/dist/gateway/static/root/assets/use-autosave-BrjVk5VH.js +1 -0
  78. package/dist/gateway/static/root/assets/user-context-page-9AAFpGAL.js +1 -0
  79. package/dist/gateway/static/root/assets/{voice-api-key-field-Boue1D46.js → voice-api-key-field-BISTPfq_.js} +1 -1
  80. package/dist/gateway/static/root/assets/{work-discovery-overlay-bbmvCmc8.js → work-discovery-overlay-Wr-uF7VA.js} +1 -1
  81. package/dist/gateway/static/root/assets/work-discovery-page-BWds95sL.js +1 -0
  82. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DlHv-GZC.js → workflow-run-setup-panel-DHqHP8_6.js} +2 -2
  83. package/dist/gateway/static/root/assets/workflows-page-0b4_DFHr.js +11 -0
  84. package/dist/gateway/static/root/index.html +7 -7
  85. package/dist/package.js +1 -1
  86. package/dist/packages/gateway-contract/src/tool-activity.js +0 -36
  87. package/dist/packages/realtime-client/src/index.js +105 -48
  88. package/dist/packages/realtime-protocol/src/index.js +6 -1
  89. package/dist/src/agent/agent-manager.d.ts +0 -1
  90. package/dist/src/agent/agent-manager.js +6 -13
  91. package/dist/src/agent/background-review/coordinator.js +1 -1
  92. package/dist/src/agent/background-review/run-background-review.js +5 -7
  93. package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +0 -1
  94. package/dist/src/agent/bootstrap/bootstrap-cache.js +3 -4
  95. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +0 -4
  96. package/dist/src/agent/bootstrap/bootstrap-files.js +3 -4
  97. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -4
  98. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +0 -1
  99. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -14
  100. package/dist/src/agent/bootstrap/types.d.ts +1 -1
  101. package/dist/src/agent/context/workspace-templates/SOUL.md +1 -1
  102. package/dist/src/agent/memory/builtin-provider.d.ts +2 -4
  103. package/dist/src/agent/memory/builtin-provider.js +35 -15
  104. package/dist/src/agent/memory/context/types.d.ts +3 -1
  105. package/dist/src/agent/memory/create-memory-manager.js +2 -0
  106. package/dist/src/agent/memory/index.d.ts +1 -1
  107. package/dist/src/agent/memory/index.js +1 -1
  108. package/dist/src/agent/memory/manager.d.ts +9 -1
  109. package/dist/src/agent/memory/manager.js +39 -9
  110. package/dist/src/agent/memory/memory-config.d.ts +1 -1
  111. package/dist/src/agent/memory/memory-config.js +1 -1
  112. package/dist/src/agent/memory/source-origin.js +0 -2
  113. package/dist/src/agent/memory/types.d.ts +5 -1
  114. package/dist/src/agent/memory/understanding/service.d.ts +10 -10
  115. package/dist/src/agent/memory/understanding/service.js +108 -176
  116. package/dist/src/agent/memory/understanding/types.d.ts +7 -8
  117. package/dist/src/agent/memory/user-context-coordinator.d.ts +2 -1
  118. package/dist/src/agent/memory/user-context-coordinator.js +27 -41
  119. package/dist/src/agent/orchestration/agent-orchestrator.js +4 -7
  120. package/dist/src/agent/prompt/sections/memory-skills.js +4 -4
  121. package/dist/src/agent/prompt/sections/tooling.js +0 -10
  122. package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
  123. package/dist/src/agent/prompt/service-prompt-builder.js +4 -33
  124. package/dist/src/agent/prompt/system-prompt.js +1 -2
  125. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  126. package/dist/src/agent/service.d.ts +1 -2
  127. package/dist/src/agent/service.js +4 -17
  128. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +1 -1
  129. package/dist/src/agent/tools/dreaming-tool.d.ts +0 -2
  130. package/dist/src/agent/tools/dreaming-tool.js +13 -38
  131. package/dist/src/agent/tools/factory.d.ts +0 -3
  132. package/dist/src/agent/tools/factory.js +1 -10
  133. package/dist/src/agent/tools/index.d.ts +0 -1
  134. package/dist/src/agent/tools/index.js +1 -2
  135. package/dist/src/agent/tools/memory-tool.js +1 -1
  136. package/dist/src/agent/workspace-runtime/registry.d.ts +3 -5
  137. package/dist/src/agent/workspace-runtime/registry.js +2 -15
  138. package/dist/src/agent-manifest/schema.d.ts +17 -17
  139. package/dist/src/agent-runtime/index.js +1 -1
  140. package/dist/src/agent-runtime/memory-runtime.d.ts +2 -2
  141. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  142. package/dist/src/automations/domain/validation.d.ts +28 -28
  143. package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -3
  144. package/dist/src/chat-commands/builtins/understanding.js +2 -5
  145. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  146. package/dist/src/cli/commands/init.js +3 -22
  147. package/dist/src/cli/templates.js +1 -1
  148. package/dist/src/config/index.js +3 -3
  149. package/dist/src/config/paths.d.ts +0 -5
  150. package/dist/src/config/paths.js +2 -11
  151. package/dist/src/config/schema.d.ts +24 -117
  152. package/dist/src/config/schema.js +9 -39
  153. package/dist/src/connectors/learning-coordinator.js +75 -3
  154. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  155. package/dist/src/gateway/agent-builtin-tools.js +0 -5
  156. package/dist/src/gateway/agents-admin.d.ts +0 -7
  157. package/dist/src/gateway/agents-admin.js +3 -32
  158. package/dist/src/gateway/dreaming-automation-reconciler.d.ts +3 -3
  159. package/dist/src/gateway/dreaming-automation-reconciler.js +48 -88
  160. package/dist/src/gateway/hono/lib/config-payload.d.ts +19 -7
  161. package/dist/src/gateway/hono/lib/config-payload.js +3 -1
  162. package/dist/src/gateway/hono/oauth-async.d.ts +1 -0
  163. package/dist/src/gateway/hono/oauth-async.js +17 -2
  164. package/dist/src/gateway/hono/routes/agents.js +1 -33
  165. package/dist/src/gateway/hono/routes/config-patch/misc.js +17 -1
  166. package/dist/src/gateway/hono/routes/connectors.js +13 -12
  167. package/dist/src/gateway/hono/routes/index.js +2 -2
  168. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -5
  169. package/dist/src/gateway/hono/routes/status.js +0 -7
  170. package/dist/src/gateway/hono/routes/understanding-sources.d.ts +3 -0
  171. package/dist/src/gateway/hono/routes/understanding-sources.js +203 -0
  172. package/dist/src/gateway/hono/routes/work-discovery.d.ts +2 -0
  173. package/dist/src/gateway/hono/routes/work-discovery.js +3 -134
  174. package/dist/src/gateway/hono/routes/you.d.ts +0 -22
  175. package/dist/src/gateway/hono/routes/you.js +234 -1118
  176. package/dist/src/gateway/service/config-coordinator.d.ts +1 -1
  177. package/dist/src/gateway/service/run-gateway-agent.js +2 -4
  178. package/dist/src/knowledge/connected-knowledge-pipeline.js +1 -1
  179. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +2 -4
  180. package/dist/src/knowledge/connected-understanding-pipeline.js +31 -81
  181. package/dist/src/knowledge/index.js +2 -2
  182. package/dist/src/knowledge/people-graph.d.ts +22 -25
  183. package/dist/src/knowledge/people-graph.js +76 -43
  184. package/dist/src/proactive/execution/context.js +8 -13
  185. package/dist/src/realtime/broker.d.ts +1 -0
  186. package/dist/src/realtime/broker.js +19 -2
  187. package/dist/src/realtime/runtime.js +6 -1
  188. package/dist/src/storage/sqlite/connector-account-repository.js +0 -1
  189. package/dist/src/storage/sqlite/context-consolidation-repository.d.ts +37 -0
  190. package/dist/src/storage/sqlite/context-consolidation-repository.js +64 -0
  191. package/dist/src/storage/sqlite/fts.d.ts +2 -0
  192. package/dist/src/storage/sqlite/fts.js +29 -1
  193. package/dist/src/storage/sqlite/index.d.ts +4 -6
  194. package/dist/src/storage/sqlite/index.js +5 -7
  195. package/dist/src/storage/sqlite/knowledge-repository.d.ts +9 -2
  196. package/dist/src/storage/sqlite/knowledge-repository.js +58 -10
  197. package/dist/src/storage/sqlite/memory-records-repository.d.ts +7 -56
  198. package/dist/src/storage/sqlite/memory-records-repository.js +68 -218
  199. package/dist/src/storage/sqlite/migrations/113_memory_evidence_single_source.sql +54 -0
  200. package/dist/src/storage/sqlite/migrations/114_user_context_domain.sql +193 -0
  201. package/dist/src/storage/sqlite/migrations/115_remove_legacy_user_context.sql +6 -0
  202. package/dist/src/storage/sqlite/migrations/116_structured_context_consolidation.sql +38 -0
  203. package/dist/src/storage/sqlite/migrations/117_unified_understanding_sources.sql +110 -0
  204. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  205. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  206. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  207. package/dist/src/storage/sqlite/schema.js +1 -1
  208. package/dist/src/storage/sqlite/schema.sql +0 -20
  209. package/dist/src/storage/sqlite/user-context-quality-repository.d.ts +34 -0
  210. package/dist/src/storage/sqlite/user-context-quality-repository.js +74 -0
  211. package/dist/src/storage/sqlite/user-context-repository.d.ts +64 -0
  212. package/dist/src/storage/sqlite/user-context-repository.js +383 -0
  213. package/dist/src/tui/tool-summary.js +1 -7
  214. package/dist/src/tui/tui-startup-resources.js +1 -2
  215. package/dist/src/user-context/config.d.ts +17 -210
  216. package/dist/src/user-context/config.js +19 -85
  217. package/dist/src/user-context/consolidation.d.ts +26 -0
  218. package/dist/src/user-context/consolidation.js +115 -0
  219. package/dist/src/user-context/domain.d.ts +75 -0
  220. package/dist/src/user-context/domain.js +4 -0
  221. package/dist/src/user-context/manual-understanding.d.ts +7 -14
  222. package/dist/src/user-context/manual-understanding.js +19 -54
  223. package/dist/src/{agent/memory/context → user-context}/planner.d.ts +5 -6
  224. package/dist/src/user-context/planner.js +311 -0
  225. package/dist/src/user-context/relationship-continuity.d.ts +3 -6
  226. package/dist/src/user-context/relationship-continuity.js +39 -32
  227. package/dist/src/user-context/sources/catalog.d.ts +2 -0
  228. package/dist/src/user-context/sources/catalog.js +149 -0
  229. package/dist/src/user-context/sources/index.d.ts +3 -0
  230. package/dist/src/user-context/sources/index.js +3 -0
  231. package/dist/src/user-context/sources/repository.d.ts +40 -0
  232. package/dist/src/user-context/sources/repository.js +164 -0
  233. package/dist/src/user-context/sources/types.d.ts +83 -0
  234. package/dist/src/work-discovery/analyzer.d.ts +4 -3
  235. package/dist/src/work-discovery/analyzer.js +21 -16
  236. package/dist/src/work-discovery/incremental-repository.js +42 -40
  237. package/dist/src/work-discovery/index.js +3 -3
  238. package/dist/src/work-discovery/service.d.ts +7 -7
  239. package/dist/src/work-discovery/service.js +241 -190
  240. package/dist/src/work-discovery/source-repository.js +42 -53
  241. package/dist/src/work-discovery/types.d.ts +2 -14
  242. package/package.json +3 -8
  243. package/dist/gateway/static/root/assets/agents-BvdqdER9.js +0 -2
  244. package/dist/gateway/static/root/assets/apps-page-nKLsfy6C.js +0 -1
  245. package/dist/gateway/static/root/assets/automations-page-Dh5bdZiN.js +0 -6
  246. package/dist/gateway/static/root/assets/browser-settings-page-CRJ_nAuh.js +0 -8
  247. package/dist/gateway/static/root/assets/capabilities-settings-panel-DeQR5BZt.js +0 -7
  248. package/dist/gateway/static/root/assets/capability-presets-api-D7tkhDMv.js +0 -1
  249. package/dist/gateway/static/root/assets/capability-presets-settings-panel-D7uK3q1p.js +0 -1
  250. package/dist/gateway/static/root/assets/channels-settings-Bw6Dniyq.js +0 -1
  251. package/dist/gateway/static/root/assets/channels-status-swr-BrUTz4uU.js +0 -1
  252. package/dist/gateway/static/root/assets/connector-logo-8YU53RUT.js +0 -1
  253. package/dist/gateway/static/root/assets/connectors-page-k9tMiOL5.js +0 -2
  254. package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +0 -2
  255. package/dist/gateway/static/root/assets/extension-settings-page-DEZw_7zN.js +0 -1
  256. package/dist/gateway/static/root/assets/gateway-settings-Dg8qCiIp.js +0 -1
  257. package/dist/gateway/static/root/assets/heartbeat-settings-27tRzDEo.js +0 -1
  258. package/dist/gateway/static/root/assets/home-page-VA511kMr.js +0 -3
  259. package/dist/gateway/static/root/assets/index-BvR-i-m6.js +0 -216
  260. package/dist/gateway/static/root/assets/index-zybP34zk.css +0 -1
  261. package/dist/gateway/static/root/assets/local-app-workbench-page-CaJq4-wV.js +0 -2
  262. package/dist/gateway/static/root/assets/locale-store-DUW5YE3R.js +0 -1
  263. package/dist/gateway/static/root/assets/logs-page-BLTCg69e.js +0 -2
  264. package/dist/gateway/static/root/assets/messages-CMjnbdbn.js +0 -3
  265. package/dist/gateway/static/root/assets/notes-workbench-Bp1w9UM1.js +0 -4
  266. package/dist/gateway/static/root/assets/project-detail-page-CZmbPDQN.js +0 -1
  267. package/dist/gateway/static/root/assets/projects-page-D5pzqfm5.js +0 -1
  268. package/dist/gateway/static/root/assets/remote-access-hub-CC-XhVGI.js +0 -1
  269. package/dist/gateway/static/root/assets/segmented-styles-BL8oLBEp.js +0 -1
  270. package/dist/gateway/static/root/assets/sessions-page-B2eTLVDV.js +0 -1
  271. package/dist/gateway/static/root/assets/settings-advanced-gate-CRuZ_bl0.js +0 -1
  272. package/dist/gateway/static/root/assets/settings-form-section-C4GXGeA4.js +0 -1
  273. package/dist/gateway/static/root/assets/shares-settings-YzSDS4G_.js +0 -1
  274. package/dist/gateway/static/root/assets/skill-reload-api-CwOo8zZk.js +0 -1
  275. package/dist/gateway/static/root/assets/skills-page-xd1cgSGN.js +0 -2
  276. package/dist/gateway/static/root/assets/time-picker-CstQ___Y.js +0 -1
  277. package/dist/gateway/static/root/assets/use-save-bar-registration-CQYE0l6z.js +0 -1
  278. package/dist/gateway/static/root/assets/user-context-page-BnQAWS_B.js +0 -1
  279. package/dist/gateway/static/root/assets/work-discovery-page-CAszL1y8.js +0 -1
  280. package/dist/gateway/static/root/assets/workflows-page-DxGzo3-x.js +0 -11
  281. package/dist/src/agent/code-intelligence/binary.d.ts +0 -15
  282. package/dist/src/agent/code-intelligence/binary.js +0 -372
  283. package/dist/src/agent/code-intelligence/index.d.ts +0 -4
  284. package/dist/src/agent/code-intelligence/index.js +0 -4
  285. package/dist/src/agent/code-intelligence/runtime.d.ts +0 -34
  286. package/dist/src/agent/code-intelligence/runtime.js +0 -280
  287. package/dist/src/agent/code-intelligence/tool-gating.d.ts +0 -5
  288. package/dist/src/agent/code-intelligence/tool-gating.js +0 -6
  289. package/dist/src/agent/code-intelligence/tools.d.ts +0 -6
  290. package/dist/src/agent/code-intelligence/tools.js +0 -266
  291. package/dist/src/agent/code-intelligence/types.d.ts +0 -22
  292. package/dist/src/agent/memory/context/planner.js +0 -286
  293. package/dist/src/agent/memory/dreaming/config.d.ts +0 -48
  294. package/dist/src/agent/memory/dreaming/config.js +0 -98
  295. package/dist/src/agent/memory/dreaming/constants.d.ts +0 -12
  296. package/dist/src/agent/memory/dreaming/constants.js +0 -18
  297. package/dist/src/agent/memory/dreaming/deep-promotion.d.ts +0 -19
  298. package/dist/src/agent/memory/dreaming/deep-promotion.js +0 -152
  299. package/dist/src/agent/memory/dreaming/light-sweep.d.ts +0 -16
  300. package/dist/src/agent/memory/dreaming/light-sweep.js +0 -115
  301. package/dist/src/agent/memory/dreaming/preview.d.ts +0 -23
  302. package/dist/src/agent/memory/dreaming/preview.js +0 -52
  303. package/dist/src/agent/memory/dreaming/promotion-lifecycle.d.ts +0 -16
  304. package/dist/src/agent/memory/dreaming/promotion-lifecycle.js +0 -44
  305. package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +0 -19
  306. package/dist/src/agent/memory/dreaming/rem-patterns.js +0 -150
  307. package/dist/src/agent/memory/dreaming/runner.d.ts +0 -10
  308. package/dist/src/agent/memory/dreaming/runner.js +0 -78
  309. package/dist/src/agent/memory/dreaming/schedule.d.ts +0 -23
  310. package/dist/src/agent/memory/dreaming/schedule.js +0 -38
  311. package/dist/src/agent/memory/dreaming/scope.d.ts +0 -11
  312. package/dist/src/agent/memory/dreaming/scope.js +0 -33
  313. package/dist/src/agent/memory/dreaming/utils.d.ts +0 -3
  314. package/dist/src/agent/memory/dreaming/utils.js +0 -31
  315. package/dist/src/gateway/hono/routes/memory.d.ts +0 -3
  316. package/dist/src/gateway/hono/routes/memory.js +0 -460
  317. package/dist/src/storage/sqlite/dreaming-repository.d.ts +0 -61
  318. package/dist/src/storage/sqlite/dreaming-repository.js +0 -88
  319. package/dist/src/storage/sqlite/memory-readiness-repository.d.ts +0 -7
  320. package/dist/src/storage/sqlite/memory-readiness-repository.js +0 -30
  321. package/dist/src/storage/sqlite/memory-reference-consent-repository.d.ts +0 -27
  322. package/dist/src/storage/sqlite/memory-reference-consent-repository.js +0 -107
  323. package/dist/src/storage/sqlite/user-claims-repository.d.ts +0 -101
  324. package/dist/src/storage/sqlite/user-claims-repository.js +0 -241
  325. package/dist/src/storage/sqlite/user-profile-setup-repository.d.ts +0 -3
  326. package/dist/src/storage/sqlite/user-profile-setup-repository.js +0 -32
  327. package/dist/src/user-context/actionableInsights.d.ts +0 -14
  328. package/dist/src/user-context/actionableInsights.js +0 -34
  329. package/dist/src/user-context/context-compiler.d.ts +0 -27
  330. package/dist/src/user-context/context-compiler.js +0 -48
  331. package/dist/src/user-context/import.d.ts +0 -12
  332. package/dist/src/user-context/import.js +0 -51
  333. package/dist/src/user-context/memory-episode-evaluator.d.ts +0 -32
  334. package/dist/src/user-context/memory-episode-evaluator.js +0 -35
  335. package/dist/src/user-context/memory-readiness.d.ts +0 -33
  336. package/dist/src/user-context/memory-readiness.js +0 -41
  337. package/dist/src/user-context/memory-use-audit.d.ts +0 -10
  338. package/dist/src/user-context/memory-use-audit.js +0 -26
  339. package/dist/src/user-context/personal-playbook.d.ts +0 -11
  340. package/dist/src/user-context/personal-playbook.js +0 -41
  341. package/dist/src/user-context/profile.d.ts +0 -37
  342. package/dist/src/user-context/profile.js +0 -163
  343. package/dist/src/user-context/projection.d.ts +0 -120
  344. package/dist/src/user-context/projection.js +0 -262
  345. package/dist/src/user-context/source-recommendations.d.ts +0 -13
  346. package/dist/src/user-context/source-recommendations.js +0 -85
  347. /package/dist/src/{agent/code-intelligence → user-context/sources}/types.js +0 -0
@@ -1,1167 +1,283 @@
1
- import { runSqliteWriteTransaction } from "../../../storage/sqlite/transaction.js";
2
- import { getDreamingRun, listDreamingDecisions, listDreamingRuns } from "../../../storage/sqlite/dreaming-repository.js";
3
- import { getUserClaim, linkUserClaimMemoryRecord, listUserClaimEvidence, listUserClaimStatsBySource, listUserClaims, removeUserClaimEvidenceForSource, setUserClaimDecision } from "../../../storage/sqlite/user-claims-repository.js";
4
- import { listConnectorLearningJobs } from "../../../storage/sqlite/connector-learning-repository.js";
5
- import { setInteractionState } from "../../../storage/sqlite/interaction-state-repository.js";
6
- import { getRelationshipSettings, updateRelationshipSettings } from "../../../storage/sqlite/relationship-settings-repository.js";
7
- import { deleteMemoryRecord, getMemoryRecord, getMemoryTurnFeedback, listMemoryRecords, listMemorySignals, setMemoryTurnFeedback, upsertMemoryRecord } from "../../../storage/sqlite/memory-records-repository.js";
8
- import { listKnowledgeSourceItems, listKnowledgeSyncRuns } from "../../../storage/sqlite/knowledge-repository.js";
9
- import { listConnectorConnections } from "../../../storage/sqlite/connector-repository.js";
10
- import { getConnectorAccount } from "../../../storage/sqlite/connector-account-repository.js";
11
- import { USER_TRUST_LEVELS, isUserTrustLevel } from "../../../user-context/trust-policy.js";
12
- import { getUserTrustPolicy, setUserTrustPolicy } from "../../../storage/sqlite/user-trust-repository.js";
13
- import { decideMemoryReferenceConsent, listMemoryReferenceConsents, revokeMemoryReferenceConsent } from "../../../storage/sqlite/memory-reference-consent-repository.js";
14
- import { getUserProfilePromptState, setUserProfilePromptState } from "../../../storage/sqlite/user-profile-setup-repository.js";
1
+ import { listContextConsolidationRuns } from "../../../storage/sqlite/context-consolidation-repository.js";
2
+ import { createCollaborationRule, createUnderstanding, decideContextConsent, deleteCollaborationRule, deleteUnderstanding, getCollaborationRule, getTurnPersonalization, getUnderstanding, getUserProfile, listCollaborationRules, listUnderstandingEvidence, listUnderstandings, recordContextFeedback, rejectUnderstanding, reviseCollaborationRule, reviseUnderstanding, setCollaborationRuleStatus, setUnderstandingStatus, updateUserProfile } from "../../../storage/sqlite/user-context-repository.js";
15
3
  import "../../../storage/sqlite/index.js";
16
- import { DreamingSettingsSchema, UserContextConfigSchema, init_config } from "../../../user-context/config.js";
17
- import { init_agent_scope, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
18
- import { TaskRepository } from "../../../tasks/task-repository.js";
19
- import { revokeComposioConnection } from "../../../connectors/composio.js";
20
- import { listConnectorCatalog } from "../../../connectors/catalog.js";
21
- import { nextDreamingRunTimes } from "../../../agent/memory/dreaming/schedule.js";
22
- import { resolveDreamingSettings } from "../../../agent/memory/dreaming/config.js";
23
- import { readUserProfileFile, writeUserProfileFile } from "../../agents-admin.js";
24
- import { TaskContextRepository } from "../../../tasks/task-context-repository.js";
25
- import "../../../tasks/index.js";
26
- import { nextMemoryReviewAt } from "../../../agent/memory/lifecycle.js";
27
- import { isUserContextMemoryKind, isUserContextRecord, projectPersonalContextSources, projectUserContextRecord, recordsDerivedFromPersonalContextSource } from "../../../user-context/projection.js";
28
- import { PERSONAL_PLAYBOOK_DISABLED_TAG, PERSONAL_PLAYBOOK_ORDER_PREFIX, PERSONAL_PLAYBOOK_RULE_TAG, patchPersonalPlaybookContextTags, personalPlaybookContext } from "../../../user-context/personal-playbook.js";
29
- import { INSIGHT_ACCEPTED_TAG, INSIGHT_DISMISSED_TAG, USER_CONFIRMED_MEMORY_TAG, buildActionableInsightSuggestions } from "../../../user-context/actionableInsights.js";
30
- import { createManualUnderstanding } from "../../../user-context/manual-understanding.js";
31
- import { resolveDreamingAgentScope } from "../../../agent/memory/dreaming/scope.js";
32
- import { runDreamingPhase } from "../../../agent/memory/dreaming/runner.js";
33
- import { listConnectorInstances } from "../../../connectors/instances.js";
34
- import { uninstallConnector } from "../../../connectors/install.js";
35
- import { renderUserClaim } from "../../../knowledge/connected-understanding-pipeline.js";
36
- import { prepareUserContextImport } from "../../../user-context/import.js";
37
- import { buildUserProfileSetup, parseUserProfileMarkdown, patchUserProfileMarkdown } from "../../../user-context/profile.js";
38
- import { buildTaskSourceRecommendations } from "../../../user-context/source-recommendations.js";
4
+ import { userInfo } from "node:os";
5
+ import { createHash } from "node:crypto";
39
6
  //#region src/gateway/hono/routes/you.ts
40
- init_agent_scope();
41
- init_config();
42
- const VISIBLE_STATUSES = new Set([
43
- "active",
44
- "candidate",
45
- "needs_review"
7
+ const UNDERSTANDING_KINDS = new Set([
8
+ "preference",
9
+ "boundary",
10
+ "relationship",
11
+ "routine",
12
+ "current_state",
13
+ "long_term_goal",
14
+ "project_context",
15
+ "task_lesson",
16
+ "derived_insight"
46
17
  ]);
47
- const FEEDBACK_RATINGS = new Set([
48
- "helpful",
49
- "not_helpful",
50
- "mixed",
51
- "irrelevant",
52
- "incorrect",
53
- "outdated",
54
- "sensitive"
55
- ]);
56
- const PLAYBOOK_IDS = [
57
- "communication",
58
- "execution",
59
- "routines"
60
- ];
61
- const PLAYBOOK_SUPPORT_NEEDS = new Set([
62
- "listen",
63
- "clarify",
64
- "advise",
65
- "act",
66
- "unknown"
67
- ]);
68
- const PROFILE_FIELD_LIMITS = {
69
- callName: 80,
70
- pronouns: 80,
71
- timezone: 100,
72
- notes: 5e3
73
- };
74
- const PROFILE_PROMPT_SNOOZE_MS = 10080 * 60 * 1e3;
75
- const ALL_MEMORY_STATUSES = [
18
+ const UNDERSTANDING_STATUSES = new Set([
76
19
  "candidate",
77
20
  "active",
78
21
  "needs_review",
79
22
  "stale",
80
23
  "archived",
81
24
  "rejected"
82
- ];
83
- const MEMORY_SENSITIVITIES = new Set([
84
- "normal",
85
- "personal",
86
- "secret",
87
- "regulated"
88
25
  ]);
89
- const MEMORY_DURABILITIES = new Set([
90
- "ephemeral",
91
- "durable",
92
- "recurring"
26
+ const RULE_CATEGORIES = new Set([
27
+ "communication",
28
+ "execution",
29
+ "boundary",
30
+ "routine",
31
+ "proactive"
93
32
  ]);
94
- const MEMORY_DISCLOSURE_POLICIES = new Set([
95
- "silent",
96
- "referenceable",
97
- "ask_before_reference"
33
+ const RULE_STATUSES = new Set([
34
+ "active",
35
+ "disabled",
36
+ "archived"
98
37
  ]);
99
- function listAllUserContextRecords(statuses) {
100
- return statuses.flatMap((status) => {
101
- const records = [];
102
- let offset = 0;
103
- while (true) {
104
- const page = listMemoryRecords({
105
- status,
106
- limit: 500,
107
- offset
108
- });
109
- records.push(...page);
110
- if (page.length < 500) break;
111
- offset += page.length;
112
- }
113
- return records;
114
- });
115
- }
116
- function projectReferenceConsent(consent, record) {
117
- return {
118
- id: consent.id,
119
- recordId: consent.recordId,
120
- sessionKey: consent.sessionKey,
121
- purpose: consent.purpose,
122
- statement: record.content,
123
- sourceName: record.source.provider ?? "local",
124
- status: consent.status,
125
- grantScope: consent.grantScope,
126
- expiresAt: consent.expiresAt,
127
- createdAt: consent.createdAt,
128
- updatedAt: consent.updatedAt
129
- };
38
+ const FEEDBACK_RATINGS = new Set([
39
+ "helpful",
40
+ "irrelevant",
41
+ "wrong",
42
+ "stale",
43
+ "sensitive"
44
+ ]);
45
+ function asRecord(value) {
46
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
130
47
  }
131
- function buildConflictGroups(records) {
132
- const groups = /* @__PURE__ */ new Map();
133
- for (const record of records) {
134
- if (!record.conflictGroupId) continue;
135
- const group = groups.get(record.conflictGroupId) ?? [];
136
- group.push(record);
137
- groups.set(record.conflictGroupId, group);
48
+ async function readBody(c) {
49
+ try {
50
+ return asRecord(await c.req.json());
51
+ } catch {
52
+ return;
138
53
  }
139
- return [...groups.entries()].filter(([, group]) => group.length > 1 && group.some((record) => VISIBLE_STATUSES.has(record.status))).map(([id, group]) => ({
140
- id,
141
- records: group.sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt)).map((record) => ({
142
- ...projectUserContextRecord(record),
143
- storedStatus: record.status
144
- })),
145
- unresolved: group.filter((record) => VISIBLE_STATUSES.has(record.status)).length > 1
146
- }));
147
- }
148
- async function readProfileBundle(config) {
149
- const result = await readUserProfileFile();
150
- const profileContent = result.ok ? result.data.content : "";
151
- const profile = parseUserProfileMarkdown(profileContent);
152
- return {
153
- profileContent,
154
- profile,
155
- profileSetup: buildUserProfileSetup({
156
- profile,
157
- promptState: getUserProfilePromptState(),
158
- config
159
- })
160
- };
161
54
  }
162
- function parseProfilePatch(body) {
163
- if (!body || typeof body !== "object" || Array.isArray(body)) return { error: "Invalid profile patch" };
164
- const record = body;
165
- const patch = {};
166
- for (const field of Object.keys(PROFILE_FIELD_LIMITS)) {
167
- if (!(field in record)) continue;
168
- if (typeof record[field] !== "string") return { error: `${field} must be a string` };
169
- const value = record[field].trim();
170
- if (value.length > PROFILE_FIELD_LIMITS[field]) return { error: `${field} is too long` };
171
- patch[field] = value;
172
- }
173
- return Object.keys(patch).length > 0 ? { patch } : { error: "No profile fields provided" };
55
+ function nonEmptyString(value, max = 2e3) {
56
+ if (typeof value !== "string") return void 0;
57
+ const result = value.trim();
58
+ return result && result.length <= max ? result : void 0;
174
59
  }
175
- function playbookForRecord(record) {
176
- if (!record.tags?.includes("playbook:rule")) return void 0;
177
- if (record.kind === "preference" || record.kind === "boundary" || record.kind === "tool_preference") return "communication";
178
- if (record.kind === "task_lesson" || record.kind === "derived_insight") return "execution";
179
- if (record.kind === "routine") return "routines";
60
+ function scopeFrom(value) {
61
+ const raw = asRecord(value);
62
+ const type = raw?.type;
63
+ if (type !== "global" && type !== "workspace" && type !== "project" && type !== "session") return void 0;
64
+ if (type === "global") return { type };
65
+ const id = nonEmptyString(raw.id, 500);
66
+ return id ? {
67
+ type,
68
+ id
69
+ } : void 0;
180
70
  }
181
- function playbookRuleOrder(record) {
182
- const tag = record.tags?.find((value) => value.startsWith(PERSONAL_PLAYBOOK_ORDER_PREFIX));
183
- const parsed = tag ? Number.parseInt(tag.slice(PERSONAL_PLAYBOOK_ORDER_PREFIX.length), 10) : NaN;
184
- return Number.isFinite(parsed) ? parsed : 1e3;
71
+ function canonicalKey(kind, statement) {
72
+ const normalized = statement.toLocaleLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
73
+ return `${kind}:${createHash("sha256").update(normalized).digest("hex").slice(0, 20)}`;
185
74
  }
186
- function patchPlaybookRuleTags(record, patch) {
187
- let tags = (record.tags ?? []).filter((tag) => !tag.startsWith(PERSONAL_PLAYBOOK_ORDER_PREFIX));
188
- if (patch.enabled === true) tags = tags.filter((tag) => tag !== PERSONAL_PLAYBOOK_DISABLED_TAG);
189
- if (patch.enabled === false) tags.push(PERSONAL_PLAYBOOK_DISABLED_TAG);
190
- if (patch.order !== void 0) tags.push(`${PERSONAL_PLAYBOOK_ORDER_PREFIX}${patch.order}`);
191
- return [...new Set(tags)];
75
+ function sameScope(left, right) {
76
+ return left.type === right.type && left.id === right.id;
192
77
  }
193
- function parsePlaybookContext(value) {
194
- if (value === void 0) return { context: {} };
195
- if (!value || typeof value !== "object" || Array.isArray(value)) return { error: "context must be an object" };
196
- const input = value;
197
- const context = {};
198
- if ("channel" in input) {
199
- if (input.channel !== null && (typeof input.channel !== "string" || !/^[a-z0-9_-]{1,40}$/i.test(input.channel))) return { error: "context.channel is invalid" };
200
- context.channel = input.channel === null ? void 0 : String(input.channel);
201
- }
202
- if ("supportNeed" in input) {
203
- if (input.supportNeed !== null && !PLAYBOOK_SUPPORT_NEEDS.has(String(input.supportNeed))) return { error: "context.supportNeed is invalid" };
204
- context.supportNeed = input.supportNeed === null ? void 0 : input.supportNeed;
78
+ function validTimezone(value) {
79
+ if (!value) return true;
80
+ try {
81
+ new Intl.DateTimeFormat("en", { timeZone: value }).format();
82
+ return true;
83
+ } catch {
84
+ return false;
205
85
  }
206
- return { context };
207
- }
208
- function buildPersonalPlaybooks(records) {
209
- return PLAYBOOK_IDS.map((id) => {
210
- const rules = records.filter((record) => record.status === "active" && playbookForRecord(record) === id).sort((left, right) => playbookRuleOrder(left) - playbookRuleOrder(right) || left.updatedAt.localeCompare(right.updatedAt));
211
- return {
212
- id,
213
- enabled: rules.some((record) => !record.tags?.includes(PERSONAL_PLAYBOOK_DISABLED_TAG)),
214
- rules: rules.map((record) => ({
215
- id: record.id,
216
- statement: record.content,
217
- origin: record.explicitness,
218
- enabled: !record.tags?.includes(PERSONAL_PLAYBOOK_DISABLED_TAG),
219
- order: playbookRuleOrder(record),
220
- context: personalPlaybookContext(record),
221
- versions: playbookVersionChain(records, record.id).map((version) => ({
222
- id: version.id,
223
- statement: version.content,
224
- updatedAt: version.updatedAt,
225
- current: version.id === record.id
226
- }))
227
- })),
228
- updatedAt: rules.map((record) => record.updatedAt).sort().at(-1)
229
- };
230
- });
231
- }
232
- function buildRoutineAutomationDraftHref(record) {
233
- return `/automations?${new URLSearchParams({
234
- draft: record.content,
235
- autogenerate: "1",
236
- insight: record.id
237
- }).toString()}`;
238
- }
239
- function selectedAgentId(config) {
240
- return resolveDefaultAgentId(config);
241
- }
242
- function editableRecord(recordId) {
243
- const record = getMemoryRecord(recordId);
244
- if (!record || !VISIBLE_STATUSES.has(record.status) || !isUserContextRecord(record)) return null;
245
- return record;
246
86
  }
247
- function memoryRecordInput(record) {
248
- return {
249
- providerId: record.providerId,
250
- kind: record.kind,
251
- userId: record.scope.userId,
252
- sourceAgentId: record.provenance.sourceAgentId,
253
- workspaceId: record.scope.workspaceId,
254
- sessionKey: record.scope.sessionKey,
255
- projectId: record.scope.projectId,
256
- content: record.content,
257
- source: record.source,
258
- confidence: record.confidence,
259
- tags: record.tags,
260
- status: record.status,
261
- sensitivity: record.sensitivity,
262
- canonicalKey: record.canonicalKey,
263
- explicitness: record.explicitness,
264
- durability: record.durability,
265
- importance: record.importance,
266
- disclosurePolicy: record.disclosurePolicy,
267
- evidence: record.evidence,
268
- reviewAfter: record.reviewAfter,
269
- expiresAt: record.expiresAt,
270
- validFrom: record.validFrom,
271
- validTo: record.validTo,
272
- supersedesRecordId: record.supersedesRecordId,
273
- conflictGroupId: record.conflictGroupId
274
- };
275
- }
276
- function preserveRecord(record, patch) {
277
- return upsertMemoryRecord({
278
- ...memoryRecordInput(record),
279
- ...patch,
280
- id: record.id
281
- });
282
- }
283
- function playbookVersionChain(records, recordId) {
284
- const relatedIds = new Set([recordId]);
285
- let previousSize = 0;
286
- while (previousSize !== relatedIds.size) {
287
- previousSize = relatedIds.size;
288
- for (const record of records) {
289
- if (!record.supersedesRecordId) continue;
290
- if (relatedIds.has(record.id) || relatedIds.has(record.supersedesRecordId)) {
291
- relatedIds.add(record.id);
292
- relatedIds.add(record.supersedesRecordId);
293
- }
294
- }
87
+ function machineCallName() {
88
+ try {
89
+ const username = userInfo().username.trim();
90
+ return [
91
+ "root",
92
+ "admin",
93
+ "administrator",
94
+ "user"
95
+ ].includes(username.toLocaleLowerCase()) ? "" : username.slice(0, 100);
96
+ } catch {
97
+ return "";
295
98
  }
296
- return records.filter((record) => relatedIds.has(record.id) && playbookForRecord(record) !== void 0).sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt));
297
- }
298
- function versionPlaybookRule(record, patch) {
299
- return upsertMemoryRecord({
300
- ...memoryRecordInput(record),
301
- ...patch,
302
- status: "active",
303
- supersedesRecordId: record.id,
304
- source: {
305
- provider: "local",
306
- path: "you://playbook/version"
307
- }
308
- });
309
99
  }
310
100
  function registerYouRoutes(authenticated, deps) {
311
- authenticated.get("/api/you", async (c) => {
312
- const config = deps.service.currentConfig;
313
- const agentId = selectedAgentId(config);
314
- const profileBundle = await readProfileBundle(config);
315
- const allUserContextRecords = listAllUserContextRecords(ALL_MEMORY_STATUSES).filter(isUserContextRecord);
316
- const records = allUserContextRecords.filter((record) => VISIBLE_STATUSES.has(record.status));
317
- const recordById = new Map(allUserContextRecords.map((record) => [record.id, record]));
318
- const consents = listMemoryReferenceConsents();
319
- const trustPolicy = getUserTrustPolicy();
320
- const sourceDefinitions = listConnectorCatalog();
321
- const sourceInstances = listConnectorInstances(config);
322
- const sources = projectPersonalContextSources(sourceDefinitions, sourceInstances, {
323
- sourceItems: listKnowledgeSourceItems({ limit: 500 }),
324
- syncRuns: listKnowledgeSyncRuns({ limit: 500 }),
325
- connections: listConnectorConnections({ principalId: "local-owner" }),
326
- learningJobs: listConnectorLearningJobs({ limit: 500 }),
327
- claimStatsBySource: listUserClaimStatsBySource()
328
- });
329
- const openTasks = new TaskRepository().list({ limit: 500 }).filter((task) => task.delegateAgentId === agentId && task.phase !== "closed");
330
- const activeTasks = openTasks.slice(0, 20).map((task) => {
331
- return {
332
- id: task.id,
333
- title: task.title,
334
- body: task.body
335
- };
336
- });
337
- return c.json({
338
- scope: {
339
- profile: "global",
340
- memory: "global",
341
- trust: "global"
342
- },
343
- ...profileBundle,
344
- understanding: records.map(projectUserContextRecord),
345
- connectedClaims: listUserClaims({
346
- agentId,
347
- limit: 100
348
- }).map((claim) => ({
349
- ...claim,
350
- evidence: listUserClaimEvidence(claim.id)
351
- })),
352
- consentRequests: consents.filter((consent) => consent.status === "pending").flatMap((consent) => {
353
- const record = recordById.get(consent.recordId);
354
- return record ? [projectReferenceConsent(consent, record)] : [];
355
- }),
356
- referenceGrants: consents.filter((consent) => consent.status === "granted" && (!consent.expiresAt || Date.parse(consent.expiresAt) > Date.now())).flatMap((consent) => {
357
- const record = recordById.get(consent.recordId);
358
- return record ? [projectReferenceConsent(consent, record)] : [];
359
- }),
360
- conflictGroups: buildConflictGroups(allUserContextRecords),
361
- insights: buildActionableInsightSuggestions(records, openTasks.map((task) => [task.title, task.body].filter(Boolean).join("\n"))).map((insight) => ({
362
- ...insight,
363
- delegateAgentId: agentId
364
- })),
365
- playbooks: buildPersonalPlaybooks(allUserContextRecords),
366
- sources,
367
- sourceRecommendations: buildTaskSourceRecommendations(sourceDefinitions, new Set(sourceInstances.map((instance) => instance.connectorId)), activeTasks),
368
- controls: {
369
- mode: config.userContext.memory.mode,
370
- sensitiveWritePolicy: config.userContext.privacy.sensitiveWritePolicy
371
- },
372
- relationship: getRelationshipSettings(),
373
- trust: {
374
- defaultActionLevel: trustPolicy.defaultActionLevel,
375
- levels: USER_TRUST_LEVELS,
376
- autoRequiresExplicitOptIn: true
377
- }
378
- });
379
- });
380
- authenticated.get("/api/you/feedback/:turnId", (c) => {
381
- const trace = getMemoryTurnFeedback(c.req.param("turnId"));
382
- if (!trace) return c.json({ error: "Turn context not found" }, 404);
383
- const personalContext = trace.selectedRecordIds.map((id) => getMemoryRecord(id)).filter((record) => Boolean(record) && isUserContextRecord(record)).map(projectUserContextRecord);
384
- return c.json({
385
- trace,
386
- personalContext
387
- });
388
- });
389
- authenticated.put("/api/you/feedback/:turnId", deps.strictRateLimitMiddleware, async (c) => {
390
- const body = await c.req.json().catch(() => null);
391
- if (!body || typeof body !== "object" || Array.isArray(body)) return c.json({ error: "Invalid feedback" }, 400);
392
- const input = body;
393
- if (typeof input.rating !== "string" || !FEEDBACK_RATINGS.has(input.rating)) return c.json({ error: "Invalid rating" }, 400);
394
- const records = Array.isArray(input.records) ? input.records.flatMap((value) => {
395
- if (!value || typeof value !== "object" || Array.isArray(value)) return [];
396
- const item = value;
397
- if (typeof item.recordId !== "string" || typeof item.rating !== "string" || !FEEDBACK_RATINGS.has(item.rating)) return [];
398
- return [{
399
- recordId: item.recordId,
400
- rating: item.rating,
401
- ...typeof item.reasonCode === "string" ? { reasonCode: item.reasonCode } : {},
402
- ...typeof item.note === "string" ? { note: item.note } : {}
403
- }];
404
- }) : void 0;
405
- const trace = setMemoryTurnFeedback({
406
- turnId: c.req.param("turnId"),
407
- rating: input.rating,
408
- source: "user",
409
- ...typeof input.score === "number" ? { score: input.score } : {},
410
- ...typeof input.reasonCode === "string" ? { reasonCode: input.reasonCode } : {},
411
- ...typeof input.note === "string" ? { note: input.note } : {},
412
- ...records ? { records } : {}
413
- });
414
- if (!trace) return c.json({ error: "Turn context not found" }, 404);
415
- if (trace.sessionKey && input.rating === "not_helpful" && input.reasonCode === "tone_mismatch") setInteractionState({
416
- sessionKey: trace.sessionKey,
417
- signal: {
418
- supportNeed: "unknown",
419
- confidence: 1,
420
- source: "explicit",
421
- repairStatus: "needed",
422
- repairReason: "tone_mismatch"
423
- }
424
- });
425
- const personalContext = trace.selectedRecordIds.map((id) => getMemoryRecord(id)).filter((record) => Boolean(record) && isUserContextRecord(record)).map(projectUserContextRecord);
426
- return c.json({
427
- trace,
428
- personalContext
429
- });
430
- });
431
- authenticated.get("/api/you/dreaming", (c) => {
432
- const config = deps.service.currentConfig;
433
- const scope = resolveDreamingAgentScope(config);
434
- const settings = resolveDreamingSettings(config);
435
- const signals = listMemorySignals({
436
- workspaceId: scope.workspaceDir,
437
- limit: 500
438
- });
439
- return c.json({
440
- agentId: scope.agentId,
441
- settings,
442
- config: {
443
- ...scope.config,
444
- phases: {
445
- light: {
446
- ...scope.config.phases.light,
447
- nextRunsAt: nextDreamingRunTimes(scope.config.phases.light.schedule, scope.config.timezone)
448
- },
449
- deep: {
450
- ...scope.config.phases.deep,
451
- nextRunsAt: nextDreamingRunTimes(scope.config.phases.deep.schedule, scope.config.timezone)
452
- },
453
- rem: {
454
- ...scope.config.phases.rem,
455
- nextRunsAt: nextDreamingRunTimes(scope.config.phases.rem.schedule, scope.config.timezone)
456
- }
457
- }
458
- },
459
- readiness: scope.readiness,
460
- runs: listDreamingRuns({
461
- agentId: scope.agentId,
462
- limit: 50
463
- }),
464
- signalCount: signals.filter((signal) => signal.source === "dreaming").length
465
- });
466
- });
467
- authenticated.put("/api/you/dreaming", deps.strictRateLimitMiddleware, async (c) => {
468
- const config = deps.service.currentConfig;
469
- const body = await c.req.json().catch(() => ({}));
470
- const settings = DreamingSettingsSchema.safeParse(body);
471
- if (!settings.success) return c.json({ error: settings.error.issues[0]?.message ?? "Invalid Dreaming settings" }, 400);
472
- const currentPhases = config.userContext.dreaming.phases ?? {};
473
- const parsed = UserContextConfigSchema.safeParse({
474
- ...config.userContext,
475
- dreaming: {
476
- ...config.userContext.dreaming,
477
- mode: settings.data.mode,
478
- timezone: settings.data.timezone,
479
- phases: {
480
- light: {
481
- ...currentPhases.light,
482
- ...settings.data.phases.light
483
- },
484
- deep: {
485
- ...currentPhases.deep,
486
- ...settings.data.phases.deep
487
- },
488
- rem: {
489
- ...currentPhases.rem,
490
- ...settings.data.phases.rem
491
- }
492
- }
493
- }
494
- });
495
- if (!parsed.success) return c.json({ error: parsed.error.issues[0]?.message ?? "Invalid Dreaming settings" }, 400);
496
- const saved = await deps.service.saveConfig({
497
- ...config,
498
- userContext: parsed.data
499
- });
500
- if (!saved.saved) return c.json({ error: saved.error ?? "save failed" }, 500);
501
- const savedConfig = deps.service.currentConfig;
502
- return c.json({ settings: resolveDreamingSettings(savedConfig) });
503
- });
504
- authenticated.get("/api/you/readiness", (c) => {
505
- return c.json(resolveDreamingAgentScope(deps.service.currentConfig).readiness);
506
- });
507
- authenticated.post("/api/you/dreaming/runs", deps.strictRateLimitMiddleware, async (c) => {
508
- const body = await c.req.json().catch(() => ({}));
509
- const phase = body.phase === "light" || body.phase === "deep" || body.phase === "rem" ? body.phase : "deep";
510
- try {
511
- const result = await runDreamingPhase({
512
- config: deps.service.currentConfig,
513
- phase,
514
- triggerKind: "manual"
515
- });
516
- return c.json(result);
517
- } catch (error) {
518
- return c.json({ error: error instanceof Error ? error.message : String(error) }, 400);
519
- }
520
- });
521
- authenticated.get("/api/you/dreaming/runs/:runId", (c) => {
522
- const scope = resolveDreamingAgentScope(deps.service.currentConfig);
523
- const run = getDreamingRun(c.req.param("runId"));
524
- if (!run || run.agentId !== scope.agentId || run.workspaceId !== scope.workspaceDir) return c.json({ error: "Dreaming run not found" }, 404);
101
+ const write = deps.strictRateLimitMiddleware;
102
+ authenticated.get("/api/you", (c) => c.json({
103
+ profile: getUserProfile(),
104
+ understandings: listUnderstandings(),
105
+ rules: listCollaborationRules(),
106
+ consolidation: { lastRun: listContextConsolidationRuns(1)[0] ?? null }
107
+ }));
108
+ authenticated.get("/api/you/profile", (c) => {
109
+ const profile = getUserProfile();
525
110
  return c.json({
526
- run,
527
- decisions: listDreamingDecisions(run.runId)
111
+ profile,
112
+ suggestedCallName: profile.callName || machineCallName()
528
113
  });
529
114
  });
530
- authenticated.patch("/api/you/relationship", deps.strictRateLimitMiddleware, async (c) => {
531
- const body = await c.req.json().catch(() => null);
532
- if (!body || typeof body !== "object" || Array.isArray(body)) return c.json({ error: "Invalid relationship settings" }, 400);
533
- const input = body;
115
+ authenticated.patch("/api/you/profile", write, async (c) => {
116
+ const body = await readBody(c);
117
+ if (!body) return c.json({ error: "Invalid JSON" }, 400);
534
118
  const patch = {};
535
- if ("supportMode" in input) {
536
- if (![
537
- "efficient",
538
- "coach",
539
- "companion",
540
- "auto"
541
- ].includes(String(input.supportMode))) return c.json({ error: "Invalid supportMode" }, 400);
542
- patch.supportMode = input.supportMode;
543
- }
544
- if ("proactiveEnabled" in input) {
545
- if (typeof input.proactiveEnabled !== "boolean") return c.json({ error: "proactiveEnabled must be boolean" }, 400);
546
- patch.proactiveEnabled = input.proactiveEnabled;
547
- }
548
- for (const field of ["quietStart", "quietEnd"]) {
549
- if (!(field in input)) continue;
550
- const value = input[field];
551
- if (value !== null && (typeof value !== "string" || !/^([01]\d|2[0-3]):[0-5]\d$/.test(value))) return c.json({ error: `${field} must use HH:mm` }, 400);
552
- patch[field] = value === null ? void 0 : String(value);
119
+ for (const field of [
120
+ "callName",
121
+ "role",
122
+ "primaryGoal",
123
+ "pronouns",
124
+ "timezone",
125
+ "locale"
126
+ ]) {
127
+ if (body[field] === void 0) continue;
128
+ const max = field === "primaryGoal" ? 500 : field === "role" ? 300 : 100;
129
+ if (typeof body[field] !== "string" || body[field].length > max) return c.json({ error: `${field} must be a string of at most ${max} characters` }, 400);
130
+ patch[field] = body[field].trim();
553
131
  }
554
- for (const field of ["allowedTopics", "blockedTopics"]) {
555
- if (!(field in input)) continue;
556
- if (!Array.isArray(input[field]) || input[field].length > 20 || input[field].some((value) => typeof value !== "string" || !value.trim() || value.length > 80)) return c.json({ error: `${field} must contain up to 20 short topics` }, 400);
557
- patch[field] = [...new Set(input[field].map((value) => value.trim()))];
558
- }
559
- if (Object.keys(patch).length === 0) return c.json({ error: "No relationship settings provided" }, 400);
560
- return c.json({
561
- ok: true,
562
- relationship: updateRelationshipSettings(patch)
563
- });
564
- });
565
- authenticated.patch("/api/you/claims/:id", deps.strictRateLimitMiddleware, async (c) => {
566
- const body = await c.req.json().catch(() => ({}));
567
- const action = body.action === "confirm" || body.action === "reject" ? body.action : void 0;
568
- if (!action) return c.json({ error: "Action must be confirm or reject" }, 400);
569
- const claim = runSqliteWriteTransaction(() => {
570
- const updated = setUserClaimDecision(c.req.param("id"), action === "confirm" ? "confirmed" : "rejected");
571
- if (!updated) return updated;
572
- const existing = updated.memoryRecordId ? getMemoryRecord(updated.memoryRecordId) : void 0;
573
- if (existing) preserveRecord(existing, {
574
- status: action === "confirm" ? "active" : "rejected",
575
- ...action === "confirm" ? { reviewAfter: nextMemoryReviewAt(existing) } : {}
576
- });
577
- else if (action === "confirm") {
578
- const candidate = renderUserClaim(updated);
579
- const evidence = listUserClaimEvidence(updated.id);
580
- const record = upsertMemoryRecord({
581
- providerId: "local",
582
- kind: candidate.kind,
583
- sourceAgentId: updated.agentId,
584
- content: candidate.content,
585
- canonicalKey: candidate.canonicalKey,
586
- source: { provider: "connected-sources" },
587
- confidence: 1,
588
- status: "active",
589
- sensitivity: candidate.sensitivity,
590
- explicitness: "explicit",
591
- durability: candidate.durability,
592
- importance: candidate.importance,
593
- disclosurePolicy: candidate.disclosurePolicy,
594
- tags: [...new Set([
595
- "user-understanding",
596
- ...candidate.tags ?? [],
597
- USER_CONFIRMED_MEMORY_TAG
598
- ])],
599
- evidence: evidence.map((item) => ({
600
- sourceItemId: item.sourceItemId,
601
- relation: item.relation === "contradicts" ? "contradicts" : "supports",
602
- observedAt: item.observedAt,
603
- confidence: updated.confidence
604
- })),
605
- reviewAfter: nextMemoryReviewAt({
606
- durability: candidate.durability,
607
- explicitness: "explicit"
608
- })
609
- });
610
- linkUserClaimMemoryRecord(updated.id, record.id);
611
- }
612
- return getUserClaim(updated.id);
613
- });
614
- if (!claim) return c.json({ error: "Connected claim not found" }, 404);
615
- return c.json({
616
- ok: true,
617
- claim: {
618
- ...claim,
619
- evidence: listUserClaimEvidence(claim.id)
620
- }
621
- });
622
- });
623
- authenticated.get("/api/you/profile", async (c) => {
624
- return c.json(await readProfileBundle(deps.service.currentConfig));
625
- });
626
- authenticated.get("/api/you/export", async (c) => {
627
- const config = deps.service.currentConfig;
628
- const profileBundle = await readProfileBundle(config);
629
- const understanding = listAllUserContextRecords(ALL_MEMORY_STATUSES).filter(isUserContextRecord).map((record) => ({
630
- statement: record.content,
631
- kind: record.kind,
632
- status: record.status,
633
- sensitivity: record.sensitivity ?? "normal",
634
- durability: record.durability,
635
- disclosurePolicy: record.disclosurePolicy,
636
- sourceName: record.source.provider ?? "local",
637
- updatedAt: record.updatedAt
638
- }));
639
- return c.json({
640
- version: 2,
641
- exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
642
- profile: profileBundle.profile,
643
- understanding
644
- });
645
- });
646
- authenticated.post("/api/you/import", deps.strictRateLimitMiddleware, async (c) => {
647
- const body = await c.req.json().catch(() => null);
648
- if (!body || typeof body !== "object" || Array.isArray(body) || body.version !== 2 || !Array.isArray(body.understanding)) return c.json({ error: "Invalid About You export" }, 400);
649
- if (body.understanding.length > 500) return c.json({ error: "Import is limited to 500 understandings" }, 400);
650
- const config = deps.service.currentConfig;
651
- const agentId = selectedAgentId(config);
652
- const existingStatements = listAllUserContextRecords(ALL_MEMORY_STATUSES).filter(isUserContextRecord).map((record) => record.content);
653
- const { imports, skippedCount } = prepareUserContextImport(body.understanding, existingStatements);
654
- runSqliteWriteTransaction(() => {
655
- for (const item of imports) upsertMemoryRecord({
656
- providerId: "local",
657
- kind: item.kind,
658
- sourceAgentId: agentId,
659
- content: item.statement,
660
- source: {
661
- provider: "local",
662
- path: "import://about-you"
663
- },
664
- confidence: 1,
665
- tags: ["user-understanding", "user-import"],
666
- status: "candidate",
667
- sensitivity: item.sensitivity,
668
- explicitness: "explicit",
669
- durability: item.durability,
670
- importance: .7,
671
- disclosurePolicy: item.disclosurePolicy
672
- });
673
- });
674
- return c.json({
675
- ok: true,
676
- importedCount: imports.length,
677
- skippedCount
678
- });
679
- });
680
- authenticated.post("/api/you/understanding", deps.strictRateLimitMiddleware, async (c) => {
681
- const body = await c.req.json().catch(() => ({}));
682
- const content = typeof body.content === "string" ? body.content.trim() : "";
683
- const kind = isUserContextMemoryKind(body.kind) ? body.kind : void 0;
684
- if (!content || content.length > 5e3) return c.json({ error: "Understanding content must be 1-5000 characters" }, 400);
685
- if (!kind) return c.json({ error: "A valid user understanding kind is required" }, 400);
686
- const scope = body.scope === "session" ? {
687
- type: "session",
688
- sessionKey: typeof body.sessionKey === "string" ? body.sessionKey.trim() : ""
689
- } : body.scope === void 0 || body.scope === "global" ? { type: "global" } : null;
690
- if (!scope || scope.type === "session" && !scope.sessionKey) return c.json({ error: "scope must be global or a session with sessionKey" }, 400);
691
- const sensitivity = MEMORY_SENSITIVITIES.has(body.sensitivity) ? body.sensitivity : "normal";
692
- const durability = MEMORY_DURABILITIES.has(body.durability) ? body.durability : "durable";
693
- const disclosurePolicy = MEMORY_DISCLOSURE_POLICIES.has(body.disclosurePolicy) ? body.disclosurePolicy : "referenceable";
694
- const config = deps.service.currentConfig;
695
- const result = createManualUnderstanding({
696
- agentId: selectedAgentId(config),
697
- content,
698
- kind,
699
- scope,
700
- sensitivity,
701
- durability,
702
- disclosurePolicy
703
- });
704
- if (!result.created) return c.json({
705
- error: "This understanding already exists in the selected scope",
706
- understanding: projectUserContextRecord(result.record)
707
- }, 409);
708
- return c.json({ understanding: projectUserContextRecord(result.record) }, 201);
709
- });
710
- authenticated.get("/api/you/understanding/:id/history", (c) => {
711
- const all = listAllUserContextRecords(ALL_MEMORY_STATUSES).filter(isUserContextRecord);
712
- const target = all.find((record) => record.id === c.req.param("id"));
713
- if (!target) return c.json({ error: "Understanding not found" }, 404);
714
- const relatedIds = new Set([target.id]);
715
- let changed = true;
716
- while (changed) {
717
- changed = false;
718
- for (const record of all) if (record.supersedesRecordId && relatedIds.has(record.supersedesRecordId) || record.supersedesRecordId && relatedIds.has(record.id)) {
719
- if (!relatedIds.has(record.id)) {
720
- relatedIds.add(record.id);
721
- changed = true;
722
- }
723
- if (record.supersedesRecordId && !relatedIds.has(record.supersedesRecordId)) {
724
- relatedIds.add(record.supersedesRecordId);
725
- changed = true;
726
- }
727
- }
132
+ if (body.accessibility !== void 0) {
133
+ const accessibility = asRecord(body.accessibility);
134
+ if (!accessibility) return c.json({ error: "accessibility must be an object" }, 400);
135
+ if (JSON.stringify(accessibility).length > 1e4) return c.json({ error: "accessibility is too large" }, 400);
136
+ patch.accessibility = accessibility;
728
137
  }
729
- const history = all.filter((record) => relatedIds.has(record.id)).sort((left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt)).map((record) => ({
730
- ...projectUserContextRecord(record),
731
- storedStatus: record.status
732
- }));
733
- return c.json({ history });
734
- });
735
- authenticated.post("/api/you/understanding/batch", deps.strictRateLimitMiddleware, async (c) => {
736
- const body = await c.req.json().catch(() => ({}));
737
- const ids = Array.isArray(body.ids) ? [...new Set(body.ids.filter((id) => typeof id === "string" && id.trim().length > 0).slice(0, 100))] : [];
738
- const action = body.action === "confirm" || body.action === "reject" || body.action === "forget" ? body.action : void 0;
739
- if (!ids.length || !action) return c.json({ error: "ids and a valid action are required" }, 400);
740
- let updatedCount = 0;
741
- runSqliteWriteTransaction(() => {
742
- for (const id of ids) {
743
- const record = editableRecord(id);
744
- if (!record) continue;
745
- if (action === "forget") deleteMemoryRecord(id);
746
- else preserveRecord(record, {
747
- status: action === "confirm" ? "active" : "rejected",
748
- ...action === "confirm" ? {
749
- reviewAfter: nextMemoryReviewAt(record),
750
- tags: [...new Set([...record.tags ?? [], USER_CONFIRMED_MEMORY_TAG])]
751
- } : {}
752
- });
753
- updatedCount += 1;
754
- }
755
- });
756
- return c.json({
757
- ok: true,
758
- updatedCount
759
- });
760
- });
761
- authenticated.post("/api/you/conflicts/:id/resolve", deps.strictRateLimitMiddleware, async (c) => {
762
- const body = await c.req.json().catch(() => ({}));
763
- const winnerId = typeof body.winnerId === "string" ? body.winnerId : "";
764
- const group = listAllUserContextRecords(ALL_MEMORY_STATUSES).filter(isUserContextRecord).filter((record) => record.conflictGroupId === c.req.param("id"));
765
- const winner = group.find((record) => record.id === winnerId && VISIBLE_STATUSES.has(record.status));
766
- if (group.length < 2 || !winner) return c.json({ error: "Conflict group or winner not found" }, 404);
767
- const now = (/* @__PURE__ */ new Date()).toISOString();
768
- runSqliteWriteTransaction(() => {
769
- for (const record of group) preserveRecord(record, record.id === winnerId ? {
770
- status: "active",
771
- reviewAfter: nextMemoryReviewAt(record),
772
- tags: [...new Set([...record.tags ?? [], USER_CONFIRMED_MEMORY_TAG])]
773
- } : {
774
- status: "archived",
775
- validTo: record.validTo ?? now
776
- });
777
- });
778
- return c.json({
779
- ok: true,
780
- understanding: projectUserContextRecord(getMemoryRecord(winnerId))
781
- });
782
- });
783
- authenticated.patch("/api/you/profile", deps.strictRateLimitMiddleware, async (c) => {
784
- const config = deps.service.currentConfig;
785
- const parsed = parseProfilePatch(await c.req.json().catch(() => null));
786
- if ("error" in parsed) return c.json({ error: parsed.error }, 400);
787
- const current = await readUserProfileFile();
788
- const saved = await writeUserProfileFile(patchUserProfileMarkdown(current.ok ? current.data.content : "", parsed.patch));
789
- if (saved.ok === false) return c.json({ error: saved.error }, saved.status ?? 500);
790
- if (parsed.patch.callName !== void 0) setUserProfilePromptState({ state: "active" });
791
- deps.service.refreshUserProfileContext();
792
- return c.json(await readProfileBundle(config));
793
- });
794
- authenticated.post("/api/you/profile-prompt", deps.strictRateLimitMiddleware, async (c) => {
795
- const body = await c.req.json().catch(() => ({}));
796
- const action = typeof body.action === "string" ? body.action : "";
797
- if (action !== "snooze" && action !== "reset") return c.json({ error: "Action must be snooze or reset" }, 400);
798
- const config = deps.service.currentConfig;
799
- const current = await readProfileBundle(config);
800
- const suggestionHash = current.profileSetup.callNameSuggestion?.id;
801
- const promptState = action === "snooze" ? setUserProfilePromptState({
802
- state: "snoozed",
803
- suggestionHash,
804
- snoozedUntil: new Date(Date.now() + PROFILE_PROMPT_SNOOZE_MS).toISOString()
805
- }) : setUserProfilePromptState({
806
- state: "active",
807
- suggestionHash
808
- });
809
- return c.json({ profileSetup: buildUserProfileSetup({
810
- profile: current.profile,
811
- promptState,
812
- config
813
- }) });
814
- });
815
- authenticated.patch("/api/you/trust", deps.strictRateLimitMiddleware, async (c) => {
816
- const body = await c.req.json().catch(() => ({}));
817
- if (!isUserTrustLevel(body.defaultActionLevel)) return c.json({ error: "Invalid default action level" }, 400);
818
- const policy = setUserTrustPolicy(body.defaultActionLevel);
819
- deps.service.refreshActionTrustPolicy();
820
- return c.json({ trust: {
821
- defaultActionLevel: policy.defaultActionLevel,
822
- levels: USER_TRUST_LEVELS,
823
- autoRequiresExplicitOptIn: true
824
- } });
825
- });
826
- authenticated.patch("/api/you/playbooks/:id", deps.strictRateLimitMiddleware, async (c) => {
827
- const id = c.req.param("id");
828
- if (!PLAYBOOK_IDS.includes(id)) return c.json({ error: "Playbook not found" }, 404);
829
- const enabled = (await c.req.json().catch(() => ({}))).enabled;
830
- if (typeof enabled !== "boolean") return c.json({ error: "enabled must be a boolean" }, 400);
831
- const active = listMemoryRecords({
832
- status: "active",
833
- limit: 500
834
- }).filter(isUserContextRecord).filter((record) => playbookForRecord(record) === id);
835
- runSqliteWriteTransaction(() => {
836
- for (const record of active) versionPlaybookRule(record, { tags: patchPlaybookRuleTags(record, { enabled }) });
837
- });
838
- const current = active.map((record) => ({
839
- ...record,
840
- tags: patchPlaybookRuleTags(record, { enabled })
841
- }));
842
- return c.json({
843
- ok: true,
844
- playbook: buildPersonalPlaybooks(current).find((playbook) => playbook.id === id)
845
- });
846
- });
847
- authenticated.post("/api/you/playbooks/:id/rules", deps.strictRateLimitMiddleware, async (c) => {
848
- const id = c.req.param("id");
849
- if (!PLAYBOOK_IDS.includes(id)) return c.json({ error: "Playbook not found" }, 404);
850
- const body = await c.req.json().catch(() => ({}));
851
- const statement = typeof body.statement === "string" ? body.statement.trim() : "";
852
- if (!statement || statement.length > 5e3) return c.json({ error: "Rule statement is required" }, 400);
853
- const parsedContext = parsePlaybookContext(body.context);
854
- if ("error" in parsedContext) return c.json({ error: parsedContext.error }, 400);
855
- const record = upsertMemoryRecord({
856
- providerId: "local",
857
- kind: id === "communication" ? "preference" : id === "execution" ? "task_lesson" : "routine",
858
- sourceAgentId: selectedAgentId(deps.service.currentConfig),
859
- content: statement,
860
- source: {
861
- provider: "local",
862
- path: "you://playbook"
863
- },
864
- confidence: 1,
865
- tags: patchPersonalPlaybookContextTags([
866
- "user-understanding",
867
- PERSONAL_PLAYBOOK_RULE_TAG,
868
- `${PERSONAL_PLAYBOOK_ORDER_PREFIX}${Number.isInteger(body.order) ? body.order : 1e3}`
869
- ], parsedContext.context),
138
+ if (patch.timezone !== void 0 && !validTimezone(patch.timezone)) return c.json({ error: "timezone must be a valid IANA time zone" }, 400);
139
+ return c.json({ profile: updateUserProfile(patch) });
140
+ });
141
+ authenticated.post("/api/you/understandings", write, async (c) => {
142
+ const body = await readBody(c);
143
+ const statement = nonEmptyString(body?.statement);
144
+ const kind = body?.kind;
145
+ const scope = scopeFrom(body?.scope ?? { type: "global" });
146
+ if (!statement || !UNDERSTANDING_KINDS.has(kind) || !scope) return c.json({ error: "Valid statement, kind, and scope are required" }, 400);
147
+ const typedKind = kind;
148
+ const key = canonicalKey(typedKind, statement);
149
+ if (listUnderstandings().some((item) => item.canonicalKey === key && sameScope(item.scope, scope) && item.status !== "archived" && item.status !== "rejected")) return c.json({ error: "This understanding already exists" }, 409);
150
+ const understanding = createUnderstanding({
151
+ kind: typedKind,
152
+ canonicalKey: key,
870
153
  status: "active",
871
- sensitivity: "normal",
154
+ scope,
872
155
  explicitness: "explicit",
873
- durability: id === "routines" ? "recurring" : "durable",
874
- importance: .85,
875
- disclosurePolicy: "referenceable"
876
- });
877
- return c.json({
878
- ok: true,
879
- rule: buildPersonalPlaybooks([record]).find((playbook) => playbook.id === id)?.rules[0]
880
- }, 201);
881
- });
882
- authenticated.patch("/api/you/playbooks/:id/rules/:recordId", deps.strictRateLimitMiddleware, async (c) => {
883
- const id = c.req.param("id");
884
- const record = editableRecord(c.req.param("recordId"));
885
- if (!PLAYBOOK_IDS.includes(id) || !record || playbookForRecord(record) !== id) return c.json({ error: "Playbook rule not found" }, 404);
886
- const body = await c.req.json().catch(() => ({}));
887
- const content = body.statement === void 0 ? record.content : typeof body.statement === "string" ? body.statement.trim() : "";
888
- if (!content || content.length > 5e3) return c.json({ error: "Rule statement is required" }, 400);
889
- if (body.enabled !== void 0 && typeof body.enabled !== "boolean") return c.json({ error: "enabled must be boolean" }, 400);
890
- if (body.order !== void 0 && (!Number.isInteger(body.order) || body.order < 0 || body.order > 1e4)) return c.json({ error: "order must be an integer between 0 and 10000" }, 400);
891
- const parsedContext = parsePlaybookContext(body.context);
892
- if ("error" in parsedContext) return c.json({ error: parsedContext.error }, 400);
893
- const updated = versionPlaybookRule(record, {
894
- content,
895
- tags: patchPersonalPlaybookContextTags(patchPlaybookRuleTags(record, {
896
- enabled: body.enabled,
897
- order: body.order
898
- }), parsedContext.context),
899
- explicitness: body.statement === void 0 ? record.explicitness : "explicit"
900
- });
901
- return c.json({
902
- ok: true,
903
- rule: buildPersonalPlaybooks([updated]).find((playbook) => playbook.id === id)?.rules[0]
156
+ durability: "durable",
157
+ sensitivity: "normal",
158
+ disclosurePolicy: typedKind === "boundary" ? "silent" : "referenceable",
159
+ confidence: 1,
160
+ statement,
161
+ createdBy: "user",
162
+ changeReason: "Created by user"
904
163
  });
164
+ return c.json({ understanding }, 201);
905
165
  });
906
- authenticated.delete("/api/you/playbooks/:id/rules/:recordId", deps.strictRateLimitMiddleware, (c) => {
907
- const id = c.req.param("id");
908
- const record = editableRecord(c.req.param("recordId"));
909
- if (!PLAYBOOK_IDS.includes(id) || !record || playbookForRecord(record) !== id) return c.json({ error: "Playbook rule not found" }, 404);
910
- preserveRecord(record, {
911
- status: "archived",
912
- validTo: (/* @__PURE__ */ new Date()).toISOString()
913
- });
914
- return c.json({ ok: true });
166
+ authenticated.get("/api/you/understandings/:id/evidence", (c) => {
167
+ const understanding = getUnderstanding(c.req.param("id"));
168
+ if (!understanding) return c.json({ error: "Understanding not found" }, 404);
169
+ return c.json({ evidence: listUnderstandingEvidence(understanding.id) });
915
170
  });
916
- authenticated.post("/api/you/playbooks/:id/rules/:recordId/rollback", deps.strictRateLimitMiddleware, async (c) => {
171
+ authenticated.patch("/api/you/understandings/:id", write, async (c) => {
917
172
  const id = c.req.param("id");
918
- const current = editableRecord(c.req.param("recordId"));
919
- if (!PLAYBOOK_IDS.includes(id) || !current || playbookForRecord(current) !== id) return c.json({ error: "Playbook rule not found" }, 404);
920
- const body = await c.req.json().catch(() => ({}));
921
- const versionId = typeof body.versionId === "string" ? body.versionId : "";
922
- const all = listAllUserContextRecords(ALL_MEMORY_STATUSES);
923
- const target = playbookVersionChain(all, current.id).find((record) => record.id === versionId);
924
- if (!target || target.id === current.id) return c.json({ error: "Previous version not found" }, 404);
925
- const rolledBack = versionPlaybookRule(current, {
926
- content: target.content,
927
- tags: target.tags,
928
- evidence: target.evidence,
929
- explicitness: "explicit"
930
- });
931
- return c.json({
932
- ok: true,
933
- rule: buildPersonalPlaybooks([...all, rolledBack]).find((playbook) => playbook.id === id)?.rules.find((rule) => rule.id === rolledBack.id)
934
- });
935
- });
936
- authenticated.post("/api/you/insights/:id/apply", deps.strictRateLimitMiddleware, async (c) => {
937
- const config = deps.service.currentConfig;
938
- const existing = editableRecord(c.req.param("id"));
939
- const suggestion = existing ? buildActionableInsightSuggestions([existing], [])[0] : void 0;
940
- if (!existing || !suggestion) return c.json({ error: "Insight not found" }, 404);
941
- if (suggestion.action === "start_progress") return c.json({ error: "Progress insights must be reviewed as task drafts" }, 400);
942
- if (existing.kind === "routine") {
943
- preserveRecord(existing, { tags: [...new Set([...existing.tags ?? [], INSIGHT_ACCEPTED_TAG])] });
944
- return c.json({
945
- ok: true,
946
- status: "drafting",
947
- href: buildRoutineAutomationDraftHref(existing)
173
+ let understanding = getUnderstanding(id);
174
+ if (!understanding) return c.json({ error: "Understanding not found" }, 404);
175
+ const body = await readBody(c);
176
+ if (!body) return c.json({ error: "Invalid JSON" }, 400);
177
+ if (body.statement !== void 0) {
178
+ const statement = nonEmptyString(body.statement);
179
+ if (!statement) return c.json({ error: "statement must be 1-2000 characters" }, 400);
180
+ const key = canonicalKey(understanding.kind, statement);
181
+ if (listUnderstandings().some((item) => item.id !== id && item.canonicalKey === key && sameScope(item.scope, understanding.scope) && item.status !== "archived" && item.status !== "rejected")) return c.json({ error: "This understanding already exists" }, 409);
182
+ understanding = reviseUnderstanding(id, statement, {
183
+ canonicalKey: key,
184
+ explicitness: "explicit",
185
+ confidence: 1,
186
+ changeReason: "Edited by user"
948
187
  });
949
188
  }
950
- upsertMemoryRecord({
951
- providerId: "local",
952
- kind: "task_lesson",
953
- sourceAgentId: selectedAgentId(config),
954
- content: existing.content,
955
- source: {
956
- provider: "local",
957
- path: "you://insight-proposal"
958
- },
959
- confidence: 1,
960
- tags: [
961
- "user-understanding",
962
- USER_CONFIRMED_MEMORY_TAG,
963
- PERSONAL_PLAYBOOK_RULE_TAG,
964
- `${PERSONAL_PLAYBOOK_ORDER_PREFIX}1000`
965
- ],
966
- status: "active",
967
- sensitivity: existing.sensitivity,
968
- explicitness: "explicit",
969
- durability: "durable",
970
- importance: existing.importance,
971
- disclosurePolicy: existing.disclosurePolicy,
972
- evidence: existing.evidence
973
- });
974
- preserveRecord(existing, { tags: [...new Set([...existing.tags ?? [], INSIGHT_ACCEPTED_TAG])] });
975
- return c.json({
976
- ok: true,
977
- status: "saved"
978
- });
979
- });
980
- authenticated.delete("/api/you/insights/:id", deps.strictRateLimitMiddleware, (c) => {
981
- const existing = editableRecord(c.req.param("id"));
982
- const suggestion = existing ? buildActionableInsightSuggestions([existing], [])[0] : void 0;
983
- if (!existing || !suggestion) return c.json({ error: "Insight not found" }, 404);
984
- preserveRecord(existing, { tags: [...new Set([...existing.tags ?? [], INSIGHT_DISMISSED_TAG])] });
985
- return c.json({
986
- ok: true,
987
- status: "dismissed"
988
- });
989
- });
990
- authenticated.post("/api/you/insights/:id/complete", deps.strictRateLimitMiddleware, async (c) => {
991
- const existing = editableRecord(c.req.param("id"));
992
- const suggestion = existing ? buildActionableInsightSuggestions([existing], [])[0] : void 0;
993
- if (!existing || suggestion?.action !== "start_progress") return c.json({ error: "Insight not found" }, 404);
994
- const body = await c.req.json().catch(() => ({}));
995
- const taskId = typeof body.taskId === "string" ? body.taskId.trim() : "";
996
- const task = taskId ? new TaskRepository().get(taskId) : null;
997
- const linked = task && new TaskContextRepository().list(task.id).some((edge) => edge.targetKind === "memory" && edge.targetId === existing.id);
998
- if (!task || !linked) return c.json({ error: "A linked task draft is required" }, 400);
999
- preserveRecord(existing, { tags: [...new Set([...existing.tags ?? [], INSIGHT_ACCEPTED_TAG])] });
1000
- return c.json({
1001
- ok: true,
1002
- status: "saved",
1003
- taskId: task.id
189
+ if (body.status !== void 0) {
190
+ if (!UNDERSTANDING_STATUSES.has(body.status)) return c.json({ error: "Invalid status" }, 400);
191
+ understanding = body.status === "rejected" ? rejectUnderstanding(id, nonEmptyString(body.reason, 500) ?? "Rejected by user") : setUnderstandingStatus(id, body.status, body.status === "active" ? {
192
+ explicitness: "explicit",
193
+ confidence: 1
194
+ } : void 0);
195
+ }
196
+ return c.json({ understanding });
197
+ });
198
+ authenticated.delete("/api/you/understandings/:id", write, (c) => deleteUnderstanding(c.req.param("id")) ? c.json({ ok: true }) : c.json({ error: "Understanding not found" }, 404));
199
+ authenticated.post("/api/you/rules", write, async (c) => {
200
+ const body = await readBody(c);
201
+ const statement = nonEmptyString(body?.statement);
202
+ const category = body?.category;
203
+ const scope = scopeFrom(body?.scope ?? { type: "global" });
204
+ if (!statement || !RULE_CATEGORIES.has(category) || !scope) return c.json({ error: "Valid statement, category, and scope are required" }, 400);
205
+ const priority = typeof body?.priority === "number" && Number.isInteger(body.priority) ? Math.max(0, Math.min(100, body.priority)) : 50;
206
+ const conditions = body?.conditions === void 0 ? {} : asRecord(body.conditions);
207
+ if (!conditions) return c.json({ error: "conditions must be an object" }, 400);
208
+ const rule = createCollaborationRule({
209
+ category,
210
+ priority,
211
+ scope,
212
+ conditions,
213
+ statement
1004
214
  });
215
+ return c.json({ rule }, 201);
1005
216
  });
1006
- authenticated.patch("/api/you/controls", deps.strictRateLimitMiddleware, async (c) => {
1007
- const config = deps.service.currentConfig;
1008
- const body = await c.req.json().catch(() => ({}));
1009
- const parsed = UserContextConfigSchema.safeParse({
1010
- ...config.userContext,
1011
- memory: {
1012
- ...config.userContext.memory,
1013
- mode: body.mode
1014
- },
1015
- privacy: {
1016
- ...config.userContext.privacy,
1017
- sensitiveWritePolicy: body.sensitiveWritePolicy
1018
- }
1019
- });
1020
- if (!parsed.success) return c.json({ error: parsed.error.issues[0]?.message ?? "Invalid personal context controls" }, 400);
1021
- const saved = await deps.service.saveConfig({
1022
- ...config,
1023
- userContext: parsed.data
1024
- });
1025
- if (!saved.saved) return c.json({ error: saved.error ?? "save failed" }, 500);
1026
- const updated = deps.service.currentConfig.userContext;
1027
- return c.json({ controls: {
1028
- mode: updated.memory.mode,
1029
- sensitiveWritePolicy: updated.privacy.sensitiveWritePolicy
1030
- } });
217
+ authenticated.patch("/api/you/rules/:id", write, async (c) => {
218
+ const id = c.req.param("id");
219
+ let rule = getCollaborationRule(id);
220
+ if (!rule) return c.json({ error: "Collaboration rule not found" }, 404);
221
+ const body = await readBody(c);
222
+ if (!body) return c.json({ error: "Invalid JSON" }, 400);
223
+ if (body.statement !== void 0) {
224
+ const statement = nonEmptyString(body.statement);
225
+ if (!statement) return c.json({ error: "statement must be 1-2000 characters" }, 400);
226
+ rule = reviseCollaborationRule(id, statement);
227
+ }
228
+ if (body.status !== void 0) {
229
+ if (!RULE_STATUSES.has(body.status)) return c.json({ error: "Invalid status" }, 400);
230
+ rule = setCollaborationRuleStatus(id, body.status);
231
+ }
232
+ return c.json({ rule });
233
+ });
234
+ authenticated.delete("/api/you/rules/:id", write, (c) => deleteCollaborationRule(c.req.param("id")) ? c.json({ ok: true }) : c.json({ error: "Collaboration rule not found" }, 404));
235
+ authenticated.get("/api/you/turns/:turnId/personalization", (c) => {
236
+ const personalization = getTurnPersonalization(c.req.param("turnId"));
237
+ return personalization ? c.json({ personalization }) : c.json({ error: "Personalization run not found" }, 404);
238
+ });
239
+ authenticated.post("/api/you/turns/:turnId/feedback", write, async (c) => {
240
+ const turnId = c.req.param("turnId");
241
+ const run = getTurnPersonalization(turnId);
242
+ if (!run) return c.json({ error: "Personalization run not found" }, 404);
243
+ const body = await readBody(c);
244
+ if (!body || !FEEDBACK_RATINGS.has(String(body.rating))) return c.json({ error: "Invalid feedback rating" }, 400);
245
+ const objectType = body.objectType;
246
+ const objectId = body.objectId;
247
+ if (objectType === void 0 !== (objectId === void 0) || objectType !== void 0 && ![
248
+ "profile",
249
+ "rule",
250
+ "understanding"
251
+ ].includes(String(objectType)) || objectId !== void 0 && typeof objectId !== "string") return c.json({ error: "objectType and objectId must be valid and provided together" }, 400);
252
+ if (objectType !== void 0 && !run.items.some((item) => item.objectType === objectType && item.objectId === objectId)) return c.json({ error: "The context object was not part of this turn" }, 400);
253
+ const rating = body.rating;
254
+ recordContextFeedback({
255
+ turnId,
256
+ runId: run.runId,
257
+ rating,
258
+ ...objectType ? {
259
+ objectType,
260
+ objectId
261
+ } : {},
262
+ ...typeof body.reason === "string" ? { reason: body.reason.slice(0, 500) } : {}
263
+ });
264
+ if (objectType === "understanding" && typeof objectId === "string") {
265
+ if (rating === "wrong") rejectUnderstanding(objectId, "Marked wrong from turn feedback");
266
+ if (rating === "stale") setUnderstandingStatus(objectId, "stale");
267
+ if (rating === "sensitive") setUnderstandingStatus(objectId, "needs_review");
268
+ }
269
+ return c.json({ ok: true });
1031
270
  });
1032
- authenticated.patch("/api/you/consents/:id", deps.strictRateLimitMiddleware, async (c) => {
1033
- const body = await c.req.json().catch(() => ({}));
1034
- const decision = typeof body.decision === "string" ? body.decision : "";
271
+ authenticated.patch("/api/you/consents/:id", write, async (c) => {
272
+ const decision = (await readBody(c))?.decision;
1035
273
  if (![
1036
274
  "once",
1037
275
  "session",
1038
276
  "always",
1039
277
  "deny"
1040
- ].includes(decision)) return c.json({ error: "Decision must be once, session, always, or deny" }, 400);
1041
- const consent = decideMemoryReferenceConsent(c.req.param("id"), decision);
1042
- if (!consent) return c.json({ error: "Pending consent not found" }, 404);
1043
- return c.json({
1044
- ok: true,
1045
- consent
1046
- });
1047
- });
1048
- authenticated.delete("/api/you/consents/:id", deps.strictRateLimitMiddleware, (c) => {
1049
- const consent = revokeMemoryReferenceConsent(c.req.param("id"));
1050
- if (!consent) return c.json({ error: "Active reference grant not found" }, 404);
1051
- return c.json({
1052
- ok: true,
1053
- consent
1054
- });
1055
- });
1056
- authenticated.delete("/api/you/sources/:instanceId", deps.strictRateLimitMiddleware, async (c) => {
1057
- const config = deps.service.currentConfig;
1058
- const instanceId = c.req.param("instanceId");
1059
- const installedInstances = listConnectorInstances(config);
1060
- const account = getConnectorAccount(instanceId);
1061
- const accountConnections = account ? listConnectorConnections({
1062
- principalId: account.principalId,
1063
- connectorId: account.connectorId
1064
- }).filter((connection) => connection.accountId === account.id) : [];
1065
- const instance = installedInstances.find((item) => item.instanceId === instanceId);
1066
- const connectorId = account?.connectorId ?? instance?.connectorId;
1067
- const definition = connectorId ? listConnectorCatalog().find((item) => item.id === connectorId) : void 0;
1068
- if (!instance && !account || !definition || !definition.capabilities.some((capability) => capability === "context" || capability === "memory_source")) return c.json({ error: "Personal context source not found" }, 404);
1069
- const body = await c.req.json().catch(() => ({}));
1070
- const understandingPolicy = body.understandingPolicy === "keep" || body.understandingPolicy === "delete" ? body.understandingPolicy : void 0;
1071
- if (!understandingPolicy) return c.json({ error: "understandingPolicy must be keep or delete" }, 400);
1072
- try {
1073
- if (account) for (const connection of accountConnections.filter((candidate) => candidate.status !== "revoked")) await revokeComposioConnection(connection.id);
1074
- else if (instance) {
1075
- uninstallConnector(config, instance.instanceId);
1076
- const saved = await deps.service.saveConfig(config);
1077
- if (!saved.saved) return c.json({ error: saved.error ?? "save failed" }, 500);
1078
- }
1079
- } catch (error) {
1080
- return c.json({ error: error instanceof Error ? error.message : String(error) }, 400);
1081
- }
1082
- let deletedUnderstandingCount = 0;
1083
- let deletedClaimCount = 0;
1084
- if (understandingPolicy === "delete") {
1085
- const sourceInstanceId = account ? `composio:${account.connectorId}:${account.id}` : instanceId;
1086
- const targets = recordsDerivedFromPersonalContextSource(listAllUserContextRecords(ALL_MEMORY_STATUSES), sourceInstanceId);
1087
- runSqliteWriteTransaction(() => {
1088
- const claimRemoval = removeUserClaimEvidenceForSource(sourceInstanceId);
1089
- deletedClaimCount = claimRemoval.deletedClaimCount;
1090
- const retainedMemoryIds = new Set(claimRemoval.retainedClaims.map((claim) => claim.memoryRecordId));
1091
- const deleteIds = new Set([...claimRemoval.deletedMemoryRecordIds, ...targets.filter((record) => !retainedMemoryIds.has(record.id)).map((record) => record.id)]);
1092
- for (const recordId of deleteIds) deleteMemoryRecord(recordId);
1093
- for (const retained of claimRemoval.retainedClaims) {
1094
- if (retained.state === "active") continue;
1095
- const record = getMemoryRecord(retained.memoryRecordId);
1096
- if (record) preserveRecord(record, { status: retained.state === "rejected" ? "rejected" : "stale" });
1097
- }
1098
- deletedUnderstandingCount = deleteIds.size;
1099
- });
1100
- }
1101
- return c.json({
1102
- ok: true,
1103
- deletedUnderstandingCount,
1104
- deletedClaimCount
1105
- });
1106
- });
1107
- authenticated.patch("/api/you/understanding/:id", deps.strictRateLimitMiddleware, async (c) => {
1108
- const existing = editableRecord(c.req.param("id"));
1109
- if (!existing) return c.json({ error: "Understanding not found" }, 404);
1110
- const body = await c.req.json().catch(() => ({}));
1111
- const action = typeof body.action === "string" ? body.action : "";
1112
- if (action === "confirm") return c.json({ understanding: projectUserContextRecord(preserveRecord(existing, {
1113
- status: "active",
1114
- reviewAfter: nextMemoryReviewAt(existing),
1115
- tags: [...new Set([...existing.tags ?? [], USER_CONFIRMED_MEMORY_TAG])]
1116
- })) });
1117
- if (action === "reject") return c.json({ understanding: projectUserContextRecord(preserveRecord(existing, { status: "rejected" })) });
1118
- if (action === "update") {
1119
- const content = typeof body.content === "string" ? body.content.trim() : "";
1120
- if (!content) return c.json({ error: "Updated understanding cannot be empty" }, 400);
1121
- const replacement = upsertMemoryRecord({
1122
- providerId: "local",
1123
- kind: existing.kind,
1124
- sourceAgentId: existing.provenance.sourceAgentId,
1125
- workspaceId: existing.scope.workspaceId,
1126
- sessionKey: existing.scope.sessionKey,
1127
- projectId: existing.scope.projectId,
1128
- content,
1129
- source: { provider: "local" },
1130
- confidence: 1,
1131
- tags: [...new Set([
1132
- ...existing.tags ?? [],
1133
- "user-understanding",
1134
- "explicit-user-correction",
1135
- USER_CONFIRMED_MEMORY_TAG
1136
- ])],
1137
- status: "active",
1138
- sensitivity: existing.sensitivity,
1139
- explicitness: "explicit",
1140
- durability: existing.durability,
1141
- importance: Math.max(existing.importance, .8),
1142
- disclosurePolicy: existing.disclosurePolicy,
1143
- evidence: existing.evidence,
1144
- reviewAfter: nextMemoryReviewAt({
1145
- durability: existing.durability,
1146
- explicitness: "explicit"
1147
- }),
1148
- supersedesRecordId: existing.id,
1149
- conflictGroupId: existing.conflictGroupId
1150
- });
1151
- preserveRecord(existing, {
1152
- status: "archived",
1153
- validTo: (/* @__PURE__ */ new Date()).toISOString()
1154
- });
1155
- return c.json({ understanding: projectUserContextRecord(replacement) });
1156
- }
1157
- return c.json({ error: "Action must be confirm, reject, or update" }, 400);
1158
- });
1159
- authenticated.delete("/api/you/understanding/:id", deps.strictRateLimitMiddleware, (c) => {
1160
- const existing = editableRecord(c.req.param("id"));
1161
- if (!existing) return c.json({ error: "Understanding not found" }, 404);
1162
- deleteMemoryRecord(existing.id);
1163
- return c.json({ ok: true });
278
+ ].includes(String(decision))) return c.json({ error: "Invalid consent decision" }, 400);
279
+ return decideContextConsent(c.req.param("id"), decision) ? c.json({ ok: true }) : c.json({ error: "Consent request not found" }, 404);
1164
280
  });
1165
281
  }
1166
282
  //#endregion
1167
- export { buildPersonalPlaybooks, buildRoutineAutomationDraftHref, registerYouRoutes };
283
+ export { registerYouRoutes };