@arnilo/prism-tools 0.0.0-stage → 0.13.0

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 (331) hide show
  1. package/CHANGELOG.md +410 -0
  2. package/LICENSE +21 -0
  3. package/README.md +44 -2
  4. package/browser/README.md +98 -0
  5. package/browser/skills/browser-automation/SKILL.md +14 -0
  6. package/browser/src/actions/cdp.ts +131 -0
  7. package/browser/src/actions/dialog.ts +25 -0
  8. package/browser/src/actions/download_release.ts +22 -0
  9. package/browser/src/actions/index.ts +37 -0
  10. package/browser/src/actions/locator.ts +70 -0
  11. package/browser/src/actions/navigate.ts +23 -0
  12. package/browser/src/actions/screenshot.ts +27 -0
  13. package/browser/src/actions/scroll.ts +24 -0
  14. package/browser/src/actions/select_page.ts +21 -0
  15. package/browser/src/actions/types.ts +114 -0
  16. package/browser/src/actions/upload.ts +44 -0
  17. package/browser/src/actions/wait.ts +45 -0
  18. package/browser/src/browser.ts +197 -0
  19. package/browser/src/cdp.ts +178 -0
  20. package/browser/src/checkpoint.ts +189 -0
  21. package/browser/src/config.ts +72 -0
  22. package/browser/src/downloads.ts +253 -0
  23. package/browser/src/errors.ts +31 -0
  24. package/browser/src/evaluate.ts +101 -0
  25. package/browser/src/index.ts +129 -0
  26. package/browser/src/limits.ts +271 -0
  27. package/browser/src/manager.ts +730 -0
  28. package/browser/src/network.ts +263 -0
  29. package/browser/src/observe.ts +178 -0
  30. package/browser/src/policy.ts +133 -0
  31. package/browser/src/screenshot.ts +107 -0
  32. package/browser/src/shared-sandbox.ts +53 -0
  33. package/browser/src/snapshot.ts +99 -0
  34. package/browser/src/targets.ts +165 -0
  35. package/browser/src/tools.ts +480 -0
  36. package/browser/src/types.ts +316 -0
  37. package/browser/src/uploads.ts +174 -0
  38. package/coding/README.md +337 -0
  39. package/coding/src/agent/acp-operations.ts +146 -0
  40. package/coding/src/agent/artifacts.ts +38 -0
  41. package/coding/src/agent/ask-user-decision.ts +623 -0
  42. package/coding/src/agent/atomic-write.ts +23 -0
  43. package/coding/src/agent/bounded-file.ts +21 -0
  44. package/coding/src/agent/checks.ts +301 -0
  45. package/coding/src/agent/coding-checkpoint.ts +828 -0
  46. package/coding/src/agent/delete.ts +237 -0
  47. package/coding/src/agent/diagnostics-tool.ts +163 -0
  48. package/coding/src/agent/diagnostics.ts +262 -0
  49. package/coding/src/agent/edit-diff.ts +382 -0
  50. package/coding/src/agent/edit.ts +322 -0
  51. package/coding/src/agent/effects.ts +102 -0
  52. package/coding/src/agent/env.ts +28 -0
  53. package/coding/src/agent/execution-policy.ts +89 -0
  54. package/coding/src/agent/file-mutation-queue.ts +72 -0
  55. package/coding/src/agent/forge/github.ts +603 -0
  56. package/coding/src/agent/forge/index.ts +16 -0
  57. package/coding/src/agent/forge/types.ts +185 -0
  58. package/coding/src/agent/git-aware-repository.ts +305 -0
  59. package/coding/src/agent/git-exec.ts +326 -0
  60. package/coding/src/agent/git-status.ts +177 -0
  61. package/coding/src/agent/git-tools.ts +360 -0
  62. package/coding/src/agent/git.ts +1074 -0
  63. package/coding/src/agent/glob-match.ts +146 -0
  64. package/coding/src/agent/glob.ts +182 -0
  65. package/coding/src/agent/goal-verify.ts +385 -0
  66. package/coding/src/agent/grep-worker.ts +74 -0
  67. package/coding/src/agent/grep.ts +459 -0
  68. package/coding/src/agent/identity.ts +48 -0
  69. package/coding/src/agent/index.ts +676 -0
  70. package/coding/src/agent/language/client.ts +429 -0
  71. package/coding/src/agent/language/framing.ts +190 -0
  72. package/coding/src/agent/language/index.ts +23 -0
  73. package/coding/src/agent/language/intelligence.ts +682 -0
  74. package/coding/src/agent/language/types.ts +187 -0
  75. package/coding/src/agent/lifecycle-events.ts +121 -0
  76. package/coding/src/agent/lifecycle.ts +166 -0
  77. package/coding/src/agent/limits.ts +214 -0
  78. package/coding/src/agent/move.ts +178 -0
  79. package/coding/src/agent/mutation-path.ts +52 -0
  80. package/coding/src/agent/output-accumulator.ts +304 -0
  81. package/coding/src/agent/path-utils.ts +120 -0
  82. package/coding/src/agent/process/index.ts +58 -0
  83. package/coding/src/agent/process/recovery.ts +508 -0
  84. package/coding/src/agent/process/sessions-host.ts +222 -0
  85. package/coding/src/agent/process/sessions-monitor.ts +141 -0
  86. package/coding/src/agent/process/sessions-recovery.ts +241 -0
  87. package/coding/src/agent/process/sessions-spawn.ts +613 -0
  88. package/coding/src/agent/process/sessions-teardown.ts +281 -0
  89. package/coding/src/agent/process/sessions.ts +30 -0
  90. package/coding/src/agent/process/types.ts +358 -0
  91. package/coding/src/agent/read-path-set.ts +126 -0
  92. package/coding/src/agent/read.ts +713 -0
  93. package/coding/src/agent/repository/glob.ts +147 -0
  94. package/coding/src/agent/repository/indexed-search.ts +480 -0
  95. package/coding/src/agent/repository/list.ts +131 -0
  96. package/coding/src/agent/repository/operations.ts +22 -0
  97. package/coding/src/agent/repository/path.ts +98 -0
  98. package/coding/src/agent/repository/search.ts +277 -0
  99. package/coding/src/agent/repository/types.ts +243 -0
  100. package/coding/src/agent/repository/walk.ts +126 -0
  101. package/coding/src/agent/repository.ts +12 -0
  102. package/coding/src/agent/shell-background.ts +264 -0
  103. package/coding/src/agent/shell-output.ts +75 -0
  104. package/coding/src/agent/shell.ts +526 -0
  105. package/coding/src/agent/todo.ts +399 -0
  106. package/coding/src/agent/truncate.ts +251 -0
  107. package/coding/src/agent/write.ts +170 -0
  108. package/coding/src/ask-user-host.ts +48 -0
  109. package/coding/src/config.ts +278 -0
  110. package/coding/src/hard-deny.ts +97 -0
  111. package/coding/src/index.ts +318 -0
  112. package/coding/src/principal-guard.ts +84 -0
  113. package/coding/src/sandbox.ts +92 -0
  114. package/coding/src/security/approval.ts +144 -0
  115. package/coding/src/security/command-rules.ts +57 -0
  116. package/coding/src/security/docker-cli.ts +222 -0
  117. package/coding/src/security/docker-sandbox.ts +1205 -0
  118. package/coding/src/security/e2b-sandbox.ts +853 -0
  119. package/coding/src/security/egress/dns-pin.ts +88 -0
  120. package/coding/src/security/egress/index.ts +32 -0
  121. package/coding/src/security/egress/limits.ts +57 -0
  122. package/coding/src/security/egress/policy.ts +137 -0
  123. package/coding/src/security/egress/proxy.ts +599 -0
  124. package/coding/src/security/egress/types.ts +30 -0
  125. package/coding/src/security/index.ts +199 -0
  126. package/coding/src/security/native-sandbox.ts +639 -0
  127. package/coding/src/security/path-containment.ts +55 -0
  128. package/coding/src/security/sandbox-coding-operations.ts +392 -0
  129. package/coding/src/security/sandbox-fs-operations.ts +644 -0
  130. package/coding/src/security/sandbox-limits.ts +147 -0
  131. package/coding/src/security/sandbox-tar.ts +308 -0
  132. package/coding/src/security/sandbox.ts +179 -0
  133. package/coding/src/security/semaphore.ts +55 -0
  134. package/coding/src/targets.ts +110 -0
  135. package/coding/src/workspace/diff.ts +78 -0
  136. package/coding/src/workspace/errors.ts +28 -0
  137. package/coding/src/workspace/index.ts +5 -0
  138. package/coding/src/workspace/merge.ts +151 -0
  139. package/coding/src/workspace/routing.ts +76 -0
  140. package/coding/src/workspace/service.ts +545 -0
  141. package/computer-use/README.md +105 -0
  142. package/computer-use/skills/computer-use-linux/SKILL.md +17 -0
  143. package/computer-use/src/classify.ts +53 -0
  144. package/computer-use/src/command.ts +29 -0
  145. package/computer-use/src/config.ts +69 -0
  146. package/computer-use/src/create.ts +170 -0
  147. package/computer-use/src/devices.ts +247 -0
  148. package/computer-use/src/env.ts +28 -0
  149. package/computer-use/src/index.ts +157 -0
  150. package/computer-use/src/skill.ts +21 -0
  151. package/openapi/README.md +97 -0
  152. package/openapi/src/compile.ts +386 -0
  153. package/openapi/src/config.ts +73 -0
  154. package/openapi/src/errors.ts +16 -0
  155. package/openapi/src/execute.ts +241 -0
  156. package/openapi/src/index.ts +124 -0
  157. package/openapi/src/limits.ts +63 -0
  158. package/openapi/src/specs.ts +86 -0
  159. package/openapi/src/tools.ts +60 -0
  160. package/openapi/src/types.ts +61 -0
  161. package/package.json +171 -4
  162. package/research/README.md +72 -0
  163. package/research/skills/research-report/SKILL.md +12 -0
  164. package/research/skills/research-scoping/SKILL.md +10 -0
  165. package/research/skills/research-synthesis/SKILL.md +10 -0
  166. package/research/skills/source-triage/SKILL.md +10 -0
  167. package/research/src/check.ts +71 -0
  168. package/research/src/config.ts +41 -0
  169. package/research/src/index.ts +147 -0
  170. package/research/src/ledger.ts +157 -0
  171. package/research/src/urls.ts +21 -0
  172. package/web/README.md +287 -0
  173. package/web/skills/web-research/SKILL.md +17 -0
  174. package/web/src/brave.ts +66 -0
  175. package/web/src/cache.ts +151 -0
  176. package/web/src/config.ts +210 -0
  177. package/web/src/controls.ts +128 -0
  178. package/web/src/domains.ts +114 -0
  179. package/web/src/exa.ts +60 -0
  180. package/web/src/firecrawl.ts +160 -0
  181. package/web/src/index.ts +387 -0
  182. package/web/src/kagi.ts +73 -0
  183. package/web/src/limits.ts +55 -0
  184. package/web/src/native/convert.ts +84 -0
  185. package/web/src/native/fetch.ts +226 -0
  186. package/web/src/normalize.ts +131 -0
  187. package/web/src/obscura/cdp.ts +201 -0
  188. package/web/src/obscura/classify.ts +35 -0
  189. package/web/src/obscura/cli.ts +254 -0
  190. package/web/src/obscura/errors.ts +8 -0
  191. package/web/src/obscura/index.ts +59 -0
  192. package/web/src/obscura/limits.ts +92 -0
  193. package/web/src/obscura/mcp.ts +104 -0
  194. package/web/src/obscura/playwright.ts +133 -0
  195. package/web/src/obscura/process.ts +235 -0
  196. package/web/src/obscura/search-profile.ts +73 -0
  197. package/web/src/obscura/types.ts +48 -0
  198. package/web/src/obscura/web.ts +419 -0
  199. package/web/src/prompt-fetch.ts +88 -0
  200. package/web/src/render.ts +75 -0
  201. package/web/src/searxng.ts +78 -0
  202. package/web/src/slice.ts +139 -0
  203. package/web/src/tavily.ts +77 -0
  204. package/web/src/tools.ts +182 -0
  205. package/web/src/transport.ts +310 -0
  206. package/web/src/types.ts +199 -0
  207. package/work/README.md +77 -0
  208. package/work/THIRD_PARTY_NOTICES +24 -0
  209. package/work/docling/ocr.py +150 -0
  210. package/work/sandbox/Dockerfile +36 -0
  211. package/work/sandbox/soffice.sh +12 -0
  212. package/work/src/command.ts +29 -0
  213. package/work/src/config.ts +138 -0
  214. package/work/src/connectors/cli.ts +343 -0
  215. package/work/src/connectors/drafts.ts +647 -0
  216. package/work/src/connectors/errors.ts +8 -0
  217. package/work/src/connectors/file-bytes.ts +149 -0
  218. package/work/src/connectors/google-workspace-http.ts +399 -0
  219. package/work/src/connectors/google-workspace.ts +465 -0
  220. package/work/src/connectors/gws-tools.ts +378 -0
  221. package/work/src/connectors/http.ts +123 -0
  222. package/work/src/connectors/idempotency.ts +235 -0
  223. package/work/src/connectors/identity.ts +34 -0
  224. package/work/src/connectors/index.ts +93 -0
  225. package/work/src/connectors/limits.ts +50 -0
  226. package/work/src/connectors/m365-tools.ts +308 -0
  227. package/work/src/connectors/microsoft365-http.ts +428 -0
  228. package/work/src/connectors/microsoft365.ts +402 -0
  229. package/work/src/connectors/normalize.ts +120 -0
  230. package/work/src/connectors/tool-helpers.ts +398 -0
  231. package/work/src/connectors/tools.ts +42 -0
  232. package/work/src/connectors/types.ts +399 -0
  233. package/work/src/diagrams/canonicalize.ts +166 -0
  234. package/work/src/diagrams/caps.ts +52 -0
  235. package/work/src/diagrams/embed.ts +340 -0
  236. package/work/src/diagrams/errors.ts +76 -0
  237. package/work/src/diagrams/index.ts +81 -0
  238. package/work/src/diagrams/messages.ts +150 -0
  239. package/work/src/diagrams/origin.ts +52 -0
  240. package/work/src/diagrams/telemetry.ts +34 -0
  241. package/work/src/diagrams/xml.ts +267 -0
  242. package/work/src/document-extraction/index.ts +563 -0
  243. package/work/src/document-reader/ambient.d.ts +2 -0
  244. package/work/src/document-reader/errors.ts +7 -0
  245. package/work/src/document-reader/index.ts +181 -0
  246. package/work/src/document-reader/mistral-ocr.ts +318 -0
  247. package/work/src/document-reader/parsers.ts +171 -0
  248. package/work/src/documents/caps.ts +135 -0
  249. package/work/src/documents/diff.ts +269 -0
  250. package/work/src/documents/errors.ts +44 -0
  251. package/work/src/documents/fidelity.ts +98 -0
  252. package/work/src/documents/generate.ts +96 -0
  253. package/work/src/documents/hash.ts +8 -0
  254. package/work/src/documents/index.ts +14 -0
  255. package/work/src/documents/model-schema.ts +639 -0
  256. package/work/src/documents/parse.ts +252 -0
  257. package/work/src/documents/patch-history.ts +81 -0
  258. package/work/src/documents/patch.ts +476 -0
  259. package/work/src/documents/preview-html.ts +245 -0
  260. package/work/src/documents/preview.ts +227 -0
  261. package/work/src/documents/telemetry.ts +36 -0
  262. package/work/src/documents/translate/docx.ts +292 -0
  263. package/work/src/documents/translate/pptx.ts +304 -0
  264. package/work/src/documents/translate/xlsx.ts +137 -0
  265. package/work/src/documents/types.ts +188 -0
  266. package/work/src/index.ts +311 -0
  267. package/work/src/runtime/worker-pool-entry.ts +102 -0
  268. package/work/src/runtime/worker-pool.ts +267 -0
  269. package/work/src/sandbox/composition.ts +212 -0
  270. package/work/src/sandbox/image.ts +6 -0
  271. package/work/src/sandbox/index.ts +14 -0
  272. package/work/src/sheets/caps.ts +68 -0
  273. package/work/src/sheets/csv.ts +351 -0
  274. package/work/src/sheets/decimal.ts +388 -0
  275. package/work/src/sheets/errors.ts +52 -0
  276. package/work/src/sheets/index.ts +62 -0
  277. package/work/src/sheets/inference.ts +378 -0
  278. package/work/src/sheets/telemetry.ts +34 -0
  279. package/work/src/sheets/types.ts +162 -0
  280. package/work/src/sheets/xlsx.ts +388 -0
  281. package/work/src/skills/index.ts +8 -0
  282. package/work/src/skills/load.ts +43 -0
  283. package/work/src/tools/filesystem.ts +21 -0
  284. package/work/src/tools/index.ts +1 -0
  285. package/work/src/tools/local-filesystem.ts +33 -0
  286. package/work/src/tools/office.ts +311 -0
  287. package/work/vendor/hermes-agent/LICENSE +21 -0
  288. package/work/vendor/hermes-agent/skills/productivity/docx/LICENSE +21 -0
  289. package/work/vendor/hermes-agent/skills/productivity/docx/SKILL.md +196 -0
  290. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_comments.py +289 -0
  291. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_common.py +94 -0
  292. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_create.py +177 -0
  293. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_edit.py +250 -0
  294. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_read.py +149 -0
  295. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_revisions.py +147 -0
  296. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_template.py +70 -0
  297. package/work/vendor/hermes-agent/skills/productivity/docx/scripts/docx_validate.py +156 -0
  298. package/work/vendor/hermes-agent/skills/productivity/pdf/LICENSE +21 -0
  299. package/work/vendor/hermes-agent/skills/productivity/pdf/SKILL.md +125 -0
  300. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/_raster.py +76 -0
  301. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/extract_marker.py +88 -0
  302. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/extract_pymupdf.py +101 -0
  303. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_create.py +130 -0
  304. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_fill_form.py +97 -0
  305. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_form_layout.py +168 -0
  306. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_make_form.py +145 -0
  307. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_merge.py +50 -0
  308. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_meta.py +115 -0
  309. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_page_image.py +99 -0
  310. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_read.py +153 -0
  311. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_secure.py +71 -0
  312. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_split.py +84 -0
  313. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_stamp.py +143 -0
  314. package/work/vendor/hermes-agent/skills/productivity/pdf/scripts/pdf_watermark.py +51 -0
  315. package/work/vendor/hermes-agent/skills/productivity/powerpoint/LICENSE +21 -0
  316. package/work/vendor/hermes-agent/skills/productivity/powerpoint/SKILL.md +220 -0
  317. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_create.py +214 -0
  318. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_edit.py +436 -0
  319. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_from_template.py +88 -0
  320. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_read.py +131 -0
  321. package/work/vendor/hermes-agent/skills/productivity/powerpoint/scripts/pptx_render.py +93 -0
  322. package/work/vendor/hermes-agent/skills/productivity/xlsx/LICENSE +21 -0
  323. package/work/vendor/hermes-agent/skills/productivity/xlsx/SKILL.md +196 -0
  324. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/csv_to_xlsx.py +104 -0
  325. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_create.py +259 -0
  326. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_edit.py +263 -0
  327. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_read.py +160 -0
  328. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_recalc.py +111 -0
  329. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_restructure.py +337 -0
  330. package/work/vendor/hermes-agent/skills/productivity/xlsx/scripts/xlsx_to_csv.py +69 -0
  331. package/work/vendor-lock.json +11 -0
@@ -0,0 +1,360 @@
1
+ /**
2
+ * Structured Git tool factories and aggregator.
3
+ *
4
+ * Tools cover status, diff, commit, and PR handoff. Branch, worktree, and patch application are
5
+ * not tools: `shell` runs `git`, and worktrees belong to the `workspace` service (plan 189 Task 8).
6
+ * Shell is never used internally; all Git invocations go through typed arg arrays.
7
+ */
8
+ import type { JsonObject, ToolDefinition, ToolExecutionContext, ToolResult } from "@arnilo/prism";
9
+ import { type CodingCheckToolOptions, createCodingCheckTool, type NamedCheckDefinition } from "./checks.js";
10
+ import { CODING_LOCAL_EFFECT, CODING_OBSERVATION_EFFECT, CODING_UNSUPPORTED_EFFECT } from "./effects.js";
11
+ import { enforceExecutionPolicy } from "./execution-policy.js";
12
+ import {
13
+ type ArtifactWriter,
14
+ type CreateGitOperationsOptions,
15
+ createGitOperations,
16
+ GitError,
17
+ type GitOperations,
18
+ type PrHandoff,
19
+ } from "./git.js";
20
+ import type { ExecutionPolicy } from "./execution-policy.js";
21
+
22
+ export interface GitToolsOptions {
23
+ readonly executionPolicy?: ExecutionPolicy;
24
+ readonly gitPath?: string;
25
+ readonly execFile?: CreateGitOperationsOptions["execFile"];
26
+ readonly runner?: CreateGitOperationsOptions["runner"];
27
+ readonly artifactWriter?: ArtifactWriter;
28
+ readonly commitIdentity?: CreateGitOperationsOptions["commitIdentity"];
29
+ readonly limits?: CreateGitOperationsOptions;
30
+ readonly operations?: GitOperations;
31
+ /** Optional named checks included by `createGitTools` when provided. */
32
+ readonly checks?: Readonly<Record<string, NamedCheckDefinition>>;
33
+ readonly checkOptions?: Omit<CodingCheckToolOptions, "checks" | "executionPolicy">;
34
+ }
35
+
36
+ function errorResult(toolName: string, toolCallId: string, message: string): ToolResult {
37
+ return {
38
+ toolCallId,
39
+ name: toolName,
40
+ content: [{ type: "text", text: message }],
41
+ error: { message },
42
+ };
43
+ }
44
+
45
+ function messageOf(error: unknown): string {
46
+ if (error instanceof GitError) return error.message;
47
+ if (error instanceof Error) return error.message;
48
+ return String(error);
49
+ }
50
+
51
+ function opsFactory(cwd: string, options?: GitToolsOptions): () => Promise<GitOperations> {
52
+ if (options?.operations) {
53
+ const ops = options.operations;
54
+ return async () => ops;
55
+ }
56
+ let cached: Promise<GitOperations> | undefined;
57
+ return () => {
58
+ cached ??= createGitOperations({
59
+ cwd,
60
+ gitPath: options?.gitPath,
61
+ execFile: options?.execFile,
62
+ runner: options?.runner,
63
+ artifactWriter: options?.artifactWriter,
64
+ commitIdentity: options?.commitIdentity,
65
+ ...(options?.limits ?? {}),
66
+ });
67
+ return cached;
68
+ };
69
+ }
70
+
71
+ export function createGitStatusTool(cwd: string, options?: GitToolsOptions): ToolDefinition {
72
+ const getOps = opsFactory(cwd, options);
73
+ return {
74
+ name: "git_status",
75
+ effect: CODING_OBSERVATION_EFFECT,
76
+ effects: ["read"],
77
+ description:
78
+ "Return structured Git status (porcelain v2) including branch metadata and dirty-state. Does not follow shell; paths are repository-relative.",
79
+ parameters: {
80
+ type: "object",
81
+ properties: {
82
+ includeIgnored: { type: "boolean", description: "Include ignored files (default false)" },
83
+ },
84
+ additionalProperties: false,
85
+ } as JsonObject,
86
+ async execute(args, context: ToolExecutionContext): Promise<ToolResult> {
87
+ const toolCallId = context.toolCallId;
88
+ if (context.signal?.aborted) return errorResult("git_status", toolCallId, "Operation aborted");
89
+ const includeIgnored = args.includeIgnored === true;
90
+ const policy = await enforceExecutionPolicy(
91
+ options?.executionPolicy,
92
+ {
93
+ kind: "git",
94
+ operation: "status",
95
+ paths: [cwd],
96
+ risk: "low",
97
+ metadata: { includeIgnored, sessionId: context.sessionId, runId: context.runId },
98
+ },
99
+ toolCallId,
100
+ "git_status",
101
+ );
102
+ if (!policy.allowed) return policy.result;
103
+ try {
104
+ const status = await (await getOps()).status({ includeIgnored, signal: context.signal });
105
+ const lines = [
106
+ `branch=${status.branch.head ?? "(detached)"} oid=${status.branch.oid ?? "(initial)"} dirty=${status.dirty}`,
107
+ ...status.entries.map((e) => `${e.kind}\t${e.xy}\t${e.path}${e.origPath ? `\t${e.origPath}` : ""}`),
108
+ ];
109
+ return {
110
+ toolCallId,
111
+ name: "git_status",
112
+ content: [{ type: "text", text: lines.join("\n") }],
113
+ metadata: { ...status },
114
+ };
115
+ } catch (error) {
116
+ return errorResult("git_status", toolCallId, messageOf(error));
117
+ }
118
+ },
119
+ };
120
+ }
121
+
122
+ export function createGitDiffTool(cwd: string, options?: GitToolsOptions): ToolDefinition {
123
+ const getOps = opsFactory(cwd, options);
124
+ return {
125
+ name: "git_diff",
126
+ effect: CODING_OBSERVATION_EFFECT,
127
+ effects: ["read"],
128
+ description:
129
+ "Return a bounded unified diff (--no-ext-diff --no-textconv). Large diffs truncate inline and may spill through the host artifact writer.",
130
+ parameters: {
131
+ type: "object",
132
+ properties: {
133
+ staged: { type: "boolean", description: "Diff the index (default false)" },
134
+ paths: {
135
+ type: "array",
136
+ items: { type: "string" },
137
+ description: "Optional pathspecs (passed after --)",
138
+ },
139
+ },
140
+ additionalProperties: false,
141
+ } as JsonObject,
142
+ async execute(args, context: ToolExecutionContext): Promise<ToolResult> {
143
+ const toolCallId = context.toolCallId;
144
+ if (context.signal?.aborted) return errorResult("git_diff", toolCallId, "Operation aborted");
145
+ const staged = args.staged === true;
146
+ const paths = Array.isArray(args.paths) ? (args.paths as string[]) : undefined;
147
+ const policy = await enforceExecutionPolicy(
148
+ options?.executionPolicy,
149
+ {
150
+ kind: "git",
151
+ operation: "diff",
152
+ paths: paths ?? [cwd],
153
+ risk: "low",
154
+ metadata: { staged, sessionId: context.sessionId, runId: context.runId },
155
+ },
156
+ toolCallId,
157
+ "git_diff",
158
+ );
159
+ if (!policy.allowed) return policy.result;
160
+ try {
161
+ const result = await (await getOps()).diff({ staged, paths, signal: context.signal });
162
+ const suffix = result.truncated
163
+ ? `\n[truncated after ${result.lineCount} lines${result.artifact ? `; artifact ${result.artifact.uri}` : ""}]`
164
+ : "";
165
+ return {
166
+ toolCallId,
167
+ name: "git_diff",
168
+ content: [{ type: "text", text: `${result.text}${suffix}`.trim() || "(empty diff)" }],
169
+ metadata: {
170
+ truncated: result.truncated,
171
+ lineCount: result.lineCount,
172
+ artifact: result.artifact,
173
+ },
174
+ };
175
+ } catch (error) {
176
+ return errorResult("git_diff", toolCallId, messageOf(error));
177
+ }
178
+ },
179
+ };
180
+ }
181
+
182
+ export function createGitCommitTool(cwd: string, options?: GitToolsOptions): ToolDefinition {
183
+ const getOps = opsFactory(cwd, options);
184
+ return {
185
+ name: "git_commit",
186
+ effect: CODING_LOCAL_EFFECT,
187
+ effects: ["write"],
188
+ description:
189
+ "Stage and commit explicit paths only (never `git add -A`). Refuses dirty unrelated worktrees unless createCheckpoint=true. Uses --no-verify and a temp message file; never pushes.",
190
+ exclusive: true,
191
+ parameters: {
192
+ type: "object",
193
+ properties: {
194
+ paths: {
195
+ type: "array",
196
+ items: { type: "string" },
197
+ description: "Exact paths to stage and commit",
198
+ },
199
+ message: { type: "string", description: "Commit message" },
200
+ createCheckpoint: {
201
+ type: "boolean",
202
+ description: "Stash checkpoint first when the tree is already dirty",
203
+ },
204
+ },
205
+ required: ["paths", "message"],
206
+ additionalProperties: false,
207
+ } as JsonObject,
208
+ async execute(args, context: ToolExecutionContext): Promise<ToolResult> {
209
+ const toolCallId = context.toolCallId;
210
+ if (context.signal?.aborted) return errorResult("git_commit", toolCallId, "Operation aborted");
211
+ const paths = Array.isArray(args.paths) ? (args.paths as string[]) : [];
212
+ const message = typeof args.message === "string" ? args.message : "";
213
+ const createCheckpoint = args.createCheckpoint === true;
214
+ const policy = await enforceExecutionPolicy(
215
+ options?.executionPolicy,
216
+ {
217
+ kind: "git",
218
+ operation: "commit",
219
+ paths,
220
+ risk: "high",
221
+ metadata: { createCheckpoint, sessionId: context.sessionId, runId: context.runId },
222
+ },
223
+ toolCallId,
224
+ "git_commit",
225
+ );
226
+ if (!policy.allowed) return policy.result;
227
+ try {
228
+ const result = await (await getOps()).commit({
229
+ paths,
230
+ message,
231
+ createCheckpoint,
232
+ signal: context.signal,
233
+ });
234
+ return {
235
+ toolCallId,
236
+ name: "git_commit",
237
+ content: [{ type: "text", text: `committed ${result.sha}` }],
238
+ metadata: result,
239
+ };
240
+ } catch (error) {
241
+ return errorResult("git_commit", toolCallId, messageOf(error));
242
+ }
243
+ },
244
+ };
245
+ }
246
+
247
+ export function createGitPrHandoffTool(cwd: string, options?: GitToolsOptions): ToolDefinition {
248
+ const getOps = opsFactory(cwd, options);
249
+ return {
250
+ name: "git_pr_handoff",
251
+ effect: CODING_UNSUPPORTED_EFFECT,
252
+ effects: ["external", "network"],
253
+ description:
254
+ "Build a bounded host-owned PR handoff payload (base/head/commits/paths/diffstat/checks/artifact). Never pushes, authenticates, or opens a PR.",
255
+ exclusive: true,
256
+ parameters: {
257
+ type: "object",
258
+ properties: {
259
+ base: { type: "string", description: "Base ref/commit for the handoff" },
260
+ head: { type: "string", description: "Head ref/commit (default HEAD)" },
261
+ includeBundle: {
262
+ type: "boolean",
263
+ description: "Prefer a git bundle artifact over a patch when an artifact writer is configured",
264
+ },
265
+ checks: {
266
+ type: "array",
267
+ description: "Optional check summaries to embed",
268
+ items: {
269
+ type: "object",
270
+ properties: {
271
+ name: { type: "string" },
272
+ exitCode: { type: "number" },
273
+ summary: { type: "string" },
274
+ },
275
+ },
276
+ },
277
+ },
278
+ required: ["base"],
279
+ additionalProperties: false,
280
+ } as JsonObject,
281
+ async execute(args, context: ToolExecutionContext): Promise<ToolResult> {
282
+ const toolCallId = context.toolCallId;
283
+ if (context.signal?.aborted) return errorResult("git_pr_handoff", toolCallId, "Operation aborted");
284
+ const base = typeof args.base === "string" ? args.base : "";
285
+ const head = typeof args.head === "string" ? args.head : undefined;
286
+ const includeBundle = args.includeBundle === true;
287
+ const checks = Array.isArray(args.checks) ? (args.checks as Array<{ name: string; exitCode: number; summary: string }>) : undefined;
288
+ const policy = await enforceExecutionPolicy(
289
+ options?.executionPolicy,
290
+ {
291
+ kind: "git",
292
+ operation: "pr_handoff",
293
+ paths: [cwd],
294
+ risk: "medium",
295
+ metadata: { base, head, includeBundle, sessionId: context.sessionId, runId: context.runId },
296
+ },
297
+ toolCallId,
298
+ "git_pr_handoff",
299
+ );
300
+ if (!policy.allowed) return policy.result;
301
+ try {
302
+ const handoff: PrHandoff = await (await getOps()).prHandoff({
303
+ base,
304
+ head,
305
+ checks,
306
+ includeBundle,
307
+ signal: context.signal,
308
+ });
309
+ return {
310
+ toolCallId,
311
+ name: "git_pr_handoff",
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: JSON.stringify(
316
+ {
317
+ base: handoff.base,
318
+ head: handoff.head,
319
+ commits: handoff.commits.length,
320
+ changedPaths: handoff.changedPaths.length,
321
+ diffstat: handoff.diffstat,
322
+ checks: handoff.checks,
323
+ artifact: handoff.artifact,
324
+ },
325
+ null,
326
+ 2,
327
+ ),
328
+ },
329
+ ],
330
+ metadata: { ...handoff } as Readonly<Record<string, unknown>>,
331
+ };
332
+ } catch (error) {
333
+ return errorResult("git_pr_handoff", toolCallId, messageOf(error));
334
+ }
335
+ },
336
+ };
337
+ }
338
+
339
+ /**
340
+ * Structured Git tool set. Optionally appends `coding_check` when `checks` are declared.
341
+ * Not included in `createCodingTools()` — hosts opt in explicitly.
342
+ */
343
+ export function createGitTools(cwd: string, options?: GitToolsOptions): readonly ToolDefinition[] {
344
+ const tools: ToolDefinition[] = [
345
+ createGitStatusTool(cwd, options),
346
+ createGitDiffTool(cwd, options),
347
+ createGitCommitTool(cwd, options),
348
+ createGitPrHandoffTool(cwd, options),
349
+ ];
350
+ if (options?.checks) {
351
+ tools.push(
352
+ createCodingCheckTool(cwd, {
353
+ checks: options.checks,
354
+ executionPolicy: options.executionPolicy,
355
+ ...(options.checkOptions ?? {}),
356
+ }),
357
+ );
358
+ }
359
+ return tools;
360
+ }