vellum 0.0.16 → 0.2.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 (838) hide show
  1. package/.dockerignore +27 -0
  2. package/.env.example +22 -0
  3. package/Dockerfile +99 -0
  4. package/Dockerfile.sandbox +5 -0
  5. package/README.md +150 -3
  6. package/bun.lock +1768 -0
  7. package/bunfig.toml +2 -0
  8. package/docs/skills.md +158 -0
  9. package/drizzle/0000_dizzy_maggott.sql +301 -0
  10. package/drizzle/meta/0000_snapshot.json +1999 -0
  11. package/drizzle/meta/_journal.json +13 -0
  12. package/drizzle.config.ts +7 -0
  13. package/eslint.config.mjs +17 -0
  14. package/hook-templates/debug-prompt-logger/hook.json +7 -0
  15. package/hook-templates/debug-prompt-logger/run.sh +68 -0
  16. package/knip.json +9 -0
  17. package/package.json +60 -10
  18. package/scripts/ipc/check-contract-inventory.ts +104 -0
  19. package/scripts/ipc/check-swift-decoder-drift.ts +163 -0
  20. package/scripts/ipc/generate-swift.ts +492 -0
  21. package/scripts/test-filesystem-tools.sh +48 -0
  22. package/scripts/test.sh +122 -0
  23. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +2079 -0
  24. package/src/__tests__/account-registry.test.ts +244 -0
  25. package/src/__tests__/active-skill-tools.test.ts +378 -0
  26. package/src/__tests__/agent-loop-thinking.test.ts +81 -0
  27. package/src/__tests__/agent-loop.test.ts +1135 -0
  28. package/src/__tests__/anthropic-provider.test.ts +778 -0
  29. package/src/__tests__/app-builder-tool-scripts.test.ts +290 -0
  30. package/src/__tests__/app-bundler.test.ts +313 -0
  31. package/src/__tests__/app-executors.test.ts +613 -0
  32. package/src/__tests__/app-open-proxy.test.ts +62 -0
  33. package/src/__tests__/asset-materialize-tool.test.ts +451 -0
  34. package/src/__tests__/asset-search-tool.test.ts +476 -0
  35. package/src/__tests__/assistant-attachment-directive.test.ts +401 -0
  36. package/src/__tests__/assistant-attachments.test.ts +437 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +226 -0
  38. package/src/__tests__/assistant-event.test.ts +123 -0
  39. package/src/__tests__/attachments-store.test.ts +547 -0
  40. package/src/__tests__/attachments.test.ts +134 -0
  41. package/src/__tests__/audit-log-rotation.test.ts +154 -0
  42. package/src/__tests__/browser-fill-credential.test.ts +309 -0
  43. package/src/__tests__/browser-manager.test.ts +203 -0
  44. package/src/__tests__/browser-runtime-check.test.ts +55 -0
  45. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +67 -0
  46. package/src/__tests__/browser-skill-endstate.test.ts +198 -0
  47. package/src/__tests__/bundle-scanner.test.ts +313 -0
  48. package/src/__tests__/checker.test.ts +3856 -0
  49. package/src/__tests__/clarification-resolver.test.ts +159 -0
  50. package/src/__tests__/classifier.test.ts +67 -0
  51. package/src/__tests__/claude-code-skill-regression.test.ts +127 -0
  52. package/src/__tests__/claude-code-tool-profiles.test.ts +88 -0
  53. package/src/__tests__/cli-discover.test.ts +85 -0
  54. package/src/__tests__/cli.test.ts +81 -0
  55. package/src/__tests__/clipboard.test.ts +80 -0
  56. package/src/__tests__/commit-guarantee.test.ts +335 -0
  57. package/src/__tests__/computer-use-session-compaction.test.ts +132 -0
  58. package/src/__tests__/computer-use-session-lifecycle.test.ts +293 -0
  59. package/src/__tests__/computer-use-session-working-dir.test.ts +117 -0
  60. package/src/__tests__/computer-use-skill-baseline.test.ts +74 -0
  61. package/src/__tests__/computer-use-skill-endstate.test.ts +89 -0
  62. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +217 -0
  63. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +107 -0
  64. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +54 -0
  65. package/src/__tests__/config-schema.test.ts +720 -0
  66. package/src/__tests__/conflict-store.test.ts +329 -0
  67. package/src/__tests__/connection-policy.test.ts +102 -0
  68. package/src/__tests__/context-memory-e2e.test.ts +434 -0
  69. package/src/__tests__/context-token-estimator.test.ts +135 -0
  70. package/src/__tests__/context-window-manager.test.ts +376 -0
  71. package/src/__tests__/contradiction-checker.test.ts +216 -0
  72. package/src/__tests__/conversation-store.test.ts +614 -0
  73. package/src/__tests__/credential-broker-browser-fill.test.ts +517 -0
  74. package/src/__tests__/credential-broker-server-use.test.ts +554 -0
  75. package/src/__tests__/credential-broker.test.ts +167 -0
  76. package/src/__tests__/credential-host-pattern-match.test.ts +104 -0
  77. package/src/__tests__/credential-metadata-store.test.ts +779 -0
  78. package/src/__tests__/credential-policy-validate.test.ts +121 -0
  79. package/src/__tests__/credential-resolve.test.ts +328 -0
  80. package/src/__tests__/credential-security-e2e.test.ts +352 -0
  81. package/src/__tests__/credential-security-invariants.test.ts +563 -0
  82. package/src/__tests__/credential-selection.test.ts +354 -0
  83. package/src/__tests__/credential-vault.test.ts +852 -0
  84. package/src/__tests__/daemon-assistant-events.test.ts +164 -0
  85. package/src/__tests__/daemon-server-session-init.test.ts +522 -0
  86. package/src/__tests__/delete-managed-skill-tool.test.ts +97 -0
  87. package/src/__tests__/diff.test.ts +121 -0
  88. package/src/__tests__/domain-normalize.test.ts +112 -0
  89. package/src/__tests__/domain-policy.test.ts +124 -0
  90. package/src/__tests__/doordash-client.test.ts +186 -0
  91. package/src/__tests__/doordash-session.test.ts +143 -0
  92. package/src/__tests__/dynamic-page-surface.test.ts +91 -0
  93. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +132 -0
  94. package/src/__tests__/edit-engine.test.ts +180 -0
  95. package/src/__tests__/email-cli.test.ts +283 -0
  96. package/src/__tests__/encrypted-store.test.ts +332 -0
  97. package/src/__tests__/entity-extractor.test.ts +190 -0
  98. package/src/__tests__/ephemeral-permissions.test.ts +312 -0
  99. package/src/__tests__/evaluate-typescript-tool.test.ts +286 -0
  100. package/src/__tests__/event-bus.test.ts +222 -0
  101. package/src/__tests__/file-edit-tool.test.ts +122 -0
  102. package/src/__tests__/file-ops-service.test.ts +330 -0
  103. package/src/__tests__/file-read-tool.test.ts +75 -0
  104. package/src/__tests__/file-write-tool.test.ts +113 -0
  105. package/src/__tests__/fixtures/credential-security-fixtures.ts +181 -0
  106. package/src/__tests__/fixtures/media-reuse-fixtures.ts +126 -0
  107. package/src/__tests__/fixtures/mock-signup-server.ts +387 -0
  108. package/src/__tests__/fixtures/proxy-fixtures.ts +147 -0
  109. package/src/__tests__/fuzzy-match-property.test.ts +216 -0
  110. package/src/__tests__/fuzzy-match.test.ts +138 -0
  111. package/src/__tests__/gemini-image-service.test.ts +261 -0
  112. package/src/__tests__/gemini-provider.test.ts +651 -0
  113. package/src/__tests__/get-weather.test.ts +318 -0
  114. package/src/__tests__/gmail-integration.test.ts +73 -0
  115. package/src/__tests__/handlers-cu-observation-blob.test.ts +351 -0
  116. package/src/__tests__/handlers-ipc-blob-probe.test.ts +190 -0
  117. package/src/__tests__/handlers-slack-config.test.ts +199 -0
  118. package/src/__tests__/handlers-task-submit-slash.test.ts +38 -0
  119. package/src/__tests__/headless-browser-interactions.test.ts +536 -0
  120. package/src/__tests__/headless-browser-navigate.test.ts +211 -0
  121. package/src/__tests__/headless-browser-read-tools.test.ts +261 -0
  122. package/src/__tests__/headless-browser-snapshot.test.ts +185 -0
  123. package/src/__tests__/history-repair-observability.test.ts +56 -0
  124. package/src/__tests__/history-repair.test.ts +510 -0
  125. package/src/__tests__/home-base-bootstrap.test.ts +77 -0
  126. package/src/__tests__/hooks-blocking.test.ts +128 -0
  127. package/src/__tests__/hooks-cli.test.ts +144 -0
  128. package/src/__tests__/hooks-config.test.ts +93 -0
  129. package/src/__tests__/hooks-discovery.test.ts +199 -0
  130. package/src/__tests__/hooks-integration.test.ts +189 -0
  131. package/src/__tests__/hooks-manager.test.ts +187 -0
  132. package/src/__tests__/hooks-runner.test.ts +178 -0
  133. package/src/__tests__/hooks-settings.test.ts +154 -0
  134. package/src/__tests__/hooks-templates.test.ts +137 -0
  135. package/src/__tests__/hooks-ts-runner.test.ts +125 -0
  136. package/src/__tests__/hooks-watch.test.ts +100 -0
  137. package/src/__tests__/host-file-edit-tool.test.ts +104 -0
  138. package/src/__tests__/host-file-read-tool.test.ts +61 -0
  139. package/src/__tests__/host-file-write-tool.test.ts +77 -0
  140. package/src/__tests__/host-shell-tool.test.ts +311 -0
  141. package/src/__tests__/intent-routing.test.ts +255 -0
  142. package/src/__tests__/ipc-blob-store.test.ts +315 -0
  143. package/src/__tests__/ipc-contract-inventory.test.ts +54 -0
  144. package/src/__tests__/ipc-contract.test.ts +74 -0
  145. package/src/__tests__/ipc-protocol.test.ts +113 -0
  146. package/src/__tests__/ipc-snapshot.test.ts +1560 -0
  147. package/src/__tests__/ipc-validate.test.ts +357 -0
  148. package/src/__tests__/key-migration.test.ts +183 -0
  149. package/src/__tests__/keychain.test.ts +258 -0
  150. package/src/__tests__/llm-usage-store.test.ts +226 -0
  151. package/src/__tests__/managed-skill-lifecycle.test.ts +257 -0
  152. package/src/__tests__/managed-store.test.ts +608 -0
  153. package/src/__tests__/media-generate-image.test.ts +238 -0
  154. package/src/__tests__/media-reuse-story.e2e.test.ts +676 -0
  155. package/src/__tests__/media-visibility-policy.test.ts +141 -0
  156. package/src/__tests__/memory-context-benchmark.test.ts +235 -0
  157. package/src/__tests__/memory-lifecycle-e2e.test.ts +481 -0
  158. package/src/__tests__/memory-query-builder.test.ts +59 -0
  159. package/src/__tests__/memory-recall-quality.test.ts +846 -0
  160. package/src/__tests__/memory-regressions.experimental.test.ts +538 -0
  161. package/src/__tests__/memory-regressions.test.ts +4238 -0
  162. package/src/__tests__/memory-retrieval-budget.test.ts +49 -0
  163. package/src/__tests__/migration-cli-flows.test.ts +169 -0
  164. package/src/__tests__/migration-ordering.test.ts +249 -0
  165. package/src/__tests__/mock-signup-server.test.ts +528 -0
  166. package/src/__tests__/onboarding-starter-tasks.test.ts +166 -0
  167. package/src/__tests__/onboarding-template-contract.test.ts +58 -0
  168. package/src/__tests__/openai-provider.test.ts +753 -0
  169. package/src/__tests__/parser.test.ts +472 -0
  170. package/src/__tests__/path-classifier.test.ts +73 -0
  171. package/src/__tests__/path-policy.test.ts +435 -0
  172. package/src/__tests__/platform-move-helper.test.ts +99 -0
  173. package/src/__tests__/platform-socket-path.test.ts +52 -0
  174. package/src/__tests__/platform-workspace-migration.test.ts +1000 -0
  175. package/src/__tests__/platform.test.ts +131 -0
  176. package/src/__tests__/prebuilt-home-base-seed.test.ts +71 -0
  177. package/src/__tests__/pricing.test.ts +256 -0
  178. package/src/__tests__/profile-compiler.test.ts +373 -0
  179. package/src/__tests__/provider-registry-ollama.test.ts +16 -0
  180. package/src/__tests__/proxy-approval-callback.test.ts +601 -0
  181. package/src/__tests__/ratelimit.test.ts +297 -0
  182. package/src/__tests__/registry.test.ts +487 -0
  183. package/src/__tests__/reminder-store.test.ts +220 -0
  184. package/src/__tests__/reminder.test.ts +263 -0
  185. package/src/__tests__/request-file-tool.test.ts +158 -0
  186. package/src/__tests__/run-orchestrator.test.ts +200 -0
  187. package/src/__tests__/runtime-attachment-metadata.test.ts +190 -0
  188. package/src/__tests__/runtime-runs-http.test.ts +451 -0
  189. package/src/__tests__/runtime-runs.test.ts +273 -0
  190. package/src/__tests__/sandbox-diagnostics.test.ts +408 -0
  191. package/src/__tests__/sandbox-host-parity.test.ts +950 -0
  192. package/src/__tests__/scaffold-managed-skill-tool.test.ts +253 -0
  193. package/src/__tests__/script-proxy-certs.test.ts +90 -0
  194. package/src/__tests__/script-proxy-connect-tunnel.test.ts +177 -0
  195. package/src/__tests__/script-proxy-decision-trace.test.ts +156 -0
  196. package/src/__tests__/script-proxy-http-forwarder.test.ts +281 -0
  197. package/src/__tests__/script-proxy-injection-runtime.test.ts +401 -0
  198. package/src/__tests__/script-proxy-mitm-handler.test.ts +407 -0
  199. package/src/__tests__/script-proxy-policy-runtime.test.ts +287 -0
  200. package/src/__tests__/script-proxy-policy.test.ts +310 -0
  201. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +135 -0
  202. package/src/__tests__/script-proxy-router.test.ts +180 -0
  203. package/src/__tests__/script-proxy-session-manager.test.ts +382 -0
  204. package/src/__tests__/script-proxy-session-runtime.test.ts +113 -0
  205. package/src/__tests__/secret-allowlist.test.ts +229 -0
  206. package/src/__tests__/secret-ingress-handler.test.ts +99 -0
  207. package/src/__tests__/secret-onetime-send.test.ts +130 -0
  208. package/src/__tests__/secret-prompt-log-hygiene.test.ts +106 -0
  209. package/src/__tests__/secret-response-routing.test.ts +93 -0
  210. package/src/__tests__/secret-scanner-executor.test.ts +348 -0
  211. package/src/__tests__/secret-scanner.test.ts +857 -0
  212. package/src/__tests__/secure-keys.test.ts +323 -0
  213. package/src/__tests__/server-history-render.test.ts +430 -0
  214. package/src/__tests__/session-abort-tool-results.test.ts +240 -0
  215. package/src/__tests__/session-conflict-gate.test.ts +697 -0
  216. package/src/__tests__/session-error.test.ts +341 -0
  217. package/src/__tests__/session-evictor.test.ts +188 -0
  218. package/src/__tests__/session-load-history-repair.test.ts +222 -0
  219. package/src/__tests__/session-pre-run-repair.test.ts +213 -0
  220. package/src/__tests__/session-profile-injection.test.ts +444 -0
  221. package/src/__tests__/session-provider-retry-repair.test.ts +306 -0
  222. package/src/__tests__/session-queue.test.ts +1462 -0
  223. package/src/__tests__/session-runtime-assembly.test.ts +315 -0
  224. package/src/__tests__/session-runtime-workspace.test.ts +183 -0
  225. package/src/__tests__/session-skill-tools.test.ts +2431 -0
  226. package/src/__tests__/session-slash-known.test.ts +368 -0
  227. package/src/__tests__/session-slash-queue.test.ts +288 -0
  228. package/src/__tests__/session-slash-unknown.test.ts +271 -0
  229. package/src/__tests__/session-tool-setup-app-refresh.test.ts +473 -0
  230. package/src/__tests__/session-tool-setup-memory-scope.test.ts +140 -0
  231. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +140 -0
  232. package/src/__tests__/session-undo.test.ts +75 -0
  233. package/src/__tests__/session-workspace-cache-state.test.ts +246 -0
  234. package/src/__tests__/session-workspace-injection.test.ts +327 -0
  235. package/src/__tests__/session-workspace-tool-tracking.test.ts +240 -0
  236. package/src/__tests__/shared-filesystem-errors.test.ts +78 -0
  237. package/src/__tests__/shell-credential-ref.test.ts +187 -0
  238. package/src/__tests__/shell-parser-fuzz.test.ts +544 -0
  239. package/src/__tests__/shell-parser-property.test.ts +433 -0
  240. package/src/__tests__/shell-tool-proxy-mode.test.ts +272 -0
  241. package/src/__tests__/signup-e2e.test.ts +352 -0
  242. package/src/__tests__/size-guard.test.ts +117 -0
  243. package/src/__tests__/skill-include-graph.test.ts +303 -0
  244. package/src/__tests__/skill-load-tool.test.ts +409 -0
  245. package/src/__tests__/skill-script-runner-host.test.ts +489 -0
  246. package/src/__tests__/skill-script-runner-sandbox.test.ts +349 -0
  247. package/src/__tests__/skill-tool-factory.test.ts +252 -0
  248. package/src/__tests__/skill-tool-manifest.test.ts +658 -0
  249. package/src/__tests__/skill-version-hash.test.ts +182 -0
  250. package/src/__tests__/skills.test.ts +597 -0
  251. package/src/__tests__/slash-commands-catalog.test.ts +86 -0
  252. package/src/__tests__/slash-commands-parser.test.ts +119 -0
  253. package/src/__tests__/slash-commands-resolver.test.ts +193 -0
  254. package/src/__tests__/slash-commands-rewrite.test.ts +39 -0
  255. package/src/__tests__/starter-bundle.test.ts +136 -0
  256. package/src/__tests__/starter-task-flow.test.ts +143 -0
  257. package/src/__tests__/subagent-manager-notify.test.ts +372 -0
  258. package/src/__tests__/subagent-tools.test.ts +118 -0
  259. package/src/__tests__/subagent-types.test.ts +78 -0
  260. package/src/__tests__/swarm-orchestrator.test.ts +428 -0
  261. package/src/__tests__/swarm-plan-validator.test.ts +330 -0
  262. package/src/__tests__/swarm-recursion.test.ts +165 -0
  263. package/src/__tests__/swarm-router-planner.test.ts +208 -0
  264. package/src/__tests__/swarm-session-integration.test.ts +274 -0
  265. package/src/__tests__/swarm-tool.test.ts +145 -0
  266. package/src/__tests__/swarm-worker-backend.test.ts +129 -0
  267. package/src/__tests__/swarm-worker-runner.test.ts +272 -0
  268. package/src/__tests__/system-prompt.test.ts +461 -0
  269. package/src/__tests__/task-compiler.test.ts +283 -0
  270. package/src/__tests__/task-runner.test.ts +215 -0
  271. package/src/__tests__/task-scheduler.test.ts +216 -0
  272. package/src/__tests__/task-tools.test.ts +602 -0
  273. package/src/__tests__/terminal-sandbox-docker.test.ts +1064 -0
  274. package/src/__tests__/terminal-sandbox.integration.test.ts +178 -0
  275. package/src/__tests__/terminal-sandbox.test.ts +202 -0
  276. package/src/__tests__/test-support/browser-skill-harness.ts +90 -0
  277. package/src/__tests__/test-support/computer-use-skill-harness.ts +45 -0
  278. package/src/__tests__/tool-audit-listener.test.ts +112 -0
  279. package/src/__tests__/tool-domain-event-publisher.test.ts +251 -0
  280. package/src/__tests__/tool-executor-lifecycle-events.test.ts +516 -0
  281. package/src/__tests__/tool-executor-redaction.test.ts +289 -0
  282. package/src/__tests__/tool-executor.test.ts +1971 -0
  283. package/src/__tests__/tool-metrics-listener.test.ts +225 -0
  284. package/src/__tests__/tool-notification-listener.test.ts +49 -0
  285. package/src/__tests__/tool-policy.test.ts +54 -0
  286. package/src/__tests__/tool-profiling-listener.test.ts +268 -0
  287. package/src/__tests__/tool-result-truncation.test.ts +217 -0
  288. package/src/__tests__/tool-trace-listener.test.ts +226 -0
  289. package/src/__tests__/top-level-renderer.test.ts +121 -0
  290. package/src/__tests__/top-level-scanner.test.ts +141 -0
  291. package/src/__tests__/trace-emitter.test.ts +173 -0
  292. package/src/__tests__/trust-store.test.ts +2030 -0
  293. package/src/__tests__/turn-commit.test.ts +219 -0
  294. package/src/__tests__/url-safety.test.ts +418 -0
  295. package/src/__tests__/weather-skill-regression.test.ts +225 -0
  296. package/src/__tests__/web-fetch.test.ts +869 -0
  297. package/src/__tests__/web-search.test.ts +584 -0
  298. package/src/__tests__/workspace-git-service.test.ts +750 -0
  299. package/src/__tests__/workspace-heartbeat-service.test.ts +347 -0
  300. package/src/__tests__/workspace-lifecycle.test.ts +292 -0
  301. package/src/agent/attachments.ts +35 -0
  302. package/src/agent/loop.ts +500 -0
  303. package/src/agent/message-types.ts +17 -0
  304. package/src/autonomy/autonomy-resolver.ts +60 -0
  305. package/src/autonomy/autonomy-store.ts +122 -0
  306. package/src/autonomy/disposition-mapper.ts +31 -0
  307. package/src/autonomy/index.ts +11 -0
  308. package/src/autonomy/types.ts +39 -0
  309. package/src/bundler/app-bundler.ts +274 -0
  310. package/src/bundler/bundle-scanner.ts +535 -0
  311. package/src/bundler/bundle-signer.ts +124 -0
  312. package/src/bundler/manifest.ts +21 -0
  313. package/src/bundler/signature-verifier.ts +184 -0
  314. package/src/cli/autonomy.ts +188 -0
  315. package/src/cli/contacts.ts +149 -0
  316. package/src/cli/doordash.ts +824 -0
  317. package/src/cli/email-guardrails.ts +200 -0
  318. package/src/cli/email.ts +405 -0
  319. package/src/cli/main-screen.tsx +155 -0
  320. package/src/cli.ts +935 -0
  321. package/src/config/bundled-skills/.gitkeep +0 -0
  322. package/src/config/bundled-skills/agentmail/SKILL.md +128 -0
  323. package/src/config/bundled-skills/agentmail/icon.svg +21 -0
  324. package/src/config/bundled-skills/app-builder/SKILL.md +1348 -0
  325. package/src/config/bundled-skills/app-builder/TOOLS.json +279 -0
  326. package/src/config/bundled-skills/app-builder/icon.svg +9 -0
  327. package/src/config/bundled-skills/app-builder/tools/app-create.ts +15 -0
  328. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +10 -0
  329. package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +11 -0
  330. package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +10 -0
  331. package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +18 -0
  332. package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +11 -0
  333. package/src/config/bundled-skills/app-builder/tools/app-list.ts +10 -0
  334. package/src/config/bundled-skills/app-builder/tools/app-query.ts +10 -0
  335. package/src/config/bundled-skills/app-builder/tools/app-update.ts +20 -0
  336. package/src/config/bundled-skills/browser/SKILL.md +28 -0
  337. package/src/config/bundled-skills/browser/TOOLS.json +234 -0
  338. package/src/config/bundled-skills/browser/tools/browser-click.ts +9 -0
  339. package/src/config/bundled-skills/browser/tools/browser-close.ts +9 -0
  340. package/src/config/bundled-skills/browser/tools/browser-extract.ts +9 -0
  341. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +9 -0
  342. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +9 -0
  343. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +9 -0
  344. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +9 -0
  345. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +9 -0
  346. package/src/config/bundled-skills/browser/tools/browser-type.ts +9 -0
  347. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +9 -0
  348. package/src/config/bundled-skills/claude-code/SKILL.md +50 -0
  349. package/src/config/bundled-skills/claude-code/TOOLS.json +40 -0
  350. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +9 -0
  351. package/src/config/bundled-skills/computer-use/SKILL.md +17 -0
  352. package/src/config/bundled-skills/computer-use/TOOLS.json +326 -0
  353. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +9 -0
  354. package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +9 -0
  355. package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +9 -0
  356. package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +9 -0
  357. package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +9 -0
  358. package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +9 -0
  359. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +9 -0
  360. package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +9 -0
  361. package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +9 -0
  362. package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +9 -0
  363. package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +9 -0
  364. package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +9 -0
  365. package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +9 -0
  366. package/src/config/bundled-skills/google-calendar/SKILL.md +51 -0
  367. package/src/config/bundled-skills/google-calendar/TOOLS.json +108 -0
  368. package/src/config/bundled-skills/google-calendar/calendar-client.ts +165 -0
  369. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +21 -0
  370. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +42 -0
  371. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +13 -0
  372. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +30 -0
  373. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +41 -0
  374. package/src/config/bundled-skills/google-calendar/tools/shared.ts +18 -0
  375. package/src/config/bundled-skills/google-calendar/types.ts +97 -0
  376. package/src/config/bundled-skills/image-studio/SKILL.md +32 -0
  377. package/src/config/bundled-skills/image-studio/TOOLS.json +42 -0
  378. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +137 -0
  379. package/src/config/bundled-skills/messaging/SKILL.md +126 -0
  380. package/src/config/bundled-skills/messaging/TOOLS.json +357 -0
  381. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +23 -0
  382. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +23 -0
  383. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +25 -0
  384. package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +26 -0
  385. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +25 -0
  386. package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +23 -0
  387. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +84 -0
  388. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +18 -0
  389. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +124 -0
  390. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +16 -0
  391. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +49 -0
  392. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +21 -0
  393. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +25 -0
  394. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +28 -0
  395. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +29 -0
  396. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +22 -0
  397. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +27 -0
  398. package/src/config/bundled-skills/messaging/tools/shared.ts +71 -0
  399. package/src/config/bundled-skills/messaging/tools/slack-add-reaction.ts +25 -0
  400. package/src/config/bundled-skills/messaging/tools/slack-leave-channel.ts +23 -0
  401. package/src/config/bundled-skills/self-upgrade/SKILL.md +74 -0
  402. package/src/config/bundled-skills/start-the-day/SKILL.md +70 -0
  403. package/src/config/bundled-skills/start-the-day/icon.svg +13 -0
  404. package/src/config/bundled-skills/weather/SKILL.md +37 -0
  405. package/src/config/bundled-skills/weather/TOOLS.json +32 -0
  406. package/src/config/bundled-skills/weather/icon.svg +24 -0
  407. package/src/config/bundled-skills/weather/tools/get-weather.ts +9 -0
  408. package/src/config/computer-use-prompt.ts +97 -0
  409. package/src/config/defaults.ts +186 -0
  410. package/src/config/loader.ts +336 -0
  411. package/src/config/schema.ts +1004 -0
  412. package/src/config/skill-state.ts +95 -0
  413. package/src/config/skills.ts +972 -0
  414. package/src/config/system-prompt.ts +927 -0
  415. package/src/config/templates/BOOTSTRAP.md +70 -0
  416. package/src/config/templates/IDENTITY.md +18 -0
  417. package/src/config/templates/LOOKS.md +25 -0
  418. package/src/config/templates/SOUL.md +37 -0
  419. package/src/config/templates/USER.md +19 -0
  420. package/src/config/types.ts +32 -0
  421. package/src/config/vellum-skills/deploy-fullstack-vercel/SKILL.md +179 -0
  422. package/src/config/vellum-skills/document-writer/SKILL.md +195 -0
  423. package/src/config/vellum-skills/google-oauth-setup/SKILL.md +194 -0
  424. package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +147 -0
  425. package/src/config/vellum-skills/telegram-setup/SKILL.md +105 -0
  426. package/src/contacts/contact-store.ts +410 -0
  427. package/src/contacts/index.ts +11 -0
  428. package/src/contacts/types.ts +28 -0
  429. package/src/context/token-estimator.ts +108 -0
  430. package/src/context/tool-result-truncation.ts +128 -0
  431. package/src/context/window-manager.ts +531 -0
  432. package/src/daemon/assistant-attachments.ts +679 -0
  433. package/src/daemon/classifier.ts +108 -0
  434. package/src/daemon/computer-use-session.ts +900 -0
  435. package/src/daemon/connection-policy.ts +41 -0
  436. package/src/daemon/handlers/apps.ts +446 -0
  437. package/src/daemon/handlers/computer-use.ts +181 -0
  438. package/src/daemon/handlers/config.ts +434 -0
  439. package/src/daemon/handlers/diagnostics.ts +334 -0
  440. package/src/daemon/handlers/documents.ts +184 -0
  441. package/src/daemon/handlers/home-base.ts +73 -0
  442. package/src/daemon/handlers/index.ts +355 -0
  443. package/src/daemon/handlers/misc.ts +323 -0
  444. package/src/daemon/handlers/open-bundle-handler.ts +80 -0
  445. package/src/daemon/handlers/publish.ts +182 -0
  446. package/src/daemon/handlers/sessions.ts +486 -0
  447. package/src/daemon/handlers/shared.ts +533 -0
  448. package/src/daemon/handlers/skills.ts +487 -0
  449. package/src/daemon/handlers/subagents.ts +122 -0
  450. package/src/daemon/handlers/work-items.ts +176 -0
  451. package/src/daemon/handlers.ts +17 -0
  452. package/src/daemon/history-repair.ts +214 -0
  453. package/src/daemon/ipc-blob-store.ts +231 -0
  454. package/src/daemon/ipc-contract-inventory.json +407 -0
  455. package/src/daemon/ipc-contract-inventory.ts +126 -0
  456. package/src/daemon/ipc-contract.ts +2102 -0
  457. package/src/daemon/ipc-protocol.ts +70 -0
  458. package/src/daemon/ipc-validate.ts +171 -0
  459. package/src/daemon/lifecycle.ts +503 -0
  460. package/src/daemon/main.ts +15 -0
  461. package/src/daemon/media-visibility-policy.ts +57 -0
  462. package/src/daemon/ride-shotgun-handler.ts +244 -0
  463. package/src/daemon/server.ts +1085 -0
  464. package/src/daemon/session-attachments.ts +173 -0
  465. package/src/daemon/session-conflict-gate.ts +219 -0
  466. package/src/daemon/session-dynamic-profile.ts +63 -0
  467. package/src/daemon/session-error.ts +269 -0
  468. package/src/daemon/session-evictor.ts +196 -0
  469. package/src/daemon/session-history.ts +437 -0
  470. package/src/daemon/session-memory.ts +212 -0
  471. package/src/daemon/session-process.ts +264 -0
  472. package/src/daemon/session-queue-manager.ts +81 -0
  473. package/src/daemon/session-runtime-assembly.ts +395 -0
  474. package/src/daemon/session-skill-tools.ts +237 -0
  475. package/src/daemon/session-slash.ts +302 -0
  476. package/src/daemon/session-surfaces.ts +624 -0
  477. package/src/daemon/session-tool-setup.ts +286 -0
  478. package/src/daemon/session-usage.ts +74 -0
  479. package/src/daemon/session-workspace.ts +19 -0
  480. package/src/daemon/session.ts +1651 -0
  481. package/src/daemon/trace-emitter.ts +82 -0
  482. package/src/daemon/watch-handler.ts +274 -0
  483. package/src/doordash/client.ts +905 -0
  484. package/src/doordash/queries.ts +1312 -0
  485. package/src/doordash/query-extractor.ts +93 -0
  486. package/src/doordash/session.ts +82 -0
  487. package/src/email/provider.ts +117 -0
  488. package/src/email/providers/agentmail.ts +317 -0
  489. package/src/email/providers/index.ts +58 -0
  490. package/src/email/service.ts +303 -0
  491. package/src/email/types.ts +126 -0
  492. package/src/events/bus.ts +157 -0
  493. package/src/events/domain-events.ts +83 -0
  494. package/src/events/index.ts +18 -0
  495. package/src/events/tool-audit-listener.ts +80 -0
  496. package/src/events/tool-domain-event-publisher.ts +111 -0
  497. package/src/events/tool-metrics-listener.ts +159 -0
  498. package/src/events/tool-notification-listener.ts +17 -0
  499. package/src/events/tool-profiling-listener.ts +158 -0
  500. package/src/events/tool-trace-listener.ts +75 -0
  501. package/src/export/formatter.ts +96 -0
  502. package/src/followups/followup-store.ts +166 -0
  503. package/src/followups/index.ts +10 -0
  504. package/src/followups/types.ts +23 -0
  505. package/src/gallery/default-gallery.ts +795 -0
  506. package/src/gallery/gallery-manifest.ts +24 -0
  507. package/src/home-base/app-link-store.ts +82 -0
  508. package/src/home-base/bootstrap.ts +66 -0
  509. package/src/home-base/prebuilt/index.html +662 -0
  510. package/src/home-base/prebuilt/seed-metadata.json +21 -0
  511. package/src/home-base/prebuilt/seed.ts +101 -0
  512. package/src/home-base/prebuilt-home-base-updater.ts +30 -0
  513. package/src/hooks/cli.ts +163 -0
  514. package/src/hooks/config.ts +88 -0
  515. package/src/hooks/discovery.ts +110 -0
  516. package/src/hooks/manager.ts +128 -0
  517. package/src/hooks/runner.ts +123 -0
  518. package/src/hooks/templates.ts +52 -0
  519. package/src/hooks/types.ts +72 -0
  520. package/src/index.ts +1194 -0
  521. package/src/instrument.ts +60 -0
  522. package/src/logfire.ts +99 -0
  523. package/src/media/gemini-image-service.ts +136 -0
  524. package/src/memory/account-store.ts +108 -0
  525. package/src/memory/admin.ts +211 -0
  526. package/src/memory/app-store.ts +556 -0
  527. package/src/memory/attachments-store.ts +453 -0
  528. package/src/memory/channel-delivery-store.ts +368 -0
  529. package/src/memory/checkpoints.ts +52 -0
  530. package/src/memory/clarification-resolver.ts +297 -0
  531. package/src/memory/conflict-store.ts +342 -0
  532. package/src/memory/contradiction-checker.ts +329 -0
  533. package/src/memory/conversation-key-store.ts +127 -0
  534. package/src/memory/conversation-store.ts +469 -0
  535. package/src/memory/db.ts +1105 -0
  536. package/src/memory/embedding-backend.ts +229 -0
  537. package/src/memory/embedding-gemini.ts +52 -0
  538. package/src/memory/embedding-local.ts +75 -0
  539. package/src/memory/embedding-ollama.ts +55 -0
  540. package/src/memory/embedding-openai.ts +25 -0
  541. package/src/memory/entity-extractor.ts +471 -0
  542. package/src/memory/fingerprint.ts +20 -0
  543. package/src/memory/indexer.ts +156 -0
  544. package/src/memory/items-extractor.ts +460 -0
  545. package/src/memory/job-handlers/backfill.ts +139 -0
  546. package/src/memory/job-handlers/cleanup.ts +58 -0
  547. package/src/memory/job-handlers/conflict.ts +99 -0
  548. package/src/memory/job-handlers/embedding.ts +61 -0
  549. package/src/memory/job-handlers/extraction.ts +123 -0
  550. package/src/memory/job-handlers/index-maintenance.ts +54 -0
  551. package/src/memory/job-handlers/summarization.ts +286 -0
  552. package/src/memory/job-utils.ts +170 -0
  553. package/src/memory/jobs-store.ts +400 -0
  554. package/src/memory/jobs-worker.ts +274 -0
  555. package/src/memory/llm-request-log-store.ts +45 -0
  556. package/src/memory/llm-usage-store.ts +62 -0
  557. package/src/memory/message-content.ts +54 -0
  558. package/src/memory/profile-compiler.ts +160 -0
  559. package/src/memory/published-pages-store.ts +137 -0
  560. package/src/memory/qdrant-client.ts +366 -0
  561. package/src/memory/qdrant-manager.ts +242 -0
  562. package/src/memory/query-builder.ts +45 -0
  563. package/src/memory/retrieval-budget.ts +30 -0
  564. package/src/memory/retriever.ts +653 -0
  565. package/src/memory/runs-store.ts +211 -0
  566. package/src/memory/schema.ts +529 -0
  567. package/src/memory/search/entity.ts +298 -0
  568. package/src/memory/search/formatting.ts +207 -0
  569. package/src/memory/search/lexical.ts +227 -0
  570. package/src/memory/search/ranking.ts +401 -0
  571. package/src/memory/search/semantic.ts +121 -0
  572. package/src/memory/search/types.ts +137 -0
  573. package/src/memory/segmenter.ts +68 -0
  574. package/src/memory/shared-app-links-store.ts +138 -0
  575. package/src/memory/tool-usage-store.ts +62 -0
  576. package/src/messaging/activity-analyzer.ts +76 -0
  577. package/src/messaging/draft-store.ts +88 -0
  578. package/src/messaging/index.ts +3 -0
  579. package/src/messaging/provider-types.ts +80 -0
  580. package/src/messaging/provider.ts +43 -0
  581. package/src/messaging/providers/gmail/adapter.ts +193 -0
  582. package/src/messaging/providers/gmail/client.ts +204 -0
  583. package/src/messaging/providers/gmail/types.ts +90 -0
  584. package/src/messaging/providers/slack/adapter.ts +202 -0
  585. package/src/messaging/providers/slack/client.ts +198 -0
  586. package/src/messaging/providers/slack/types.ts +119 -0
  587. package/src/messaging/registry.ts +34 -0
  588. package/src/messaging/style-analyzer.ts +158 -0
  589. package/src/messaging/thread-summarizer.ts +310 -0
  590. package/src/messaging/triage-engine.ts +321 -0
  591. package/src/messaging/types.ts +55 -0
  592. package/src/permissions/checker.ts +636 -0
  593. package/src/permissions/defaults.ts +243 -0
  594. package/src/permissions/prompter.ts +102 -0
  595. package/src/permissions/secret-prompter.ts +114 -0
  596. package/src/permissions/trust-store.ts +584 -0
  597. package/src/permissions/types.ts +62 -0
  598. package/src/playbooks/index.ts +2 -0
  599. package/src/playbooks/playbook-compiler.ts +90 -0
  600. package/src/playbooks/types.ts +55 -0
  601. package/src/providers/anthropic/client.ts +751 -0
  602. package/src/providers/failover.ts +129 -0
  603. package/src/providers/fireworks/client.ts +20 -0
  604. package/src/providers/gemini/client.ts +285 -0
  605. package/src/providers/ollama/client.ts +30 -0
  606. package/src/providers/openai/client.ts +337 -0
  607. package/src/providers/ratelimit.ts +93 -0
  608. package/src/providers/registry.ts +138 -0
  609. package/src/providers/retry.ts +106 -0
  610. package/src/providers/stream-timeout.ts +38 -0
  611. package/src/providers/types.ts +109 -0
  612. package/src/runtime/assistant-event-hub.ts +120 -0
  613. package/src/runtime/assistant-event.ts +82 -0
  614. package/src/runtime/http-server.ts +478 -0
  615. package/src/runtime/http-types.ts +68 -0
  616. package/src/runtime/routes/app-routes.ts +174 -0
  617. package/src/runtime/routes/attachment-routes.ts +134 -0
  618. package/src/runtime/routes/channel-routes.ts +342 -0
  619. package/src/runtime/routes/conversation-routes.ts +349 -0
  620. package/src/runtime/routes/run-routes.ts +223 -0
  621. package/src/runtime/routes/secret-routes.ts +76 -0
  622. package/src/runtime/run-orchestrator.ts +206 -0
  623. package/src/schedule/schedule-store.ts +452 -0
  624. package/src/schedule/scheduler.ts +168 -0
  625. package/src/security/encrypted-store.ts +238 -0
  626. package/src/security/keychain.ts +252 -0
  627. package/src/security/oauth2.ts +241 -0
  628. package/src/security/redaction.ts +89 -0
  629. package/src/security/secret-allowlist.ts +118 -0
  630. package/src/security/secret-ingress.ts +57 -0
  631. package/src/security/secret-scanner.ts +543 -0
  632. package/src/security/secure-keys.ts +180 -0
  633. package/src/security/token-manager.ts +141 -0
  634. package/src/services/published-app-updater.ts +69 -0
  635. package/src/services/vercel-deploy.ts +73 -0
  636. package/src/skills/active-skill-tools.ts +81 -0
  637. package/src/skills/clawhub.ts +414 -0
  638. package/src/skills/include-graph.ts +146 -0
  639. package/src/skills/managed-store.ts +233 -0
  640. package/src/skills/path-classifier.ts +128 -0
  641. package/src/skills/slash-commands.ts +174 -0
  642. package/src/skills/tool-manifest.ts +165 -0
  643. package/src/skills/version-hash.ts +110 -0
  644. package/src/slack/slack-webhook.ts +61 -0
  645. package/src/subagent/index.ts +19 -0
  646. package/src/subagent/manager.ts +477 -0
  647. package/src/subagent/types.ts +69 -0
  648. package/src/swarm/backend-claude-code.ts +90 -0
  649. package/src/swarm/index.ts +44 -0
  650. package/src/swarm/limits.ts +37 -0
  651. package/src/swarm/orchestrator.ts +279 -0
  652. package/src/swarm/plan-validator.ts +151 -0
  653. package/src/swarm/router-planner.ts +100 -0
  654. package/src/swarm/router-prompts.ts +36 -0
  655. package/src/swarm/synthesizer.ts +62 -0
  656. package/src/swarm/types.ts +62 -0
  657. package/src/swarm/worker-backend.ts +121 -0
  658. package/src/swarm/worker-prompts.ts +78 -0
  659. package/src/swarm/worker-runner.ts +164 -0
  660. package/src/tasks/SPEC.md +133 -0
  661. package/src/tasks/candidate-store.ts +86 -0
  662. package/src/tasks/ephemeral-permissions.ts +41 -0
  663. package/src/tasks/task-compiler.ts +198 -0
  664. package/src/tasks/task-runner.ts +85 -0
  665. package/src/tasks/task-scheduler.ts +20 -0
  666. package/src/tasks/task-store.ts +127 -0
  667. package/src/tools/apps/definitions.ts +59 -0
  668. package/src/tools/apps/executors.ts +313 -0
  669. package/src/tools/apps/open-proxy.ts +43 -0
  670. package/src/tools/apps/registry.ts +16 -0
  671. package/src/tools/assets/materialize.ts +218 -0
  672. package/src/tools/assets/search.ts +396 -0
  673. package/src/tools/browser/__tests__/auth-cache.test.ts +219 -0
  674. package/src/tools/browser/__tests__/auth-detector.test.ts +362 -0
  675. package/src/tools/browser/__tests__/jit-auth.test.ts +189 -0
  676. package/src/tools/browser/auth-cache.ts +149 -0
  677. package/src/tools/browser/auth-detector.ts +347 -0
  678. package/src/tools/browser/browser-execution.ts +979 -0
  679. package/src/tools/browser/browser-handoff.ts +79 -0
  680. package/src/tools/browser/browser-manager.ts +715 -0
  681. package/src/tools/browser/browser-screencast.ts +217 -0
  682. package/src/tools/browser/headless-browser.ts +450 -0
  683. package/src/tools/browser/jit-auth.ts +51 -0
  684. package/src/tools/browser/network-recorder.ts +348 -0
  685. package/src/tools/browser/network-recording-types.ts +49 -0
  686. package/src/tools/browser/recording-store.ts +49 -0
  687. package/src/tools/browser/runtime-check.ts +43 -0
  688. package/src/tools/claude-code/claude-code.ts +232 -0
  689. package/src/tools/computer-use/definitions.ts +443 -0
  690. package/src/tools/computer-use/registry.ts +22 -0
  691. package/src/tools/computer-use/request-computer-control.ts +53 -0
  692. package/src/tools/computer-use/skill-proxy-bridge.ts +28 -0
  693. package/src/tools/contacts/contact-merge.ts +87 -0
  694. package/src/tools/contacts/contact-search.ts +102 -0
  695. package/src/tools/contacts/contact-upsert.ts +137 -0
  696. package/src/tools/contacts/index.ts +4 -0
  697. package/src/tools/credentials/account-registry.ts +127 -0
  698. package/src/tools/credentials/broker-types.ts +107 -0
  699. package/src/tools/credentials/broker.ts +372 -0
  700. package/src/tools/credentials/domain-policy.ts +51 -0
  701. package/src/tools/credentials/host-pattern-match.ts +60 -0
  702. package/src/tools/credentials/metadata-store.ts +335 -0
  703. package/src/tools/credentials/policy-types.ts +52 -0
  704. package/src/tools/credentials/policy-validate.ts +80 -0
  705. package/src/tools/credentials/resolve.ts +122 -0
  706. package/src/tools/credentials/selection.ts +159 -0
  707. package/src/tools/credentials/tool-policy.ts +25 -0
  708. package/src/tools/credentials/vault.ts +641 -0
  709. package/src/tools/document/document-tool.ts +165 -0
  710. package/src/tools/document/editor-template.ts +237 -0
  711. package/src/tools/document/index.ts +5 -0
  712. package/src/tools/executor.ts +825 -0
  713. package/src/tools/filesystem/edit.ts +127 -0
  714. package/src/tools/filesystem/fuzzy-match.ts +202 -0
  715. package/src/tools/filesystem/read.ts +71 -0
  716. package/src/tools/filesystem/view-image.ts +199 -0
  717. package/src/tools/filesystem/write.ts +79 -0
  718. package/src/tools/followups/followup_create.ts +118 -0
  719. package/src/tools/followups/followup_list.ts +100 -0
  720. package/src/tools/followups/followup_resolve.ts +91 -0
  721. package/src/tools/followups/index.ts +3 -0
  722. package/src/tools/host-filesystem/edit.ts +125 -0
  723. package/src/tools/host-filesystem/read.ts +80 -0
  724. package/src/tools/host-filesystem/write.ts +76 -0
  725. package/src/tools/host-terminal/cli-discover.ts +179 -0
  726. package/src/tools/host-terminal/host-shell.ts +181 -0
  727. package/src/tools/memory/definitions.ts +69 -0
  728. package/src/tools/memory/handlers.ts +245 -0
  729. package/src/tools/memory/register.ts +66 -0
  730. package/src/tools/network/domain-normalize.ts +85 -0
  731. package/src/tools/network/script-proxy/certs.ts +237 -0
  732. package/src/tools/network/script-proxy/connect-tunnel.ts +82 -0
  733. package/src/tools/network/script-proxy/http-forwarder.ts +151 -0
  734. package/src/tools/network/script-proxy/index.ts +28 -0
  735. package/src/tools/network/script-proxy/logging.ts +196 -0
  736. package/src/tools/network/script-proxy/mitm-handler.ts +269 -0
  737. package/src/tools/network/script-proxy/policy.ts +152 -0
  738. package/src/tools/network/script-proxy/router.ts +60 -0
  739. package/src/tools/network/script-proxy/server.ts +136 -0
  740. package/src/tools/network/script-proxy/session-manager.ts +534 -0
  741. package/src/tools/network/script-proxy/types.ts +125 -0
  742. package/src/tools/network/url-safety.ts +227 -0
  743. package/src/tools/network/web-fetch.ts +701 -0
  744. package/src/tools/network/web-search.ts +319 -0
  745. package/src/tools/playbooks/index.ts +5 -0
  746. package/src/tools/playbooks/playbook-create.ts +140 -0
  747. package/src/tools/playbooks/playbook-delete.ts +76 -0
  748. package/src/tools/playbooks/playbook-list.ts +101 -0
  749. package/src/tools/playbooks/playbook-update.ts +159 -0
  750. package/src/tools/registry.ts +297 -0
  751. package/src/tools/reminder/reminder-store.ts +148 -0
  752. package/src/tools/reminder/reminder.ts +153 -0
  753. package/src/tools/schedule/create.ts +86 -0
  754. package/src/tools/schedule/delete.ts +54 -0
  755. package/src/tools/schedule/list.ts +88 -0
  756. package/src/tools/schedule/update.ts +97 -0
  757. package/src/tools/shared/filesystem/edit-engine.ts +56 -0
  758. package/src/tools/shared/filesystem/errors.ts +85 -0
  759. package/src/tools/shared/filesystem/file-ops-service.ts +215 -0
  760. package/src/tools/shared/filesystem/format-diff.ts +35 -0
  761. package/src/tools/shared/filesystem/path-policy.ts +125 -0
  762. package/src/tools/shared/filesystem/size-guard.ts +41 -0
  763. package/src/tools/shared/filesystem/types.ts +80 -0
  764. package/src/tools/shared/shell-output.ts +52 -0
  765. package/src/tools/skills/delete-managed.ts +60 -0
  766. package/src/tools/skills/load.ts +139 -0
  767. package/src/tools/skills/sandbox-runner.ts +279 -0
  768. package/src/tools/skills/scaffold-managed.ts +150 -0
  769. package/src/tools/skills/script-contract.ts +6 -0
  770. package/src/tools/skills/skill-script-runner.ts +86 -0
  771. package/src/tools/skills/skill-tool-factory.ts +64 -0
  772. package/src/tools/skills/vellum-catalog.ts +217 -0
  773. package/src/tools/subagent/abort.ts +62 -0
  774. package/src/tools/subagent/index.ts +5 -0
  775. package/src/tools/subagent/message.ts +72 -0
  776. package/src/tools/subagent/read.ts +98 -0
  777. package/src/tools/subagent/spawn.ts +85 -0
  778. package/src/tools/subagent/status.ts +74 -0
  779. package/src/tools/swarm/delegate.ts +182 -0
  780. package/src/tools/system/request-permission.ts +98 -0
  781. package/src/tools/tasks/index.ts +25 -0
  782. package/src/tools/tasks/task-delete.ts +69 -0
  783. package/src/tools/tasks/task-list.ts +65 -0
  784. package/src/tools/tasks/task-run.ts +125 -0
  785. package/src/tools/tasks/task-save.ts +79 -0
  786. package/src/tools/tasks/work-item-enqueue.ts +176 -0
  787. package/src/tools/tasks/work-item-list.ts +86 -0
  788. package/src/tools/terminal/backends/docker.ts +372 -0
  789. package/src/tools/terminal/backends/native.ts +188 -0
  790. package/src/tools/terminal/backends/types.ts +26 -0
  791. package/src/tools/terminal/evaluate-typescript.ts +275 -0
  792. package/src/tools/terminal/parser.ts +393 -0
  793. package/src/tools/terminal/safe-env.ts +37 -0
  794. package/src/tools/terminal/sandbox-diagnostics.ts +149 -0
  795. package/src/tools/terminal/sandbox.ts +44 -0
  796. package/src/tools/terminal/shell.ts +257 -0
  797. package/src/tools/tool-manifest.ts +250 -0
  798. package/src/tools/types.ts +177 -0
  799. package/src/tools/ui-surface/definitions.ts +232 -0
  800. package/src/tools/ui-surface/registry.ts +14 -0
  801. package/src/tools/watch/screen-watch.ts +128 -0
  802. package/src/tools/watch/watch-state.ts +119 -0
  803. package/src/tools/watcher/create.ts +110 -0
  804. package/src/tools/watcher/delete.ts +53 -0
  805. package/src/tools/watcher/digest.ts +84 -0
  806. package/src/tools/watcher/list.ts +90 -0
  807. package/src/tools/watcher/update.ts +102 -0
  808. package/src/tools/weather/service.ts +551 -0
  809. package/src/usage/actors.ts +24 -0
  810. package/src/usage/types.ts +38 -0
  811. package/src/util/clipboard.ts +33 -0
  812. package/src/util/content-id.ts +16 -0
  813. package/src/util/diff.ts +181 -0
  814. package/src/util/errors.ts +129 -0
  815. package/src/util/logger.ts +243 -0
  816. package/src/util/platform.ts +607 -0
  817. package/src/util/pricing.ts +150 -0
  818. package/src/util/spinner.ts +51 -0
  819. package/src/util/time.ts +16 -0
  820. package/src/util/xml.ts +4 -0
  821. package/src/version.ts +3 -0
  822. package/src/watcher/constants.ts +11 -0
  823. package/src/watcher/engine.ts +199 -0
  824. package/src/watcher/provider-registry.ts +15 -0
  825. package/src/watcher/provider-types.ts +48 -0
  826. package/src/watcher/providers/gmail.ts +198 -0
  827. package/src/watcher/providers/google-calendar.ts +228 -0
  828. package/src/watcher/providers/slack.ts +128 -0
  829. package/src/watcher/watcher-store.ts +418 -0
  830. package/src/work-items/work-item-store.ts +91 -0
  831. package/src/workspace/git-service.ts +620 -0
  832. package/src/workspace/heartbeat-service.ts +288 -0
  833. package/src/workspace/top-level-renderer.ts +19 -0
  834. package/src/workspace/top-level-scanner.ts +41 -0
  835. package/src/workspace/turn-commit.ts +122 -0
  836. package/tsconfig.json +21 -0
  837. package/LICENSE +0 -674
  838. package/dist/cli.js +0 -569
@@ -0,0 +1,636 @@
1
+ import { RiskLevel, type PermissionCheckResult, type AllowlistOption, type ScopeOption, type PolicyContext } from './types.js';
2
+ import { findHighestPriorityRule } from './trust-store.js';
3
+ import { parse } from '../tools/terminal/parser.js';
4
+ import { resolveSkillSelector } from '../config/skills.js';
5
+ import { computeSkillVersionHash } from '../skills/version-hash.js';
6
+ import { getTool } from '../tools/registry.js';
7
+ import { getConfig } from '../config/loader.js';
8
+ import { dirname, resolve } from 'node:path';
9
+ import { homedir } from 'node:os';
10
+ import { looksLikeHostPortShorthand, looksLikePathOnlyInput } from '../tools/network/url-safety.js';
11
+ import { normalizeFilePath, isSkillSourcePath } from '../skills/path-classifier.js';
12
+
13
+ // Low-risk shell programs that are read-only / informational
14
+ const LOW_RISK_PROGRAMS = new Set([
15
+ 'ls', 'cat', 'head', 'tail', 'less', 'more', 'wc', 'file', 'stat',
16
+ 'grep', 'rg', 'ag', 'ack', 'find', 'fd', 'which', 'where', 'whereis', 'type',
17
+ 'echo', 'printf', 'date', 'cal', 'uptime', 'whoami', 'hostname', 'uname',
18
+ 'pwd', 'realpath', 'dirname', 'basename',
19
+ 'git', 'node', 'bun', 'deno', 'npm', 'npx', 'yarn', 'pnpm',
20
+ 'python', 'python3', 'pip', 'pip3',
21
+ 'man', 'help', 'info',
22
+ 'env', 'printenv', 'set',
23
+ 'diff', 'sort', 'uniq', 'cut', 'tr', 'tee', 'xargs',
24
+ 'jq', 'yq', 'sed', 'awk',
25
+ 'curl', 'wget', 'http', 'dig', 'nslookup', 'ping',
26
+ 'tree', 'du', 'df',
27
+ ]);
28
+
29
+ // High-risk shell programs / patterns
30
+ const HIGH_RISK_PROGRAMS = new Set([
31
+ 'sudo', 'su', 'doas',
32
+ 'dd', 'mkfs', 'fdisk', 'parted', 'mount', 'umount',
33
+ 'systemctl', 'service', 'launchctl',
34
+ 'useradd', 'userdel', 'usermod', 'groupadd', 'groupdel',
35
+ 'iptables', 'ufw', 'firewall-cmd',
36
+ 'reboot', 'shutdown', 'halt', 'poweroff',
37
+ 'kill', 'killall', 'pkill',
38
+ ]);
39
+
40
+ // Git subcommands that are low-risk (read-only)
41
+ const LOW_RISK_GIT_SUBCOMMANDS = new Set([
42
+ 'status', 'log', 'diff', 'show', 'branch', 'tag', 'remote', 'stash',
43
+ 'blame', 'shortlog', 'describe', 'rev-parse', 'ls-files', 'ls-tree',
44
+ 'cat-file', 'reflog',
45
+ ]);
46
+
47
+ function isHighRiskRm(args: string[]): boolean {
48
+ // rm with -r, -rf, -fr, or targeting root/home
49
+ for (const arg of args) {
50
+ if (arg.startsWith('-') && (arg.includes('r') || arg.includes('f'))) {
51
+ return true;
52
+ }
53
+ if (arg === '/' || arg === '~' || arg === '$HOME') {
54
+ return true;
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+
60
+ function getStringField(input: Record<string, unknown>, ...keys: string[]): string {
61
+ for (const key of keys) {
62
+ const value = input[key];
63
+ if (typeof value === 'string') return value;
64
+ }
65
+ return '';
66
+ }
67
+
68
+ /**
69
+ * Resolve a skill selector to its id and version hash. The version hash
70
+ * is always computed from disk so that untrusted input cannot spoof a
71
+ * pre-approved hash. If disk computation fails, only the bare id is returned.
72
+ */
73
+ function resolveSkillIdAndHash(selector: string): { id: string; versionHash?: string } | null {
74
+ const resolved = resolveSkillSelector(selector);
75
+ if (!resolved.skill) return null;
76
+
77
+ try {
78
+ const hash = computeSkillVersionHash(resolved.skill.directoryPath);
79
+ return { id: resolved.skill.id, versionHash: hash };
80
+ } catch {
81
+ return { id: resolved.skill.id };
82
+ }
83
+ }
84
+
85
+ function canonicalizeWebFetchUrl(parsed: URL): URL {
86
+ parsed.hash = '';
87
+ parsed.username = '';
88
+ parsed.password = '';
89
+
90
+ try {
91
+ // Normalize equivalent escaped paths (for example, "/%70rivate" -> "/private")
92
+ // so path-scoped trust rules cannot be bypassed via percent-encoding.
93
+ parsed.pathname = decodeURI(parsed.pathname);
94
+ } catch {
95
+ // Keep URL parser canonical form when decoding fails.
96
+ }
97
+
98
+ if (parsed.hostname.endsWith('.')) {
99
+ parsed.hostname = parsed.hostname.replace(/\.+$/, '');
100
+ }
101
+
102
+ return parsed;
103
+ }
104
+
105
+ export function normalizeWebFetchUrl(rawUrl: string): URL | null {
106
+ const trimmed = rawUrl.trim();
107
+ if (!trimmed) return null;
108
+
109
+ if (looksLikeHostPortShorthand(trimmed)) {
110
+ try {
111
+ return canonicalizeWebFetchUrl(new URL(`https://${trimmed}`));
112
+ } catch {
113
+ return null;
114
+ }
115
+ }
116
+
117
+ try {
118
+ const parsed = new URL(trimmed);
119
+ if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
120
+ return canonicalizeWebFetchUrl(parsed);
121
+ }
122
+ return null;
123
+ } catch {
124
+ // Fall through.
125
+ }
126
+
127
+ if (looksLikePathOnlyInput(trimmed)) {
128
+ return null;
129
+ }
130
+
131
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
132
+ return null;
133
+ }
134
+
135
+ try {
136
+ return canonicalizeWebFetchUrl(new URL(`https://${trimmed}`));
137
+ } catch {
138
+ return null;
139
+ }
140
+ }
141
+
142
+ function escapeMinimatchLiteral(value: string): string {
143
+ return value.replace(/([\\*?[\]{}()!+@|])/g, '\\$1');
144
+ }
145
+
146
+ function buildCommandCandidates(toolName: string, input: Record<string, unknown>, workingDir: string): string[] {
147
+ if (toolName === 'bash' || toolName === 'host_bash') {
148
+ return [getStringField(input, 'command')];
149
+ }
150
+
151
+ if (toolName === 'skill_load') {
152
+ const rawSelector = getStringField(input, 'skill').trim();
153
+ const targets: string[] = [];
154
+ if (!rawSelector) {
155
+ targets.push('');
156
+ } else {
157
+ const resolved = resolveSkillIdAndHash(rawSelector);
158
+ if (resolved) {
159
+ // Version-specific candidate lets rules pin to an exact skill version
160
+ if (resolved.versionHash) {
161
+ targets.push(`${resolved.id}@${resolved.versionHash}`);
162
+ }
163
+ // Bare skill id candidate for backward compat / any-version rules
164
+ targets.push(resolved.id);
165
+ }
166
+ targets.push(rawSelector);
167
+ }
168
+ return [...new Set(targets)].map((target) => `${toolName}:${target}`);
169
+ }
170
+
171
+ if (toolName === 'scaffold_managed_skill' || toolName === 'delete_managed_skill') {
172
+ const skillId = getStringField(input, 'skill_id').trim();
173
+ return [`${toolName}:${skillId}`];
174
+ }
175
+
176
+ if (toolName === 'web_fetch' || toolName === 'browser_navigate' || toolName === 'network_request') {
177
+ const rawUrl = getStringField(input, 'url').trim();
178
+ const candidates: string[] = [];
179
+
180
+ if (rawUrl) {
181
+ candidates.push(`${toolName}:${rawUrl}`);
182
+ }
183
+
184
+ const normalized = normalizeWebFetchUrl(rawUrl);
185
+ if (normalized) {
186
+ candidates.push(`${toolName}:${normalized.href}`);
187
+ candidates.push(`${toolName}:${normalized.origin}/*`);
188
+ }
189
+
190
+ if (candidates.length === 0) {
191
+ candidates.push(`${toolName}:`);
192
+ }
193
+
194
+ return [...new Set(candidates)];
195
+ }
196
+
197
+ const fileTarget = getStringField(input, 'path', 'file_path');
198
+ if (toolName === 'host_file_read' || toolName === 'host_file_write' || toolName === 'host_file_edit') {
199
+ const resolved = fileTarget ? resolve(fileTarget) : fileTarget;
200
+ const normalized = resolved && process.platform === 'win32' ? resolved.replaceAll('\\', '/') : resolved;
201
+ const candidates = [`${toolName}:${normalized}`];
202
+ if (normalized !== fileTarget) {
203
+ candidates.push(`${toolName}:${fileTarget}`);
204
+ }
205
+ // Include the canonical (symlink-resolved) form so rules written against
206
+ // real paths match even when the tool receives a symlinked path.
207
+ if (fileTarget) {
208
+ const canonical = normalizeFilePath(normalized);
209
+ if (canonical !== normalized && canonical !== fileTarget) {
210
+ candidates.push(`${toolName}:${canonical}`);
211
+ }
212
+ }
213
+ return [...new Set(candidates)];
214
+ }
215
+
216
+ const rawResolved = fileTarget ? resolve(workingDir, fileTarget) : fileTarget;
217
+ const resolved = rawResolved && process.platform === 'win32' ? rawResolved.replaceAll('\\', '/') : rawResolved;
218
+ const candidates = [`${toolName}:${resolved}`];
219
+ // Also include the raw path if it differs, so user-created rules with
220
+ // raw paths still match.
221
+ if (resolved !== fileTarget) {
222
+ candidates.push(`${toolName}:${fileTarget}`);
223
+ }
224
+ // Include the canonical (symlink-resolved) form so rules written against
225
+ // real paths match even when the tool receives a symlinked or relative path
226
+ // with redundant segments like `./foo/../bar`.
227
+ if (fileTarget) {
228
+ const canonical = normalizeFilePath(resolved);
229
+ if (canonical !== resolved && canonical !== fileTarget) {
230
+ candidates.push(`${toolName}:${canonical}`);
231
+ }
232
+ }
233
+ return [...new Set(candidates)];
234
+ }
235
+
236
+ export async function classifyRisk(toolName: string, input: Record<string, unknown>, workingDir?: string): Promise<RiskLevel> {
237
+ if (toolName === 'file_read') return RiskLevel.Low;
238
+ if (toolName === 'file_write' || toolName === 'file_edit') {
239
+ const filePath = getStringField(input, 'path', 'file_path');
240
+ if (filePath && isSkillSourcePath(resolve(workingDir ?? process.cwd(), filePath), getConfig().skills.load.extraDirs)) {
241
+ return RiskLevel.High;
242
+ }
243
+ return RiskLevel.Medium;
244
+ }
245
+ if (toolName === 'web_search') return RiskLevel.Low;
246
+ if (toolName === 'web_fetch') {
247
+ // Private-network fetches are High risk so that blanket allow rules
248
+ // (including the starter bundle) cannot silently bypass the prompt.
249
+ return input.allow_private_network === true ? RiskLevel.High : RiskLevel.Low;
250
+ }
251
+ if (toolName === 'browser_navigate') {
252
+ return input.allow_private_network === true ? RiskLevel.High : RiskLevel.Low;
253
+ }
254
+ // All other browser tools are low risk — the browser is sandboxed and user-visible.
255
+ if (toolName.startsWith('browser_')) return RiskLevel.Low;
256
+ // Proxy-authenticated network requests are Medium risk — they carry injected
257
+ // credentials and the user should approve the target host/origin.
258
+ if (toolName === 'network_request') return RiskLevel.Medium;
259
+ if (toolName === 'skill_load') return RiskLevel.Low;
260
+
261
+ // Escalate host file mutations targeting skill source paths to High risk.
262
+ // The host variants fall through to the tool registry (Medium) by default,
263
+ // but writing to skill source code is a privilege-escalation vector.
264
+ if (toolName === 'host_file_write' || toolName === 'host_file_edit') {
265
+ const filePath = getStringField(input, 'path', 'file_path');
266
+ if (filePath && isSkillSourcePath(resolve(filePath), getConfig().skills.load.extraDirs)) {
267
+ return RiskLevel.High;
268
+ }
269
+ // Fall through to the tool registry default (Medium) below.
270
+ }
271
+
272
+ if (toolName === 'bash' || toolName === 'host_bash') {
273
+ const command = (input.command as string) ?? '';
274
+ if (!command.trim()) return RiskLevel.Low;
275
+
276
+ const parsed = await parse(command);
277
+
278
+ // Dangerous patterns → High
279
+ if (parsed.dangerousPatterns.length > 0) return RiskLevel.High;
280
+
281
+ // Opaque constructs → at least Medium (never Low)
282
+ if (parsed.hasOpaqueConstructs) return RiskLevel.Medium;
283
+
284
+ // Check each segment
285
+ let maxRisk = RiskLevel.Low;
286
+
287
+ for (const seg of parsed.segments) {
288
+ const prog = seg.program;
289
+
290
+ if (HIGH_RISK_PROGRAMS.has(prog)) return RiskLevel.High;
291
+
292
+ if (prog === 'rm') {
293
+ if (isHighRiskRm(seg.args)) return RiskLevel.High;
294
+ maxRisk = RiskLevel.Medium;
295
+ continue;
296
+ }
297
+
298
+ if (prog === 'chmod' || prog === 'chown' || prog === 'chgrp') {
299
+ maxRisk = RiskLevel.Medium;
300
+ continue;
301
+ }
302
+
303
+ if (prog === 'git') {
304
+ const subcommand = seg.args[0];
305
+ if (subcommand && LOW_RISK_GIT_SUBCOMMANDS.has(subcommand)) {
306
+ // Stay at current risk
307
+ continue;
308
+ }
309
+ // Non-read-only git commands are medium
310
+ maxRisk = RiskLevel.Medium;
311
+ continue;
312
+ }
313
+
314
+ if (!LOW_RISK_PROGRAMS.has(prog)) {
315
+ // Unknown program → medium
316
+ if (maxRisk === RiskLevel.Low) {
317
+ maxRisk = RiskLevel.Medium;
318
+ }
319
+ }
320
+ }
321
+
322
+ // If no segments could be extracted, treat as opaque
323
+ if (parsed.segments.length === 0) {
324
+ return RiskLevel.Medium;
325
+ }
326
+
327
+ return maxRisk;
328
+ }
329
+
330
+ // Check the tool registry for a declared default risk level
331
+ const tool = getTool(toolName);
332
+ if (tool) return tool.defaultRiskLevel;
333
+
334
+ // Unknown tool → Medium
335
+ return RiskLevel.Medium;
336
+ }
337
+
338
+ export async function check(
339
+ toolName: string,
340
+ input: Record<string, unknown>,
341
+ workingDir: string,
342
+ policyContext?: PolicyContext,
343
+ ): Promise<PermissionCheckResult> {
344
+ const risk = await classifyRisk(toolName, input, workingDir);
345
+
346
+ // Build command string candidates for rule matching
347
+ const commandCandidates = buildCommandCandidates(toolName, input, workingDir);
348
+
349
+ // Find the highest-priority matching rule across all candidates
350
+ const matchedRule = findHighestPriorityRule(toolName, commandCandidates, workingDir, policyContext);
351
+
352
+ // Deny rules apply at ALL risk levels — including proxied network mode.
353
+ // Evaluate them first so hard blocks are never downgraded to a prompt.
354
+ if (matchedRule && matchedRule.decision === 'deny') {
355
+ return { decision: 'deny', reason: `Blocked by deny rule: ${matchedRule.pattern}`, matchedRule };
356
+ }
357
+
358
+ // Proxied network mode requires explicit user approval for every
359
+ // invocation because the command routes through an authenticated
360
+ // proxy with injected credentials. This runs after deny rules but
361
+ // before allow/ask rules so that trust rules cannot auto-approve
362
+ // proxied commands.
363
+ if (toolName === 'bash' && input.network_mode === 'proxied') {
364
+ return { decision: 'prompt', reason: 'Proxied network mode requires explicit approval for each invocation.' };
365
+ }
366
+
367
+ if (matchedRule) {
368
+ if (matchedRule.decision === 'ask') {
369
+ // Ask rules always prompt — never auto-allow or auto-deny
370
+ return { decision: 'prompt', reason: `Matched ask rule: ${matchedRule.pattern}`, matchedRule };
371
+ }
372
+
373
+ // Allow rule: auto-allow for non-High risk
374
+ if (risk !== RiskLevel.High) {
375
+ return { decision: 'allow', reason: `Matched trust rule: ${matchedRule.pattern}`, matchedRule };
376
+ }
377
+ // High risk with allow rule that explicitly permits high-risk → auto-allow
378
+ if (matchedRule.allowHighRisk === true) {
379
+ return { decision: 'allow', reason: `Matched high-risk trust rule: ${matchedRule.pattern}`, matchedRule };
380
+ }
381
+ // High risk with allow rule (without allowHighRisk) → fall through to prompt
382
+ }
383
+
384
+ // No matching rule (or High risk with allow rule) → risk-based fallback
385
+
386
+ // Third-party skill-origin tools default to prompting when no trust rule
387
+ // matches, regardless of risk level. Bundled skill tools are first-party
388
+ // and trusted, so they fall through to the normal risk-based policy.
389
+ if (!matchedRule) {
390
+ const tool = getTool(toolName);
391
+ if (tool?.origin === 'skill' && !tool.ownerSkillBundled) {
392
+ return { decision: 'prompt', reason: 'Skill tool: requires approval by default' };
393
+ }
394
+ }
395
+
396
+ // In strict mode, every tool without an explicit matching rule must be
397
+ // prompted — there is no implicit auto-allow for any risk level.
398
+ // This explicitly covers skill_load: activating a skill can grant the
399
+ // agent new capabilities, so in strict mode users must approve each
400
+ // skill load via an exact-version or wildcard trust rule.
401
+ const permissionsMode = getConfig().permissions.mode;
402
+ if (permissionsMode === 'strict' && !matchedRule) {
403
+ return { decision: 'prompt', reason: `Strict mode: no matching rule, requires approval` };
404
+ }
405
+
406
+ // Auto-allow low-risk bundled skill tools even without explicit trust rules.
407
+ // These are first-party tools with a vetted risk declaration — applying the
408
+ // same policy as the per-tool default allow rules for browser tools, but
409
+ // generically so every new bundled skill benefits automatically.
410
+ // This block must come AFTER the strict mode check so that strict mode
411
+ // still prompts for bundled skill tools without explicit rules.
412
+ if (!matchedRule && risk === RiskLevel.Low) {
413
+ const tool = getTool(toolName);
414
+ if (tool?.origin === 'skill' && tool.ownerSkillBundled) {
415
+ return { decision: 'allow', reason: 'Bundled skill tool: low risk, auto-allowed' };
416
+ }
417
+ }
418
+
419
+ if (risk === RiskLevel.High) {
420
+ return { decision: 'prompt', reason: `High risk: always requires approval` };
421
+ }
422
+
423
+ if (risk === RiskLevel.Low) {
424
+ return { decision: 'allow', reason: 'Low risk: auto-allowed' };
425
+ }
426
+
427
+ return { decision: 'prompt', reason: `${risk} risk: requires approval` };
428
+ }
429
+
430
+ const TOOL_DISPLAY_NAMES: Record<string, string> = {
431
+ file_read: 'file reads',
432
+ file_write: 'file writes',
433
+ file_edit: 'file edits',
434
+ host_file_read: 'host file reads',
435
+ host_file_write: 'host file writes',
436
+ host_file_edit: 'host file edits',
437
+ web_fetch: 'URL fetches',
438
+ browser_navigate: 'browser navigations',
439
+ network_request: 'network requests',
440
+ };
441
+
442
+ function friendlyBasename(filePath: string): string {
443
+ const parts = filePath.split('/');
444
+ return parts[parts.length - 1] || filePath;
445
+ }
446
+
447
+ function friendlyHostname(url: URL): string {
448
+ return url.hostname.replace(/^www\./, '');
449
+ }
450
+
451
+ export function generateAllowlistOptions(toolName: string, input: Record<string, unknown>): AllowlistOption[] {
452
+ if (toolName === 'bash' || toolName === 'host_bash') {
453
+ const command = ((input.command as string) ?? '').trim();
454
+ const parts = command.split(/\s+/);
455
+ const program = parts[0] ?? command;
456
+ const options: AllowlistOption[] = [];
457
+
458
+ // Exact match
459
+ options.push({ label: command, description: 'This exact command', pattern: command });
460
+
461
+ if (parts.length >= 2) {
462
+ // Subcommand wildcard: "npm install *"
463
+ const sub = parts.slice(0, -1).join(' ');
464
+ options.push({
465
+ label: `${sub} *`,
466
+ description: `Any "${sub}" command`,
467
+ pattern: `${sub} *`,
468
+ });
469
+ }
470
+
471
+ if (parts.length >= 1) {
472
+ // Program wildcard: "npm *"
473
+ options.push({ label: `${program} *`, description: `Any ${program} command`, pattern: `${program} *` });
474
+ }
475
+
476
+ // Deduplicate
477
+ const seen = new Set<string>();
478
+ return options.filter((o) => {
479
+ if (seen.has(o.pattern)) return false;
480
+ seen.add(o.pattern);
481
+ return true;
482
+ });
483
+ }
484
+
485
+ if (
486
+ toolName === 'file_write' || toolName === 'file_read' || toolName === 'file_edit'
487
+ || toolName === 'host_file_write' || toolName === 'host_file_read' || toolName === 'host_file_edit'
488
+ ) {
489
+ const filePath = (input.path as string) ?? (input.file_path as string) ?? '';
490
+ const toolLabel = TOOL_DISPLAY_NAMES[toolName] ?? toolName;
491
+ const options: AllowlistOption[] = [];
492
+
493
+ // Patterns must match the "tool:path" format used by check()
494
+ // Exact file
495
+ options.push({ label: filePath, description: `This file only`, pattern: `${toolName}:${filePath}` });
496
+
497
+ // Ancestor directory wildcards — walk up from immediate parent, stop at home dir or /
498
+ const home = homedir();
499
+ let dir = dirname(filePath);
500
+ const maxLevels = 3;
501
+ let levels = 0;
502
+ while (dir && dir !== '/' && dir !== '.' && levels < maxLevels) {
503
+ const dirName = friendlyBasename(dir);
504
+ options.push({ label: `${dir}/**`, description: `Anything in ${dirName}/`, pattern: `${toolName}:${dir}/**` });
505
+ if (dir === home) break;
506
+ const parent = dirname(dir);
507
+ if (parent === dir) break;
508
+ dir = parent;
509
+ levels++;
510
+ }
511
+
512
+ // Tool wildcard
513
+ options.push({ label: `${toolName}:*`, description: `All ${toolLabel}`, pattern: `${toolName}:*` });
514
+
515
+ return options;
516
+ }
517
+
518
+ if (toolName === 'web_fetch' || toolName === 'browser_navigate' || toolName === 'network_request') {
519
+ const rawUrl = getStringField(input, 'url').trim();
520
+ const normalized = normalizeWebFetchUrl(rawUrl);
521
+ const exact = normalized?.href ?? rawUrl;
522
+
523
+ const options: AllowlistOption[] = [];
524
+ if (exact) {
525
+ options.push({ label: exact, description: 'This exact URL', pattern: `${toolName}:${escapeMinimatchLiteral(exact)}` });
526
+ }
527
+ if (normalized) {
528
+ const host = friendlyHostname(normalized);
529
+ options.push({
530
+ label: `${normalized.origin}/*`,
531
+ description: `Any page on ${host}`,
532
+ pattern: `${toolName}:${escapeMinimatchLiteral(normalized.origin)}/*`,
533
+ });
534
+ }
535
+ const toolLabel = TOOL_DISPLAY_NAMES[toolName] ?? toolName;
536
+ // Use standalone "**" globstar — minimatch only treats ** as globstar when
537
+ // it is its own path segment, so "${toolName}:*" would fail to match URL
538
+ // candidates containing "/". The tool field is already filtered separately.
539
+ options.push({ label: `${toolName}:*`, description: `All ${toolLabel}`, pattern: `**` });
540
+
541
+ const seen = new Set<string>();
542
+ return options.filter((o) => {
543
+ if (seen.has(o.pattern)) return false;
544
+ seen.add(o.pattern);
545
+ return true;
546
+ });
547
+ }
548
+
549
+ if (toolName === 'scaffold_managed_skill' || toolName === 'delete_managed_skill') {
550
+ const skillId = getStringField(input, 'skill_id').trim();
551
+ const toolLabel = toolName === 'scaffold_managed_skill' ? 'scaffold' : 'delete';
552
+ const options: AllowlistOption[] = [];
553
+ if (skillId) {
554
+ options.push({
555
+ label: skillId,
556
+ description: `This skill only`,
557
+ pattern: `${toolName}:${skillId}`,
558
+ });
559
+ }
560
+ options.push({
561
+ label: `${toolName}:*`,
562
+ description: `All managed skill ${toolLabel}s`,
563
+ pattern: `${toolName}:*`,
564
+ });
565
+ return options;
566
+ }
567
+
568
+ if (toolName === 'skill_load') {
569
+ const rawSelector = getStringField(input, 'skill').trim();
570
+
571
+ if (rawSelector) {
572
+ const resolved = resolveSkillIdAndHash(rawSelector);
573
+ if (resolved && resolved.versionHash) {
574
+ // Always pin approval to the exact version
575
+ return [
576
+ {
577
+ label: `${resolved.id}@${resolved.versionHash}`,
578
+ description: 'This exact version',
579
+ pattern: `skill_load:${resolved.id}@${resolved.versionHash}`,
580
+ },
581
+ ];
582
+ }
583
+ // No version hash — use the resolved id or raw selector
584
+ const id = resolved ? resolved.id : rawSelector;
585
+ return [
586
+ {
587
+ label: id,
588
+ description: 'This skill',
589
+ pattern: `skill_load:${id}`,
590
+ },
591
+ ];
592
+ }
593
+
594
+ // No selector at all — fallback to wildcard
595
+ return [
596
+ {
597
+ label: 'skill_load:*',
598
+ description: 'All skill loads',
599
+ pattern: 'skill_load:*',
600
+ },
601
+ ];
602
+ }
603
+
604
+ return [{ label: '*', description: 'Everything', pattern: '*' }];
605
+ }
606
+
607
+ export function generateScopeOptions(workingDir: string, toolName?: string): ScopeOption[] {
608
+ const home = homedir();
609
+ const options: ScopeOption[] = [];
610
+
611
+ // Project directory
612
+ const displayDir = workingDir.startsWith(home)
613
+ ? '~' + workingDir.slice(home.length)
614
+ : workingDir;
615
+ options.push({ label: displayDir, scope: workingDir });
616
+
617
+ // Parent directory
618
+ const parentDir = dirname(workingDir);
619
+ if (parentDir !== workingDir) {
620
+ const displayParent = parentDir.startsWith(home)
621
+ ? '~' + parentDir.slice(home.length)
622
+ : parentDir;
623
+ options.push({ label: `${displayParent}/*`, scope: parentDir });
624
+ }
625
+
626
+ // Everywhere
627
+ options.push({ label: 'everywhere', scope: 'everywhere' });
628
+
629
+ if (!toolName?.startsWith('host_')) {
630
+ return options;
631
+ }
632
+
633
+ const everywhere = options.find((option) => option.scope === 'everywhere');
634
+ const scoped = options.filter((option) => option.scope !== 'everywhere');
635
+ return everywhere ? [everywhere, ...scoped] : options;
636
+ }