@bjoernrochel/sevro 1.0.0 → 1.1.1

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 (405) hide show
  1. package/CONTRIBUTING.md +34 -4
  2. package/README.md +7 -6
  3. package/dist/examples/basic/graded.json +13 -0
  4. package/dist/examples/basic/host.js +9 -0
  5. package/dist/examples/basic/host.js.map +1 -0
  6. package/dist/examples/basic/prompt-only.json +7 -0
  7. package/dist/examples/recipes/candidate.js +23 -0
  8. package/dist/examples/recipes/candidate.js.map +1 -0
  9. package/dist/examples/recipes/cases/coding-change.json +21 -0
  10. package/dist/examples/recipes/cases/host-tools.json +21 -0
  11. package/dist/examples/recipes/cases/mise.json +21 -0
  12. package/dist/examples/recipes/cases/node.json +21 -0
  13. package/dist/examples/recipes/cases/python-uv.json +21 -0
  14. package/dist/examples/recipes/cases/semantic.json +17 -0
  15. package/dist/examples/recipes/coding-change/check.js +16 -0
  16. package/dist/examples/recipes/coding-change/check.js.map +1 -0
  17. package/dist/examples/recipes/executable.js +20 -0
  18. package/dist/examples/recipes/executable.js.map +1 -0
  19. package/dist/examples/recipes/extension-artifacts.js +56 -0
  20. package/dist/examples/recipes/extension-artifacts.js.map +1 -0
  21. package/dist/examples/recipes/extension-methods.js +167 -0
  22. package/dist/examples/recipes/extension-methods.js.map +1 -0
  23. package/dist/examples/recipes/extension.js +28 -0
  24. package/dist/examples/recipes/extension.js.map +1 -0
  25. package/dist/examples/recipes/modules.js +9 -0
  26. package/dist/examples/recipes/modules.js.map +1 -0
  27. package/dist/examples/recipes/repository-skill/.agents/skills/startup-guide/SKILL.md +7 -0
  28. package/dist/examples/recipes/repository-skill/.claude/skills/startup-guide/SKILL.md +7 -0
  29. package/dist/examples/recipes/repository-skill/README.md +3 -0
  30. package/dist/examples/recipes/run-inputs.js +144 -0
  31. package/dist/examples/recipes/run-inputs.js.map +1 -0
  32. package/dist/examples/recipes/run-options.js +103 -0
  33. package/dist/examples/recipes/run-options.js.map +1 -0
  34. package/dist/examples/recipes/run.js +62 -0
  35. package/dist/examples/recipes/run.js.map +1 -0
  36. package/dist/examples/recipes/runtime/empty.json +1 -0
  37. package/dist/examples/recipes/runtime/goals.json +1 -0
  38. package/dist/examples/recipes/runtime/mise.json +6 -0
  39. package/dist/examples/recipes/runtime/path.json +1 -0
  40. package/dist/examples/recipes/runtime/plugins.json +4 -0
  41. package/dist/examples/recipes/runtime/python-uv.json +10 -0
  42. package/dist/examples/recipes/semantic-judge.js +27 -0
  43. package/dist/examples/recipes/semantic-judge.js.map +1 -0
  44. package/dist/examples/templates/coding/adapter.js +14 -0
  45. package/dist/examples/templates/coding/adapter.js.map +1 -0
  46. package/dist/examples/templates/coding/case.json +15 -0
  47. package/dist/examples/templates/repository-skill/.agents/skills/startup-guide/SKILL.md +6 -0
  48. package/dist/examples/templates/repository-skill/extension-data.js +61 -0
  49. package/dist/examples/templates/repository-skill/extension-data.js.map +1 -0
  50. package/dist/examples/templates/repository-skill/extension.js +29 -0
  51. package/dist/examples/templates/repository-skill/extension.js.map +1 -0
  52. package/dist/examples/templates/response/adapter.js +13 -0
  53. package/dist/examples/templates/response/adapter.js.map +1 -0
  54. package/dist/examples/templates/response/case.json +13 -0
  55. package/dist/src/advisory.js +86 -0
  56. package/dist/src/advisory.js.map +1 -0
  57. package/dist/src/candidate-artifacts.js +139 -0
  58. package/dist/src/candidate-artifacts.js.map +1 -0
  59. package/dist/src/candidate-codex-state.js +110 -0
  60. package/dist/src/candidate-codex-state.js.map +1 -0
  61. package/dist/src/case-validation.js +92 -0
  62. package/dist/src/case-validation.js.map +1 -0
  63. package/dist/src/cli/cancellation.js +21 -0
  64. package/dist/src/cli/cancellation.js.map +1 -0
  65. package/dist/src/cli/command.js +60 -0
  66. package/dist/src/cli/command.js.map +1 -0
  67. package/dist/src/cli/completion.js +14 -0
  68. package/dist/src/cli/completion.js.map +1 -0
  69. package/dist/src/cli/demo.js +45 -0
  70. package/dist/src/cli/demo.js.map +1 -0
  71. package/dist/src/cli/evaluation.js +40 -0
  72. package/dist/src/cli/evaluation.js.map +1 -0
  73. package/dist/src/cli/extension.js +54 -0
  74. package/dist/src/cli/extension.js.map +1 -0
  75. package/dist/src/cli/help.js +190 -0
  76. package/dist/src/cli/help.js.map +1 -0
  77. package/dist/src/cli/hosts.js +33 -0
  78. package/dist/src/cli/hosts.js.map +1 -0
  79. package/dist/src/cli/init-settings.js +29 -0
  80. package/dist/src/cli/init-settings.js.map +1 -0
  81. package/dist/src/cli/init.js +82 -0
  82. package/dist/src/cli/init.js.map +1 -0
  83. package/dist/src/cli/invocation.js +431 -0
  84. package/dist/src/cli/invocation.js.map +1 -0
  85. package/dist/src/cli/loading.js +110 -0
  86. package/dist/src/cli/loading.js.map +1 -0
  87. package/dist/src/cli/preparation.js +88 -0
  88. package/dist/src/cli/preparation.js.map +1 -0
  89. package/dist/src/cli/presentation.js +61 -0
  90. package/dist/src/cli/presentation.js.map +1 -0
  91. package/dist/src/cli/progress.js +5 -0
  92. package/dist/src/cli/progress.js.map +1 -0
  93. package/dist/src/cli/run-manifest.js +108 -0
  94. package/dist/src/cli/run-manifest.js.map +1 -0
  95. package/dist/src/cli/run-options.js +367 -0
  96. package/dist/src/cli/run-options.js.map +1 -0
  97. package/dist/src/cli/run-overrides.js +51 -0
  98. package/dist/src/cli/run-overrides.js.map +1 -0
  99. package/dist/src/cli/settings.js +127 -0
  100. package/dist/src/cli/settings.js.map +1 -0
  101. package/dist/src/cli/summary.js +28 -0
  102. package/dist/src/cli/summary.js.map +1 -0
  103. package/dist/src/cli.js +20 -0
  104. package/dist/src/cli.js.map +1 -0
  105. package/dist/src/contract-types.js +2 -0
  106. package/dist/src/contract-types.js.map +1 -0
  107. package/dist/src/engine.js +4 -0
  108. package/dist/src/engine.js.map +1 -0
  109. package/dist/src/evaluation/advisory.js +85 -0
  110. package/dist/src/evaluation/advisory.js.map +1 -0
  111. package/dist/src/evaluation/check-plan.js +292 -0
  112. package/dist/src/evaluation/check-plan.js.map +1 -0
  113. package/dist/src/evaluation/collection.js +61 -0
  114. package/dist/src/evaluation/collection.js.map +1 -0
  115. package/dist/src/evaluation/context.js +2 -0
  116. package/dist/src/evaluation/context.js.map +1 -0
  117. package/dist/src/evaluation/grading-host.js +28 -0
  118. package/dist/src/evaluation/grading-host.js.map +1 -0
  119. package/dist/src/evaluation/grading.js +154 -0
  120. package/dist/src/evaluation/grading.js.map +1 -0
  121. package/dist/src/evaluation/invocation-plan.js +312 -0
  122. package/dist/src/evaluation/invocation-plan.js.map +1 -0
  123. package/dist/src/evaluation/plan.js +376 -0
  124. package/dist/src/evaluation/plan.js.map +1 -0
  125. package/dist/src/evaluation/progress.js +14 -0
  126. package/dist/src/evaluation/progress.js.map +1 -0
  127. package/dist/src/evaluation/resources.js +159 -0
  128. package/dist/src/evaluation/resources.js.map +1 -0
  129. package/dist/src/evaluation/run.js +148 -0
  130. package/dist/src/evaluation/run.js.map +1 -0
  131. package/dist/src/evaluation/scheduler.js +27 -0
  132. package/dist/src/evaluation/scheduler.js.map +1 -0
  133. package/dist/src/evaluation/semantic.js +183 -0
  134. package/dist/src/evaluation/semantic.js.map +1 -0
  135. package/dist/src/evaluation/trial.js +593 -0
  136. package/dist/src/evaluation/trial.js.map +1 -0
  137. package/dist/src/evaluation/types.js +20 -0
  138. package/dist/src/evaluation/types.js.map +1 -0
  139. package/dist/src/evidence/host-results.js +67 -0
  140. package/dist/src/evidence/host-results.js.map +1 -0
  141. package/dist/src/evidence/retained-artifacts.js +17 -0
  142. package/dist/src/evidence/retained-artifacts.js.map +1 -0
  143. package/dist/src/evidence/trial-writer.js +131 -0
  144. package/dist/src/evidence/trial-writer.js.map +1 -0
  145. package/dist/src/evidence/usage.js +14 -0
  146. package/dist/src/evidence/usage.js.map +1 -0
  147. package/dist/src/executable.js +20 -0
  148. package/dist/src/executable.js.map +1 -0
  149. package/dist/src/extension-client.js +212 -0
  150. package/dist/src/extension-client.js.map +1 -0
  151. package/dist/src/extension-session.js +236 -0
  152. package/dist/src/extension-session.js.map +1 -0
  153. package/dist/src/fixtures/advisory.js +206 -0
  154. package/dist/src/fixtures/advisory.js.map +1 -0
  155. package/dist/src/fixtures/bin.js +41 -0
  156. package/dist/src/fixtures/bin.js.map +1 -0
  157. package/dist/src/fixtures/cleanup.js +43 -0
  158. package/dist/src/fixtures/cleanup.js.map +1 -0
  159. package/dist/src/fixtures/create.js +94 -0
  160. package/dist/src/fixtures/create.js.map +1 -0
  161. package/dist/src/fixtures/generated.js +181 -0
  162. package/dist/src/fixtures/generated.js.map +1 -0
  163. package/dist/src/fixtures/git-hooks.js +16 -0
  164. package/dist/src/fixtures/git-hooks.js.map +1 -0
  165. package/dist/src/fixtures/preparation.js +201 -0
  166. package/dist/src/fixtures/preparation.js.map +1 -0
  167. package/dist/src/fixtures/repository.js +255 -0
  168. package/dist/src/fixtures/repository.js.map +1 -0
  169. package/dist/src/fixtures/setup.js +175 -0
  170. package/dist/src/fixtures/setup.js.map +1 -0
  171. package/dist/src/fixtures/tools.js +57 -0
  172. package/dist/src/fixtures/tools.js.map +1 -0
  173. package/dist/src/fixtures/workspace-state.js +155 -0
  174. package/dist/src/fixtures/workspace-state.js.map +1 -0
  175. package/dist/src/generated/cli-result.cjs +2 -0
  176. package/dist/src/generated/extension.cjs +2 -0
  177. package/dist/src/generated/report.cjs +2 -0
  178. package/dist/src/generated/run-evidence.cjs +2 -0
  179. package/dist/src/generated/runtime.cjs +2 -0
  180. package/dist/src/git.js +72 -0
  181. package/dist/src/git.js.map +1 -0
  182. package/dist/src/graders/artifact.js +68 -0
  183. package/dist/src/graders/artifact.js.map +1 -0
  184. package/dist/src/graders/git-head.js +112 -0
  185. package/dist/src/graders/git-head.js.map +1 -0
  186. package/dist/src/graders/output.js +345 -0
  187. package/dist/src/graders/output.js.map +1 -0
  188. package/dist/src/graders/semantic.js +132 -0
  189. package/dist/src/graders/semantic.js.map +1 -0
  190. package/dist/src/graders/shell.js +321 -0
  191. package/dist/src/graders/shell.js.map +1 -0
  192. package/dist/src/host-diagnostic-redaction.js +52 -0
  193. package/dist/src/host-diagnostic-redaction.js.map +1 -0
  194. package/dist/src/host-diagnostics.js +248 -0
  195. package/dist/src/host-diagnostics.js.map +1 -0
  196. package/dist/src/hosts/claude-continuation.js +89 -0
  197. package/dist/src/hosts/claude-continuation.js.map +1 -0
  198. package/dist/src/hosts/claude-credential.js +121 -0
  199. package/dist/src/hosts/claude-credential.js.map +1 -0
  200. package/dist/src/hosts/claude-events.js +136 -0
  201. package/dist/src/hosts/claude-events.js.map +1 -0
  202. package/dist/src/hosts/claude-keychain.js +100 -0
  203. package/dist/src/hosts/claude-keychain.js.map +1 -0
  204. package/dist/src/hosts/claude-login-recovery.js +67 -0
  205. package/dist/src/hosts/claude-login-recovery.js.map +1 -0
  206. package/dist/src/hosts/claude-login-refresh.js +146 -0
  207. package/dist/src/hosts/claude-login-refresh.js.map +1 -0
  208. package/dist/src/hosts/claude-login-store.js +124 -0
  209. package/dist/src/hosts/claude-login-store.js.map +1 -0
  210. package/dist/src/hosts/claude-login.js +74 -0
  211. package/dist/src/hosts/claude-login.js.map +1 -0
  212. package/dist/src/hosts/claude-native-goal.js +138 -0
  213. package/dist/src/hosts/claude-native-goal.js.map +1 -0
  214. package/dist/src/hosts/claude-process.js +10 -0
  215. package/dist/src/hosts/claude-process.js.map +1 -0
  216. package/dist/src/hosts/claude-refresh-lock.js +76 -0
  217. package/dist/src/hosts/claude-refresh-lock.js.map +1 -0
  218. package/dist/src/hosts/claude-repository-invocation.js +229 -0
  219. package/dist/src/hosts/claude-repository-invocation.js.map +1 -0
  220. package/dist/src/hosts/claude-settings.js +158 -0
  221. package/dist/src/hosts/claude-settings.js.map +1 -0
  222. package/dist/src/hosts/claude-skill-activations.js +131 -0
  223. package/dist/src/hosts/claude-skill-activations.js.map +1 -0
  224. package/dist/src/hosts/claude-state.js +237 -0
  225. package/dist/src/hosts/claude-state.js.map +1 -0
  226. package/dist/src/hosts/claude-tool-calls.js +150 -0
  227. package/dist/src/hosts/claude-tool-calls.js.map +1 -0
  228. package/dist/src/hosts/claude.js +373 -0
  229. package/dist/src/hosts/claude.js.map +1 -0
  230. package/dist/src/hosts/codex-app-server.js +764 -0
  231. package/dist/src/hosts/codex-app-server.js.map +1 -0
  232. package/dist/src/hosts/codex-configuration.js +91 -0
  233. package/dist/src/hosts/codex-configuration.js.map +1 -0
  234. package/dist/src/hosts/codex-events.js +104 -0
  235. package/dist/src/hosts/codex-events.js.map +1 -0
  236. package/dist/src/hosts/codex-exec-controls.js +434 -0
  237. package/dist/src/hosts/codex-exec-controls.js.map +1 -0
  238. package/dist/src/hosts/codex-invocation.js +54 -0
  239. package/dist/src/hosts/codex-invocation.js.map +1 -0
  240. package/dist/src/hosts/codex-marketplace.js +185 -0
  241. package/dist/src/hosts/codex-marketplace.js.map +1 -0
  242. package/dist/src/hosts/codex-native-calls.js +516 -0
  243. package/dist/src/hosts/codex-native-calls.js.map +1 -0
  244. package/dist/src/hosts/codex-process.js +10 -0
  245. package/dist/src/hosts/codex-process.js.map +1 -0
  246. package/dist/src/hosts/codex-profile.js +206 -0
  247. package/dist/src/hosts/codex-profile.js.map +1 -0
  248. package/dist/src/hosts/codex-session-files.js +89 -0
  249. package/dist/src/hosts/codex-session-files.js.map +1 -0
  250. package/dist/src/hosts/codex-state.js +310 -0
  251. package/dist/src/hosts/codex-state.js.map +1 -0
  252. package/dist/src/hosts/codex.js +527 -0
  253. package/dist/src/hosts/codex.js.map +1 -0
  254. package/dist/src/hosts/isolation-common.js +43 -0
  255. package/dist/src/hosts/isolation-common.js.map +1 -0
  256. package/dist/src/hosts/isolation-roots.js +64 -0
  257. package/dist/src/hosts/isolation-roots.js.map +1 -0
  258. package/dist/src/hosts/isolation.js +12 -0
  259. package/dist/src/hosts/isolation.js.map +1 -0
  260. package/dist/src/hosts/linux-sandbox.js +127 -0
  261. package/dist/src/hosts/linux-sandbox.js.map +1 -0
  262. package/dist/src/hosts/mac-sandbox.js +137 -0
  263. package/dist/src/hosts/mac-sandbox.js.map +1 -0
  264. package/dist/src/hosts/native-controls.js +151 -0
  265. package/dist/src/hosts/native-controls.js.map +1 -0
  266. package/dist/src/hosts/native-request.js +33 -0
  267. package/dist/src/hosts/native-request.js.map +1 -0
  268. package/dist/src/hosts/process-lifecycle.js +167 -0
  269. package/dist/src/hosts/process-lifecycle.js.map +1 -0
  270. package/dist/src/hosts/protected-worktrees.js +81 -0
  271. package/dist/src/hosts/protected-worktrees.js.map +1 -0
  272. package/dist/src/hosts/skill-hook-catalog.js +100 -0
  273. package/dist/src/hosts/skill-hook-catalog.js.map +1 -0
  274. package/dist/src/hosts/skill-hook-handler.js +228 -0
  275. package/dist/src/hosts/skill-hook-handler.js.map +1 -0
  276. package/dist/src/hosts/skill-hooks.js +423 -0
  277. package/dist/src/hosts/skill-hooks.js.map +1 -0
  278. package/dist/src/hosts/workspace-fingerprint.js +72 -0
  279. package/dist/src/hosts/workspace-fingerprint.js.map +1 -0
  280. package/dist/src/identity.js +167 -0
  281. package/dist/src/identity.js.map +1 -0
  282. package/dist/src/instrumentation.js +83 -0
  283. package/dist/src/instrumentation.js.map +1 -0
  284. package/dist/src/native-transcript-state.js +85 -0
  285. package/dist/src/native-transcript-state.js.map +1 -0
  286. package/dist/src/native-transcript-view.js +65 -0
  287. package/dist/src/native-transcript-view.js.map +1 -0
  288. package/dist/src/native-transcripts.js +208 -0
  289. package/dist/src/native-transcripts.js.map +1 -0
  290. package/dist/src/paths.js +13 -0
  291. package/dist/src/paths.js.map +1 -0
  292. package/dist/src/process-lifecycle.js +101 -0
  293. package/dist/src/process-lifecycle.js.map +1 -0
  294. package/dist/src/provenance.js +263 -0
  295. package/dist/src/provenance.js.map +1 -0
  296. package/dist/src/prune.js +228 -0
  297. package/dist/src/prune.js.map +1 -0
  298. package/dist/src/report.js +276 -0
  299. package/dist/src/report.js.map +1 -0
  300. package/dist/src/resolved-case.js +29 -0
  301. package/dist/src/resolved-case.js.map +1 -0
  302. package/dist/src/results-lock.js +40 -0
  303. package/dist/src/results-lock.js.map +1 -0
  304. package/dist/src/results.js +127 -0
  305. package/dist/src/results.js.map +1 -0
  306. package/dist/src/run-owner.js +283 -0
  307. package/dist/src/run-owner.js.map +1 -0
  308. package/dist/src/runner-paths.js +11 -0
  309. package/dist/src/runner-paths.js.map +1 -0
  310. package/dist/src/runtime/config.js +323 -0
  311. package/dist/src/runtime/config.js.map +1 -0
  312. package/dist/src/runtime/discovery-apple.js +65 -0
  313. package/dist/src/runtime/discovery-apple.js.map +1 -0
  314. package/dist/src/runtime/discovery-providers.js +37 -0
  315. package/dist/src/runtime/discovery-providers.js.map +1 -0
  316. package/dist/src/runtime/discovery.js +40 -0
  317. package/dist/src/runtime/discovery.js.map +1 -0
  318. package/dist/src/runtime/hook-processes.js +81 -0
  319. package/dist/src/runtime/hook-processes.js.map +1 -0
  320. package/dist/src/runtime/hooks.js +304 -0
  321. package/dist/src/runtime/hooks.js.map +1 -0
  322. package/dist/src/runtime/paths.js +244 -0
  323. package/dist/src/runtime/paths.js.map +1 -0
  324. package/dist/src/runtime/query.js +76 -0
  325. package/dist/src/runtime/query.js.map +1 -0
  326. package/dist/src/runtime/seeds.js +98 -0
  327. package/dist/src/runtime/seeds.js.map +1 -0
  328. package/dist/src/runtime/shared-cache.js +81 -0
  329. package/dist/src/runtime/shared-cache.js.map +1 -0
  330. package/dist/src/runtime/state.js +106 -0
  331. package/dist/src/runtime/state.js.map +1 -0
  332. package/dist/src/runtime-process.js +148 -0
  333. package/dist/src/runtime-process.js.map +1 -0
  334. package/dist/src/schema-types.js +2 -0
  335. package/dist/src/schema-types.js.map +1 -0
  336. package/dist/src/schema.js +16 -0
  337. package/dist/src/schema.js.map +1 -0
  338. package/dist/src/shell.js +5 -0
  339. package/dist/src/shell.js.map +1 -0
  340. package/dist/src/sqlite-lock.js +18 -0
  341. package/dist/src/sqlite-lock.js.map +1 -0
  342. package/dist/src/storage.js +21 -0
  343. package/dist/src/storage.js.map +1 -0
  344. package/dist/src/transcript-retention.js +109 -0
  345. package/dist/src/transcript-retention.js.map +1 -0
  346. package/dist/src/value-guards.js +26 -0
  347. package/dist/src/value-guards.js.map +1 -0
  348. package/docs/architecture.md +5 -2
  349. package/docs/creating-cases.md +2 -3
  350. package/docs/development-cli.md +12 -7
  351. package/docs/documentation-quality.md +4 -3
  352. package/docs/evaluation-workflow.md +8 -8
  353. package/docs/getting-started.md +7 -6
  354. package/docs/guide-evaluation.md +1 -1
  355. package/docs/identity-v1.md +4 -1
  356. package/docs/installing.md +31 -13
  357. package/docs/licensing.md +2 -2
  358. package/docs/native-hosts.md +1 -1
  359. package/docs/recipes.md +41 -40
  360. package/docs/releases.md +20 -4
  361. package/docs/run-settings-v1.md +3 -3
  362. package/docs/specs/repository-guide.md +1 -1
  363. package/docs/troubleshooting.md +1 -1
  364. package/docs/typescript-quality.md +18 -1
  365. package/examples/recipes/executable.ts +19 -0
  366. package/examples/recipes/extension-artifacts.ts +1 -1
  367. package/examples/recipes/extension.ts +2 -1
  368. package/examples/recipes/modules.ts +9 -0
  369. package/examples/recipes/run-inputs.ts +14 -19
  370. package/examples/recipes/run-options.ts +9 -8
  371. package/examples/recipes/run.ts +21 -7
  372. package/examples/templates/repository-skill/extension-data.ts +1 -1
  373. package/examples/templates/repository-skill/extension.ts +2 -1
  374. package/package.json +14 -6
  375. package/src/cli/demo.ts +3 -2
  376. package/src/cli/help.ts +4 -3
  377. package/src/cli/init-settings.ts +5 -4
  378. package/src/cli/init.ts +9 -8
  379. package/src/cli/invocation.ts +2 -1
  380. package/src/cli/preparation.ts +2 -2
  381. package/src/cli.ts +1 -1
  382. package/src/executable.ts +19 -0
  383. package/src/extension-client.ts +6 -12
  384. package/src/fixtures/setup.ts +3 -2
  385. package/src/git.ts +2 -1
  386. package/src/graders/git-head.ts +3 -2
  387. package/src/graders/shell.ts +4 -3
  388. package/src/hosts/claude-keychain.ts +3 -2
  389. package/src/hosts/claude-login-refresh.ts +3 -2
  390. package/src/hosts/claude-refresh-lock.ts +2 -1
  391. package/src/hosts/claude-settings.ts +3 -1
  392. package/src/hosts/claude.ts +1 -1
  393. package/src/hosts/isolation-roots.ts +3 -2
  394. package/src/hosts/process-lifecycle.ts +4 -6
  395. package/src/hosts/protected-worktrees.ts +2 -1
  396. package/src/hosts/skill-hook-handler.ts +1 -1
  397. package/src/hosts/skill-hooks.ts +10 -2
  398. package/src/provenance.ts +7 -6
  399. package/src/results-lock.ts +4 -4
  400. package/src/run-owner.ts +15 -9
  401. package/src/runner-paths.ts +21 -0
  402. package/src/runtime/hook-processes.ts +2 -1
  403. package/src/runtime/hooks.ts +9 -7
  404. package/src/runtime-process.ts +194 -0
  405. package/src/sqlite-lock.ts +25 -0
@@ -1,4 +1,4 @@
1
- import { Database } from "bun:sqlite";
1
+ import { openLockDatabase } from "./sqlite-lock";
2
2
  import { join } from "node:path";
3
3
  import { lstat } from "node:fs/promises";
4
4
 
@@ -28,10 +28,10 @@ export async function withResultsLock<T>(
28
28
  /** Hold a root lock while discovering and validating additional nested roots. */
29
29
  export async function acquireResultsLock(root: string): Promise<() => void> {
30
30
  await retainedFile(join(root, ".retention-lock.sqlite"));
31
- const database = new Database(join(root, ".retention-lock.sqlite"));
31
+ const database = openLockDatabase(join(root, ".retention-lock.sqlite"));
32
32
  try {
33
- database.run("PRAGMA busy_timeout = 5000");
34
- database.run("BEGIN IMMEDIATE");
33
+ database.exec("PRAGMA busy_timeout = 5000");
34
+ database.exec("BEGIN IMMEDIATE");
35
35
  return () => {
36
36
  database.close();
37
37
  };
package/src/run-owner.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import { spawnSync } from "./runtime-process";
1
2
  import { isRecord } from "./value-guards";
2
- import { Database } from "bun:sqlite";
3
+ import { openLockDatabase } from "./sqlite-lock";
3
4
  import { randomUUID } from "node:crypto";
4
5
  import {
5
6
  mkdirSync,
@@ -115,11 +116,16 @@ function atomicJson(path: string, value: unknown): void {
115
116
  function withClaimLock<T>(claimPath: string, action: () => T): T {
116
117
  const locks = join(dirname(dirname(claimPath)), "locks");
117
118
  mkdirSync(locks, { recursive: true, mode: 0o700 });
118
- const database = new Database(join(locks, `${basename(claimPath)}.sqlite`));
119
+ const database = openLockDatabase(
120
+ join(locks, `${basename(claimPath)}.sqlite`),
121
+ );
119
122
  try {
120
- database.run("PRAGMA busy_timeout = 5000");
121
- database.run("CREATE TABLE IF NOT EXISTS mutex (id INTEGER PRIMARY KEY)");
122
- return database.transaction(action).immediate();
123
+ database.exec("PRAGMA busy_timeout = 5000");
124
+ database.exec("CREATE TABLE IF NOT EXISTS mutex (id INTEGER PRIMARY KEY)");
125
+ database.exec("BEGIN IMMEDIATE");
126
+ const result = action();
127
+ database.exec("COMMIT");
128
+ return result;
123
129
  } finally {
124
130
  database.close();
125
131
  }
@@ -159,16 +165,16 @@ function identityEnvironment(windows: boolean) {
159
165
  : { PATH: "/usr/bin:/bin", LC_ALL: "C" };
160
166
  }
161
167
 
162
- function processStartTime(result: ReturnType<typeof Bun.spawnSync>): string {
163
- return result.stdout?.toString().trim() ?? "";
168
+ function processStartTime(result: ReturnType<typeof spawnSync>): string {
169
+ return result.stdout.toString().trim();
164
170
  }
165
171
 
166
172
  export function processIdentity(pid: number): ProcessIdentity | null {
167
173
  const windows = process.platform === "win32";
168
174
  const argv = identityCommand(pid, windows);
169
- let result: ReturnType<typeof Bun.spawnSync>;
175
+ let result: ReturnType<typeof spawnSync>;
170
176
  try {
171
- result = Bun.spawnSync(argv, {
177
+ result = spawnSync(argv, {
172
178
  env: identityEnvironment(windows),
173
179
  stdout: "pipe",
174
180
  stderr: "ignore",
@@ -0,0 +1,21 @@
1
+ import { resolve, join } from "node:path";
2
+
3
+ export const sourceRuntime = import.meta.filename.endsWith(".ts");
4
+ export const runnerRoot = resolve(
5
+ import.meta.dirname,
6
+ sourceRuntime ? ".." : "../..",
7
+ );
8
+
9
+ export function examplePath(...parts: string[]): string {
10
+ const path = join(
11
+ runnerRoot,
12
+ ...(sourceRuntime ? [] : ["dist"]),
13
+ "examples",
14
+ ...parts,
15
+ );
16
+ return runtimeModule(path);
17
+ }
18
+
19
+ export function runtimeModule(path: string): string {
20
+ return sourceRuntime ? path : path.replace(/\.ts$/, ".js");
21
+ }
@@ -1,3 +1,4 @@
1
+ import { spawn } from "../runtime-process";
1
2
  import { readFile, readdir, writeFile } from "node:fs/promises";
2
3
  import { basename, dirname, join } from "node:path";
3
4
  import { isRecord } from "../value-guards";
@@ -22,7 +23,7 @@ export async function hookExecutions(
22
23
  }
23
24
 
24
25
  async function processOutput(argv: string[]): Promise<string> {
25
- const child = Bun.spawn(argv, { stdout: "pipe", stderr: "ignore" });
26
+ const child = spawn(argv, { stdout: "pipe", stderr: "ignore" });
26
27
  const output = await new Response(child.stdout).text();
27
28
  await child.exited;
28
29
  if (Buffer.byteLength(output) > 1024 * 1024)
@@ -1,3 +1,5 @@
1
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
2
+ import { existsSync } from "node:fs";
1
3
  import {
2
4
  cp,
3
5
  mkdir,
@@ -253,23 +255,23 @@ async function rewritePlugin(
253
255
  manifest: Record<string, unknown>,
254
256
  state: HookRewrite,
255
257
  ): Promise<void> {
256
- await requireHookOnlyPlugin(state.root);
258
+ requireHookOnlyPlugin(state.root);
257
259
  await rewriteManifest(manifest, state, ".claude-plugin/plugin.json");
258
260
  const native = join(state.root, ".codex-plugin/plugin.json");
259
- if (await Bun.file(native).exists())
261
+ if (existsSync(native))
260
262
  await rewriteManifest(
261
263
  object(JSON.parse(await readFile(native, "utf8"))),
262
264
  state,
263
265
  ".codex-plugin/plugin.json",
264
266
  );
265
267
  const standard = join(state.root, "hooks/hooks.json");
266
- if (await Bun.file(standard).exists()) await hookFile(standard, state);
268
+ if (existsSync(standard)) await hookFile(standard, state);
267
269
  await rewriteFrontmatter(state.root, state);
268
270
  }
269
271
 
270
- async function requireHookOnlyPlugin(root: string): Promise<void> {
272
+ function requireHookOnlyPlugin(root: string): void {
271
273
  for (const name of [".mcp.json", ".lsp.json"])
272
- if (await Bun.file(join(root, name)).exists())
274
+ if (existsSync(join(root, name)))
273
275
  throw new Error("runtime auxiliary plugin execution is unsupported");
274
276
  }
275
277
 
@@ -432,7 +434,7 @@ async function rewriteMarkdown(
432
434
  else delete metadata.hooks;
433
435
  await writeFile(
434
436
  path,
435
- `---\n${Bun.YAML.stringify(metadata)}\n---\n${body.slice(header[0].length)}`,
437
+ `---\n${stringifyYaml(metadata)}\n---\n${body.slice(header[0].length)}`,
436
438
  );
437
439
  }
438
440
 
@@ -440,7 +442,7 @@ function hookFrontmatter(
440
442
  header: string | undefined,
441
443
  ): Record<string, unknown> | undefined {
442
444
  if (!header?.includes("hooks")) return undefined;
443
- const metadata = object(Bun.YAML.parse(header));
445
+ const metadata = object(parseYaml(header));
444
446
  return metadata.hooks === undefined ? undefined : metadata;
445
447
  }
446
448
 
@@ -0,0 +1,194 @@
1
+ import {
2
+ spawn as nodeSpawn,
3
+ spawnSync as nodeSpawnSync,
4
+ type ChildProcess,
5
+ } from "node:child_process";
6
+ import { Readable, Writable } from "node:stream";
7
+ import { constants } from "node:os";
8
+
9
+ interface ProcessWriter {
10
+ write(data: string | Uint8Array): unknown;
11
+ end(): unknown;
12
+ }
13
+
14
+ export interface Subprocess {
15
+ pid: number;
16
+ stdin: ProcessWriter | null;
17
+ stdout: ReadableStream<Uint8Array>;
18
+ stderr: ReadableStream<Uint8Array>;
19
+ exited: Promise<number>;
20
+ readonly signalCode: string | null;
21
+ kill(signal: NodeJS.Signals): void;
22
+ }
23
+
24
+ interface SpawnOptions {
25
+ cwd?: string;
26
+ env?: NodeJS.ProcessEnv;
27
+ detached?: boolean;
28
+ stdin?: "pipe" | "ignore" | Uint8Array;
29
+ stdout?: "pipe" | "ignore";
30
+ stderr?: "pipe" | "ignore";
31
+ }
32
+
33
+ function emptyStream(): ReadableStream<Uint8Array> {
34
+ return new ReadableStream({
35
+ start(controller) {
36
+ controller.close();
37
+ },
38
+ });
39
+ }
40
+
41
+ function readable(stream: Readable | null): ReadableStream<Uint8Array> {
42
+ // Node and Bun declare different overloads for the same Web Streams API.
43
+ return stream
44
+ ? (Readable.toWeb(stream) as unknown as ReadableStream<Uint8Array>)
45
+ : emptyStream();
46
+ }
47
+
48
+ function output(
49
+ stream: ReadableStream<Uint8Array> | null | undefined,
50
+ ): ReadableStream<Uint8Array> {
51
+ return stream ?? emptyStream();
52
+ }
53
+
54
+ function writer(stream: Writable | null): ProcessWriter | null {
55
+ if (!stream) return null;
56
+ const destination = Writable.toWeb(stream).getWriter();
57
+ return {
58
+ write: (data) =>
59
+ destination.write(typeof data === "string" ? Buffer.from(data) : data),
60
+ end: () => destination.close(),
61
+ };
62
+ }
63
+
64
+ function commandName(argv: string[]): string {
65
+ const name = argv[0];
66
+ if (!name) throw new Error("process command must be nonempty");
67
+ return name;
68
+ }
69
+
70
+ function stdinMode(input: SpawnOptions["stdin"]) {
71
+ return input === "pipe" || input instanceof Uint8Array ? "pipe" : "ignore";
72
+ }
73
+
74
+ function processId(child: ChildProcess): number {
75
+ if (child.pid !== undefined) return child.pid;
76
+ child.once("error", () => {});
77
+ throw new Error("could not start process");
78
+ }
79
+
80
+ function exitCode(code: number | null, signal: NodeJS.Signals | null): number {
81
+ return code ?? 128 + (signal ? constants.signals[signal] : 0);
82
+ }
83
+
84
+ function completion(child: ChildProcess): Promise<number> {
85
+ return new Promise((resolve, reject) => {
86
+ child.once("error", reject);
87
+ child.once("exit", (code, signal) => {
88
+ resolve(exitCode(code, signal));
89
+ });
90
+ });
91
+ }
92
+
93
+ async function initialInput(
94
+ stdin: ProcessWriter | null,
95
+ input: SpawnOptions["stdin"],
96
+ ) {
97
+ if (!(input instanceof Uint8Array)) return;
98
+ if (!stdin) throw new Error("process input pipe unavailable");
99
+ await stdin.write(input);
100
+ await stdin.end();
101
+ }
102
+
103
+ function nodeProcess(argv: string[], options: SpawnOptions): Subprocess {
104
+ const child = nodeSpawn(commandName(argv), argv.slice(1), {
105
+ cwd: options.cwd,
106
+ env: options.env,
107
+ detached: options.detached,
108
+ stdio: [
109
+ stdinMode(options.stdin),
110
+ options.stdout ?? "pipe",
111
+ options.stderr ?? "pipe",
112
+ ],
113
+ });
114
+ const pid = processId(child);
115
+ const exited = completion(child);
116
+ const stdin = writer(child.stdin);
117
+ return {
118
+ pid,
119
+ stdin,
120
+ stdout: readable(child.stdout),
121
+ stderr: readable(child.stderr),
122
+ exited: Promise.all([exited, initialInput(stdin, options.stdin)]).then(
123
+ ([code]) => code,
124
+ ),
125
+ get signalCode() {
126
+ return child.signalCode;
127
+ },
128
+ kill(signal) {
129
+ child.kill(signal);
130
+ },
131
+ };
132
+ }
133
+
134
+ function bunProcess(argv: string[], options: SpawnOptions): Subprocess {
135
+ const child = Bun.spawn(argv, {
136
+ ...options,
137
+ stdin: options.stdin ?? "ignore",
138
+ stderr: options.stderr ?? "pipe",
139
+ });
140
+ return {
141
+ pid: child.pid,
142
+ stdin: typeof child.stdin === "object" ? child.stdin : null,
143
+ stdout: output(child.stdout),
144
+ stderr: output(child.stderr),
145
+ exited: child.exited,
146
+ get signalCode() {
147
+ return child.signalCode ?? null;
148
+ },
149
+ kill(signal) {
150
+ child.kill(signal);
151
+ },
152
+ };
153
+ }
154
+
155
+ /** Keep the runner's process/stream contract independent of its JS runtime. */
156
+ export function spawn(argv: string[], options: SpawnOptions = {}): Subprocess {
157
+ return process.versions.bun
158
+ ? bunProcess(argv, options)
159
+ : nodeProcess(argv, options);
160
+ }
161
+
162
+ function buffer(bytes: Buffer | null | undefined): Buffer {
163
+ return bytes ?? Buffer.alloc(0);
164
+ }
165
+
166
+ function bunSync(argv: string[], options: SpawnOptions) {
167
+ const result = Bun.spawnSync(argv, options);
168
+ return {
169
+ exitCode: result.exitCode,
170
+ stdout: buffer(result.stdout),
171
+ stderr: buffer(result.stderr),
172
+ };
173
+ }
174
+
175
+ function nodeSync(argv: string[], options: SpawnOptions) {
176
+ const result = nodeSpawnSync(commandName(argv), argv.slice(1), {
177
+ cwd: options.cwd,
178
+ env: options.env,
179
+ stdio: ["ignore", options.stdout ?? "pipe", options.stderr ?? "pipe"],
180
+ maxBuffer: 64 * 1024 * 1024,
181
+ });
182
+ if (result.error) throw result.error;
183
+ return {
184
+ exitCode: result.status ?? 1,
185
+ stdout: buffer(result.stdout),
186
+ stderr: buffer(result.stderr),
187
+ };
188
+ }
189
+
190
+ export function spawnSync(argv: string[], options: SpawnOptions = {}) {
191
+ return process.versions.bun
192
+ ? bunSync(argv, options)
193
+ : nodeSync(argv, options);
194
+ }
@@ -0,0 +1,25 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ const require = createRequire(import.meta.url);
4
+
5
+ interface LockDatabase {
6
+ exec(sql: string): unknown;
7
+ close(): void;
8
+ }
9
+
10
+ /** Both drivers use SQLite file locks, including across Node and Bun runners. */
11
+ export function openLockDatabase(path: string): LockDatabase {
12
+ if (process.versions.bun) {
13
+ const { Database } = require("bun:sqlite") as typeof import("bun:sqlite");
14
+ const database = new Database(path);
15
+ return {
16
+ exec: (sql) => database.run(sql),
17
+ close() {
18
+ database.close();
19
+ },
20
+ };
21
+ }
22
+ const { DatabaseSync } =
23
+ require("node:sqlite") as typeof import("node:sqlite");
24
+ return new DatabaseSync(path);
25
+ }