@xopcai/xopc 0.0.308 → 0.0.309

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 (181) hide show
  1. package/dist/browser-ext/_locales/en/messages.json +8 -0
  2. package/dist/browser-ext/_locales/zh_CN/messages.json +8 -0
  3. package/dist/browser-ext/dist/assets/{sidepanel-BbSQr-6P.css → sidepanel-DD6GEMvc.css} +16 -0
  4. package/dist/browser-ext/dist/sidepanel.html +1 -1
  5. package/dist/browser-ext/dist/sidepanel.js +537 -96
  6. package/dist/browser-ext/manifest.json +1 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/gateway/static/root/assets/{activity-store-wgSB2HYK.js → activity-store-XKNYlFUI.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dUotwUO6.js → agent-avatar-dicebear-1S2TFECE.js} +1 -1
  10. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-C6LflMXr.js → agent-defaults-settings-panel-f0-YFMUz.js} +1 -1
  11. package/dist/gateway/static/root/assets/{agents-VPDIGRSS.js → agents-CPqUMtCL.js} +1 -1
  12. package/dist/gateway/static/root/assets/{api-BKHmTb0w.js → api-BEUEE4f2.js} +1 -1
  13. package/dist/gateway/static/root/assets/api-CN4id43t.js +1 -0
  14. package/dist/gateway/static/root/assets/{app-management-settings-panel-zPz0rOND.js → app-management-settings-panel-CgVBSqzu.js} +1 -1
  15. package/dist/gateway/static/root/assets/{appearance-settings-DhvhR43G.js → appearance-settings-CoWdCokb.js} +1 -1
  16. package/dist/gateway/static/root/assets/{apps-page-Pmslbzzr.js → apps-page-CexHOcWg.js} +1 -1
  17. package/dist/gateway/static/root/assets/{archive-plugin-BQVZMreT.js → archive-plugin-C3ZA6LRS.js} +1 -1
  18. package/dist/gateway/static/root/assets/{attachment-load-CPE-TMPf.js → attachment-load-CdgS6_zy.js} +1 -1
  19. package/dist/gateway/static/root/assets/{automations-page-C4IAy_zF.js → automations-page-BtHL2hpg.js} +1 -1
  20. package/dist/gateway/static/root/assets/{automations-workspace-Fx5VUJRu.js → automations-workspace-onJPfmO6.js} +1 -1
  21. package/dist/gateway/static/root/assets/{binary-plugins-DgTl7diZ.js → binary-plugins-CiDhtq_H.js} +1 -1
  22. package/dist/gateway/static/root/assets/{block-editor-CcOVA-Gw.js → block-editor-Br00T83w.js} +1 -1
  23. package/dist/gateway/static/root/assets/{browser-automation-inputs-BzkJog8e.js → browser-automation-inputs-D2tILykA.js} +1 -1
  24. package/dist/gateway/static/root/assets/{browser-automations-page--zKAgj1k.js → browser-automations-page-BVuEmryB.js} +1 -1
  25. package/dist/gateway/static/root/assets/{browser-settings-page-DBms6d35.js → browser-settings-page-BgVTyPFY.js} +1 -1
  26. package/dist/gateway/static/root/assets/{capabilities-settings-panel-epdDWIZy.js → capabilities-settings-panel-Dra8wj1S.js} +1 -1
  27. package/dist/gateway/static/root/assets/{channels-settings-B0bsDtmP.js → channels-settings-CkxiMDJ4.js} +1 -1
  28. package/dist/gateway/static/root/assets/{channels-status-swr-B2JwuTjG.js → channels-status-swr-Dtder4G_.js} +1 -1
  29. package/dist/gateway/static/root/assets/{chat-terminal-dock-BfLd2rIJ.js → chat-terminal-dock-JsMtzDao.js} +1 -1
  30. package/dist/gateway/static/root/assets/{computer-settings-page-Ckgc0Py-.js → computer-settings-page-DHerePwo.js} +1 -1
  31. package/dist/gateway/static/root/assets/{connector-service-page-BlC1OXX4.js → connector-service-page-DZFNUTiN.js} +1 -1
  32. package/dist/gateway/static/root/assets/{connectors-page-By33-bF1.js → connectors-page-cl9ZrV4D.js} +1 -1
  33. package/dist/gateway/static/root/assets/{cron-expression-CqNE-nf6.js → cron-expression-DAhdv_Xv.js} +1 -1
  34. package/dist/gateway/static/root/assets/{date-picker-BS9ZjzYJ.js → date-picker-PacO1m3a.js} +1 -1
  35. package/dist/gateway/static/root/assets/{dependency-picker-CF_zYzxX.js → dependency-picker-B-BcuG1y.js} +1 -1
  36. package/dist/gateway/static/root/assets/{desktop-pet-CDwtLR7Z.js → desktop-pet-CdBBhhdY.js} +1 -1
  37. package/dist/gateway/static/root/assets/{desktop-pet-settings-C0djIc1J.js → desktop-pet-settings-Gy03NgMI.js} +1 -1
  38. package/dist/gateway/static/root/assets/{device-pairing-wizard-CDKj9LQj.js → device-pairing-wizard-aV25nKag.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-debug-page-CX5OXxEU.js → extension-debug-page-BFp5eKtY.js} +1 -1
  40. package/dist/gateway/static/root/assets/{extension-page-BytR1PaY.js → extension-page-DL3vyyH6.js} +1 -1
  41. package/dist/gateway/static/root/assets/{extension-settings-page-CkaMJA5F.js → extension-settings-page-BXtvdAsY.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-config-swr-B6wHa6ZI.js → gateway-config-swr-xAOGtenO.js} +1 -1
  43. package/dist/gateway/static/root/assets/{gateway-realtime-B53R0CA4.js → gateway-realtime-BuaTsMSi.js} +1 -1
  44. package/dist/gateway/static/root/assets/gateway-realtime-store-BG95uGVW.js +1 -0
  45. package/dist/gateway/static/root/assets/{gateway-settings-_YU-1p0z.js → gateway-settings-Dcr2Ikeh.js} +1 -1
  46. package/dist/gateway/static/root/assets/{gateway-startup-retry-DRzGnEV-.js → gateway-startup-retry-BwDxKHd4.js} +1 -1
  47. package/dist/gateway/static/root/assets/{heartbeat-settings-CVIvvm4x.js → heartbeat-settings-DOy3alvT.js} +1 -1
  48. package/dist/gateway/static/root/assets/{home-page-COCHelcL.js → home-page-CDm3dGVy.js} +1 -1
  49. package/dist/gateway/static/root/assets/{image-generation-api-Ck_pyDom.js → image-generation-api-wGMeI_yW.js} +1 -1
  50. package/dist/gateway/static/root/assets/{imports-page-DrtbjL8O.js → imports-page-zexFT5Rq.js} +1 -1
  51. package/dist/gateway/static/root/assets/index-D-vczw_0.css +1 -0
  52. package/dist/gateway/static/root/assets/{index-CDfcPiPb.js → index-DJo4DimT.js} +47 -47
  53. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BlZh41Xq.js → keyboard-shortcuts-settings-CutG9zLh.js} +1 -1
  54. package/dist/gateway/static/root/assets/{local-app-workbench-page-D7_Raxjw.js → local-app-workbench-page-CwLvTwjn.js} +1 -1
  55. package/dist/gateway/static/root/assets/{local-apps-page-DbP7wWuh.js → local-apps-page-CJy6I7Dt.js} +1 -1
  56. package/dist/gateway/static/root/assets/{locale-store-msTfRK8P.js → locale-store-DPZ79W1-.js} +1 -1
  57. package/dist/gateway/static/root/assets/{logs-page-C0n66FiO.js → logs-page-egGcPHNi.js} +1 -1
  58. package/dist/gateway/static/root/assets/{management-settings-i6GhxpGV.js → management-settings-BQhIOELc.js} +1 -1
  59. package/dist/gateway/static/root/assets/{markdown-view-BInabSKf.js → markdown-view-p2P5hP1U.js} +1 -1
  60. package/dist/gateway/static/root/assets/{media-plugins-CnWChQ3Y.js → media-plugins-CsBylqlN.js} +1 -1
  61. package/dist/gateway/static/root/assets/messages-BiYTyLJr.js +3 -0
  62. package/dist/gateway/static/root/assets/{note-detail-panel-C59d8vDW.js → note-detail-panel-c2k5Uz6X.js} +3 -3
  63. package/dist/gateway/static/root/assets/{notes-page-C1GBPrVI.js → notes-page-BLQWJMhf.js} +1 -1
  64. package/dist/gateway/static/root/assets/{page-tabs-BWitjb3e.js → page-tabs-ChQ4jJFs.js} +1 -1
  65. package/dist/gateway/static/root/assets/{preview-open-alternatives-UaCWCxZv.js → preview-open-alternatives-9B5W7nVE.js} +1 -1
  66. package/dist/gateway/static/root/assets/{proactive-page-CtSFJxoM.js → proactive-page-iOjI0d_e.js} +1 -1
  67. package/dist/gateway/static/root/assets/{product-open-page-gmi5LLwM.js → product-open-page-BADxWEdP.js} +1 -1
  68. package/dist/gateway/static/root/assets/{project-detail-page-ILTmQ1YN.js → project-detail-page-BcxbQn2M.js} +1 -1
  69. package/dist/gateway/static/root/assets/{projects-page-snl4rOQZ.js → projects-page-BuSvld0O.js} +1 -1
  70. package/dist/gateway/static/root/assets/{registry-api-BSWtko7U.js → registry-api-B_e_nZSN.js} +1 -1
  71. package/dist/gateway/static/root/assets/{remote-access-hub-BbaAcEN3.js → remote-access-hub-CFS8LQKW.js} +1 -1
  72. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CtOjKGWg.js → runtime-tools-settings-panel-D-pwiIyp.js} +1 -1
  73. package/dist/gateway/static/root/assets/{schema-form-DkyyDcl2.js → schema-form-IWmb05DX.js} +1 -1
  74. package/dist/gateway/static/root/assets/{sessions-page-DrWL71O8.js → sessions-page-DZjc__ok.js} +1 -1
  75. package/dist/gateway/static/root/assets/settings-advanced-gate-C1SM5B93.js +1 -0
  76. package/dist/gateway/static/root/assets/{settings-form-section-C0JDGN_V.js → settings-form-section-B0veRBZs.js} +1 -1
  77. package/dist/gateway/static/root/assets/{settings-page-DiIyMQ52.js → settings-page-CxRWyWYe.js} +1 -1
  78. package/dist/gateway/static/root/assets/{setup-status-panel-EPazhoZO.js → setup-status-panel-D9Rl7Tec.js} +1 -1
  79. package/dist/gateway/static/root/assets/{share-preview-page-Bt1K657Y.js → share-preview-page-CirpgkfD.js} +1 -1
  80. package/dist/gateway/static/root/assets/{shares-settings-g2MdRXSZ.js → shares-settings-CwCThBs0.js} +1 -1
  81. package/dist/gateway/static/root/assets/skill-reload-api-DG6VGbOX.js +1 -0
  82. package/dist/gateway/static/root/assets/{skills-page-Wd0uYSPG.js → skills-page-BdRJ2vnL.js} +1 -1
  83. package/dist/gateway/static/root/assets/{skills-page.utils-vq5Ujm03.js → skills-page.utils-B42mpWKV.js} +1 -1
  84. package/dist/gateway/static/root/assets/{system-settings-panel-Cz1P-HDH.js → system-settings-panel-DXIZpAvU.js} +1 -1
  85. package/dist/gateway/static/root/assets/{task-detail-page-BG3A5gPZ.js → task-detail-page-QXo9LJly.js} +1 -1
  86. package/dist/gateway/static/root/assets/{theme-store-1SZ-HFHX.js → theme-store-BFbj_2Tu.js} +1 -1
  87. package/dist/gateway/static/root/assets/{tunnel-api-DQGoFuZO.js → tunnel-api-Db2guRdW.js} +1 -1
  88. package/dist/gateway/static/root/assets/{use-autosave-DVDlBb95.js → use-autosave-DDY9qoXZ.js} +1 -1
  89. package/dist/gateway/static/root/assets/{user-model-page-qM5UiTGx.js → user-model-page-CzPmMkaO.js} +1 -1
  90. package/dist/gateway/static/root/assets/{voice-api-key-field-B2pZCcxY.js → voice-api-key-field-BZbKQ8HT.js} +1 -1
  91. package/dist/gateway/static/root/assets/{voice-config-api-DgJML_uM.js → voice-config-api-SKCeQLrH.js} +1 -1
  92. package/dist/gateway/static/root/assets/{work-discovery-overlay-Bptv7bEY.js → work-discovery-overlay-BRVTTXNG.js} +1 -1
  93. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BijCrNc4.js → workflow-run-setup-panel-D2kuwv5e.js} +1 -1
  94. package/dist/gateway/static/root/assets/{workflows-page-DRy1RAYH.js → workflows-page-CQXtiYtq.js} +1 -1
  95. package/dist/gateway/static/root/index.html +12 -12
  96. package/dist/package.js +1 -1
  97. package/dist/packages/gateway-contract/src/sessions.js +6 -1
  98. package/dist/src/agent/agent-manager.js +29 -4
  99. package/dist/src/agent/child-agent-factory.d.ts +1 -0
  100. package/dist/src/agent/child-agent-factory.js +18 -4
  101. package/dist/src/agent/coding/repository-instructions.d.ts +4 -0
  102. package/dist/src/agent/coding/repository-instructions.js +46 -2
  103. package/dist/src/agent/data-acquisition/git.d.ts +17 -0
  104. package/dist/src/agent/data-acquisition/git.js +100 -0
  105. package/dist/src/agent/data-acquisition/render.d.ts +7 -0
  106. package/dist/src/agent/data-acquisition/render.js +79 -0
  107. package/dist/src/agent/data-acquisition/scheduler.d.ts +12 -0
  108. package/dist/src/agent/data-acquisition/scheduler.js +53 -0
  109. package/dist/src/agent/data-acquisition/schema.d.ts +75 -0
  110. package/dist/src/agent/data-acquisition/schema.js +206 -0
  111. package/dist/src/agent/data-acquisition/service.d.ts +10 -0
  112. package/dist/src/agent/data-acquisition/service.js +292 -0
  113. package/dist/src/agent/data-acquisition/types.d.ts +37 -0
  114. package/dist/src/agent/data-acquisition/types.js +5 -0
  115. package/dist/src/agent/embedded/run-turn.js +16 -4
  116. package/dist/src/agent/embedded/session-runner.d.ts +1 -0
  117. package/dist/src/agent/embedded/session-runner.js +3 -0
  118. package/dist/src/agent/embedded/tool-result-truncation.js +11 -0
  119. package/dist/src/agent/embedded/xopc-tools-bridge.js +2 -1
  120. package/dist/src/agent/external-tools/composio-provider.js +12 -1
  121. package/dist/src/agent/external-tools/gateway-tools.js +2 -1
  122. package/dist/src/agent/external-tools/index.js +8 -1
  123. package/dist/src/agent/external-tools/read-policy.d.ts +6 -0
  124. package/dist/src/agent/external-tools/read-policy.js +21 -0
  125. package/dist/src/agent/external-tools/service.d.ts +1 -0
  126. package/dist/src/agent/external-tools/service.js +4 -1
  127. package/dist/src/agent/external-tools/types.d.ts +2 -0
  128. package/dist/src/agent/orchestration/agent-turn-policy.js +25 -10
  129. package/dist/src/agent/orchestration/delegation-scope.d.ts +9 -0
  130. package/dist/src/agent/orchestration/delegation-scope.js +11 -0
  131. package/dist/src/agent/prompt/sections/tooling.js +3 -1
  132. package/dist/src/agent/prompt/subagent-context.js +4 -2
  133. package/dist/src/agent/sandbox/fileAccess.d.ts +2 -0
  134. package/dist/src/agent/sandbox/fileAccess.js +31 -2
  135. package/dist/src/agent/tools/dataBatch.d.ts +4 -0
  136. package/dist/src/agent/tools/dataBatch.js +50 -0
  137. package/dist/src/agent/tools/delegate-tool.d.ts +6 -3
  138. package/dist/src/agent/tools/delegate-tool.js +65 -48
  139. package/dist/src/agent/tools/delegation-parent-policy.d.ts +7 -0
  140. package/dist/src/agent/tools/delegation-parent-policy.js +41 -0
  141. package/dist/src/agent/tools/delegation-policy.d.ts +16 -0
  142. package/dist/src/agent/tools/delegation-policy.js +93 -0
  143. package/dist/src/agent/tools/factory.d.ts +2 -0
  144. package/dist/src/agent/tools/factory.js +42 -3
  145. package/dist/src/agent/tools/fetch-text.d.ts +7 -0
  146. package/dist/src/agent/tools/fetch-text.js +86 -0
  147. package/dist/src/agent/tools/find.js +1 -1
  148. package/dist/src/agent/tools/grep.js +11 -23
  149. package/dist/src/agent/tools/index.d.ts +1 -0
  150. package/dist/src/agent/tools/index.js +2 -1
  151. package/dist/src/agent/tools/knowledge-memory-tool.js +10 -2
  152. package/dist/src/agent/tools/read.js +7 -5
  153. package/dist/src/agent/tools/repository-search.d.ts +12 -2
  154. package/dist/src/agent/tools/repository-search.js +127 -74
  155. package/dist/src/agent/tools/web.js +19 -28
  156. package/dist/src/agent/workflow/subagent-runner.js +25 -3
  157. package/dist/src/agent/workflow/workflow-child-tools.js +13 -8
  158. package/dist/src/agent-config/schema.d.ts +7 -0
  159. package/dist/src/agent-config/schema.js +2 -0
  160. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  161. package/dist/src/config/schema.d.ts +4 -0
  162. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  163. package/dist/src/gateway/heartbeat/service.js +2 -2
  164. package/dist/src/gateway/hono/lib/config-payload.d.ts +2 -0
  165. package/dist/src/gateway/hono/routes/sessions.js +141 -13
  166. package/dist/src/heartbeat/index.js +1 -1
  167. package/dist/src/storage/sqlite/index.d.ts +1 -0
  168. package/dist/src/storage/sqlite/index.js +2 -1
  169. package/dist/src/storage/sqlite/migrations/186_sidebar_layout.sql +16 -0
  170. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  171. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  172. package/dist/src/storage/sqlite/schema.js +1 -1
  173. package/dist/src/storage/sqlite/sidebar-layout-repository.d.ts +12 -0
  174. package/dist/src/storage/sqlite/sidebar-layout-repository.js +53 -0
  175. package/package.json +3 -3
  176. package/dist/gateway/static/root/assets/api-DFOlahZv.js +0 -1
  177. package/dist/gateway/static/root/assets/gateway-realtime-store-BLDgrJ30.js +0 -1
  178. package/dist/gateway/static/root/assets/index-CRu1p38D.css +0 -1
  179. package/dist/gateway/static/root/assets/messages-F74LVAiU.js +0 -3
  180. package/dist/gateway/static/root/assets/settings-advanced-gate-BG0kl4HT.js +0 -1
  181. package/dist/gateway/static/root/assets/skill-reload-api-B1DPzu98.js +0 -1
@@ -1,84 +1,137 @@
1
1
  import { prepareSafeToolEnv } from "../sandbox/sanitize-env-vars.js";
2
2
  import { evaluateFilePolicy } from "../sandbox/exec-policy.js";
3
+ import { dataScheduler } from "../data-acquisition/scheduler.js";
3
4
  import { resolveRipgrepBinary } from "../../infra/ripgrep.js";
4
5
  import { lstatSync } from "node:fs";
5
6
  import { spawn } from "node:child_process";
7
+ import { StringDecoder } from "node:string_decoder";
6
8
  //#region src/agent/tools/repository-search.ts
7
- /** Bounded native search; unavailable tools and invalid regexes are explicit failures. */
8
- async function repositorySearch(cwd, args, signal) {
9
- signal?.throwIfAborted();
10
- const binary = await resolveRipgrepBinary();
11
- return new Promise((resolve, reject) => {
12
- const separator = args.indexOf("--");
13
- const options = separator < 0 ? args : args.slice(0, separator);
14
- const targets = separator < 0 ? [] : args.slice(separator);
15
- const excluded = [
16
- ".git",
17
- "node_modules",
18
- ".env",
19
- ".env.*",
20
- ".ssh",
21
- ".aws",
22
- ".gnupg",
23
- ".docker",
24
- ".config",
25
- ".netrc",
26
- ".npmrc",
27
- ".cargo/credentials",
28
- ".kube",
29
- ".xopc"
30
- ];
31
- const child = spawn(binary, [
32
- "--no-config",
33
- "--hidden",
34
- ...options,
35
- ...excluded.flatMap((path) => [
36
- "--glob",
37
- `!**/${path}`,
38
- "--glob",
39
- `!**/${path}/**`
40
- ]),
41
- "--no-follow",
42
- ...targets
43
- ], {
44
- cwd,
45
- env: prepareSafeToolEnv(process.env)
46
- });
47
- const chunks = [];
48
- let bytes = 0, truncated = false, stderr = "";
49
- const timer = setTimeout(() => child.kill("SIGKILL"), 1e4);
50
- const abort = () => child.kill("SIGKILL");
51
- signal?.addEventListener("abort", abort, { once: true });
52
- child.stdout.on("data", (chunk) => {
53
- const remaining = Math.max(0, 5e4 - bytes);
54
- chunks.push(chunk.subarray(0, remaining));
55
- bytes += chunk.length;
56
- if (bytes > 5e4) {
57
- truncated = true;
58
- child.kill("SIGKILL");
59
- }
60
- });
61
- child.stderr.on("data", (chunk) => {
62
- stderr = (stderr + String(chunk)).slice(-4e3);
63
- });
64
- child.on("error", reject);
65
- child.on("close", (code) => {
66
- clearTimeout(timer);
67
- signal?.removeEventListener("abort", abort);
68
- if (signal?.aborted) {
69
- reject(signal.reason ?? /* @__PURE__ */ new Error("Search aborted"));
70
- return;
71
- }
72
- if (code !== 0 && code !== 1 && !truncated) {
73
- reject(new Error(stderr || "Search did not complete; check ripgrep installation or narrow the search."));
74
- return;
75
- }
76
- resolve({
77
- output: Buffer.concat(chunks).toString("utf8"),
78
- truncated
9
+ function parseRepositoryMatch(workspace, line) {
10
+ if (!line) return void 0;
11
+ const event = JSON.parse(line);
12
+ if (event.type !== "match" && event.type !== "context") return void 0;
13
+ const data = event.data;
14
+ if (typeof data?.path?.text !== "string" || typeof data.lines?.text !== "string" || !Number.isInteger(data.line_number) || !isSearchFileAllowed(workspace, data.path.text)) return void 0;
15
+ return {
16
+ path: data.path.text,
17
+ line: data.line_number,
18
+ text: data.lines.text.replace(/\r?\n$/, ""),
19
+ match: event.type === "match"
20
+ };
21
+ }
22
+ /** One bounded process path for raw filename output and streamed JSON events. */
23
+ async function repositorySearch(cwd, args, signal, options = {}) {
24
+ const deadline = AbortSignal.any([...signal ? [signal] : [], AbortSignal.timeout(1e4)]);
25
+ return dataScheduler.run(cwd, deadline, async () => {
26
+ deadline.throwIfAborted();
27
+ const binary = await resolveRipgrepBinary();
28
+ deadline.throwIfAborted();
29
+ return new Promise((resolve, reject) => {
30
+ const separator = args.indexOf("--");
31
+ const searchOptions = separator < 0 ? args : args.slice(0, separator);
32
+ const targets = separator < 0 ? [] : args.slice(separator);
33
+ const excluded = [
34
+ ".git",
35
+ "node_modules",
36
+ ".env",
37
+ ".env.*",
38
+ ".ssh",
39
+ ".aws",
40
+ ".gnupg",
41
+ ".docker",
42
+ ".config",
43
+ ".netrc",
44
+ ".npmrc",
45
+ ".cargo/credentials",
46
+ ".kube",
47
+ ".xopc"
48
+ ];
49
+ const child = spawn(binary, [
50
+ "--no-config",
51
+ "--hidden",
52
+ ...searchOptions,
53
+ ...excluded.flatMap((path) => [
54
+ "--glob",
55
+ `!**/${path}`,
56
+ "--glob",
57
+ `!**/${path}/**`
58
+ ]),
59
+ "--no-follow",
60
+ ...targets
61
+ ], {
62
+ cwd,
63
+ env: prepareSafeToolEnv(process.env)
64
+ });
65
+ const chunks = [];
66
+ const decoder = new StringDecoder("utf8");
67
+ let bytes = 0, truncated = false, stderr = "", pending = "";
68
+ let failure;
69
+ const stop = () => child.kill("SIGKILL");
70
+ const consume = (text) => {
71
+ pending += text;
72
+ let newline;
73
+ while (!truncated && (newline = pending.indexOf("\n")) !== -1) {
74
+ const line = pending.slice(0, newline);
75
+ pending = pending.slice(newline + 1);
76
+ if (options.onLine?.(line) === false) {
77
+ truncated = true;
78
+ stop();
79
+ }
80
+ }
81
+ };
82
+ deadline.addEventListener("abort", stop, { once: true });
83
+ child.stdout.on("data", (chunk) => {
84
+ if (truncated || failure) return;
85
+ const remaining = Math.max(0, (options.maxBytes ?? 5e4) - bytes);
86
+ const selected = chunk.subarray(0, remaining);
87
+ bytes += chunk.length;
88
+ try {
89
+ if (options.onLine) consume(decoder.write(selected));
90
+ else chunks.push(selected);
91
+ } catch (error) {
92
+ failure = error instanceof Error ? error : new Error(String(error));
93
+ stop();
94
+ }
95
+ if (bytes > (options.maxBytes ?? 5e4)) {
96
+ truncated = true;
97
+ stop();
98
+ }
99
+ });
100
+ child.stderr.on("data", (chunk) => {
101
+ stderr = (stderr + String(chunk)).slice(-4e3);
102
+ });
103
+ child.on("error", (error) => {
104
+ failure = error;
105
+ });
106
+ child.on("close", (code) => {
107
+ deadline.removeEventListener("abort", stop);
108
+ if (deadline.aborted) {
109
+ reject(deadline.reason);
110
+ return;
111
+ }
112
+ if (failure) {
113
+ reject(failure);
114
+ return;
115
+ }
116
+ if (code !== 0 && code !== 1 && !truncated) {
117
+ reject(new Error(stderr || "Search did not complete; narrow the search."));
118
+ return;
119
+ }
120
+ try {
121
+ if (options.onLine && !truncated) {
122
+ consume(decoder.end());
123
+ if (pending && options.onLine(pending) === false) truncated = true;
124
+ }
125
+ resolve({
126
+ output: Buffer.concat(chunks).toString("utf8"),
127
+ truncated
128
+ });
129
+ } catch (error) {
130
+ reject(error);
131
+ }
79
132
  });
133
+ if (deadline.aborted) stop();
80
134
  });
81
- if (signal?.aborted) abort();
82
135
  });
83
136
  }
84
137
  /** Search results must satisfy the same policy as direct file reads. */
@@ -97,4 +150,4 @@ function isSearchFileAllowed(workspace, path) {
97
150
  }
98
151
  }
99
152
  //#endregion
100
- export { isSearchFileAllowed, repositorySearch };
153
+ export { isSearchFileAllowed, parseRepositoryMatch, repositorySearch };
@@ -1,6 +1,6 @@
1
1
  import { SearchProviderRegistry } from "./search/registry.js";
2
2
  import { resolveWebSearchConfig } from "./search/resolve-config.js";
3
- import { checkUrlSafety, checkWebsiteBlocklist } from "./url-safety.js";
3
+ import { fetchPublicText } from "./fetch-text.js";
4
4
  import { Type } from "@sinclair/typebox";
5
5
  //#region src/agent/tools/web.ts
6
6
  const WebSearchSchema = Type.Object({
@@ -16,6 +16,7 @@ function createWebSearchTool(getConfig) {
16
16
  description: "Search the web. Uses configured search APIs when set; otherwise falls back to a built-in HTML search (region-aware).",
17
17
  parameters: WebSearchSchema,
18
18
  label: "🔍 Web Search",
19
+ supportsParallel: true,
19
20
  async execute(_toolCallId, params, signal) {
20
21
  const p = params;
21
22
  const cfg = resolveWebSearchConfig(getConfig()?.tools?.web);
@@ -49,13 +50,15 @@ function createWebSearchTool(getConfig) {
49
50
  type: "text",
50
51
  text: `Search error: ${error instanceof Error ? error.message : String(error)}`
51
52
  }],
52
- details: { results: [] }
53
+ details: {
54
+ results: [],
55
+ error: error instanceof Error ? error.message : String(error)
56
+ }
53
57
  };
54
58
  }
55
59
  }
56
60
  };
57
61
  }
58
- const MAX_FETCH_CHARS = 6e6;
59
62
  const WebFetchSchema = Type.Object({
60
63
  url: Type.String({ description: "The URL to fetch" }),
61
64
  maxChars: Type.Optional(Type.Number({ description: "Maximum characters to return (default: 10000)" }))
@@ -76,47 +79,35 @@ function createWebFetchTool(getConfig) {
76
79
  description: "Fetch and extract readable content from a URL (HTML via Readability; plain text as-is).",
77
80
  parameters: WebFetchSchema,
78
81
  label: "🌐 Web Fetch",
82
+ supportsParallel: true,
79
83
  async execute(_toolCallId, params, signal) {
80
84
  try {
81
85
  const p = params;
82
- const safety = checkUrlSafety(p.url);
83
- if (!safety.safe) return {
84
- content: [{
85
- type: "text",
86
- text: `Blocked: ${safety.reason}`
87
- }],
88
- details: {}
89
- };
90
- const blocked = checkWebsiteBlocklist(p.url, getConfig()?.tools?.web?.blocklist);
91
- if (blocked) return {
92
- content: [{
93
- type: "text",
94
- text: `Blocked: ${blocked.message}`
95
- }],
96
- details: {}
97
- };
98
- const response = await fetch(p.url, { signal });
99
- if (!response.ok) throw new Error(`HTTP ${response.status}`);
100
- const html = await response.text();
101
- if (html.length > MAX_FETCH_CHARS) throw new Error("Response too large");
86
+ const fetched = await fetchPublicText(p.url, getConfig()?.tools?.web?.blocklist, signal);
87
+ const html = fetched.text;
102
88
  const maxChars = p.maxChars || 1e4;
103
- const contentType = response.headers.get("content-type") ?? "";
89
+ const contentType = fetched.contentType;
104
90
  const looksHtml = /html|xml/i.test(contentType) || /^[\s\n]*</.test(html.slice(0, Math.min(500, html.length)));
105
91
  let text;
106
92
  if (looksHtml) try {
107
- text = await extractReadableText(html, p.url);
93
+ text = await extractReadableText(html, fetched.url);
108
94
  if (!text || text.length < 40) text = stripHtmlFallback(html);
109
95
  } catch {
110
96
  text = stripHtmlFallback(html);
111
97
  }
112
98
  else text = html.trim();
113
- if (text.length > maxChars) text = text.substring(0, maxChars) + "\n\n[truncated...]";
99
+ const truncated = text.length > maxChars;
100
+ if (truncated) text = text.substring(0, maxChars) + "\n\n[truncated...]";
114
101
  return {
115
102
  content: [{
116
103
  type: "text",
117
104
  text
118
105
  }],
119
- details: {}
106
+ details: {
107
+ truncated,
108
+ complete: !truncated,
109
+ url: fetched.url
110
+ }
120
111
  };
121
112
  } catch (error) {
122
113
  return {
@@ -124,7 +115,7 @@ function createWebFetchTool(getConfig) {
124
115
  type: "text",
125
116
  text: `Fetch error: ${error instanceof Error ? error.message : String(error)}`
126
117
  }],
127
- details: {}
118
+ details: { error: error instanceof Error ? error.message : String(error) }
128
119
  };
129
120
  }
130
121
  }
@@ -2,7 +2,9 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { createSqliteTranscriptRuntime } from "../embedded/transcript-runtime.js";
4
4
  import { createDelegateChildHandle } from "../child-agent-factory.js";
5
- import { DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS } from "../tools/delegate-tool.js";
5
+ import { DELEGATION_TOOL_CAPABILITIES, protectDelegatedTool, resolveDelegationTools } from "../tools/delegation-policy.js";
6
+ import { DELEGATE_BLOCKED_TOOLS } from "../tools/delegate-tool.js";
7
+ import { createDelegationParentPolicy } from "../tools/delegation-parent-policy.js";
6
8
  import { STRUCTURED_OUTPUT_TOOL_NAME, createStructuredOutputTool } from "./structured-output-tool.js";
7
9
  //#region src/agent/workflow/subagent-runner.ts
8
10
  init_logger();
@@ -38,11 +40,27 @@ var DelegateSubagentRunner = class {
38
40
  agentId: this.deps.agentId,
39
41
  getConfig: this.deps.getConfig,
40
42
  toolExecutorConfig: this.deps.toolExecutorConfig,
43
+ authorizeToolCall: createDelegationParentPolicy({
44
+ getConfig: this.deps.getConfig,
45
+ conversationId: opts.sessionMetadata?.parentConversationId,
46
+ agentId: this.deps.agentId
47
+ }).beforeToolCall,
41
48
  buildChildTools: (childOpts) => {
42
- const base = this.deps.buildChildTools({
49
+ const candidates = this.deps.buildChildTools({
43
50
  ...childOpts,
44
51
  agentId: this.deps.agentId ?? childOpts.agentId
45
52
  });
53
+ const access = resolveDelegationTools(candidates.map((tool) => tool.name), "custom", opts.allowedToolNames, [
54
+ "local_read",
55
+ "web_read",
56
+ "knowledge_read",
57
+ "skills_read",
58
+ "external_read",
59
+ ...opts.allowedToolNames?.includes("browser_use") ? ["browser"] : []
60
+ ]);
61
+ if (access.rejected.length) throw new Error(`Workflow delegation rejected tools: ${JSON.stringify(access.rejected)}. Use delegate_task implement for isolated writes and commands.`);
62
+ const granted = new Set(access.granted);
63
+ const base = candidates.filter((tool) => granted.has(tool.name)).map(protectDelegatedTool);
46
64
  if (!wantStructured || !opts.schema) return base;
47
65
  return [...base.filter((t) => t.name !== STRUCTURED_OUTPUT_TOOL_NAME), createStructuredOutputTool({
48
66
  schema: opts.schema,
@@ -129,7 +147,11 @@ var DelegateSubagentRunner = class {
129
147
  }
130
148
  };
131
149
  function resolveAllowedToolNames(requested, wantStructured) {
132
- const filtered = (requested ?? [...DEFAULT_DELEGATE_TOOLS]).map((s) => String(s).trim()).filter((s) => s.length > 0).filter((s) => !DELEGATE_BLOCKED_TOOLS.has(s));
150
+ const filtered = (requested ?? Object.keys(DELEGATION_TOOL_CAPABILITIES).filter((name) => ![
151
+ "local_write",
152
+ "command",
153
+ "browser"
154
+ ].includes(DELEGATION_TOOL_CAPABILITIES[name]))).map((s) => String(s).trim()).filter((s) => s.length > 0).filter((s) => !DELEGATE_BLOCKED_TOOLS.has(s));
133
155
  if (wantStructured && !filtered.includes("structured_output")) filtered.push(STRUCTURED_OUTPUT_TOOL_NAME);
134
156
  return [...new Set(filtered)];
135
157
  }
@@ -1,13 +1,22 @@
1
- import { EXTERNAL_TOOL_NAMES } from "../external-tools/gateway-tools.js";
2
- import "../external-tools/index.js";
1
+ import { resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
2
  import { AgentToolsFactory } from "../tools/factory.js";
4
3
  //#region src/agent/workflow/workflow-child-tools.ts
5
4
  /** Builds the tool set for workflow child agents (wired from gateway to avoid cycles). */
6
5
  function buildWorkflowChildTools(childOptions) {
6
+ const config = childOptions.getConfig();
7
+ const profile = config ? childOptions.browserConversationId ? resolveEffectiveAgentProfileForSession(config, childOptions.browserConversationId) : childOptions.agentId ? resolveEffectiveAgentProfile(config, childOptions.agentId) : resolveEffectiveAgentProfileForSession(config, void 0) : void 0;
7
8
  return new AgentToolsFactory({
8
9
  workspace: childOptions.workspace,
9
10
  bus: childOptions.bus,
10
- getCurrentContext: () => null,
11
+ getCurrentContext: () => childOptions.browserConversationId ? {
12
+ conversationId: childOptions.browserConversationId,
13
+ channel: "workflow",
14
+ chatId: childOptions.browserConversationId,
15
+ origin: {
16
+ type: "system",
17
+ source: "workflow"
18
+ }
19
+ } : null,
11
20
  getConfig: childOptions.getConfig,
12
21
  getPrimaryModel: () => childOptions.model,
13
22
  endpointTools: childOptions.endpointTools,
@@ -17,11 +26,7 @@ function buildWorkflowChildTools(childOptions) {
17
26
  getPrimaryModel: () => childOptions.model,
18
27
  agentId: childOptions.agentId,
19
28
  conversationId: childOptions.browserConversationId,
20
- disabledTools: new Set([
21
- EXTERNAL_TOOL_NAMES.search,
22
- EXTERNAL_TOOL_NAMES.describe,
23
- EXTERNAL_TOOL_NAMES.execute
24
- ])
29
+ disabledTools: profile?.tools.denied
25
30
  });
26
31
  }
27
32
  //#endregion
@@ -96,6 +96,7 @@ export declare const ToolPolicySchema: z.ZodObject<{
96
96
  deny: "deny";
97
97
  ask: "ask";
98
98
  }>;
99
+ readOnly: z.ZodOptional<z.ZodBoolean>;
99
100
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
100
101
  timeoutMs: z.ZodOptional<z.ZodNumber>;
101
102
  }, z.core.$strict>;
@@ -105,6 +106,7 @@ export declare const ToolPoliciesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
105
106
  deny: "deny";
106
107
  ask: "ask";
107
108
  }>;
109
+ readOnly: z.ZodOptional<z.ZodBoolean>;
108
110
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
109
111
  timeoutMs: z.ZodOptional<z.ZodNumber>;
110
112
  }, z.core.$strict>>;
@@ -198,6 +200,7 @@ export declare const AgentDefaultsSchema: z.ZodObject<{
198
200
  deny: "deny";
199
201
  ask: "ask";
200
202
  }>;
203
+ readOnly: z.ZodOptional<z.ZodBoolean>;
201
204
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
202
205
  timeoutMs: z.ZodOptional<z.ZodNumber>;
203
206
  }, z.core.$strict>>>;
@@ -289,6 +292,7 @@ export declare const AgentEntrySchema: z.ZodObject<{
289
292
  deny: "deny";
290
293
  ask: "ask";
291
294
  }>;
295
+ readOnly: z.ZodOptional<z.ZodBoolean>;
292
296
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
293
297
  timeoutMs: z.ZodOptional<z.ZodNumber>;
294
298
  }, z.core.$strict>>>;
@@ -370,6 +374,7 @@ export declare const AgentsConfigSchema: z.ZodObject<{
370
374
  deny: "deny";
371
375
  ask: "ask";
372
376
  }>;
377
+ readOnly: z.ZodOptional<z.ZodBoolean>;
373
378
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
374
379
  timeoutMs: z.ZodOptional<z.ZodNumber>;
375
380
  }, z.core.$strict>>>;
@@ -457,6 +462,7 @@ export declare const AgentsConfigSchema: z.ZodObject<{
457
462
  deny: "deny";
458
463
  ask: "ask";
459
464
  }>;
465
+ readOnly: z.ZodOptional<z.ZodBoolean>;
460
466
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
461
467
  timeoutMs: z.ZodOptional<z.ZodNumber>;
462
468
  }, z.core.$strict>>>;
@@ -544,6 +550,7 @@ export declare const EffectiveAgentConfigSchema: z.ZodObject<{
544
550
  deny: "deny";
545
551
  ask: "ask";
546
552
  }>;
553
+ readOnly: z.ZodOptional<z.ZodBoolean>;
547
554
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
548
555
  timeoutMs: z.ZodOptional<z.ZodNumber>;
549
556
  }, z.core.$strict>>;
@@ -49,6 +49,8 @@ var init_schema = __esmMin((() => {
49
49
  ]);
50
50
  ToolPolicySchema = z.object({
51
51
  mode: ToolModeSchema,
52
+ /** Host assertion for external tools; remote annotations alone cannot grant read access. */
53
+ readOnly: z.boolean().optional(),
52
54
  maxCallsPerTurn: z.number().int().positive().optional(),
53
55
  timeoutMs: z.number().int().positive().optional()
54
56
  }).strict();
@@ -53,7 +53,7 @@ async function checkDatabaseSchema(ctx) {
53
53
  id: "database-schema",
54
54
  label: "Database schema",
55
55
  status: "pass",
56
- message: `SQLite schema v${status.dbVersion} (current release v185).`,
56
+ message: `SQLite schema v${status.dbVersion} (current release v186).`,
57
57
  hints: []
58
58
  };
59
59
  }
@@ -100,6 +100,7 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
100
100
  deny: "deny";
101
101
  ask: "ask";
102
102
  }>;
103
+ readOnly: z.ZodOptional<z.ZodBoolean>;
103
104
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
104
105
  timeoutMs: z.ZodOptional<z.ZodNumber>;
105
106
  }, z.core.$strict>>>;
@@ -187,6 +188,7 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
187
188
  deny: "deny";
188
189
  ask: "ask";
189
190
  }>;
191
+ readOnly: z.ZodOptional<z.ZodBoolean>;
190
192
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
191
193
  timeoutMs: z.ZodOptional<z.ZodNumber>;
192
194
  }, z.core.$strict>>>;
@@ -1610,6 +1612,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1610
1612
  deny: "deny";
1611
1613
  ask: "ask";
1612
1614
  }>;
1615
+ readOnly: z.ZodOptional<z.ZodBoolean>;
1613
1616
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
1614
1617
  timeoutMs: z.ZodOptional<z.ZodNumber>;
1615
1618
  }, z.core.$strict>>>;
@@ -1697,6 +1700,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1697
1700
  deny: "deny";
1698
1701
  ask: "ask";
1699
1702
  }>;
1703
+ readOnly: z.ZodOptional<z.ZodBoolean>;
1700
1704
  maxCallsPerTurn: z.ZodOptional<z.ZodNumber>;
1701
1705
  timeoutMs: z.ZodOptional<z.ZodNumber>;
1702
1706
  }, z.core.$strict>>>;
@@ -277,4 +277,4 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
277
277
  readonly zh: "使用已验证的参数执行选定的外部工具。";
278
278
  };
279
279
  }];
280
- export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "xopc_tool_execute" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "computer_use" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
280
+ export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "user_context_search" | "user_context_get" | "user_context_update" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "xopc_tool_execute" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "computer_use" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
@@ -4,11 +4,11 @@ import { init_agent_scope, resolveDefaultAgentId } from "../../agent/agent-scope
4
4
  import { createConversation, init_conversation_repository, resolveRoutedConversation } from "../../storage/sqlite/conversation-repository.js";
5
5
  import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
6
6
  import { proactiveChecksAllowed, proactivePreferences } from "../../proactive/policy/service.js";
7
+ import { beginHeartbeatCheck, completeHeartbeatCheck, deliverHeartbeatChecks, recentHeartbeatChecks, recoverHeartbeatChecks } from "./check-store.js";
8
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
9
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
8
10
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
9
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
10
11
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
11
- import { beginHeartbeatCheck, completeHeartbeatCheck, deliverHeartbeatChecks, recentHeartbeatChecks, recoverHeartbeatChecks } from "./check-store.js";
12
12
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
13
13
  import { readFile } from "fs/promises";
14
14
  //#region src/gateway/heartbeat/service.ts
@@ -49,6 +49,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
49
49
  };
50
50
  tools: Record<string, {
51
51
  mode: "allow" | "deny" | "ask";
52
+ readOnly?: boolean;
52
53
  maxCallsPerTurn?: number;
53
54
  timeoutMs?: number;
54
55
  }>;
@@ -99,6 +100,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
99
100
  };
100
101
  tools: Record<string, {
101
102
  mode: "allow" | "deny" | "ask";
103
+ readOnly?: boolean;
102
104
  maxCallsPerTurn?: number;
103
105
  timeoutMs?: number;
104
106
  }>;