@xopcai/xopc 0.0.217 → 0.0.219

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 (329) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-D6trMTyZ.js → activity-store-slG02hSm.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CAQdFrcu.js → agent-avatar-dicebear-DZ6ETNIk.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DxaIH0Ep.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-B9pZAyMB.js → api-Tz57QxiN.js} +1 -1
  7. package/dist/gateway/static/root/assets/app-management-settings-panel-DdR1L4LR.js +1 -0
  8. package/dist/gateway/static/root/assets/appearance-settings-wYbwqmee.js +1 -0
  9. package/dist/gateway/static/root/assets/apps-page-CyWr6KyO.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-BF0q7N24.js → archive-plugin-DKXa160O.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-D1qmjGDo.js → attachment-load-CzwA9g2y.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-Ccu4yRFa.js → automations-page-DwAXyWAY.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-CL7ieYIt.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-DooqxEZz.js → binary-plugins-DoQ_DnT7.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-Dqg9kvb9.js → block-editor-Bj_Uxxng.js} +47 -47
  16. package/dist/gateway/static/root/assets/browser-settings-page-BYa_FNC1.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-CsIh8ySc.js → browser-workflow-inputs-D4roXE6r.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-BXQFxT0p.js → browser-workflows-page-CleKTAKD.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-DYG37N0k.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-BX9U0FRh.js → capability-presets-api-wtEN6Ss6.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-C0Q4dFq-.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-CUBTQ0Bz.js → channel-recipient-api-DhuS2RJ3.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-CpO6Xg0n.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-CXhPeiNj.js +1 -0
  25. package/dist/gateway/static/root/assets/chat-terminal-dock-ClQMDe2n.js +36 -0
  26. package/dist/gateway/static/root/assets/connectors-page-BvyiPdKU.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-XzPZhzVM.js → cron-expression-4DvCFs-v.js} +1 -1
  28. package/dist/gateway/static/root/assets/date-picker-B6FSjt4Z.js +1 -0
  29. package/dist/gateway/static/root/assets/dependency-picker-Za18eMp1.js +1 -0
  30. package/dist/gateway/static/root/assets/{desktop-pet-DZjW-7Tw.js → desktop-pet-DUUf3yyJ.js} +1 -1
  31. package/dist/gateway/static/root/assets/desktop-pet-settings-Dwx3GfB8.js +1 -0
  32. package/dist/gateway/static/root/assets/directory-picker-path-field-C6dfTCsl.js +1 -0
  33. package/dist/gateway/static/root/assets/ellipsis-0k4rZLoy.js +1 -0
  34. package/dist/gateway/static/root/assets/{extension-debug-page-D7APnE3n.js → extension-debug-page-Cordpg4X.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-BhV5hz70.js → extension-page-Dw0dGyMl.js} +1 -1
  36. package/dist/gateway/static/root/assets/extension-settings-page-B2pUMaXm.js +1 -0
  37. package/dist/gateway/static/root/assets/eye-CABVeTq0.js +1 -0
  38. package/dist/gateway/static/root/assets/eye-off-DEAzt3g1.js +1 -0
  39. package/dist/gateway/static/root/assets/file-code-corner-byQA1VfD.js +1 -0
  40. package/dist/gateway/static/root/assets/form-field-width-DJw_jULe.js +1 -0
  41. package/dist/gateway/static/root/assets/gateway-config-api-DAZUOEQh.js +1 -0
  42. package/dist/gateway/static/root/assets/{gateway-config-swr-BTH9HVUk.js → gateway-config-swr-BIqRg-zo.js} +1 -1
  43. package/dist/gateway/static/root/assets/gateway-settings-ik2f-pmV.js +1 -0
  44. package/dist/gateway/static/root/assets/{gateway-startup-retry-DAEk_tnd.js → gateway-startup-retry-BFjWYOCS.js} +1 -1
  45. package/dist/gateway/static/root/assets/heartbeat-settings-BE81XJ8F.js +1 -0
  46. package/dist/gateway/static/root/assets/home-page-BTWXJu_m.js +1 -0
  47. package/dist/gateway/static/root/assets/{image-generation-api-HqcQrSed.js → image-generation-api-HXAWlgm6.js} +1 -1
  48. package/dist/gateway/static/root/assets/index-B6gWYy08.js +108 -0
  49. package/dist/gateway/static/root/assets/index-CDkuz_YC.css +2 -0
  50. package/dist/gateway/static/root/assets/interaction-BmQogeqz.js +1 -0
  51. package/dist/gateway/static/root/assets/is-masked-secret-DOkL5b_X.js +1 -0
  52. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BG6lShzn.js → keyboard-shortcuts-settings-ROqQ_Xlo.js} +1 -1
  53. package/dist/gateway/static/root/assets/local-app-workbench-page-Dcaf190G.js +2 -0
  54. package/dist/gateway/static/root/assets/{local-apps-page-vaz8ewe2.js → local-apps-page-Be79cyMG.js} +1 -1
  55. package/dist/gateway/static/root/assets/{locale-store-De8wYkd7.js → locale-store-DfK-Hofd.js} +1 -1
  56. package/dist/gateway/static/root/assets/logs-page-C2pjbXno.js +2 -0
  57. package/dist/gateway/static/root/assets/{management-settings-tqTGCHt0.js → management-settings-CRspx0oY.js} +1 -1
  58. package/dist/gateway/static/root/assets/{markdown-split-BGx8Aao0.js → markdown-split-G3PTpGw3.js} +1 -1
  59. package/dist/gateway/static/root/assets/{markdown-view-ybRARsPs.js → markdown-view-D4FPJZ91.js} +1 -1
  60. package/dist/gateway/static/root/assets/{media-plugins-xbM-SSP5.js → media-plugins-DT0P7j7u.js} +1 -1
  61. package/dist/gateway/static/root/assets/messages-B701TEZ5.js +3 -0
  62. package/dist/gateway/static/root/assets/{notes-api-D9CCwyWK.js → notes-api-q7HjYO07.js} +1 -1
  63. package/dist/gateway/static/root/assets/{notes-page-CMNBbg6g.js → notes-page-Cgl2h7AR.js} +1 -1
  64. package/dist/gateway/static/root/assets/notes-workbench-DFMQYyGJ.js +4 -0
  65. package/dist/gateway/static/root/assets/page-tabs-BaEQMYm_.js +1 -0
  66. package/dist/gateway/static/root/assets/preview-open-alternatives-CsNVTKC0.js +1 -0
  67. package/dist/gateway/static/root/assets/{product-open-page-CZdzgPZW.js → product-open-page-ComKLO4D.js} +1 -1
  68. package/dist/gateway/static/root/assets/project-detail-page-DUFmQscH.js +1 -0
  69. package/dist/gateway/static/root/assets/projects-page-CTWxt3dv.js +1 -0
  70. package/dist/gateway/static/root/assets/{registry-api-DYmKEwiG.js → registry-api-BBoJ7khF.js} +1 -1
  71. package/dist/gateway/static/root/assets/remote-access-hub-qmG-3qjj.js +1 -0
  72. package/dist/gateway/static/root/assets/rotate-cw-LIg3Am9S.js +1 -0
  73. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DQ12tLCL.js → runtime-tools-settings-panel-CXHQc53b.js} +2 -2
  74. package/dist/gateway/static/root/assets/{schema-form-DNCDIkqC.js → schema-form-3jTDF2lJ.js} +1 -1
  75. package/dist/gateway/static/root/assets/search-DA7gz22f.js +1 -0
  76. package/dist/gateway/static/root/assets/sessions-page-D_We4_MV.js +1 -0
  77. package/dist/gateway/static/root/assets/settings-advanced-gate-B_QhPgU0.js +1 -0
  78. package/dist/gateway/static/root/assets/settings-form-section-CUDozALU.js +1 -0
  79. package/dist/gateway/static/root/assets/{settings-loading-skeleton-xgo41cfo.js → settings-loading-skeleton-H3ZH6a6l.js} +1 -1
  80. package/dist/gateway/static/root/assets/{settings-page-8astk_1U.js → settings-page-tx29z21o.js} +1 -1
  81. package/dist/gateway/static/root/assets/setup-status-panel-VunfXpTX.js +1 -0
  82. package/dist/gateway/static/root/assets/{share-preview-page-BBZV4AGy.js → share-preview-page-MyThymEx.js} +1 -1
  83. package/dist/gateway/static/root/assets/shares-settings-DkZvY1cr.js +1 -0
  84. package/dist/gateway/static/root/assets/skill-reload-api-DVDOh1iY.js +1 -0
  85. package/dist/gateway/static/root/assets/skills-page-BOOyMnno.js +2 -0
  86. package/dist/gateway/static/root/assets/{skills-page.utils-HmoDhJVh.js → skills-page.utils-Bl5Yv3Cx.js} +1 -1
  87. package/dist/gateway/static/root/assets/system-settings-panel-DwQ3O1ta.js +1 -0
  88. package/dist/gateway/static/root/assets/tab-completion-input-D64VNmiA.js +1 -0
  89. package/dist/gateway/static/root/assets/tab-completion-input.utils-BP3NH_du.js +1 -0
  90. package/dist/gateway/static/root/assets/task-detail-page-BwOyrADL.js +1 -0
  91. package/dist/gateway/static/root/assets/{theme-store-STx6jo38.js → theme-store-Br4BtK4x.js} +1 -1
  92. package/dist/gateway/static/root/assets/typed-models-lib-q5-Vfqd8.js +1 -0
  93. package/dist/gateway/static/root/assets/{use-autosave-CqFVx92z.js → use-autosave-DRS3RwS9.js} +1 -1
  94. package/dist/gateway/static/root/assets/user-context-page-ClV2r3Cr.js +1 -0
  95. package/dist/gateway/static/root/assets/{voice-api-key-field-pYDiKKMo.js → voice-api-key-field-CGTE5156.js} +1 -1
  96. package/dist/gateway/static/root/assets/{work-discovery-overlay-LJLw9zf0.js → work-discovery-overlay-CW-HKD7h.js} +1 -1
  97. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D0WhQ3kI.js → workflow-run-setup-panel-Dtr9fDC8.js} +2 -2
  98. package/dist/gateway/static/root/assets/workflows-page-CDOyNgZf.js +5 -0
  99. package/dist/gateway/static/root/index.html +20 -11
  100. package/dist/package.js +1 -1
  101. package/dist/packages/gateway-contract/src/new-session.js +99 -0
  102. package/dist/packages/gateway-contract/src/tasks.js +5 -0
  103. package/dist/packages/gateway-contract/src/user-message-display.js +55 -0
  104. package/dist/src/agent/agent-manager.js +3 -2
  105. package/dist/src/agent/background-review/prompts.d.ts +1 -1
  106. package/dist/src/agent/background-review/prompts.js +6 -3
  107. package/dist/src/agent/background-review/run-background-review.js +144 -16
  108. package/dist/src/agent/inbound/turn-dispatcher.d.ts +3 -1
  109. package/dist/src/agent/inbound/turn-dispatcher.js +2 -1
  110. package/dist/src/agent/memory/context/types.d.ts +1 -1
  111. package/dist/src/agent/memory/create-memory-manager.js +1 -1
  112. package/dist/src/agent/memory/manager.d.ts +2 -1
  113. package/dist/src/agent/memory/manager.js +2 -6
  114. package/dist/src/agent/memory/understanding/service.d.ts +1 -0
  115. package/dist/src/agent/memory/understanding/service.js +179 -36
  116. package/dist/src/agent/memory/understanding/types.d.ts +6 -0
  117. package/dist/src/agent/messaging/command-handler.d.ts +2 -0
  118. package/dist/src/agent/messaging/command-handler.js +3 -1
  119. package/dist/src/agent/service/direct-turn-helpers.d.ts +3 -0
  120. package/dist/src/agent/service/direct-turn-helpers.js +13 -3
  121. package/dist/src/agent/service/process-direct-streaming.d.ts +2 -1
  122. package/dist/src/agent/service/process-direct-streaming.js +12 -11
  123. package/dist/src/agent/session/session-config-service.d.ts +1 -0
  124. package/dist/src/agent/session/session-config-service.js +11 -0
  125. package/dist/src/agent/session/session-inspector.d.ts +1 -0
  126. package/dist/src/agent/session/session-inspector.js +1 -0
  127. package/dist/src/agent/source-context/budget.d.ts +3 -0
  128. package/dist/src/agent/source-context/budget.js +21 -0
  129. package/dist/src/agent/source-context/index.js +3 -3
  130. package/dist/src/agent/source-context/injector.d.ts +2 -2
  131. package/dist/src/agent/source-context/injector.js +19 -9
  132. package/dist/src/agent/source-context/types.d.ts +16 -0
  133. package/dist/src/agent/source-context/types.js +25 -1
  134. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  135. package/dist/src/agent/tool-manuals/xopc-use.js +19 -2
  136. package/dist/src/agent/tools/xopc-use-tool.js +62 -2
  137. package/dist/src/agent-runtime/index.js +1 -1
  138. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  139. package/dist/src/browser/backend-from-config.d.ts +8 -0
  140. package/dist/src/browser/backend-from-config.js +16 -1
  141. package/dist/src/browser/providers/browser-ext-install.d.ts +3 -2
  142. package/dist/src/browser/providers/browser-ext-install.js +4 -2
  143. package/dist/src/chat-commands/builtins/review.js +11 -2
  144. package/dist/src/chat-commands/builtins/understanding.js +11 -4
  145. package/dist/src/chat-commands/types.d.ts +4 -0
  146. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  147. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  148. package/dist/src/cli/commands/extension.js +1 -1
  149. package/dist/src/config/agent-profile.js +1 -1
  150. package/dist/src/config/models-json.d.ts +20 -20
  151. package/dist/src/connectors/connected-source-ingestion.js +21 -4
  152. package/dist/src/connectors/connected-source-normalizers.js +51 -4
  153. package/dist/src/connectors/connected-source-understanding.d.ts +20 -0
  154. package/dist/src/connectors/connected-source-understanding.js +180 -0
  155. package/dist/src/connectors/content-enrichment.d.ts +1 -0
  156. package/dist/src/connectors/content-enrichment.js +11 -7
  157. package/dist/src/connectors/learning-coordinator.js +112 -15
  158. package/dist/src/connectors/learning-recipes.js +2 -2
  159. package/dist/src/document-understanding/extract.d.ts +1 -1
  160. package/dist/src/document-understanding/extract.js +54 -1
  161. package/dist/src/extensions/update.js +1 -1
  162. package/dist/src/gateway/agents-admin.js +1 -1
  163. package/dist/src/gateway/chat-stream/mapper.js +18 -0
  164. package/dist/src/gateway/heartbeat/service.js +1 -1
  165. package/dist/src/gateway/hono/routes/agent-stream.js +12 -2
  166. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  167. package/dist/src/gateway/hono/routes/commands-skills.js +1 -0
  168. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +46 -2
  169. package/dist/src/gateway/hono/routes/session-input-handler.js +23 -3
  170. package/dist/src/gateway/hono/routes/sessions.js +17 -20
  171. package/dist/src/gateway/hono/routes/tasks.js +25 -0
  172. package/dist/src/gateway/hono/routes/understanding-sources.d.ts +9 -0
  173. package/dist/src/gateway/hono/routes/understanding-sources.js +138 -24
  174. package/dist/src/gateway/hono/routes/you.js +71 -4
  175. package/dist/src/gateway/rate-limit/buckets.d.ts +1 -1
  176. package/dist/src/gateway/rate-limit/buckets.js +2 -2
  177. package/dist/src/gateway/service/agent-runner.d.ts +7 -2
  178. package/dist/src/gateway/service/agent-runner.js +21 -1
  179. package/dist/src/gateway/service/config-coordinator.js +1 -1
  180. package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -0
  181. package/dist/src/gateway/service/run-gateway-agent.js +2 -1
  182. package/dist/src/gateway/service/session-input-coordinator.d.ts +8 -2
  183. package/dist/src/gateway/service/session-input-coordinator.js +62 -3
  184. package/dist/src/gateway/service/sessions-api.d.ts +1 -0
  185. package/dist/src/gateway/service.d.ts +3 -2
  186. package/dist/src/gateway/service.js +16 -6
  187. package/dist/src/gateway/user-turn-input.d.ts +2 -0
  188. package/dist/src/gateway/xopc-cloud-capability-setup.d.ts +3 -2
  189. package/dist/src/gateway/xopc-cloud-capability-setup.js +16 -3
  190. package/dist/src/heartbeat/index.js +1 -1
  191. package/dist/src/infra/update-runner.js +1 -1
  192. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +1 -1
  193. package/dist/src/knowledge/connected-understanding-pipeline.js +4 -2
  194. package/dist/src/retrieval/queryProfile.d.ts +1 -0
  195. package/dist/src/retrieval/queryProfile.js +9 -1
  196. package/dist/src/session/client-history.d.ts +11 -0
  197. package/dist/src/session/client-history.js +24 -2
  198. package/dist/src/session/config-types.d.ts +1 -1
  199. package/dist/src/session/session-title.js +2 -3
  200. package/dist/src/session/store.js +1 -0
  201. package/dist/src/session/transcript-outline.js +5 -2
  202. package/dist/src/session/types.d.ts +1 -0
  203. package/dist/src/session/user-message-display.d.ts +4 -0
  204. package/dist/src/session/user-message-display.js +22 -0
  205. package/dist/src/storage/sqlite/context-extraction-repository.d.ts +57 -0
  206. package/dist/src/storage/sqlite/context-extraction-repository.js +119 -0
  207. package/dist/src/storage/sqlite/context-relation-repository.d.ts +50 -0
  208. package/dist/src/storage/sqlite/context-relation-repository.js +97 -0
  209. package/dist/src/storage/sqlite/index.d.ts +4 -2
  210. package/dist/src/storage/sqlite/index.js +5 -3
  211. package/dist/src/storage/sqlite/migrations/126_focus_context_governance.sql +72 -0
  212. package/dist/src/storage/sqlite/migrations/127_context_object_origin.sql +36 -0
  213. package/dist/src/storage/sqlite/migrations/128_context_extraction.sql +73 -0
  214. package/dist/src/storage/sqlite/migrations/129_focus_versions.sql +51 -0
  215. package/dist/src/storage/sqlite/migrations/130_context_evidence_provenance.sql +18 -0
  216. package/dist/src/storage/sqlite/migrations/131_session_input_contexts.sql +2 -0
  217. package/dist/src/storage/sqlite/migrations/132_transcript_source_context_metadata.sql +34 -0
  218. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  219. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  220. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  221. package/dist/src/storage/sqlite/schema.js +1 -1
  222. package/dist/src/storage/sqlite/session-input-repository.d.ts +8 -0
  223. package/dist/src/storage/sqlite/session-input-repository.js +19 -7
  224. package/dist/src/storage/sqlite/session-turn-replace-repository.d.ts +3 -0
  225. package/dist/src/storage/sqlite/session-turn-replace-repository.js +3 -2
  226. package/dist/src/storage/sqlite/transcript-repository.js +29 -3
  227. package/dist/src/storage/sqlite/user-context-repository.d.ts +4 -1
  228. package/dist/src/storage/sqlite/user-context-repository.js +65 -29
  229. package/dist/src/tasks/index.d.ts +1 -0
  230. package/dist/src/tasks/index.js +2 -1
  231. package/dist/src/tasks/task-deletion-service.d.ts +21 -0
  232. package/dist/src/tasks/task-deletion-service.js +35 -0
  233. package/dist/src/tasks/task-repository.js +22 -1
  234. package/dist/src/tui/backends/embedded-backend.js +5 -3
  235. package/dist/src/tui/backends/gateway-realtime-backend.js +5 -3
  236. package/dist/src/tui/chat-history.js +2 -1
  237. package/dist/src/tui/tui-agent-events.js +4 -2
  238. package/dist/src/tui/tui-commands.d.ts +1 -0
  239. package/dist/src/tui/tui-commands.js +8 -3
  240. package/dist/src/tui/tui-empty-session-cleanup.d.ts +0 -1
  241. package/dist/src/tui/tui-empty-session-cleanup.js +1 -11
  242. package/dist/src/tui/tui-new-session-preferences.d.ts +10 -0
  243. package/dist/src/tui/tui-new-session-preferences.js +32 -0
  244. package/dist/src/tui/tui-session-actions.d.ts +1 -0
  245. package/dist/src/tui/tui-session-actions.js +2 -1
  246. package/dist/src/tui/tui-settings.d.ts +2 -0
  247. package/dist/src/tui/tui-settings.js +4 -1
  248. package/dist/src/tui/tui-types.d.ts +1 -0
  249. package/dist/src/tui/tui.js +57 -4
  250. package/dist/src/tunnel/frpc-process.js +3 -0
  251. package/dist/src/tunnel/tunnel-service.d.ts +2 -0
  252. package/dist/src/tunnel/tunnel-service.js +40 -28
  253. package/dist/src/user-context/context-objects.d.ts +17 -0
  254. package/dist/src/user-context/context-objects.js +99 -0
  255. package/dist/src/user-context/domain.d.ts +13 -1
  256. package/dist/src/user-context/evaluation/harness.d.ts +13 -0
  257. package/dist/src/user-context/evaluation/harness.js +31 -0
  258. package/dist/src/user-context/extraction/registry.d.ts +26 -0
  259. package/dist/src/user-context/extraction/registry.js +113 -0
  260. package/dist/src/user-context/extraction/repair.d.ts +19 -0
  261. package/dist/src/user-context/extraction/repair.js +68 -0
  262. package/dist/src/user-context/planner.js +214 -57
  263. package/dist/src/user-context/retriever.js +69 -9
  264. package/dist/src/user-context/sources/catalog.js +9 -2
  265. package/dist/src/user-context/sources/index.js +2 -2
  266. package/dist/src/user-context/sources/local-source-contract.d.ts +1 -1
  267. package/dist/src/user-context/sources/local-source-contract.js +1 -0
  268. package/dist/src/user-context/sources/processing-policy.d.ts +2 -0
  269. package/dist/src/user-context/sources/processing-policy.js +7 -0
  270. package/dist/src/user-context/sources/repository.d.ts +23 -4
  271. package/dist/src/user-context/sources/repository.js +122 -12
  272. package/dist/src/user-context/sources/types.d.ts +10 -1
  273. package/dist/src/user-context/understanding-writing.d.ts +1 -0
  274. package/dist/src/user-context/understanding-writing.js +4 -0
  275. package/dist/src/user-context/understanding.js +1 -1
  276. package/dist/src/work-discovery/analyzer.d.ts +6 -0
  277. package/dist/src/work-discovery/analyzer.js +181 -57
  278. package/dist/src/work-discovery/index.js +1 -1
  279. package/dist/src/work-discovery/probe.js +20 -0
  280. package/dist/src/work-discovery/service.d.ts +9 -0
  281. package/dist/src/work-discovery/service.js +39 -11
  282. package/dist/src/work-discovery/source-repository.js +1 -1
  283. package/dist/src/work-discovery/types.d.ts +5 -0
  284. package/package.json +3 -3
  285. package/dist/gateway/static/root/assets/agents-C6q_vDzP.js +0 -68
  286. package/dist/gateway/static/root/assets/app-management-settings-panel-DRsTwFbF.js +0 -1
  287. package/dist/gateway/static/root/assets/appearance-settings-B99NaPTf.js +0 -1
  288. package/dist/gateway/static/root/assets/apps-page-Dx66anqa.js +0 -1
  289. package/dist/gateway/static/root/assets/automations-workspace-CHbA8d-P.js +0 -6
  290. package/dist/gateway/static/root/assets/browser-settings-page-CpRc-9Jy.js +0 -8
  291. package/dist/gateway/static/root/assets/capabilities-settings-panel-C89FGECN.js +0 -7
  292. package/dist/gateway/static/root/assets/capability-presets-settings-panel-XT6WEz9E.js +0 -3
  293. package/dist/gateway/static/root/assets/channels-settings-DhKk1oNT.js +0 -1
  294. package/dist/gateway/static/root/assets/channels-status-swr-CiwOOoVL.js +0 -1
  295. package/dist/gateway/static/root/assets/chat-terminal-dock-CTbkTsc2.js +0 -36
  296. package/dist/gateway/static/root/assets/connectors-page-BDn3HTzX.js +0 -2
  297. package/dist/gateway/static/root/assets/date-picker-BmZjs4Bq.js +0 -1
  298. package/dist/gateway/static/root/assets/dependency-picker-ndtb88_T.js +0 -1
  299. package/dist/gateway/static/root/assets/desktop-pet-settings-C7BLs783.js +0 -1
  300. package/dist/gateway/static/root/assets/directory-picker-path-field-BWiap88p.js +0 -1
  301. package/dist/gateway/static/root/assets/extension-settings-page-BhbcGuiJ.js +0 -1
  302. package/dist/gateway/static/root/assets/gateway-config-api-CUt9bIpL.js +0 -1
  303. package/dist/gateway/static/root/assets/gateway-settings-RafSECLG.js +0 -1
  304. package/dist/gateway/static/root/assets/heartbeat-settings-CwVPlPLB.js +0 -1
  305. package/dist/gateway/static/root/assets/home-page-CbdBcCwC.js +0 -1
  306. package/dist/gateway/static/root/assets/index-AbNnQyKk.css +0 -2
  307. package/dist/gateway/static/root/assets/index-CMLkr37Y.js +0 -108
  308. package/dist/gateway/static/root/assets/local-app-workbench-page-DdaPtQ5M.js +0 -2
  309. package/dist/gateway/static/root/assets/logs-page-CjxMHTQO.js +0 -2
  310. package/dist/gateway/static/root/assets/messages-VI9m1xJl.js +0 -3
  311. package/dist/gateway/static/root/assets/notes-workbench-V9C-8vSn.js +0 -4
  312. package/dist/gateway/static/root/assets/page-tabs-e99j9S9K.js +0 -1
  313. package/dist/gateway/static/root/assets/preview-open-alternatives-DW9MDOva.js +0 -1
  314. package/dist/gateway/static/root/assets/project-detail-page-DHmAUggu.js +0 -1
  315. package/dist/gateway/static/root/assets/projects-page-D0EiN69Y.js +0 -1
  316. package/dist/gateway/static/root/assets/remote-access-hub-BuAVFk2O.js +0 -1
  317. package/dist/gateway/static/root/assets/sessions-page-hzlTfgOl.js +0 -1
  318. package/dist/gateway/static/root/assets/settings-advanced-gate-BlCoA_9h.js +0 -1
  319. package/dist/gateway/static/root/assets/settings-form-section-z0JH53Fu.js +0 -1
  320. package/dist/gateway/static/root/assets/setup-status-panel-fZQfoJAk.js +0 -1
  321. package/dist/gateway/static/root/assets/shares-settings-B5dPMq3Y.js +0 -1
  322. package/dist/gateway/static/root/assets/skill-reload-api-i1PGf1V2.js +0 -1
  323. package/dist/gateway/static/root/assets/skills-page-BSN2VaqR.js +0 -2
  324. package/dist/gateway/static/root/assets/system-settings-panel-CSibO8vj.js +0 -1
  325. package/dist/gateway/static/root/assets/tab-completion-input-B-VsxKhC.js +0 -1
  326. package/dist/gateway/static/root/assets/task-detail-page-HCKZ11E8.js +0 -1
  327. package/dist/gateway/static/root/assets/typed-models-lib-zrYg51t3.js +0 -1
  328. package/dist/gateway/static/root/assets/user-context-page-CqG56cDS.js +0 -1
  329. package/dist/gateway/static/root/assets/workflows-page-DQAJzV5w.js +0 -5
@@ -109,6 +109,7 @@ export type CommandHandlerDeps = {
109
109
  extensionShortcuts?: TuiHotkeyExtensionShortcut[];
110
110
  currentAgentId?: string;
111
111
  setSession?: (rawKey: string) => Promise<void>;
112
+ newSession?: () => Promise<void>;
112
113
  resetSession?: () => Promise<void>;
113
114
  recoverStream?: () => void | Promise<void>;
114
115
  retryLastMessage?: () => void | Promise<void>;
@@ -584,6 +584,7 @@ function runTuiProjectCommand(state, args) {
584
584
  ...parsed.projectKind ? { projectKind: parsed.projectKind } : {}
585
585
  });
586
586
  projects.attachSession(state.currentSessionKey, project.id);
587
+ state.sessionInfo.projectId = project.id;
587
588
  return `Created and attached project:\n${formatTuiProject(project)}`;
588
589
  }
589
590
  if (subcommand === "switch" || subcommand === "attach") {
@@ -592,10 +593,12 @@ function runTuiProjectCommand(state, args) {
592
593
  const project = resolveTuiProject(projects, ref);
593
594
  if (!project) return `Project not found: ${ref}`;
594
595
  projects.attachSession(state.currentSessionKey, project.id);
596
+ state.sessionInfo.projectId = project.id;
595
597
  return `Attached current session to project: ${project.name}`;
596
598
  }
597
599
  if (subcommand === "detach") {
598
600
  projects.detachSession(state.currentSessionKey);
601
+ state.sessionInfo.projectId = void 0;
599
602
  return "Detached current session from project.";
600
603
  }
601
604
  if (subcommand === "archive") {
@@ -1260,9 +1263,11 @@ function createTuiCommandHandler(deps) {
1260
1263
  (async () => {
1261
1264
  try {
1262
1265
  await abortActive();
1263
- const uniqueKey = `tui-${randomUUID()}`;
1264
- if (setSession) {
1265
- await setSession(uniqueKey);
1266
+ if (deps.newSession) {
1267
+ await deps.newSession();
1268
+ chatLog.addSystem(`new session: ${state.currentSessionKey}`);
1269
+ } else if (setSession) {
1270
+ await setSession(`tui-${randomUUID()}`);
1266
1271
  chatLog.addSystem(`new session: ${state.currentSessionKey}`);
1267
1272
  } else {
1268
1273
  chatLog.clearAll();
@@ -8,4 +8,3 @@ export declare const GENERATED_TUI_SESSION_SHELL_PATCH: {
8
8
  export declare function isGeneratedTuiSessionKey(sessionKey: string): boolean;
9
9
  export declare function deleteGeneratedTuiSessionIfEmpty(client: Pick<TuiBackend, 'getSessionStats' | 'deleteSession'>, sessionKey: string): Promise<boolean>;
10
10
  export declare function cleanupAbandonedTuiSessions(client: Pick<TuiBackend, 'listSessions' | 'getSessionStats' | 'deleteSession'>, currentSessionKey: string, nowMs?: number): Promise<string[]>;
11
- export declare function hideLegacyEmptyTuiSessions(client: Pick<TuiBackend, 'listSessions' | 'patchSession'>): Promise<string[]>;
@@ -23,15 +23,5 @@ async function cleanupAbandonedTuiSessions(client, currentSessionKey, nowMs = Da
23
23
  for (const session of candidates) if (await deleteGeneratedTuiSessionIfEmpty(client, session.key)) deleted.push(session.key);
24
24
  return deleted;
25
25
  }
26
- async function hideLegacyEmptyTuiSessions(client) {
27
- const sessions = await client.listSessions();
28
- const hidden = [];
29
- for (const session of sessions) {
30
- if (session.messageCount !== 0 || !isGeneratedTuiSessionKey(session.key)) continue;
31
- await client.patchSession(session.key, GENERATED_TUI_SESSION_SHELL_PATCH);
32
- hidden.push(session.key);
33
- }
34
- return hidden;
35
- }
36
26
  //#endregion
37
- export { GENERATED_TUI_SESSION_SHELL_PATCH, cleanupAbandonedTuiSessions, deleteGeneratedTuiSessionIfEmpty, hideLegacyEmptyTuiSessions, isGeneratedTuiSessionKey };
27
+ export { GENERATED_TUI_SESSION_SHELL_PATCH, cleanupAbandonedTuiSessions, deleteGeneratedTuiSessionIfEmpty, isGeneratedTuiSessionKey };
@@ -0,0 +1,10 @@
1
+ import { type AgentModelPreference, type NewSessionPreferences, type SessionInitialAgentConfig } from '@xopcai/gateway-contract';
2
+ import type { TuiSettings } from './tui-settings.js';
3
+ export declare function tuiGatewayPreferenceKey(url?: string): string;
4
+ export declare function getTuiNewSessionPreferences(settings: TuiSettings, gatewayKey: string): NewSessionPreferences;
5
+ export declare function rememberTuiSessionContext(settings: TuiSettings, gatewayKey: string, context: {
6
+ agentId: string;
7
+ projectId?: string | null;
8
+ }): TuiSettings;
9
+ export declare function rememberTuiAgentModel(settings: TuiSettings, gatewayKey: string, agentId: string, preference: AgentModelPreference): TuiSettings;
10
+ export declare function tuiInitialAgentConfig(settings: TuiSettings, gatewayKey: string, agentId: string): SessionInitialAgentConfig | undefined;
@@ -0,0 +1,32 @@
1
+ import { createDefaultNewSessionPreferences, modelPreferenceForAgent, withAgentModelPreference, withLastChatScope, withSelectedAgent } from "../../packages/gateway-contract/src/new-session.js";
2
+ //#region src/tui/tui-new-session-preferences.ts
3
+ function tuiGatewayPreferenceKey(url) {
4
+ return url?.trim() || "local";
5
+ }
6
+ function getTuiNewSessionPreferences(settings, gatewayKey) {
7
+ return settings.newSessionPreferencesByGateway[gatewayKey] ?? createDefaultNewSessionPreferences();
8
+ }
9
+ function withPreferences(settings, gatewayKey, preferences) {
10
+ return {
11
+ ...settings,
12
+ newSessionPreferencesByGateway: {
13
+ ...settings.newSessionPreferencesByGateway,
14
+ [gatewayKey]: preferences
15
+ }
16
+ };
17
+ }
18
+ function rememberTuiSessionContext(settings, gatewayKey, context) {
19
+ return withPreferences(settings, gatewayKey, withLastChatScope(withSelectedAgent(getTuiNewSessionPreferences(settings, gatewayKey), context.agentId), context.projectId));
20
+ }
21
+ function rememberTuiAgentModel(settings, gatewayKey, agentId, preference) {
22
+ return withPreferences(settings, gatewayKey, withAgentModelPreference(getTuiNewSessionPreferences(settings, gatewayKey), agentId, preference));
23
+ }
24
+ function tuiInitialAgentConfig(settings, gatewayKey, agentId) {
25
+ const preference = modelPreferenceForAgent(getTuiNewSessionPreferences(settings, gatewayKey), agentId);
26
+ return preference ? {
27
+ model: preference.modelRef,
28
+ ...preference.thinkingLevel ? { thinkingLevel: preference.thinkingLevel } : {}
29
+ } : void 0;
30
+ }
31
+ //#endregion
32
+ export { getTuiNewSessionPreferences, rememberTuiAgentModel, rememberTuiSessionContext, tuiGatewayPreferenceKey, tuiInitialAgentConfig };
@@ -15,6 +15,7 @@ export type SessionActionsContext = {
15
15
  historyLimit?: number;
16
16
  onAgentIdChange?: (agentId: string) => void;
17
17
  sessionSnapshot?: TuiSessionSnapshot;
18
+ onSessionInfoChange?: () => void;
18
19
  };
19
20
  export declare function createSessionActions(context: SessionActionsContext): {
20
21
  refreshSessionInfo: () => Promise<void>;
@@ -6,7 +6,7 @@ import { clearSeenStreamEvents } from "./tui-agent-events.js";
6
6
  //#region src/tui/tui-session-actions.ts
7
7
  init_agent_session_key();
8
8
  function createSessionActions(context) {
9
- const { client, chatLog, tui, state, resolveSessionKey, updateHeader, updateFooter, setActivityStatus, historyLimit = 200, onAgentIdChange, sessionSnapshot } = context;
9
+ const { client, chatLog, tui, state, resolveSessionKey, updateHeader, updateFooter, setActivityStatus, historyLimit = 200, onAgentIdChange, sessionSnapshot, onSessionInfoChange } = context;
10
10
  let refreshSessionInfoPromise = Promise.resolve();
11
11
  let lastHistoryKeys = [];
12
12
  const updateAgentFromSessionKey = (key) => {
@@ -17,6 +17,7 @@ function createSessionActions(context) {
17
17
  const runRefreshSessionInfo = async () => {
18
18
  try {
19
19
  state.sessionInfo = await client.getSessionInfo(state.currentSessionKey);
20
+ onSessionInfoChange?.();
20
21
  updateFooter();
21
22
  tui.requestRender();
22
23
  } catch {}
@@ -1,3 +1,4 @@
1
+ import { type NewSessionPreferences } from '@xopcai/gateway-contract';
1
2
  export type TuiThemeId = 'auto' | 'dark' | 'light' | (string & {});
2
3
  export type DoubleEscapeAction = 'none' | 'tree' | 'fork';
3
4
  export type TreeFilterMode = 'default' | 'no-tools' | 'user-only' | 'labeled-only' | 'all';
@@ -24,6 +25,7 @@ export interface TuiSettings {
24
25
  clearOnShrink: boolean;
25
26
  /** Default transcript filter when opening `/tree`. */
26
27
  treeFilterMode: TreeFilterMode;
28
+ newSessionPreferencesByGateway: Record<string, NewSessionPreferences>;
27
29
  }
28
30
  export declare const DEFAULT_TUI_SETTINGS: TuiSettings;
29
31
  /** Load persisted TUI settings from `~/.xopc/tui-settings.json`. */
@@ -1,5 +1,6 @@
1
1
  import { resolveStateDir } from "../config/paths-state.js";
2
2
  import { init_paths } from "../config/paths.js";
3
+ import { parseNewSessionPreferences } from "../../packages/gateway-contract/src/new-session.js";
3
4
  import { join } from "node:path";
4
5
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
6
  //#region src/tui/tui-settings.ts
@@ -17,7 +18,8 @@ const DEFAULT_TUI_SETTINGS = {
17
18
  editorPaddingX: 0,
18
19
  autocompleteMaxVisible: 5,
19
20
  clearOnShrink: false,
20
- treeFilterMode: "default"
21
+ treeFilterMode: "default",
22
+ newSessionPreferencesByGateway: {}
21
23
  };
22
24
  const SETTINGS_PATH = join(resolveStateDir(), "tui-settings.json");
23
25
  function isDoubleEscapeAction(value) {
@@ -43,6 +45,7 @@ function normalizeSettings(raw) {
43
45
  if (typeof obj.autocompleteMaxVisible === "number" && Number.isFinite(obj.autocompleteMaxVisible)) base.autocompleteMaxVisible = Math.max(3, Math.min(20, Math.floor(obj.autocompleteMaxVisible)));
44
46
  if (typeof obj.clearOnShrink === "boolean") base.clearOnShrink = obj.clearOnShrink;
45
47
  if (isTreeFilterMode(obj.treeFilterMode)) base.treeFilterMode = obj.treeFilterMode;
48
+ if (obj.newSessionPreferencesByGateway && typeof obj.newSessionPreferencesByGateway === "object" && !Array.isArray(obj.newSessionPreferencesByGateway)) base.newSessionPreferencesByGateway = Object.fromEntries(Object.entries(obj.newSessionPreferencesByGateway).map(([gatewayId, preferences]) => [gatewayId, parseNewSessionPreferences(preferences)]));
46
49
  return base;
47
50
  }
48
51
  /** Load persisted TUI settings from `~/.xopc/tui-settings.json`. */
@@ -57,6 +57,7 @@ export interface SessionInfo {
57
57
  displayName?: string;
58
58
  effectiveWorkspacePath?: string;
59
59
  workingDirectoryLocked?: boolean;
60
+ projectId?: string;
60
61
  }
61
62
  /** Mutable state bag for the TUI runtime. */
62
63
  export interface TuiState {
@@ -27,13 +27,14 @@ import { transcriptTreeEntryIdToRowNumber } from "./tui-transcript-tree.js";
27
27
  import { formatTuiCompactionResult, formatTuiShareResult } from "./tui-command-formatters.js";
28
28
  import { formatTuiStartupText } from "./tui-startup-text.js";
29
29
  import { createTuiCommandHandler, getSlashCommands } from "./tui-commands.js";
30
- import { GENERATED_TUI_SESSION_SHELL_PATCH, cleanupAbandonedTuiSessions, deleteGeneratedTuiSessionIfEmpty, hideLegacyEmptyTuiSessions, isGeneratedTuiSessionKey } from "./tui-empty-session-cleanup.js";
30
+ import { GENERATED_TUI_SESSION_SHELL_PATCH, cleanupAbandonedTuiSessions, deleteGeneratedTuiSessionIfEmpty, isGeneratedTuiSessionKey } from "./tui-empty-session-cleanup.js";
31
31
  import { extensionCustomMessageContentToText, extensionCustomMessageToTurnText, extensionUserMessageContentToText } from "./tui-extension-user-message.js";
32
32
  import { resolveFdPath } from "./tui-fd-path.js";
33
33
  import { createBackspaceDeduper, drainAndStopTuiSafely, isIgnorableTuiStopError, resolveCtrlCAction, stopTuiSafely } from "./tui-lifecycle.js";
34
34
  import { createLocalShellRunner } from "./tui-local-shell.js";
35
35
  import { filterModelsForCycle, loadScopedModelRefs, saveScopedModelRefs } from "./tui-scoped-models.js";
36
36
  import { openModelPickerOverlay } from "./tui-model-picker.js";
37
+ import { getTuiNewSessionPreferences, rememberTuiAgentModel, rememberTuiSessionContext, tuiGatewayPreferenceKey, tuiInitialAgentConfig } from "./tui-new-session-preferences.js";
37
38
  import { runTuiOAuthLogin } from "./tui-oauth-login.js";
38
39
  import { openAgentPickerOverlay, openProjectTrustOverlay, openReviewLauncherOverlay, openScopedModelsOverlay, openSessionPickerOverlay, openSessionTreeOverlay, openSettingsOverlay, openThinkingSelectorOverlay, openTimelineOverlay, openTranscriptTreeOverlay, openUserMessageForkOverlay } from "./tui-picker-overlay.js";
39
40
  import { formatActiveRunStatus, formatRunDuration } from "./tui-run-status-format.js";
@@ -195,6 +196,7 @@ async function runTui(opts) {
195
196
  sessionMainKey
196
197
  });
197
198
  let tuiSettings = loadTuiSettings();
199
+ const newSessionPreferenceKey = isLocalMode ? tuiGatewayPreferenceKey() : tuiGatewayPreferenceKey(opts.url ?? "http://localhost:3120");
198
200
  initTuiTheme({ themeId: opts.theme ?? tuiSettings.theme });
199
201
  const state = createInitialState(startup.sessionKey);
200
202
  const generatedStartupSessionKey = !opts.session?.trim() && isGeneratedTuiSessionKey(startup.sessionKey) ? startup.sessionKey : null;
@@ -722,7 +724,7 @@ async function runTui(opts) {
722
724
  };
723
725
  const runExtensionNewSession = async (options) => {
724
726
  await abortActive({ clearUi: false });
725
- await setSession(resolveSessionKey(`session-${randomUUID()}`));
727
+ await startPreferredNewSession("session");
726
728
  await options?.setup?.(sessionSnapshot.manager());
727
729
  await runWithReplacementContext(options?.withSession);
728
730
  return { cancelled: false };
@@ -989,8 +991,34 @@ async function runTui(opts) {
989
991
  sessionSnapshot,
990
992
  onAgentIdChange: (agentId) => {
991
993
  currentAgentId = agentId;
992
- }
994
+ },
995
+ onSessionInfoChange: () => persistCurrentNewSessionContext()
993
996
  });
997
+ const persistCurrentNewSessionContext = () => {
998
+ const current = getTuiNewSessionPreferences(tuiSettings, newSessionPreferenceKey);
999
+ const normalizedProjectId = state.sessionInfo.projectId?.trim() || null;
1000
+ const currentProjectId = current.lastChatScope.kind === "project" ? current.lastChatScope.projectId : null;
1001
+ if (current.selectedAgentId === currentAgentId && currentProjectId === normalizedProjectId) return;
1002
+ tuiSettings = rememberTuiSessionContext(tuiSettings, newSessionPreferenceKey, {
1003
+ agentId: currentAgentId,
1004
+ projectId: normalizedProjectId
1005
+ });
1006
+ saveTuiSettings(tuiSettings);
1007
+ };
1008
+ const startPreferredNewSession = async (prefix = "tui") => {
1009
+ const projectId = state.sessionInfo.projectId?.trim() || void 0;
1010
+ await setSession(resolveSessionKey(`${prefix}-${randomUUID()}`));
1011
+ const initialAgentConfig = tuiInitialAgentConfig(tuiSettings, newSessionPreferenceKey, currentAgentId);
1012
+ if (initialAgentConfig || projectId) {
1013
+ await client.patchSession(state.currentSessionKey, {
1014
+ ...initialAgentConfig,
1015
+ ...projectId ? { projectId } : {},
1016
+ ...isGeneratedTuiSessionKey(state.currentSessionKey) ? GENERATED_TUI_SESSION_SHELL_PATCH : {}
1017
+ });
1018
+ await refreshSessionInfo();
1019
+ }
1020
+ persistCurrentNewSessionContext();
1021
+ };
994
1022
  const refreshSessionInfoWithBorder = async () => {
995
1023
  await refreshSessionInfo();
996
1024
  updateEditorBorderColor();
@@ -1115,6 +1143,14 @@ async function runTui(opts) {
1115
1143
  try {
1116
1144
  await client.patchSession(state.currentSessionKey, { thinkingLevel: level });
1117
1145
  state.sessionInfo.thinkingLevel = level;
1146
+ const currentModelRef = state.sessionInfo.modelProvider && state.sessionInfo.model ? `${state.sessionInfo.modelProvider}/${state.sessionInfo.model}` : state.sessionInfo.model;
1147
+ if (currentModelRef) {
1148
+ tuiSettings = rememberTuiAgentModel(tuiSettings, newSessionPreferenceKey, currentAgentId, {
1149
+ modelRef: currentModelRef,
1150
+ thinkingLevel: level
1151
+ });
1152
+ saveTuiSettings(tuiSettings);
1153
+ }
1118
1154
  await refreshSessionInfoWithBorder();
1119
1155
  updateFooter();
1120
1156
  chatLog.addStatus(theme.dim(`Thinking level: ${level}`));
@@ -1250,6 +1286,11 @@ async function runTui(opts) {
1250
1286
  await client.patchSession(state.currentSessionKey, { model: trimmed });
1251
1287
  state.sessionInfo.modelProvider = selected.provider;
1252
1288
  state.sessionInfo.model = selected.id;
1289
+ tuiSettings = rememberTuiAgentModel(tuiSettings, newSessionPreferenceKey, currentAgentId, {
1290
+ modelRef: trimmed,
1291
+ ...state.sessionInfo.thinkingLevel ? { thinkingLevel: state.sessionInfo.thinkingLevel } : {}
1292
+ });
1293
+ saveTuiSettings(tuiSettings);
1253
1294
  if (selected.contextWindow != null) state.sessionInfo.contextWindow = selected.contextWindow;
1254
1295
  await refreshSessionInfoWithBorder();
1255
1296
  updateFooter();
@@ -1706,6 +1747,10 @@ async function runTui(opts) {
1706
1747
  await setSession(rawKey);
1707
1748
  await refreshStartupResources();
1708
1749
  },
1750
+ newSession: async () => {
1751
+ await startPreferredNewSession();
1752
+ await refreshStartupResources();
1753
+ },
1709
1754
  resetSession: resetCurrentSession,
1710
1755
  projectTrust: {
1711
1756
  cwd: process.cwd(),
@@ -2158,7 +2203,15 @@ async function runTui(opts) {
2158
2203
  const errorMessage = err instanceof Error ? err.message : String(err);
2159
2204
  chatLog.addSystem(`Project not selected: ${errorMessage}`);
2160
2205
  }
2206
+ if (!opts.session?.trim() && isGeneratedTuiSessionKey(state.currentSessionKey)) {
2207
+ const initialAgentConfig = tuiInitialAgentConfig(tuiSettings, newSessionPreferenceKey, currentAgentId);
2208
+ if (initialAgentConfig || opts.thinking?.trim()) await client.patchSession(state.currentSessionKey, {
2209
+ ...initialAgentConfig,
2210
+ ...opts.thinking?.trim() ? { thinkingLevel: opts.thinking.trim() } : {}
2211
+ });
2212
+ }
2161
2213
  await refreshSessionInfoWithBorder();
2214
+ persistCurrentNewSessionContext();
2162
2215
  try {
2163
2216
  state.pendingInputCount = countPendingChatInputs((await client.getChatInputState(state.currentSessionKey)).inputs);
2164
2217
  } catch {
@@ -2166,7 +2219,7 @@ async function runTui(opts) {
2166
2219
  }
2167
2220
  await refreshModelChoices();
2168
2221
  await loadSessionHistory({ merge: true });
2169
- cleanupAbandonedTuiSessions(client, state.currentSessionKey).then(() => hideLegacyEmptyTuiSessions(client)).catch(() => {});
2222
+ cleanupAbandonedTuiSessions(client, state.currentSessionKey).catch(() => {});
2170
2223
  showStartupCardOnce();
2171
2224
  refreshStartupResources().then(() => {
2172
2225
  updateFooter();
@@ -45,6 +45,9 @@ function spawnFrpcProcess(frpcBin, configPath) {
45
45
  loginReject = void 0;
46
46
  });
47
47
  child.on("exit", (code, signal) => {
48
+ loginReject?.(/* @__PURE__ */ new Error(`frpc exited before login (code=${code ?? "null"}, signal=${signal ?? "null"})`));
49
+ loginResolve = void 0;
50
+ loginReject = void 0;
48
51
  for (const h of exitHandlers) h(code, signal);
49
52
  });
50
53
  if (!child.pid) throw new Error("Failed to spawn frpc process");
@@ -18,6 +18,7 @@ export declare class TunnelService extends EventEmitter {
18
18
  private lastError;
19
19
  private state;
20
20
  private reconnectAttempt;
21
+ private reconnectTask;
21
22
  private stopping;
22
23
  private startContext;
23
24
  private frpcDownload;
@@ -36,6 +37,7 @@ export declare class TunnelService extends EventEmitter {
36
37
  private resolveRegistration;
37
38
  private spawnAndWait;
38
39
  private scheduleReconnect;
40
+ private runReconnectLoop;
39
41
  private startHeartbeat;
40
42
  private clearHeartbeat;
41
43
  }
@@ -36,6 +36,7 @@ var TunnelService = class extends EventEmitter {
36
36
  lastError = null;
37
37
  state = "disconnected";
38
38
  reconnectAttempt = 0;
39
+ reconnectTask = null;
39
40
  stopping = false;
40
41
  startContext = null;
41
42
  frpcDownload = null;
@@ -240,13 +241,14 @@ var TunnelService = class extends EventEmitter {
240
241
  }
241
242
  async spawnAndWait(frpcBin, configPath, broker, state, heartbeatIntervalMs) {
242
243
  if (this.frpcHandle) {
243
- await this.frpcHandle.kill();
244
+ const previousHandle = this.frpcHandle;
244
245
  this.frpcHandle = null;
246
+ await previousHandle.kill();
245
247
  }
246
248
  const handle = spawnFrpcProcess(frpcBin, configPath);
247
249
  this.frpcHandle = handle;
248
250
  handle.onExit((code, signal) => {
249
- if (this.stopping) return;
251
+ if (this.stopping || this.frpcHandle !== handle) return;
250
252
  log.warn({
251
253
  code,
252
254
  signal,
@@ -261,33 +263,43 @@ var TunnelService = class extends EventEmitter {
261
263
  }
262
264
  async scheduleReconnect(frpcBin, configPath, broker, state, heartbeatIntervalMs) {
263
265
  if (this.stopping) return;
266
+ if (this.reconnectTask) return this.reconnectTask;
267
+ const task = this.runReconnectLoop(frpcBin, configPath, broker, state, heartbeatIntervalMs).finally(() => {
268
+ if (this.reconnectTask === task) this.reconnectTask = null;
269
+ });
270
+ this.reconnectTask = task;
271
+ return task;
272
+ }
273
+ async runReconnectLoop(frpcBin, configPath, broker, state, heartbeatIntervalMs) {
264
274
  const maxAttempts = 5;
265
- this.reconnectAttempt += 1;
266
- if (this.reconnectAttempt > maxAttempts) {
267
- this.state = "error";
268
- this.lastError = "frpc reconnect failed after maximum attempts";
269
- log.error({ attempts: maxAttempts }, this.lastError);
270
- this.emit("tunnel:error", this.lastError);
271
- return;
272
- }
273
- this.state = "reconnecting";
274
- this.setStartPhase("reconnecting_frpc", { publicUrl: state.publicUrl ?? null });
275
- const delayMs = Math.min(16e3, 1e3 * 2 ** (this.reconnectAttempt - 1));
276
- log.info({
277
- attempt: this.reconnectAttempt,
278
- delayMs
279
- }, "Scheduling frpc reconnect");
280
- await new Promise((r) => setTimeout(r, delayMs));
281
- if (this.stopping) return;
282
- try {
283
- await this.spawnAndWait(frpcBin, configPath, broker, state, heartbeatIntervalMs);
284
- this.clearStartProgress();
285
- this.state = "connected";
286
- this.reconnectAttempt = 0;
287
- this.emit("tunnel:connected");
288
- } catch (err) {
289
- this.lastError = err instanceof Error ? err.message : String(err);
290
- this.scheduleReconnect(frpcBin, configPath, broker, state, heartbeatIntervalMs);
275
+ while (!this.stopping) {
276
+ this.reconnectAttempt += 1;
277
+ if (this.reconnectAttempt > maxAttempts) {
278
+ this.state = "error";
279
+ this.lastError = "frpc reconnect failed after maximum attempts";
280
+ log.error({ attempts: maxAttempts }, this.lastError);
281
+ this.emit("tunnel:error", this.lastError);
282
+ return;
283
+ }
284
+ this.state = "reconnecting";
285
+ this.setStartPhase("reconnecting_frpc", { publicUrl: state.publicUrl ?? null });
286
+ const delayMs = Math.min(16e3, 1e3 * 2 ** (this.reconnectAttempt - 1));
287
+ log.info({
288
+ attempt: this.reconnectAttempt,
289
+ delayMs
290
+ }, "Scheduling frpc reconnect");
291
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
292
+ if (this.stopping) return;
293
+ try {
294
+ await this.spawnAndWait(frpcBin, configPath, broker, state, heartbeatIntervalMs);
295
+ this.clearStartProgress();
296
+ this.state = "connected";
297
+ this.reconnectAttempt = 0;
298
+ this.emit("tunnel:connected");
299
+ return;
300
+ } catch (err) {
301
+ this.lastError = err instanceof Error ? err.message : String(err);
302
+ }
291
303
  }
292
304
  }
293
305
  startHeartbeat(broker, state, intervalMs) {
@@ -0,0 +1,17 @@
1
+ import type { ContextEvidence, UserContextScope } from './domain.js';
2
+ export type ContextObjectView = 'current' | 'review' | 'history';
3
+ export type ContextObjectOrigin = 'told_by_user' | 'observed' | 'inferred' | 'connected_source';
4
+ export type ContextObject = {
5
+ objectType: 'profile' | 'rule' | 'focus' | 'understanding';
6
+ objectId: string;
7
+ status: string;
8
+ content: string;
9
+ scope: UserContextScope;
10
+ origin: ContextObjectOrigin;
11
+ confidence: number;
12
+ evidence: ContextEvidence[] | Array<{
13
+ sourceRef: string;
14
+ }>;
15
+ updatedAt: number;
16
+ };
17
+ export declare function listContextObjects(view: ContextObjectView): ContextObject[];
@@ -0,0 +1,99 @@
1
+ import { getUserProfile, listCollaborationRules, listUnderstandingEvidence, listUnderstandings } from "../storage/sqlite/user-context-repository.js";
2
+ import "../storage/sqlite/index.js";
3
+ import { getUnderstandingSourceGrant, getUnderstandingSourceRun, listUserFocusEvidence, listUserFocuses } from "./sources/repository.js";
4
+ //#region src/user-context/context-objects.ts
5
+ function understandingOrigin(item, evidence) {
6
+ if (item.explicitness === "explicit") return "told_by_user";
7
+ if (evidence.some((entry) => entry.sourceType === "connector")) return "connected_source";
8
+ return item.explicitness === "observed" ? "observed" : "inferred";
9
+ }
10
+ function includesStatus(view, objectType, status) {
11
+ if (view === "current") return status === "active";
12
+ if (view === "review") return objectType === "understanding" ? [
13
+ "candidate",
14
+ "needs_review",
15
+ "stale"
16
+ ].includes(status) : objectType === "focus" && status === "candidate";
17
+ return objectType === "understanding" ? ["archived", "rejected"].includes(status) : objectType === "focus" ? [
18
+ "paused",
19
+ "completed",
20
+ "rejected"
21
+ ].includes(status) : objectType === "rule" && ["disabled", "archived"].includes(status);
22
+ }
23
+ function listContextObjects(view) {
24
+ const objects = [];
25
+ if (view === "current") {
26
+ const profile = getUserProfile();
27
+ const fields = [
28
+ ["callName", profile.callName],
29
+ ["role", profile.role],
30
+ ["primaryGoal", profile.primaryGoal],
31
+ ["pronouns", profile.pronouns],
32
+ ["timezone", profile.timezone],
33
+ ["locale", profile.locale]
34
+ ];
35
+ for (const [field, value] of fields) {
36
+ if (!value) continue;
37
+ objects.push({
38
+ objectType: "profile",
39
+ objectId: field,
40
+ status: "active",
41
+ content: value,
42
+ scope: { type: "global" },
43
+ origin: "told_by_user",
44
+ confidence: 1,
45
+ evidence: [{ sourceRef: `user-profile://${field}` }],
46
+ updatedAt: profile.updatedAt
47
+ });
48
+ }
49
+ }
50
+ for (const rule of listCollaborationRules()) {
51
+ if (!includesStatus(view, "rule", rule.status)) continue;
52
+ objects.push({
53
+ objectType: "rule",
54
+ objectId: rule.id,
55
+ status: rule.status,
56
+ content: rule.statement,
57
+ scope: rule.scope,
58
+ origin: "told_by_user",
59
+ confidence: 1,
60
+ evidence: [{ sourceRef: `collaboration-rule://${rule.revisionId}` }],
61
+ updatedAt: rule.updatedAt
62
+ });
63
+ }
64
+ for (const focus of listUserFocuses()) {
65
+ if (!includesStatus(view, "focus", focus.status)) continue;
66
+ const sourceRun = focus.sourceRunId ? getUnderstandingSourceRun(focus.sourceRunId) : null;
67
+ const sourceGrant = sourceRun ? getUnderstandingSourceGrant(sourceRun.grantId) : null;
68
+ const linkedEvidence = listUserFocusEvidence(focus.id);
69
+ objects.push({
70
+ objectType: "focus",
71
+ objectId: focus.id,
72
+ status: focus.status,
73
+ content: `${focus.title}: ${focus.summary}`,
74
+ scope: focus.scope,
75
+ origin: focus.explicitness === "explicit" ? "told_by_user" : sourceGrant?.adapterId.startsWith("connector:") ? "connected_source" : focus.explicitness === "observed" ? "observed" : "inferred",
76
+ confidence: focus.confidence,
77
+ evidence: linkedEvidence.length ? linkedEvidence : focus.evidenceRefs.map((sourceRef) => ({ sourceRef })),
78
+ updatedAt: focus.updatedAt
79
+ });
80
+ }
81
+ for (const understanding of listUnderstandings()) {
82
+ if (!includesStatus(view, "understanding", understanding.status)) continue;
83
+ const evidence = listUnderstandingEvidence(understanding.id);
84
+ objects.push({
85
+ objectType: "understanding",
86
+ objectId: understanding.id,
87
+ status: understanding.status,
88
+ content: understanding.statement,
89
+ scope: understanding.scope,
90
+ origin: understandingOrigin(understanding, evidence),
91
+ confidence: understanding.confidence,
92
+ evidence,
93
+ updatedAt: understanding.updatedAt
94
+ });
95
+ }
96
+ return objects.sort((left, right) => right.updatedAt - left.updatedAt);
97
+ }
98
+ //#endregion
99
+ export { listContextObjects };
@@ -53,13 +53,14 @@ export type CollaborationRule = {
53
53
  updatedAt: number;
54
54
  };
55
55
  export type PersonalizationItem = {
56
- objectType: 'profile' | 'rule' | 'understanding';
56
+ objectType: 'profile' | 'rule' | 'focus' | 'understanding';
57
57
  objectId: string;
58
58
  versionId?: string;
59
59
  decision: 'selected' | 'irrelevant' | 'expired' | 'scope_mismatch' | 'sensitive' | 'needs_consent' | 'budget_exceeded' | 'conflicted' | 'disabled';
60
60
  reason: string;
61
61
  content: string;
62
62
  sourceLabel: string;
63
+ origin: 'told_by_user' | 'observed' | 'inferred' | 'connected_source';
63
64
  rank?: number;
64
65
  score?: number;
65
66
  injectedChars: number;
@@ -69,8 +70,19 @@ export type ContextEvidence = {
69
70
  sourceType: 'conversation' | 'connector' | 'user' | 'runtime';
70
71
  sourceInstanceId?: string;
71
72
  sourceRef: string;
73
+ sourceRunId?: string;
74
+ sourceItemId?: string;
75
+ sessionId?: string;
76
+ turnId?: string;
77
+ messageId?: string;
78
+ contentHash?: string;
79
+ retentionPolicy?: 'metadata_only' | 'derived_only' | 'bounded_raw';
80
+ processingPolicy?: 'local_only' | 'remote_allowed';
81
+ extractorId?: string;
82
+ extractorVersion?: string;
72
83
  redactedExcerpt?: string;
73
84
  trustLevel: 'owner' | 'trusted' | 'untrusted';
74
85
  observedAt: number;
86
+ ingestedAt: number;
75
87
  createdAt: number;
76
88
  };
@@ -0,0 +1,13 @@
1
+ export type RetrievalEvaluationCase = {
2
+ id: string;
3
+ expectedIds: string[];
4
+ shouldAbstain?: boolean;
5
+ retrieve: () => string[];
6
+ };
7
+ export type RetrievalEvaluationMetrics = {
8
+ cases: number;
9
+ recallAtK: number;
10
+ precisionAtK: number;
11
+ abstentionAccuracy: number;
12
+ };
13
+ export declare function evaluateRetrievalCases(cases: RetrievalEvaluationCase[], k?: number): RetrievalEvaluationMetrics;
@@ -0,0 +1,31 @@
1
+ //#region src/user-context/evaluation/harness.ts
2
+ function evaluateRetrievalCases(cases, k = 3) {
3
+ let expected = 0;
4
+ let recalled = 0;
5
+ let returned = 0;
6
+ let relevantReturned = 0;
7
+ let abstentionCases = 0;
8
+ let correctAbstentions = 0;
9
+ for (const item of cases) {
10
+ const results = [...new Set(item.retrieve())].slice(0, Math.max(1, k));
11
+ const expectedIds = new Set(item.expectedIds);
12
+ if (item.shouldAbstain) {
13
+ abstentionCases += 1;
14
+ if (results.length === 0) correctAbstentions += 1;
15
+ continue;
16
+ }
17
+ expected += expectedIds.size;
18
+ returned += results.length;
19
+ const matches = results.filter((id) => expectedIds.has(id)).length;
20
+ recalled += matches;
21
+ relevantReturned += matches;
22
+ }
23
+ return {
24
+ cases: cases.length,
25
+ recallAtK: expected ? recalled / expected : 1,
26
+ precisionAtK: returned ? relevantReturned / returned : 1,
27
+ abstentionAccuracy: abstentionCases ? correctAbstentions / abstentionCases : 1
28
+ };
29
+ }
30
+ //#endregion
31
+ export { evaluateRetrievalCases };