@xopcai/xopc 0.0.224 → 0.0.227

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 (232) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/demo-memory/src/index.js +10 -1
  3. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store--GBciH10.js → activity-store-BevwE16n.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-K7V4XXt7.js → agent-avatar-dicebear-BggVQrEZ.js} +1 -1
  7. package/dist/gateway/static/root/assets/agents-TJpjRHnr.js +68 -0
  8. package/dist/gateway/static/root/assets/{api-HoIz_ija.js → api-Bx_BpIt8.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-xQCmkAHh.js → app-management-settings-panel-BtKP9n2r.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-BRoeA4kU.js → appearance-settings-BoH2NAUX.js} +1 -1
  11. package/dist/gateway/static/root/assets/apps-page-CZ4Da51l.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-CteCVsBP.js → archive-plugin-DnceUyxm.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-D7xNA2jB.js → attachment-load-Bh8_9gkr.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-page-BD1vK7r5.js → automations-page-ZKeAAVxD.js} +1 -1
  15. package/dist/gateway/static/root/assets/automations-workspace-2Y00PvJU.js +6 -0
  16. package/dist/gateway/static/root/assets/{binary-plugins-C3DaJa0W.js → binary-plugins-Cy9er6w-.js} +1 -1
  17. package/dist/gateway/static/root/assets/{block-editor-lTkcHTve.js → block-editor-Cc0wWvNX.js} +3 -3
  18. package/dist/gateway/static/root/assets/browser-settings-page-CbJD27_j.js +8 -0
  19. package/dist/gateway/static/root/assets/{browser-workflow-inputs-1UZ0vnIy.js → browser-workflow-inputs-BS7rpLLl.js} +1 -1
  20. package/dist/gateway/static/root/assets/{browser-workflows-page-BHuJOF4M.js → browser-workflows-page-BdBVUZXm.js} +2 -2
  21. package/dist/gateway/static/root/assets/capabilities-settings-panel-Dv8y6OuP.js +7 -0
  22. package/dist/gateway/static/root/assets/{capability-presets-api-yNqTIuyd.js → capability-presets-api-D1Lqz0Tt.js} +1 -1
  23. package/dist/gateway/static/root/assets/capability-presets-settings-panel-TZmjzWzt.js +3 -0
  24. package/dist/gateway/static/root/assets/{channel-recipient-api-krezGsKc.js → channel-recipient-api-CGuEl-l2.js} +1 -1
  25. package/dist/gateway/static/root/assets/{channels-settings-B4AtvQHk.js → channels-settings-g-68dutA.js} +1 -1
  26. package/dist/gateway/static/root/assets/channels-status-swr-D7KsAeWh.js +1 -0
  27. package/dist/gateway/static/root/assets/{chat-terminal-dock-BRrL2iHA.js → chat-terminal-dock-CdX_7aQh.js} +1 -1
  28. package/dist/gateway/static/root/assets/connectors-page-DXA0rAvQ.js +2 -0
  29. package/dist/gateway/static/root/assets/{cron-expression-Bl-2DzBQ.js → cron-expression-BnSQc4Ek.js} +1 -1
  30. package/dist/gateway/static/root/assets/{date-picker-CxTl6Wlz.js → date-picker-BbuG7zQ_.js} +1 -1
  31. package/dist/gateway/static/root/assets/{dependency-picker-DSl0mOPa.js → dependency-picker-snZeqOmG.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-DTeCmCdb.js → desktop-pet-DJQ8JoR1.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-BNebxg0V.js → desktop-pet-settings-B9txsRtv.js} +1 -1
  34. package/dist/gateway/static/root/assets/{directory-picker-path-field-Dn9XpmXY.js → directory-picker-path-field-D7WKWkNB.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-debug-page-D-J-eOTb.js → extension-debug-page-D_7cOCj2.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-page-CpST24nU.js → extension-page-Bwu47iUb.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-settings-page-4nQXFnFq.js → extension-settings-page-Dwg4dSZM.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-config-api-BHWHduDi.js → gateway-config-api-jURUSte_.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-swr-yUxMMVjK.js → gateway-config-swr-6SQXF1yR.js} +1 -1
  40. package/dist/gateway/static/root/assets/{gateway-settings-BimMKmkM.js → gateway-settings-UklJOMLX.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-9mrsL84j.js → gateway-startup-retry-DqWaxyvZ.js} +1 -1
  42. package/dist/gateway/static/root/assets/heartbeat-settings-Djs_nduD.js +1 -0
  43. package/dist/gateway/static/root/assets/{home-page-DSM6aPHF.js → home-page-i6bXCHdo.js} +1 -1
  44. package/dist/gateway/static/root/assets/{image-generation-api-CgFAGDi8.js → image-generation-api-Bxmt6LEr.js} +1 -1
  45. package/dist/gateway/static/root/assets/index-BBBE89vm.css +2 -0
  46. package/dist/gateway/static/root/assets/index-BsD5wygl.js +74 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-6Ar5rfX4.js → keyboard-shortcuts-settings-ByVsCH3d.js} +1 -1
  48. package/dist/gateway/static/root/assets/{local-app-workbench-page-tzM0wTL8.js → local-app-workbench-page-BCKEDMlP.js} +2 -2
  49. package/dist/gateway/static/root/assets/{local-apps-page-B5n-x544.js → local-apps-page-D19R-xsz.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-CPylQjH9.js → locale-store-Ci1Qi0Q-.js} +1 -1
  51. package/dist/gateway/static/root/assets/{logs-page-CgoQlera.js → logs-page-Cy9YQK7j.js} +2 -2
  52. package/dist/gateway/static/root/assets/{management-settings-CXBLyU-0.js → management-settings-G0y7zmfY.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-split-CtmQemJi.js → markdown-split-B69d2HWt.js} +1 -1
  54. package/dist/gateway/static/root/assets/{markdown-view-CUsob4Pz.js → markdown-view-CBM-v2ph.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-Dsd-IEOW.js → media-plugins-6TWEQgN_.js} +1 -1
  56. package/dist/gateway/static/root/assets/messages-CtOJwGW3.js +3 -0
  57. package/dist/gateway/static/root/assets/{notes-api-CfKZYrBC.js → notes-api-DLsnnZCS.js} +1 -1
  58. package/dist/gateway/static/root/assets/{notes-page-BKbOTE2n.js → notes-page-CkRJJKDm.js} +1 -1
  59. package/dist/gateway/static/root/assets/notes-workbench-B10T3hGX.js +4 -0
  60. package/dist/gateway/static/root/assets/{product-open-page-DqB9bsDB.js → product-open-page-HxArIvoN.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-DsqRlgsy.js +1 -0
  62. package/dist/gateway/static/root/assets/{projects-page-PeXUdGdO.js → projects-page-Bu2PN8OK.js} +1 -1
  63. package/dist/gateway/static/root/assets/{registry-api-B_5D8epF.js → registry-api-lEar5FOV.js} +1 -1
  64. package/dist/gateway/static/root/assets/remote-access-hub-CXACdJ2f.js +1 -0
  65. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DBTH_t0O.js → runtime-tools-settings-panel-Bf03UNGD.js} +2 -2
  66. package/dist/gateway/static/root/assets/{schema-form-CqMKAwV0.js → schema-form-CIXMBgx5.js} +1 -1
  67. package/dist/gateway/static/root/assets/sessions-page-CS2knWDT.js +1 -0
  68. package/dist/gateway/static/root/assets/settings-advanced-gate-ByFGk0q_.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-form-section-dPriuuYq.js → settings-form-section-DgdB26mE.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-loading-skeleton-B-Mbm8Va.js → settings-loading-skeleton-efk5W6lG.js} +1 -1
  71. package/dist/gateway/static/root/assets/{settings-page-Dyj3w-Ml.js → settings-page-BHVf4gEP.js} +1 -1
  72. package/dist/gateway/static/root/assets/{setup-status-panel-C4FxY5J3.js → setup-status-panel-WK0dGNMv.js} +1 -1
  73. package/dist/gateway/static/root/assets/{share-preview-page-emEdx7YL.js → share-preview-page-Cod-w2qm.js} +1 -1
  74. package/dist/gateway/static/root/assets/shares-settings-CUqQ31gt.js +1 -0
  75. package/dist/gateway/static/root/assets/skill-reload-api-DweAPjI8.js +1 -0
  76. package/dist/gateway/static/root/assets/{skills-page-BNtYnrRT.js → skills-page-DwCcipqK.js} +1 -1
  77. package/dist/gateway/static/root/assets/{skills-page.utils-DjnbNFs5.js → skills-page.utils-3WSbtl3S.js} +1 -1
  78. package/dist/gateway/static/root/assets/{system-settings-panel-DDStf-jZ.js → system-settings-panel-C5VxqC_s.js} +1 -1
  79. package/dist/gateway/static/root/assets/task-detail-page-DEj-BFMP.js +1 -0
  80. package/dist/gateway/static/root/assets/{theme-store-BN-32Fz5.js → theme-store-Dd89g_ki.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-autosave-C2mKZ-ua.js → use-autosave-CeV8VJh2.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-context-page-f7yh7aD5.js +1 -0
  83. package/dist/gateway/static/root/assets/{voice-api-key-field-D7OHeQby.js → voice-api-key-field-EmJ-8aZu.js} +1 -1
  84. package/dist/gateway/static/root/assets/{work-discovery-overlay-CIiXie7F.js → work-discovery-overlay-zsk6E3Mi.js} +1 -1
  85. package/dist/gateway/static/root/assets/workflow-run-setup-panel-CBAYvm3G.js +3 -0
  86. package/dist/gateway/static/root/assets/workflows-page-BN0JmHrG.js +5 -0
  87. package/dist/gateway/static/root/index.html +11 -11
  88. package/dist/package.js +1 -1
  89. package/dist/src/agent/agent-manager.d.ts +3 -1
  90. package/dist/src/agent/agent-manager.js +22 -5
  91. package/dist/src/agent/embedded/run-turn.js +2 -0
  92. package/dist/src/agent/mcp/bundle-mcp-config.d.ts +9 -1
  93. package/dist/src/agent/mcp/bundle-mcp-config.js +11 -15
  94. package/dist/src/agent/mcp/embedded-mcp.d.ts +1 -1
  95. package/dist/src/agent/mcp/index.d.ts +1 -0
  96. package/dist/src/agent/mcp/index.js +7 -1
  97. package/dist/src/agent/mcp/mcp-http.d.ts +4 -0
  98. package/dist/src/agent/mcp/mcp-http.js +25 -1
  99. package/dist/src/agent/mcp/mcp-transport-config.d.ts +4 -0
  100. package/dist/src/agent/mcp/mcp-transport-config.js +1 -0
  101. package/dist/src/agent/mcp/mcp-transport.d.ts +7 -1
  102. package/dist/src/agent/mcp/mcp-transport.js +38 -11
  103. package/dist/src/agent/mcp/oauth/index.d.ts +6 -0
  104. package/dist/src/agent/mcp/oauth/index.js +6 -0
  105. package/dist/src/agent/mcp/oauth/mcp-oauth-errors.d.ts +5 -0
  106. package/dist/src/agent/mcp/oauth/mcp-oauth-errors.js +14 -0
  107. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +25 -0
  108. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +219 -0
  109. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.d.ts +33 -0
  110. package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +103 -0
  111. package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +29 -0
  112. package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +169 -0
  113. package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +9 -0
  114. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +79 -0
  115. package/dist/src/agent/mcp/oauth/mcp-oauth-types.d.ts +22 -0
  116. package/dist/src/agent/mcp/oauth/mcp-oauth-types.js +1 -0
  117. package/dist/src/agent/memory/builtin-provider.js +23 -4
  118. package/dist/src/agent/memory/compaction-promotion.d.ts +18 -0
  119. package/dist/src/agent/memory/compaction-promotion.js +211 -0
  120. package/dist/src/agent/memory/context/types.d.ts +5 -0
  121. package/dist/src/agent/memory/manager.d.ts +3 -0
  122. package/dist/src/agent/memory/manager.js +12 -2
  123. package/dist/src/agent/memory/trusted-recall.d.ts +7 -0
  124. package/dist/src/agent/memory/trusted-recall.js +53 -0
  125. package/dist/src/agent/memory/turn-provenance.d.ts +14 -0
  126. package/dist/src/agent/memory/turn-provenance.js +60 -0
  127. package/dist/src/agent/memory/types.d.ts +18 -3
  128. package/dist/src/agent/memory/understanding/service.js +1 -0
  129. package/dist/src/agent/memory/understanding/types.d.ts +1 -0
  130. package/dist/src/agent/memory/user-context-coordinator.js +57 -6
  131. package/dist/src/agent/service.d.ts +2 -0
  132. package/dist/src/agent/service.js +6 -0
  133. package/dist/src/agent/skills/index.d.ts +22 -2
  134. package/dist/src/agent/skills/index.js +74 -32
  135. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +2 -0
  136. package/dist/src/agent/skills/skill-sources.d.ts +0 -1
  137. package/dist/src/agent/skills/skill-sources.js +1 -11
  138. package/dist/src/agent/tools/memory-tool.js +5 -1
  139. package/dist/src/capabilities/store-connector.js +99 -10
  140. package/dist/src/cli/commands/channels.js +1 -1
  141. package/dist/src/cli/commands/connectors.js +1 -1
  142. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  143. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  144. package/dist/src/cli/commands/models.js +1 -1
  145. package/dist/src/cli/commands/onboard.js +1 -1
  146. package/dist/src/config/config-mutation.d.ts +14 -0
  147. package/dist/src/config/config-mutation.js +33 -0
  148. package/dist/src/config/index.js +3 -3
  149. package/dist/src/config/paths.d.ts +2 -0
  150. package/dist/src/config/paths.js +5 -1
  151. package/dist/src/config/schema.d.ts +17 -0
  152. package/dist/src/config/schema.js +26 -2
  153. package/dist/src/connectors/auth-provider-registry.d.ts +1 -1
  154. package/dist/src/connectors/auth-provider-registry.js +23 -2
  155. package/dist/src/connectors/connected-source-understanding.js +1 -1
  156. package/dist/src/connectors/install.js +3 -3
  157. package/dist/src/connectors/instances.d.ts +2 -1
  158. package/dist/src/connectors/instances.js +15 -5
  159. package/dist/src/connectors/materialize.d.ts +1 -0
  160. package/dist/src/connectors/materialize.js +9 -1
  161. package/dist/src/connectors/runtime-adapter-registry.js +1 -0
  162. package/dist/src/connectors/types.d.ts +4 -1
  163. package/dist/src/extensions/connector-dependencies.d.ts +10 -0
  164. package/dist/src/extensions/connector-dependencies.js +65 -0
  165. package/dist/src/extensions/install.js +27 -0
  166. package/dist/src/extensions/normalize-manifest.js +1 -0
  167. package/dist/src/extensions/sdk/index.js +1 -1
  168. package/dist/src/extensions/types/manifest.d.ts +2 -0
  169. package/dist/src/gateway/hono/routes/capabilities.js +8 -8
  170. package/dist/src/gateway/hono/routes/connectors.js +104 -70
  171. package/dist/src/gateway/hono/routes/mcp.js +77 -5
  172. package/dist/src/gateway/hono/routes/project-skills.js +30 -2
  173. package/dist/src/gateway/hono/routes/you.js +52 -0
  174. package/dist/src/gateway/service.js +8 -8
  175. package/dist/src/knowledge/connected-knowledge-pipeline.js +26 -4
  176. package/dist/src/knowledge/connected-understanding-pipeline.js +12 -3
  177. package/dist/src/knowledge/index.d.ts +0 -1
  178. package/dist/src/knowledge/index.js +1 -2
  179. package/dist/src/projects/project-skill-service.d.ts +28 -6
  180. package/dist/src/projects/project-skill-service.js +76 -29
  181. package/dist/src/session/store.js +27 -0
  182. package/dist/src/storage/sqlite/index.d.ts +1 -0
  183. package/dist/src/storage/sqlite/index.js +2 -1
  184. package/dist/src/storage/sqlite/memory-records-repository.d.ts +9 -1
  185. package/dist/src/storage/sqlite/memory-records-repository.js +40 -6
  186. package/dist/src/storage/sqlite/migrations/134_memory_provenance.sql +18 -0
  187. package/dist/src/storage/sqlite/migrations/135_user_people.sql +59 -0
  188. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  189. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  190. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  191. package/dist/src/storage/sqlite/schema.js +1 -1
  192. package/dist/src/storage/sqlite/user-people-repository.d.ts +32 -0
  193. package/dist/src/storage/sqlite/user-people-repository.js +246 -0
  194. package/dist/src/tui/backends/embedded-backend.js +1 -1
  195. package/dist/src/user-context/planner.js +8 -3
  196. package/dist/src/user-context/relationships/indexer.d.ts +13 -0
  197. package/dist/src/user-context/relationships/indexer.js +185 -0
  198. package/dist/src/user-context/relationships/service.d.ts +22 -0
  199. package/dist/src/user-context/relationships/service.js +50 -0
  200. package/dist/src/user-context/relationships/types.d.ts +55 -0
  201. package/dist/src/user-context/relationships/types.js +10 -0
  202. package/dist/src/user-context/sources/repository.d.ts +1 -1
  203. package/dist/src/user-context/sources/repository.js +8 -2
  204. package/dist/src/work-discovery/service.js +1 -1
  205. package/package.json +2 -2
  206. package/dist/gateway/static/root/assets/agents-BsxTpXyq.js +0 -68
  207. package/dist/gateway/static/root/assets/apps-page-BXgpBA8w.js +0 -1
  208. package/dist/gateway/static/root/assets/automations-workspace-wrgf-z7D.js +0 -6
  209. package/dist/gateway/static/root/assets/browser-settings-page-zhzNkeVG.js +0 -8
  210. package/dist/gateway/static/root/assets/capabilities-settings-panel-DuCmg2Ej.js +0 -7
  211. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DjiP3mQQ.js +0 -3
  212. package/dist/gateway/static/root/assets/channels-status-swr-DMxB7slL.js +0 -1
  213. package/dist/gateway/static/root/assets/connectors-page-fmda2NEP.js +0 -2
  214. package/dist/gateway/static/root/assets/heartbeat-settings-MUJ3mEC9.js +0 -1
  215. package/dist/gateway/static/root/assets/index-B3zYJBhK.js +0 -74
  216. package/dist/gateway/static/root/assets/index-D3_xSYKd.css +0 -2
  217. package/dist/gateway/static/root/assets/messages-B82nsi9k.js +0 -3
  218. package/dist/gateway/static/root/assets/notes-workbench-BScELo01.js +0 -4
  219. package/dist/gateway/static/root/assets/project-detail-page-DUoyty8X.js +0 -1
  220. package/dist/gateway/static/root/assets/remote-access-hub-sHho-uXP.js +0 -1
  221. package/dist/gateway/static/root/assets/sessions-page-DyvNgaP9.js +0 -1
  222. package/dist/gateway/static/root/assets/settings-advanced-gate-CnYf1R7z.js +0 -1
  223. package/dist/gateway/static/root/assets/shares-settings-BQBVq-sN.js +0 -1
  224. package/dist/gateway/static/root/assets/skill-reload-api-BFoEpQ4I.js +0 -1
  225. package/dist/gateway/static/root/assets/task-detail-page-ZVwr8KbS.js +0 -1
  226. package/dist/gateway/static/root/assets/user-context-page-CHjIinCW.js +0 -1
  227. package/dist/gateway/static/root/assets/workflow-run-setup-panel-9_dAGW3_.js +0 -3
  228. package/dist/gateway/static/root/assets/workflows-page-DXpYJxao.js +0 -5
  229. package/dist/src/extensions/bundle-mcp.d.ts +0 -18
  230. package/dist/src/extensions/bundle-mcp.js +0 -69
  231. package/dist/src/knowledge/people-graph.d.ts +0 -25
  232. package/dist/src/knowledge/people-graph.js +0 -92
@@ -2,21 +2,31 @@ import { canonicalizeConfiguredMcpServer, normalizeConfiguredMcpServers } from "
2
2
  import { loadMergedBundleMcpConfig } from "../../../agent/mcp/bundle-mcp-config.js";
3
3
  import { isManagedConnectorServer } from "../../../connectors/materialize.js";
4
4
  import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
5
+ import { getMcpOAuthManager } from "../../../agent/mcp/oauth/mcp-oauth-manager.js";
5
6
  import { listBundleMcpServerCapabilitiesForGateway, listBundleMcpServerToolsForGateway } from "../../../agent/mcp/bundle-mcp-gateway.js";
6
7
  //#region src/gateway/hono/routes/mcp.ts
7
8
  function registerMcpRoutes(authenticated, deps) {
8
- authenticated.get("/api/mcp/servers", (c) => {
9
+ const resolveServer = (id) => {
10
+ const cfg = deps.service.currentConfig;
11
+ return loadMergedBundleMcpConfig({
12
+ workspaceDir: getWorkspacePath(cfg) || "./workspace",
13
+ cfg
14
+ }).config.mcpServers[id];
15
+ };
16
+ authenticated.get("/api/mcp/servers", async (c) => {
9
17
  const cfg = deps.service.currentConfig;
10
18
  const merged = loadMergedBundleMcpConfig({
11
19
  workspaceDir: getWorkspacePath(cfg) || "./workspace",
12
20
  cfg
13
21
  });
14
22
  const configured = normalizeConfiguredMcpServers(cfg.mcp?.servers);
15
- const servers = Object.entries(configured).map(([id, server]) => ({
23
+ const oauthManager = getMcpOAuthManager();
24
+ const servers = await Promise.all(Object.entries(configured).map(async ([id, server]) => ({
16
25
  id,
17
26
  managed: isManagedConnectorServer(server),
18
- connectorId: isManagedConnectorServer(server) ? server.xopcConnector.connectorId : void 0
19
- }));
27
+ connectorId: isManagedConnectorServer(server) ? server.xopcConnector.connectorId : void 0,
28
+ oauth: await oauthManager.status(id, server)
29
+ })));
20
30
  return c.json({
21
31
  ok: true,
22
32
  payload: {
@@ -26,6 +36,62 @@ function registerMcpRoutes(authenticated, deps) {
26
36
  }
27
37
  });
28
38
  });
39
+ authenticated.get("/api/mcp/servers/:id/oauth", async (c) => {
40
+ const id = c.req.param("id");
41
+ const server = resolveServer(id);
42
+ if (!server) return c.json({
43
+ ok: false,
44
+ error: `Unknown MCP server: ${id}`
45
+ }, 404);
46
+ return c.json({
47
+ ok: true,
48
+ payload: await getMcpOAuthManager().status(id, server)
49
+ });
50
+ });
51
+ authenticated.post("/api/mcp/servers/:id/oauth/start", deps.strictRateLimitMiddleware, async (c) => {
52
+ const id = c.req.param("id");
53
+ const server = resolveServer(id);
54
+ if (!server) return c.json({
55
+ ok: false,
56
+ error: `Unknown MCP server: ${id}`
57
+ }, 404);
58
+ try {
59
+ const payload = await getMcpOAuthManager().start({
60
+ serverId: id,
61
+ rawServer: server,
62
+ cfg: deps.service.currentConfig
63
+ });
64
+ return c.json({
65
+ ok: true,
66
+ payload
67
+ });
68
+ } catch (err) {
69
+ return c.json({
70
+ ok: false,
71
+ error: err instanceof Error ? err.message : String(err)
72
+ }, 400);
73
+ }
74
+ });
75
+ authenticated.delete("/api/mcp/servers/:id/oauth", deps.strictRateLimitMiddleware, async (c) => {
76
+ const id = c.req.param("id");
77
+ const server = resolveServer(id);
78
+ if (!server) return c.json({
79
+ ok: false,
80
+ error: `Unknown MCP server: ${id}`
81
+ }, 404);
82
+ try {
83
+ const payload = await getMcpOAuthManager().disconnect(id, server);
84
+ return c.json({
85
+ ok: true,
86
+ payload
87
+ });
88
+ } catch (err) {
89
+ return c.json({
90
+ ok: false,
91
+ error: err instanceof Error ? err.message : String(err)
92
+ }, 400);
93
+ }
94
+ });
29
95
  authenticated.get("/api/mcp/servers/:id/tools", async (c) => {
30
96
  const id = c.req.param("id");
31
97
  const cfg = deps.service.currentConfig;
@@ -79,11 +145,17 @@ function registerMcpRoutes(authenticated, deps) {
79
145
  workspaceDir,
80
146
  cfg
81
147
  }).config.mcpServers;
82
- if (!(inlineServer ?? servers[id] ?? mergedServers[id])) return c.json({
148
+ const knownServer = inlineServer ?? servers[id] ?? mergedServers[id];
149
+ if (!knownServer) return c.json({
83
150
  ok: false,
84
151
  error: `Unknown MCP server: ${id}`
85
152
  }, 404);
86
153
  try {
154
+ const oauth = await getMcpOAuthManager().status(id, knownServer);
155
+ if (oauth.configured && oauth.status !== "connected") return c.json({
156
+ ok: false,
157
+ error: oauth.session?.error ?? "MCP server authorization is required"
158
+ }, 409);
87
159
  const capabilities = await listBundleMcpServerCapabilitiesForGateway({
88
160
  workspaceDir,
89
161
  cfg: inlineServer ? {
@@ -5,6 +5,8 @@ function projectSkills(deps) {
5
5
  return new ProjectSkillService({
6
6
  projects: deps.service.projects,
7
7
  getConfig: () => deps.service.currentConfig,
8
+ getWorkspaceTrust: (workspaceRoot) => deps.service.agentService.getWorkspaceTrust(workspaceRoot),
9
+ setWorkspaceTrust: (workspaceRoot, trusted) => deps.service.agentService.setWorkspaceTrust(workspaceRoot, trusted),
8
10
  refreshSkills: () => deps.service.agentService.refreshSkillsAfterDiskChange()
9
11
  });
10
12
  }
@@ -31,11 +33,37 @@ function registerProjectSkillRoutes(authenticated, deps) {
31
33
  return errorResponse(c, error);
32
34
  }
33
35
  });
34
- authenticated.get("/api/projects/:projectId/skills/:skillId", (c) => {
36
+ authenticated.get("/api/projects/:projectId/workspace-trust", (c) => {
35
37
  try {
36
38
  return c.json({
37
39
  ok: true,
38
- skill: projectSkills(deps).getContent(c.req.param("projectId"), c.req.param("skillId"))
40
+ trust: projectSkills(deps).getWorkspaceTrust(c.req.param("projectId"))
41
+ });
42
+ } catch (error) {
43
+ return errorResponse(c, error);
44
+ }
45
+ });
46
+ authenticated.patch("/api/projects/:projectId/workspace-trust", async (c) => {
47
+ try {
48
+ const body = await c.req.json();
49
+ if (typeof body.trusted !== "boolean") return c.json({
50
+ ok: false,
51
+ error: "Expected { trusted: boolean }"
52
+ }, 400);
53
+ const trust = projectSkills(deps).setWorkspaceTrust(c.req.param("projectId"), body.trusted);
54
+ return c.json({
55
+ ok: true,
56
+ trust
57
+ });
58
+ } catch (error) {
59
+ return errorResponse(c, error);
60
+ }
61
+ });
62
+ authenticated.get("/api/projects/:projectId/skills/:skillKey", (c) => {
63
+ try {
64
+ return c.json({
65
+ ok: true,
66
+ skill: projectSkills(deps).getContent(c.req.param("projectId"), c.req.param("skillKey"))
39
67
  });
40
68
  } catch (error) {
41
69
  return errorResponse(c, error);
@@ -7,6 +7,8 @@ import { listUserFocuses, updateUserFocus } from "../../../user-context/sources/
7
7
  import { canonicalUnderstandingKey, findDuplicateUnderstanding } from "../../../user-context/understanding.js";
8
8
  import { listContextObjects } from "../../../user-context/context-objects.js";
9
9
  import { repairExtractedContext } from "../../../user-context/extraction/repair.js";
10
+ import { getUserRelationship, listUserRelationships, mergeUserRelationships, patchUserRelationship } from "../../../user-context/relationships/service.js";
11
+ import { USER_PERSON_KINDS } from "../../../user-context/relationships/types.js";
10
12
  import { userInfo } from "node:os";
11
13
  //#region src/gateway/hono/routes/you.ts
12
14
  const UNDERSTANDING_KIND_SET = new Set(UNDERSTANDING_KINDS);
@@ -42,6 +44,7 @@ const CONTEXT_OBJECT_VIEWS = new Set([
42
44
  "review",
43
45
  "history"
44
46
  ]);
47
+ const USER_PERSON_KIND_SET = new Set(USER_PERSON_KINDS);
45
48
  function asRecord(value) {
46
49
  return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
47
50
  }
@@ -99,6 +102,55 @@ function registerYouRoutes(authenticated, deps) {
99
102
  rules: listCollaborationRules(),
100
103
  consolidation: { lastRun: listContextConsolidationRuns(1)[0] ?? null }
101
104
  }));
105
+ authenticated.get("/api/you/relationships", (c) => {
106
+ const kind = c.req.query("kind");
107
+ if (kind && !USER_PERSON_KIND_SET.has(kind)) return c.json({ error: "Invalid relationship kind" }, 400);
108
+ const requestedLimit = Number(c.req.query("limit") ?? "30");
109
+ if (!Number.isInteger(requestedLimit) || requestedLimit < 1 || requestedLimit > 100) return c.json({ error: "limit must be an integer from 1 to 100" }, 400);
110
+ const cursor = c.req.query("cursor");
111
+ if (cursor && !/^\d+$/.test(cursor)) return c.json({ error: "Invalid cursor" }, 400);
112
+ return c.json(listUserRelationships({
113
+ query: c.req.query("q") ?? "",
114
+ ...kind ? { kind } : {},
115
+ ...c.req.query("source") ? { sourceInstanceId: c.req.query("source") } : {},
116
+ includeHidden: c.req.query("includeHidden") === "true",
117
+ hiddenOnly: c.req.query("hidden") === "true",
118
+ ...cursor ? { cursor } : {},
119
+ limit: requestedLimit
120
+ }));
121
+ });
122
+ authenticated.get("/api/you/relationships/:id", (c) => {
123
+ const person = getUserRelationship(c.req.param("id"));
124
+ return person ? c.json({ person }) : c.json({ error: "Relationship not found" }, 404);
125
+ });
126
+ authenticated.patch("/api/you/relationships/:id", write, async (c) => {
127
+ const body = await readBody(c);
128
+ if (!body) return c.json({ error: "Invalid JSON" }, 400);
129
+ const patch = {};
130
+ if (body.displayName !== void 0) {
131
+ if (body.displayName !== null && (typeof body.displayName !== "string" || body.displayName.trim().length > 160)) return c.json({ error: "displayName must be null or a string of at most 160 characters" }, 400);
132
+ patch.displayName = typeof body.displayName === "string" && body.displayName.trim() ? body.displayName.trim() : null;
133
+ }
134
+ if (body.kind !== void 0) {
135
+ if (body.kind !== null && !USER_PERSON_KIND_SET.has(body.kind)) return c.json({ error: "Invalid relationship kind" }, 400);
136
+ patch.kind = body.kind;
137
+ }
138
+ if (body.hidden !== void 0) {
139
+ if (typeof body.hidden !== "boolean") return c.json({ error: "hidden must be a boolean" }, 400);
140
+ patch.hidden = body.hidden;
141
+ }
142
+ if (!Object.keys(patch).length) return c.json({ error: "No relationship fields provided" }, 400);
143
+ const person = patchUserRelationship(c.req.param("id"), patch);
144
+ return person ? c.json({ person }) : c.json({ error: "Relationship not found" }, 404);
145
+ });
146
+ authenticated.post("/api/you/relationships/merge", write, async (c) => {
147
+ const body = await readBody(c);
148
+ const sourcePersonId = nonEmptyString(body?.sourcePersonId, 200);
149
+ const targetPersonId = nonEmptyString(body?.targetPersonId, 200);
150
+ if (!sourcePersonId || !targetPersonId || sourcePersonId === targetPersonId) return c.json({ error: "Distinct sourcePersonId and targetPersonId are required" }, 400);
151
+ const person = mergeUserRelationships(sourcePersonId, targetPersonId);
152
+ return person ? c.json({ person }) : c.json({ error: "Relationship not found" }, 404);
153
+ });
102
154
  authenticated.get("/api/you/context-objects", (c) => {
103
155
  const view = c.req.query("view") ?? "current";
104
156
  if (!CONTEXT_OBJECT_VIEWS.has(view)) return c.json({ error: "Invalid context object view" }, 400);
@@ -45,11 +45,17 @@ import { MessageBus, MessageBusShutdownError } from "../infra/bus/queue.js";
45
45
  import "../infra/bus/index.js";
46
46
  import { AgentService } from "../agent/service.js";
47
47
  import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
48
- import { getWorkspacePath } from "../config/workspace-path-helpers.js";
49
- import "../config/index.js";
50
48
  import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
51
49
  import { registerClarifyBridge } from "./clarify-runtime.js";
52
50
  import { ChannelManager } from "../channels/manager.js";
51
+ import { getWorkspacePath } from "../config/workspace-path-helpers.js";
52
+ import "../config/index.js";
53
+ import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
54
+ import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
55
+ import "../knowledge/index.js";
56
+ import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
57
+ import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
58
+ import { startConnectorSupervisor } from "../connectors/supervisor.js";
53
59
  import { DiscussionService } from "../discussions/service.js";
54
60
  import { DiscussionOrganizer } from "../discussions/organizer.js";
55
61
  import { DiscussionLiveWorker } from "../discussions/live-worker.js";
@@ -58,12 +64,6 @@ import { DiscussionSealer } from "../discussions/sealer.js";
58
64
  import "../discussions/index.js";
59
65
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
60
66
  import "../endpoint-tools/index.js";
61
- import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
62
- import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
63
- import "../knowledge/index.js";
64
- import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
65
- import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
66
- import { startConnectorSupervisor } from "../connectors/supervisor.js";
67
67
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
68
68
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
69
69
  import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
@@ -87,7 +87,14 @@ var ConnectedKnowledgePipeline = class {
87
87
  expiresAt: existing.expiresAt,
88
88
  canonicalKey: existing.canonicalKey,
89
89
  supersedesRecordId: existing.supersedesRecordId,
90
- conflictGroupId: existing.conflictGroupId
90
+ conflictGroupId: existing.conflictGroupId,
91
+ originClass: existing.provenance.originClass,
92
+ sessionKind: existing.provenance.sessionKind,
93
+ observedAt: existing.provenance.observedAt,
94
+ sourceSessionId: existing.provenance.sourceSessionId,
95
+ sourceTurnId: existing.provenance.sourceTurnId,
96
+ supersedesKey: existing.provenance.supersedesKey,
97
+ derivedFromRecalledContext: existing.provenance.derivedFromRecalledContext
91
98
  });
92
99
  completeKnowledgeSourceItemSynthesis({
93
100
  itemId: item.id,
@@ -141,7 +148,11 @@ var ConnectedKnowledgePipeline = class {
141
148
  confidence: .78,
142
149
  observedAt: item.occurredAt ?? item.sourceUpdatedAt
143
150
  }],
144
- validFrom: item.occurredAt ?? item.sourceUpdatedAt
151
+ validFrom: item.occurredAt ?? item.sourceUpdatedAt,
152
+ originClass: "untrusted",
153
+ sessionKind: "background",
154
+ observedAt: item.occurredAt ?? item.sourceUpdatedAt ?? item.updatedAt,
155
+ derivedFromRecalledContext: false
145
156
  });
146
157
  attachMemoryEvidence({
147
158
  recordId: record.id,
@@ -238,7 +249,14 @@ var ConnectedKnowledgePipeline = class {
238
249
  validTo: (/* @__PURE__ */ new Date()).toISOString(),
239
250
  reviewAfter: existing.reviewAfter,
240
251
  expiresAt: existing.expiresAt,
241
- canonicalKey: existing.canonicalKey
252
+ canonicalKey: existing.canonicalKey,
253
+ originClass: existing.provenance.originClass,
254
+ sessionKind: existing.provenance.sessionKind,
255
+ observedAt: existing.provenance.observedAt,
256
+ sourceSessionId: existing.provenance.sourceSessionId,
257
+ sourceTurnId: existing.provenance.sourceTurnId,
258
+ supersedesKey: existing.provenance.supersedesKey,
259
+ derivedFromRecalledContext: existing.provenance.derivedFromRecalledContext
242
260
  });
243
261
  return false;
244
262
  }
@@ -282,7 +300,11 @@ var ConnectedKnowledgePipeline = class {
282
300
  confidence: .72,
283
301
  observedAt: item.occurredAt ?? item.sourceUpdatedAt
284
302
  })),
285
- validFrom: `${day}T00:00:00.000Z`
303
+ validFrom: `${day}T00:00:00.000Z`,
304
+ originClass: "untrusted",
305
+ sessionKind: "background",
306
+ observedAt: items.map((item) => item.occurredAt ?? item.sourceUpdatedAt ?? item.updatedAt).sort().at(-1),
307
+ derivedFromRecalledContext: false
286
308
  });
287
309
  deleteMemoryEvidenceForRecord(summary.id, "derived_from");
288
310
  for (const item of items) attachMemoryEvidence({
@@ -1,6 +1,7 @@
1
1
  import { listKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
2
2
  import "../storage/sqlite/index.js";
3
3
  import { clusterUnderstandingSignals } from "../user-context/sources/signal-clustering.js";
4
+ import { personIdForIdentity, personIdentityKey, rebuildUserPeopleIndex } from "../user-context/relationships/indexer.js";
4
5
  //#region src/knowledge/connected-understanding-pipeline.ts
5
6
  function logicalEventKey(item) {
6
7
  const value = item.metadata.logicalEventKey;
@@ -96,9 +97,12 @@ function relationshipObservations(items) {
96
97
  const strongIdentity = (signal.email ?? signal.username)?.toLowerCase();
97
98
  if (strongIdentity && owners.has(strongIdentity)) continue;
98
99
  const label = signal.name ?? signal.email ?? signal.username;
99
- const identityKey = signal.email?.toLowerCase() ?? `${String(item.metadata.toolkit ?? item.sourceInstanceId)}:${signal.username?.toLowerCase() ?? signal.name?.toLowerCase()}`;
100
+ const identityKey = personIdentityKey(signal, item.sourceInstanceId);
101
+ const personId = personIdForIdentity(signal, item.sourceInstanceId);
102
+ if (!identityKey || !personId) continue;
100
103
  const entry = grouped.get(identityKey) ?? {
101
104
  label,
105
+ personId,
102
106
  events: /* @__PURE__ */ new Map()
103
107
  };
104
108
  const eventKey = logicalEventKey(item);
@@ -108,8 +112,11 @@ function relationshipObservations(items) {
108
112
  }
109
113
  return [...grouped.values()].sort((left, right) => right.events.size - left.events.size).slice(0, 8).map((entry) => ({
110
114
  class: "relationship",
111
- key: `person:${entry.label.toLocaleLowerCase()}`,
112
- value: { label: entry.label },
115
+ key: `person:${entry.personId}`,
116
+ value: {
117
+ label: entry.label,
118
+ personId: entry.personId
119
+ },
113
120
  items: [...entry.events.values()],
114
121
  windowDays: 90
115
122
  }));
@@ -182,6 +189,7 @@ function renderConnectedObservation(observation) {
182
189
  kind: "relationship",
183
190
  content: `Frequently collaborates with ${label}.`,
184
191
  canonicalKey: `connected:${observation.key}`,
192
+ payload: typeof observation.value.personId === "string" ? { personId: observation.value.personId } : void 0,
185
193
  confidence,
186
194
  importance: .65,
187
195
  explicitness: "inferred",
@@ -227,6 +235,7 @@ var ConnectedUnderstandingPipeline = class {
227
235
  this.memoryManager = memoryManager;
228
236
  }
229
237
  async process(agentId, extractionRunId) {
238
+ rebuildUserPeopleIndex();
230
239
  const observations = deriveConnectedClaimObservations(listKnowledgeSourceItems({
231
240
  agentId,
232
241
  includeDeleted: false,
@@ -4,4 +4,3 @@ export * from './connected-knowledge-pipeline.js';
4
4
  export * from './connected-understanding-pipeline.js';
5
5
  export * from './coordinator.js';
6
6
  export * from './local-folder-adapter.js';
7
- export * from './people-graph.js';
@@ -3,5 +3,4 @@ import { ConnectedKnowledgePipeline } from "./connected-knowledge-pipeline.js";
3
3
  import { ConnectedUnderstandingPipeline, deriveConnectedClaimObservations, renderConnectedObservation } from "./connected-understanding-pipeline.js";
4
4
  import { startConnectedKnowledgeCoordinator } from "./coordinator.js";
5
5
  import { LocalFolderKnowledgeSourceAdapter } from "./local-folder-adapter.js";
6
- import { buildConnectedPeopleGraph } from "./people-graph.js";
7
- export { ConnectedKnowledgePipeline, ConnectedUnderstandingPipeline, KnowledgeIngestionService, LocalFolderKnowledgeSourceAdapter, SqliteKnowledgeSourceStateStore, buildConnectedPeopleGraph, deriveConnectedClaimObservations, renderConnectedObservation, startConnectedKnowledgeCoordinator };
6
+ export { ConnectedKnowledgePipeline, ConnectedUnderstandingPipeline, KnowledgeIngestionService, LocalFolderKnowledgeSourceAdapter, SqliteKnowledgeSourceStateStore, deriveConnectedClaimObservations, renderConnectedObservation, startConnectedKnowledgeCoordinator };
@@ -1,5 +1,6 @@
1
1
  import type { Config } from '../config/schema.js';
2
- import type { SkillDiagnostic, SkillMetadata, SkillToolConditions } from '../agent/skills/types.js';
2
+ import { type WorkspaceSkillSourceStatus } from '../agent/skills/index.js';
3
+ import type { Skill, SkillDiagnostic, SkillMetadata, SkillToolConditions } from '../agent/skills/types.js';
3
4
  import type { ProjectService } from './project-service.js';
4
5
  export type ProjectSkillErrorCode = 'project_not_found' | 'project_workspace_required' | 'project_workspace_missing' | 'project_workspace_not_writable' | 'skill_not_found' | 'invalid_skill_id';
5
6
  export declare class ProjectSkillError extends Error {
@@ -8,33 +9,53 @@ export declare class ProjectSkillError extends Error {
8
9
  constructor(code: ProjectSkillErrorCode, status: 400 | 403 | 404 | 409, message: string);
9
10
  }
10
11
  export interface ProjectSkillSummary {
11
- id: string;
12
+ key: string;
13
+ directoryId: string;
12
14
  name: string;
13
15
  description: string;
14
16
  category?: string;
17
+ origin: Skill['origin']['id'];
18
+ path: string;
19
+ managed: boolean;
20
+ writable: boolean;
21
+ removable: boolean;
22
+ effective: boolean;
23
+ shadowedBy?: Skill['origin']['id'];
15
24
  disableModelInvocation: boolean;
16
25
  metadata: SkillMetadata;
17
26
  toolConditions?: SkillToolConditions;
18
27
  requiredEnvVarNames?: string[];
19
28
  }
29
+ export interface ProjectWorkspaceTrustState {
30
+ workspacePath: string;
31
+ required: boolean;
32
+ decision: boolean | null;
33
+ trusted: boolean;
34
+ }
20
35
  export interface ProjectSkillListResult {
21
36
  workspaceRoot: string;
22
- skillsRoot: string;
37
+ sources: WorkspaceSkillSourceStatus[];
38
+ trust: ProjectWorkspaceTrustState;
23
39
  items: ProjectSkillSummary[];
40
+ inheritedItems: ProjectSkillSummary[];
24
41
  diagnostics: SkillDiagnostic[];
25
42
  }
26
43
  interface ProjectSkillServiceOptions {
27
44
  projects: ProjectService;
28
45
  getConfig: () => Config;
46
+ getWorkspaceTrust: (workspaceRoot: string) => ProjectWorkspaceTrustState;
47
+ setWorkspaceTrust: (workspaceRoot: string, trusted: boolean) => ProjectWorkspaceTrustState;
29
48
  refreshSkills: () => void | Promise<void>;
30
49
  }
31
50
  export declare class ProjectSkillService {
32
51
  private readonly options;
33
52
  constructor(options: ProjectSkillServiceOptions);
34
53
  list(projectId: string): ProjectSkillListResult;
35
- getContent(projectId: string, skillId: string): ProjectSkillSummary & {
54
+ getContent(projectId: string, skillKey: string): ProjectSkillSummary & {
36
55
  bodyMarkdown: string;
37
56
  };
57
+ getWorkspaceTrust(projectId: string): ProjectWorkspaceTrustState;
58
+ setWorkspaceTrust(projectId: string, trusted: boolean): ProjectWorkspaceTrustState;
38
59
  installZip(projectId: string, buffer: Buffer, input?: {
39
60
  skillId?: string;
40
61
  overwrite?: boolean;
@@ -59,9 +80,10 @@ export declare class ProjectSkillService {
59
80
  bodyMarkdown: string;
60
81
  }>;
61
82
  remove(projectId: string, skillId: string): Promise<void>;
62
- private findSkill;
63
83
  private resolveLocation;
64
- private isDirectSkill;
84
+ private loadCatalog;
85
+ private skillKey;
86
+ private encodeSkillKey;
65
87
  private toSummary;
66
88
  }
67
89
  export {};
@@ -1,5 +1,6 @@
1
+ import { init_paths, resolveBundledSkillsDir } from "../config/paths.js";
1
2
  import { resolveWorkspaceSkillsDir, resolveWorkspaceSkillsLockPath } from "../agent/skills/workspace-skills-dir.js";
2
- import { loadWorkspaceSkills } from "../agent/skills/index.js";
3
+ import { loadSkills, loadWorkspaceSkillInventory } from "../agent/skills/index.js";
3
4
  import { removeSkillsLockEntry } from "../agent/skills/hub-lock.js";
4
5
  import { deleteManagedSkill, installSkillFromZip, isValidSkillId } from "../agent/skills/managed-store.js";
5
6
  import { pullSkillFromSource } from "../agent/skills/hub-pull.js";
@@ -7,6 +8,7 @@ import { downloadFromMarketplace } from "../agent/skills/skills-marketplace.js";
7
8
  import { basename, dirname, join, relative, resolve, sep } from "node:path";
8
9
  import { accessSync, constants, existsSync, statSync } from "node:fs";
9
10
  //#region src/projects/project-skill-service.ts
11
+ init_paths();
10
12
  var ProjectSkillError = class extends Error {
11
13
  constructor(code, status, message) {
12
14
  super(message);
@@ -20,21 +22,44 @@ var ProjectSkillService = class {
20
22
  this.options = options;
21
23
  }
22
24
  list(projectId) {
23
- const location = this.resolveLocation(projectId, false);
24
- const loaded = loadWorkspaceSkills(location.workspaceRoot);
25
+ const { location, loaded, inherited, trust } = this.loadCatalog(projectId);
25
26
  return {
26
- ...location,
27
- items: loaded.skills.filter((skill) => this.isDirectSkill(skill, location.skillsRoot)).map((skill) => this.toSummary(skill)),
28
- diagnostics: loaded.diagnostics
27
+ workspaceRoot: location.workspaceRoot,
28
+ sources: loaded.sources,
29
+ trust,
30
+ items: loaded.entries.map((entry) => this.toSummary(entry)),
31
+ inheritedItems: inherited.skills.map((skill) => this.toSummary({
32
+ skill,
33
+ effective: true
34
+ })),
35
+ diagnostics: inherited.diagnostics
29
36
  };
30
37
  }
31
- getContent(projectId, skillId) {
32
- const { skill } = this.findSkill(projectId, skillId);
38
+ getContent(projectId, skillKey) {
39
+ const { loaded, inherited } = this.loadCatalog(projectId);
40
+ const entry = loaded.entries.find((candidate) => this.skillKey(candidate.skill) === skillKey);
41
+ if (entry) return {
42
+ ...this.toSummary(entry),
43
+ bodyMarkdown: entry.skill.content
44
+ };
45
+ const inheritedSkill = inherited.skills.find((candidate) => this.skillKey(candidate) === skillKey);
46
+ if (!inheritedSkill) throw new ProjectSkillError("skill_not_found", 404, "Project skill not found");
33
47
  return {
34
- ...this.toSummary(skill),
35
- bodyMarkdown: skill.content
48
+ ...this.toSummary({
49
+ skill: inheritedSkill,
50
+ effective: true
51
+ }),
52
+ bodyMarkdown: inheritedSkill.content
36
53
  };
37
54
  }
55
+ getWorkspaceTrust(projectId) {
56
+ const location = this.resolveLocation(projectId, false);
57
+ return this.options.getWorkspaceTrust(location.workspaceRoot);
58
+ }
59
+ setWorkspaceTrust(projectId, trusted) {
60
+ const location = this.resolveLocation(projectId, false);
61
+ return this.options.setWorkspaceTrust(location.workspaceRoot, trusted);
62
+ }
38
63
  async installZip(projectId, buffer, input = {}) {
39
64
  const location = this.resolveLocation(projectId, true);
40
65
  const installed = installSkillFromZip(buffer, {
@@ -44,7 +69,7 @@ var ProjectSkillService = class {
44
69
  });
45
70
  removeSkillsLockEntry(installed.skillId, resolveWorkspaceSkillsLockPath(location.workspaceRoot));
46
71
  await this.options.refreshSkills();
47
- return this.getContent(projectId, installed.skillId);
72
+ return this.getContent(projectId, this.encodeSkillKey("xopc-workspace", installed.skillId));
48
73
  }
49
74
  async installMarketplace(projectId, input) {
50
75
  const downloaded = await downloadFromMarketplace(this.options.getConfig(), input.name, input.version, input.provider);
@@ -64,7 +89,7 @@ var ProjectSkillService = class {
64
89
  lockPath: resolveWorkspaceSkillsLockPath(location.workspaceRoot)
65
90
  });
66
91
  await this.options.refreshSkills();
67
- return this.getContent(projectId, installed.skillId);
92
+ return this.getContent(projectId, this.encodeSkillKey("xopc-workspace", installed.skillId));
68
93
  }
69
94
  async remove(projectId, skillId) {
70
95
  const location = this.resolveLocation(projectId, true);
@@ -74,18 +99,6 @@ var ProjectSkillService = class {
74
99
  removeSkillsLockEntry(skillId, resolveWorkspaceSkillsLockPath(location.workspaceRoot));
75
100
  await this.options.refreshSkills();
76
101
  }
77
- findSkill(projectId, skillId) {
78
- if (!isValidSkillId(skillId)) throw new ProjectSkillError("invalid_skill_id", 400, "Invalid skill id");
79
- const location = this.resolveLocation(projectId, false);
80
- const skill = loadWorkspaceSkills(location.workspaceRoot).skills.find((item) => {
81
- return !relative(location.skillsRoot, item.baseDir).includes(sep) && basename(item.baseDir) === skillId;
82
- });
83
- if (!skill) throw new ProjectSkillError("skill_not_found", 404, "Project skill not found");
84
- return {
85
- skill,
86
- skillsRoot: location.skillsRoot
87
- };
88
- }
89
102
  resolveLocation(projectId, requireWritable) {
90
103
  const project = this.options.projects.get(projectId);
91
104
  if (!project) throw new ProjectSkillError("project_not_found", 404, "Project not found");
@@ -110,16 +123,50 @@ var ProjectSkillService = class {
110
123
  skillsRoot
111
124
  };
112
125
  }
113
- isDirectSkill(skill, skillsRoot) {
114
- const rel = relative(skillsRoot, skill.baseDir);
115
- return Boolean(rel) && !rel.includes(sep) && isValidSkillId(basename(skill.baseDir));
126
+ loadCatalog(projectId) {
127
+ const location = this.resolveLocation(projectId, false);
128
+ const trust = this.options.getWorkspaceTrust(location.workspaceRoot);
129
+ const loaded = loadWorkspaceSkillInventory(location.workspaceRoot, { workspaceTrust: trust.trusted ? "trusted" : "untrusted" });
130
+ const all = loadSkills({
131
+ workspaceDir: location.workspaceRoot,
132
+ builtinDir: resolveBundledSkillsDir(),
133
+ workspaceTrust: trust.trusted ? "trusted" : "untrusted"
134
+ });
135
+ return {
136
+ location,
137
+ loaded,
138
+ inherited: {
139
+ skills: all.skills.filter((skill) => skill.origin.scope !== "workspace"),
140
+ diagnostics: all.diagnostics
141
+ },
142
+ trust
143
+ };
144
+ }
145
+ skillKey(skill) {
146
+ const rel = relative(skill.origin.rootDir, skill.baseDir).split(sep).join("/");
147
+ return this.encodeSkillKey(skill.origin.id, rel);
148
+ }
149
+ encodeSkillKey(origin, relativeDir) {
150
+ return Buffer.from(`${origin}\0${relativeDir}`, "utf8").toString("base64url");
116
151
  }
117
- toSummary(skill) {
152
+ toSummary(entry) {
153
+ const { skill } = entry;
154
+ const id = basename(skill.baseDir);
155
+ const relativeDir = relative(skill.origin.rootDir, skill.baseDir);
156
+ const removable = skill.origin.id === "xopc-workspace" && !relativeDir.includes(sep) && isValidSkillId(id);
118
157
  return {
119
- id: basename(skill.baseDir),
158
+ key: this.skillKey(skill),
159
+ directoryId: id,
120
160
  name: skill.name,
121
161
  description: skill.description,
122
162
  category: skill.category,
163
+ origin: skill.origin.id,
164
+ path: skill.baseDir,
165
+ managed: skill.origin.managed,
166
+ writable: skill.origin.writable,
167
+ removable,
168
+ effective: entry.effective,
169
+ shadowedBy: entry.shadowedBy,
123
170
  disableModelInvocation: skill.disableModelInvocation,
124
171
  metadata: skill.metadata,
125
172
  toolConditions: skill.toolConditions,