@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,316 @@
1
+ /**
2
+ * Structural Playwright surfaces used by Prism browser tools.
3
+ * Hosts supply a real Playwright Browser; tests supply fakes.
4
+ * No Playwright import occurs at package load time.
5
+ */
6
+
7
+ export type BrowserActionName =
8
+ | "navigate"
9
+ | "click"
10
+ | "type"
11
+ | "fill"
12
+ | "select"
13
+ | "check"
14
+ | "uncheck"
15
+ | "scroll"
16
+ | "wait"
17
+ | "dialog"
18
+ | "select_page"
19
+ | "upload"
20
+ | "screenshot"
21
+ | "download_release"
22
+ | "block_urls"
23
+ | "unblock_urls"
24
+ | "throttle"
25
+ | "emulate";
26
+
27
+ export type BrowserTarget =
28
+ | { readonly ref: string }
29
+ | { readonly role: string; readonly name?: string; readonly exact?: boolean }
30
+ | { readonly label: string; readonly exact?: boolean }
31
+ | { readonly testId: string }
32
+ | { readonly text: string; readonly exact?: boolean }
33
+ | { readonly css: string }
34
+ | { readonly xpath: string };
35
+
36
+ export interface BrowserActRequest {
37
+ readonly action: BrowserActionName;
38
+ readonly target?: BrowserTarget;
39
+ readonly snapshotId?: string;
40
+ readonly pageId?: string;
41
+ readonly url?: string;
42
+ readonly text?: string;
43
+ readonly values?: readonly string[];
44
+ readonly paths?: readonly string[];
45
+ readonly downloadId?: string;
46
+ readonly fullPage?: boolean;
47
+ readonly clip?: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };
48
+ readonly direction?: "up" | "down";
49
+ readonly amount?: number;
50
+ readonly timeoutMs?: number;
51
+ readonly dialogResponse?: "accept" | "dismiss";
52
+ readonly promptText?: string;
53
+ /** CDP: URL patterns to block (block_urls) — bounded by maxBlockedUrlPatterns. */
54
+ readonly patterns?: readonly string[];
55
+ /** CDP: offline flag (throttle). */
56
+ readonly offline?: boolean;
57
+ /** CDP: network latency in ms (throttle), capped. */
58
+ readonly latencyMs?: number;
59
+ /** CDP: download throughput in kbps (throttle), capped. */
60
+ readonly downloadKbps?: number;
61
+ /** CDP: upload throughput in kbps (throttle), capped. */
62
+ readonly uploadKbps?: number;
63
+ /** CDP: reset current throttle/emulation (throttle/emulate). */
64
+ readonly reset?: boolean;
65
+ /** CDP: viewport width px (emulate), capped. */
66
+ readonly width?: number;
67
+ /** CDP: viewport height px (emulate), capped. */
68
+ readonly height?: number;
69
+ /** CDP: mobile viewport flag (emulate). */
70
+ readonly mobile?: boolean;
71
+ /** CDP: device scale factor (emulate), capped. */
72
+ readonly deviceScaleFactor?: number;
73
+ /** CDP: user-agent override (emulate); only applied when explicitly supplied. */
74
+ readonly userAgent?: string;
75
+ }
76
+
77
+ export interface SnapshotRefInfo {
78
+ readonly ref: string;
79
+ readonly role?: string;
80
+ readonly name?: string;
81
+ }
82
+
83
+ export interface BrowserSnapshotResult {
84
+ readonly snapshotId: string;
85
+ readonly pageId: string;
86
+ readonly url: string;
87
+ readonly title: string;
88
+ readonly ariaSnapshot: string;
89
+ readonly refCount: number;
90
+ readonly truncated: boolean;
91
+ readonly truncatedBy?: "bytes" | "refs" | "depth";
92
+ }
93
+
94
+ export interface BrowserPageInfo {
95
+ readonly pageId: string;
96
+ readonly url: string;
97
+ readonly title: string;
98
+ readonly active: boolean;
99
+ readonly kind?: "main" | "popup";
100
+ }
101
+
102
+ export interface BrowserDownloadInfo {
103
+ readonly downloadId: string;
104
+ readonly suggestedName: string;
105
+ readonly bytes: number;
106
+ readonly sha256: string;
107
+ readonly mimeType?: string;
108
+ readonly released: boolean;
109
+ readonly url: string;
110
+ }
111
+
112
+ /** Minimal Locator surface used by Prism. */
113
+ export interface PlaywrightLocator {
114
+ click(options?: { timeout?: number }): Promise<void>;
115
+ fill(value: string, options?: { timeout?: number }): Promise<void>;
116
+ type?(text: string, options?: { timeout?: number; delay?: number }): Promise<void>;
117
+ pressSequentially?(text: string, options?: { timeout?: number; delay?: number }): Promise<void>;
118
+ selectOption(
119
+ values: string | readonly string[] | { label?: string; value?: string } | ReadonlyArray<{ label?: string; value?: string }>,
120
+ options?: { timeout?: number },
121
+ ): Promise<string[]>;
122
+ check(options?: { timeout?: number }): Promise<void>;
123
+ uncheck(options?: { timeout?: number }): Promise<void>;
124
+ scrollIntoViewIfNeeded?(options?: { timeout?: number }): Promise<void>;
125
+ setInputFiles?(
126
+ files: string | readonly string[] | { name: string; mimeType: string; buffer: Buffer },
127
+ options?: { timeout?: number },
128
+ ): Promise<void>;
129
+ count(): Promise<number>;
130
+ first(): PlaywrightLocator;
131
+ nth(index: number): PlaywrightLocator;
132
+ }
133
+
134
+ export interface PlaywrightDialog {
135
+ type(): string;
136
+ message(): string;
137
+ accept(promptText?: string): Promise<void>;
138
+ dismiss(): Promise<void>;
139
+ }
140
+
141
+ export interface PlaywrightRequest {
142
+ url(): string;
143
+ resourceType?(): string;
144
+ redirectedFrom?(): PlaywrightRequest | null;
145
+ method?(): string;
146
+ }
147
+
148
+ export interface PlaywrightRoute {
149
+ request(): PlaywrightRequest;
150
+ continue(options?: { url?: string; headers?: Record<string, string> }): Promise<void>;
151
+ abort(errorCode?: string): Promise<void>;
152
+ fulfill?(options?: { status?: number; body?: string | Buffer; contentType?: string }): Promise<void>;
153
+ }
154
+
155
+ export interface PlaywrightDownload {
156
+ url(): string;
157
+ suggestedFilename(): string;
158
+ createReadStream?(): Promise<NodeJS.ReadableStream | null>;
159
+ saveAs?(path: string): Promise<void>;
160
+ cancel?(): Promise<void>;
161
+ failure?(): Promise<string | null>;
162
+ }
163
+
164
+ export interface PlaywrightPage {
165
+ readonly url: () => string;
166
+ title(): Promise<string>;
167
+ goto(url: string, options?: { timeout?: number; waitUntil?: "load" | "domcontentloaded" | "networkidle" | "commit" }): Promise<unknown>;
168
+ ariaSnapshot(options?: { mode?: "ai" | "default"; depth?: number; boxes?: boolean; timeout?: number }): Promise<string>;
169
+ screenshot?(options?: {
170
+ type?: "png" | "jpeg";
171
+ fullPage?: boolean;
172
+ clip?: { x: number; y: number; width: number; height: number };
173
+ timeout?: number;
174
+ }): Promise<Buffer>;
175
+ locator(selector: string): PlaywrightLocator;
176
+ getByRole(role: string, options?: { name?: string | RegExp; exact?: boolean }): PlaywrightLocator;
177
+ getByLabel(text: string | RegExp, options?: { exact?: boolean }): PlaywrightLocator;
178
+ getByTestId(testId: string | RegExp): PlaywrightLocator;
179
+ getByText(text: string | RegExp, options?: { exact?: boolean }): PlaywrightLocator;
180
+ waitForTimeout?(timeout: number): Promise<void>;
181
+ waitForURL?(url: string | RegExp, options?: { timeout?: number }): Promise<void>;
182
+ waitForSelector?(selector: string, options?: { timeout?: number }): Promise<unknown>;
183
+ close(): Promise<void>;
184
+ isClosed(): boolean;
185
+ on(event: "dialog", handler: (dialog: PlaywrightDialog) => void): void;
186
+ on(event: "popup" | "close" | "crash" | "download", handler: (page?: PlaywrightPage | PlaywrightDownload) => void): void;
187
+ off?(event: string, handler: (...args: never[]) => void): void;
188
+ once?(event: string, handler: (...args: never[]) => void): void;
189
+ mouse?: {
190
+ wheel(deltaX: number, deltaY: number): Promise<void>;
191
+ };
192
+ evaluate?<T = unknown>(pageFunction: string | ((arg: unknown) => T | Promise<T>), arg?: unknown): Promise<T>;
193
+ }
194
+
195
+ export interface PlaywrightBrowserContext {
196
+ newPage(): Promise<PlaywrightPage>;
197
+ pages(): PlaywrightPage[];
198
+ close(): Promise<void>;
199
+ on(event: "page" | "download", handler: (pageOrDownload: PlaywrightPage | PlaywrightDownload) => void): void;
200
+ off?(event: string, handler: (...args: never[]) => void): void;
201
+ route?(url: string | RegExp, handler: (route: PlaywrightRoute) => unknown): Promise<void>;
202
+ unroute?(url: string | RegExp, handler?: (route: PlaywrightRoute) => unknown): Promise<void>;
203
+ setDefaultTimeout?(timeout: number): void;
204
+ setDefaultNavigationTimeout?(timeout: number): void;
205
+ /** CDP (Chromium only): page-level Chrome DevTools Protocol session. */
206
+ newCDPSession?(page: PlaywrightPage): Promise<PlaywrightCdpSession>;
207
+ }
208
+
209
+ export interface PlaywrightBrowser {
210
+ newContext(options?: {
211
+ serviceWorkers?: "allow" | "block";
212
+ acceptDownloads?: boolean;
213
+ javaScriptEnabled?: boolean;
214
+ userAgent?: string;
215
+ viewport?: { width: number; height: number } | null;
216
+ // Host may pass storageState; Prism never returns or persists it.
217
+ storageState?: string | { cookies?: unknown[]; origins?: unknown[] };
218
+ proxy?: { server: string; bypass?: string; username?: string; password?: string };
219
+ }): Promise<PlaywrightBrowserContext>;
220
+ isConnected?(): boolean;
221
+ version?(): string;
222
+ close?(): Promise<void>;
223
+ /** CDP (Chromium only): browser-level Chrome DevTools Protocol session. */
224
+ newBrowserCDPSession?(): Promise<PlaywrightCdpSession>;
225
+ }
226
+
227
+ /**
228
+ * Structural Chrome DevTools Protocol session surface (playwright-core CDPSession).
229
+ * Hosts that want CDP tools must supply a Chromium-based Playwright Browser whose
230
+ * contexts expose newCDPSession(page); fakes in tests supply the same surface.
231
+ * No playwright import occurs at package load time.
232
+ */
233
+ export interface PlaywrightCdpSession {
234
+ send<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
235
+ on(event: string, handler: (params: Record<string, unknown>) => void): void;
236
+ off?(event: string, handler: (params: Record<string, unknown>) => void): void;
237
+ detach?(): Promise<void>;
238
+ }
239
+
240
+ /** CDP capability gating for browser tools. Default: "auto" (enabled on Chromium hosts). */
241
+ export interface BrowserCdpOptions {
242
+ /** "auto": use CDP when the host browser exposes page CDP sessions (Chromium); "on": require it; "off": disable CDP tools. */
243
+ readonly mode?: "auto" | "on" | "off";
244
+ }
245
+
246
+ export interface BrowserOpenResult {
247
+ readonly runId: string;
248
+ readonly pageId: string;
249
+ readonly url: string;
250
+ readonly title: string;
251
+ readonly pages: readonly BrowserPageInfo[];
252
+ }
253
+
254
+ export interface BrowserActResult {
255
+ readonly action: BrowserActionName;
256
+ readonly pageId: string;
257
+ readonly url: string;
258
+ readonly title: string;
259
+ readonly dialogHandled?: boolean;
260
+ readonly pages?: readonly BrowserPageInfo[];
261
+ readonly download?: BrowserDownloadInfo;
262
+ readonly uploads?: ReadonlyArray<{ path: string; bytes: number; sha256: string }>;
263
+ readonly screenshotBytes?: number;
264
+ /** Present for screenshot actions; bounded ImageContent (no storage/cookies). */
265
+ readonly image?: import("@arnilo/prism").ImageContent;
266
+ }
267
+
268
+ export interface BrowserEvaluateRequest {
269
+ readonly pageId?: string;
270
+ /** JavaScript expression evaluated in the page context (bounded by maxActionInputBytes). */
271
+ readonly expression: string;
272
+ /** Await promise resolution before returning (Runtime.evaluate awaitPromise). */
273
+ readonly awaitPromise?: boolean;
274
+ /** Per-action timeout, clamped to actionTimeoutMs. */
275
+ readonly timeoutMs?: number;
276
+ }
277
+
278
+ export interface BrowserEvaluateResult {
279
+ readonly pageId: string;
280
+ readonly url: string;
281
+ /** JSON-serializable evaluated value (bounded by maxEvaluateResultBytes). */
282
+ readonly value?: unknown;
283
+ /** Bounded exception description when evaluation threw (page or serialization error). */
284
+ readonly exception?: string;
285
+ /** Result was truncated to the evaluate-result byte cap. */
286
+ readonly truncated?: boolean;
287
+ }
288
+
289
+ /** Bounded console observation entry (Runtime.consoleAPICalled / exceptionThrown). */
290
+ export interface CdpConsoleEntry {
291
+ readonly seq: number;
292
+ readonly type: "log" | "error" | "warning" | "info" | "debug" | "exception" | "assert" | "other";
293
+ /** Bounded argument previews; never raw object graphs. */
294
+ readonly args: readonly string[];
295
+ readonly text?: string;
296
+ }
297
+
298
+ /** Bounded network observation entry (Network.requestWillBeSent / responseReceived / loadingFailed). */
299
+ export interface CdpNetworkEntry {
300
+ readonly seq: number;
301
+ readonly phase: "request" | "response" | "failed";
302
+ readonly requestId: string;
303
+ readonly url: string;
304
+ readonly method?: string;
305
+ readonly status?: number;
306
+ readonly errorText?: string;
307
+ }
308
+
309
+ export interface BrowserObserveResult {
310
+ readonly pageId: string;
311
+ readonly url: string;
312
+ /** Entries since the previous observe call for this page (drain semantics). */
313
+ readonly console: readonly CdpConsoleEntry[];
314
+ readonly network: readonly CdpNetworkEntry[];
315
+ readonly truncated: boolean;
316
+ }
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Realpath-contained upload path approval for browser file inputs.
3
+ */
4
+ import { createHash } from "node:crypto";
5
+ import type { Stats } from "node:fs";
6
+ import { lstat, open, realpath } from "node:fs/promises";
7
+ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
8
+ import { BrowserError } from "./errors.js";
9
+ import type { ResolvedBrowserLimits } from "./limits.js";
10
+
11
+ export interface BrowserUploadOptions {
12
+ /** Absolute workspace roots that may contribute upload files. */
13
+ readonly roots: readonly string[];
14
+ /** Per-file byte cap override (still clamped by resolved limits). */
15
+ readonly maxBytes?: number;
16
+ }
17
+
18
+ export interface ApprovedUploadFile {
19
+ readonly path: string;
20
+ readonly name: string;
21
+ readonly bytes: number;
22
+ readonly sha256: string;
23
+ }
24
+
25
+ export interface UploadBudget {
26
+ count: number;
27
+ aggregateBytes: number;
28
+ }
29
+
30
+ export function createUploadBudget(): UploadBudget {
31
+ return { count: 0, aggregateBytes: 0 };
32
+ }
33
+
34
+ function isPathInside(root: string, target: string): boolean {
35
+ const from = resolve(root);
36
+ const to = resolve(target);
37
+ const rel = relative(from, to);
38
+ return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
39
+ }
40
+
41
+ async function assertInsideRoots(roots: readonly string[], target: string): Promise<string> {
42
+ if (!isAbsolute(target)) {
43
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path must be absolute");
44
+ }
45
+ let targetReal: string;
46
+ try {
47
+ targetReal = await realpath(target);
48
+ } catch {
49
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path does not exist");
50
+ }
51
+ for (const root of roots) {
52
+ if (!isAbsolute(root)) {
53
+ throw new BrowserError("ERR_PRISM_BROWSER_INPUT", "upload root must be absolute");
54
+ }
55
+ let rootReal: string;
56
+ try {
57
+ rootReal = await realpath(root);
58
+ } catch {
59
+ continue;
60
+ }
61
+ if (isPathInside(rootReal, targetReal)) return targetReal;
62
+ }
63
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path escapes approved roots");
64
+ }
65
+
66
+ export async function approveUploadPaths(
67
+ paths: readonly string[],
68
+ options: BrowserUploadOptions,
69
+ limits: ResolvedBrowserLimits,
70
+ budget: UploadBudget,
71
+ ): Promise<readonly ApprovedUploadFile[]> {
72
+ if (!options.roots.length) {
73
+ throw new BrowserError("ERR_PRISM_BROWSER_INPUT", "uploads.roots is required before upload");
74
+ }
75
+ if (paths.length === 0) {
76
+ throw new BrowserError("ERR_PRISM_BROWSER_INPUT", "upload requires at least one path");
77
+ }
78
+ if (budget.count + paths.length > limits.maxUploads) {
79
+ throw new BrowserError("ERR_PRISM_BROWSER_LIMIT", `maxUploads ${limits.maxUploads} exceeded`);
80
+ }
81
+
82
+ const perFileCap = Math.min(options.maxBytes ?? limits.maxUploadBytes, limits.maxUploadBytes);
83
+ const approved: ApprovedUploadFile[] = [];
84
+
85
+ for (const raw of paths) {
86
+ if (typeof raw !== "string" || !raw) {
87
+ throw new BrowserError("ERR_PRISM_BROWSER_INPUT", "upload path must be a non-empty string");
88
+ }
89
+ const abs = isAbsolute(raw) ? raw : resolve(raw);
90
+ // Reject symlink escapes: lstat the leaf; realpath for containment of final target.
91
+ let leafStat: Stats;
92
+ try {
93
+ leafStat = await lstat(abs);
94
+ } catch {
95
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", `upload path not found: ${basename(abs)}`);
96
+ }
97
+ if (leafStat.isSymbolicLink()) {
98
+ // Allow only if the resolved target stays inside roots.
99
+ const parentReal = await realpath(dirname(abs)).catch(() => undefined);
100
+ if (!parentReal) {
101
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload symlink parent is unresolvable");
102
+ }
103
+ }
104
+ if (!leafStat.isFile() && !leafStat.isSymbolicLink()) {
105
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path must be a regular file");
106
+ }
107
+
108
+ const real = await assertInsideRoots(options.roots, abs);
109
+ // Open first, then decide from descriptor (CodeQL js/file-system-race: open→fstat before use).
110
+ const handle = await open(real, "r");
111
+ let st: Awaited<ReturnType<typeof handle.stat>>;
112
+ try {
113
+ st = await handle.stat();
114
+ // Verify we opened a regular file of the approved inode (detects TOCTOU/symlink swap).
115
+ if (!st.isFile()) {
116
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path must resolve to a regular file");
117
+ }
118
+ try {
119
+ const curStat = await lstat(real);
120
+ if (curStat.isSymbolicLink() || curStat.ino !== st.ino || curStat.dev !== st.dev) {
121
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path was replaced between check and open");
122
+ }
123
+ } catch (e) {
124
+ if (e instanceof BrowserError) throw e;
125
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload path was replaced between check and open");
126
+ }
127
+ if (st.size > perFileCap) {
128
+ throw new BrowserError("ERR_PRISM_BROWSER_LIMIT", `upload exceeds maxUploadBytes ${perFileCap}`);
129
+ }
130
+ if (budget.aggregateBytes + st.size > limits.maxUploadAggregateBytes) {
131
+ throw new BrowserError("ERR_PRISM_BROWSER_LIMIT", `upload exceeds maxUploadAggregateBytes ${limits.maxUploadAggregateBytes}`);
132
+ }
133
+ } catch (e) {
134
+ await handle.close();
135
+ throw e;
136
+ }
137
+
138
+ const hash = createHash("sha256");
139
+ try {
140
+ const buf = Buffer.alloc(64 * 1024);
141
+ let remaining = st.size;
142
+ while (remaining > 0) {
143
+ const { bytesRead } = await handle.read(buf, 0, Math.min(buf.length, remaining), null);
144
+ if (bytesRead <= 0) break;
145
+ hash.update(buf.subarray(0, bytesRead));
146
+ remaining -= bytesRead;
147
+ }
148
+ } finally {
149
+ await handle.close();
150
+ }
151
+
152
+ approved.push({
153
+ path: real,
154
+ name: basename(real),
155
+ bytes: st.size,
156
+ sha256: hash.digest("hex"),
157
+ });
158
+ budget.count += 1;
159
+ budget.aggregateBytes += st.size;
160
+ }
161
+
162
+ return approved;
163
+ }
164
+
165
+ /** Join a relative upload path under the first root (host convenience). */
166
+ export function resolveUploadCandidate(root: string, relativePath: string): string {
167
+ if (!isAbsolute(root)) {
168
+ throw new BrowserError("ERR_PRISM_BROWSER_INPUT", "upload root must be absolute");
169
+ }
170
+ if (isAbsolute(relativePath) || relativePath.includes("\0") || /(^|[\\/])\.\.([\\/]|$)/.test(relativePath)) {
171
+ throw new BrowserError("ERR_PRISM_BROWSER_ARTIFACT", "upload relative path is invalid");
172
+ }
173
+ return join(root, relativePath);
174
+ }