@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,392 @@
1
+ /**
2
+ * One construction path for coding tools with an explicit workspace mode.
3
+ *
4
+ * `workspaceMode` is required. Sandbox shell + host FS is fail-closed unless
5
+ * `allowMixedWorkspaceWiring` is set. Sandbox mode needs agreeing FS/repo
6
+ * backends (host-supplied custom ops, or DisposableSandbox auto-wire).
7
+ *
8
+ * Git/check stay opt-in: `createGitTools(composition.workspaceRoot, {
9
+ * execFile: sandbox.execFile.bind(sandbox), commitIdentity, checks?
10
+ * })` so runners share the same tree/cwd. Not folded into coding tools.
11
+ */
12
+ import type { ToolDefinition } from "@arnilo/prism";
13
+ import {
14
+ createCodingTools,
15
+ createReadOnlyTools,
16
+ type DeleteOperations,
17
+ type DeleteToolOptions,
18
+ type EditOperations,
19
+ type EditToolOptions,
20
+ type MoveOperations,
21
+ type MoveToolOptions,
22
+ type ReadOperations,
23
+ type ReadToolOptions,
24
+ type RepositoryLimitOptions,
25
+ type RepositoryOperations,
26
+ type GrepToolOptions,
27
+ type ShellToolOptions,
28
+ type ToolsOptions,
29
+ type WriteOperations,
30
+ type WriteToolOptions,
31
+ } from "../agent/index.js";
32
+ import {
33
+ createSandboxBashOperations,
34
+ type DisposableSandbox,
35
+ type SandboxAdapter,
36
+ type SandboxCapabilities,
37
+ type SandboxExportMetadata,
38
+ } from "./sandbox.js";
39
+ import { createSandboxFilesystemOperations, createSandboxRepositoryOperations } from "./sandbox-fs-operations.js";
40
+ import type { ExecutionPolicy } from "../agent/execution-policy.js";
41
+
42
+ export type WorkspaceMode = "host" | "sandbox";
43
+
44
+ /** Every capability false; the conservative default for unknown/omitted metadata. */
45
+ const EMPTY_SANDBOX_CAPABILITIES: SandboxCapabilities = Object.freeze({
46
+ workspaceCoherent: false,
47
+ filesystemIsolated: false,
48
+ networkIsolated: false,
49
+ processIsolated: false,
50
+ privilegeIsolated: false,
51
+ egressRestricted: false,
52
+ });
53
+
54
+ const CAPABILITY_KEYS = [
55
+ "workspaceCoherent",
56
+ "filesystemIsolated",
57
+ "networkIsolated",
58
+ "processIsolated",
59
+ "privilegeIsolated",
60
+ "egressRestricted",
61
+ ] as const;
62
+
63
+ /**
64
+ * Resolve a sandbox adapter's capability attestation into a frozen, complete
65
+ * capability object. Omitted metadata, non-object values, missing fields,
66
+ * non-boolean values, and unknown keys all fail closed to every-field-false —
67
+ * an adapter can never gain a capability by omission or by interface shape.
68
+ * Explicit metadata is host attestation, copied/validated/frozen; Prism does
69
+ * not verify the underlying controls.
70
+ */
71
+ export function resolveSandboxCapabilities(sandbox: SandboxAdapter | undefined): SandboxCapabilities {
72
+ const metadata = sandbox?.capabilities;
73
+ if (!metadata || typeof metadata !== "object") return EMPTY_SANDBOX_CAPABILITIES;
74
+ const keys = Object.keys(metadata);
75
+ if (keys.length !== CAPABILITY_KEYS.length) return EMPTY_SANDBOX_CAPABILITIES;
76
+ for (const key of CAPABILITY_KEYS) {
77
+ if (typeof (metadata as Record<string, unknown>)[key] !== "boolean") return EMPTY_SANDBOX_CAPABILITIES;
78
+ }
79
+ return Object.freeze({
80
+ workspaceCoherent: metadata.workspaceCoherent,
81
+ filesystemIsolated: metadata.filesystemIsolated,
82
+ networkIsolated: metadata.networkIsolated,
83
+ processIsolated: metadata.processIsolated,
84
+ privilegeIsolated: metadata.privilegeIsolated,
85
+ egressRestricted: metadata.egressRestricted,
86
+ });
87
+ }
88
+
89
+ export interface SandboxCodingComposition {
90
+ readonly workspaceMode: WorkspaceMode;
91
+ /**
92
+ * @deprecated 0.2.0 — use `capabilities`. Conservative projection of
93
+ * `workspaceCoherent && filesystemIsolated && networkIsolated &&
94
+ * processIsolated` (privilege isolation excluded). Never authorize a
95
+ * security-sensitive action from this boolean alone.
96
+ */
97
+ readonly containmentClaim: boolean;
98
+ readonly capabilities: SandboxCapabilities;
99
+ readonly mixedWiringAllowed: boolean;
100
+ readonly warnings: readonly string[];
101
+ readonly workspaceRoot: string;
102
+ readonly treeIdentity?: Pick<SandboxExportMetadata, "sha256" | "entryCount" | "byteCount">;
103
+ }
104
+
105
+ export interface SandboxCodingCompositionResult {
106
+ readonly tools: readonly ToolDefinition[];
107
+ readonly composition: SandboxCodingComposition;
108
+ }
109
+
110
+ export interface SandboxCodingToolsOptions {
111
+ readonly workspaceMode: WorkspaceMode;
112
+ /** Required for `workspaceMode: "sandbox"`. Optional in host mode (preferred: omit). */
113
+ readonly sandbox?: SandboxAdapter;
114
+ /**
115
+ * Escape hatch: allow sandbox shell paired with host-local FS/search backends.
116
+ * Surfaces warnings on composition; forces `containmentClaim: false`.
117
+ */
118
+ readonly allowMixedWorkspaceWiring?: boolean;
119
+ /** Sandbox tree root for mode `"sandbox"` (default `/workspace`). */
120
+ readonly workspaceRoot?: string;
121
+ readonly executionPolicy?: ExecutionPolicy;
122
+ readonly repository?: RepositoryLimitOptions & { operations?: RepositoryOperations };
123
+ readonly shell?: Omit<ShellToolOptions, "operations">;
124
+ readonly read?: ReadToolOptions;
125
+ readonly write?: WriteToolOptions;
126
+ readonly edit?: EditToolOptions;
127
+ readonly delete?: DeleteToolOptions;
128
+ readonly move?: MoveToolOptions;
129
+ readonly search?: GrepToolOptions;
130
+ }
131
+
132
+ export class SandboxCodingCompositionError extends Error {
133
+ readonly code = "ERR_PRISM_SANDBOX_CODING_COMPOSITION";
134
+ constructor(message: string) {
135
+ super(message);
136
+ this.name = "SandboxCodingCompositionError";
137
+ }
138
+ }
139
+
140
+ const DEFAULT_SANDBOX_WORKSPACE_ROOT = "/workspace";
141
+ const MIXED_WIRING_WARNING = "mixed workspace wiring: sandbox shell with host filesystem backends; containment not claimed";
142
+
143
+ function isDisposableSandbox(sandbox: SandboxAdapter): sandbox is DisposableSandbox {
144
+ const candidate = sandbox as DisposableSandbox;
145
+ return typeof candidate.execFile === "function" && typeof candidate.close === "function";
146
+ }
147
+
148
+ function treeIdentityFromSandbox(
149
+ sandbox: SandboxAdapter | undefined,
150
+ ): Pick<SandboxExportMetadata, "sha256" | "entryCount" | "byteCount"> | undefined {
151
+ if (!sandbox || !isDisposableSandbox(sandbox)) return undefined;
152
+ const id = sandbox.importIdentity ?? sandbox.lastExportIdentity;
153
+ if (!id) return undefined;
154
+ return { sha256: id.sha256, entryCount: id.entryCount, byteCount: id.byteCount };
155
+ }
156
+
157
+ function hasCustomOperations(options: SandboxCodingToolsOptions, kind: "full" | "readonly"): boolean {
158
+ const repoOps = options.repository?.operations ?? options.search?.operations;
159
+ const readOk = options.read?.operations !== undefined;
160
+ const repoOk = repoOps !== undefined;
161
+ if (kind === "readonly") return readOk && repoOk;
162
+ return (
163
+ readOk &&
164
+ options.write?.operations !== undefined &&
165
+ options.edit?.operations !== undefined &&
166
+ options.delete?.operations !== undefined &&
167
+ options.move?.operations !== undefined &&
168
+ repoOk
169
+ );
170
+ }
171
+
172
+ /**
173
+ * Auto-wire DisposableSandbox execFile backends for sandbox mode.
174
+ */
175
+ function tryAutoWireSandboxTreeOperations(
176
+ sandbox: DisposableSandbox,
177
+ workspaceRoot: string,
178
+ repositoryLimits?: RepositoryLimitOptions,
179
+ ): {
180
+ read: ReadOperations;
181
+ write: WriteOperations;
182
+ edit: EditOperations;
183
+ delete: DeleteOperations;
184
+ move: MoveOperations;
185
+ repository: RepositoryOperations;
186
+ } {
187
+ const fs = createSandboxFilesystemOperations(sandbox, { workspaceRoot });
188
+ const repository = createSandboxRepositoryOperations(sandbox, {
189
+ workspaceRoot,
190
+ limits: repositoryLimits,
191
+ });
192
+ return {
193
+ read: fs.read,
194
+ write: fs.write,
195
+ edit: fs.edit,
196
+ delete: fs.delete,
197
+ move: fs.move,
198
+ repository,
199
+ };
200
+ }
201
+
202
+ function requireWorkspaceMode(options: SandboxCodingToolsOptions): WorkspaceMode {
203
+ const mode = options.workspaceMode;
204
+ if (mode !== "host" && mode !== "sandbox") {
205
+ throw new SandboxCodingCompositionError('workspaceMode is required and must be "host" or "sandbox"');
206
+ }
207
+ return mode;
208
+ }
209
+
210
+ function resolveCompositionCapabilities(
211
+ sandbox: SandboxAdapter | undefined,
212
+ workspaceMode: WorkspaceMode,
213
+ backendsBound: boolean,
214
+ mixedWiringAllowed: boolean,
215
+ warnings: readonly string[],
216
+ sandboxShell: boolean,
217
+ ): SandboxCapabilities {
218
+ // Workspace coherence derives from actual wiring; isolation fields derive
219
+ // only from validated adapter capability metadata — never from execFile/close
220
+ // duck typing or custom operations being present.
221
+ const coherent = workspaceMode === "sandbox" ? backendsBound && !mixedWiringAllowed && warnings.length === 0 : !sandboxShell;
222
+ if (!coherent) return EMPTY_SANDBOX_CAPABILITIES;
223
+ const isolated = resolveSandboxCapabilities(sandbox);
224
+ return Object.freeze({
225
+ workspaceCoherent: true,
226
+ filesystemIsolated: isolated.filesystemIsolated,
227
+ networkIsolated: isolated.networkIsolated,
228
+ processIsolated: isolated.processIsolated,
229
+ privilegeIsolated: isolated.privilegeIsolated,
230
+ egressRestricted: isolated.egressRestricted,
231
+ });
232
+ }
233
+
234
+ function resolveComposition(
235
+ cwd: string,
236
+ options: SandboxCodingToolsOptions,
237
+ kind: "full" | "readonly",
238
+ ): { toolsOptions: ToolsOptions; composition: SandboxCodingComposition; toolCwd: string } {
239
+ const workspaceMode = requireWorkspaceMode(options);
240
+ const mixedWiringAllowed = options.allowMixedWorkspaceWiring === true;
241
+ const warnings: string[] = [];
242
+ const sandbox = options.sandbox;
243
+
244
+ if (workspaceMode === "host") {
245
+ const workspaceRoot = cwd;
246
+ const sandboxShell = sandbox !== undefined && kind === "full";
247
+ if (sandboxShell && !mixedWiringAllowed) {
248
+ throw new SandboxCodingCompositionError(
249
+ "host mode with sandbox shell uses host filesystem backends (mixed wiring); " +
250
+ "set allowMixedWorkspaceWiring: true or omit sandbox for local shell",
251
+ );
252
+ }
253
+ if (sandboxShell) warnings.push(MIXED_WIRING_WARNING);
254
+
255
+ const toolsOptions: ToolsOptions = {
256
+ executionPolicy: options.executionPolicy,
257
+ repository: options.repository,
258
+ shell: sandboxShell ? { ...options.shell, operations: createSandboxBashOperations(sandbox) } : options.shell,
259
+ read: options.read,
260
+ write: options.write,
261
+ edit: options.edit,
262
+ delete: options.delete,
263
+ move: options.move,
264
+ search: options.search,
265
+ };
266
+
267
+ const capabilities = resolveCompositionCapabilities(sandbox, workspaceMode, false, mixedWiringAllowed, warnings, sandboxShell);
268
+ return {
269
+ toolsOptions,
270
+ toolCwd: cwd,
271
+ composition: {
272
+ workspaceMode,
273
+ containmentClaim: deprecatedContainmentProjection(capabilities),
274
+ capabilities,
275
+ mixedWiringAllowed,
276
+ warnings,
277
+ workspaceRoot,
278
+ },
279
+ };
280
+ }
281
+
282
+ // sandbox mode
283
+ if (!sandbox) {
284
+ throw new SandboxCodingCompositionError('workspaceMode "sandbox" requires options.sandbox');
285
+ }
286
+
287
+ const workspaceRoot = options.workspaceRoot ?? DEFAULT_SANDBOX_WORKSPACE_ROOT;
288
+ let readOps = options.read?.operations;
289
+ let writeOps = options.write?.operations;
290
+ let editOps = options.edit?.operations;
291
+ let deleteOps = options.delete?.operations;
292
+ let moveOps = options.move?.operations;
293
+ let repoOps = options.repository?.operations ?? options.search?.operations;
294
+ let backendsBound = hasCustomOperations(options, kind);
295
+
296
+ if (!backendsBound) {
297
+ if (mixedWiringAllowed) {
298
+ // Explicit split-brain: sandbox shell + host-local FS defaults.
299
+ warnings.push(MIXED_WIRING_WARNING);
300
+ } else if (!isDisposableSandbox(sandbox)) {
301
+ throw new SandboxCodingCompositionError(
302
+ 'workspaceMode "sandbox" requires DisposableSandbox (execFile) for auto-wire, ' +
303
+ "custom read/write/edit/delete/move/repository operations, or allowMixedWorkspaceWiring: true",
304
+ );
305
+ } else {
306
+ const auto = tryAutoWireSandboxTreeOperations(sandbox, workspaceRoot, options.repository);
307
+ readOps = auto.read;
308
+ writeOps = auto.write;
309
+ editOps = auto.edit;
310
+ deleteOps = auto.delete;
311
+ moveOps = auto.move;
312
+ repoOps = auto.repository;
313
+ backendsBound = true;
314
+ }
315
+ }
316
+
317
+ const toolsOptions: ToolsOptions = {
318
+ executionPolicy: options.executionPolicy,
319
+ repository: {
320
+ ...options.repository,
321
+ ...(repoOps ? { operations: repoOps } : {}),
322
+ },
323
+ shell: {
324
+ ...options.shell,
325
+ operations: createSandboxBashOperations(sandbox),
326
+ },
327
+ read: { ...options.read, ...(readOps ? { operations: readOps } : {}) },
328
+ write: { ...options.write, ...(writeOps ? { operations: writeOps } : {}) },
329
+ edit: { ...options.edit, ...(editOps ? { operations: editOps } : {}) },
330
+ delete: { ...options.delete, ...(deleteOps ? { operations: deleteOps } : {}) },
331
+ move: { ...options.move, ...(moveOps ? { operations: moveOps } : {}) },
332
+ search: options.search,
333
+ };
334
+
335
+ const capabilities = resolveCompositionCapabilities(sandbox, workspaceMode, backendsBound, mixedWiringAllowed, warnings, false);
336
+ // Bound sandbox backends observe the container tree — tools must resolve under workspaceRoot.
337
+ const toolCwd = backendsBound ? workspaceRoot : cwd;
338
+ const treeIdentity = treeIdentityFromSandbox(sandbox);
339
+
340
+ return {
341
+ toolsOptions,
342
+ toolCwd,
343
+ composition: {
344
+ workspaceMode,
345
+ containmentClaim: deprecatedContainmentProjection(capabilities),
346
+ capabilities,
347
+ mixedWiringAllowed,
348
+ warnings,
349
+ workspaceRoot,
350
+ ...(treeIdentity ? { treeIdentity } : {}),
351
+ },
352
+ };
353
+ }
354
+
355
+ /**
356
+ * @deprecated 0.2.0 — conservative projection of the full capability object:
357
+ * `workspaceCoherent && filesystemIsolated && networkIsolated &&
358
+ * processIsolated` (privilege isolation excluded because root-in-container
359
+ * without user namespaces is unreliable). Kept for 0.1.7 compatibility; never
360
+ * authorize a security-sensitive action from this boolean alone.
361
+ */
362
+ function deprecatedContainmentProjection(capabilities: SandboxCapabilities): boolean {
363
+ return capabilities.workspaceCoherent && capabilities.filesystemIsolated && capabilities.networkIsolated && capabilities.processIsolated;
364
+ }
365
+
366
+ /** Authoritative construction path: tools plus composition metadata. */
367
+ export function createSandboxCodingComposition(cwd: string, options: SandboxCodingToolsOptions): SandboxCodingCompositionResult {
368
+ const { toolsOptions, composition, toolCwd } = resolveComposition(cwd, options, "full");
369
+ return {
370
+ tools: createCodingTools(toolCwd, toolsOptions),
371
+ composition,
372
+ };
373
+ }
374
+
375
+ /** Read-only construction path with the same workspace-mode contract. */
376
+ export function createSandboxReadOnlyComposition(cwd: string, options: SandboxCodingToolsOptions): SandboxCodingCompositionResult {
377
+ const { toolsOptions, composition, toolCwd } = resolveComposition(cwd, options, "readonly");
378
+ return {
379
+ tools: createReadOnlyTools(toolCwd, toolsOptions),
380
+ composition,
381
+ };
382
+ }
383
+
384
+ /** Full coding set; returns tools only (compat wrapper). */
385
+ export function createSandboxCodingTools(cwd: string, options: SandboxCodingToolsOptions): readonly ToolDefinition[] {
386
+ return createSandboxCodingComposition(cwd, options).tools;
387
+ }
388
+
389
+ /** Read-only coding set; returns tools only (compat wrapper). */
390
+ export function createSandboxReadOnlyTools(cwd: string, options: SandboxCodingToolsOptions): readonly ToolDefinition[] {
391
+ return createSandboxReadOnlyComposition(cwd, options).tools;
392
+ }