@xopcai/xopc 0.0.283 → 0.0.285

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 (234) 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-iPtG94qr.js → activity-store-B0BTIk9j.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DQ74xqLi.js → agent-avatar-dicebear-Dc-0QZTQ.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CcmqK1Sc.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-B_7PVt7S.js +1 -0
  7. package/dist/gateway/static/root/assets/api-COG_Tzpv.js +1 -0
  8. package/dist/gateway/static/root/assets/{api-KMJzMqvZ.js → api-Coly9ab6.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-B42TpqIb.js → app-management-settings-panel-TWBO-msg.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-D9Lfe7Sk.js → appearance-settings-CpTZ2KuT.js} +1 -1
  11. package/dist/gateway/static/root/assets/apps-page-6qxxKFsK.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-BdmQwj4x.js → archive-plugin-z_u6alob.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-B4S0_nji.js → attachment-load-C2nS04TC.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-page-B3TmHNjQ.js → automations-page-aIBsw9zR.js} +1 -1
  15. package/dist/gateway/static/root/assets/automations-workspace-BRQlU4qk.js +6 -0
  16. package/dist/gateway/static/root/assets/{binary-plugins-B3cXF_DP.js → binary-plugins-CGmXoZnl.js} +1 -1
  17. package/dist/gateway/static/root/assets/{block-editor-05zyBXBe.js → block-editor-CtvzCZhC.js} +3 -3
  18. package/dist/gateway/static/root/assets/{browser-automation-inputs-BTIufVbM.js → browser-automation-inputs-BOTU1isH.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-automations-page-DRBA9nwe.js → browser-automations-page-BwU5V8J0.js} +2 -2
  20. package/dist/gateway/static/root/assets/browser-settings-page-DDjbDeHQ.js +8 -0
  21. package/dist/gateway/static/root/assets/capabilities-settings-panel-DM1Bcf1x.js +8 -0
  22. package/dist/gateway/static/root/assets/channels-settings-Bq36CUxL.js +1 -0
  23. package/dist/gateway/static/root/assets/{channels-status-swr-DMYQNs-J.js → channels-status-swr-Dfi0Desh.js} +1 -1
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-Dx5KQyo5.js → chat-terminal-dock-B0MvcO6j.js} +2 -2
  25. package/dist/gateway/static/root/assets/connectors-page-L8JehrxF.js +2 -0
  26. package/dist/gateway/static/root/assets/{date-picker-CkDROZoe.js → date-picker-DXOvbHCr.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-Bl8HcvzL.js → dependency-picker-BEnC-eS0.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-BcknAjbW.js → desktop-pet-DtPNvznL.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-BuCpXQPm.js → desktop-pet-settings-CYyjcSn6.js} +1 -1
  30. package/dist/gateway/static/root/assets/device-pairing-wizard-BPMGvAKE.js +1 -0
  31. package/dist/gateway/static/root/assets/{extension-debug-page-qRpb2FFa.js → extension-debug-page-H_aPMGXW.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-C7gs9wu4.js → extension-page-C1JnpeMt.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-CyJP1CMZ.js → extension-settings-page-C75kCOqe.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-swr-Cpmyrr6j.js → gateway-config-swr-G2lQt7Ak.js} +1 -1
  35. package/dist/gateway/static/root/assets/gateway-settings-BCF732TU.js +1 -0
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-DoiPeb65.js → gateway-startup-retry-GP31PUrG.js} +1 -1
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-CV6Dolcn.js → heartbeat-settings-C7fjiowt.js} +1 -1
  38. package/dist/gateway/static/root/assets/home-page-DZXeXdUL.js +1 -0
  39. package/dist/gateway/static/root/assets/{image-generation-api-CqjHWl2T.js → image-generation-api-CKFhfHSw.js} +1 -1
  40. package/dist/gateway/static/root/assets/imports-page-GROumhj8.js +1 -0
  41. package/dist/gateway/static/root/assets/{index-CHgOG1aR.js → index-ChIrvv3t.js} +47 -47
  42. package/dist/gateway/static/root/assets/index-R1VNlHjj.css +2 -0
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B3XqA41D.js → keyboard-shortcuts-settings-zcI822m_.js} +1 -1
  44. package/dist/gateway/static/root/assets/local-app-workbench-page-CAEKGTAg.js +2 -0
  45. package/dist/gateway/static/root/assets/{local-apps-page-BcIVYp0J.js → local-apps-page-BtgDJ92Q.js} +1 -1
  46. package/dist/gateway/static/root/assets/{locale-store-1urrBBCQ.js → locale-store-DlOv7896.js} +1 -1
  47. package/dist/gateway/static/root/assets/logs-page-DHZ4BEkG.js +2 -0
  48. package/dist/gateway/static/root/assets/{management-settings-DNFCdgzR.js → management-settings-DasZxCyD.js} +1 -1
  49. package/dist/gateway/static/root/assets/{markdown-view-BZmcFIWa.js → markdown-view-6oYdBahT.js} +1 -1
  50. package/dist/gateway/static/root/assets/{media-plugins-BDxNhoBC.js → media-plugins-CxthbBvk.js} +1 -1
  51. package/dist/gateway/static/root/assets/messages-Ls1Aaiqd.js +3 -0
  52. package/dist/gateway/static/root/assets/note-detail-panel-BcWq3ddw.js +5 -0
  53. package/dist/gateway/static/root/assets/notes-page-DfZ8QWyv.js +8 -0
  54. package/dist/gateway/static/root/assets/{page-tabs-agH3a2PI.js → page-tabs-BG39KidE.js} +1 -1
  55. package/dist/gateway/static/root/assets/{preview-open-alternatives-XEZ7zDOP.js → preview-open-alternatives-Bevpbq9f.js} +1 -1
  56. package/dist/gateway/static/root/assets/proactive-page-D2U_xQaS.js +1 -0
  57. package/dist/gateway/static/root/assets/{product-open-page-lXAbj85Z.js → product-open-page-Bi1seZpM.js} +1 -1
  58. package/dist/gateway/static/root/assets/project-detail-page-CzlGTW4F.js +1 -0
  59. package/dist/gateway/static/root/assets/projects-page-mQsM-TsP.js +1 -0
  60. package/dist/gateway/static/root/assets/{registry-api-CxQstD00.js → registry-api-D0ddwBFj.js} +1 -1
  61. package/dist/gateway/static/root/assets/remote-access-hub-Cb56JcO1.js +1 -0
  62. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DErKZlVJ.js → runtime-tools-settings-panel-Wkru8_My.js} +2 -2
  63. package/dist/gateway/static/root/assets/{schema-form-DhCmJQVJ.js → schema-form-CSMRzj9Y.js} +1 -1
  64. package/dist/gateway/static/root/assets/sessions-page-Hj9uFcIO.js +1 -0
  65. package/dist/gateway/static/root/assets/settings-advanced-gate-CV4-_EVA.js +1 -0
  66. package/dist/gateway/static/root/assets/{settings-form-section-Dg6chotg.js → settings-form-section-wcAdCkK8.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-page-LyuN5N3M.js → settings-page-BcQGAnCs.js} +1 -1
  68. package/dist/gateway/static/root/assets/setup-status-panel-DzxmsaQG.js +1 -0
  69. package/dist/gateway/static/root/assets/{share-preview-page-CZvmf4Ob.js → share-preview-page-DQocUl-1.js} +1 -1
  70. package/dist/gateway/static/root/assets/shares-settings-xlJh1ccG.js +1 -0
  71. package/dist/gateway/static/root/assets/skill-reload-api-wSXJRSxX.js +1 -0
  72. package/dist/gateway/static/root/assets/skills-page-AmqtBJo7.js +2 -0
  73. package/dist/gateway/static/root/assets/{skills-page.utils-Eu0WVHTS.js → skills-page.utils-DtlfCgJp.js} +1 -1
  74. package/dist/gateway/static/root/assets/{system-settings-panel-DQKkM7B2.js → system-settings-panel-Ct698Nf-.js} +1 -1
  75. package/dist/gateway/static/root/assets/task-detail-page-sQpwq5-c.js +1 -0
  76. package/dist/gateway/static/root/assets/{theme-store-Dc5s20V3.js → theme-store-ng8KJsAT.js} +1 -1
  77. package/dist/gateway/static/root/assets/{tunnel-api-TKQpPVd6.js → tunnel-api-Boajol0M.js} +1 -1
  78. package/dist/gateway/static/root/assets/{use-autosave-CkVlrFk1.js → use-autosave-BSyxRHt2.js} +1 -1
  79. package/dist/gateway/static/root/assets/user-model-page-DIEHnAER.js +2 -0
  80. package/dist/gateway/static/root/assets/{voice-api-key-field-B12fFN-L.js → voice-api-key-field-SE3OQI1s.js} +1 -1
  81. package/dist/gateway/static/root/assets/{voice-config-api-Mk78BrpP.js → voice-config-api-VNuCmdFe.js} +1 -1
  82. package/dist/gateway/static/root/assets/{work-discovery-overlay-CT9Zy36i.js → work-discovery-overlay-Dn1vy2oq.js} +1 -1
  83. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BwefQliE.js → workflow-run-setup-panel-BJEfGY-k.js} +2 -2
  84. package/dist/gateway/static/root/assets/workflows-page-DgRNIyr7.js +6 -0
  85. package/dist/gateway/static/root/index.html +10 -10
  86. package/dist/package.js +1 -1
  87. package/dist/packages/gateway-contract/src/proactive.js +13 -4
  88. package/dist/src/agent/coding/repository-instructions.js +1 -1
  89. package/dist/src/agent/coding/workspace-revision.js +1 -1
  90. package/dist/src/agent/commands/command-isolation.js +1 -1
  91. package/dist/src/agent/tools/factory.js +7 -3
  92. package/dist/src/agent/tools/review-workspace.js +1 -1
  93. package/dist/src/browser/providers/browser-ext-install.js +10 -2
  94. package/dist/src/cli/command-loaders.js +1 -0
  95. package/dist/src/cli/command-manifest.js +4 -0
  96. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  97. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  98. package/dist/src/cli/commands/gateway/run-foreground.js +3 -0
  99. package/dist/src/cli/commands/import.d.ts +2 -0
  100. package/dist/src/cli/commands/import.js +78 -0
  101. package/dist/src/discussions/action-tasks.js +1 -1
  102. package/dist/src/discussions/edits.js +1 -1
  103. package/dist/src/discussions/index.js +1 -1
  104. package/dist/src/discussions/organizer.js +1 -1
  105. package/dist/src/discussions/recording.js +1 -1
  106. package/dist/src/discussions/sealer.js +1 -1
  107. package/dist/src/discussions/service.js +2 -2
  108. package/dist/src/endpoint-tools/invocation-service.d.ts +2 -0
  109. package/dist/src/endpoint-tools/invocation-service.js +48 -19
  110. package/dist/src/gateway/heartbeat/check-store.d.ts +18 -0
  111. package/dist/src/gateway/heartbeat/check-store.js +73 -0
  112. package/dist/src/gateway/heartbeat/service.d.ts +12 -3
  113. package/dist/src/gateway/heartbeat/service.js +61 -44
  114. package/dist/src/gateway/hono/routes/discussions.js +2 -2
  115. package/dist/src/gateway/hono/routes/imports.d.ts +3 -0
  116. package/dist/src/gateway/hono/routes/imports.js +56 -0
  117. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  118. package/dist/src/gateway/hono/routes/proactive-control.js +2 -1
  119. package/dist/src/gateway/service.d.ts +7 -0
  120. package/dist/src/gateway/service.js +26 -9
  121. package/dist/src/imports/compatibility.d.ts +7 -0
  122. package/dist/src/imports/compatibility.js +174 -0
  123. package/dist/src/imports/contextImport.d.ts +3 -0
  124. package/dist/src/imports/contextImport.js +56 -0
  125. package/dist/src/imports/files.d.ts +13 -0
  126. package/dist/src/imports/files.js +77 -0
  127. package/dist/src/imports/importService.d.ts +50 -0
  128. package/dist/src/imports/importService.js +414 -0
  129. package/dist/src/imports/inventory.d.ts +11 -0
  130. package/dist/src/imports/inventory.js +202 -0
  131. package/dist/src/imports/planner.d.ts +11 -0
  132. package/dist/src/imports/planner.js +98 -0
  133. package/dist/src/imports/productImport.d.ts +10 -0
  134. package/dist/src/imports/productImport.js +241 -0
  135. package/dist/src/imports/runtime.d.ts +5 -0
  136. package/dist/src/imports/runtime.js +61 -0
  137. package/dist/src/imports/scanner.d.ts +14 -0
  138. package/dist/src/imports/scanner.js +159 -0
  139. package/dist/src/imports/secrets.d.ts +2 -0
  140. package/dist/src/imports/secrets.js +9 -0
  141. package/dist/src/imports/sources.d.ts +37 -0
  142. package/dist/src/imports/sources.js +75 -0
  143. package/dist/src/imports/types.d.ts +144 -0
  144. package/dist/src/imports/types.js +11 -0
  145. package/dist/src/infra/background-task.d.ts +2 -0
  146. package/dist/src/infra/background-task.js +25 -0
  147. package/dist/src/infra/process-diagnostics.d.ts +5 -0
  148. package/dist/src/infra/process-diagnostics.js +97 -0
  149. package/dist/src/infra/unhandled-rejections.js +6 -3
  150. package/dist/src/infra/update-restart.js +1 -1
  151. package/dist/src/knowledge/ingestion-service.js +1 -0
  152. package/dist/src/knowledge-memory/repository.js +4 -2
  153. package/dist/src/media-shared/http/ssrf-guard.js +1 -1
  154. package/dist/src/notifications/proactive-policy.js +7 -5
  155. package/dist/src/proactive/execution/authorization.d.ts +2 -0
  156. package/dist/src/proactive/execution/authorization.js +10 -1
  157. package/dist/src/proactive/execution/context.js +1 -0
  158. package/dist/src/proactive/execution/repository.d.ts +2 -0
  159. package/dist/src/proactive/execution/repository.js +19 -2
  160. package/dist/src/proactive/execution/worker.js +14 -4
  161. package/dist/src/proactive/experience.d.ts +4 -1
  162. package/dist/src/proactive/experience.js +3 -0
  163. package/dist/src/proactive/follow-ups.d.ts +5 -0
  164. package/dist/src/proactive/follow-ups.js +18 -7
  165. package/dist/src/proactive/inbox/cards.js +2 -1
  166. package/dist/src/proactive/inbox/delivery.js +6 -7
  167. package/dist/src/proactive/inbox/digest.d.ts +1 -1
  168. package/dist/src/proactive/inbox/digest.js +23 -13
  169. package/dist/src/proactive/inbox/notification-policy.d.ts +1 -1
  170. package/dist/src/proactive/inbox/notification-policy.js +9 -6
  171. package/dist/src/proactive/inbox/repository.js +3 -2
  172. package/dist/src/proactive/inbox/service.d.ts +6 -0
  173. package/dist/src/proactive/inbox/service.js +18 -0
  174. package/dist/src/proactive/inbox/types.d.ts +1 -0
  175. package/dist/src/proactive/policy/presence.d.ts +1 -1
  176. package/dist/src/proactive/policy/presence.js +7 -5
  177. package/dist/src/proactive/policy/service.d.ts +8 -5
  178. package/dist/src/proactive/policy/service.js +12 -12
  179. package/dist/src/proactive/scenarios/control.d.ts +3 -3
  180. package/dist/src/proactive/scenarios/control.js +12 -2
  181. package/dist/src/proactive/source-freshness.d.ts +8 -0
  182. package/dist/src/proactive/source-freshness.js +27 -0
  183. package/dist/src/proactive/status.d.ts +2 -0
  184. package/dist/src/proactive/status.js +21 -0
  185. package/dist/src/proactive/temporal/worker.js +2 -1
  186. package/dist/src/realtime/runtime.js +31 -5
  187. package/dist/src/realtime/writer.js +16 -9
  188. package/dist/src/storage/sqlite/import-repository.d.ts +18 -0
  189. package/dist/src/storage/sqlite/import-repository.js +35 -0
  190. package/dist/src/storage/sqlite/import-selection-repository.d.ts +15 -0
  191. package/dist/src/storage/sqlite/import-selection-repository.js +28 -0
  192. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  193. package/dist/src/storage/sqlite/knowledge-repository.js +2 -2
  194. package/dist/src/storage/sqlite/migrations/174_capability_imports.sql +11 -0
  195. package/dist/src/storage/sqlite/migrations/175_import_selections.sql +8 -0
  196. package/dist/src/storage/sqlite/migrations/176_proactive_quality.sql +5 -0
  197. package/dist/src/storage/sqlite/migrations/177_proactive_check_controls.sql +25 -0
  198. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  199. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  200. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  201. package/dist/src/storage/sqlite/schema.js +1 -1
  202. package/dist/src/work-discovery/candidate-discovery.js +1 -1
  203. package/dist/src/work-discovery/probe.js +1 -1
  204. package/package.json +4 -3
  205. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-SElFkQd6.js +0 -1
  206. package/dist/gateway/static/root/assets/agents-DYazUaZ6.js +0 -1
  207. package/dist/gateway/static/root/assets/apps-page-BzrodN8C.js +0 -1
  208. package/dist/gateway/static/root/assets/automations-workspace--A4I0jMu.js +0 -6
  209. package/dist/gateway/static/root/assets/browser-settings-page-DDTXUNWK.js +0 -8
  210. package/dist/gateway/static/root/assets/capabilities-settings-panel-Ll5UeXq5.js +0 -8
  211. package/dist/gateway/static/root/assets/channels-settings-BzL15bkU.js +0 -1
  212. package/dist/gateway/static/root/assets/connectors-page-RPw1AOMb.js +0 -2
  213. package/dist/gateway/static/root/assets/device-pairing-wizard-D0_tCX49.js +0 -1
  214. package/dist/gateway/static/root/assets/gateway-settings-DOeeTdWE.js +0 -1
  215. package/dist/gateway/static/root/assets/home-page-Djw1H_Go.js +0 -1
  216. package/dist/gateway/static/root/assets/index-B_Sg5BKz.css +0 -2
  217. package/dist/gateway/static/root/assets/local-app-workbench-page-BPqgyYJq.js +0 -2
  218. package/dist/gateway/static/root/assets/logs-page-BHax3XlS.js +0 -2
  219. package/dist/gateway/static/root/assets/messages-DYFcjtmG.js +0 -3
  220. package/dist/gateway/static/root/assets/note-detail-panel-Cs46LFXO.js +0 -5
  221. package/dist/gateway/static/root/assets/notes-page-BUkcn_0t.js +0 -8
  222. package/dist/gateway/static/root/assets/proactive-page-Bn484J9v.js +0 -1
  223. package/dist/gateway/static/root/assets/project-detail-page-LcH21ixD.js +0 -1
  224. package/dist/gateway/static/root/assets/projects-page-DelBiwyB.js +0 -1
  225. package/dist/gateway/static/root/assets/remote-access-hub-3BjFYXCf.js +0 -1
  226. package/dist/gateway/static/root/assets/sessions-page-CVFirgVd.js +0 -1
  227. package/dist/gateway/static/root/assets/settings-advanced-gate-DyfBpqkY.js +0 -1
  228. package/dist/gateway/static/root/assets/setup-status-panel-CrXhTzHr.js +0 -1
  229. package/dist/gateway/static/root/assets/shares-settings-DyM_D8hM.js +0 -1
  230. package/dist/gateway/static/root/assets/skill-reload-api-Bys58-15.js +0 -1
  231. package/dist/gateway/static/root/assets/skills-page-sWNvFo6D.js +0 -2
  232. package/dist/gateway/static/root/assets/task-detail-page-B18NcZQJ.js +0 -1
  233. package/dist/gateway/static/root/assets/user-model-page-ul-zr58b.js +0 -2
  234. package/dist/gateway/static/root/assets/workflows-page-BY_AWs7S.js +0 -6
@@ -0,0 +1,159 @@
1
+ import { containsSecret } from "./secrets.js";
2
+ import { ImportError } from "./types.js";
3
+ import { IMPORT_LIMITS, digest, readRegularFile, readTree } from "./files.js";
4
+ import { inspectMcp, inspectSkill } from "./compatibility.js";
5
+ import { IMPORT_SOURCES, sourceLayout } from "./sources.js";
6
+ import { basename, join } from "node:path";
7
+ import { existsSync, readdirSync, realpathSync } from "node:fs";
8
+ import { randomUUID } from "node:crypto";
9
+ import { setImmediate } from "node:timers/promises";
10
+ import { parse as parse$1 } from "smol-toml";
11
+ //#region src/imports/scanner.ts
12
+ function scanResult(source) {
13
+ if (!IMPORT_SOURCES.some((s) => s.id === source)) throw new ImportError("unsupported_source", "Unsupported source");
14
+ return {
15
+ id: randomUUID(),
16
+ createdAt: Date.now(),
17
+ source,
18
+ candidates: [],
19
+ diagnostics: []
20
+ };
21
+ }
22
+ function base(source, scope, location, shared = false) {
23
+ return {
24
+ id: randomUUID(),
25
+ source,
26
+ scope,
27
+ location,
28
+ shared
29
+ };
30
+ }
31
+ function appendMcp(scan, raw, scope, location) {
32
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
33
+ for (const [name, config] of Object.entries(raw)) scan.candidates.push(inspectMcp(base(scan.source, scope, location), name, config));
34
+ }
35
+ async function scanLocal(input) {
36
+ const scan = scanResult(input.source);
37
+ const { home, root, layout } = sourceLayout(input.source, input.home, input.root);
38
+ const scopes = (input.projectOnly ? [] : layout.skills).map((s) => ({
39
+ path: join(s.base === "home" ? home : root, s.path),
40
+ scope: "user",
41
+ shared: s.shared
42
+ }));
43
+ if (input.projectRoot) scopes.push({
44
+ path: join(input.projectRoot, layout.projectSkills),
45
+ scope: "project",
46
+ shared: layout.skills.some((s) => s.shared)
47
+ });
48
+ const seen = /* @__PURE__ */ new Set();
49
+ const budget = input.budget ?? {
50
+ bytes: 0,
51
+ files: 0
52
+ };
53
+ const consume = (bytes, files) => {
54
+ budget.bytes += bytes;
55
+ budget.files += files;
56
+ if (budget.bytes > IMPORT_LIMITS.total || budget.files > IMPORT_LIMITS.count) throw new ImportError("limit_exceeded", "Import exceeds batch limits", 413);
57
+ };
58
+ for (const scope of scopes) {
59
+ if (!existsSync(scope.path)) continue;
60
+ let entries;
61
+ try {
62
+ entries = readdirSync(scope.path, { withFileTypes: true });
63
+ } catch {
64
+ scan.diagnostics.push("Unable to read skills directory");
65
+ continue;
66
+ }
67
+ for (const entry of entries) {
68
+ await setImmediate();
69
+ if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
70
+ const location = join(scope.path, entry.name);
71
+ if (!existsSync(join(location, "SKILL.md"))) continue;
72
+ try {
73
+ const real = realpathSync(location);
74
+ if (seen.has(real)) continue;
75
+ seen.add(real);
76
+ const files = readTree(location);
77
+ consume(files.reduce((n, f) => n + Buffer.byteLength(f.data, "base64"), 0), files.length);
78
+ scan.candidates.push(inspectSkill(base(input.source, scope.scope, real, scope.shared), files));
79
+ } catch (error) {
80
+ if (error instanceof ImportError && error.code === "limit_exceeded") throw error;
81
+ scan.diagnostics.push(`${entry.name}: ${error instanceof ImportError ? error.message : "Unable to read skill"}`);
82
+ }
83
+ }
84
+ }
85
+ const configs = [{
86
+ path: join(root, layout.config.path),
87
+ scope: "user"
88
+ }];
89
+ if (input.projectRoot) configs.push({
90
+ path: join(input.projectRoot, layout.projectConfig),
91
+ scope: "project"
92
+ });
93
+ for (const config of configs) {
94
+ if (!existsSync(config.path)) continue;
95
+ try {
96
+ const text = readRegularFile(config.path, 1024 * 1024).toString("utf8");
97
+ const parsed = layout.config.format === "toml" ? parse$1(text) : JSON.parse(text);
98
+ if (!input.projectOnly || config.scope === "project") appendMcp(scan, parsed[layout.config.mcpKey], config.scope, config.path);
99
+ const projects = parsed.projects;
100
+ if (config.scope === "user" && projects && typeof projects === "object" && !Array.isArray(projects)) {
101
+ scan.projectRoots = Object.keys(projects);
102
+ if (input.projectRoot) {
103
+ const project = projects[input.projectRoot];
104
+ appendMcp(scan, project?.[layout.config.mcpKey], "project", config.path);
105
+ }
106
+ }
107
+ } catch {
108
+ scan.diagnostics.push(`${basename(config.path)}: invalid or unreadable configuration`);
109
+ }
110
+ }
111
+ const addDocument = (path, scope) => {
112
+ if (!existsSync(path)) return;
113
+ try {
114
+ const content = readRegularFile(path, 128 * 1024).toString("utf8").trim();
115
+ if (!content) return;
116
+ consume(Buffer.byteLength(content), 1);
117
+ const blocked = containsSecret(content);
118
+ scan.candidates.push({
119
+ ...base(input.source, scope, realpathSync(path)),
120
+ kind: "rule",
121
+ name: basename(path),
122
+ description: "",
123
+ hash: digest(content),
124
+ files: [],
125
+ compatibility: blocked ? "blocked" : "compatible",
126
+ findings: blocked ? ["Document contains probable credentials"] : [],
127
+ requiredEnv: [],
128
+ content: blocked ? void 0 : content
129
+ });
130
+ } catch {
131
+ scan.diagnostics.push(`${basename(path)}: unable to read context document`);
132
+ }
133
+ };
134
+ const addInstructions = (directory, groups, scope) => {
135
+ for (const names of groups) {
136
+ const path = names.map((name) => join(directory, name)).find(existsSync);
137
+ if (path) addDocument(path, scope);
138
+ }
139
+ };
140
+ const addRules = (directory, scope) => {
141
+ if (!existsSync(directory)) return;
142
+ try {
143
+ for (const entry of readdirSync(directory, { withFileTypes: true }).slice(0, 100)) if (entry.isFile() && entry.name.endsWith(".md")) addDocument(join(directory, entry.name), scope);
144
+ } catch {
145
+ scan.diagnostics.push("Unable to read rules directory");
146
+ }
147
+ };
148
+ if (!input.projectOnly) {
149
+ addInstructions(root, layout.instructions, "user");
150
+ if (layout.rules) addRules(join(root, layout.rules), "user");
151
+ }
152
+ if (input.projectRoot) {
153
+ addInstructions(input.projectRoot, layout.projectInstructions, "project");
154
+ if (layout.projectRules) addRules(join(input.projectRoot, layout.projectRules), "project");
155
+ }
156
+ return scan;
157
+ }
158
+ //#endregion
159
+ export { IMPORT_SOURCES, scanLocal };
@@ -0,0 +1,2 @@
1
+ export declare function containsSecret(text: string): boolean;
2
+ export declare function isCredentialPath(path: string): boolean;
@@ -0,0 +1,9 @@
1
+ //#region src/imports/secrets.ts
2
+ function containsSecret(text) {
3
+ return /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----|\b(?:sk-[a-zA-Z0-9_-]{20,}|gh[pousr]_[a-zA-Z0-9]{20,}|AKIA[A-Z0-9]{16})\b/i.test(text) || /(?:api[_-]?key|access[_-]?token|client[_-]?secret|password|authorization)\s*[=:]\s*["']?(?!\$|<|\{|process\.env|os\.environ)[a-zA-Z0-9_+/.-]{12,}/i.test(text);
4
+ }
5
+ function isCredentialPath(path) {
6
+ return /(^|\/)(\.env(?:\..*)?|auth\.json|credentials[^/]*|id_rsa|id_ed25519)$/i.test(path);
7
+ }
8
+ //#endregion
9
+ export { containsSecret, isCredentialPath };
@@ -0,0 +1,37 @@
1
+ import { type ImportSource } from './types.js';
2
+ interface SourceLayout {
3
+ id: ImportSource;
4
+ name: string;
5
+ directory: string;
6
+ environment: string;
7
+ skills: Array<{
8
+ base: 'home' | 'root';
9
+ path: string;
10
+ shared: boolean;
11
+ }>;
12
+ projectSkills: string;
13
+ instructions: string[][];
14
+ projectInstructions: string[][];
15
+ rules?: string;
16
+ projectRules?: string;
17
+ config: {
18
+ path: string;
19
+ format: 'json' | 'toml';
20
+ mcpKey: string;
21
+ };
22
+ projectConfig: string;
23
+ }
24
+ /** Product differences live here; readers and destination writers are shared. */
25
+ export declare const IMPORT_SOURCES: readonly SourceLayout[];
26
+ export declare function sourceLayout(source: ImportSource, home?: string, root?: string): {
27
+ layout: SourceLayout;
28
+ home: string;
29
+ root: string;
30
+ };
31
+ export declare function detectImportSources(): {
32
+ id: ImportSource;
33
+ name: string;
34
+ detected: boolean;
35
+ }[];
36
+ export declare function isImportSource(value: string): value is ImportSource;
37
+ export {};
@@ -0,0 +1,75 @@
1
+ import { ImportError } from "./types.js";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { existsSync } from "node:fs";
5
+ //#region src/imports/sources.ts
6
+ /** Product differences live here; readers and destination writers are shared. */
7
+ const IMPORT_SOURCES = [{
8
+ id: "codex",
9
+ name: "Codex",
10
+ directory: ".codex",
11
+ environment: "CODEX_HOME",
12
+ skills: [{
13
+ base: "home",
14
+ path: ".agents/skills",
15
+ shared: true
16
+ }],
17
+ projectSkills: ".agents/skills",
18
+ instructions: [["AGENTS.override.md", "AGENTS.md"]],
19
+ projectInstructions: [["AGENTS.override.md", "AGENTS.md"]],
20
+ config: {
21
+ path: "config.toml",
22
+ format: "toml",
23
+ mcpKey: "mcp_servers"
24
+ },
25
+ projectConfig: ".codex/config.toml"
26
+ }, {
27
+ id: "claude-code",
28
+ name: "Claude Code",
29
+ directory: ".claude",
30
+ environment: "CLAUDE_CONFIG_DIR",
31
+ skills: [{
32
+ base: "root",
33
+ path: "skills",
34
+ shared: false
35
+ }],
36
+ projectSkills: ".claude/skills",
37
+ instructions: [["CLAUDE.md"]],
38
+ projectInstructions: [
39
+ ["CLAUDE.md"],
40
+ [".claude/CLAUDE.md"],
41
+ ["CLAUDE.local.md"]
42
+ ],
43
+ rules: "rules",
44
+ projectRules: ".claude/rules",
45
+ config: {
46
+ path: "../.claude.json",
47
+ format: "json",
48
+ mcpKey: "mcpServers"
49
+ },
50
+ projectConfig: ".mcp.json"
51
+ }];
52
+ function sourceLayout(source, home, root) {
53
+ const layout = IMPORT_SOURCES.find((s) => s.id === source);
54
+ if (!layout) throw new ImportError("unsupported_source", "Unsupported source");
55
+ return {
56
+ layout,
57
+ home: home ?? homedir(),
58
+ root: root ?? (home ? void 0 : process.env[layout.environment]) ?? join(home ?? homedir(), layout.directory)
59
+ };
60
+ }
61
+ function detectImportSources() {
62
+ return IMPORT_SOURCES.map((s) => {
63
+ const { root } = sourceLayout(s.id);
64
+ return {
65
+ id: s.id,
66
+ name: s.name,
67
+ detected: existsSync(root) || existsSync(join(root, s.config.path))
68
+ };
69
+ });
70
+ }
71
+ function isImportSource(value) {
72
+ return IMPORT_SOURCES.some((source) => source.id === value);
73
+ }
74
+ //#endregion
75
+ export { IMPORT_SOURCES, detectImportSources, isImportSource, sourceLayout };
@@ -0,0 +1,144 @@
1
+ export type ImportSource = 'codex' | 'claude-code';
2
+ export type ImportScope = 'user' | 'project';
3
+ export type Compatibility = 'compatible' | 'needs_setup' | 'blocked' | 'unsupported';
4
+ export interface ImportFile {
5
+ path: string;
6
+ data: string;
7
+ executable: boolean;
8
+ }
9
+ export interface ImportCandidate {
10
+ id: string;
11
+ source: ImportSource;
12
+ kind: 'skill' | 'mcp' | 'rule';
13
+ name: string;
14
+ description: string;
15
+ scope: ImportScope;
16
+ location: string;
17
+ hash: string;
18
+ compatibility: Compatibility;
19
+ findings: string[];
20
+ files: ImportFile[];
21
+ content?: string;
22
+ mcp?: Record<string, unknown>;
23
+ requiredEnv: string[];
24
+ shared: boolean;
25
+ connected?: boolean;
26
+ }
27
+ export interface ImportScan {
28
+ id: string;
29
+ createdAt: number;
30
+ source: ImportSource;
31
+ candidates: ImportCandidate[];
32
+ diagnostics: string[];
33
+ projectRoots?: string[];
34
+ }
35
+ export interface ImportTarget {
36
+ projectId?: string;
37
+ root: string;
38
+ }
39
+ export interface ImportAction {
40
+ candidateId: string;
41
+ operation: 'skip' | 'create' | 'rename' | 'replace';
42
+ name: string;
43
+ beforeHash: string | null;
44
+ }
45
+ export interface ImportPlan {
46
+ id: string;
47
+ scanId: string;
48
+ createdAt: number;
49
+ expiresAt: number;
50
+ target: ImportTarget;
51
+ targetRevision: string;
52
+ actions: ImportAction[];
53
+ }
54
+ export interface ImportJobItem {
55
+ action: ImportAction;
56
+ status: 'staged' | 'skipped' | 'publishing' | 'active' | 'rolling_back' | 'rolled_back' | 'failed';
57
+ error?: string;
58
+ afterHash?: string;
59
+ backupPath?: string;
60
+ }
61
+ export interface ImportJob {
62
+ id: string;
63
+ plan: ImportPlan;
64
+ createdAt: number;
65
+ expiresAt: number;
66
+ items: ImportJobItem[];
67
+ }
68
+ export declare class ImportError extends Error {
69
+ readonly code: string;
70
+ readonly status: 400 | 403 | 404 | 409 | 413;
71
+ constructor(code: string, message: string, status?: 400 | 403 | 404 | 409 | 413);
72
+ }
73
+ export type InventoryStatus = 'ready' | 'existing' | 'conflict' | 'blocked';
74
+ export interface InventoryItem {
75
+ id: string;
76
+ kind: 'skill' | 'context' | 'project';
77
+ parentId?: string;
78
+ name: string;
79
+ description: string;
80
+ displayPath: string;
81
+ scope: ImportScope;
82
+ status: InventoryStatus;
83
+ reason?: string;
84
+ suggested: boolean;
85
+ targetName?: string;
86
+ }
87
+ export interface ImportInventory {
88
+ id: string;
89
+ source: ImportSource;
90
+ createdAt: number;
91
+ expiresAt: number;
92
+ candidates: InventoryItem[];
93
+ notices: string[];
94
+ complete: boolean;
95
+ }
96
+ export interface StoredInventoryItem extends InventoryItem {
97
+ location: string;
98
+ scanId?: string;
99
+ candidate?: ImportCandidate;
100
+ targetRoot?: string;
101
+ projectId?: string;
102
+ }
103
+ export interface StoredInventory extends Omit<ImportInventory, 'candidates'> {
104
+ candidates: StoredInventoryItem[];
105
+ scanIds: string[];
106
+ }
107
+ export interface ImportSelection {
108
+ inventoryId: string;
109
+ candidateIds: string[];
110
+ requestId: string;
111
+ retryOf?: string;
112
+ }
113
+ export interface ImportRunItem {
114
+ candidateId: string;
115
+ kind: InventoryItem['kind'];
116
+ name: string;
117
+ status: 'pending' | 'imported' | 'existing' | 'failed';
118
+ targetId?: string;
119
+ jobId?: string;
120
+ error?: string;
121
+ }
122
+ export interface ProductImportResult {
123
+ id: string;
124
+ source: ImportSource;
125
+ createdAt: number;
126
+ inventoryId: string;
127
+ selectionHash: string;
128
+ status: 'running' | 'completed' | 'partial';
129
+ items: ImportRunItem[];
130
+ skills: number;
131
+ context: number;
132
+ projects: number;
133
+ skipped: number;
134
+ issues: Array<{
135
+ name: string;
136
+ reason: string;
137
+ }>;
138
+ }
139
+ export interface DetectedImportSource {
140
+ id: ImportSource;
141
+ name: string;
142
+ detected: boolean;
143
+ lastImport?: ProductImportResult;
144
+ }
@@ -0,0 +1,11 @@
1
+ //#region src/imports/types.ts
2
+ var ImportError = class extends Error {
3
+ constructor(code, message, status = 400) {
4
+ super(message);
5
+ this.code = code;
6
+ this.status = status;
7
+ this.name = "ImportError";
8
+ }
9
+ };
10
+ //#endregion
11
+ export { ImportError };
@@ -0,0 +1,2 @@
1
+ /** Run one background tick at a time, reporting once per consecutive failure period. */
2
+ export declare function createBackgroundTask(run: () => void | Promise<void>, onError: (error: unknown) => void): () => void;
@@ -0,0 +1,25 @@
1
+ //#region src/infra/background-task.ts
2
+ /** Run one background tick at a time, reporting once per consecutive failure period. */
3
+ function createBackgroundTask(run, onError) {
4
+ let running = false;
5
+ let failed = false;
6
+ return () => {
7
+ if (running) return;
8
+ running = true;
9
+ (async () => {
10
+ try {
11
+ await run();
12
+ failed = false;
13
+ } catch (error) {
14
+ if (!failed) {
15
+ failed = true;
16
+ onError(error);
17
+ }
18
+ } finally {
19
+ running = false;
20
+ }
21
+ })();
22
+ };
23
+ }
24
+ //#endregion
25
+ export { createBackgroundTask };
@@ -0,0 +1,5 @@
1
+ export declare function recordProcessDiagnostic(event: string, detail: unknown): void;
2
+ /** Independent of SQLite and async logger transports; safe to use during process failure. */
3
+ export declare function createProcessDiagnosticWriter(path: string): (event: string, detail: unknown) => void;
4
+ /** Observe fatal exceptions without resuming execution in an unknown process state. */
5
+ export declare function installProcessDiagnostics(path: string): () => void;
@@ -0,0 +1,97 @@
1
+ import { init_redact, redactObject, redactSensitiveInfo } from "../utils/logger/redact.js";
2
+ import { dirname } from "node:path";
3
+ import { appendFileSync, mkdirSync, renameSync, rmSync, statSync } from "node:fs";
4
+ import { inspect } from "node:util";
5
+ //#region src/infra/process-diagnostics.ts
6
+ init_redact();
7
+ const MAX_LOG_BYTES = 2 * 1024 * 1024;
8
+ const MAX_DETAIL_CHARS = 64 * 1024;
9
+ function diagnosticValue(value, depth = 0) {
10
+ if (depth > 5) return "[MaxDepth]";
11
+ if (value instanceof Error) return {
12
+ name: value.name,
13
+ message: value.message,
14
+ stack: value.stack,
15
+ ...value.cause === void 0 ? {} : { cause: diagnosticValue(value.cause, depth + 1) }
16
+ };
17
+ if (Array.isArray(value)) return value.slice(0, 30).map((item) => diagnosticValue(item, depth + 1));
18
+ if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).slice(0, 30).map(([key, item]) => [key, diagnosticValue(item, depth + 1)]));
19
+ return value;
20
+ }
21
+ let activeWriter;
22
+ function recordProcessDiagnostic(event, detail) {
23
+ activeWriter?.(event, detail);
24
+ }
25
+ /** Independent of SQLite and async logger transports; safe to use during process failure. */
26
+ function createProcessDiagnosticWriter(path) {
27
+ return (event, detail) => {
28
+ try {
29
+ const text = typeof detail === "string" ? detail : inspect(redactObject(diagnosticValue(detail)), {
30
+ depth: 5,
31
+ maxArrayLength: 30,
32
+ maxStringLength: MAX_DETAIL_CHARS,
33
+ customInspect: false,
34
+ getters: false
35
+ });
36
+ const line = JSON.stringify({
37
+ time: (/* @__PURE__ */ new Date()).toISOString(),
38
+ pid: process.pid,
39
+ event,
40
+ detail: redactSensitiveInfo(text).slice(-MAX_DETAIL_CHARS)
41
+ }) + "\n";
42
+ mkdirSync(dirname(path), {
43
+ recursive: true,
44
+ mode: 448
45
+ });
46
+ let size = 0;
47
+ try {
48
+ size = statSync(path).size;
49
+ } catch (err) {
50
+ if (err.code !== "ENOENT") throw err;
51
+ }
52
+ if (size + Buffer.byteLength(line) > MAX_LOG_BYTES) {
53
+ rmSync(`${path}.2`, { force: true });
54
+ try {
55
+ renameSync(`${path}.1`, `${path}.2`);
56
+ } catch (err) {
57
+ if (err.code !== "ENOENT") throw err;
58
+ }
59
+ renameSync(path, `${path}.1`);
60
+ }
61
+ appendFileSync(path, line, {
62
+ encoding: "utf8",
63
+ mode: 384
64
+ });
65
+ } catch {}
66
+ };
67
+ }
68
+ /** Observe fatal exceptions without resuming execution in an unknown process state. */
69
+ function installProcessDiagnostics(path) {
70
+ const write = createProcessDiagnosticWriter(path);
71
+ const previousWriter = activeWriter;
72
+ activeWriter = write;
73
+ const onFatal = (error, origin) => write("uncaught_exception", {
74
+ origin,
75
+ error,
76
+ uptimeSeconds: process.uptime(),
77
+ memory: process.memoryUsage()
78
+ });
79
+ const onExit = (code) => write("process_exit", {
80
+ code,
81
+ uptimeSeconds: process.uptime()
82
+ });
83
+ process.on("uncaughtExceptionMonitor", onFatal);
84
+ process.on("exit", onExit);
85
+ write("process_start", {
86
+ node: process.version,
87
+ platform: process.platform,
88
+ arch: process.arch
89
+ });
90
+ return () => {
91
+ if (activeWriter === write) activeWriter = previousWriter;
92
+ process.removeListener("uncaughtExceptionMonitor", onFatal);
93
+ process.removeListener("exit", onExit);
94
+ };
95
+ }
96
+ //#endregion
97
+ export { createProcessDiagnosticWriter, installProcessDiagnostics, recordProcessDiagnostic };
@@ -1,6 +1,7 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
3
  import { resolveGlobalSingleton } from "../utils/global-singleton.js";
4
+ import { recordProcessDiagnostic } from "./process-diagnostics.js";
4
5
  import { isTransientSqliteError } from "./sqlite-errors.js";
5
6
  //#region src/infra/unhandled-rejections.ts
6
7
  init_logger();
@@ -10,12 +11,14 @@ function installSqliteTransientRejectionHandler() {
10
11
  const state = resolveGlobalSingleton(installStateKey, () => ({ installed: false }));
11
12
  if (state.installed) return;
12
13
  process.on("unhandledRejection", (reason) => {
13
- if (!isTransientSqliteError(reason)) return;
14
+ recordProcessDiagnostic("unhandled_rejection", reason);
14
15
  const em = reason instanceof Error ? reason.message : String(reason);
15
- log.warn({
16
+ const fields = {
16
17
  err: reason instanceof Error ? reason : void 0,
17
18
  errorMessage: em
18
- }, `Transient SQLite rejection: ${em}`);
19
+ };
20
+ if (isTransientSqliteError(reason)) log.warn(fields, `Transient SQLite rejection: ${em}`);
21
+ else log.error(fields, `Unhandled promise rejection: ${em}`);
19
22
  });
20
23
  state.installed = true;
21
24
  }
@@ -3,9 +3,9 @@ import { init_logger } from "../utils/logger.js";
3
3
  import { init_paths, resolveConfigPath } from "../config/paths.js";
4
4
  import { init_loader, loadConfig } from "../config/loader.js";
5
5
  import { isRestartEnabled } from "../config/commands.flags.js";
6
- import { resolveGatewayService } from "../daemon/service.js";
7
6
  import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "./restart.js";
8
7
  import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
8
+ import { resolveGatewayService } from "../daemon/service.js";
9
9
  import { refreshGatewayServiceAfterUpdate } from "./update-service-refresh.js";
10
10
  //#region src/infra/update-restart.ts
11
11
  init_loader();
@@ -89,6 +89,7 @@ var KnowledgeIngestionService = class {
89
89
  const cursorBefore = this.state.getCursor(params.instanceId, params.collectionScope);
90
90
  const run = startKnowledgeSyncRun({
91
91
  sourceInstanceId: params.instanceId,
92
+ collectionScope: params.collectionScope,
92
93
  cursorBefore
93
94
  });
94
95
  const controller = params.signal ? null : new AbortController();
@@ -142,7 +142,9 @@ function searchKnowledgeItems(input) {
142
142
  const visible = visibilityClause(input.context);
143
143
  const sourceParts = [];
144
144
  const sourceValues = [];
145
- if (input.sources?.includes("connector")) sourceParts.push("k.record_class = 'source_index'");
145
+ const importedSource = "COALESCE(json_extract(k.source_json, '$.kind'), '') = 'product_import'";
146
+ if (input.sources?.includes("connector")) sourceParts.push(`(k.record_class = 'source_index' AND NOT (${importedSource}))`);
147
+ if (input.sources?.includes("workspace")) sourceParts.push(`(k.record_class = 'source_index' AND ${importedSource})`);
146
148
  const memoryScopes = input.sources?.filter((source) => source !== "connector") ?? [];
147
149
  if (memoryScopes.length) {
148
150
  sourceParts.push(`(k.record_class = 'memory' AND k.scope_type IN (${memoryScopes.map(() => "?").join(", ")}))`);
@@ -163,7 +165,7 @@ function searchKnowledgeItems(input) {
163
165
  ORDER BY rank ASC, k.importance DESC, k.updated_at DESC LIMIT ?`).all(fts, principalId, asOf, asOf, asOf, ...input.recordClass ? [input.recordClass] : [], ...sourceValues, ...visible.values, limit).map(fromRow);
164
166
  }
165
167
  function knowledgeSourceAllowed(item, sources) {
166
- if (item.recordClass === "source_index") return sources.includes("connector");
168
+ if (item.recordClass === "source_index") return sources.includes(item.source.kind === "product_import" ? "workspace" : "connector");
167
169
  return item.scope.type === "session" ? sources.includes("session") : item.scope.type === "workspace" ? sources.includes("workspace") : item.scope.type === "project" ? sources.includes("project") : false;
168
170
  }
169
171
  //#endregion
@@ -1,5 +1,5 @@
1
- import { isIP } from "node:net";
2
1
  import { promisify } from "node:util";
2
+ import { isIP } from "node:net";
3
3
  import { lookup } from "node:dns";
4
4
  //#region src/media-shared/http/ssrf-guard.ts
5
5
  /**