forge-openclaw-plugin 0.3.15 → 0.3.17

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 (415) hide show
  1. package/README.md +6 -6
  2. package/dist/assets/{action-bar-B9MYlps2.js → action-bar-D3CEYlj4.js} +1 -1
  3. package/dist/assets/{activity-page-DbzbChcE.js → activity-page-Ce1pHIu5.js} +1 -1
  4. package/dist/assets/{ai-surface-workspace-CF0257Hs.js → ai-surface-workspace-DEliwOjF.js} +1 -1
  5. package/dist/assets/artifacts-page-BgyFVIVM.js +2 -0
  6. package/dist/assets/{atlas-panel-CO3RYAKn.js → atlas-panel-VZOnJa1c.js} +1 -1
  7. package/dist/assets/{board-CuxQRKPJ.js → board-DprRipIG.js} +1 -1
  8. package/dist/assets/{calendar-page-BuuHKEHC.js → calendar-page-Zstsn4uG.js} +1 -1
  9. package/dist/assets/{calendar-rules-DKftgNx5.js → calendar-rules-BGIBuEDk.js} +1 -1
  10. package/dist/assets/{calendar-week-toolbar-ChIpkT-G.js → calendar-week-toolbar-DXFkMkbq.js} +1 -1
  11. package/dist/assets/{charts-BzT4pUPg.js → charts-C5S0-BL7.js} +1 -1
  12. package/dist/assets/{companion-sync-lab-page-BZRX4Btw.js → companion-sync-lab-page-DIPPLFKt.js} +1 -1
  13. package/dist/assets/{daily-metrics-dashboard-CXDsaAQd.js → daily-metrics-dashboard-CG-OOCJz.js} +1 -1
  14. package/dist/assets/{define-workbench-box-CpG0Zb1L.js → define-workbench-box-BEEdtBkQ.js} +1 -1
  15. package/dist/assets/{entity-link-multiselect-Dl4rZqdg.js → entity-link-multiselect-BfDAROHB.js} +1 -1
  16. package/dist/assets/{entity-note-count-link-Bs1aKYyD.js → entity-note-count-link-BGOiaash.js} +1 -1
  17. package/dist/assets/{entity-notes-surface-B56XSw7M.js → entity-notes-surface-DPsJwqQa.js} +1 -1
  18. package/dist/assets/execution-board-Dg-2GSKv.js +1 -0
  19. package/dist/assets/{faceted-token-search-Dg2rjknH.js → faceted-token-search-DV7MSVYb.js} +1 -1
  20. package/dist/assets/{flagship-signal-deck-C6KVPhmM.js → flagship-signal-deck-D3wVL3bC.js} +1 -1
  21. package/dist/assets/{floating-action-menu-DAFAEBcA.js → floating-action-menu-BUs382px.js} +1 -1
  22. package/dist/assets/{forms-D1qJ3oOP.js → forms-ByKjodjN.js} +1 -1
  23. package/dist/assets/{generic-node-view-C6DK5hJ6.js → generic-node-view-BY5dbPXJ.js} +1 -1
  24. package/dist/assets/{goal-detail-page-CC4VXud6.js → goal-detail-page-MYr6j2B4.js} +1 -1
  25. package/dist/assets/{goal-dialog-15hD8EBp.js → goal-dialog-nkdME5Uy.js} +1 -1
  26. package/dist/assets/goals-page-BsFeBzU1.js +1 -0
  27. package/dist/assets/{graph-BF4IsheG.js → graph-CHVj0Z7n.js} +1 -1
  28. package/dist/assets/habits-page-wO461EVU.js +1 -0
  29. package/dist/assets/{health-boxes-DqgvIYoL.js → health-boxes-BphMeSJj.js} +1 -1
  30. package/dist/assets/index-CSd8ylsy.css +1 -0
  31. package/dist/assets/index-gmPaoLN-.js +2 -0
  32. package/dist/assets/{inline-note-fields-COgzxr_7.js → inline-note-fields-BvQwmMAv.js} +1 -1
  33. package/dist/assets/{insight-flow-dialog-Dmb6NSGp.js → insight-flow-dialog-H_eaOmst.js} +1 -1
  34. package/dist/assets/{insights-page-OnqR4cYI.js → insights-page-DINYe3cB.js} +3 -3
  35. package/dist/assets/{kanban-boxes-BWUzntCV.js → kanban-boxes-oACOTDYG.js} +1 -1
  36. package/dist/assets/{kanban-page-BI16Gzp_.js → kanban-page-BGLXH91f.js} +1 -1
  37. package/dist/assets/knowledge-graph-page-VfMvw5jL.js +1 -0
  38. package/dist/assets/{life-force-page-CDEXEQai.js → life-force-page-DQPb6UL-.js} +1 -1
  39. package/dist/assets/{life-force-workspace-C7UOnJEf.js → life-force-workspace-BJ1aI3JE.js} +1 -1
  40. package/dist/assets/{maps-BTVHALP8.js → maps-CvEHVkBk.js} +1 -1
  41. package/dist/assets/{metric-tile-boeHB1R1.js → metric-tile-CbEe19Gd.js} +1 -1
  42. package/dist/assets/{motion-DcgUnXhY.js → motion-BibSzp57.js} +1 -1
  43. package/dist/assets/{movement-boxes-BUSqaTL2.js → movement-boxes-dtDYhw5c.js} +1 -1
  44. package/dist/assets/{movement-page-DcbO0497.js → movement-page-BhmwCHjs.js} +1 -1
  45. package/dist/assets/{note-markdown-DXXI3W3V.js → note-markdown-CG8u2d6p.js} +1 -1
  46. package/dist/assets/{note-tags-input-CYh3TVW2.js → note-tags-input-D_conqDO.js} +1 -1
  47. package/dist/assets/{notes-boxes-CMJXX2K0.js → notes-boxes-BLKucFqW.js} +1 -1
  48. package/dist/assets/notes-page-CafVxWjb.js +1 -0
  49. package/dist/assets/{open-in-graph-button-4UYrp1XP.js → open-in-graph-button-DFQ4r6SN.js} +1 -1
  50. package/dist/assets/{orbit-map-BwK7sDaC.js → orbit-map-DsEl3ori.js} +1 -1
  51. package/dist/assets/overview-page-BffcX-pM.js +1 -0
  52. package/dist/assets/page-hero-U603l9rQ.js +1 -0
  53. package/dist/assets/pill-cluster-BYVFNppV.js +1 -0
  54. package/dist/assets/{preference-entity-handoff-button-C2ATjvws.js → preference-entity-handoff-button-cPrTpHsV.js} +1 -1
  55. package/dist/assets/{preferences-page-BAexXHye.js → preferences-page-DQjFIOmt.js} +1 -1
  56. package/dist/assets/{project-collections-B9nr-Ts-.js → project-collections-B9OGHGqm.js} +1 -1
  57. package/dist/assets/project-detail-page-r1Sw2kcO.js +1 -0
  58. package/dist/assets/{project-dialog-CBA-D65n.js → project-dialog-B2_PcXAf.js} +1 -1
  59. package/dist/assets/project-management-hierarchy-page-qLNG8hsh.js +1 -0
  60. package/dist/assets/{project-management-section-nav-DJ3QKCtr.js → project-management-section-nav-DFUlmMEB.js} +1 -1
  61. package/dist/assets/{projects-boxes-iBu_PRqe.js → projects-boxes-BA7_XaqX.js} +1 -1
  62. package/dist/assets/projects-page-B6ggXWFw.js +1 -0
  63. package/dist/assets/psyche-behaviors-page-ByWpXlLq.js +5 -0
  64. package/dist/assets/{psyche-flashcards-page-DQaw_vUQ.js → psyche-flashcards-page-B9nSc0mk.js} +1 -1
  65. package/dist/assets/{psyche-goal-map-page-C-ZTVOEP.js → psyche-goal-map-page-BQU7qI88.js} +1 -1
  66. package/dist/assets/{psyche-graph-DYzeClxn.js → psyche-graph-DCeP7r2b.js} +1 -1
  67. package/dist/assets/{psyche-metrics-page-C9hKn10A.js → psyche-metrics-page-DD2lOP-J.js} +1 -1
  68. package/dist/assets/psyche-mode-guide-page-DbtZgnjr.js +1 -0
  69. package/dist/assets/psyche-modes-page-3zFJWFQf.js +1 -0
  70. package/dist/assets/psyche-page-D5vXYkfB.js +1 -0
  71. package/dist/assets/psyche-patterns-page-BneAAeKS.js +5 -0
  72. package/dist/assets/{psyche-questionnaire-builder-page-gRwdGXde.js → psyche-questionnaire-builder-page-BH1la5C9.js} +1 -1
  73. package/dist/assets/{psyche-questionnaire-detail-page-CIP9b2UI.js → psyche-questionnaire-detail-page-DYav634P.js} +1 -1
  74. package/dist/assets/psyche-questionnaire-run-detail-page-9VaijhJm.js +1 -0
  75. package/dist/assets/{psyche-questionnaire-run-page-CXiJyd5i.js → psyche-questionnaire-run-page-e1T6k_dS.js} +1 -1
  76. package/dist/assets/{psyche-questionnaires-page-CFPKwA3O.js → psyche-questionnaires-page-Dyv367z9.js} +1 -1
  77. package/dist/assets/{psyche-report-detail-page-dU30a2WE.js → psyche-report-detail-page-hqxHIXw2.js} +3 -3
  78. package/dist/assets/psyche-reports-page-DhIfcGbt.js +1 -0
  79. package/dist/assets/{psyche-schemas-DDol0j-g.js → psyche-schemas-Cg51Ztxz.js} +1 -1
  80. package/dist/assets/psyche-schemas-beliefs-page-Dgb5o9vx.js +9 -0
  81. package/dist/assets/{psyche-screen-time-page-lIe6GQxJ.js → psyche-screen-time-page-D6MnJGNa.js} +1 -1
  82. package/dist/assets/{psyche-self-observation-page-BTE3KfIl.js → psyche-self-observation-page-C1Vyezbv.js} +1 -1
  83. package/dist/assets/{psyche-values-page-DclBZ9xw.js → psyche-values-page-B_JWVw1Q.js} +2 -2
  84. package/dist/assets/{question-flow-dialog-Ded2E85L.js → question-flow-dialog-yMYVk998.js} +2 -2
  85. package/dist/assets/{report-chain-fields-DY640iqL.js → report-chain-fields-D4NM9a6I.js} +1 -1
  86. package/dist/assets/rewards-page-B5-bcL4R.js +1 -0
  87. package/dist/assets/{scheduling-rules-editor-jakFfxqF.js → scheduling-rules-editor-De72IUax.js} +1 -1
  88. package/dist/assets/{schema-badge-30B5syHA.js → schema-badge-jX28kUa6.js} +1 -1
  89. package/dist/assets/{schemas-Db29G8NU.js → schemas-BlFy-uPR.js} +1 -1
  90. package/dist/assets/{select-menu-BF2zI3RW.js → select-menu-BXv1rsVc.js} +1 -1
  91. package/dist/assets/{settings-agents-page-Bh-Bv6FQ.js → settings-agents-page-DN_np10S.js} +1 -1
  92. package/dist/assets/settings-bin-page-BM5BpK_i.js +1 -0
  93. package/dist/assets/{settings-calendar-page-BA4_Qqiu.js → settings-calendar-page-Cg0gSSFs.js} +3 -3
  94. package/dist/assets/{settings-data-page-K4kpmQJY.js → settings-data-page-Dwmp2rLy.js} +1 -1
  95. package/dist/assets/{settings-logs-page-DkuNPAZo.js → settings-logs-page-DQNM21Re.js} +1 -1
  96. package/dist/assets/{settings-mobile-page-4pCNwD91.js → settings-mobile-page-DQdiRa-a.js} +1 -1
  97. package/dist/assets/settings-models-page-CAEPpuHF.js +1 -0
  98. package/dist/assets/{settings-page-B_Be0vOY.js → settings-page-Cl2KiCFg.js} +1 -1
  99. package/dist/assets/{settings-rewards-page-C6nFTWJu.js → settings-rewards-page-DoIUumhe.js} +1 -1
  100. package/dist/assets/{settings-section-nav-Lo-VKCfZ.js → settings-section-nav-D_N87IG0.js} +1 -1
  101. package/dist/assets/{settings-users-page-CVzNp4-m.js → settings-users-page-CPesR62N.js} +1 -1
  102. package/dist/assets/{settings-wiki-page-DXM--7BB.js → settings-wiki-page-BxMQM5Vi.js} +1 -1
  103. package/dist/assets/{sleep-page-DvPdZMKx.js → sleep-page-DUYmQKrg.js} +1 -1
  104. package/dist/assets/{sports-page-DjuZlOur.js → sports-page-Bzi5TF9T.js} +1 -1
  105. package/dist/assets/{state-Bpe5dF3T.js → state-BFyKSULP.js} +1 -1
  106. package/dist/assets/{strategies-page-PE1IlatS.js → strategies-page-C-T2MZx4.js} +1 -1
  107. package/dist/assets/{strategy-detail-page-C4KiEGCI.js → strategy-detail-page-3tYuSZu-.js} +1 -1
  108. package/dist/assets/{strategy-dialog-Cwf7Y3P5.js → strategy-dialog-BWm4slo4.js} +1 -1
  109. package/dist/assets/{surface-ubuOfukq.js → surface-BJObZeRw.js} +1 -1
  110. package/dist/assets/{table-U7otr5go.js → table-CTLroJKN.js} +1 -1
  111. package/dist/assets/task-detail-page-ZZOXSpSF.js +1 -0
  112. package/dist/assets/{task-dialog-CI_Fy_FW.js → task-dialog-2wy0xI7f.js} +5 -5
  113. package/dist/assets/timebox-planning-dialog-C6h0Hp71.js +1 -0
  114. package/dist/assets/{today-boxes-CYuxSkZf.js → today-boxes-B_TdgSDz.js} +1 -1
  115. package/dist/assets/today-page-Dipns9tl.js +1 -0
  116. package/dist/assets/training-load-page-B78e1-o-.js +1 -0
  117. package/dist/assets/{ui-B9TWEtCx.js → ui-uo_bNP7c.js} +1 -1
  118. package/dist/assets/{use-anchored-overlay-position-BY4kNzPj.js → use-anchored-overlay-position-BSxFX6Hi.js} +1 -1
  119. package/dist/assets/{use-psyche-focus-target-BhNedCZB.js → use-psyche-focus-target-1GLkhYiv.js} +1 -1
  120. package/dist/assets/{user-badge-ByhC6bMU.js → user-badge-C4eZu1e_.js} +1 -1
  121. package/dist/assets/{user-select-field-fx129Uh6.js → user-select-field-CmKwcbZt.js} +1 -1
  122. package/dist/assets/{utility-widgets-ilORjDmg.js → utility-widgets-B06wQFrd.js} +2 -2
  123. package/dist/assets/{vendor-BwL6m4SE.js → vendor-B7FKSwHK.js} +222 -212
  124. package/dist/assets/{vitals-page-mdEqIm_9.js → vitals-page-BC7QFsm2.js} +1 -1
  125. package/dist/assets/{weekly-review-page-C8W-yg5r.js → weekly-review-page-BjNsNoWj.js} +1 -1
  126. package/dist/assets/{weight-loss-page-BApTknCn.js → weight-loss-page-BOahGY9r.js} +1 -1
  127. package/dist/assets/{wiki-article-markdown-DBccllQg.js → wiki-article-markdown-DO47HnZf.js} +2 -2
  128. package/dist/assets/{wiki-editor-page-BfRfH1O3.js → wiki-editor-page-OWRUHl4O.js} +5 -5
  129. package/dist/assets/{wiki-ingest-history-page-C-6H3MU6.js → wiki-ingest-history-page-CuHpg2lZ.js} +1 -1
  130. package/dist/assets/{wiki-ingest-modal-DnlhByD_.js → wiki-ingest-modal-EZ3kX-vA.js} +1 -1
  131. package/dist/assets/wiki-page-BPV3HIgu.js +1 -0
  132. package/dist/assets/{workbench-flow-page-_-NKIx5R.js → workbench-flow-page-C53KueEz.js} +3 -3
  133. package/dist/assets/{workbench-page-NIAzggwX.js → workbench-page-DJ7nT2JQ.js} +1 -1
  134. package/dist/assets/workout-detail-page-Dhyu0q7o.js +2 -0
  135. package/dist/index.html +8 -8
  136. package/dist/openclaw/api-client.js +28 -2
  137. package/dist/openclaw/local-runtime.js +31 -14
  138. package/dist/openclaw/parity.d.ts +1 -1
  139. package/dist/openclaw/parity.js +10 -0
  140. package/dist/openclaw/routes.js +78 -0
  141. package/dist/openclaw/tools.js +42 -0
  142. package/dist/server/apps/api/migrations/072_artifact_store.sql +106 -0
  143. package/dist/server/{server → apps/api}/src/app.js +365 -4
  144. package/dist/server/{server → apps/api}/src/connectors/box-registry.js +3 -3
  145. package/dist/server/{server → apps/api}/src/db.js +23 -4
  146. package/dist/server/{server → apps/api}/src/health-weight-loss.js +1 -1
  147. package/dist/server/{server → apps/api}/src/openapi.js +570 -1
  148. package/dist/server/{server → apps/api}/src/questionnaire-seeds.js +1 -1
  149. package/dist/server/{server → apps/api}/src/repositories/ai-connectors.js +1 -1
  150. package/dist/server/apps/api/src/repositories/entity-links.js +66 -0
  151. package/dist/server/{server → apps/api}/src/repositories/habits.js +1 -1
  152. package/dist/server/apps/api/src/services/artifacts.js +1059 -0
  153. package/dist/server/{server → apps/api}/src/services/companion-iroh.js +4 -1
  154. package/dist/server/{server → apps/api}/src/services/doctor.js +3 -3
  155. package/dist/server/{server → apps/api}/src/services/entity-crud.js +22 -0
  156. package/dist/server/{server → apps/api}/src/services/gamification-assets.js +1 -1
  157. package/dist/server/{server → apps/api}/src/services/gamification.js +1 -1
  158. package/dist/server/{server → apps/api}/src/services/knowledge-graph.js +48 -3
  159. package/dist/server/{server → apps/api}/src/services/psyche-observation-calendar.js +1 -0
  160. package/dist/server/{server → apps/api}/src/types.js +4 -2
  161. package/dist/server/{server → apps/api}/src/watch-mobile.js +1 -1
  162. package/dist/server/{src → apps/web/src}/lib/api.js +69 -0
  163. package/dist/server/{src → apps/web/src}/lib/entity-visuals.js +10 -1
  164. package/dist/server/{src → apps/web/src}/lib/knowledge-graph-types.js +9 -0
  165. package/openclaw.plugin.json +2 -1
  166. package/package.json +3 -3
  167. package/server/index.js +3 -3
  168. package/server/migrations/072_artifact_store.sql +106 -0
  169. package/skills/forge-openclaw/SKILL.md +60 -7
  170. package/skills/forge-openclaw/entity_conversation_playbooks.md +212 -14
  171. package/skills/forge-openclaw/psyche_entity_playbooks.md +20 -0
  172. package/dist/assets/execution-board-D66C_ikW.js +0 -1
  173. package/dist/assets/goals-page-CQ2lJMzI.js +0 -1
  174. package/dist/assets/habits-page-a7KVPaQp.js +0 -1
  175. package/dist/assets/index-ClJbJhca.css +0 -1
  176. package/dist/assets/index-FpGANF9S.js +0 -2
  177. package/dist/assets/knowledge-graph-page-DxEBaEke.js +0 -1
  178. package/dist/assets/notes-page-DvHMcQey.js +0 -1
  179. package/dist/assets/overview-page-Z5vaUTm3.js +0 -1
  180. package/dist/assets/page-hero-DvrM83_C.js +0 -1
  181. package/dist/assets/pill-cluster-DYI3Ibj8.js +0 -1
  182. package/dist/assets/project-detail-page-B9PqyPu9.js +0 -1
  183. package/dist/assets/project-management-hierarchy-page-DXK14jn0.js +0 -1
  184. package/dist/assets/projects-page-CdAk-ByT.js +0 -1
  185. package/dist/assets/psyche-behaviors-page-CbhhTfU2.js +0 -5
  186. package/dist/assets/psyche-mode-guide-page-CR8e984W.js +0 -1
  187. package/dist/assets/psyche-modes-page-lQdpAcY3.js +0 -1
  188. package/dist/assets/psyche-page-CTdIDkw9.js +0 -1
  189. package/dist/assets/psyche-patterns-page-Drgm-f7I.js +0 -5
  190. package/dist/assets/psyche-questionnaire-run-detail-page-SYndwtF3.js +0 -1
  191. package/dist/assets/psyche-reports-page-Cn0EBndy.js +0 -1
  192. package/dist/assets/psyche-schemas-beliefs-page-Bab4xSWv.js +0 -9
  193. package/dist/assets/rewards-page-FxUXB76B.js +0 -1
  194. package/dist/assets/settings-bin-page-DT8JJero.js +0 -1
  195. package/dist/assets/settings-models-page-CZHG3t7W.js +0 -1
  196. package/dist/assets/task-detail-page-B3SMFZQ3.js +0 -1
  197. package/dist/assets/timebox-planning-dialog-BtFuVoA1.js +0 -1
  198. package/dist/assets/today-page-CHGpLEZ3.js +0 -1
  199. package/dist/assets/training-load-page-GZJF-Yy5.js +0 -1
  200. package/dist/assets/wiki-page-DPZ55e3x.js +0 -1
  201. package/dist/assets/workout-detail-page-3fxr6HL4.js +0 -2
  202. /package/dist/server/{server → apps/api}/migrations/001_core.sql +0 -0
  203. /package/dist/server/{server → apps/api}/migrations/002_psyche.sql +0 -0
  204. /package/dist/server/{server → apps/api}/migrations/003_habits.sql +0 -0
  205. /package/dist/server/{server → apps/api}/migrations/004_habit_links.sql +0 -0
  206. /package/dist/server/{server → apps/api}/migrations/005_habit_psyche_links.sql +0 -0
  207. /package/dist/server/{server → apps/api}/migrations/006_work_adjustments.sql +0 -0
  208. /package/dist/server/{server → apps/api}/migrations/007_weekly_review_closures.sql +0 -0
  209. /package/dist/server/{server → apps/api}/migrations/008_calendar_execution.sql +0 -0
  210. /package/dist/server/{server → apps/api}/migrations/009_true_calendar_events.sql +0 -0
  211. /package/dist/server/{server → apps/api}/migrations/010_calendar_selection_state.sql +0 -0
  212. /package/dist/server/{server → apps/api}/migrations/011_calendar_timezone_backfill.sql +0 -0
  213. /package/dist/server/{server → apps/api}/migrations/012_work_block_ranges.sql +0 -0
  214. /package/dist/server/{server → apps/api}/migrations/013_microsoft_local_auth_settings.sql +0 -0
  215. /package/dist/server/{server → apps/api}/migrations/014_note_tags_and_ephemeral.sql +0 -0
  216. /package/dist/server/{server → apps/api}/migrations/015_multi_user_and_strategies.sql +0 -0
  217. /package/dist/server/{server → apps/api}/migrations/016_health_companion.sql +0 -0
  218. /package/dist/server/{server → apps/api}/migrations/016_strategy_contracts_and_user_graph.sql +0 -0
  219. /package/dist/server/{server → apps/api}/migrations/017_preferences.sql +0 -0
  220. /package/dist/server/{server → apps/api}/migrations/018_preference_catalogs.sql +0 -0
  221. /package/dist/server/{server → apps/api}/migrations/019_wiki_memory.sql +0 -0
  222. /package/dist/server/{server → apps/api}/migrations/020_wiki_page_hierarchy.sql +0 -0
  223. /package/dist/server/{server → apps/api}/migrations/021_hide_evidence_from_wiki_index.sql +0 -0
  224. /package/dist/server/{server → apps/api}/migrations/022_wiki_ingest_background.sql +0 -0
  225. /package/dist/server/{server → apps/api}/migrations/023_diagnostic_logs.sql +0 -0
  226. /package/dist/server/{server → apps/api}/migrations/024_questionnaires.sql +0 -0
  227. /package/dist/server/{server → apps/api}/migrations/025_ai_model_connections.sql +0 -0
  228. /package/dist/server/{server → apps/api}/migrations/026_custom_theme_settings.sql +0 -0
  229. /package/dist/server/{server → apps/api}/migrations/027_ai_processors.sql +0 -0
  230. /package/dist/server/{server → apps/api}/migrations/028_movement_domain.sql +0 -0
  231. /package/dist/server/{server → apps/api}/migrations/029_watch_micro_capture.sql +0 -0
  232. /package/dist/server/{server → apps/api}/migrations/030_surface_layouts.sql +0 -0
  233. /package/dist/server/{server → apps/api}/migrations/031_ai_processor_runtime_upgrades.sql +0 -0
  234. /package/dist/server/{server → apps/api}/migrations/032_ai_connectors.sql +0 -0
  235. /package/dist/server/{server → apps/api}/migrations/033_movement_trip_point_sync.sql +0 -0
  236. /package/dist/server/{server → apps/api}/migrations/034_movement_segment_sync.sql +0 -0
  237. /package/dist/server/{server → apps/api}/migrations/035_google_local_auth_settings.sql +0 -0
  238. /package/dist/server/{server → apps/api}/migrations/036_google_local_auth_client_secret.sql +0 -0
  239. /package/dist/server/{server → apps/api}/migrations/037_workbench_public_inputs_and_run_inputs.sql +0 -0
  240. /package/dist/server/{server → apps/api}/migrations/038_data_management_settings.sql +0 -0
  241. /package/dist/server/{server → apps/api}/migrations/039_life_force_and_action_points.sql +0 -0
  242. /package/dist/server/{server → apps/api}/migrations/040_screen_time_domain.sql +0 -0
  243. /package/dist/server/{server → apps/api}/migrations/041_companion_source_states.sql +0 -0
  244. /package/dist/server/{server → apps/api}/migrations/042_movement_boxes.sql +0 -0
  245. /package/dist/server/{server → apps/api}/migrations/043_movement_box_overlap_overrides.sql +0 -0
  246. /package/dist/server/{server → apps/api}/migrations/044_macos_local_calendar_provider.sql +0 -0
  247. /package/dist/server/{server → apps/api}/migrations/045_sleep_nights_and_raw_segments.sql +0 -0
  248. /package/dist/server/{server → apps/api}/migrations/046_work_item_hierarchy.sql +0 -0
  249. /package/dist/server/{server → apps/api}/migrations/047_sleep_source_records.sql +0 -0
  250. /package/dist/server/{server → apps/api}/migrations/048_task_run_git_context.sql +0 -0
  251. /package/dist/server/{server → apps/api}/migrations/049_agent_runtime_sessions.sql +0 -0
  252. /package/dist/server/{server → apps/api}/migrations/050_agent_token_bootstrap_policy.sql +0 -0
  253. /package/dist/server/{server → apps/api}/migrations/051_agent_token_scope_policy.sql +0 -0
  254. /package/dist/server/{server → apps/api}/migrations/052_agent_identity_tightening.sql +0 -0
  255. /package/dist/server/{server → apps/api}/migrations/053_agent_runtime_session_canonical_labels.sql +0 -0
  256. /package/dist/server/{server → apps/api}/migrations/054_sqlite_backed_wiki_memory.sql +0 -0
  257. /package/dist/server/{server → apps/api}/migrations/055_gamification_progression.sql +0 -0
  258. /package/dist/server/{server → apps/api}/migrations/056_gamification_equipment.sql +0 -0
  259. /package/dist/server/{server → apps/api}/migrations/057_gamification_catalog_cleanup.sql +0 -0
  260. /package/dist/server/{server → apps/api}/migrations/058_gamification_theme_preference.sql +0 -0
  261. /package/dist/server/{server → apps/api}/migrations/059_data_backup_retention.sql +0 -0
  262. /package/dist/server/{server → apps/api}/migrations/060_psyche_devrage_metrics.sql +0 -0
  263. /package/dist/server/{server → apps/api}/migrations/061_health_workout_raw_evidence.sql +0 -0
  264. /package/dist/server/{server → apps/api}/migrations/062_health_mobile_sync_sessions.sql +0 -0
  265. /package/dist/server/{server → apps/api}/migrations/063_psyche_flashcards.sql +0 -0
  266. /package/dist/server/{server → apps/api}/migrations/064_health_workout_time_series_identity.sql +0 -0
  267. /package/dist/server/{server → apps/api}/migrations/065_weight_loss_nutrition_insights.sql +0 -0
  268. /package/dist/server/{server → apps/api}/migrations/066_watch_action_receipts.sql +0 -0
  269. /package/dist/server/{server → apps/api}/migrations/067_weight_loss_daily_active_overrides.sql +0 -0
  270. /package/dist/server/{server → apps/api}/migrations/068_remove_generated_movement_wiki_logs.sql +0 -0
  271. /package/dist/server/{server → apps/api}/migrations/069_psyche_devrage_cumulative_rage.sql +0 -0
  272. /package/dist/server/{server → apps/api}/migrations/070_health_mobile_sync_completion_index.sql +0 -0
  273. /package/dist/server/{server → apps/api}/migrations/071_agent_runtime_claude_identity.sql +0 -0
  274. /package/dist/server/{server → apps/api}/src/data-management-types.js +0 -0
  275. /package/dist/server/{server → apps/api}/src/debug.js +0 -0
  276. /package/dist/server/{server → apps/api}/src/demo-data.js +0 -0
  277. /package/dist/server/{server → apps/api}/src/discovery-advertiser.js +0 -0
  278. /package/dist/server/{server → apps/api}/src/e2e-server.js +0 -0
  279. /package/dist/server/{server → apps/api}/src/errors.js +0 -0
  280. /package/dist/server/{server → apps/api}/src/health-workout-adapters.js +0 -0
  281. /package/dist/server/{server → apps/api}/src/health-workout-analytics.js +0 -0
  282. /package/dist/server/{server → apps/api}/src/health.js +0 -0
  283. /package/dist/server/{server → apps/api}/src/index.js +0 -0
  284. /package/dist/server/{server → apps/api}/src/managers/base.js +0 -0
  285. /package/dist/server/{server → apps/api}/src/managers/contracts.js +0 -0
  286. /package/dist/server/{server → apps/api}/src/managers/platform/api-gateway-manager.js +0 -0
  287. /package/dist/server/{server → apps/api}/src/managers/platform/audit-manager.js +0 -0
  288. /package/dist/server/{server → apps/api}/src/managers/platform/authentication-manager.js +0 -0
  289. /package/dist/server/{server → apps/api}/src/managers/platform/authorization-manager.js +0 -0
  290. /package/dist/server/{server → apps/api}/src/managers/platform/background-job-manager.js +0 -0
  291. /package/dist/server/{server → apps/api}/src/managers/platform/configuration-manager.js +0 -0
  292. /package/dist/server/{server → apps/api}/src/managers/platform/database-manager.js +0 -0
  293. /package/dist/server/{server → apps/api}/src/managers/platform/event-bus-manager.js +0 -0
  294. /package/dist/server/{server → apps/api}/src/managers/platform/external-service-manager.js +0 -0
  295. /package/dist/server/{server → apps/api}/src/managers/platform/health-manager.js +0 -0
  296. /package/dist/server/{server → apps/api}/src/managers/platform/llm-manager.js +0 -0
  297. /package/dist/server/{server → apps/api}/src/managers/platform/migration-manager.js +0 -0
  298. /package/dist/server/{server → apps/api}/src/managers/platform/mock-workbench-provider.js +0 -0
  299. /package/dist/server/{server → apps/api}/src/managers/platform/openai-responses-provider.js +0 -0
  300. /package/dist/server/{server → apps/api}/src/managers/platform/search-index-manager.js +0 -0
  301. /package/dist/server/{server → apps/api}/src/managers/platform/secrets-manager.js +0 -0
  302. /package/dist/server/{server → apps/api}/src/managers/platform/session-manager.js +0 -0
  303. /package/dist/server/{server → apps/api}/src/managers/platform/storage-manager.js +0 -0
  304. /package/dist/server/{server → apps/api}/src/managers/platform/token-manager.js +0 -0
  305. /package/dist/server/{server → apps/api}/src/managers/platform/transaction-manager.js +0 -0
  306. /package/dist/server/{server → apps/api}/src/managers/platform/trusted-network.js +0 -0
  307. /package/dist/server/{server → apps/api}/src/managers/runtime.js +0 -0
  308. /package/dist/server/{server → apps/api}/src/managers/type-guards.js +0 -0
  309. /package/dist/server/{server → apps/api}/src/movement.js +0 -0
  310. /package/dist/server/{server → apps/api}/src/preferences-seeds.js +0 -0
  311. /package/dist/server/{server → apps/api}/src/preferences-types.js +0 -0
  312. /package/dist/server/{server → apps/api}/src/psyche-types.js +0 -0
  313. /package/dist/server/{server → apps/api}/src/questionnaire-flow.js +0 -0
  314. /package/dist/server/{server → apps/api}/src/questionnaire-types.js +0 -0
  315. /package/dist/server/{server → apps/api}/src/repositories/activity-events.js +0 -0
  316. /package/dist/server/{server → apps/api}/src/repositories/agent-runtime-sessions.js +0 -0
  317. /package/dist/server/{server → apps/api}/src/repositories/ai-processors.js +0 -0
  318. /package/dist/server/{server → apps/api}/src/repositories/calendar.js +0 -0
  319. /package/dist/server/{server → apps/api}/src/repositories/collaboration.js +0 -0
  320. /package/dist/server/{server → apps/api}/src/repositories/deleted-entities.js +0 -0
  321. /package/dist/server/{server → apps/api}/src/repositories/diagnostic-logs.js +0 -0
  322. /package/dist/server/{server → apps/api}/src/repositories/domains.js +0 -0
  323. /package/dist/server/{server → apps/api}/src/repositories/entity-ownership.js +0 -0
  324. /package/dist/server/{server → apps/api}/src/repositories/event-log.js +0 -0
  325. /package/dist/server/{server → apps/api}/src/repositories/gamification.js +0 -0
  326. /package/dist/server/{server → apps/api}/src/repositories/goals.js +0 -0
  327. /package/dist/server/{server → apps/api}/src/repositories/model-settings.js +0 -0
  328. /package/dist/server/{server → apps/api}/src/repositories/notes.js +0 -0
  329. /package/dist/server/{server → apps/api}/src/repositories/preferences.js +0 -0
  330. /package/dist/server/{server → apps/api}/src/repositories/projects.js +0 -0
  331. /package/dist/server/{server → apps/api}/src/repositories/psyche.js +0 -0
  332. /package/dist/server/{server → apps/api}/src/repositories/questionnaires.js +0 -0
  333. /package/dist/server/{server → apps/api}/src/repositories/rewards.js +0 -0
  334. /package/dist/server/{server → apps/api}/src/repositories/settings.js +0 -0
  335. /package/dist/server/{server → apps/api}/src/repositories/strategies.js +0 -0
  336. /package/dist/server/{server → apps/api}/src/repositories/surface-layouts.js +0 -0
  337. /package/dist/server/{server → apps/api}/src/repositories/tags.js +0 -0
  338. /package/dist/server/{server → apps/api}/src/repositories/task-runs.js +0 -0
  339. /package/dist/server/{server → apps/api}/src/repositories/tasks.js +0 -0
  340. /package/dist/server/{server → apps/api}/src/repositories/users.js +0 -0
  341. /package/dist/server/{server → apps/api}/src/repositories/weekly-reviews.js +0 -0
  342. /package/dist/server/{server → apps/api}/src/repositories/wiki-memory.js +0 -0
  343. /package/dist/server/{server → apps/api}/src/repositories/work-adjustments.js +0 -0
  344. /package/dist/server/{server → apps/api}/src/runtime-data-root.js +0 -0
  345. /package/dist/server/{server → apps/api}/src/screen-time.js +0 -0
  346. /package/dist/server/{server → apps/api}/src/seed-demo.js +0 -0
  347. /package/dist/server/{server → apps/api}/src/services/calendar-runtime.js +0 -0
  348. /package/dist/server/{server → apps/api}/src/services/context.js +0 -0
  349. /package/dist/server/{server → apps/api}/src/services/dashboard.js +0 -0
  350. /package/dist/server/{server → apps/api}/src/services/data-management.js +0 -0
  351. /package/dist/server/{server → apps/api}/src/services/devrage-scanner.js +0 -0
  352. /package/dist/server/{server → apps/api}/src/services/devrage.js +0 -0
  353. /package/dist/server/{server → apps/api}/src/services/git-helper.js +0 -0
  354. /package/dist/server/{server → apps/api}/src/services/google-calendar-oauth-config.js +0 -0
  355. /package/dist/server/{server → apps/api}/src/services/insights.js +0 -0
  356. /package/dist/server/{server → apps/api}/src/services/legacy-wiki-markdown-import.js +0 -0
  357. /package/dist/server/{server → apps/api}/src/services/life-force-model.js +0 -0
  358. /package/dist/server/{server → apps/api}/src/services/life-force.js +0 -0
  359. /package/dist/server/{server → apps/api}/src/services/macos-calendar-helper.js +0 -0
  360. /package/dist/server/{server → apps/api}/src/services/openai-codex-oauth.js +0 -0
  361. /package/dist/server/{server → apps/api}/src/services/projects.js +0 -0
  362. /package/dist/server/{server → apps/api}/src/services/psyche.js +0 -0
  363. /package/dist/server/{server → apps/api}/src/services/relations.js +0 -0
  364. /package/dist/server/{server → apps/api}/src/services/reviews.js +0 -0
  365. /package/dist/server/{server → apps/api}/src/services/run-recovery.js +0 -0
  366. /package/dist/server/{server → apps/api}/src/services/tagging.js +0 -0
  367. /package/dist/server/{server → apps/api}/src/services/task-run-watchdog.js +0 -0
  368. /package/dist/server/{server → apps/api}/src/services/work-time.js +0 -0
  369. /package/dist/server/{server → apps/api}/src/web.js +0 -0
  370. /package/dist/server/{src → apps/web/src}/components/customization/utility-widgets.js +0 -0
  371. /package/dist/server/{src → apps/web/src}/components/ui/info-tooltip.js +0 -0
  372. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/calendar/calendar-boxes.js +0 -0
  373. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/goals/goals-boxes.js +0 -0
  374. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/habits/habits-boxes.js +0 -0
  375. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/health/health-boxes.js +0 -0
  376. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/insights/insights-boxes.js +0 -0
  377. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/kanban/kanban-boxes.js +0 -0
  378. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/movement/movement-boxes.js +0 -0
  379. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/notes/notes-boxes.js +0 -0
  380. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/overview/overview-boxes.js +0 -0
  381. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/preferences/preferences-boxes.js +0 -0
  382. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/projects/projects-boxes.js +0 -0
  383. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/psyche/psyche-boxes.js +0 -0
  384. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/questionnaires/questionnaires-boxes.js +0 -0
  385. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/review/review-boxes.js +0 -0
  386. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/shared/define-workbench-box.js +0 -0
  387. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/shared/generic-node-view.js +0 -0
  388. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/strategies/strategies-boxes.js +0 -0
  389. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/tasks/tasks-boxes.js +0 -0
  390. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/today/today-boxes.js +0 -0
  391. /package/dist/server/{src → apps/web/src}/components/workbench-boxes/wiki/wiki-boxes.js +0 -0
  392. /package/dist/server/{src → apps/web/src}/lib/api-error.js +0 -0
  393. /package/dist/server/{src → apps/web/src}/lib/calendar-name-deduper.js +0 -0
  394. /package/dist/server/{src → apps/web/src}/lib/data-management-types.js +0 -0
  395. /package/dist/server/{src → apps/web/src}/lib/date-keys.js +0 -0
  396. /package/dist/server/{src → apps/web/src}/lib/diagnostics.js +0 -0
  397. /package/dist/server/{src → apps/web/src}/lib/gamification-catalog.js +0 -0
  398. /package/dist/server/{src → apps/web/src}/lib/knowledge-graph.js +0 -0
  399. /package/dist/server/{src → apps/web/src}/lib/psyche-schemas.js +0 -0
  400. /package/dist/server/{src → apps/web/src}/lib/psyche-types.js +0 -0
  401. /package/dist/server/{src → apps/web/src}/lib/questionnaire-types.js +0 -0
  402. /package/dist/server/{src → apps/web/src}/lib/runtime-paths.js +0 -0
  403. /package/dist/server/{src → apps/web/src}/lib/schemas.js +0 -0
  404. /package/dist/server/{src → apps/web/src}/lib/snapshot-normalizer.js +0 -0
  405. /package/dist/server/{src → apps/web/src}/lib/theme-system.js +0 -0
  406. /package/dist/server/{src → apps/web/src}/lib/types.js +0 -0
  407. /package/dist/server/{src → apps/web/src}/lib/utils.js +0 -0
  408. /package/dist/server/{src → apps/web/src}/lib/weight-loss-energy-model.js +0 -0
  409. /package/dist/server/{src → apps/web/src}/lib/weight-loss-types.js +0 -0
  410. /package/dist/server/{src → apps/web/src}/lib/workbench/boxes.js +0 -0
  411. /package/dist/server/{src → apps/web/src}/lib/workbench/contracts.js +0 -0
  412. /package/dist/server/{src → apps/web/src}/lib/workbench/nodes.js +0 -0
  413. /package/dist/server/{src → apps/web/src}/lib/workbench/registry.js +0 -0
  414. /package/dist/server/{src → apps/web/src}/lib/workbench/runtime.js +0 -0
  415. /package/dist/server/{src → apps/web/src}/lib/workbench/tool-catalog.js +0 -0
@@ -45,6 +45,7 @@ import { getGamificationAssetStatus, installGamificationAssetStyle } from "./ser
45
45
  import { getInsightsPayload } from "./services/insights.js";
46
46
  import { buildLifeForcePayload, createFatigueSignal, listLifeForceTemplates, resolveLifeForceUser, updateLifeForceProfile, updateLifeForceTemplate } from "./services/life-force.js";
47
47
  import { createEntities, deleteEntities, deleteEntity, getSettingsBinPayload, restoreEntities, searchEntities, updateEntities } from "./services/entity-crud.js";
48
+ import { artifactEnrichmentRequestSchema, artifactListQuerySchema, artifactMetadataPatchSchema, artifactTrustPatchSchema, artifactUploadSchema, createArtifactFromUpload, entityLinkInputSchema, enrichArtifactWithLlm, getArtifactById, listArtifactAuditEvents, listArtifactVersions, listArtifacts, patchArtifactTrust, readArtifactDownload, replaceArtifactEntityLinks, rescanArtifact, updateArtifactMetadata } from "./services/artifacts.js";
48
49
  import { getPsycheOverview } from "./services/psyche.js";
49
50
  import { getPsycheMetricsViewData, syncDevrageMetricHistoryIfNeeded } from "./services/devrage.js";
50
51
  import { exportPsycheObservationCalendar, getPsycheObservationCalendar } from "./services/psyche-observation-calendar.js";
@@ -2219,6 +2220,9 @@ function classifyOnboardingEntity(entityType) {
2219
2220
  if (entityType === "wiki_page" || entityType === "calendar_connection") {
2220
2221
  return "specialized_crud_entity";
2221
2222
  }
2223
+ if (entityType === "artifact") {
2224
+ return "specialized_crud_entity";
2225
+ }
2222
2226
  if (entityType === "movement" ||
2223
2227
  entityType === "life_force" ||
2224
2228
  entityType === "workbench") {
@@ -2243,6 +2247,8 @@ function buildPreferredMutationPath(entityType) {
2243
2247
  return "Use /api/v1/wiki/pages with POST or PATCH for page CRUD.";
2244
2248
  case "calendar_connection":
2245
2249
  return "Use /api/v1/calendar/discovery or /api/v1/calendar/macos-local/discovery before setup when needed; use /api/v1/calendar/connections with POST, PATCH, DELETE, rediscovery, and sync for connection lifecycle work.";
2250
+ case "artifact":
2251
+ return "Use POST /api/v1/artifacts for trusted file upload, GET/PATCH /api/v1/artifacts/:id for metadata, POST /api/v1/artifacts/:id/links for generic entity links, POST /api/v1/artifacts/:id/scan for static rescans, POST /api/v1/artifacts/:id/enrich for optional LLM metadata enrichment, POST /api/v1/artifacts/:id/trust for trusted state changes, GET /api/v1/artifacts/:id/versions and /audit for history, and GET /api/v1/artifacts/:id/download only for human operator downloads. Batch CRUD may search, patch metadata, soft-delete, restore, and hard-delete metadata only; it must not create file artifacts or download bytes.";
2246
2252
  case "task_run":
2247
2253
  return "Use the task-run action routes to start, heartbeat, focus, complete, or release live work.";
2248
2254
  case "questionnaire_run":
@@ -2288,6 +2294,8 @@ function buildPreferredMutationTool(entityType) {
2288
2294
  return "forge_upsert_wiki_page";
2289
2295
  case "calendar_connection":
2290
2296
  return "forge_connect_calendar_provider | forge_sync_calendar_connection | mirrored calendar connection routes";
2297
+ case "artifact":
2298
+ return "forge_call_artifact_route | forge_search_entities | forge_update_entities | forge_delete_entities | forge_restore_entities";
2291
2299
  case "task_run":
2292
2300
  return "forge_start_task_run | forge_heartbeat_task_run | forge_focus_task_run | forge_complete_task_run | forge_release_task_run";
2293
2301
  case "questionnaire_run":
@@ -2324,6 +2332,8 @@ function buildPreferredReadPath(entityType) {
2324
2332
  return "/api/v1/wiki/pages/:id";
2325
2333
  case "calendar_connection":
2326
2334
  return "/api/v1/calendar/connections";
2335
+ case "artifact":
2336
+ return "/api/v1/artifacts";
2327
2337
  case "task_run":
2328
2338
  return "/api/v1/operator/context";
2329
2339
  case "questionnaire_run":
@@ -2974,6 +2984,75 @@ const AGENT_ONBOARDING_ENTITY_CATALOG = [
2974
2984
  }
2975
2985
  ]
2976
2986
  }),
2987
+ enrichOnboardingEntityGuide({
2988
+ entityType: "artifact",
2989
+ purpose: "A trusted stored file artifact with precise metadata, provenance, static safety scan results, optional LLM-assisted metadata enrichment, generic links to other Forge entities, version history, audit events, and human-only download access.",
2990
+ minimumCreateFields: ["originalFileName", "contentBase64"],
2991
+ relationshipRules: [
2992
+ "Artifact file upload is not batch CRUD. Use POST /api/v1/artifacts so Forge can enforce trust, store bytes content-addressably, run static inspection, preserve provenance, and create the metadata record.",
2993
+ "Artifact relationships use the general entity_links model and are exposed as artifact.links with sourceEntityType/sourceEntityId and targetEntityType/targetEntityId; do not invent artifact-specific link routes or relationship semantics.",
2994
+ "Batch CRUD can search, patch metadata, soft-delete, restore, or hard-delete artifact metadata, but it must not create file artifacts or transfer bytes.",
2995
+ "Only trusted human sessions or trusted/autonomous agent tokens with artifact.create and artifact.uploadBytes may upload bytes.",
2996
+ "Agents must not download, open, execute, transform, parse with external programs, or autonomously run stored files. GET /api/v1/artifacts/:id/download is for human operator sessions only.",
2997
+ "LLM enrichment may fill missing title, shortDescription, description, tags, and danger interpretation from safe metadata and static text samples; it must never lower the deterministic scanner danger score."
2998
+ ],
2999
+ searchHints: [
3000
+ "Before uploading, ask only for missing decision-critical metadata: what the file is, why it should be preserved, where it came from, and which Forge records it should stay linked to.",
3001
+ "If the user gave a file but no metadata, accept a concise title and provenance as enough; optional tags and links can be added later.",
3002
+ "If the file may be sensitive or risky, confirm whether it should be stored at all and whether download should remain disabled or human-only.",
3003
+ "For a review request, list or read artifact metadata and safety findings first; do not ask for upload details unless the user is adding a file."
3004
+ ],
3005
+ fieldGuide: [
3006
+ {
3007
+ name: "title",
3008
+ type: "string",
3009
+ required: false,
3010
+ description: "Human-readable artifact title. LLM enrichment may fill it when missing."
3011
+ },
3012
+ {
3013
+ name: "shortDescription",
3014
+ type: "string",
3015
+ required: false,
3016
+ description: "Compact display summary. LLM enrichment may fill it when missing."
3017
+ },
3018
+ {
3019
+ name: "description",
3020
+ type: "string",
3021
+ required: false,
3022
+ description: "Longer purpose, provenance, and retrieval context."
3023
+ },
3024
+ {
3025
+ name: "originalFileName",
3026
+ type: "string",
3027
+ required: true,
3028
+ description: "Original user-facing filename; extension must be allowed."
3029
+ },
3030
+ {
3031
+ name: "contentBase64",
3032
+ type: "string",
3033
+ required: true,
3034
+ description: "Base64 bytes sent only through the dedicated artifact upload route."
3035
+ },
3036
+ {
3037
+ name: "sourceLabel",
3038
+ type: "string",
3039
+ required: false,
3040
+ description: "Provenance label such as source, project, export, or sender."
3041
+ },
3042
+ {
3043
+ name: "links",
3044
+ type: "Array<{ entityType, entityId, anchorKey?, relationship? }>",
3045
+ required: false,
3046
+ description: "Generic Forge entity links stored through entity_links."
3047
+ },
3048
+ {
3049
+ name: "useLlmEnrichment",
3050
+ type: "boolean",
3051
+ required: false,
3052
+ description: "When true and an LLM profile is configured, Forge fills missing metadata from safe scan context."
3053
+ }
3054
+ ]
3055
+ }),
2977
3056
  enrichOnboardingEntityGuide({
2978
3057
  entityType: "movement",
2979
3058
  purpose: "The specialized Movement surface for day, month, all-time, timeline, trip, place, selection, settings, and manual overlay work.",
@@ -3105,6 +3184,7 @@ const AGENT_ONBOARDING_CONVERSATION_RULES = [
3105
3184
  "If the user already answered the normal opening question, do not repeat it. Move to the next missing clarification.",
3106
3185
  "Do not over-therapize logistical entities. For tasks, calendar events, work blocks, timeboxes, and task runs, one brief confirming sentence plus one question is usually enough.",
3107
3186
  "After each substantive answer, briefly say what is becoming clearer and ask only for the next thing that still changes the record shape or usefulness.",
3187
+ "Use the active-listening turn contract before deepening: reflect the specific stake, working shape, or product object in one sentence; decide internally whether the next answer would change wording, placement, timing, route scope, support action, verification read, preservation choice, or consent; then ask one question. For Psyche, name the felt stake, protection, prediction, payoff, cost, or value conflict, and when a functional loop or belief sentence is already visible, offer one tentative hypothesis plus one fit-or-correction question instead of another broad exploration. For logistical records, keep the reflection short and ask for the operational detail.",
3108
3188
  "Before asking a follow-up, know what the user's answer would change: save, update, review, link, schedule, correct, run, publish, preserve, enrich, open the UI, or stop. If no possible answer would change the next action, summarize and act instead of asking.",
3109
3189
  "Use a minimum save-readiness checkpoint before asking another follow-up. For normal batch entities, act when you have accepted wording, meaningful body, and any ownership or placement that changes later use; do not ask for tags, links, priority, dates, assignees, or status just because optional fields exist. For operational records, act when the target action plus the time, object, or state that makes it truthful is clear. For read-model surfaces, read once the practical question and answer-changing scope are clear. For specialized Movement, Life Force, and Workbench writes, act once the lane plus target span/object/weekday/flow/run/node and intended correction or effect are clear.",
3110
3190
  "For strategic, reflective, or emotionally meaningful non-Psyche records, ask what feels important to keep true before you ask for labels, dates, or taxonomy.",
@@ -3122,6 +3202,8 @@ const AGENT_ONBOARDING_CONVERSATION_RULES = [
3122
3202
  "For read and overview requests, ask for human or bot user scope only when the answer would meaningfully differ across owners; otherwise keep the next question focused on the user's practical question.",
3123
3203
  "The opening question should help the user understand what they are actually trying to save, decide, review, or change, not make them perform the schema out loud.",
3124
3204
  "If the user already named the exact correction in usable language, confirm only the missing scope, timing, or route-selecting detail that still matters, then act.",
3205
+ "Use the known-target fast path when the user already supplied the object, action, and likely lane: for normal entities ask only for parent, owner, or duplicate disambiguation that changes the write; for task hierarchy ask only for the project, issue, or parent task that changes placement; for Movement ask only for the missing interval, boundary, saved object, or confirmation; for Life Force ask only for the weekday, profile field, signal intensity, or planning effect; for Workbench ask only for the missing flow, run, node, input, output, or preservation choice; for direct Psyche saves ask one accuracy or consent question instead of restarting exploration.",
3206
+ "Use the route execution handoff before any read, write, run, repair, or publish call: freeze the accepted user-facing target, choose exactly one lane, use batch CRUD only for catalog entities, use named tools or documented routes for specialized CRUD and action workflows, and for Movement, Life Force, or Workbench verify routeKey, method, path, and pathParams from live onboarding methodRoutes before calling. Never hide placeholders in query or body, and never guess a nearby path.",
3125
3207
  "Keep API and architecture nouns out of user-facing questions unless the user asks about implementation. Do not ask the user about surfaces, route families, CRUD, payloads, mutation paths, or read paths; ask about the human object such as a wiki page, note, trigger report, behavior pattern, belief, mode, movement timeline, energy model, weekday pattern, flow, run, or node result.",
3126
3208
  "Self-observation is not the default container for Psyche material. Use it only for a lightweight observed event note; prefer trigger_report for one emotionally meaningful episode, behavior_pattern for a recurring loop and functional analysis, behavior for one repeated move, belief_entry for a core sentence, mode_guide_session or mode_profile for an active part-state, flashcard for a brief rehearsable reminder to use during a trigger or urge, and wiki_page for durable memory.",
3127
3209
  "Do not bury schema work in self-observation. If the user is describing a schema theme, preserve it through a belief_entry, behavior_pattern, mode_profile, mode_guide_session, trigger_report, or wiki_page depending on whether it appears as a rule, loop, part-state, live exploration, one episode, or durable explanation.",
@@ -4298,6 +4380,20 @@ export const AGENT_ONBOARDING_TOOL_INPUT_CATALOG = [
4298
4380
  ],
4299
4381
  example: '{"sourceKind":"url","sourceUrl":"https://example.com/article","titleHint":"Research import","parseStrategy":"auto","entityProposalMode":"suggest"}'
4300
4382
  },
4383
+ {
4384
+ toolName: "forge_call_artifact_route",
4385
+ summary: "Call one allowed Artifact Store route for trusted file upload, metadata, scans, enrichment, generic entity links, trust state, versions, or audit.",
4386
+ whenToUse: "Use for artifact list/read/update/upload flows after the user wants a file preserved or reviewed as metadata. Use shared batch CRUD only for artifact metadata search/update/delete/restore. Do not use this tool to download, open, preview, execute, or transform file bytes.",
4387
+ inputShape: '{ routeKey: "list"|"createWithBytes"|"readMetadata"|"updateMetadata"|"rescan"|"enrichWithLlm"|"replaceGenericLinks"|"trustState"|"versions"|"audit", pathParams?: { id?: string }, query?: object, body?: object }',
4388
+ requiredFields: ["routeKey"],
4389
+ notes: [
4390
+ "The download route is intentionally absent from the agent tool surface; it is human-operator-only.",
4391
+ "For createWithBytes, the body must include originalFileName and contentBase64, and the actor must be trusted and scoped for artifact byte upload.",
4392
+ "For replaceGenericLinks, links are generic entity link inputs identifying target entityType, entityId, optional anchorKey, and relationship.",
4393
+ "Optional LLM enrichment can fill missing metadata, but it must not lower the deterministic scanner danger score."
4394
+ ],
4395
+ example: '{"routeKey":"replaceGenericLinks","pathParams":{"id":"artifact_123"},"body":{"links":[{"entityType":"wiki_page","entityId":"note_budget_model","relationship":"embedded_reference","anchorKey":"budget-workbook"}]}}'
4396
+ },
4301
4397
  {
4302
4398
  toolName: "forge_get_sleep_overview",
4303
4399
  summary: "Read the sleep surface with recent nights, scores, regularity, stage averages, and linked reflective context.",
@@ -4721,7 +4817,13 @@ function buildAgentOnboardingPayload(request) {
4721
4817
  "psyche.write",
4722
4818
  "psyche.note",
4723
4819
  "psyche.insight",
4724
- "psyche.mode"
4820
+ "psyche.mode",
4821
+ "artifact.readMetadata",
4822
+ "artifact.create",
4823
+ "artifact.uploadBytes",
4824
+ "artifact.updateMetadata",
4825
+ "artifact.link",
4826
+ "artifact.enrichWithLlm"
4725
4827
  ],
4726
4828
  recommendedTrustLevel: "trusted",
4727
4829
  recommendedAutonomyMode: "approval_required",
@@ -4771,6 +4873,7 @@ function buildAgentOnboardingPayload(request) {
4771
4873
  taskRun: "A live work session attached to a task. Start, heartbeat, focus, complete, and release runs instead of faking work with status alone.",
4772
4874
  note: "A Markdown work note that can link to one or many entities. Use notes for progress evidence, context, and close-out summaries.",
4773
4875
  wiki: "KarpaWiki is the SQLite-backed memory layer: Markdown content in notes rows plus media, backlinks, optional embeddings, explicit spaces, and structured links back to Forge entities.",
4876
+ artifact: "Artifacts are trusted stored files such as spreadsheets, documents, PDFs, text, structured text, or images. Forge stores bytes content-addressably, records provenance and metadata, runs static safety scans, exposes generic entity links, and serves downloads only to human operator sessions. Agents may upload only when trusted and scoped, and must not autonomously download, open, execute, or transform stored files.",
4774
4877
  sleepSession: "A sleep session is a first-class health record with timing, sleep and bed duration, stage breakdown, recovery metrics, annotations, and Forge links back to planning or Psyche context.",
4775
4878
  workoutSession: "A workout session is a first-class sports record imported from HealthKit or generated from a habit. It holds workout type, timing, energy or distance when available, subjective effort, narrative context, and Forge links.",
4776
4879
  preferences: "Forge Preferences is the explicit taste-modeling domain. It has workspaces, contexts, concept libraries, direct items, pairwise judgments, direct signals, and inferred scores.",
@@ -4820,6 +4923,7 @@ function buildAgentOnboardingPayload(request) {
4820
4923
  "Habits are recurring records that can connect directly to goals, projects, tasks, and durable Psyche entities.",
4821
4924
  "Task runs represent live work sessions on tasks and are separate from task status.",
4822
4925
  "Notes can link to one or many entities and are the canonical place for Markdown progress context or close-out evidence.",
4926
+ "Artifacts are linkable stored entities backed by the general entity_links model; use generic entity links to attach a file to goals, projects, tasks, wiki-backed notes, Psyche records, calendar records, or other meaningful Forge context.",
4823
4927
  "Psyche values can link to goals, projects, and tasks.",
4824
4928
  "Behavior patterns, behaviors, beliefs, modes, flashcards, and trigger reports cross-link to describe one reflective model rather than isolated records.",
4825
4929
  "Insights can point at one entity, but they exist to capture interpretation or advice rather than raw work items."
@@ -4877,6 +4981,55 @@ function buildAgentOnboardingPayload(request) {
4877
4981
  update: "/api/v1/calendar/connections/:id",
4878
4982
  sync: "/api/v1/calendar/connections/:id/sync",
4879
4983
  delete: "/api/v1/calendar/connections/:id"
4984
+ },
4985
+ artifact: {
4986
+ list: "/api/v1/artifacts",
4987
+ createWithBytes: "/api/v1/artifacts",
4988
+ readMetadata: "/api/v1/artifacts/:id",
4989
+ updateMetadata: "/api/v1/artifacts/:id",
4990
+ humanDownloadOnly: "/api/v1/artifacts/:id/download",
4991
+ rescan: "/api/v1/artifacts/:id/scan",
4992
+ enrichWithLlm: "/api/v1/artifacts/:id/enrich",
4993
+ replaceGenericLinks: "/api/v1/artifacts/:id/links",
4994
+ trustState: "/api/v1/artifacts/:id/trust",
4995
+ versions: "/api/v1/artifacts/:id/versions",
4996
+ audit: "/api/v1/artifacts/:id/audit",
4997
+ batchMetadata: {
4998
+ search: "/api/v1/entities/search",
4999
+ updateMetadata: "/api/v1/entities/update",
5000
+ deleteMetadata: "/api/v1/entities/delete",
5001
+ restoreMetadata: "/api/v1/entities/restore"
5002
+ },
5003
+ routeKeys: [
5004
+ "list",
5005
+ "createWithBytes",
5006
+ "readMetadata",
5007
+ "updateMetadata",
5008
+ "rescan",
5009
+ "enrichWithLlm",
5010
+ "replaceGenericLinks",
5011
+ "trustState",
5012
+ "versions",
5013
+ "audit"
5014
+ ],
5015
+ methodRoutes: {
5016
+ list: { method: "GET", path: "/api/v1/artifacts" },
5017
+ createWithBytes: { method: "POST", path: "/api/v1/artifacts" },
5018
+ readMetadata: { method: "GET", path: "/api/v1/artifacts/:id" },
5019
+ updateMetadata: { method: "PATCH", path: "/api/v1/artifacts/:id" },
5020
+ rescan: { method: "POST", path: "/api/v1/artifacts/:id/scan" },
5021
+ enrichWithLlm: { method: "POST", path: "/api/v1/artifacts/:id/enrich" },
5022
+ replaceGenericLinks: { method: "POST", path: "/api/v1/artifacts/:id/links" },
5023
+ trustState: { method: "POST", path: "/api/v1/artifacts/:id/trust" },
5024
+ versions: { method: "GET", path: "/api/v1/artifacts/:id/versions" },
5025
+ audit: { method: "GET", path: "/api/v1/artifacts/:id/audit" }
5026
+ },
5027
+ safetyRules: [
5028
+ "Do not expose the download route to agent tools. It is a human operator route only.",
5029
+ "Do not execute, preview, parse externally, or transform stored file bytes autonomously.",
5030
+ "Use general entity links for relationships; do not create artifact-specific link models.",
5031
+ "Use batch CRUD only for artifact metadata search/update/delete/restore, never for file-byte creation."
5032
+ ]
4880
5033
  }
4881
5034
  },
4882
5035
  actionEntities: {
@@ -5268,7 +5421,7 @@ function buildAgentOnboardingPayload(request) {
5268
5421
  ],
5269
5422
  verifyCommands: [
5270
5423
  `curl -s ${origin}/api/v1/health`,
5271
- "openclaw plugins install --link --dangerously-force-unsafe-install ./projects/forge/openclaw-plugin",
5424
+ "openclaw plugins install --link --dangerously-force-unsafe-install ./projects/forge/plugins/openclaw",
5272
5425
  "openclaw plugins inspect forge-openclaw-plugin --runtime",
5273
5426
  "openclaw gateway restart",
5274
5427
  "openclaw forge onboarding",
@@ -5381,6 +5534,15 @@ function buildAgentOnboardingPayload(request) {
5381
5534
  workbenchRunDetail: "/api/v1/workbench/flows/:id/runs/:runId",
5382
5535
  workbenchNodeResult: "/api/v1/workbench/flows/:id/runs/:runId/nodes/:nodeId",
5383
5536
  workbenchLatestNodeOutput: "/api/v1/workbench/flows/:id/nodes/:nodeId/output",
5537
+ artifacts: "/api/v1/artifacts",
5538
+ artifactDetail: "/api/v1/artifacts/:id",
5539
+ artifactDownloadHumanOnly: "/api/v1/artifacts/:id/download",
5540
+ artifactScan: "/api/v1/artifacts/:id/scan",
5541
+ artifactEnrich: "/api/v1/artifacts/:id/enrich",
5542
+ artifactEntityLinks: "/api/v1/artifacts/:id/links",
5543
+ artifactTrust: "/api/v1/artifacts/:id/trust",
5544
+ artifactVersions: "/api/v1/artifacts/:id/versions",
5545
+ artifactAudit: "/api/v1/artifacts/:id/audit",
5384
5546
  wikiSettings: "/api/v1/wiki/settings",
5385
5547
  wikiSearch: "/api/v1/wiki/search",
5386
5548
  wikiHealth: "/api/v1/wiki/health",
@@ -5426,6 +5588,13 @@ function buildAgentOnboardingPayload(request) {
5426
5588
  "forge_call_life_force_route",
5427
5589
  "forge_call_workbench_route"
5428
5590
  ],
5591
+ artifactWorkflow: [
5592
+ "forge_call_artifact_route",
5593
+ "forge_search_entities",
5594
+ "forge_update_entities",
5595
+ "forge_delete_entities",
5596
+ "forge_restore_entities"
5597
+ ],
5429
5598
  entityWorkflow: [
5430
5599
  "forge_search_entities",
5431
5600
  "forge_create_entities",
@@ -5492,9 +5661,10 @@ function buildAgentOnboardingPayload(request) {
5492
5661
  depthCalibrationRule: "Before deepening an intake, decide whether this is quick capture, guided formulation, review-first help, or action-first execution. Quick capture means the user already supplied usable wording and wants it saved, remembered, or logged; reflect the working shape once, ask only the one structural, accuracy, or consent detail that changes the write, and do not force full exploration. Guided formulation means the user asks to understand, name, map, decide, or work through unclear or charged material; use active listening, one lane at a time, and Psyche hypotheses when appropriate before saving. Review-first means read the relevant stored entity, overview, or specialized surface before asking write-shaped questions. Action-first means the target task run, work adjustment, preference signal or judgment, questionnaire run, Movement correction, Life Force signal or weekday template, or Workbench run or output is already clear, so act or ask only for the missing target, span, flow, run, node, weekday, correction, or consent. Do not downgrade psychologically meaningful material into quick capture when the user wants exploration, and do not expand a simple storage request into therapy or project planning.",
5493
5662
  operationLaneRule: "Keep the operation lane explicit before asking for lower-level details. Normal stored entities can be added, updated, reviewed or navigated, linked, or placed. Action workflows use verbs such as start, continue, complete, adjust, judge, signal, publish, sync, or observe. Specialized CRUD surfaces use lifecycle verbs such as create, read, update, sync, reconnect, delete, or browse. Read-model surfaces need a practical read question and scope before any write-shaped follow-up. Movement, Life Force, and Workbench use review, correct, repair, run, inspect, publish, or preserve lanes through their dedicated route keys. Psyche entities need a formulation lane before the storage lane when the user wants understanding; direct saves can move to one accuracy or consent question.",
5494
5663
  psycheExplorationRule: "When a Psyche entity needs understanding first, begin with one exploratory question before any working formulation, replacement belief, suggested title, or save pitch. Keep the opening reflection to one or two short sentences, stay in plain prose instead of bullets or numbered lists, keep that first reply short, do not mention Forge search or save structure yet, avoid colons or list-shaped phrasing, prefer what/when/how over why until the experience is grounded, wait for the user's answer before offering a fuller formulation, ask permission before moving from charged exploration into naming or challenge when needed, make the next question help the user feel more able to name the experience rather than more examined, do not widen into adjacent entities until the current one has a working sentence the user recognizes, and once the lived experience is coherent stop deepening and help the user name it cleanly. After one concrete example is clear and a hypothesis lands or is corrected, translate it into a saveable record shape such as a belief sentence, functional loop, behavior, mode, trigger report, value, event type, or emotion definition; do not leave the user with interpretation alone, name the primary Forge record it is becoming, and ask one accuracy or consent question instead of reopening broad exploration, then use the shared batch entity routes after the user accepts the wording or explicitly asks to save. When the user is updating a Psyche record because of one fresh episode, anchor in that episode before renaming the durable formulation, begin with the smallest part of the old wording that no longer fits, and do not reopen the full origin story unless the new understanding is truly structural. If the user accepts the wording, move toward the save instead of reopening deeper exploration.",
5495
- progressiveDisclosureRule: "Treat partial answers as progress, not as failed intake. Before asking another question, identify what is already usable: operation, entity or surface, target record or time span, working wording, owner or placement, route lane, and consent. Say the usable part back briefly, then ask only for the first missing detail that changes the action: duplicate disambiguation, hierarchy parent, time window, weekday, flow, run, node, correction, link, or save consent. For normal batch entities, do not ask for optional tags, priority, status, dates, color, links, or assignees when the accepted wording and meaningful body are already enough unless that metadata changes accountability, retrieval, or execution. For Movement, Life Force, and Workbench, if the user's wording already implies the dedicated lane, skip the broad route-family question and ask only for the target span, place, weekday, profile field, flow, run, node, output, correction, or consent that is still missing. For direct Psyche saves or updates, treat an offered belief sentence, functional loop, part voice, trigger episode, value phrase, event kind, emotion signature, or flashcard message as real data; ask one accuracy or consent question instead of reopening origin, evidence, or repair.",
5664
+ progressiveDisclosureRule: "Treat partial answers as progress, not as failed intake. Before asking another question, identify what is already usable: operation, entity or surface, target record or time span, working wording, owner or placement, route lane, and consent. Say the usable part back briefly, then ask only for the first missing detail that changes the action: duplicate disambiguation, hierarchy parent, time window, weekday, flow, run, node, correction, link, or save consent. Use the known-target fast path when the user's wording already names the object and action: for normal entities ask only for parent, owner, or duplicate disambiguation; for task hierarchy ask only for the project, issue, or parent task; for Movement ask only for the missing interval, boundary, saved object, or confirmation; for Life Force ask only for the weekday, profile field, signal intensity, or planning effect; for Workbench ask only for the missing flow, run, node, input, output, or preservation choice. For normal batch entities, do not ask for optional tags, priority, status, dates, color, links, or assignees when the accepted wording and meaningful body are already enough unless that metadata changes accountability, retrieval, or execution. For Movement, Life Force, and Workbench, if the user's wording already implies the dedicated lane, skip the broad route-family question and ask only for the target span, place, weekday, profile field, flow, run, node, output, correction, or consent that is still missing. For direct Psyche saves or updates, treat an offered belief sentence, functional loop, part voice, trigger episode, value phrase, event kind, emotion signature, or flashcard message as real data; ask one accuracy or consent question instead of reopening origin, evidence, or repair.",
5496
5665
  writeConfirmationRule: "After create, update, delete, restore, run, read, or repair actions, confirm the user-facing record, action, and result in the user's language instead of reopening intake. For batch creates and updates, confirm the working title or accepted wording, container, and owner or placement only when those changed retrieval, accountability, or execution; if optional tags, priority, status, color, links, dates, or assignees were left provisional, say that plainly once instead of asking for all of them. For action workflows, confirm the real product action such as task run started or completed, work adjustment applied, preference judgment or signal submitted, questionnaire run updated or completed, calendar connection synced, or self-observation note written. For Psyche saves, confirm the accepted wording and whether it was saved as a first version, update, link, archive, or distinct version; do not reopen origin, evidence, repair, or adjacent entity mapping after the save unless that next object is already visible and materially useful. Ask a follow-up only if it changes the next action: correction, link, schedule, run, publish, enrichment, preservation choice, or UI handoff.",
5497
5666
  specializedSurfaceRule: "For Movement, Life Force, and Workbench, clarify the job first, then choose the dedicated route family internally and do not guess at a generic CRUD path. Use specializedDomainSurfaces.routeSelectionQuestions when they are present so the next follow-up selects the right route instead of asking generic questions. Before every dedicated call, run a route-contract handshake internally: select the product lane in plain language, verify the matching routeKey against live onboarding routeKeys and methodRoutes, fill any placeholders through pathParams, and ask the user only for the missing product noun that fills the placeholder. When available, use forge_call_movement_route, forge_call_life_force_route, or forge_call_workbench_route after the lane is clear. If a route-key tool is unavailable, stale, or missing the needed key, read live onboarding and use the exact specializedDomainSurfaces.methodRoutes entry for the selected lane; cross-check OpenAPI only to confirm the same method and path, do not fall back to generic batch CRUD, do not invent a nearby raw path, and treat schema disagreement as a Forge contract bug to fix. Before calling a specialized route, inspect its methodRoutes entry for placeholders such as :id, :weekday, :slug, :runId, :nodeId, or :pointId, then fill each one through pathParams with the same placeholder name; do not hide IDs in query, body, or routeKey. If the contract is missing a lane the product clearly supports, report a contract bug instead of silently using generic batch CRUD or a nearby route. In user-facing language, talk about timeline, overlay, weekday template, published output, run detail, or node result rather than surfaces, payloads, read paths, mutation paths, or CRUD. If the truth of the current state is still uncertain, read the relevant dedicated view before you mutate it. When the user already named a precise correction or review target, confirm only the route-selecting detail that is still missing. After a concrete Movement, Life Force, or Workbench correction, mutation, or result-producing run, read the relevant view back when the user is trying to understand the result rather than just store it: timeline or place/settings detail for Movement, the Life Force overview for energy-planning impact, and flow detail, run detail, node result, latest node output, published output, or run history for Workbench. After any dedicated read, translate the result into one next action: no change, Movement overlay/place/settings/link, Life Force workload/recovery/timebox/meeting/task-choice change, or Workbench rerun/node inspection/flow edit/publish/preserve/stop. Ask only for the missing span, place, weekday, flow, run, node, output, correction, preservation choice, or confirmation that would change that action. The canonical runtime routes stay under /api/v1/*, and the OpenClaw HTTP mirror exposes the same families under /forge/v1/movement, /forge/v1/life-force, and /forge/v1/workbench.",
5667
+ artifactStoreRule: "For artifacts, ask only for the metadata that changes preservation and retrieval: what the file is, where it came from, why it should be kept, whether it should link to a Forge record, and whether optional LLM enrichment should fill missing title or description. Use dedicated Artifacts routes for upload, scan, enrichment, generic links, trust state, versions, and audit. Use batch CRUD only for artifact metadata search/update/delete/restore. Never download, open, run, execute, transform, or preview stored file bytes as an agent; downloads are human-operator-only.",
5498
5668
  reviewShortcutRule: "When the user is reviewing or correcting an existing record, ask what practical question they want the read or correction to answer, then narrow the saved object, timeframe, or route family first. Use the correct read posture before asking write-shaped questions: shared batch search or read hints for normal entities, wiki/calendar dedicated reads for specialized CRUD, read-model routes for overviews, and Movement, Life Force, or Workbench dedicated reads for those domain surfaces. After the read, answer the practical question before asking for any save, correction, link, run, enrichment, or publish detail, and state what the read rules in, rules out, or leaves uncertain. If several actions are possible, narrow to the one most directly supported by the read instead of handing the user a broad menu. Do not reopen the whole intake unless the user is actually redefining the record.",
5499
5669
  readModelWriteRule: "Self-observation is note-backed and should be written through observed notes with frontmatter.observedAt only when a lightweight episode observation is the right container. Do not use it as the default bucket for Psyche material: prefer trigger_report for one emotionally meaningful episode, behavior_pattern for functional analysis of a recurring loop, behavior for one repeated move, belief_entry for a core sentence, mode_guide_session or mode_profile for a central part-state, and wiki_page for durable memory such as books, articles, concepts, sources, or personal manuals. Sleep and workout sessions stay on batch CRUD by default; use the reflective review helpers only when enriching one already-known record after review.",
5500
5670
  psycheOpeningQuestionRule: "Prefer a concrete opening question tied to the entity: ask when the value mattered, what happened the last time the pattern appeared, what cue or body signal came first before the behavior, what the belief starts saying about self or outcome, what feels most at risk inside the mode, what the part is trying to get the user to do or stop doing, or where the shift began in the incident. Reflect briefly before the question, choose one follow-up lane at a time, say what is becoming clearer before the next deeper question, and if several Psyche entities are visible hold the adjacent ones lightly until the main container is clear.",
@@ -5523,7 +5693,7 @@ function buildAgentOnboardingPayload(request) {
5523
5693
  entityDeleteSummary: "Entity DELETE routes default to soft delete. Pass mode=hard only when permanent removal is intended. Immediate-delete entities skip the bin, and calendar-event deletes still remove remote projections downstream.",
5524
5694
  batchingRule: "forge_create_entities, forge_update_entities, forge_delete_entities, and forge_restore_entities all accept operations as arrays. Batch CRUD is the default for simple entities, so batch multiple related mutations together instead of reaching for a long list of entity-specific routes.",
5525
5695
  searchRule: "forge_search_entities accepts searches as an array. Search before create or update when duplicate risk exists.",
5526
- createRule: "Each create operation must include entityType and full data. entityType alone is not enough. This includes calendar_event, work_block_template, task_timebox, sleep_session, workout_session, preference CRUD entities, and questionnaire_instrument alongside the usual planning and Psyche entities.",
5696
+ createRule: "Each create operation must include entityType and full data. entityType alone is not enough. This includes calendar_event, work_block_template, task_timebox, sleep_session, workout_session, preference CRUD entities, and questionnaire_instrument alongside the usual planning and Psyche entities. Artifact file-byte creation is the exception: use POST /api/v1/artifacts or forge_call_artifact_route createWithBytes, not batch create.",
5527
5697
  updateRule: "Each update operation must include entityType, id, and patch. For projects, lifecycle changes are status patches: active to restart, paused to suspend, completed to finish. Keep task and project scheduling rules on those same patch payloads. Official habit outcomes can also be logged through forge_update_entities by patching the habit with checkIn: { status, dateKey?, note?, description? } instead of route-hunting. Calendar-event updates still run downstream provider projection sync, and manual health-session field edits belong on the batch route by default rather than on the reflective review helpers.",
5528
5698
  specializedRouteToolRule: "forge_call_movement_route, forge_call_life_force_route, and forge_call_workbench_route expect { routeKey, pathParams?, query?, body? }. Choose routeKey from the tool schema or entityRouteModel.specializedDomainSurfaces, fill every methodRoutes placeholder with pathParams using names such as id, weekday, slug, runId, nodeId, or pointId, use query for read filters and userIds, and use body only for POST, PATCH, or PUT route keys. Do not put required IDs or weekdays inside routeKey, query, or body when the published path has a placeholder. The Life Force overview route key maps to GET /api/v1/life-force; do not invent /api/v1/life-force/overview. Normal stored entities still use the shared batch entity tools.",
5529
5699
  createExample: '{"operations":[{"entityType":"goal","data":{"title":"Create meaningfully"},"clientRef":"goal-create-1"},{"entityType":"goal","data":{"title":"Build a beautiful family"},"clientRef":"goal-create-2"}]}',
@@ -7469,6 +7639,197 @@ export async function buildServer(options = {}) {
7469
7639
  managers.authorization.requireAnyTokenScope(context, ["write", "insights"], detail);
7470
7640
  return context;
7471
7641
  };
7642
+ const requireArtifactReadAccess = (headers, detail) => {
7643
+ const context = authenticateRequest(headers);
7644
+ managers.authorization.requireAuthenticatedActor(context, detail);
7645
+ if (!context.session) {
7646
+ managers.authorization.requireAnyTokenScope(context, ["artifact.readMetadata", "read"], detail);
7647
+ }
7648
+ return context;
7649
+ };
7650
+ const requireTrustedArtifactUploadAccess = (headers, detail) => {
7651
+ const context = authenticateRequest(headers);
7652
+ managers.authorization.requireAuthenticatedActor(context, detail);
7653
+ if (!context.session) {
7654
+ managers.authorization.requireAnyTokenScope(context, ["artifact.create"], detail);
7655
+ managers.authorization.requireAnyTokenScope(context, ["artifact.uploadBytes"], detail);
7656
+ if (context.token?.trustLevel !== "trusted" &&
7657
+ context.token?.trustLevel !== "autonomous") {
7658
+ throw new HttpError(403, "artifact_untrusted_agent", "Artifact uploads require a trusted agent identity.", {
7659
+ trustLevel: context.token?.trustLevel ?? null,
7660
+ requiredTrustLevels: ["trusted", "autonomous"],
7661
+ ...(detail ?? {})
7662
+ });
7663
+ }
7664
+ }
7665
+ return context;
7666
+ };
7667
+ const requireArtifactMetadataWriteAccess = (headers, detail) => {
7668
+ const context = authenticateRequest(headers);
7669
+ managers.authorization.requireAuthenticatedActor(context, detail);
7670
+ if (!context.session) {
7671
+ managers.authorization.requireAnyTokenScope(context, ["artifact.updateMetadata", "write"], detail);
7672
+ }
7673
+ return context;
7674
+ };
7675
+ const requireArtifactDownloadAccess = (headers, detail) => {
7676
+ const context = authenticateRequest(headers);
7677
+ managers.authorization.requireAuthenticatedOperator(context, detail);
7678
+ return context;
7679
+ };
7680
+ const requireArtifactTrustAccess = (headers, detail) => {
7681
+ const context = authenticateRequest(headers);
7682
+ managers.authorization.requireAuthenticatedActor(context, detail);
7683
+ if (!context.session) {
7684
+ managers.authorization.requireAnyTokenScope(context, ["artifact.manageTrust", "artifact.overrideQuarantine"], detail);
7685
+ if (context.token?.trustLevel !== "trusted" &&
7686
+ context.token?.trustLevel !== "autonomous") {
7687
+ throw new HttpError(403, "artifact_untrusted_agent", "Artifact trust overrides require a trusted agent identity.", {
7688
+ trustLevel: context.token?.trustLevel ?? null,
7689
+ requiredTrustLevels: ["trusted", "autonomous"],
7690
+ ...(detail ?? {})
7691
+ });
7692
+ }
7693
+ }
7694
+ return context;
7695
+ };
7696
+ app.get("/api/v1/artifacts", async (request) => {
7697
+ requireArtifactReadAccess(request.headers, {
7698
+ route: "/api/v1/artifacts"
7699
+ });
7700
+ return {
7701
+ artifacts: listArtifacts(artifactListQuerySchema.parse(request.query ?? {}))
7702
+ };
7703
+ });
7704
+ app.post("/api/v1/artifacts", { bodyLimit: 150 * 1024 * 1024 }, async (request, reply) => {
7705
+ const auth = requireTrustedArtifactUploadAccess(request.headers, { route: "/api/v1/artifacts" });
7706
+ const artifact = await createArtifactFromUpload(artifactUploadSchema.parse(request.body ?? {}), auth, { llm: managers.llm });
7707
+ reply.code(201);
7708
+ return { artifact };
7709
+ });
7710
+ app.get("/api/v1/artifacts/:id", async (request, reply) => {
7711
+ requireArtifactReadAccess(request.headers, {
7712
+ route: "/api/v1/artifacts/:id"
7713
+ });
7714
+ const { id } = request.params;
7715
+ const artifact = getArtifactById(id);
7716
+ if (!artifact) {
7717
+ reply.code(404);
7718
+ return { error: "Artifact not found" };
7719
+ }
7720
+ return { artifact };
7721
+ });
7722
+ app.patch("/api/v1/artifacts/:id", async (request, reply) => {
7723
+ const auth = requireArtifactMetadataWriteAccess(request.headers, { route: "/api/v1/artifacts/:id" });
7724
+ const { id } = request.params;
7725
+ const artifact = updateArtifactMetadata(id, artifactMetadataPatchSchema.parse(request.body ?? {}), auth);
7726
+ if (!artifact) {
7727
+ reply.code(404);
7728
+ return { error: "Artifact not found" };
7729
+ }
7730
+ return { artifact };
7731
+ });
7732
+ app.get("/api/v1/artifacts/:id/download", async (request, reply) => {
7733
+ const auth = requireArtifactDownloadAccess(request.headers, { route: "/api/v1/artifacts/:id/download" });
7734
+ const { id } = request.params;
7735
+ const result = await readArtifactDownload(id);
7736
+ if (!result) {
7737
+ reply.code(404);
7738
+ return { error: "Artifact not found" };
7739
+ }
7740
+ const fileName = result.artifact.originalFileName.replace(/["\\\r\n]/g, "_");
7741
+ recordActivityEvent({
7742
+ entityType: "artifact",
7743
+ entityId: result.artifact.id,
7744
+ eventType: "artifact.downloaded",
7745
+ title: `Artifact downloaded: ${result.artifact.title}`,
7746
+ description: "A human operator downloaded stored artifact bytes. Forge did not execute the file.",
7747
+ actor: auth.actor ?? null,
7748
+ source: auth.source,
7749
+ metadata: {
7750
+ contentSha256: result.artifact.contentSha256,
7751
+ byteSize: result.artifact.byteSize
7752
+ }
7753
+ });
7754
+ return reply
7755
+ .header("content-type", result.artifact.detectedMimeType)
7756
+ .header("content-length", String(result.bytes.byteLength))
7757
+ .header("content-disposition", `attachment; filename="${fileName}"`)
7758
+ .send(result.bytes);
7759
+ });
7760
+ app.post("/api/v1/artifacts/:id/scan", async (request, reply) => {
7761
+ const auth = requireArtifactMetadataWriteAccess(request.headers, { route: "/api/v1/artifacts/:id/scan" });
7762
+ const { id } = request.params;
7763
+ const artifact = await rescanArtifact(id, auth);
7764
+ if (!artifact) {
7765
+ reply.code(404);
7766
+ return { error: "Artifact not found" };
7767
+ }
7768
+ return { artifact };
7769
+ });
7770
+ app.post("/api/v1/artifacts/:id/enrich", async (request, reply) => {
7771
+ const auth = requireArtifactMetadataWriteAccess(request.headers, { route: "/api/v1/artifacts/:id/enrich" });
7772
+ if (!auth.session) {
7773
+ managers.authorization.requireAnyTokenScope(auth, ["artifact.enrichWithLlm"], { route: "/api/v1/artifacts/:id/enrich" });
7774
+ }
7775
+ const { id } = request.params;
7776
+ const artifact = await enrichArtifactWithLlm(id, artifactEnrichmentRequestSchema.parse(request.body ?? {}), auth, { llm: managers.llm });
7777
+ if (!artifact) {
7778
+ reply.code(404);
7779
+ return { error: "Artifact not found" };
7780
+ }
7781
+ return { artifact };
7782
+ });
7783
+ app.post("/api/v1/artifacts/:id/links", async (request, reply) => {
7784
+ const auth = requireArtifactMetadataWriteAccess(request.headers, { route: "/api/v1/artifacts/:id/links" });
7785
+ if (!auth.session) {
7786
+ managers.authorization.requireAnyTokenScope(auth, ["artifact.link"], {
7787
+ route: "/api/v1/artifacts/:id/links"
7788
+ });
7789
+ }
7790
+ const { id } = request.params;
7791
+ const body = z
7792
+ .object({ links: z.array(entityLinkInputSchema) })
7793
+ .parse(request.body ?? {});
7794
+ const artifact = replaceArtifactEntityLinks(id, body.links, auth);
7795
+ if (!artifact) {
7796
+ reply.code(404);
7797
+ return { error: "Artifact not found" };
7798
+ }
7799
+ return { artifact };
7800
+ });
7801
+ app.post("/api/v1/artifacts/:id/trust", async (request, reply) => {
7802
+ const auth = requireArtifactTrustAccess(request.headers, { route: "/api/v1/artifacts/:id/trust" });
7803
+ const { id } = request.params;
7804
+ const artifact = patchArtifactTrust(id, artifactTrustPatchSchema.parse(request.body ?? {}), auth);
7805
+ if (!artifact) {
7806
+ reply.code(404);
7807
+ return { error: "Artifact not found" };
7808
+ }
7809
+ return { artifact };
7810
+ });
7811
+ app.get("/api/v1/artifacts/:id/versions", async (request, reply) => {
7812
+ requireArtifactReadAccess(request.headers, {
7813
+ route: "/api/v1/artifacts/:id/versions"
7814
+ });
7815
+ const { id } = request.params;
7816
+ if (!getArtifactById(id)) {
7817
+ reply.code(404);
7818
+ return { error: "Artifact not found" };
7819
+ }
7820
+ return { versions: listArtifactVersions(id) };
7821
+ });
7822
+ app.get("/api/v1/artifacts/:id/audit", async (request, reply) => {
7823
+ requireArtifactReadAccess(request.headers, {
7824
+ route: "/api/v1/artifacts/:id/audit"
7825
+ });
7826
+ const { id } = request.params;
7827
+ if (!getArtifactById(id)) {
7828
+ reply.code(404);
7829
+ return { error: "Artifact not found" };
7830
+ }
7831
+ return { events: listArtifactAuditEvents(id) };
7832
+ });
7472
7833
  app.get("/api/health", async () => buildHealthPayload(taskRunWatchdog));
7473
7834
  app.get("/api/v1/health", async (request) => buildHealthPayload(taskRunWatchdog, {
7474
7835
  apiVersion: "v1",
@@ -8,9 +8,9 @@ import { updateTask } from "../repositories/tasks.js";
8
8
  import { getOverviewContext } from "../services/context.js";
9
9
  import { searchEntities } from "../services/entity-crud.js";
10
10
  import { getWikiHealth, listWikiPages } from "../repositories/wiki-memory.js";
11
- import { executeCommonWorkbenchTool, mapWorkbenchTools } from "../../../src/lib/workbench/runtime.js";
12
- import { getWorkbenchNodeCatalog, getWorkbenchNodeDefinition } from "../../../src/lib/workbench/registry.js";
13
- import { normalizeWorkbenchPortDefinition } from "../../../src/lib/workbench/nodes.js";
11
+ import { executeCommonWorkbenchTool, mapWorkbenchTools } from "../../../web/src/lib/workbench/runtime.js";
12
+ import { getWorkbenchNodeCatalog, getWorkbenchNodeDefinition } from "../../../web/src/lib/workbench/registry.js";
13
+ import { normalizeWorkbenchPortDefinition } from "../../../web/src/lib/workbench/nodes.js";
14
14
  function createSnapshotForConnectorOutput(boxId) {
15
15
  const outputId = boxId.replace(/^connector-output:/, "");
16
16
  const rows = getDatabase()
@@ -15,10 +15,29 @@ function dateOffsetIso(days) {
15
15
  date.setUTCDate(date.getUTCDate() + days);
16
16
  return date.toISOString().slice(0, 10);
17
17
  }
18
- const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
19
- const migrationsDir = path.join(projectRoot, "server", "migrations");
20
- const monorepoForgeDataRoot = path.resolve(projectRoot, "..", "..", "data", "forge");
18
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
19
+ const apiRoot = path.resolve(moduleDir, "..");
20
+ const migrationsDir = path.join(apiRoot, "migrations");
21
21
  const userSharedForgeDataRoot = path.join(os.homedir(), ".forge");
22
+ function findSourceProjectRoot(startDir) {
23
+ let current = path.resolve(startDir);
24
+ while (true) {
25
+ if (existsSync(path.join(current, "package.json")) &&
26
+ existsSync(path.join(current, "apps", "api", "migrations")) &&
27
+ existsSync(path.join(current, "apps", "web", "src"))) {
28
+ return current;
29
+ }
30
+ const parent = path.dirname(current);
31
+ if (parent === current) {
32
+ return null;
33
+ }
34
+ current = parent;
35
+ }
36
+ }
37
+ const sourceProjectRoot = findSourceProjectRoot(apiRoot);
38
+ const monorepoForgeDataRoot = sourceProjectRoot
39
+ ? path.resolve(sourceProjectRoot, "..", "..", "data", "forge")
40
+ : null;
22
41
  function resolveCanonicalDataDir(root = dataRoot) {
23
42
  return path.resolve(root);
24
43
  }
@@ -72,7 +91,7 @@ export function resolveDefaultDataRoot(currentWorkingDir = process.cwd()) {
72
91
  // Inside the private monorepo, prefer the tracked shared Forge data root so
73
92
  // the local app, Hermes, OpenClaw, and repo-managed data all point at the
74
93
  // same state by default.
75
- if (existsSync(monorepoForgeDataRoot)) {
94
+ if (monorepoForgeDataRoot && existsSync(monorepoForgeDataRoot)) {
76
95
  return monorepoForgeDataRoot;
77
96
  }
78
97
  return path.resolve(userSharedForgeDataRoot || currentWorkingDir);
@@ -4,7 +4,7 @@ import { getDatabase, runInTransaction } from "./db.js";
4
4
  import { getSettings } from "./repositories/settings.js";
5
5
  import { getDefaultUser, resolveUserForMutation } from "./repositories/users.js";
6
6
  import { readEncryptedSecret } from "./repositories/calendar.js";
7
- import { hallNiddkWeeklyRateKgToDailyEnergyAdjustment } from "../../src/lib/weight-loss-energy-model.js";
7
+ import { hallNiddkWeeklyRateKgToDailyEnergyAdjustment } from "../../web/src/lib/weight-loss-energy-model.js";
8
8
  const ACTIVE_BASELINE_WINDOW_DAYS = 7;
9
9
  const optionalNumberSchema = z
10
10
  .union([z.coerce.number().finite(), z.null()])