@phyzess/pappra 0.1.0-beta.14 → 0.1.0-beta.19

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 (365) hide show
  1. package/README.md +133 -14
  2. package/assets/integrations/skills/pappra/SKILL.md +56 -7
  3. package/assets/integrations/skills/pappra/references/collaboration.md +646 -0
  4. package/assets/integrations/skills/pappra/references/environment.md +367 -0
  5. package/assets/integrations/skills/pappra/references/hosts.md +20 -0
  6. package/assets/integrations/skills/pappra/references/operations.md +36 -5
  7. package/dist/adapters/pi/recovery-extension.d.ts +65 -0
  8. package/dist/adapters/pi/recovery-extension.js +238 -0
  9. package/dist/adapters/pi/session-transition-extension.d.ts +30 -0
  10. package/dist/adapters/pi/session-transition-extension.js +265 -0
  11. package/dist/app/automatic-handoff-events.d.ts +26 -0
  12. package/dist/app/automatic-handoff-events.js +134 -0
  13. package/dist/app/bounded-file.d.ts +2 -0
  14. package/dist/app/bounded-file.js +2 -0
  15. package/dist/app/capability-evidence/claude.d.ts +37 -0
  16. package/dist/app/capability-evidence/claude.js +206 -0
  17. package/dist/app/capability-evidence/codex.d.ts +35 -0
  18. package/dist/app/capability-evidence/codex.js +193 -0
  19. package/dist/app/capability-evidence/index.d.ts +33 -0
  20. package/dist/app/capability-evidence/index.js +117 -0
  21. package/dist/app/capability-evidence/pi.d.ts +73 -0
  22. package/dist/app/capability-evidence/pi.js +669 -0
  23. package/dist/app/capability-evidence/shared.d.ts +69 -0
  24. package/dist/app/capability-evidence/shared.js +195 -0
  25. package/dist/app/collab-auto-handoff.d.ts +55 -0
  26. package/dist/app/collab-auto-handoff.js +384 -0
  27. package/dist/app/collab-bindings.d.ts +57 -0
  28. package/dist/app/collab-bindings.js +1006 -0
  29. package/dist/app/collab-bootstrap-transport.d.ts +163 -0
  30. package/dist/app/collab-bootstrap-transport.js +769 -0
  31. package/dist/app/collab-bootstrap.d.ts +137 -0
  32. package/dist/app/collab-bootstrap.js +3455 -0
  33. package/dist/app/collab-handoff.d.ts +12 -0
  34. package/dist/app/collab-handoff.js +511 -0
  35. package/dist/app/collab-messages.d.ts +2 -0
  36. package/dist/app/collab-messages.js +2 -0
  37. package/dist/app/collab-notify.d.ts +156 -0
  38. package/dist/app/collab-notify.js +1208 -0
  39. package/dist/app/collab-preflight.d.ts +34 -0
  40. package/dist/app/collab-preflight.js +96 -0
  41. package/dist/app/collab-recovery-executor.d.ts +161 -0
  42. package/dist/app/collab-recovery-executor.js +1153 -0
  43. package/dist/app/collab-recovery-projection.d.ts +103 -0
  44. package/dist/app/collab-recovery-projection.js +659 -0
  45. package/dist/app/collab-recovery.d.ts +25 -0
  46. package/dist/app/collab-recovery.js +429 -0
  47. package/dist/app/collab-resources.d.ts +16 -0
  48. package/dist/app/collab-resources.js +278 -0
  49. package/dist/app/collab-role-events.d.ts +22 -0
  50. package/dist/app/collab-role-events.js +329 -0
  51. package/dist/app/collab-role-orchestration.d.ts +53 -0
  52. package/dist/app/collab-role-orchestration.js +601 -0
  53. package/dist/app/collab-role-plan.d.ts +81 -0
  54. package/dist/app/collab-role-plan.js +504 -0
  55. package/dist/app/collab-role-repair.d.ts +109 -0
  56. package/dist/app/collab-role-repair.js +821 -0
  57. package/dist/app/collab-rollover.d.ts +263 -0
  58. package/dist/app/collab-rollover.js +1112 -0
  59. package/dist/app/collab-route.d.ts +64 -0
  60. package/dist/app/collab-route.js +240 -0
  61. package/dist/app/collab-session-transition-request.d.ts +50 -0
  62. package/dist/app/collab-session-transition-request.js +339 -0
  63. package/dist/app/collab-session-transition-validation.d.ts +19 -0
  64. package/dist/app/collab-session-transition-validation.js +44 -0
  65. package/dist/app/collab-session-transition.d.ts +181 -0
  66. package/dist/app/collab-session-transition.js +2970 -0
  67. package/dist/app/collab-state.d.ts +7 -0
  68. package/dist/app/collab-state.js +162 -0
  69. package/dist/app/collab-task-store.d.ts +22 -0
  70. package/dist/app/collab-task-store.js +204 -0
  71. package/dist/app/collab-work-execution.d.ts +127 -0
  72. package/dist/app/collab-work-execution.js +1027 -0
  73. package/dist/app/collab-work-plan.d.ts +87 -0
  74. package/dist/app/collab-work-plan.js +437 -0
  75. package/dist/app/collaboration.d.ts +8 -2
  76. package/dist/app/collaboration.js +101 -12
  77. package/dist/app/doctor.js +104 -3
  78. package/dist/app/host-mcp.js +34 -8
  79. package/dist/app/host-probe.js +4 -4
  80. package/dist/app/init.d.ts +58 -4
  81. package/dist/app/init.js +768 -155
  82. package/dist/app/managed-pi-bootstrap-admission.d.ts +14 -0
  83. package/dist/app/managed-pi-bootstrap-admission.js +104 -0
  84. package/dist/app/managed-pi-bootstrap-refresh.d.ts +10 -0
  85. package/dist/app/managed-pi-bootstrap-refresh.js +78 -0
  86. package/dist/app/managed-pi-delivery.d.ts +8 -0
  87. package/dist/app/managed-pi-delivery.js +110 -0
  88. package/dist/app/managed-pi-handoff-receiver.d.ts +15 -0
  89. package/dist/app/managed-pi-handoff-receiver.js +263 -0
  90. package/dist/app/managed-pi-handoff-reference.d.ts +3 -0
  91. package/dist/app/managed-pi-handoff-reference.js +60 -0
  92. package/dist/app/managed-pi-herdr.d.ts +21 -0
  93. package/dist/app/managed-pi-herdr.js +185 -0
  94. package/dist/app/managed-pi-initial-admission.d.ts +28 -0
  95. package/dist/app/managed-pi-initial-admission.js +416 -0
  96. package/dist/app/managed-pi-initial-launch.d.ts +5 -0
  97. package/dist/app/managed-pi-initial-launch.js +61 -0
  98. package/dist/app/managed-pi-native-observation.d.ts +36 -0
  99. package/dist/app/managed-pi-native-observation.js +191 -0
  100. package/dist/app/managed-pi-readiness.d.ts +29 -0
  101. package/dist/app/managed-pi-readiness.js +288 -0
  102. package/dist/app/managed-pi-repair-stop.d.ts +21 -0
  103. package/dist/app/managed-pi-repair-stop.js +371 -0
  104. package/dist/app/managed-pi-resume-admission.d.ts +32 -0
  105. package/dist/app/managed-pi-resume-admission.js +618 -0
  106. package/dist/app/managed-pi-retirement.d.ts +28 -0
  107. package/dist/app/managed-pi-retirement.js +112 -0
  108. package/dist/app/managed-pi-sdk-control.d.ts +7 -0
  109. package/dist/app/managed-pi-sdk-control.js +169 -0
  110. package/dist/app/managed-pi-sdk-runtime.d.ts +3 -0
  111. package/dist/app/managed-pi-sdk-runtime.js +483 -0
  112. package/dist/app/managed-pi-source-admission.d.ts +14 -0
  113. package/dist/app/managed-pi-source-admission.js +323 -0
  114. package/dist/app/managed-pi-transition-host.d.ts +36 -0
  115. package/dist/app/managed-pi-transition-host.js +292 -0
  116. package/dist/app/managed-pi.d.ts +54 -0
  117. package/dist/app/managed-pi.js +248 -0
  118. package/dist/app/shell-readiness.d.ts +66 -0
  119. package/dist/app/shell-readiness.js +368 -0
  120. package/dist/app/task-pin.d.ts +2 -23
  121. package/dist/app/task-pin.js +2 -113
  122. package/dist/cli/collaboration-router.d.ts +17 -0
  123. package/dist/cli/collaboration-router.js +604 -0
  124. package/dist/cli/commands/collaboration-binding.d.ts +13 -0
  125. package/dist/cli/commands/collaboration-binding.js +118 -0
  126. package/dist/cli/commands/collaboration-bootstrap.d.ts +10 -0
  127. package/dist/cli/commands/collaboration-bootstrap.js +84 -0
  128. package/dist/cli/commands/collaboration-capabilities.d.ts +13 -0
  129. package/dist/cli/commands/collaboration-capabilities.js +127 -0
  130. package/dist/cli/commands/collaboration-handoff.d.ts +13 -0
  131. package/dist/cli/commands/collaboration-handoff.js +102 -0
  132. package/dist/cli/commands/collaboration-message.d.ts +17 -0
  133. package/dist/cli/commands/collaboration-message.js +177 -0
  134. package/dist/cli/commands/collaboration-plan.d.ts +8 -0
  135. package/dist/cli/commands/collaboration-plan.js +108 -0
  136. package/dist/cli/commands/collaboration-preflight.d.ts +10 -0
  137. package/dist/cli/commands/collaboration-preflight.js +167 -0
  138. package/dist/cli/commands/collaboration-recovery-run.d.ts +46 -0
  139. package/dist/cli/commands/collaboration-recovery-run.js +224 -0
  140. package/dist/cli/commands/collaboration-recovery.d.ts +11 -0
  141. package/dist/cli/commands/collaboration-recovery.js +104 -0
  142. package/dist/cli/commands/collaboration-resources.d.ts +11 -0
  143. package/dist/cli/commands/collaboration-resources.js +96 -0
  144. package/dist/cli/commands/collaboration-role-plan.d.ts +9 -0
  145. package/dist/cli/commands/collaboration-role-plan.js +69 -0
  146. package/dist/cli/commands/collaboration-role-run.d.ts +11 -0
  147. package/dist/cli/commands/collaboration-role-run.js +128 -0
  148. package/dist/cli/commands/collaboration-rollover.d.ts +10 -0
  149. package/dist/cli/commands/collaboration-rollover.js +103 -0
  150. package/dist/cli/commands/collaboration-state.d.ts +10 -0
  151. package/dist/cli/commands/collaboration-state.js +96 -0
  152. package/dist/cli/commands/collaboration-transition.d.ts +10 -0
  153. package/dist/cli/commands/collaboration-transition.js +75 -0
  154. package/dist/cli/commands/collaboration-work-run.d.ts +34 -0
  155. package/dist/cli/commands/collaboration-work-run.js +178 -0
  156. package/dist/cli/commands/collaboration.d.ts +4 -0
  157. package/dist/cli/commands/collaboration.js +39 -4
  158. package/dist/cli/commands/continuity.js +2 -6
  159. package/dist/cli/commands/docs.d.ts +2 -0
  160. package/dist/cli/commands/docs.js +89 -15
  161. package/dist/cli/commands/host.d.ts +7 -1
  162. package/dist/cli/commands/host.js +122 -7
  163. package/dist/cli/commands/init.d.ts +20 -3
  164. package/dist/cli/commands/init.js +897 -232
  165. package/dist/cli/commands/mcp.d.ts +1 -0
  166. package/dist/cli/commands/mcp.js +11 -5
  167. package/dist/cli/commands/repair.d.ts +12 -0
  168. package/dist/cli/commands/repair.js +41 -0
  169. package/dist/cli/commands/runtime.d.ts +1 -1
  170. package/dist/cli/commands/runtime.js +139 -38
  171. package/dist/cli/commands/session.d.ts +7 -0
  172. package/dist/cli/commands/session.js +82 -0
  173. package/dist/cli/commands/task.js +19 -5
  174. package/dist/cli/options.d.ts +806 -0
  175. package/dist/cli/options.js +293 -0
  176. package/dist/cli/run.js +280 -310
  177. package/dist/code/identity.d.ts +7 -0
  178. package/dist/code/identity.js +7 -3
  179. package/dist/code/registration.js +7 -0
  180. package/dist/code/service.d.ts +9 -0
  181. package/dist/code/service.js +16 -3
  182. package/dist/code/text.js +19 -7
  183. package/dist/collab/admission.d.ts +91 -66
  184. package/dist/collab/admission.js +21 -6
  185. package/dist/collab/canonical.d.ts +1 -1
  186. package/dist/collab/canonical.js +44 -3
  187. package/dist/collab/envelope.d.ts +2 -2
  188. package/dist/collab/envelope.js +12 -12
  189. package/dist/collab/first-work.d.ts +3 -0
  190. package/dist/collab/first-work.js +15 -0
  191. package/dist/collab/handoff.d.ts +16 -0
  192. package/dist/collab/handoff.js +39 -5
  193. package/dist/collab/index.d.ts +97 -1
  194. package/dist/collab/index.js +9 -1
  195. package/dist/collab/messages.js +126 -3
  196. package/dist/collab/persisted-messages.d.ts +123 -0
  197. package/dist/collab/persisted-messages.js +496 -0
  198. package/dist/collab/preflight.d.ts +1 -1
  199. package/dist/collab/resources.d.ts +13 -3
  200. package/dist/collab/resources.js +37 -6
  201. package/dist/collab/rollover.d.ts +311 -0
  202. package/dist/collab/rollover.js +1024 -0
  203. package/dist/collab/store.d.ts +1 -0
  204. package/dist/collab/store.js +1 -4
  205. package/dist/collab/types.d.ts +2 -354
  206. package/dist/collab/validation.d.ts +2 -10
  207. package/dist/collab/validation.js +2 -303
  208. package/dist/collab/work-plan.d.ts +105 -0
  209. package/dist/collab/work-plan.js +843 -0
  210. package/dist/continuity/context.d.ts +11 -2
  211. package/dist/continuity/context.js +100 -13
  212. package/dist/continuity/handoff-bundle.d.ts +296 -0
  213. package/dist/continuity/handoff-bundle.js +477 -0
  214. package/dist/continuity/index.d.ts +2 -0
  215. package/dist/continuity/index.js +1 -0
  216. package/dist/continuity/paths.js +10 -2
  217. package/dist/continuity/service.js +91 -15
  218. package/dist/continuity/task-pin.d.ts +24 -0
  219. package/dist/continuity/task-pin.js +590 -0
  220. package/dist/doctor.d.ts +1 -0
  221. package/dist/doctor.js +6 -0
  222. package/dist/experimental/index.d.ts +13 -0
  223. package/dist/experimental/index.js +25 -0
  224. package/dist/experimental/pi.d.ts +4 -0
  225. package/dist/experimental/pi.js +12 -0
  226. package/dist/hosts/claude/native.js +1 -1
  227. package/dist/hosts/codex/native.js +1 -1
  228. package/dist/hosts/codex/protocol.js +1 -1
  229. package/dist/hosts/integration/bootstrap-config.d.ts +58 -0
  230. package/dist/hosts/integration/bootstrap-config.js +254 -0
  231. package/dist/hosts/integration/bundle-export.d.ts +44 -0
  232. package/dist/hosts/integration/bundle-export.js +366 -3
  233. package/dist/hosts/integration/bundle.js +3 -0
  234. package/dist/hosts/integration/hook.js +36 -9
  235. package/dist/hosts/integration/pappra-bootstrap-extension.mjs +80 -0
  236. package/dist/hosts/integration/pappra-extension-runtime.mjs +59 -24631
  237. package/dist/hosts/integration/pappra-hook.mjs +61 -24749
  238. package/dist/hosts/integration/pappra-recovery-extension.mjs +259 -0
  239. package/dist/hosts/integration/pappra-session-transition-extension.mjs +276 -0
  240. package/dist/hosts/integration/pi-bootstrap-extension.d.ts +36 -0
  241. package/dist/hosts/integration/pi-bootstrap-extension.js +101 -0
  242. package/dist/hosts/integration/pi-bootstrap-guard.d.ts +125 -0
  243. package/dist/hosts/integration/pi-bootstrap-guard.js +438 -0
  244. package/dist/hosts/integration/pi-bootstrap-runtime.d.ts +63 -0
  245. package/dist/hosts/integration/pi-bootstrap-runtime.js +223 -0
  246. package/dist/hosts/integration/pi-native-events.d.ts +112 -0
  247. package/dist/hosts/integration/pi-native-events.js +348 -0
  248. package/dist/hosts/integration/pi-rollover-extension.d.ts +166 -0
  249. package/dist/hosts/integration/pi-rollover-extension.js +431 -0
  250. package/dist/hosts/integration/recovery-config.d.ts +48 -0
  251. package/dist/hosts/integration/recovery-config.js +117 -0
  252. package/dist/hosts/integration/service.d.ts +6 -1
  253. package/dist/hosts/integration/service.js +485 -35
  254. package/dist/hosts/integration/support.d.ts +7 -0
  255. package/dist/hosts/integration/support.js +9 -1
  256. package/dist/hosts/integration/templates.d.ts +3 -0
  257. package/dist/hosts/integration/templates.js +26 -3
  258. package/dist/hosts/pi/managed-host-identity.d.ts +2 -0
  259. package/dist/hosts/pi/managed-host-identity.js +40 -0
  260. package/dist/hosts/pi/managed-provider-diagnostics.d.ts +6 -0
  261. package/dist/hosts/pi/managed-provider-diagnostics.js +184 -0
  262. package/dist/hosts/pi/managed-sdk-session.d.ts +335 -0
  263. package/dist/hosts/pi/managed-sdk-session.js +1639 -0
  264. package/dist/hosts/pi/managed-session-extension.d.ts +20 -0
  265. package/dist/hosts/pi/managed-session-extension.js +84 -0
  266. package/dist/hosts/pi/managed-session.d.ts +177 -0
  267. package/dist/hosts/pi/managed-session.js +1557 -0
  268. package/dist/hosts/pi/protocol.js +1 -1
  269. package/dist/hosts/pi/query-result.js +1 -1
  270. package/dist/hosts/pi/resume-capability.d.ts +41 -0
  271. package/dist/hosts/pi/resume-capability.js +33 -0
  272. package/dist/hosts/pi/rpc.d.ts +182 -134
  273. package/dist/hosts/pi/rpc.js +230 -37
  274. package/dist/hosts/pilot.d.ts +90 -67
  275. package/dist/hosts/pilot.js +5 -1
  276. package/dist/hosts/version.d.ts +3 -0
  277. package/dist/hosts/version.js +18 -0
  278. package/dist/index.d.ts +0 -1
  279. package/dist/index.js +0 -1
  280. package/dist/infra/bounded-file.d.ts +19 -0
  281. package/dist/infra/bounded-file.js +66 -0
  282. package/dist/infra/fs.js +10 -2
  283. package/dist/infra/git.d.ts +29 -0
  284. package/dist/infra/git.js +45 -9
  285. package/dist/infra/json-property.d.ts +2 -0
  286. package/dist/infra/json-property.js +69 -0
  287. package/dist/infra/json.d.ts +4 -0
  288. package/dist/infra/json.js +24 -0
  289. package/dist/infra/owned-process-group.js +1 -1
  290. package/dist/infra/private-lock.d.ts +16 -0
  291. package/dist/infra/private-lock.js +148 -0
  292. package/dist/infra/private-state.d.ts +7 -0
  293. package/dist/infra/private-state.js +146 -0
  294. package/dist/infra/process-identity.d.ts +12 -0
  295. package/dist/infra/process-identity.js +142 -0
  296. package/dist/infra/validation.d.ts +5 -0
  297. package/dist/infra/validation.js +15 -0
  298. package/dist/init.d.ts +1 -0
  299. package/dist/init.js +6 -0
  300. package/dist/install/apply.d.ts +9 -1
  301. package/dist/install/apply.js +176 -12
  302. package/dist/install/dependencies.d.ts +38 -0
  303. package/dist/install/dependencies.js +282 -0
  304. package/dist/install/ownership.js +30 -1
  305. package/dist/install/references.d.ts +31 -0
  306. package/dist/install/references.js +208 -0
  307. package/dist/install/repair.d.ts +37 -0
  308. package/dist/install/repair.js +798 -0
  309. package/dist/install/reset-local.d.ts +16 -0
  310. package/dist/install/reset-local.js +304 -0
  311. package/dist/install/rollback.d.ts +3 -0
  312. package/dist/install/rollback.js +9 -3
  313. package/dist/install/runtime.d.ts +10 -6
  314. package/dist/install/runtime.js +299 -59
  315. package/dist/install/source-fingerprint.d.ts +2 -0
  316. package/dist/install/source-fingerprint.js +103 -0
  317. package/dist/knowledge/catalog.d.ts +1 -0
  318. package/dist/knowledge/catalog.js +143 -10
  319. package/dist/knowledge/journal.js +17 -7
  320. package/dist/knowledge/paths.js +2 -1
  321. package/dist/knowledge/refs.js +4 -0
  322. package/dist/knowledge/register-batch.d.ts +4 -0
  323. package/dist/knowledge/register-batch.js +225 -0
  324. package/dist/knowledge/relocate.d.ts +5 -0
  325. package/dist/knowledge/relocate.js +92 -0
  326. package/dist/knowledge/scan.js +103 -47
  327. package/dist/knowledge/service.d.ts +3 -0
  328. package/dist/knowledge/service.js +33 -1
  329. package/dist/knowledge/write.d.ts +4 -1
  330. package/dist/knowledge/write.js +1 -1
  331. package/dist/mcp/server.d.ts +4 -2
  332. package/dist/mcp/server.js +87 -136
  333. package/dist/schemas/collaboration-state-validation.d.ts +6 -0
  334. package/dist/schemas/collaboration-state-validation.js +342 -0
  335. package/dist/schemas/collaboration-state.d.ts +436 -0
  336. package/dist/schemas/collaboration-state.js +1 -0
  337. package/dist/schemas/collaboration.d.ts +335 -0
  338. package/dist/schemas/collaboration.js +272 -0
  339. package/dist/schemas/continuity.d.ts +8 -0
  340. package/dist/schemas/continuity.js +13 -3
  341. package/dist/schemas/doctor.d.ts +1 -0
  342. package/dist/schemas/doctor.js +1 -0
  343. package/dist/schemas/document.d.ts +61 -0
  344. package/dist/schemas/document.js +9 -0
  345. package/dist/schemas/errors.d.ts +1 -0
  346. package/dist/schemas/errors.js +1 -0
  347. package/dist/schemas/host.d.ts +24 -0
  348. package/dist/schemas/host.js +19 -0
  349. package/dist/schemas/install.d.ts +8 -2
  350. package/dist/schemas/install.js +11 -1
  351. package/dist/schemas/managed-pi-execution.d.ts +16 -0
  352. package/dist/schemas/managed-pi-execution.js +2 -0
  353. package/dist/schemas/outcome.d.ts +9 -5
  354. package/dist/workspace/config-file.js +1 -3
  355. package/dist/workspace/documents.js +12 -2
  356. package/dist/workspace/repositories.d.ts +7 -0
  357. package/dist/workspace/repositories.js +14 -5
  358. package/package.json +37 -35
  359. package/skills/pappra/SKILL.md +56 -7
  360. package/skills/pappra/references/collaboration.md +646 -0
  361. package/skills/pappra/references/environment.md +367 -0
  362. package/skills/pappra/references/hosts.md +20 -0
  363. package/skills/pappra/references/operations.md +36 -5
  364. package/dist/app/collab-from.d.ts +0 -35
  365. package/dist/app/collab-from.js +0 -84
@@ -28,6 +28,8 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
28
28
  reservation?: never;
29
29
  refused: boolean;
30
30
  admission: {
31
+ state?: never;
32
+ state_revision?: never;
31
33
  ok: false;
32
34
  reason: string;
33
35
  checks: Record<string, unknown>[];
@@ -36,10 +38,6 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
36
38
  required_skills?: never;
37
39
  required_tools?: never;
38
40
  preflight?: never;
39
- state?: never;
40
- detail?: never;
41
- state_revision?: never;
42
- owner_epoch?: never;
43
41
  attempt_state?: never;
44
42
  resources?: never;
45
43
  mode?: never;
@@ -50,19 +48,19 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
50
48
  capability_evidence?: never;
51
49
  assignment_digest?: never;
52
50
  input_revision?: never;
51
+ owner_epoch?: never;
52
+ detail?: never;
53
53
  } | {
54
+ expected?: never;
55
+ state?: never;
56
+ state_revision?: never;
54
57
  ok: false;
55
58
  reason: string;
56
59
  checks: Record<string, unknown>[];
57
- detail: string;
60
+ actual: string;
58
61
  required_skills?: never;
59
62
  required_tools?: never;
60
63
  preflight?: never;
61
- state?: never;
62
- expected?: never;
63
- actual?: never;
64
- state_revision?: never;
65
- owner_epoch?: never;
66
64
  attempt_state?: never;
67
65
  resources?: never;
68
66
  mode?: never;
@@ -73,19 +71,42 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
73
71
  capability_evidence?: never;
74
72
  assignment_digest?: never;
75
73
  input_revision?: never;
74
+ owner_epoch?: never;
75
+ detail?: never;
76
76
  } | {
77
+ expected?: never;
78
+ actual?: never;
79
+ state?: never;
80
+ state_revision?: never;
77
81
  ok: false;
78
82
  reason: string;
79
83
  checks: Record<string, unknown>[];
84
+ detail: string;
80
85
  required_skills?: never;
81
86
  required_tools?: never;
82
87
  preflight?: never;
83
- state?: never;
84
- detail?: never;
88
+ attempt_state?: never;
89
+ resources?: never;
90
+ mode?: never;
91
+ launch_kind?: never;
92
+ resume_selector?: never;
93
+ pre_bound_identity?: never;
94
+ expected_identity?: never;
95
+ capability_evidence?: never;
96
+ assignment_digest?: never;
97
+ input_revision?: never;
98
+ owner_epoch?: never;
99
+ } | {
85
100
  expected?: never;
86
101
  actual?: never;
102
+ state?: never;
87
103
  state_revision?: never;
88
- owner_epoch?: never;
104
+ ok: false;
105
+ reason: string;
106
+ checks: Record<string, unknown>[];
107
+ required_skills?: never;
108
+ required_tools?: never;
109
+ preflight?: never;
89
110
  attempt_state?: never;
90
111
  resources?: never;
91
112
  mode?: never;
@@ -96,7 +117,11 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
96
117
  capability_evidence?: never;
97
118
  assignment_digest?: never;
98
119
  input_revision?: never;
120
+ owner_epoch?: never;
121
+ detail?: never;
99
122
  } | {
123
+ state?: never;
124
+ state_revision?: never;
100
125
  ok: false;
101
126
  reason: string;
102
127
  checks: Record<string, unknown>[];
@@ -105,10 +130,6 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
105
130
  required_skills?: never;
106
131
  required_tools?: never;
107
132
  preflight?: never;
108
- state?: never;
109
- detail?: never;
110
- state_revision?: never;
111
- owner_epoch?: never;
112
133
  attempt_state?: never;
113
134
  resources?: never;
114
135
  mode?: never;
@@ -119,12 +140,16 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
119
140
  capability_evidence?: never;
120
141
  assignment_digest?: never;
121
142
  input_revision?: never;
143
+ owner_epoch?: never;
144
+ detail?: never;
122
145
  } | {
146
+ state?: never;
147
+ state_revision?: never;
123
148
  ok: false;
124
149
  reason: string;
125
150
  checks: Record<string, unknown>[];
126
- expected: import("../collab/types.js").Identity;
127
- actual: import("../collab/types.js").Identity & {
151
+ expected: import("../schemas/collaboration-state.js").Identity;
152
+ actual: import("../schemas/collaboration-state.js").Identity & {
128
153
  harness: string;
129
154
  cwd: string;
130
155
  surface: string;
@@ -133,10 +158,6 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
133
158
  required_skills?: never;
134
159
  required_tools?: never;
135
160
  preflight?: never;
136
- state?: never;
137
- detail?: never;
138
- state_revision?: never;
139
- owner_epoch?: never;
140
161
  attempt_state?: never;
141
162
  resources?: never;
142
163
  mode?: never;
@@ -147,7 +168,11 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
147
168
  capability_evidence?: never;
148
169
  assignment_digest?: never;
149
170
  input_revision?: never;
171
+ owner_epoch?: never;
172
+ detail?: never;
150
173
  } | {
174
+ state?: never;
175
+ state_revision?: never;
151
176
  ok: false;
152
177
  reason: string;
153
178
  checks: Record<string, unknown>[];
@@ -157,9 +182,6 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
157
182
  required_skills?: never;
158
183
  required_tools?: never;
159
184
  preflight?: never;
160
- state?: never;
161
- state_revision?: never;
162
- owner_epoch?: never;
163
185
  attempt_state?: never;
164
186
  resources?: never;
165
187
  mode?: never;
@@ -170,19 +192,18 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
170
192
  capability_evidence?: never;
171
193
  assignment_digest?: never;
172
194
  input_revision?: never;
195
+ owner_epoch?: never;
173
196
  } | {
197
+ expected?: never;
198
+ actual?: never;
199
+ state?: never;
200
+ state_revision?: never;
174
201
  ok: false;
175
202
  reason: string;
176
203
  checks: Record<string, unknown>[];
177
204
  required_skills: number;
178
205
  required_tools: number;
179
206
  preflight?: never;
180
- state?: never;
181
- detail?: never;
182
- expected?: never;
183
- actual?: never;
184
- state_revision?: never;
185
- owner_epoch?: never;
186
207
  attempt_state?: never;
187
208
  resources?: never;
188
209
  mode?: never;
@@ -193,7 +214,13 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
193
214
  capability_evidence?: never;
194
215
  assignment_digest?: never;
195
216
  input_revision?: never;
217
+ owner_epoch?: never;
218
+ detail?: never;
196
219
  } | {
220
+ expected?: never;
221
+ actual?: never;
222
+ state?: never;
223
+ state_revision?: never;
197
224
  required_skills?: never;
198
225
  required_tools?: never;
199
226
  ok: false;
@@ -220,12 +247,6 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
220
247
  warnings: import("../collab/preflight.js").Check[];
221
248
  limits: string[];
222
249
  };
223
- state?: never;
224
- detail?: never;
225
- expected?: never;
226
- actual?: never;
227
- state_revision?: never;
228
- owner_epoch?: never;
229
250
  attempt_state?: never;
230
251
  resources?: never;
231
252
  mode?: never;
@@ -236,7 +257,12 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
236
257
  capability_evidence?: never;
237
258
  assignment_digest?: never;
238
259
  input_revision?: never;
260
+ owner_epoch?: never;
261
+ detail?: never;
239
262
  } | {
263
+ expected?: never;
264
+ actual?: never;
265
+ state_revision?: never;
240
266
  required_skills?: never;
241
267
  required_tools?: never;
242
268
  preflight?: never;
@@ -244,11 +270,6 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
244
270
  reason: string;
245
271
  checks: Record<string, unknown>[];
246
272
  state: string;
247
- detail?: never;
248
- expected?: never;
249
- actual?: never;
250
- state_revision?: never;
251
- owner_epoch?: never;
252
273
  attempt_state?: never;
253
274
  resources?: never;
254
275
  mode?: never;
@@ -259,19 +280,19 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
259
280
  capability_evidence?: never;
260
281
  assignment_digest?: never;
261
282
  input_revision?: never;
283
+ owner_epoch?: never;
284
+ detail?: never;
262
285
  } | {
286
+ state?: never;
287
+ state_revision?: never;
263
288
  required_skills?: never;
264
289
  required_tools?: never;
265
290
  preflight?: never;
266
- state?: never;
267
291
  ok: false;
268
292
  reason: string;
269
293
  checks: Record<string, unknown>[];
270
294
  expected: (string | null)[];
271
295
  actual: string;
272
- detail?: never;
273
- state_revision?: never;
274
- owner_epoch?: never;
275
296
  attempt_state?: never;
276
297
  resources?: never;
277
298
  mode?: never;
@@ -282,20 +303,21 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
282
303
  capability_evidence?: never;
283
304
  assignment_digest?: never;
284
305
  input_revision?: never;
306
+ owner_epoch?: never;
307
+ detail?: never;
285
308
  } | {
309
+ expected?: never;
310
+ actual?: never;
311
+ state?: never;
312
+ state_revision?: never;
286
313
  required_skills?: never;
287
314
  required_tools?: never;
288
315
  preflight?: never;
289
- state?: never;
290
316
  ok: false;
291
317
  reason: string;
292
318
  checks: Record<string, unknown>[];
293
319
  resources: Record<string, unknown>[];
294
320
  detail: string;
295
- expected?: never;
296
- actual?: never;
297
- state_revision?: never;
298
- owner_epoch?: never;
299
321
  attempt_state?: never;
300
322
  mode?: never;
301
323
  launch_kind?: never;
@@ -305,20 +327,19 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
305
327
  capability_evidence?: never;
306
328
  assignment_digest?: never;
307
329
  input_revision?: never;
330
+ owner_epoch?: never;
308
331
  } | {
332
+ state?: never;
333
+ state_revision?: never;
309
334
  required_skills?: never;
310
335
  required_tools?: never;
311
336
  preflight?: never;
312
- state?: never;
313
- detail?: never;
314
337
  ok: false;
315
338
  reason: string;
316
339
  checks: Record<string, unknown>[];
317
340
  resources: Record<string, unknown>[];
318
341
  expected: number | undefined;
319
342
  actual: number;
320
- state_revision?: never;
321
- owner_epoch?: never;
322
343
  attempt_state?: never;
323
344
  mode?: never;
324
345
  launch_kind?: never;
@@ -328,20 +349,20 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
328
349
  capability_evidence?: never;
329
350
  assignment_digest?: never;
330
351
  input_revision?: never;
352
+ owner_epoch?: never;
353
+ detail?: never;
331
354
  } | {
355
+ expected?: never;
356
+ actual?: never;
357
+ state?: never;
358
+ state_revision?: never;
332
359
  required_skills?: never;
333
360
  required_tools?: never;
334
361
  preflight?: never;
335
- state?: never;
336
- detail?: never;
337
- expected?: never;
338
- actual?: never;
339
362
  ok: false;
340
363
  reason: string;
341
364
  checks: Record<string, unknown>[];
342
365
  resources: Record<string, unknown>[];
343
- state_revision?: never;
344
- owner_epoch?: never;
345
366
  attempt_state?: never;
346
367
  mode?: never;
347
368
  launch_kind?: never;
@@ -351,6 +372,8 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
351
372
  capability_evidence?: never;
352
373
  assignment_digest?: never;
353
374
  input_revision?: never;
375
+ owner_epoch?: never;
376
+ detail?: never;
354
377
  };
355
378
  reason: string;
356
379
  process?: never;
@@ -366,14 +389,13 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
366
389
  } | {
367
390
  refused: boolean;
368
391
  admission: {
369
- required_skills?: never;
370
- required_tools?: never;
371
- preflight?: never;
372
- state?: never;
373
- detail?: never;
374
392
  expected?: never;
375
393
  actual?: never;
394
+ state?: never;
376
395
  reason?: never;
396
+ required_skills?: never;
397
+ required_tools?: never;
398
+ preflight?: never;
377
399
  ok: true;
378
400
  checks: Record<string, unknown>[];
379
401
  state_revision: number;
@@ -388,6 +410,7 @@ export declare function runNativePilot({ harness, profile, cwd, promptFile, evid
388
410
  capability_evidence: string;
389
411
  assignment_digest: string;
390
412
  input_revision: string | null;
413
+ detail?: never;
391
414
  };
392
415
  reason: string;
393
416
  reservation: {
@@ -6,7 +6,7 @@ import { spawn } from 'node:child_process';
6
6
  import { admitLaunch, reserveLaunch, settleLaunch, classifyIdentity, TOOL_PROFILES, } from '../collab/admission.js';
7
7
  import { createNonce, nowIso } from '../collab/store.js';
8
8
  import { sha256File as digestFile } from '../collab/envelope.js';
9
- import { object, parseJson } from '../collab/validation.js';
9
+ import { object, parseJson } from '../infra/validation.js';
10
10
  import { isAssignment } from '../collab/contracts.js';
11
11
  const PHASES = new Set([
12
12
  'discovery',
@@ -28,6 +28,7 @@ function buildArgv({ harness, profile, cwd, prompt, sessionId, resume, maxBudget
28
28
  ...(trustProject ? ['--approve'] : []),
29
29
  resume ? '--session' : '--session-id',
30
30
  (resume ?? sessionId),
31
+ '--',
31
32
  prompt,
32
33
  ];
33
34
  return { command: 'pi', argv, session_selector: resume ?? sessionId };
@@ -46,6 +47,7 @@ function buildArgv({ harness, profile, cwd, prompt, sessionId, resume, maxBudget
46
47
  '--skip-git-repo-check',
47
48
  '-c',
48
49
  `sandbox_mode="${sandbox}"`,
50
+ '--',
49
51
  prompt,
50
52
  ]
51
53
  : [
@@ -56,6 +58,7 @@ function buildArgv({ harness, profile, cwd, prompt, sessionId, resume, maxBudget
56
58
  '-s',
57
59
  sandbox,
58
60
  '--skip-git-repo-check',
61
+ '--',
59
62
  prompt,
60
63
  ];
61
64
  return { command: 'codex', argv: base, session_selector: resume ?? null };
@@ -88,6 +91,7 @@ function buildArgv({ harness, profile, cwd, prompt, sessionId, resume, maxBudget
88
91
  String(maxBudgetUsd),
89
92
  resume ? '--resume' : '--session-id',
90
93
  (resume ?? sessionId),
94
+ '--',
91
95
  prompt,
92
96
  ];
93
97
  return { command: 'claude', argv, session_selector: resume ?? sessionId };
@@ -0,0 +1,3 @@
1
+ import type { HostName } from '../schemas/host.js';
2
+ /** Bounded executable observation only; never sends a prompt or starts a model. */
3
+ export declare function observeHostVersion(host: HostName, pathEnv: string): string | null;
@@ -0,0 +1,18 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { executableOnPath } from './detect.js';
3
+ /** Bounded executable observation only; never sends a prompt or starts a model. */
4
+ export function observeHostVersion(host, pathEnv) {
5
+ const executable = executableOnPath(host, pathEnv);
6
+ if (!executable)
7
+ return null;
8
+ const result = spawnSync(executable, ['--version'], {
9
+ encoding: 'utf8',
10
+ shell: false,
11
+ timeout: 5000,
12
+ maxBuffer: 16 * 1024,
13
+ env: { ...process.env, PATH: pathEnv },
14
+ });
15
+ if (result.error || result.status !== 0)
16
+ return null;
17
+ return (/(?:^|\s)([0-9]+\.[0-9]+\.[0-9]+)(?:\s|$)/.exec(`${result.stdout}\n${result.stderr}`)?.[1] ?? null);
18
+ }
package/dist/index.d.ts CHANGED
@@ -2,4 +2,3 @@ export { getPackageInfo, getPackageRoot } from './package-info.js';
2
2
  export type { PackageInfo } from './package-info.js';
3
3
  export { HostAdapter, HostIntegrationService, type HostIntegrationOptions, type HostTargetOptions, } from './hosts/integration/service.js';
4
4
  export { mapNativeHookEvent, runHostHook, type HostHookOptions, type NativeHookMapping, } from './hosts/integration/hook.js';
5
- export * from './app/collaboration.js';
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
1
  export { getPackageInfo, getPackageRoot } from './package-info.js';
2
2
  export { HostAdapter, HostIntegrationService, } from './hosts/integration/service.js';
3
3
  export { mapNativeHookEvent, runHostHook, } from './hosts/integration/hook.js';
4
- export * from './app/collaboration.js';
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Bounded, read-only access to one explicit regular file.
3
+ *
4
+ * The pathname is observed first so obviously unsafe entries are refused without
5
+ * opening them. The open itself is nonblocking/no-follow on POSIX, so a regular
6
+ * file replaced by a FIFO or symlink between inspection and open cannot block or
7
+ * redirect the read; the descriptor is re-validated afterwards for type and size.
8
+ */
9
+ export type BoundedFileFailureCode = 'path_not_absolute' | 'symlink' | 'not_regular' | 'too_large' | 'unreadable';
10
+ export type BoundedFileResult = {
11
+ readonly ok: true;
12
+ readonly bytes: Buffer;
13
+ readonly text: string;
14
+ readonly digest: string;
15
+ } | {
16
+ readonly ok: false;
17
+ readonly code: BoundedFileFailureCode;
18
+ };
19
+ export declare function readBoundedFile(file: string, maxBytes: number): BoundedFileResult;
@@ -0,0 +1,66 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ const digestOf = (bytes) => `sha256:${crypto.createHash('sha256').update(bytes).digest('hex')}`;
5
+ const nonblockingFlag = () => process.platform === 'win32' ? 0 : (fs.constants.O_NONBLOCK ?? 0);
6
+ export function readBoundedFile(file, maxBytes) {
7
+ if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
8
+ throw new Error('Bounded read limit must be a positive integer.');
9
+ }
10
+ if (!path.isAbsolute(file)) {
11
+ return { ok: false, code: 'path_not_absolute' };
12
+ }
13
+ let observed;
14
+ try {
15
+ observed = fs.lstatSync(file);
16
+ }
17
+ catch {
18
+ return { ok: false, code: 'unreadable' };
19
+ }
20
+ if (observed.isSymbolicLink())
21
+ return { ok: false, code: 'symlink' };
22
+ if (!observed.isFile())
23
+ return { ok: false, code: 'not_regular' };
24
+ if (observed.size > maxBytes)
25
+ return { ok: false, code: 'too_large' };
26
+ const flags = fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0) | nonblockingFlag();
27
+ let handle;
28
+ try {
29
+ handle = fs.openSync(file, flags);
30
+ }
31
+ catch (error) {
32
+ const code = typeof error === 'object' && error !== null && 'code' in error
33
+ ? String(error.code)
34
+ : null;
35
+ return { ok: false, code: code === 'ELOOP' ? 'symlink' : 'unreadable' };
36
+ }
37
+ try {
38
+ const stat = fs.fstatSync(handle);
39
+ if (!stat.isFile())
40
+ return { ok: false, code: 'not_regular' };
41
+ if (stat.size > maxBytes)
42
+ return { ok: false, code: 'too_large' };
43
+ // Read at most the observed size (already bounded); never read until EOF.
44
+ const bytes = Buffer.alloc(stat.size);
45
+ let total = 0;
46
+ while (total < bytes.length) {
47
+ const read = fs.readSync(handle, bytes, total, bytes.length - total, total);
48
+ if (read === 0)
49
+ break;
50
+ total += read;
51
+ }
52
+ const content = bytes.subarray(0, total);
53
+ return {
54
+ ok: true,
55
+ bytes: content,
56
+ text: content.toString('utf8'),
57
+ digest: digestOf(content),
58
+ };
59
+ }
60
+ catch {
61
+ return { ok: false, code: 'unreadable' };
62
+ }
63
+ finally {
64
+ fs.closeSync(handle);
65
+ }
66
+ }
package/dist/infra/fs.js CHANGED
@@ -51,9 +51,17 @@ export async function readFileBounded(path, maxBytes = DEFAULT_CONFIG_MAX_BYTES)
51
51
  if (!stats.isFile()) {
52
52
  return failed(diagnosticCodes.fileNotRegular, `Not a regular file: ${path}`, { nextAction: 'Replace it with a regular file.' });
53
53
  }
54
- const buffer = Buffer.allocUnsafe(maxBytes + 1);
54
+ // Size the allocation to the opened file, rather than the caller's ceiling.
55
+ // Keep one extra byte to detect overflow, including files that grow after
56
+ // fstat; a small runtime dependency must not allocate the 64 MiB ceiling.
57
+ let buffer = Buffer.allocUnsafe(Math.min(stats.size, maxBytes) + 1);
55
58
  let total = 0;
56
- while (total < buffer.length) {
59
+ while (total <= maxBytes) {
60
+ if (total === buffer.length) {
61
+ const grown = Buffer.allocUnsafe(Math.min(maxBytes + 1, Math.max(4096, buffer.length * 2)));
62
+ buffer.copy(grown, 0, 0, total);
63
+ buffer = grown;
64
+ }
57
65
  const { bytesRead } = await handle.read(buffer, total, buffer.length - total, null);
58
66
  if (bytesRead === 0)
59
67
  break;
@@ -45,6 +45,12 @@ export interface InspectGitRepositoryOptions {
45
45
  readonly timeoutMs?: number;
46
46
  readonly maxOutputBytes?: number;
47
47
  readonly signal?: AbortSignal;
48
+ /**
49
+ * Set to `false` when the caller derives working-tree state from its own
50
+ * diffs. The observation then reports `dirty: null` instead of spawning an
51
+ * additional `git status` scan.
52
+ */
53
+ readonly workingTreeState?: boolean;
48
54
  }
49
55
  /**
50
56
  * Observes a repository without modifying the index, refs, or working tree.
@@ -58,3 +64,26 @@ export declare function inspectGitRepository(candidateRoot: string, options?: In
58
64
  * "nothing is ignored".
59
65
  */
60
66
  export declare function filterGitIgnored(repositoryRoot: string, candidates: readonly string[], options?: InspectGitRepositoryOptions): Promise<Outcome<readonly string[]>>;
67
+ export interface GitObservationScope {
68
+ readonly repository: (root: string, options?: InspectGitRepositoryOptions) => Promise<Outcome<GitRepositoryObservation>>;
69
+ }
70
+ export interface GitObservationScopeOptions {
71
+ /**
72
+ * Default for `InspectGitRepositoryOptions.workingTreeState`; `true` keeps the
73
+ * `inspectGitRepository` behaviour. Callers that derive working-tree state from
74
+ * their own diffs opt out to save one `git status` scan per checkout.
75
+ */
76
+ readonly workingTreeState?: boolean;
77
+ }
78
+ /**
79
+ * Memoizes Git repository probes for exactly one operation.
80
+ *
81
+ * Repository identity (root, git dir, HEAD, branch) is immutable for the
82
+ * duration of a single command, so repeated inspections of the same checkout
83
+ * reuse the first observation instead of spawning equivalent Git processes.
84
+ * Working-tree state is *not* immutable: the scope therefore only lives inside
85
+ * one operation and must never be reused across operations or persisted. Callers
86
+ * that re-observe a tree after mutation (code prepare) keep using the scope for
87
+ * identity probes while the working-tree diff is always re-read.
88
+ */
89
+ export declare function createGitObservationScope(options?: GitObservationScopeOptions): GitObservationScope;
package/dist/infra/git.js CHANGED
@@ -20,6 +20,7 @@ function sanitizedGitEnvironment() {
20
20
  'GIT_CEILING_DIRECTORIES',
21
21
  'GIT_CONFIG_COUNT',
22
22
  'GIT_CONFIG_PARAMETERS',
23
+ 'GIT_EXTERNAL_DIFF',
23
24
  ]) {
24
25
  delete environment[key];
25
26
  }
@@ -281,17 +282,22 @@ export async function inspectGitRepository(candidateRoot, options = {}) {
281
282
  limitations.push('branch unavailable');
282
283
  }
283
284
  let dirty = null;
284
- const statusResult = await run([
285
- 'status',
286
- '--porcelain=v1',
287
- '-z',
288
- '--untracked-files=normal',
289
- ]);
290
- if (statusResult.ok) {
291
- dirty = statusResult.value.stdout.length > 0;
285
+ if (options.workingTreeState === false) {
286
+ limitations.push('working tree state not requested');
292
287
  }
293
288
  else {
294
- limitations.push(`working tree state unavailable: ${statusResult.message}`);
289
+ const statusResult = await run([
290
+ 'status',
291
+ '--porcelain=v1',
292
+ '-z',
293
+ '--untracked-files=normal',
294
+ ]);
295
+ if (statusResult.ok) {
296
+ dirty = statusResult.value.stdout.length > 0;
297
+ }
298
+ else {
299
+ limitations.push(`working tree state unavailable: ${statusResult.message}`);
300
+ }
295
301
  }
296
302
  const kind = isBare
297
303
  ? 'bare'
@@ -356,3 +362,33 @@ export async function filterGitIgnored(repositoryRoot, candidates, options = {})
356
362
  }
357
363
  return succeeded(ignored);
358
364
  }
365
+ /**
366
+ * Memoizes Git repository probes for exactly one operation.
367
+ *
368
+ * Repository identity (root, git dir, HEAD, branch) is immutable for the
369
+ * duration of a single command, so repeated inspections of the same checkout
370
+ * reuse the first observation instead of spawning equivalent Git processes.
371
+ * Working-tree state is *not* immutable: the scope therefore only lives inside
372
+ * one operation and must never be reused across operations or persisted. Callers
373
+ * that re-observe a tree after mutation (code prepare) keep using the scope for
374
+ * identity probes while the working-tree diff is always re-read.
375
+ */
376
+ export function createGitObservationScope(options = {}) {
377
+ const defaultWorkingTreeState = options.workingTreeState ?? true;
378
+ const observations = new Map();
379
+ return {
380
+ repository(root, inspectOptions = {}) {
381
+ const workingTreeState = inspectOptions.workingTreeState ?? defaultWorkingTreeState;
382
+ const key = JSON.stringify([resolve(root), workingTreeState]);
383
+ const cached = observations.get(key);
384
+ if (cached !== undefined)
385
+ return cached;
386
+ const pending = inspectGitRepository(root, {
387
+ ...inspectOptions,
388
+ workingTreeState,
389
+ });
390
+ observations.set(key, pending);
391
+ return pending;
392
+ },
393
+ };
394
+ }
@@ -0,0 +1,2 @@
1
+ /** Replace one top-level JSON property while retaining unrelated bytes and style. */
2
+ export declare function updateJsonProperty(existing: Buffer | null, key: string, value: unknown): Buffer;