@phyzess/pappra 0.1.0-beta.13 → 0.1.0-beta.18

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 (357) hide show
  1. package/README.md +134 -15
  2. package/assets/integrations/skills/pappra/SKILL.md +28 -7
  3. package/assets/integrations/skills/pappra/references/collaboration.md +633 -0
  4. package/assets/integrations/skills/pappra/references/environment.md +360 -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.d.ts +221 -0
  62. package/dist/app/collab-session-transition.js +3334 -0
  63. package/dist/app/collab-state.d.ts +7 -0
  64. package/dist/app/collab-state.js +162 -0
  65. package/dist/app/collab-task-store.d.ts +22 -0
  66. package/dist/app/collab-task-store.js +204 -0
  67. package/dist/app/collab-work-execution.d.ts +127 -0
  68. package/dist/app/collab-work-execution.js +1027 -0
  69. package/dist/app/collab-work-plan.d.ts +87 -0
  70. package/dist/app/collab-work-plan.js +437 -0
  71. package/dist/app/collaboration.d.ts +8 -2
  72. package/dist/app/collaboration.js +101 -12
  73. package/dist/app/doctor.js +108 -5
  74. package/dist/app/host-mcp.js +34 -8
  75. package/dist/app/host-probe.js +4 -4
  76. package/dist/app/init.d.ts +58 -4
  77. package/dist/app/init.js +768 -155
  78. package/dist/app/managed-pi-bootstrap-admission.d.ts +14 -0
  79. package/dist/app/managed-pi-bootstrap-admission.js +104 -0
  80. package/dist/app/managed-pi-bootstrap-refresh.d.ts +10 -0
  81. package/dist/app/managed-pi-bootstrap-refresh.js +78 -0
  82. package/dist/app/managed-pi-delivery.d.ts +8 -0
  83. package/dist/app/managed-pi-delivery.js +110 -0
  84. package/dist/app/managed-pi-handoff-receiver.d.ts +15 -0
  85. package/dist/app/managed-pi-handoff-receiver.js +263 -0
  86. package/dist/app/managed-pi-handoff-reference.d.ts +3 -0
  87. package/dist/app/managed-pi-handoff-reference.js +60 -0
  88. package/dist/app/managed-pi-herdr.d.ts +21 -0
  89. package/dist/app/managed-pi-herdr.js +185 -0
  90. package/dist/app/managed-pi-initial-admission.d.ts +28 -0
  91. package/dist/app/managed-pi-initial-admission.js +416 -0
  92. package/dist/app/managed-pi-initial-launch.d.ts +5 -0
  93. package/dist/app/managed-pi-initial-launch.js +61 -0
  94. package/dist/app/managed-pi-native-observation.d.ts +36 -0
  95. package/dist/app/managed-pi-native-observation.js +191 -0
  96. package/dist/app/managed-pi-readiness.d.ts +29 -0
  97. package/dist/app/managed-pi-readiness.js +288 -0
  98. package/dist/app/managed-pi-repair-stop.d.ts +21 -0
  99. package/dist/app/managed-pi-repair-stop.js +371 -0
  100. package/dist/app/managed-pi-resume-admission.d.ts +32 -0
  101. package/dist/app/managed-pi-resume-admission.js +618 -0
  102. package/dist/app/managed-pi-retirement.d.ts +28 -0
  103. package/dist/app/managed-pi-retirement.js +112 -0
  104. package/dist/app/managed-pi-sdk-control.d.ts +7 -0
  105. package/dist/app/managed-pi-sdk-control.js +169 -0
  106. package/dist/app/managed-pi-sdk-runtime.d.ts +3 -0
  107. package/dist/app/managed-pi-sdk-runtime.js +483 -0
  108. package/dist/app/managed-pi-source-admission.d.ts +14 -0
  109. package/dist/app/managed-pi-source-admission.js +323 -0
  110. package/dist/app/managed-pi-transition-host.d.ts +36 -0
  111. package/dist/app/managed-pi-transition-host.js +292 -0
  112. package/dist/app/managed-pi.d.ts +54 -0
  113. package/dist/app/managed-pi.js +248 -0
  114. package/dist/app/shell-readiness.d.ts +66 -0
  115. package/dist/app/shell-readiness.js +368 -0
  116. package/dist/app/task-pin.d.ts +2 -23
  117. package/dist/app/task-pin.js +2 -113
  118. package/dist/cli/commands/collaboration-binding.d.ts +13 -0
  119. package/dist/cli/commands/collaboration-binding.js +118 -0
  120. package/dist/cli/commands/collaboration-bootstrap.d.ts +10 -0
  121. package/dist/cli/commands/collaboration-bootstrap.js +84 -0
  122. package/dist/cli/commands/collaboration-capabilities.d.ts +13 -0
  123. package/dist/cli/commands/collaboration-capabilities.js +127 -0
  124. package/dist/cli/commands/collaboration-handoff.d.ts +13 -0
  125. package/dist/cli/commands/collaboration-handoff.js +102 -0
  126. package/dist/cli/commands/collaboration-message.d.ts +17 -0
  127. package/dist/cli/commands/collaboration-message.js +177 -0
  128. package/dist/cli/commands/collaboration-plan.d.ts +8 -0
  129. package/dist/cli/commands/collaboration-plan.js +108 -0
  130. package/dist/cli/commands/collaboration-preflight.d.ts +10 -0
  131. package/dist/cli/commands/collaboration-preflight.js +167 -0
  132. package/dist/cli/commands/collaboration-recovery-run.d.ts +46 -0
  133. package/dist/cli/commands/collaboration-recovery-run.js +224 -0
  134. package/dist/cli/commands/collaboration-recovery.d.ts +11 -0
  135. package/dist/cli/commands/collaboration-recovery.js +104 -0
  136. package/dist/cli/commands/collaboration-resources.d.ts +11 -0
  137. package/dist/cli/commands/collaboration-resources.js +96 -0
  138. package/dist/cli/commands/collaboration-role-plan.d.ts +9 -0
  139. package/dist/cli/commands/collaboration-role-plan.js +69 -0
  140. package/dist/cli/commands/collaboration-role-run.d.ts +11 -0
  141. package/dist/cli/commands/collaboration-role-run.js +128 -0
  142. package/dist/cli/commands/collaboration-rollover.d.ts +10 -0
  143. package/dist/cli/commands/collaboration-rollover.js +103 -0
  144. package/dist/cli/commands/collaboration-state.d.ts +10 -0
  145. package/dist/cli/commands/collaboration-state.js +96 -0
  146. package/dist/cli/commands/collaboration-transition.d.ts +10 -0
  147. package/dist/cli/commands/collaboration-transition.js +75 -0
  148. package/dist/cli/commands/collaboration-work-run.d.ts +34 -0
  149. package/dist/cli/commands/collaboration-work-run.js +178 -0
  150. package/dist/cli/commands/collaboration.d.ts +4 -0
  151. package/dist/cli/commands/collaboration.js +39 -4
  152. package/dist/cli/commands/continuity.js +2 -6
  153. package/dist/cli/commands/docs.d.ts +2 -0
  154. package/dist/cli/commands/docs.js +89 -15
  155. package/dist/cli/commands/host.d.ts +7 -1
  156. package/dist/cli/commands/host.js +122 -7
  157. package/dist/cli/commands/init.d.ts +20 -3
  158. package/dist/cli/commands/init.js +897 -232
  159. package/dist/cli/commands/mcp.d.ts +1 -0
  160. package/dist/cli/commands/mcp.js +11 -5
  161. package/dist/cli/commands/repair.d.ts +12 -0
  162. package/dist/cli/commands/repair.js +41 -0
  163. package/dist/cli/commands/runtime.d.ts +1 -1
  164. package/dist/cli/commands/runtime.js +139 -38
  165. package/dist/cli/commands/session.d.ts +7 -0
  166. package/dist/cli/commands/session.js +82 -0
  167. package/dist/cli/commands/task.js +19 -5
  168. package/dist/cli/run.js +866 -24
  169. package/dist/code/identity.d.ts +7 -0
  170. package/dist/code/identity.js +7 -3
  171. package/dist/code/registration.js +7 -0
  172. package/dist/code/service.d.ts +9 -0
  173. package/dist/code/service.js +16 -3
  174. package/dist/code/text.js +19 -7
  175. package/dist/collab/admission.d.ts +91 -66
  176. package/dist/collab/admission.js +21 -6
  177. package/dist/collab/canonical.d.ts +1 -1
  178. package/dist/collab/canonical.js +44 -3
  179. package/dist/collab/envelope.d.ts +2 -2
  180. package/dist/collab/envelope.js +12 -12
  181. package/dist/collab/first-work.d.ts +3 -0
  182. package/dist/collab/first-work.js +15 -0
  183. package/dist/collab/handoff.d.ts +16 -0
  184. package/dist/collab/handoff.js +39 -5
  185. package/dist/collab/index.d.ts +97 -1
  186. package/dist/collab/index.js +9 -1
  187. package/dist/collab/messages.js +126 -3
  188. package/dist/collab/persisted-messages.d.ts +123 -0
  189. package/dist/collab/persisted-messages.js +496 -0
  190. package/dist/collab/preflight.d.ts +1 -1
  191. package/dist/collab/resources.d.ts +13 -3
  192. package/dist/collab/resources.js +37 -6
  193. package/dist/collab/rollover.d.ts +311 -0
  194. package/dist/collab/rollover.js +1024 -0
  195. package/dist/collab/store.d.ts +1 -0
  196. package/dist/collab/store.js +1 -4
  197. package/dist/collab/types.d.ts +2 -354
  198. package/dist/collab/validation.d.ts +2 -10
  199. package/dist/collab/validation.js +2 -303
  200. package/dist/collab/work-plan.d.ts +105 -0
  201. package/dist/collab/work-plan.js +843 -0
  202. package/dist/continuity/context.d.ts +11 -2
  203. package/dist/continuity/context.js +100 -13
  204. package/dist/continuity/handoff-bundle.d.ts +296 -0
  205. package/dist/continuity/handoff-bundle.js +477 -0
  206. package/dist/continuity/index.d.ts +2 -0
  207. package/dist/continuity/index.js +1 -0
  208. package/dist/continuity/paths.js +10 -2
  209. package/dist/continuity/service.js +91 -15
  210. package/dist/continuity/task-pin.d.ts +24 -0
  211. package/dist/continuity/task-pin.js +590 -0
  212. package/dist/doctor.d.ts +1 -0
  213. package/dist/doctor.js +6 -0
  214. package/dist/experimental/index.d.ts +13 -0
  215. package/dist/experimental/index.js +25 -0
  216. package/dist/experimental/pi.d.ts +4 -0
  217. package/dist/experimental/pi.js +12 -0
  218. package/dist/hosts/claude/native.js +1 -1
  219. package/dist/hosts/codex/native.js +1 -1
  220. package/dist/hosts/codex/protocol.js +1 -1
  221. package/dist/hosts/integration/bootstrap-config.d.ts +58 -0
  222. package/dist/hosts/integration/bootstrap-config.js +254 -0
  223. package/dist/hosts/integration/bundle-export.d.ts +44 -0
  224. package/dist/hosts/integration/bundle-export.js +366 -3
  225. package/dist/hosts/integration/bundle.js +3 -0
  226. package/dist/hosts/integration/hook.js +36 -9
  227. package/dist/hosts/integration/pappra-bootstrap-extension.mjs +80 -0
  228. package/dist/hosts/integration/pappra-extension-runtime.mjs +59 -24631
  229. package/dist/hosts/integration/pappra-hook.mjs +61 -24749
  230. package/dist/hosts/integration/pappra-recovery-extension.mjs +259 -0
  231. package/dist/hosts/integration/pappra-session-transition-extension.mjs +276 -0
  232. package/dist/hosts/integration/pi-bootstrap-extension.d.ts +36 -0
  233. package/dist/hosts/integration/pi-bootstrap-extension.js +101 -0
  234. package/dist/hosts/integration/pi-bootstrap-guard.d.ts +125 -0
  235. package/dist/hosts/integration/pi-bootstrap-guard.js +438 -0
  236. package/dist/hosts/integration/pi-bootstrap-runtime.d.ts +63 -0
  237. package/dist/hosts/integration/pi-bootstrap-runtime.js +223 -0
  238. package/dist/hosts/integration/pi-native-events.d.ts +112 -0
  239. package/dist/hosts/integration/pi-native-events.js +348 -0
  240. package/dist/hosts/integration/pi-rollover-extension.d.ts +166 -0
  241. package/dist/hosts/integration/pi-rollover-extension.js +431 -0
  242. package/dist/hosts/integration/recovery-config.d.ts +48 -0
  243. package/dist/hosts/integration/recovery-config.js +117 -0
  244. package/dist/hosts/integration/service.d.ts +6 -1
  245. package/dist/hosts/integration/service.js +485 -35
  246. package/dist/hosts/integration/support.d.ts +7 -0
  247. package/dist/hosts/integration/support.js +9 -1
  248. package/dist/hosts/integration/templates.d.ts +3 -0
  249. package/dist/hosts/integration/templates.js +26 -3
  250. package/dist/hosts/pi/managed-host-identity.d.ts +2 -0
  251. package/dist/hosts/pi/managed-host-identity.js +40 -0
  252. package/dist/hosts/pi/managed-provider-diagnostics.d.ts +6 -0
  253. package/dist/hosts/pi/managed-provider-diagnostics.js +184 -0
  254. package/dist/hosts/pi/managed-sdk-session.d.ts +335 -0
  255. package/dist/hosts/pi/managed-sdk-session.js +1639 -0
  256. package/dist/hosts/pi/managed-session-extension.d.ts +20 -0
  257. package/dist/hosts/pi/managed-session-extension.js +84 -0
  258. package/dist/hosts/pi/managed-session.d.ts +177 -0
  259. package/dist/hosts/pi/managed-session.js +1557 -0
  260. package/dist/hosts/pi/protocol.js +1 -1
  261. package/dist/hosts/pi/query-result.js +1 -1
  262. package/dist/hosts/pi/resume-capability.d.ts +41 -0
  263. package/dist/hosts/pi/resume-capability.js +33 -0
  264. package/dist/hosts/pi/rpc.d.ts +182 -134
  265. package/dist/hosts/pi/rpc.js +230 -37
  266. package/dist/hosts/pilot.d.ts +97 -74
  267. package/dist/hosts/pilot.js +5 -1
  268. package/dist/hosts/version.d.ts +3 -0
  269. package/dist/hosts/version.js +18 -0
  270. package/dist/index.d.ts +0 -1
  271. package/dist/index.js +0 -1
  272. package/dist/infra/bounded-file.d.ts +19 -0
  273. package/dist/infra/bounded-file.js +66 -0
  274. package/dist/infra/fs.js +10 -2
  275. package/dist/infra/git.d.ts +29 -0
  276. package/dist/infra/git.js +45 -9
  277. package/dist/infra/json-property.d.ts +2 -0
  278. package/dist/infra/json-property.js +69 -0
  279. package/dist/infra/json.d.ts +4 -0
  280. package/dist/infra/json.js +24 -0
  281. package/dist/infra/owned-process-group.js +1 -1
  282. package/dist/infra/private-lock.d.ts +16 -0
  283. package/dist/infra/private-lock.js +148 -0
  284. package/dist/infra/private-state.d.ts +7 -0
  285. package/dist/infra/private-state.js +146 -0
  286. package/dist/infra/process-identity.d.ts +12 -0
  287. package/dist/infra/process-identity.js +142 -0
  288. package/dist/infra/validation.d.ts +5 -0
  289. package/dist/infra/validation.js +15 -0
  290. package/dist/init.d.ts +1 -0
  291. package/dist/init.js +6 -0
  292. package/dist/install/apply.d.ts +9 -1
  293. package/dist/install/apply.js +176 -12
  294. package/dist/install/dependencies.d.ts +38 -0
  295. package/dist/install/dependencies.js +282 -0
  296. package/dist/install/ownership.js +30 -1
  297. package/dist/install/references.d.ts +31 -0
  298. package/dist/install/references.js +208 -0
  299. package/dist/install/repair.d.ts +37 -0
  300. package/dist/install/repair.js +798 -0
  301. package/dist/install/reset-local.d.ts +16 -0
  302. package/dist/install/reset-local.js +304 -0
  303. package/dist/install/rollback.d.ts +3 -0
  304. package/dist/install/rollback.js +9 -3
  305. package/dist/install/runtime.d.ts +10 -6
  306. package/dist/install/runtime.js +299 -59
  307. package/dist/install/source-fingerprint.d.ts +2 -0
  308. package/dist/install/source-fingerprint.js +103 -0
  309. package/dist/knowledge/catalog.d.ts +1 -0
  310. package/dist/knowledge/catalog.js +143 -10
  311. package/dist/knowledge/journal.js +17 -7
  312. package/dist/knowledge/paths.js +2 -1
  313. package/dist/knowledge/refs.js +4 -0
  314. package/dist/knowledge/register-batch.d.ts +4 -0
  315. package/dist/knowledge/register-batch.js +225 -0
  316. package/dist/knowledge/relocate.d.ts +5 -0
  317. package/dist/knowledge/relocate.js +92 -0
  318. package/dist/knowledge/scan.js +103 -47
  319. package/dist/knowledge/service.d.ts +3 -0
  320. package/dist/knowledge/service.js +33 -1
  321. package/dist/knowledge/write.d.ts +4 -1
  322. package/dist/knowledge/write.js +1 -1
  323. package/dist/mcp/server.d.ts +4 -2
  324. package/dist/mcp/server.js +87 -136
  325. package/dist/schemas/collaboration-state-validation.d.ts +6 -0
  326. package/dist/schemas/collaboration-state-validation.js +342 -0
  327. package/dist/schemas/collaboration-state.d.ts +436 -0
  328. package/dist/schemas/collaboration-state.js +1 -0
  329. package/dist/schemas/collaboration.d.ts +335 -0
  330. package/dist/schemas/collaboration.js +272 -0
  331. package/dist/schemas/continuity.d.ts +8 -0
  332. package/dist/schemas/continuity.js +13 -3
  333. package/dist/schemas/doctor.d.ts +1 -0
  334. package/dist/schemas/doctor.js +1 -0
  335. package/dist/schemas/document.d.ts +61 -0
  336. package/dist/schemas/document.js +9 -0
  337. package/dist/schemas/errors.d.ts +1 -0
  338. package/dist/schemas/errors.js +1 -0
  339. package/dist/schemas/host.d.ts +24 -0
  340. package/dist/schemas/host.js +19 -0
  341. package/dist/schemas/install.d.ts +8 -2
  342. package/dist/schemas/install.js +11 -1
  343. package/dist/schemas/managed-pi-execution.d.ts +16 -0
  344. package/dist/schemas/managed-pi-execution.js +2 -0
  345. package/dist/schemas/outcome.d.ts +9 -5
  346. package/dist/workspace/config-file.js +1 -3
  347. package/dist/workspace/documents.js +12 -2
  348. package/dist/workspace/repositories.d.ts +7 -0
  349. package/dist/workspace/repositories.js +14 -5
  350. package/package.json +35 -35
  351. package/skills/pappra/SKILL.md +28 -7
  352. package/skills/pappra/references/collaboration.md +633 -0
  353. package/skills/pappra/references/environment.md +360 -0
  354. package/skills/pappra/references/hosts.md +20 -0
  355. package/skills/pappra/references/operations.md +36 -5
  356. package/dist/app/collab-from.d.ts +0 -35
  357. package/dist/app/collab-from.js +0 -84
@@ -0,0 +1,84 @@
1
+ import path from 'node:path';
2
+ import { applyVisibleBootstrap, loadVisibleBootstrapRequest, planVisibleBootstrap, } from '../../app/collab-bootstrap.js';
3
+ export const collaborationBootstrapUsage = 'pappra collab bootstrap <plan|apply> --task-root <abs> --request <abs request.json> [--json]\n\n' +
4
+ 'Plan is read-only. Apply performs one durable, visible Pi sibling launch or an\n' +
5
+ 'explicitly verified task-bound reuse. Readiness is not authorization, and a\n' +
6
+ 'submitted message is not receiver acceptance. Unknown outcomes are reconciled,\n' +
7
+ 'never retried automatically.';
8
+ function emitHuman(report, output) {
9
+ output.stdout(`Bootstrap ${report.action}: ${report.status}${report.code === null ? '' : ` (${report.code})`}.\n`);
10
+ if (report.message !== null)
11
+ output.stdout(` ${report.message}\n`);
12
+ if (report.request_id !== null)
13
+ output.stdout(` request: ${report.request_id}\n`);
14
+ if (report.task_id !== null)
15
+ output.stdout(` task: ${report.task_id}\n`);
16
+ if (report.target !== null && typeof report.target['choice'] === 'string')
17
+ output.stdout(` target: ${report.target['choice']}${typeof report.target['pane_id'] === 'string' ? ` ${report.target['pane_id']}` : ''}\n`);
18
+ if (report.next_action !== null)
19
+ output.stdout(` next: ${report.next_action}\n`);
20
+ if (report.effects.length > 0) {
21
+ output.stdout(' effects:\n');
22
+ for (const effect of report.effects)
23
+ output.stdout(` ${effect.step}: ${effect.status}${effect.detail === null ? '' : ` — ${effect.detail}`}\n`);
24
+ }
25
+ if (report.limits.length > 0)
26
+ output.stdout(` limits: ${report.limits.join(', ')}\n`);
27
+ }
28
+ function exitCode(report) {
29
+ if (report.status === 'planned' ||
30
+ report.status === 'applied' ||
31
+ report.status === 'already_recorded')
32
+ return 0;
33
+ if (report.status === 'invalid')
34
+ return 2;
35
+ return 1;
36
+ }
37
+ export async function runCollaborationBootstrapCommand(options, output, dependencies = {}) {
38
+ if (options.action === null) {
39
+ output.stderr(`pappra collab bootstrap requires plan or apply.\n${collaborationBootstrapUsage}\n`);
40
+ return 2;
41
+ }
42
+ if (options.taskRoot === null || options.requestFile === null) {
43
+ const message = 'collab bootstrap requires --task-root <absolute> and --request <absolute request.json>.';
44
+ if (options.json)
45
+ output.stdout(`${JSON.stringify({ ok: false, status: 'invalid', code: 'required_option_missing', message })}\n`);
46
+ else
47
+ output.stderr(`${message}\n${collaborationBootstrapUsage}\n`);
48
+ return 2;
49
+ }
50
+ if (!path.isAbsolute(options.taskRoot) ||
51
+ !path.isAbsolute(options.requestFile)) {
52
+ const message = '--task-root and --request must be absolute paths.';
53
+ if (options.json)
54
+ output.stdout(`${JSON.stringify({ ok: false, status: 'invalid', code: 'absolute_path_required', message })}\n`);
55
+ else
56
+ output.stderr(`${message}\n`);
57
+ return 2;
58
+ }
59
+ const loaded = loadVisibleBootstrapRequest(options.requestFile);
60
+ if (!loaded.ok) {
61
+ if (options.json)
62
+ output.stdout(`${JSON.stringify({ ok: false, status: 'invalid', code: loaded.code, message: loaded.message })}\n`);
63
+ else
64
+ output.stderr(`${loaded.code}: ${loaded.message}\n`);
65
+ return 2;
66
+ }
67
+ if (path.resolve(options.taskRoot) !==
68
+ path.resolve(loaded.value.request.task_root)) {
69
+ const message = '--task-root does not match request.task_root.';
70
+ if (options.json)
71
+ output.stdout(`${JSON.stringify({ ok: false, status: 'invalid', code: 'task_root_mismatch', message })}\n`);
72
+ else
73
+ output.stderr(`${message}\n`);
74
+ return 2;
75
+ }
76
+ const report = options.action === 'plan'
77
+ ? await planVisibleBootstrap(loaded.value, dependencies)
78
+ : await applyVisibleBootstrap(loaded.value, dependencies);
79
+ if (options.json)
80
+ output.stdout(`${JSON.stringify(report)}\n`);
81
+ else
82
+ emitHuman(report, output);
83
+ return exitCode(report);
84
+ }
@@ -0,0 +1,13 @@
1
+ import type { CliOutput } from '../output.js';
2
+ export declare const collaborationCapabilitiesUsage: string;
3
+ export interface CollaborationCapabilitiesOptions {
4
+ readonly harness: string | null;
5
+ readonly assignmentFile: string | null;
6
+ readonly templateFile: string | null;
7
+ readonly executionFile: string | null;
8
+ readonly sessionFile: string | null;
9
+ readonly eventsFile: string | null;
10
+ readonly json: boolean;
11
+ readonly live?: boolean;
12
+ }
13
+ export declare function runCollaborationCapabilitiesCommand(options: CollaborationCapabilitiesOptions, output: CliOutput): number;
@@ -0,0 +1,127 @@
1
+ import path from 'node:path';
2
+ import { CAPABILITIES_SCHEMA, CAPABILITY_LIMITS, deriveCapabilityCard, } from '../../app/capability-evidence/index.js';
3
+ export const collaborationCapabilitiesUsage = 'pappra collab capabilities derive --harness <pi|codex|claude> --assignment <abs assignment.json> --template <abs card.declared.json> [--execution <abs execution.json> | --live] [--session <abs pi-session.jsonl> | --events <abs events.jsonl>] [--json]\n\n' +
4
+ 'Read-only native capability evidence: Pi requires --session, Codex and Claude\n' +
5
+ 'require --events. Pi --live derives a settled saved-session snapshot without\n' +
6
+ 'an execution receipt; it does not prove live ownership, queue or approvals.\n' +
7
+ 'A derived card is a claim derived from the supplied evidence;\n' +
8
+ 'nothing is written, launched, authenticated or dispatched. Exit 0 derived,\n' +
9
+ '1 needs_input, 2 invalid.';
10
+ function invalid(harness, errors) {
11
+ return {
12
+ schema: CAPABILITIES_SCHEMA,
13
+ ok: false,
14
+ status: 'invalid',
15
+ harness,
16
+ errors,
17
+ limits: CAPABILITY_LIMITS,
18
+ };
19
+ }
20
+ function emitInvalid(output, options, result) {
21
+ if (options.json)
22
+ output.stdout(`${JSON.stringify(result)}\n`);
23
+ else {
24
+ output.stdout(`Capabilities invalid.\n`);
25
+ for (const error of result.errors ?? [])
26
+ output.stdout(` - ${error}\n`);
27
+ }
28
+ return 2;
29
+ }
30
+ function emitHuman(result, output) {
31
+ if (result.status === 'derived') {
32
+ const card = result.card;
33
+ const tools = card.tools.map((tool) => `${tool.id}:${tool.state}`);
34
+ const skills = card.skills.map((skill) => `${skill.id}:${skill.state}`);
35
+ output.stdout(`Capabilities derived (${result.harness}) at ${card.observed_at}.\n`);
36
+ output.stdout(` tools: ${tools.length ? tools.join(', ') : 'none'}\n`);
37
+ output.stdout(` skills: ${skills.length ? skills.join(', ') : 'none'}\n`);
38
+ output.stdout(` evidence: ${String(card.evidence_records?.length ?? 0)} record(s)\n`);
39
+ if (result.limitations?.length) {
40
+ output.stdout(` limitations: ${result.limitations.join(', ')}\n`);
41
+ }
42
+ }
43
+ else if (result.status === 'needs_input') {
44
+ output.stdout(`Capabilities need input: ${(result.blockers ?? []).join(', ') || 'none'}.\n`);
45
+ }
46
+ else {
47
+ output.stdout(`Capabilities invalid.\n`);
48
+ for (const error of result.errors ?? [])
49
+ output.stdout(` - ${error}\n`);
50
+ for (const blocker of result.blockers ?? [])
51
+ output.stdout(` - ${blocker}\n`);
52
+ }
53
+ output.stdout(` limits: ${result.limits.join(', ')}\n`);
54
+ }
55
+ export function runCollaborationCapabilitiesCommand(options, output) {
56
+ const harness = options.harness === 'pi' ||
57
+ options.harness === 'codex' ||
58
+ options.harness === 'claude'
59
+ ? options.harness
60
+ : null;
61
+ if (harness === null) {
62
+ return emitInvalid(output, options, invalid('unknown', ['--harness must be pi, codex or claude.']));
63
+ }
64
+ const missing = [
65
+ ['--assignment', options.assignmentFile],
66
+ ['--template', options.templateFile],
67
+ ...(!options.live ? [['--execution', options.executionFile]] : []),
68
+ ]
69
+ .filter(([, value]) => value === null)
70
+ .map(([flag]) => flag);
71
+ if (missing.length) {
72
+ return emitInvalid(output, options, invalid(harness, [`missing required option(s): ${missing.join(', ')}.`]));
73
+ }
74
+ if (options.live && (harness !== 'pi' || options.executionFile !== null)) {
75
+ return emitInvalid(output, options, invalid(harness, ['--live requires Pi and excludes --execution.']));
76
+ }
77
+ if (harness === 'pi') {
78
+ if (options.sessionFile === null) {
79
+ return emitInvalid(output, options, invalid(harness, ['--session is required for pi.']));
80
+ }
81
+ if (options.eventsFile !== null) {
82
+ return emitInvalid(output, options, invalid(harness, ['--events is only valid for codex or claude.']));
83
+ }
84
+ }
85
+ else {
86
+ if (options.eventsFile === null) {
87
+ return emitInvalid(output, options, invalid(harness, [`--events is required for ${harness}.`]));
88
+ }
89
+ if (options.sessionFile !== null) {
90
+ return emitInvalid(output, options, invalid(harness, ['--session is only valid for pi.']));
91
+ }
92
+ }
93
+ const files = [
94
+ ['--assignment', options.assignmentFile],
95
+ ['--template', options.templateFile],
96
+ ['--execution', options.executionFile],
97
+ ['--session', options.sessionFile],
98
+ ['--events', options.eventsFile],
99
+ ];
100
+ const nonAbsolute = files
101
+ .filter(([, value]) => value !== null && !path.isAbsolute(value))
102
+ .map(([flag]) => flag);
103
+ if (nonAbsolute.length) {
104
+ return emitInvalid(output, options, invalid(harness, [
105
+ `option(s) must be absolute: ${nonAbsolute.join(', ')}.`,
106
+ ]));
107
+ }
108
+ const deriveOptions = {
109
+ harness,
110
+ assignmentFile: options.assignmentFile,
111
+ templateFile: options.templateFile,
112
+ executionFile: options.executionFile,
113
+ sessionFile: options.sessionFile,
114
+ eventsFile: options.eventsFile,
115
+ live: options.live ?? false,
116
+ };
117
+ const result = deriveCapabilityCard(deriveOptions);
118
+ if (options.json) {
119
+ output.stdout(`${JSON.stringify(result)}\n`);
120
+ }
121
+ else {
122
+ emitHuman(result, output);
123
+ }
124
+ if (result.status === 'derived')
125
+ return 0;
126
+ return result.status === 'needs_input' ? 1 : 2;
127
+ }
@@ -0,0 +1,13 @@
1
+ import { type HandoffAction } from '../../app/collab-handoff.js';
2
+ import type { CliOutput } from '../output.js';
3
+ export declare const collaborationHandoffUsage: string;
4
+ export interface CollaborationHandoffOptions {
5
+ readonly action: HandoffAction | 'inventory' | null;
6
+ readonly taskRoot: string | null;
7
+ readonly requestFile: string | null;
8
+ readonly subtaskId: string | null;
9
+ readonly attempt: string | null;
10
+ readonly apply: boolean;
11
+ readonly json: boolean;
12
+ }
13
+ export declare function runCollaborationHandoffCommand(options: CollaborationHandoffOptions, output: CliOutput): Promise<number>;
@@ -0,0 +1,102 @@
1
+ import path from 'node:path';
2
+ import { COLLAB_HANDOFF_SCHEMA, applyHandoffRequest, loadHandoffRequest, planHandoffRequest, readHandoffInventory, } from '../../app/collab-handoff.js';
3
+ export const collaborationHandoffUsage = 'pappra collab handoff inventory --task-root <abs> [--subtask-id <id>] [--attempt <positive integer>] [--json]\n' +
4
+ 'pappra collab handoff <begin|stopped|rebind|transfer|confirm|complete|abort|release-dispatch> --task-root <abs> --request <abs request.json> [--apply] [--json]\n\n' +
5
+ 'Recorded ownership handoff over the existing store/lifecycle primitives. Plan is\n' +
6
+ 'namespace/request validation only; --apply performs a cooperative record\n' +
7
+ 'mutation and never stops, launches, adopts or resumes an execution. Confirmation\n' +
8
+ 'requires an accepted/recorded, explicitly correlated receiver message.';
9
+ function invalid(output, options, errors) {
10
+ if (options.json) {
11
+ output.stdout(`${JSON.stringify({
12
+ schema: COLLAB_HANDOFF_SCHEMA,
13
+ ok: false,
14
+ status: 'invalid',
15
+ action: options.action,
16
+ errors,
17
+ })}\n`);
18
+ }
19
+ else {
20
+ output.stdout(`Handoff request invalid.\n`);
21
+ for (const error of errors)
22
+ output.stdout(` - ${error}\n`);
23
+ }
24
+ return 2;
25
+ }
26
+ function failure(output, options, value, exitCode) {
27
+ if (options.json) {
28
+ output.stdout(`${JSON.stringify({
29
+ schema: COLLAB_HANDOFF_SCHEMA,
30
+ ok: false,
31
+ status: exitCode === 2 ? 'invalid' : 'needs_input',
32
+ action: options.action,
33
+ code: value.code,
34
+ message: value.message,
35
+ nextAction: value.nextAction,
36
+ })}\n`);
37
+ }
38
+ else {
39
+ output.stdout(`Handoff needs input: ${value.message}\n`);
40
+ if (value.nextAction)
41
+ output.stdout(` ${value.nextAction}\n`);
42
+ }
43
+ return exitCode;
44
+ }
45
+ function emitInventory(value, output) {
46
+ const counts = value.counts;
47
+ output.stdout(`Handoff inventory: ${String(counts.handoffs)} handoff(s), ${String(counts.inflight)} inflight, ${String(counts.uncertainty)} uncertainty.\n`);
48
+ if (value.truncated === true)
49
+ output.stdout(' Some inventory rows are omitted (bounded summary).\n');
50
+ }
51
+ function emitHuman(value, action, output) {
52
+ if (value.applied === false) {
53
+ output.stdout(`Handoff ${action} plan validated; nothing was persisted.\n`);
54
+ }
55
+ else {
56
+ output.stdout(`Handoff ${action} ${value.ok === true ? 'applied' : 'refused'}: ${String(value.reason ?? 'completed')}.\n`);
57
+ }
58
+ }
59
+ export async function runCollaborationHandoffCommand(options, output) {
60
+ if (options.action === null)
61
+ return invalid(output, options, ['handoff requires an action.']);
62
+ if (options.taskRoot === null)
63
+ return invalid(output, options, ['--task-root is required.']);
64
+ if (!path.isAbsolute(options.taskRoot))
65
+ return invalid(output, options, ['--task-root must be absolute.']);
66
+ if (options.action === 'inventory') {
67
+ let attempt = null;
68
+ if (options.attempt !== null) {
69
+ const parsed = Number(options.attempt.trim());
70
+ if (!Number.isSafeInteger(parsed) || parsed <= 0)
71
+ return invalid(output, options, [
72
+ '--attempt must be a positive integer.',
73
+ ]);
74
+ attempt = parsed;
75
+ }
76
+ const result = await readHandoffInventory(options.taskRoot, options.subtaskId, attempt);
77
+ if (!result.ok)
78
+ return failure(output, options, result, 1);
79
+ if (options.json)
80
+ output.stdout(`${JSON.stringify(result.value)}\n`);
81
+ else
82
+ emitInventory(result.value, output);
83
+ return 0;
84
+ }
85
+ if (options.requestFile === null)
86
+ return invalid(output, options, [`${options.action} requires --request.`]);
87
+ if (!path.isAbsolute(options.requestFile))
88
+ return invalid(output, options, ['--request must be absolute.']);
89
+ const loaded = loadHandoffRequest(options.requestFile, options.action);
90
+ if (!loaded.ok)
91
+ return failure(output, options, loaded, 2);
92
+ const result = options.apply
93
+ ? await applyHandoffRequest(options.taskRoot, loaded.value.request)
94
+ : await planHandoffRequest(options.taskRoot, loaded.value.request);
95
+ if (!result.ok)
96
+ return failure(output, options, result, 1);
97
+ if (options.json)
98
+ output.stdout(`${JSON.stringify(result.value)}\n`);
99
+ else
100
+ emitHuman(result.value, options.action, output);
101
+ return result.value.ok === true ? 0 : 1;
102
+ }
@@ -0,0 +1,17 @@
1
+ import type { CliOutput } from '../output.js';
2
+ export declare const collaborationMessageUsage: string;
3
+ export type CollaborationMessageAction = 'send' | 'list' | 'read' | 'notify';
4
+ export interface CollaborationMessageOptions {
5
+ readonly cwd: string;
6
+ readonly action: CollaborationMessageAction | null;
7
+ readonly taskRoot: string | null;
8
+ readonly messageFile: string | null;
9
+ readonly messageId: string | null;
10
+ readonly bindingFile: string | null;
11
+ readonly apply: boolean;
12
+ readonly retry: boolean;
13
+ readonly limit: string | null;
14
+ readonly callerPane: string | null;
15
+ readonly json: boolean;
16
+ }
17
+ export declare function runCollaborationMessageCommand(options: CollaborationMessageOptions, output: CliOutput): Promise<number>;
@@ -0,0 +1,177 @@
1
+ import { listMessagesForTaskRoot, readMessageFromTaskRoot, sendMessageFromFile, } from '../../app/collab-messages.js';
2
+ import { notifyRegisteredMessage } from '../../app/collab-notify.js';
3
+ export const collaborationMessageUsage = 'pappra collab message <send|list|read|notify> --task-root <dir> [options]\n' +
4
+ ' send --message <abs envelope.json> [--apply]\n' +
5
+ ' list [--limit <1-100>]\n' +
6
+ ' read --message-id <id>\n' +
7
+ ' notify --message-id <id> --binding <abs binding.json> [--caller-pane <id>] [--apply] [--retry]\n\n' +
8
+ 'send plans by default and persists only with --apply; it never notifies.\n' +
9
+ 'notify forwards one registered pointer through the Herdr CLI without --wait and\n' +
10
+ 'requires a task-local binding that matches the recipient and live agent metadata.';
11
+ const CALLER_PANE_PATTERN = /^[A-Za-z0-9]+:p[A-Za-z0-9]+$/;
12
+ const SUCCESS_STATUSES = new Set([
13
+ 'planned',
14
+ 'accepted',
15
+ 'duplicate',
16
+ 'submitted',
17
+ 'already_recorded',
18
+ ]);
19
+ function emit(output, json, payload, lines, exitCode) {
20
+ if (json) {
21
+ output.stdout(`${JSON.stringify(payload)}\n`);
22
+ }
23
+ else {
24
+ for (const line of lines)
25
+ output.stdout(`${line}\n`);
26
+ }
27
+ return exitCode;
28
+ }
29
+ function usageFailure(output, options, code, message) {
30
+ return emit(output, options.json, { schema: 'pappra/collaboration-message/1', ok: false, code, message }, [`pappra collab message: ${message}`], 2);
31
+ }
32
+ function serviceFailure(output, options, failure) {
33
+ if (options.json) {
34
+ output.stdout(`${JSON.stringify({
35
+ schema: 'pappra/collaboration-message/1',
36
+ ok: false,
37
+ action: options.action,
38
+ code: failure.code,
39
+ message: failure.message,
40
+ nextAction: failure.nextAction,
41
+ })}\n`);
42
+ }
43
+ else {
44
+ output.stderr(`pappra collab message: ${failure.message}\n`);
45
+ if (failure.nextAction !== null) {
46
+ output.stderr(` next: ${failure.nextAction}\n`);
47
+ }
48
+ }
49
+ return 1;
50
+ }
51
+ export async function runCollaborationMessageCommand(options, output) {
52
+ if (options.action === null) {
53
+ return usageFailure(output, options, 'action_required', 'collab message requires send, list, read, or notify.');
54
+ }
55
+ const taskRoot = options.taskRoot;
56
+ if (taskRoot === null) {
57
+ return usageFailure(output, options, 'task_root_required', 'collab message requires an absolute --task-root.');
58
+ }
59
+ if (options.action === 'send') {
60
+ if (options.messageFile === null) {
61
+ return usageFailure(output, options, 'message_required', 'collab message send requires --message <abs envelope.json>.');
62
+ }
63
+ const result = await sendMessageFromFile(taskRoot, options.messageFile, {
64
+ apply: options.apply,
65
+ });
66
+ if (!result.ok)
67
+ return serviceFailure(output, options, result);
68
+ const value = result.value;
69
+ const payload = {
70
+ schema: 'pappra/collaboration-message/1',
71
+ ok: value.status !== 'conflict' && value.status !== 'rejected',
72
+ action: 'send',
73
+ applied: options.apply,
74
+ status: value.status,
75
+ message: value.message,
76
+ registrationStatus: value.registrationStatus,
77
+ stateRevision: value.stateRevision,
78
+ messagePath: value.messagePath,
79
+ digest: value.digest,
80
+ detail: value.detail,
81
+ delivery: value.delivery,
82
+ notified: value.notified,
83
+ taskAccepted: value.taskAccepted,
84
+ };
85
+ const ok = payload.ok;
86
+ return emit(output, options.json, payload, ok
87
+ ? [
88
+ `Message ${value.message.message_id} ${value.status}; delivery ${value.delivery}.`,
89
+ ...(value.messagePath === null
90
+ ? []
91
+ : [` file: ${value.messagePath}`]),
92
+ ...(value.digest === null ? [] : [` digest: ${value.digest}`]),
93
+ ]
94
+ : [
95
+ `Message ${value.message.message_id} ${value.status}: ${String(value.detail)}`,
96
+ ], ok ? 0 : 1);
97
+ }
98
+ if (options.action === 'list') {
99
+ const parsedLimit = (() => {
100
+ if (options.limit === null)
101
+ return 20;
102
+ const value = Number(options.limit);
103
+ return Number.isSafeInteger(value) ? value : Number.NaN;
104
+ })();
105
+ if (Number.isNaN(parsedLimit)) {
106
+ return usageFailure(output, options, 'limit_invalid', '--limit must be a positive integer.');
107
+ }
108
+ const result = await listMessagesForTaskRoot(taskRoot, {
109
+ limit: parsedLimit,
110
+ });
111
+ if (!result.ok)
112
+ return serviceFailure(output, options, result);
113
+ const value = result.value;
114
+ return emit(output, options.json, {
115
+ schema: 'pappra/collaboration-message/1',
116
+ ok: true,
117
+ action: 'list',
118
+ ...value,
119
+ }, [
120
+ `Messages ${value.returned}/${value.total}${value.truncated ? ' (truncated)' : ''}`,
121
+ ...value.messages.map((entry) => ` ${entry.message_id} ${entry.type} ${entry.state}${entry.reply_to === null ? '' : ` reply_to=${entry.reply_to}`}${entry.delivery === null ? '' : ` notification=${entry.delivery.status}`}`),
122
+ ], 0);
123
+ }
124
+ if (options.action === 'read') {
125
+ if (options.messageId === null) {
126
+ return usageFailure(output, options, 'message_id_required', 'collab message read requires --message-id.');
127
+ }
128
+ const result = await readMessageFromTaskRoot(taskRoot, options.messageId);
129
+ if (!result.ok)
130
+ return serviceFailure(output, options, result);
131
+ const value = result.value;
132
+ return emit(output, options.json, {
133
+ schema: 'pappra/collaboration-message/1',
134
+ ok: true,
135
+ action: 'read',
136
+ ...value,
137
+ }, [
138
+ `${value.message.message_id} ${value.message.type} ${value.entry?.state ?? 'not-applied'}`,
139
+ ` file: ${value.messagePath}`,
140
+ ` digest: ${value.digest}`,
141
+ ` notification: ${value.delivery?.status ?? 'not-notified'}`,
142
+ ], 0);
143
+ }
144
+ if (options.callerPane !== null &&
145
+ !CALLER_PANE_PATTERN.test(options.callerPane)) {
146
+ return usageFailure(output, options, 'caller_pane_invalid', '--caller-pane must be a Herdr pane id such as w3:p1.');
147
+ }
148
+ if (options.bindingFile === null || options.messageId === null) {
149
+ return usageFailure(output, options, 'notify_arguments_required', 'collab message notify requires --message-id and --binding.');
150
+ }
151
+ const result = await notifyRegisteredMessage({
152
+ taskRoot,
153
+ messageId: options.messageId,
154
+ bindingFile: options.bindingFile,
155
+ apply: options.apply,
156
+ retry: options.retry,
157
+ callerPane: options.callerPane,
158
+ });
159
+ if (!result.ok)
160
+ return serviceFailure(output, options, result);
161
+ const value = result.value;
162
+ const ok = SUCCESS_STATUSES.has(value.status);
163
+ return emit(output, options.json, {
164
+ schema: 'pappra/collaboration-message/1',
165
+ ok,
166
+ action: 'notify',
167
+ applied: options.apply,
168
+ ...value,
169
+ }, ok
170
+ ? [
171
+ `Notification ${value.status}; consumed=false, taskAccepted=false.`,
172
+ ...(value.deliveryPath === null
173
+ ? []
174
+ : [` delivery: ${value.deliveryPath}`]),
175
+ ]
176
+ : [`Notification ${value.status}: ${String(value.detail)}`], ok ? 0 : 1);
177
+ }
@@ -0,0 +1,8 @@
1
+ import type { CliOutput } from '../output.js';
2
+ export declare const collaborationPlanUsage: string;
3
+ export interface CollaborationPlanOptions {
4
+ readonly taskRoot: string | null;
5
+ readonly planFile: string | null;
6
+ readonly json: boolean;
7
+ }
8
+ export declare function runCollaborationPlanCommand(options: CollaborationPlanOptions, output: CliOutput): Promise<number>;
@@ -0,0 +1,108 @@
1
+ import path from 'node:path';
2
+ import { COLLAB_WORK_PLAN_REPORT_SCHEMA, inspectWorkPlan, } from '../../app/collab-work-plan.js';
3
+ export const collaborationPlanUsage = 'pappra collab plan --task-root <abs> --config <abs plan.json> [--json]\n\n' +
4
+ 'Read-only role and dependency evaluation of one persisted work-plan document\n' +
5
+ 'against the authoritative task record. Nothing is claimed, dispatched, launched,\n' +
6
+ 'refreshed or written, and no prompt, network call or model call is made.\n\n' +
7
+ 'Plan nodes correlate to the existing task protocol by\n' +
8
+ 'node.assignment_id == attempt.subtask_id; there is no second assignment registry.\n' +
9
+ 'A ready node is not authorization to run it.\n\n' +
10
+ 'Exit 0 evaluated snapshot (normal waiting and blocked nodes included),\n' +
11
+ '1 incomplete or unavailable authoritative evidence, 2 invalid request/plan.';
12
+ function invalid(output, options, errors) {
13
+ if (options.json) {
14
+ output.stdout(`${JSON.stringify({
15
+ schema: COLLAB_WORK_PLAN_REPORT_SCHEMA,
16
+ ok: false,
17
+ status: 'invalid',
18
+ task_root: options.taskRoot,
19
+ task_id: null,
20
+ plan: {
21
+ ref: options.planFile,
22
+ digest: null,
23
+ plan_id: null,
24
+ owner_epoch: null,
25
+ node_count: null,
26
+ },
27
+ stale: false,
28
+ summary: null,
29
+ nodes: [],
30
+ core: null,
31
+ evidence: {
32
+ registered_decisions: 0,
33
+ supplied: 0,
34
+ envelope_bytes: 0,
35
+ unreadable: [],
36
+ truncated: false,
37
+ },
38
+ diagnostics: errors.map((error) => ({
39
+ code: 'invalid_arguments',
40
+ detail: error,
41
+ next_action: collaborationPlanUsage,
42
+ })),
43
+ identity_mapping: 'plan.nodes[].assignment_id corresponds to the existing task subtask identity (record.attempts[].subtask_id); no separate assignment registry exists.',
44
+ limits: ['persisted_snapshot_only', 'not_an_authorization'],
45
+ })}\n`);
46
+ }
47
+ else {
48
+ output.stdout('Plan request invalid.\n');
49
+ for (const error of errors)
50
+ output.stdout(` - ${error}\n`);
51
+ output.stdout(`\n${collaborationPlanUsage}\n`);
52
+ }
53
+ return 2;
54
+ }
55
+ function emitHuman(report, output) {
56
+ const planLabel = report.plan.plan_id ?? '<unparsed plan>';
57
+ const taskLabel = report.task_id ?? '<unknown task>';
58
+ output.stdout(`Plan ${planLabel} on task ${taskLabel}: ${report.status}.\n`);
59
+ if (report.status === 'invalid') {
60
+ for (const entry of report.diagnostics)
61
+ output.stdout(` invalid: ${entry.code}: ${entry.detail}\n`);
62
+ return;
63
+ }
64
+ if (report.status === 'incomplete') {
65
+ for (const entry of report.diagnostics)
66
+ output.stdout(` incomplete: ${entry.code}: ${entry.detail}\n`);
67
+ }
68
+ if (report.stale) {
69
+ output.stdout(' note: the plan owner epoch is not the current epoch; every node is stale until it is rebuilt.\n');
70
+ }
71
+ const summary = report.summary;
72
+ if (summary !== null) {
73
+ output.stdout(` ready ${summary.ready}, running ${summary.running}, awaiting acceptance ${summary.awaiting_acceptance}, accepted ${summary.accepted}, blocked ${summary.blocked}\n`);
74
+ }
75
+ for (const node of report.nodes) {
76
+ output.stdout(` ${node.role} ${node.node_id} (assignment ${node.assignment_id}#${node.attempt}): ${node.status}\n`);
77
+ for (const blocker of node.blockers)
78
+ output.stdout(` blocked by ${blocker.code}: ${blocker.detail}\n`);
79
+ if (node.next_action !== null)
80
+ output.stdout(` next: ${node.next_action}\n`);
81
+ }
82
+ output.stdout(` evidence: ${report.evidence.supplied}/${report.evidence.registered_decisions} relevant decision envelope(s) read from ${report.evidence.relevant_reports} planned report(s), ${report.evidence.raw_bytes} raw bytes\n`);
83
+ output.stdout(' read-only: this evaluation is a persisted snapshot and grants no authority to run anything.\n');
84
+ }
85
+ export async function runCollaborationPlanCommand(options, output) {
86
+ const errors = [];
87
+ if (options.taskRoot === null)
88
+ errors.push('--task-root is required.');
89
+ else if (!path.isAbsolute(options.taskRoot))
90
+ errors.push('--task-root must be absolute.');
91
+ if (options.planFile === null)
92
+ errors.push('--config is required.');
93
+ else if (!path.isAbsolute(options.planFile))
94
+ errors.push('--config must be an absolute path to the plan document.');
95
+ if (errors.length > 0)
96
+ return invalid(output, options, errors);
97
+ const report = await inspectWorkPlan({
98
+ taskRoot: options.taskRoot,
99
+ planFile: options.planFile,
100
+ });
101
+ if (options.json)
102
+ output.stdout(`${JSON.stringify(report)}\n`);
103
+ else
104
+ emitHuman(report, output);
105
+ if (report.status === 'evaluated')
106
+ return 0;
107
+ return report.status === 'invalid' ? 2 : 1;
108
+ }
@@ -0,0 +1,10 @@
1
+ import type { CliOutput } from '../output.js';
2
+ export declare const collaborationPreflightUsage: string;
3
+ export interface CollaborationPreflightOptions {
4
+ readonly cwd: string;
5
+ readonly assignmentFile: string | null;
6
+ readonly capabilitiesFile: string | null;
7
+ readonly maxAgeMinutes: string | null;
8
+ readonly json: boolean;
9
+ }
10
+ export declare function runCollaborationPreflightCommand(options: CollaborationPreflightOptions, output: CliOutput): number;