@xopcai/xopc 0.0.243 → 0.0.245

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 (202) 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-CAah-_8h.js → activity-store-BlxqErph.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DDH4HgP7.js → agent-avatar-dicebear-DRQnogaU.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BDCfJZhh.js → agent-defaults-settings-panel-CpOxGbMD.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-B0ZWgf-U.js → agents-flnXZLaT.js} +1 -1
  7. package/dist/gateway/static/root/assets/{api-B2tKxbcz.js → api-BbXzyQMj.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-Blfwszzn.js → app-management-settings-panel-CZl6n2xi.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-C3V7Na75.js → appearance-settings-Bglp-pn6.js} +1 -1
  10. package/dist/gateway/static/root/assets/{apps-page-BiEks0-F.js → apps-page-CmsWarVB.js} +1 -1
  11. package/dist/gateway/static/root/assets/{archive-plugin-BmSx7wzY.js → archive-plugin-DD2SweEH.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-BS-S4LJ9.js → attachment-load-G0HenUmG.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-C7Y3L30D.js → automations-page-B78bFjH2.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-workspace-A3zPkPuo.js → automations-workspace-BMQGmn50.js} +1 -1
  15. package/dist/gateway/static/root/assets/{binary-plugins-BM9B5kcm.js → binary-plugins-BbSQmXqn.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-BbnpkYP9.js → block-editor-DutTIH81.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-settings-page-Dk4FQ7fY.js → browser-settings-page-CALiFKm4.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-CRnkgZHI.js → browser-workflow-inputs-BAAc151l.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-B9qGL-it.js → browser-workflows-page-DE5HPrHZ.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capabilities-settings-panel--tR_El9e.js → capabilities-settings-panel-Dts7XtP3.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-settings-D347vl_J.js → channels-settings-CWEd3wzh.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-status-swr-DuY4MGxe.js → channels-status-swr-CCBCtLDg.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-DABPvwBT.js → chat-terminal-dock-Bp1fXQm1.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connectors-page-B-tvJkRJ.js → connectors-page-CQ6wVNLm.js} +1 -1
  25. package/dist/gateway/static/root/assets/{cron-expression-D3bsKbNd.js → cron-expression-B8HA5IRb.js} +1 -1
  26. package/dist/gateway/static/root/assets/{date-picker-BsGM6Yty.js → date-picker-DD8b7oad.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-Dj3g6YXZ.js → dependency-picker-BC9zwIyH.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-C1QT0Sur.js → desktop-pet-DsrsPZTW.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-r6kAOnfY.js → desktop-pet-settings-D7gp_HNA.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-debug-page-DOkf7nh9.js → extension-debug-page-BoKbOX7x.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-Cq2IA4Ho.js → extension-page-BegL4FW8.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-DQn4qjDZ.js → extension-settings-page-CjPqq57s.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-DM3poL22.js → gateway-config-api-DaG57o4X.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-swr-BC3pgb_P.js → gateway-config-swr-826dipyU.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-DPgH1hnh.js → gateway-settings-DkJGpgm6.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-uMcSfLru.js → gateway-startup-retry-DyvcAIMm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-Bk80-E3b.js → heartbeat-settings-BLZ48kSU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{home-page-DKo5JiMR.js → home-page-Dtw7Ipt1.js} +1 -1
  39. package/dist/gateway/static/root/assets/{image-generation-api-D1qlQA-A.js → image-generation-api-D7cyfks6.js} +1 -1
  40. package/dist/gateway/static/root/assets/{index-B0WJL9N1.js → index-DG5CfYat.js} +10 -10
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BEwvd8ZU.js → keyboard-shortcuts-settings-D2Has7-N.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-app-workbench-page--eJ5rmNj.js → local-app-workbench-page-BWidWY93.js} +1 -1
  43. package/dist/gateway/static/root/assets/{local-apps-page-CgkY9E-r.js → local-apps-page-Bkekjoxf.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-CMZljTJx.js → locale-store-CBoCuIMx.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-Z49Td0J9.js → logs-page-C5zSSgvA.js} +1 -1
  46. package/dist/gateway/static/root/assets/{management-settings-Dv8NSJKt.js → management-settings-B8c62vRS.js} +1 -1
  47. package/dist/gateway/static/root/assets/{markdown-split-Cm0RBB-t.js → markdown-split-3kxTTGO7.js} +1 -1
  48. package/dist/gateway/static/root/assets/{markdown-view-PPCLt7fu.js → markdown-view-BXsHghJd.js} +1 -1
  49. package/dist/gateway/static/root/assets/{media-plugins-Bcr5sU1f.js → media-plugins-BW8J1nCG.js} +1 -1
  50. package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +3 -0
  51. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-kKDiXofY.js → mobile-pairing-wizard-nwQ8iUcd.js} +1 -1
  52. package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +1 -0
  53. package/dist/gateway/static/root/assets/{notes-page-CgsaRaGi.js → notes-page-DdybD0QM.js} +1 -1
  54. package/dist/gateway/static/root/assets/{notes-workbench-C1DEE09k.js → notes-workbench-IYfpy2Jx.js} +2 -2
  55. package/dist/gateway/static/root/assets/{oauth-api-4VeMbkTJ.js → oauth-api-BjSUDIgq.js} +1 -1
  56. package/dist/gateway/static/root/assets/{product-open-page-BU0HiZtv.js → product-open-page-CAJeUXeU.js} +1 -1
  57. package/dist/gateway/static/root/assets/{project-detail-page-isRapnp5.js → project-detail-page-4wjw-b7h.js} +1 -1
  58. package/dist/gateway/static/root/assets/{projects-page-zvsjg0mi.js → projects-page-CCMj9PeL.js} +1 -1
  59. package/dist/gateway/static/root/assets/{registry-api-CWOtPFrE.js → registry-api-BhGKnvLP.js} +1 -1
  60. package/dist/gateway/static/root/assets/{remote-access-hub-C9TGZ9Hc.js → remote-access-hub-DsBJqWIk.js} +1 -1
  61. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-2zm9edMA.js → runtime-tools-settings-panel-B4IDcqx0.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schema-form-54A5gzkN.js → schema-form-DiGUUjO6.js} +1 -1
  63. package/dist/gateway/static/root/assets/{sessions-page-BP8RyiUn.js → sessions-page-BwGj0t-2.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-BJCfUghk.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-page-DzDhoyxv.js → settings-page-CVQUsAhd.js} +1 -1
  66. package/dist/gateway/static/root/assets/{setup-status-panel-uDicHU1w.js → setup-status-panel-CQACRh1i.js} +1 -1
  67. package/dist/gateway/static/root/assets/{share-preview-page-lOmLCWFS.js → share-preview-page-DTP1dtuS.js} +1 -1
  68. package/dist/gateway/static/root/assets/{shares-settings-T4Yvouvv.js → shares-settings-D_YPh6Rw.js} +1 -1
  69. package/dist/gateway/static/root/assets/skill-reload-api-B43xlJlX.js +1 -0
  70. package/dist/gateway/static/root/assets/{skills-page-CnyNH3To.js → skills-page-Czpn7Y28.js} +1 -1
  71. package/dist/gateway/static/root/assets/{skills-page.utils-CgDtf2qs.js → skills-page.utils-d39rm3hb.js} +1 -1
  72. package/dist/gateway/static/root/assets/{system-settings-panel-C8yWfwtR.js → system-settings-panel-CXXySCSp.js} +1 -1
  73. package/dist/gateway/static/root/assets/{task-detail-page-Tzfjlbf3.js → task-detail-page-DHiOqQMx.js} +1 -1
  74. package/dist/gateway/static/root/assets/{theme-store-uxUwr10D.js → theme-store-hybK3oC9.js} +1 -1
  75. package/dist/gateway/static/root/assets/{tunnel-api-Bvg679no.js → tunnel-api-BiBGK7O2.js} +1 -1
  76. package/dist/gateway/static/root/assets/{use-autosave-D88VGoyG.js → use-autosave-DjpzpeIm.js} +1 -1
  77. package/dist/gateway/static/root/assets/{user-context-page-RijPtyfO.js → user-context-page-1XBRV5gX.js} +1 -1
  78. package/dist/gateway/static/root/assets/{voice-api-key-field-CBHLsMcc.js → voice-api-key-field-CUIPNmOc.js} +1 -1
  79. package/dist/gateway/static/root/assets/{voice-config-api-MqyI6cgq.js → voice-config-api-CBbiF1T3.js} +1 -1
  80. package/dist/gateway/static/root/assets/{work-discovery-overlay-GGe2TQ98.js → work-discovery-overlay-DVNxhb1x.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C0layUE9.js → workflow-run-setup-panel-HxxFQFY7.js} +1 -1
  82. package/dist/gateway/static/root/assets/{workflows-page-DQXIzBAc.js → workflows-page-BCgL7PRm.js} +1 -1
  83. package/dist/gateway/static/root/index.html +11 -11
  84. package/dist/package.js +1 -1
  85. package/dist/packages/gateway-contract/src/turn-outcome.js +3 -1
  86. package/dist/src/agent/agent-instance-gateway.d.ts +3 -1
  87. package/dist/src/agent/agent-manager.d.ts +2 -4
  88. package/dist/src/agent/agent-manager.js +24 -28
  89. package/dist/src/agent/background-review/coordinator.js +1 -1
  90. package/dist/src/agent/background-review/run-background-review.js +1 -1
  91. package/dist/src/agent/child-agent-factory.d.ts +10 -7
  92. package/dist/src/agent/child-agent-factory.js +112 -158
  93. package/dist/src/agent/coding/index.d.ts +1 -1
  94. package/dist/src/agent/coding/index.js +2 -2
  95. package/dist/src/agent/coding/repository-instructions.d.ts +12 -0
  96. package/dist/src/agent/coding/repository-instructions.js +76 -0
  97. package/dist/src/agent/coding/run-verification.d.ts +34 -0
  98. package/dist/src/agent/coding/run-verification.js +134 -0
  99. package/dist/src/agent/coding/verification-command.d.ts +3 -0
  100. package/dist/src/agent/coding/verification-command.js +50 -0
  101. package/dist/src/agent/coding/workspace-revision.d.ts +2 -0
  102. package/dist/src/agent/coding/workspace-revision.js +77 -0
  103. package/dist/src/agent/commands/command-isolation.d.ts +21 -0
  104. package/dist/src/agent/commands/command-isolation.js +71 -0
  105. package/dist/src/agent/commands/command-registry.d.ts +56 -0
  106. package/dist/src/agent/commands/command-registry.js +259 -0
  107. package/dist/src/agent/embedded/index.js +1 -1
  108. package/dist/src/agent/embedded/run-for-session.js +2 -1
  109. package/dist/src/agent/embedded/run-turn.js +88 -25
  110. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -2
  111. package/dist/src/agent/embedded/subscribe-session.d.ts +2 -1
  112. package/dist/src/agent/embedded/subscribe-session.js +2 -1
  113. package/dist/src/agent/embedded/types.d.ts +3 -1
  114. package/dist/src/agent/embedded/xopc-tools-bridge.js +4 -1
  115. package/dist/src/agent/image/index.js +1 -1
  116. package/dist/src/agent/index.js +3 -3
  117. package/dist/src/agent/memory/user-context-coordinator.js +1 -1
  118. package/dist/src/agent/middleware/index.d.ts +0 -5
  119. package/dist/src/agent/middleware/index.js +1 -2
  120. package/dist/src/agent/orchestration/agent-event-handler.d.ts +0 -5
  121. package/dist/src/agent/orchestration/agent-event-handler.js +1 -96
  122. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
  123. package/dist/src/agent/orchestration/agent-turn-policy.js +5 -5
  124. package/dist/src/agent/orchestration/index.d.ts +1 -1
  125. package/dist/src/agent/orchestration/index.js +2 -2
  126. package/dist/src/agent/orchestration/loop-guard.d.ts +4 -31
  127. package/dist/src/agent/orchestration/loop-guard.js +14 -99
  128. package/dist/src/agent/prompt/sections/tooling.js +2 -4
  129. package/dist/src/agent/sandbox/types.d.ts +2 -2
  130. package/dist/src/agent/sandbox/types.js +1 -1
  131. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  132. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  133. package/dist/src/agent/service.d.ts +0 -2
  134. package/dist/src/agent/service.js +6 -23
  135. package/dist/src/agent/tasks/task-judge-service.d.ts +7 -0
  136. package/dist/src/agent/tasks/task-judge-service.js +24 -2
  137. package/dist/src/agent/tools/delegate-tool.d.ts +2 -1
  138. package/dist/src/agent/tools/delegate-tool.js +102 -124
  139. package/dist/src/agent/tools/exec-command.d.ts +8 -1
  140. package/dist/src/agent/tools/exec-command.js +77 -169
  141. package/dist/src/agent/tools/executor.js +9 -2
  142. package/dist/src/agent/tools/factory.js +50 -5
  143. package/dist/src/agent/tools/find.d.ts +10 -13
  144. package/dist/src/agent/tools/find.js +33 -80
  145. package/dist/src/agent/tools/grep.d.ts +14 -18
  146. package/dist/src/agent/tools/grep.js +56 -144
  147. package/dist/src/agent/tools/index.d.ts +0 -1
  148. package/dist/src/agent/tools/index.js +2 -3
  149. package/dist/src/agent/tools/language-diagnostics.d.ts +11 -0
  150. package/dist/src/agent/tools/language-diagnostics.js +62 -0
  151. package/dist/src/agent/tools/managed-job-tool.d.ts +2 -1
  152. package/dist/src/agent/tools/managed-job-tool.js +58 -118
  153. package/dist/src/agent/tools/read.js +24 -7
  154. package/dist/src/agent/tools/repository-search.d.ts +5 -0
  155. package/dist/src/agent/tools/repository-search.js +56 -0
  156. package/dist/src/agent/tools/review-workspace.d.ts +2 -0
  157. package/dist/src/agent/tools/review-workspace.js +103 -0
  158. package/dist/src/agent/tools/write.js +4 -4
  159. package/dist/src/agent/transcript/index.js +2 -2
  160. package/dist/src/agent/transcript/transcript-hygiene.js +2 -2
  161. package/dist/src/agent/workflow/subagent-runner.d.ts +0 -2
  162. package/dist/src/agent/workflow/subagent-runner.js +12 -31
  163. package/dist/src/agent-config/schema.d.ts +42 -0
  164. package/dist/src/agent-config/schema.js +5 -0
  165. package/dist/src/automations/draft/automation-draft-service.js +1 -1
  166. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  167. package/dist/src/config/schema.d.ts +28 -0
  168. package/dist/src/execution-environments/local-worktree-manager.d.ts +3 -1
  169. package/dist/src/execution-environments/local-worktree-manager.js +8 -3
  170. package/dist/src/execution-environments/session-environment-service.js +5 -3
  171. package/dist/src/extensions/update.js +1 -1
  172. package/dist/src/gateway/hono/lib/config-payload.d.ts +7 -0
  173. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  174. package/dist/src/gateway/hono/routes/connectors.js +23 -23
  175. package/dist/src/gateway/hono/routes/sessions.js +1 -1
  176. package/dist/src/gateway/media-access.js +1 -1
  177. package/dist/src/gateway/service/config-coordinator.js +1 -1
  178. package/dist/src/gateway/service/run-gateway-agent.js +4 -1
  179. package/dist/src/gateway/service.js +1 -1
  180. package/dist/src/gateway/session-reset-service.js +1 -1
  181. package/dist/src/gateway/workspace-ripgrep.d.ts +0 -6
  182. package/dist/src/gateway/workspace-ripgrep.js +2 -40
  183. package/dist/src/infra/ripgrep.d.ts +13 -0
  184. package/dist/src/infra/ripgrep.js +46 -0
  185. package/dist/src/infra/update-runner.js +1 -1
  186. package/dist/src/proactive/execution/agent-executor.js +1 -1
  187. package/dist/src/session/store.js +1 -1
  188. package/dist/src/session/turn-outcome-projector.js +26 -6
  189. package/dist/src/tasks/task-run-coordinator.d.ts +2 -2
  190. package/dist/src/tasks/task-run-coordinator.js +14 -12
  191. package/dist/src/tui/backends/embedded-backend.js +1 -1
  192. package/package.json +3 -3
  193. package/dist/gateway/static/root/assets/messages-CTSgFlE4.js +0 -3
  194. package/dist/gateway/static/root/assets/models-hub-cache-ZrbGRiGY.js +0 -1
  195. package/dist/gateway/static/root/assets/settings-advanced-gate-D4EMxWAZ.js +0 -1
  196. package/dist/gateway/static/root/assets/skill-reload-api-DVb7nrXz.js +0 -1
  197. package/dist/src/agent/coding/turn-diff-tracker.d.ts +0 -67
  198. package/dist/src/agent/coding/turn-diff-tracker.js +0 -231
  199. package/dist/src/agent/middleware/self-verify.d.ts +0 -136
  200. package/dist/src/agent/middleware/self-verify.js +0 -380
  201. package/dist/src/agent/tools/execute-code-tool.d.ts +0 -11
  202. package/dist/src/agent/tools/execute-code-tool.js +0 -208
@@ -1,9 +1,14 @@
1
1
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
2
  import type { TurnOutcomeDeliverable } from '@xopcai/gateway-contract';
3
+ import type { CommandIsolation } from '../commands/command-isolation.js';
4
+ import { type CommandStatus } from '../commands/command-registry.js';
3
5
  export interface ExecCommandDetails {
4
6
  command: string;
5
7
  cwd: string;
6
- status: 'success' | 'failed' | 'timed_out' | 'blocked';
8
+ status: CommandStatus | 'blocked';
9
+ id?: string;
10
+ logPath?: string;
11
+ logTruncated?: boolean;
7
12
  exitCode: number | null;
8
13
  durationMs: number;
9
14
  timedOut: boolean;
@@ -27,6 +32,8 @@ export interface ExecCommandUpdateDetails {
27
32
  }
28
33
  export interface CreateExecCommandToolOptions {
29
34
  /** Env var names allowed through prepareSafeToolEnv even if they match secret heuristics. */
35
+ getCommandIsolation?: () => CommandIsolation | undefined;
36
+ getSessionKey?: () => string | undefined;
30
37
  getSkillPassthroughEnvVarNames?: () => string[];
31
38
  prepareEnv?: (baseEnv: Record<string, string>, cwd: string) => Promise<Record<string, string>>;
32
39
  }
@@ -1,76 +1,32 @@
1
+ import { commandRegistry, commandTimeout } from "../commands/command-registry.js";
1
2
  import { formatSize, truncateTail } from "./truncate.js";
2
3
  import { evaluateExecPolicy } from "../sandbox/exec-policy.js";
3
4
  import { publishArtifactPaths } from "./publish-artifacts.js";
4
5
  import { resolve } from "node:path";
5
- import { spawn } from "node:child_process";
6
6
  import { Type } from "@sinclair/typebox";
7
7
  //#region src/agent/tools/exec-command.ts
8
- const MAX_COMMAND_TIMEOUT_MS = 14400 * 1e3;
9
- const DEFAULT_TIMEOUT_MS = 1800 * 1e3;
10
8
  const DEFAULT_MAX_OUTPUT_CHARS = 5e4;
11
- const STREAM_DELTA_MAX_CHARS = 16e3;
12
9
  const ExecCommandSchema = Type.Object({
13
10
  cmd: Type.String({ description: "Shell command to execute." }),
14
11
  cwd: Type.Optional(Type.String({ description: "Working directory. Relative paths are resolved under the agent workspace." })),
15
12
  timeoutMs: Type.Optional(Type.Number({ description: "Command timeout in milliseconds. Defaults to 1800000 (30m) and is capped at 14400000 (4h)." })),
16
13
  maxOutputChars: Type.Optional(Type.Number({ description: "Maximum characters returned to the model. UI streaming still receives output deltas." })),
14
+ yieldTimeMs: Type.Optional(Type.Number({
15
+ minimum: 0,
16
+ maximum: 6e4,
17
+ description: "Return a running job after this wait; manage it with managed_job. Omit to wait for completion. Cannot be combined with outputs."
18
+ })),
17
19
  outputs: Type.Optional(Type.Array(Type.String({ minLength: 1 }), {
18
20
  maxItems: 50,
19
21
  description: "Final user-facing files created by this command. Relative paths resolve under the effective cwd and are persisted as chat deliverables after a successful command."
20
22
  }))
21
23
  });
22
- function clampTimeoutMs(raw) {
23
- return Math.min(MAX_COMMAND_TIMEOUT_MS, Math.max(1e3, Math.floor(typeof raw === "number" && Number.isFinite(raw) ? raw : DEFAULT_TIMEOUT_MS)));
24
- }
25
24
  function clampMaxOutputChars(raw) {
26
25
  return Math.max(1e3, Math.min(5e5, Math.floor(typeof raw === "number" && Number.isFinite(raw) ? raw : DEFAULT_MAX_OUTPUT_CHARS)));
27
26
  }
28
- function commandStatus(exitCode, timedOut) {
29
- if (timedOut) return "timed_out";
30
- if (exitCode === 0) return "success";
31
- return "failed";
32
- }
33
- function appendBoundedTail(current, chunk, maxChars) {
34
- const combined = current + chunk;
35
- if (combined.length <= maxChars) return {
36
- value: combined,
37
- truncated: false
38
- };
39
- return {
40
- value: combined.slice(-maxChars),
41
- truncated: true
42
- };
43
- }
44
- function terminateProcessTree(proc) {
45
- if (!proc.pid) return;
46
- if (process.platform === "win32") {
47
- const killer = spawn("taskkill", [
48
- "/pid",
49
- String(proc.pid),
50
- "/t",
51
- "/f"
52
- ], {
53
- stdio: "ignore",
54
- windowsHide: true
55
- });
56
- killer.once("error", () => {
57
- try {
58
- proc.kill("SIGKILL");
59
- } catch {}
60
- });
61
- killer.unref();
62
- return;
63
- }
64
- try {
65
- process.kill(-proc.pid, "SIGKILL");
66
- return;
67
- } catch {}
68
- try {
69
- proc.kill("SIGKILL");
70
- } catch {}
71
- }
72
27
  function commandFailureHint(details) {
73
- if (details.status === "success") return void 0;
28
+ if (details.status === "success" || details.status === "running") return void 0;
29
+ if (details.status === "cancelled") return "The command was cancelled. Inspect its partial output before deciding whether to restart.";
74
30
  if (details.status === "timed_out") return "The command timed out. Re-run a narrower command, increase timeoutMs if the long run is expected, or inspect partial output before retrying.";
75
31
  if (details.exitCode !== 0 && details.stderr.trim()) return "The command failed. Inspect stderr first, fix the underlying issue, then re-run the narrowest relevant verification command.";
76
32
  if (details.exitCode !== 0 && details.stdout.trim()) return "The command failed. Inspect stdout for the failure location, then re-run the narrowest relevant verification command.";
@@ -80,7 +36,7 @@ function formatOutputForModel(details, maxOutputChars) {
80
36
  let prefix = "";
81
37
  if (details.timedOut) prefix += `Command timed out after ${Math.round(details.durationMs / 1e3)}s\n`;
82
38
  if (details.exitCode !== 0 && details.exitCode != null) prefix += `Command exited with code ${details.exitCode}\n`;
83
- if (details.captureTruncated) prefix += `Earlier command output was discarded after ${formatSize(details.totalOutputBytes)}; showing the latest captured output.\n`;
39
+ if (details.captureTruncated) prefix += `Earlier command output was discarded from model context after ${formatSize(details.totalOutputBytes)}; showing the latest captured output.\n`;
84
40
  const truncation = truncateTail(details.aggregatedOutput, { maxBytes: Math.min(maxOutputChars, DEFAULT_MAX_OUTPUT_CHARS) });
85
41
  let text = `${prefix}${truncation.content}`.trimEnd();
86
42
  if (!text) text = "(no output)";
@@ -109,7 +65,8 @@ function createExecCommandTool(workspaceCwd, options) {
109
65
  idempotent: false,
110
66
  finalGuardRelevant: true,
111
67
  async execute(toolCallId, params, signal, onUpdate) {
112
- const command = (params.cmd ?? params.command ?? "").trim();
68
+ const command = (params.cmd ?? "").trim();
69
+ if (params.yieldTimeMs !== void 0 && params.outputs?.length) throw new Error("yieldTimeMs cannot be combined with outputs; publish files after the job completes.");
113
70
  if (!command) return {
114
71
  content: [{
115
72
  type: "text",
@@ -163,127 +120,78 @@ function createExecCommandTool(workspaceCwd, options) {
163
120
  }
164
121
  };
165
122
  }
166
- const timeoutMs = Math.min(clampTimeoutMs(params.timeoutMs), policy.timeoutMs);
123
+ const timeoutMs = commandTimeout(params.timeoutMs, policy.timeoutMs);
167
124
  const maxOutputChars = clampMaxOutputChars(params.maxOutputChars);
168
- const startTime = Date.now();
169
125
  const runtimeEnv = options?.prepareEnv ? await options.prepareEnv(policy.sanitizedEnv, policy.effectiveCwd) : policy.sanitizedEnv;
170
- let stdout = "";
171
- let stderr = "";
172
- let aggregatedOutput = "";
173
- let totalOutputBytes = 0;
174
- let captureTruncated = false;
175
- let timedOut = false;
176
- let settled = false;
177
- return new Promise((resolveTool) => {
178
- const proc = spawn(command, [], {
179
- shell: true,
180
- detached: process.platform !== "win32",
181
- cwd: policy.effectiveCwd,
182
- env: {
183
- ...runtimeEnv,
184
- COLUMNS: "200"
185
- }
186
- });
187
- const publishDelta = (stream, raw) => {
188
- const text = raw.toString();
189
- if (!text) return;
190
- totalOutputBytes += Buffer.byteLength(text);
191
- if (stream === "stdout") {
192
- const next = appendBoundedTail(stdout, text, maxOutputChars);
193
- stdout = next.value;
194
- captureTruncated ||= next.truncated;
195
- } else {
196
- const next = appendBoundedTail(stderr, text, maxOutputChars);
197
- stderr = next.value;
198
- captureTruncated ||= next.truncated;
199
- }
200
- const nextAggregate = appendBoundedTail(aggregatedOutput, text, maxOutputChars);
201
- aggregatedOutput = nextAggregate.value;
202
- captureTruncated ||= nextAggregate.truncated;
203
- const delta = text.length > STREAM_DELTA_MAX_CHARS ? `${text.slice(0, STREAM_DELTA_MAX_CHARS)}\n[stream delta truncated]` : text;
204
- onUpdate?.({
205
- content: [],
206
- details: {
207
- kind: "command_output_delta",
208
- command,
209
- cwd: policy.effectiveCwd,
210
- stream,
211
- delta
212
- }
213
- });
214
- };
215
- const finish = async (exitCode, errorText) => {
216
- if (settled) return;
217
- settled = true;
218
- clearTimeout(timeout);
219
- signal?.removeEventListener("abort", abort);
220
- if (errorText) {
221
- totalOutputBytes += Buffer.byteLength(errorText);
222
- const nextStderr = appendBoundedTail(stderr, errorText, maxOutputChars);
223
- stderr = nextStderr.value;
224
- const nextAggregate = appendBoundedTail(aggregatedOutput, errorText, maxOutputChars);
225
- aggregatedOutput = nextAggregate.value;
226
- captureTruncated ||= nextStderr.truncated || nextAggregate.truncated;
227
- }
228
- const durationMs = Date.now() - startTime;
229
- const baseDetails = {
126
+ const owner = options?.getSessionKey?.() ?? workspaceCwd;
127
+ const registry = commandRegistry();
128
+ let commandResult = await registry.start({
129
+ workspace: workspaceCwd,
130
+ isolation: options?.getCommandIsolation?.(),
131
+ owner,
132
+ command,
133
+ cwd: policy.effectiveCwd,
134
+ env: {
135
+ ...runtimeEnv,
136
+ COLUMNS: "200"
137
+ },
138
+ timeoutMs,
139
+ maxOutputChars,
140
+ signal,
141
+ snapshot: true,
142
+ onOutput: (stream, delta) => onUpdate?.({
143
+ content: [],
144
+ details: {
145
+ kind: "command_output_delta",
230
146
  command,
231
147
  cwd: policy.effectiveCwd,
232
- status: commandStatus(exitCode, timedOut),
233
- exitCode,
234
- durationMs,
235
- timedOut,
236
- truncated: false,
237
- outputBytes: Buffer.byteLength(aggregatedOutput),
238
- totalOutputBytes,
239
- captureTruncated,
240
- stdout,
241
- stderr,
242
- aggregatedOutput
243
- };
244
- baseDetails.failureHint = commandFailureHint(baseDetails);
245
- const formatted = formatOutputForModel(baseDetails, maxOutputChars);
246
- const details = {
247
- ...baseDetails,
248
- truncated: formatted.truncated,
249
- truncatedBy: formatted.truncatedBy,
250
- outputBytes: formatted.outputBytes
251
- };
252
- let resultText = formatted.text;
253
- if (details.status === "success" && params.outputs?.length) {
254
- details.artifacts = await publishArtifactPaths({
255
- paths: params.outputs,
256
- baseDir: policy.effectiveCwd,
257
- workspaceRoot: workspaceCwd,
258
- toolCallId
259
- });
260
- const published = details.artifacts.filter((item) => item.availability === "available").length;
261
- const failed = details.artifacts.length - published;
262
- resultText += `\n\nArtifacts: ${published} published${failed > 0 ? `, ${failed} failed` : ""}.`;
148
+ stream,
149
+ delta
263
150
  }
264
- resolveTool({
265
- content: [{
266
- type: "text",
267
- text: resultText
268
- }],
269
- details
270
- });
271
- };
272
- const abort = () => {
273
- timedOut = true;
274
- terminateProcessTree(proc);
275
- };
276
- const timeout = setTimeout(() => {
277
- timedOut = true;
278
- terminateProcessTree(proc);
279
- }, timeoutMs);
280
- if (signal?.aborted) abort();
281
- else signal?.addEventListener("abort", abort, { once: true });
282
- proc.stdout?.on("data", (data) => publishDelta("stdout", data));
283
- proc.stderr?.on("data", (data) => publishDelta("stderr", data));
284
- proc.on("error", (err) => void finish(null, `Error: ${err.message}`));
285
- proc.on("close", (code) => void finish(code));
151
+ })
286
152
  });
153
+ try {
154
+ do
155
+ commandResult = await registry.wait(owner, commandResult.id, params.yieldTimeMs ?? 6e4, signal);
156
+ while (params.yieldTimeMs === void 0 && commandResult.status === "running");
157
+ } catch (error) {
158
+ if (!signal?.aborted) throw error;
159
+ commandResult = await registry.cancel(owner, commandResult.id);
160
+ }
161
+ const baseDetails = {
162
+ ...commandResult,
163
+ truncated: false,
164
+ outputBytes: Buffer.byteLength(commandResult.aggregatedOutput)
165
+ };
166
+ baseDetails.failureHint = commandFailureHint(baseDetails);
167
+ const formatted = formatOutputForModel(baseDetails, maxOutputChars);
168
+ const details = {
169
+ ...baseDetails,
170
+ truncated: formatted.truncated,
171
+ truncatedBy: formatted.truncatedBy,
172
+ outputBytes: formatted.outputBytes
173
+ };
174
+ let resultText = formatted.text;
175
+ if (details.status === "running") resultText += `\n\nCommand is running (jobId: ${details.id}). Use managed_job wait/status/stdin/cancel.`;
176
+ if (details.logPath) resultText += `\n\nLog: ${details.logPath}${details.logTruncated ? " (truncated)" : ""}`;
177
+ if (details.status === "success" && params.outputs?.length) {
178
+ details.artifacts = await publishArtifactPaths({
179
+ paths: params.outputs,
180
+ baseDir: policy.effectiveCwd,
181
+ workspaceRoot: workspaceCwd,
182
+ toolCallId
183
+ });
184
+ const published = details.artifacts.filter((item) => item.availability === "available").length;
185
+ const failed = details.artifacts.length - published;
186
+ resultText += `\n\nArtifacts: ${published} published${failed > 0 ? `, ${failed} failed` : ""}.`;
187
+ }
188
+ return {
189
+ content: [{
190
+ type: "text",
191
+ text: resultText
192
+ }],
193
+ details
194
+ };
287
195
  }
288
196
  };
289
197
  }
@@ -1,5 +1,6 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { commandTimeout } from "../commands/command-registry.js";
3
4
  import { DEFAULT_TOOL_EXECUTION_TIMEOUT_MS, TimeoutError, executeWithTimeout } from "../lifecycle/timeout-wrapper.js";
4
5
  import { withRetry } from "../../infra/retry.js";
5
6
  import { ToolConcurrencyController, resolveToolLockMode } from "./concurrency.js";
@@ -41,8 +42,14 @@ async function executeToolWithProtection(tool, toolCallId, params, signal, onUpd
41
42
  const onParentAbort = () => controller.abort(signal?.reason);
42
43
  if (signal?.aborted) onParentAbort();
43
44
  else signal?.addEventListener("abort", onParentAbort, { once: true });
44
- const execute = () => tool.execute(toolCallId, params, controller.signal, onUpdate);
45
- return (fullConfig.enableTimeout ? executeWithTimeout(execute, {
45
+ const policyDeadline = fullConfig.resolveTimeoutMs?.(toolName);
46
+ const commandDeadlineField = toolName === "exec_command" ? "timeoutMs" : toolName === "managed_job" && params.action === "start" ? "maxRuntimeMs" : void 0;
47
+ const executionParams = commandDeadlineField && policyDeadline ? {
48
+ ...params,
49
+ [commandDeadlineField]: Math.min(commandTimeout(params[commandDeadlineField]), policyDeadline)
50
+ } : params;
51
+ const execute = () => tool.execute(toolCallId, executionParams, controller.signal, onUpdate);
52
+ return (fullConfig.enableTimeout && toolName !== "exec_command" ? executeWithTimeout(execute, {
46
53
  toolName,
47
54
  timeoutMs: resolveTimeoutMs(tool, fullConfig),
48
55
  description: `Executing ${toolName}`,
@@ -5,7 +5,9 @@ import { isXopcDatabaseOpen } from "../../storage/sqlite/connection.js";
5
5
  import { getSessionTaskPlan, setSessionTaskPlan } from "../../storage/sqlite/session-task-plan-repository.js";
6
6
  import "../../storage/sqlite/index.js";
7
7
  import { init_agent_scope, resolveDefaultAgentId } from "../agent-scope.js";
8
+ import { resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
8
9
  import { wrapToolsWithProtection } from "./executor.js";
10
+ import { EXTERNAL_TOOL_NAMES } from "../external-tools/gateway-tools.js";
9
11
  import { buildRuntimeEnvironment } from "../../runtime-tools/environment.js";
10
12
  import { createDefaultExternalToolGatewayTools } from "../external-tools/index.js";
11
13
  import { createReadFileTool } from "./read.js";
@@ -36,9 +38,8 @@ import { resolveBrowserBackendFromConfig } from "../../browser/backend-from-conf
36
38
  import { checkBrowserReadiness } from "../../browser/readiness.js";
37
39
  import { CdpSupervisor } from "../../browser/cdp-supervisor.js";
38
40
  import "../../browser/index.js";
39
- import "./delegate-tool.js";
41
+ import { createDelegateTool } from "./delegate-tool.js";
40
42
  import { createWorkflowTool } from "./workflow-tool.js";
41
- import "./execute-code-tool.js";
42
43
  import { createAutomationTool } from "./automation-tool.js";
43
44
  import { createBrowserRecipeTool } from "./browser-recipe-tool.js";
44
45
  import { createXopcUseTool } from "./xopc-use-tool.js";
@@ -53,6 +54,8 @@ import { createImageTool } from "./image-tool.js";
53
54
  import { createImageGenerateTool } from "./image-generate-tool.js";
54
55
  import "./index.js";
55
56
  import { createBrowserUseTool } from "./browser/tool/browser-use-tool.js";
57
+ import { createReviewWorkspaceTool } from "./review-workspace.js";
58
+ import { createLanguageDiagnosticsTool } from "./language-diagnostics.js";
56
59
  import { createWorkflowCatalog } from "../workflow/catalog.js";
57
60
  import { mergeTtsConfigFromAppConfig } from "../../voice/tts/merge-config.js";
58
61
  import { createTextToSpeechTool } from "./tts-tool.js";
@@ -70,7 +73,7 @@ const CLARIFY_SUPPORTED_CHANNELS = new Set([
70
73
  "telegram",
71
74
  "cli"
72
75
  ]);
73
- var AgentToolsFactory = class {
76
+ var AgentToolsFactory = class AgentToolsFactory {
74
77
  browserManager = null;
75
78
  /** One dialog/console supervisor per chat session (browser tab). */
76
79
  browserTaskSupervisors = /* @__PURE__ */ new Map();
@@ -193,6 +196,10 @@ var AgentToolsFactory = class {
193
196
  agentId: options?.agentId ?? (cfg ? resolveDefaultAgentId(cfg) : "main")
194
197
  });
195
198
  const agentId = options?.agentId;
199
+ const getCommandIsolation = () => {
200
+ const config = this.deps.getConfig?.();
201
+ return config ? resolveEffectiveAgentConfigForSession(config, this.deps.getCurrentContext()?.sessionKey ?? `agent:${agentId ?? "main"}:internal`).config.runtime.commandIsolation : void 0;
202
+ };
196
203
  const externalTools = createDefaultExternalToolGatewayTools({
197
204
  workspace,
198
205
  getConfig: () => this.deps.getConfig?.(),
@@ -271,10 +278,18 @@ var AgentToolsFactory = class {
271
278
  grep,
272
279
  find,
273
280
  createExecCommandTool(workspace, {
281
+ getCommandIsolation,
282
+ getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
274
283
  getSkillPassthroughEnvVarNames: this.deps.getSkillPassthroughEnvVarNames,
275
284
  prepareEnv: this.prepareRuntimeEnv
276
285
  }),
277
- createManagedJobTool(workspace, () => this.deps.getCurrentContext()?.sessionKey, this.deps.getSkillPassthroughEnvVarNames, this.prepareRuntimeEnv),
286
+ createReviewWorkspaceTool(workspace),
287
+ createLanguageDiagnosticsTool(workspace, {
288
+ getCommandIsolation,
289
+ getSessionKey: () => this.deps.getCurrentContext()?.sessionKey,
290
+ prepareEnv: this.prepareRuntimeEnv
291
+ }),
292
+ createManagedJobTool(workspace, () => this.deps.getCurrentContext()?.sessionKey, this.deps.getSkillPassthroughEnvVarNames, this.prepareRuntimeEnv, getCommandIsolation),
278
293
  createWebSearchTool(() => this.deps.getConfig?.()),
279
294
  createWebFetchTool(() => this.deps.getConfig?.()),
280
295
  createWebExtractTool({ getConfig: () => this.deps.getConfig?.() }),
@@ -345,7 +360,37 @@ var AgentToolsFactory = class {
345
360
  getConfig: () => this.deps.getConfig?.(),
346
361
  startWorkflowRun: this.deps.getWorkflowRunService ? (params) => this.deps.getWorkflowRunService().startWorkflowRun(params) : void 0
347
362
  })] : [],
348
- ...[],
363
+ ...primary ? [createDelegateTool({
364
+ workspace,
365
+ getSubagentModel: () => {
366
+ const m = (options?.getPrimaryModel ?? this.deps.getPrimaryModel)?.();
367
+ if (!m) throw new Error("No primary model configured for delegate_task");
368
+ return m;
369
+ },
370
+ bus: this.deps.bus,
371
+ getConfig: () => this.deps.getConfig?.(),
372
+ getCurrentContext: () => this.deps.getCurrentContext?.() ?? null,
373
+ toolExecutorConfig: this.deps.toolExecutorConfig,
374
+ buildChildTools: (childOpts) => {
375
+ return new AgentToolsFactory({
376
+ workspace: childOpts.workspace,
377
+ bus: childOpts.bus,
378
+ getCurrentContext: () => null,
379
+ getConfig: childOpts.getConfig,
380
+ getPrimaryModel: () => childOpts.model,
381
+ toolExecutorConfig: childOpts.toolExecutorConfig
382
+ }).createAllTools({
383
+ workspace: childOpts.workspace,
384
+ getPrimaryModel: () => childOpts.model,
385
+ agentId: options?.agentId ?? childOpts.agentId,
386
+ disabledTools: new Set([
387
+ EXTERNAL_TOOL_NAMES.search,
388
+ EXTERNAL_TOOL_NAMES.describe,
389
+ EXTERNAL_TOOL_NAMES.execute
390
+ ])
391
+ });
392
+ }
393
+ })] : [],
349
394
  ...optionalTools
350
395
  ], disabled);
351
396
  }
@@ -1,17 +1,14 @@
1
+ import { type Static } from '@sinclair/typebox';
1
2
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
- import { type TruncationResult } from './truncate.js';
3
- export type FindToolInput = {
4
- pattern: string;
5
- path?: string;
6
- limit?: number;
7
- };
3
+ declare const findSchema: import("@sinclair/typebox").TObject<{
4
+ pattern: import("@sinclair/typebox").TString;
5
+ path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
6
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
7
+ }>;
8
8
  export interface FindToolDetails {
9
- truncation?: TruncationResult;
10
- resultLimitReached?: number;
9
+ truncated: boolean;
11
10
  }
12
- /**
13
- * Find tool - Search for files by glob pattern
14
- */
11
+ export type FindToolInput = Static<typeof findSchema>;
15
12
  export declare function createFindTool(cwd: string): AgentTool;
16
- /** Default find tool using process.cwd() */
17
- export declare const findTool: AgentTool;
13
+ export declare const findTool: AgentTool<import("typebox").TSchema, any>;
14
+ export {};
@@ -1,97 +1,50 @@
1
- import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
1
+ import { evaluateFilePolicy } from "../sandbox/exec-policy.js";
2
2
  import { resolveToCwd } from "../../utils/helpers.js";
3
- import path from "path";
4
- import { existsSync } from "fs";
3
+ import { repositorySearch } from "./repository-search.js";
5
4
  import { Type } from "@sinclair/typebox";
6
- import { globSync } from "glob";
7
5
  //#region src/agent/tools/find.ts
8
6
  const findSchema = Type.Object({
9
- pattern: Type.String({ description: "Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'" }),
10
- path: Type.Optional(Type.String({ description: "Directory to search in (default: current directory)" })),
11
- limit: Type.Optional(Type.Number({ description: "Maximum number of results (default: 1000)" }))
7
+ pattern: Type.String({ description: "Glob pattern, e.g. *.ts or src/**/*.json" }),
8
+ path: Type.Optional(Type.String()),
9
+ limit: Type.Optional(Type.Integer({
10
+ minimum: 1,
11
+ maximum: 1e4
12
+ }))
12
13
  });
13
- const DEFAULT_LIMIT = 1e3;
14
- /**
15
- * Find tool - Search for files by glob pattern
16
- */
17
14
  function createFindTool(cwd) {
18
15
  return {
19
16
  name: "find",
20
- label: "📁 find",
21
- description: "Find files by glob pattern (e.g., *.ts, **/*.json).",
17
+ label: "Find files",
22
18
  parameters: findSchema,
19
+ description: "Find files by glob with ripgrep; respects .gitignore and skips .git and node_modules. Results are relative to the search directory.",
23
20
  supportsParallel: true,
24
21
  idempotent: true,
25
- execute: async (_toolCallId, params, signal) => {
26
- try {
27
- const p = params;
28
- const searchPath = resolveToCwd(p.path || ".", cwd);
29
- const effectiveLimit = p.limit || DEFAULT_LIMIT;
30
- if (!existsSync(searchPath)) return {
31
- content: [{
32
- type: "text",
33
- text: `Error: Path not found: ${searchPath}`
34
- }],
35
- details: {}
36
- };
37
- if (signal?.aborted) return {
38
- content: [{
39
- type: "text",
40
- text: "Operation aborted"
41
- }],
42
- details: {}
43
- };
44
- const filePaths = globSync(p.pattern, {
45
- cwd: searchPath,
46
- dot: true,
47
- ignore: ["**/node_modules/**", "**/.git/**"]
48
- });
49
- if (filePaths.length === 0) return {
50
- content: [{
51
- type: "text",
52
- text: "No files found matching pattern"
53
- }],
54
- details: {}
55
- };
56
- const relativized = filePaths.map((p) => {
57
- if (p.startsWith(searchPath)) return p.slice(searchPath.length + 1);
58
- return path.relative(searchPath, p);
59
- });
60
- relativized.sort();
61
- const resultLimitReached = relativized.length >= effectiveLimit;
62
- const truncation = truncateHead((resultLimitReached ? relativized.slice(0, effectiveLimit) : relativized).join("\n"), { maxLines: Number.MAX_SAFE_INTEGER });
63
- let resultOutput = truncation.content;
64
- const details = {};
65
- const notices = [];
66
- if (resultLimitReached) {
67
- notices.push(`${effectiveLimit} results limit reached`);
68
- details.resultLimitReached = effectiveLimit;
69
- }
70
- if (truncation.truncated) {
71
- notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
72
- details.truncation = truncation;
73
- }
74
- if (notices.length > 0) resultOutput += `\n\n[${notices.join(". ")}]`;
75
- return {
76
- content: [{
77
- type: "text",
78
- text: resultOutput
79
- }],
80
- details: Object.keys(details).length > 0 ? details : void 0
81
- };
82
- } catch (error) {
83
- return {
84
- content: [{
85
- type: "text",
86
- text: `Error during find: ${error instanceof Error ? error.message : String(error)}`
87
- }],
88
- details: {}
89
- };
90
- }
22
+ async execute(_id, params, signal) {
23
+ const path = resolveToCwd(params.path || ".", cwd);
24
+ const policy = evaluateFilePolicy({
25
+ operation: "read",
26
+ path,
27
+ workspaceRoot: cwd
28
+ });
29
+ if (!policy.allowed) throw new Error(policy.reason);
30
+ const result = await repositorySearch(path, [
31
+ "--files",
32
+ "--glob",
33
+ params.pattern
34
+ ], signal);
35
+ const limit = Math.min(1e4, Math.max(1, params.limit ?? 1e3));
36
+ const lines = result.output.trimEnd().split("\n").filter(Boolean).sort();
37
+ const truncated = result.truncated || lines.length > limit;
38
+ return {
39
+ content: [{
40
+ type: "text",
41
+ text: (lines.slice(0, limit).join("\n") || "No files found matching pattern") + (truncated ? "\n[Results truncated; narrow the glob.]" : "")
42
+ }],
43
+ details: { truncated }
44
+ };
91
45
  }
92
46
  };
93
47
  }
94
- /** Default find tool using process.cwd() */
95
48
  const findTool = createFindTool(process.cwd());
96
49
  //#endregion
97
50
  export { createFindTool, findTool };
@@ -1,22 +1,18 @@
1
+ import { type Static } from '@sinclair/typebox';
1
2
  import type { AgentTool } from '@earendil-works/pi-agent-core';
2
- import { type TruncationResult } from './truncate.js';
3
- export type GrepToolInput = {
4
- pattern: string;
5
- path?: string;
6
- glob?: string;
7
- ignoreCase?: boolean;
8
- literal?: boolean;
9
- context?: number;
10
- limit?: number;
11
- };
3
+ declare const grepSchema: import("@sinclair/typebox").TObject<{
4
+ pattern: import("@sinclair/typebox").TString;
5
+ path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
6
+ glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
7
+ ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
8
+ literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
9
+ context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
10
+ limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
11
+ }>;
12
12
  export interface GrepToolDetails {
13
- truncation?: TruncationResult;
14
- matchLimitReached?: number;
15
- linesTruncated?: boolean;
13
+ truncated: boolean;
16
14
  }
17
- /**
18
- * Grep tool - Search file contents for a pattern
19
- */
15
+ export type GrepToolInput = Static<typeof grepSchema>;
20
16
  export declare function createGrepTool(cwd: string): AgentTool;
21
- /** Default grep tool using process.cwd() */
22
- export declare const grepTool: AgentTool;
17
+ export declare const grepTool: AgentTool<import("typebox").TSchema, any>;
18
+ export {};