@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
package/dist/cli/run.js CHANGED
@@ -8,275 +8,111 @@ import { doctorUsage, runDoctorCommand } from './commands/doctor.js';
8
8
  import { docsUsage, runDocsCommand } from './commands/docs.js';
9
9
  import { checkpointUsage, resumeUsage, runCheckpointCommand, runResumeCommand, } from './commands/continuity.js';
10
10
  import { codeUsage, runCodeCommand } from './commands/code.js';
11
- import { collaborationUsage, runCollaborationCommand, } from './commands/collaboration.js';
12
11
  import { hostUsage, runHostCommand } from './commands/host.js';
12
+ import { sessionUsage, runSessionCommand } from './commands/session.js';
13
+ import { collaborationCommandLine } from './commands/collaboration.js';
14
+ import { collaborationRoleRunUsage, runCollaborationRoleRunCommand, } from './commands/collaboration-role-run.js';
15
+ import { collaborationRolePlanUsage, runCollaborationRolePlanCommand, } from './commands/collaboration-role-plan.js';
13
16
  import { runtimeUsage, runRuntimeCommand } from './commands/runtime.js';
17
+ import { repairUsage, runRepairCommand } from './commands/repair.js';
14
18
  import { hostNameSchema } from '../schemas/host.js';
15
- function parseOptions(args) {
16
- const { values, positionals } = parseArgs({
17
- args: [...args],
18
- options: {
19
- help: { type: 'boolean', short: 'h' },
20
- version: { type: 'boolean', short: 'v' },
21
- json: { type: 'boolean' },
22
- config: { type: 'string' },
23
- apply: { type: 'boolean' },
24
- yes: { type: 'boolean', short: 'y' },
25
- 'no-runtime': { type: 'boolean' },
26
- reconfigure: { type: 'boolean' },
27
- hosts: { type: 'string' },
28
- 'apply-host': { type: 'boolean' },
29
- 'dry-run': { type: 'boolean' },
30
- 'print-handoff': { type: 'boolean' },
31
- 'auto-resume': { type: 'boolean' },
32
- from: { type: 'string' },
33
- tarball: { type: 'string' },
34
- out: { type: 'string' },
35
- mode: { type: 'string' },
36
- marketplace: { type: 'boolean' },
37
- scope: { type: 'string' },
38
- bind: { type: 'boolean' },
39
- force: { type: 'boolean' },
40
- 'no-interactive': { type: 'boolean' },
41
- 'print-choices': { type: 'boolean' },
42
- 'install-runtime': { type: 'boolean' },
43
- 'runtime-tarball': { type: 'string' },
44
- 'runtime-version': { type: 'string' },
45
- root: { type: 'string' },
46
- 'include-private': { type: 'boolean' },
47
- 'include-archived': { type: 'boolean' },
48
- task: { type: 'string' },
49
- objective: { type: 'string' },
50
- acceptance: { type: 'string', multiple: true },
51
- constraint: { type: 'string', multiple: true },
52
- decision: { type: 'string', multiple: true },
53
- attempted: { type: 'string', multiple: true },
54
- 'next-action': { type: 'string', multiple: true },
55
- limitation: { type: 'string', multiple: true },
56
- artifact: { type: 'string', multiple: true },
57
- 'collaboration-record': { type: 'string' },
58
- 'context-completeness': { type: 'string' },
59
- 'author-session': { type: 'string' },
60
- 'native-harness': { type: 'string' },
61
- 'native-session': { type: 'string' },
62
- session: { type: 'string' },
63
- repo: { type: 'string' },
64
- kind: { type: 'string' },
65
- query: { type: 'string' },
66
- limit: { type: 'string' },
67
- 'max-bytes': { type: 'string' },
68
- rebuild: { type: 'boolean' },
69
- host: { type: 'string' },
70
- 'host-root': { type: 'string' },
71
- 'host-version': { type: 'string' },
72
- goal: { type: 'string' },
73
- prepared: { type: 'string' },
74
- capabilities: { type: 'string' },
75
- controller: { type: 'string' },
76
- 'domain-root': { type: 'string' },
77
- },
78
- allowPositionals: true,
79
- strict: true,
80
- });
81
- if (values.help && values.version) {
82
- throw new Error('Use either --help or --version, not both.');
83
- }
84
- const command = positionals[0] ?? null;
85
- if (command === 'task') {
86
- if (positionals.length > 3) {
87
- throw new Error('task accepts one action and an optional task id.');
88
- }
89
- return {
90
- values,
91
- command,
92
- docsAction: null,
93
- docsArgument: null,
94
- codeAction: null,
95
- hostAction: null,
96
- hostSubAction: null,
97
- collaborationAction: null,
98
- resumeTaskId: null,
99
- runtimeAction: null,
100
- taskAction: positionals[1] ?? null,
101
- taskArgument: positionals[2] ?? null,
102
- };
103
- }
104
- if (command === 'docs') {
105
- if (positionals.length > 3) {
106
- throw new Error('Unknown command; docs accepts one action and one argument.');
107
- }
108
- return {
109
- values,
110
- codeAction: null,
111
- command,
112
- docsAction: positionals[1] ?? null,
113
- docsArgument: positionals[2] ?? null,
114
- hostAction: null,
115
- hostSubAction: null,
116
- collaborationAction: null,
117
- resumeTaskId: null,
118
- runtimeAction: null,
119
- taskAction: null,
120
- taskArgument: null,
121
- };
122
- }
123
- if (command === 'resume') {
124
- if (positionals.length > 2) {
125
- throw new Error('resume accepts exactly one task id.');
126
- }
127
- return {
128
- values,
129
- command,
130
- docsAction: null,
131
- docsArgument: null,
132
- codeAction: null,
133
- hostAction: null,
134
- hostSubAction: null,
135
- collaborationAction: null,
136
- resumeTaskId: positionals[1] ?? null,
137
- runtimeAction: null,
138
- taskAction: null,
139
- taskArgument: null,
140
- };
141
- }
142
- if (command === 'code') {
143
- if (positionals.length > 2) {
144
- throw new Error('code accepts one action: status, prepare, or query.');
145
- }
146
- return {
147
- values,
148
- command,
149
- docsAction: null,
150
- docsArgument: null,
151
- codeAction: positionals[1] ?? null,
152
- hostAction: null,
153
- hostSubAction: null,
154
- collaborationAction: null,
155
- resumeTaskId: null,
156
- runtimeAction: null,
157
- taskAction: null,
158
- taskArgument: null,
159
- };
160
- }
161
- if (command === 'host') {
162
- if (positionals.length > 3) {
163
- throw new Error('host accepts one action and an optional mcp sub-action.');
164
- }
165
- return {
166
- values,
167
- command,
168
- docsAction: null,
169
- docsArgument: null,
170
- codeAction: null,
171
- hostAction: positionals[1] ?? null,
172
- hostSubAction: positionals[2] ?? null,
173
- collaborationAction: null,
174
- resumeTaskId: null,
175
- runtimeAction: null,
176
- taskAction: null,
177
- taskArgument: null,
178
- };
179
- }
180
- if (command === 'runtime') {
181
- if (positionals.length > 2) {
182
- throw new Error('runtime accepts one action: install, status, verify, or remove.');
183
- }
184
- return {
185
- values,
186
- command,
187
- docsAction: null,
188
- docsArgument: null,
189
- codeAction: null,
190
- hostAction: null,
191
- hostSubAction: null,
192
- collaborationAction: null,
193
- resumeTaskId: null,
194
- runtimeAction: positionals[1] ?? null,
195
- taskAction: null,
196
- taskArgument: null,
197
- };
198
- }
199
- if (command === 'collab') {
200
- if (positionals.length > 2) {
201
- throw new Error('collab accepts one action: prepare, run, or query.');
202
- }
203
- return {
204
- values,
205
- command,
206
- docsAction: null,
207
- docsArgument: null,
208
- codeAction: null,
209
- hostAction: null,
210
- hostSubAction: null,
211
- collaborationAction: positionals[1] ?? null,
212
- resumeTaskId: null,
213
- runtimeAction: null,
214
- taskAction: null,
215
- taskArgument: null,
216
- };
217
- }
218
- if (positionals.length > 1) {
219
- throw new Error('Only one command may be specified.');
220
- }
221
- return {
222
- values,
223
- command,
224
- docsAction: null,
225
- docsArgument: null,
226
- codeAction: null,
227
- hostAction: null,
228
- collaborationAction: null,
229
- resumeTaskId: null,
230
- runtimeAction: null,
231
- };
232
- }
233
- function failure(output, json, code, error) {
234
- const message = typeof error === 'string'
235
- ? error
236
- : error instanceof Error
237
- ? error.message
238
- : 'Operation failed.';
239
- if (json) {
240
- output.stdout(`${JSON.stringify({ ok: false, code, message })}\n`);
241
- }
242
- else {
243
- output.stderr(`pappra: ${message}\n`);
244
- }
245
- }
246
- function hasContinuityOptions(values, includeSession = true) {
247
- return (values.task !== undefined ||
248
- values.objective !== undefined ||
249
- values.acceptance !== undefined ||
250
- values.constraint !== undefined ||
251
- values.decision !== undefined ||
252
- values.attempted !== undefined ||
253
- values['next-action'] !== undefined ||
254
- values.limitation !== undefined ||
255
- values.artifact !== undefined ||
256
- values['collaboration-record'] !== undefined ||
257
- values['context-completeness'] !== undefined ||
258
- values['author-session'] !== undefined ||
259
- values['native-harness'] !== undefined ||
260
- values['native-session'] !== undefined ||
261
- (includeSession && values.session !== undefined));
262
- }
19
+ import { parseOptions, failure, hasContinuityOptions } from './options.js';
20
+ import { routeCollaboration } from './collaboration-router.js';
263
21
  const globalUsage = 'pappra [--help | --version] [--json]\n' +
264
22
  'pappra task <pin|unpin|show> [taskId] [--auto-resume] [--json]\n' +
265
- 'pappra mcp [--root <dir>] [--help]\n' +
23
+ 'pappra mcp [--root <dir>] [--allow-workspace-writes] [--help]\n' +
266
24
  'pappra onboard [--root <dir>] [--config <file>] [--hosts <list>] [--yes]\n' +
267
25
  ' [--apply-host] [--dry-run] [--print-handoff] [--json]\n' +
268
26
  'pappra init [--config <file> | --yes] [--apply] [--json] [--print-choices]\n' +
269
27
  ' [--install-runtime (--runtime-tarball <file> | --runtime-version <version>)]\n' +
270
28
  'pappra doctor [--root <path>] [--json]\n' +
271
- 'pappra docs <list|check|archive> [options]\n' +
29
+ 'pappra repair [--root <path>] [--runtime-version <v>] [--install-id <uuid>] [--apply] [--json]\n' +
30
+ 'pappra docs <list|check|archive|scan|relocate|forget> [options]\n' +
272
31
  'pappra checkpoint --task <id> [options] [--json]\n' +
273
32
  'pappra resume <taskId> [--session <id>] [--json]\n' +
274
33
  'pappra code <status|prepare|query> --repo <id> [options] [--json]\n' +
275
- 'pappra host <detect|describe|plan|install|verify> --host <name> [options] [--json]\n' +
276
- 'pappra runtime <install|status|verify|remove> [options] [--json]\n' +
277
- 'pappra collab <prepare|run|query> [options]';
34
+ 'pappra host <detect|describe|probe|plan|install|verify|uninstall|bundle|mcp> --host <name> [options] [--json]\n' +
35
+ 'pappra runtime <install|status|verify|remove|gc> [options] [--json]\n' +
36
+ 'pappra session <plan|start|status|fence|stop> --config <abs managed-pi.json> [--json]\n' +
37
+ `${collaborationCommandLine}`;
278
38
  export async function runCli(args, output) {
279
39
  const jsonRequested = args.includes('--json');
40
+ if (args[0] === 'repair') {
41
+ try {
42
+ const parsedRepair = parseArgs({
43
+ args: [...args.slice(1)],
44
+ options: {
45
+ root: { type: 'string' },
46
+ 'runtime-version': { type: 'string' },
47
+ 'install-id': { type: 'string' },
48
+ apply: { type: 'boolean' },
49
+ 'quarantine-unowned-locks': { type: 'boolean' },
50
+ 'reset-local': { type: 'boolean' },
51
+ 'all-writers-stopped': { type: 'boolean' },
52
+ json: { type: 'boolean' },
53
+ help: { type: 'boolean', short: 'h' },
54
+ },
55
+ allowPositionals: false,
56
+ strict: true,
57
+ });
58
+ if (['--root', '--runtime-version', '--install-id'].some((flag) => args.filter((arg) => arg === flag || arg.startsWith(`${flag}=`))
59
+ .length > 1))
60
+ throw new Error('Repair options must not be repeated.');
61
+ if (parsedRepair.values.help) {
62
+ output.stdout(repairUsage);
63
+ return 0;
64
+ }
65
+ return runRepairCommand({
66
+ root: parsedRepair.values.root ?? process.cwd(),
67
+ ...(parsedRepair.values['runtime-version'] === undefined
68
+ ? {}
69
+ : { runtimeVersion: parsedRepair.values['runtime-version'] }),
70
+ ...(parsedRepair.values['install-id'] === undefined
71
+ ? {}
72
+ : { installId: parsedRepair.values['install-id'] }),
73
+ apply: parsedRepair.values.apply === true,
74
+ quarantineUnownedLocks: parsedRepair.values['quarantine-unowned-locks'] === true,
75
+ resetLocal: parsedRepair.values['reset-local'] === true,
76
+ allWritersStopped: parsedRepair.values['all-writers-stopped'] === true,
77
+ json: parsedRepair.values.json === true,
78
+ }, output);
79
+ }
80
+ catch (error) {
81
+ failure(output, jsonRequested, 'invalid_arguments', error);
82
+ return 2;
83
+ }
84
+ }
85
+ if (args[0] === 'session') {
86
+ try {
87
+ const parsedSession = parseArgs({
88
+ args: [...args.slice(1)],
89
+ options: {
90
+ config: { type: 'string' },
91
+ json: { type: 'boolean' },
92
+ help: { type: 'boolean', short: 'h' },
93
+ },
94
+ allowPositionals: true,
95
+ strict: true,
96
+ });
97
+ if (parsedSession.values.help) {
98
+ output.stdout(`${sessionUsage}\n`);
99
+ return 0;
100
+ }
101
+ if (parsedSession.positionals.length !== 1 ||
102
+ args.filter((arg) => arg === '--config' || arg.startsWith('--config='))
103
+ .length > 1)
104
+ throw new Error(sessionUsage);
105
+ return runSessionCommand({
106
+ action: parsedSession.positionals[0],
107
+ config: parsedSession.values.config ?? null,
108
+ json: parsedSession.values.json ?? false,
109
+ }, output);
110
+ }
111
+ catch (error) {
112
+ failure(output, jsonRequested, 'invalid_arguments', error);
113
+ return 2;
114
+ }
115
+ }
280
116
  let parsed;
281
117
  try {
282
118
  parsed = parseOptions(args);
@@ -287,7 +123,61 @@ export async function runCli(args, output) {
287
123
  }
288
124
  const { values, command, docsAction, docsArgument, codeAction, hostAction, collaborationAction, resumeTaskId, runtimeAction, hostSubAction, taskAction, taskArgument, } = parsed;
289
125
  const json = values.json === true;
126
+ if (values['allow-workspace-writes'] === true && command !== 'mcp') {
127
+ failure(output, json, 'invalid_arguments', '--allow-workspace-writes is a trusted MCP server startup option only.');
128
+ return 2;
129
+ }
290
130
  const applyRequested = values.apply === true;
131
+ if (command === 'collab' && collaborationAction === 'role-run') {
132
+ const allowed = new Set(['request', 'apply', 'watch', 'json', 'help']);
133
+ const invalid = Object.entries(values).some(([key, value]) => value !== undefined && !allowed.has(key));
134
+ const duplicates = args.filter((arg) => arg === '--request' || arg.startsWith('--request='))
135
+ .length > 1;
136
+ if (invalid || duplicates) {
137
+ failure(output, json, 'invalid_arguments', collaborationRoleRunUsage);
138
+ return 2;
139
+ }
140
+ if (values.help) {
141
+ output.stdout(`${collaborationRoleRunUsage}\n`);
142
+ return 0;
143
+ }
144
+ return runCollaborationRoleRunCommand({
145
+ requestFile: values.request ?? null,
146
+ apply: applyRequested,
147
+ watch: values.watch === true,
148
+ json,
149
+ }, output);
150
+ }
151
+ if (values.watch !== undefined) {
152
+ failure(output, json, 'invalid_arguments', '--watch is supported only by collab role-run.');
153
+ return 2;
154
+ }
155
+ if (command === 'collab' && collaborationAction?.startsWith('role-plan')) {
156
+ const allowed = new Set(['request', 'task-root', 'config', 'json', 'help']);
157
+ const extra = Object.entries(values).filter(([key, value]) => value !== undefined && !allowed.has(key));
158
+ const duplicate = ['--request', '--task-root', '--config'].some((flag) => args.filter((arg) => arg === flag || arg.startsWith(`${flag}=`))
159
+ .length > 1);
160
+ if (extra.length || duplicate) {
161
+ failure(output, json, 'invalid_arguments', collaborationRolePlanUsage);
162
+ return 2;
163
+ }
164
+ if (values.help) {
165
+ output.stdout(`${collaborationRolePlanUsage}\n`);
166
+ return 0;
167
+ }
168
+ return runCollaborationRolePlanCommand({
169
+ action: collaborationAction.slice('role-plan:'.length),
170
+ requestFile: values.request ?? null,
171
+ taskRoot: values['task-root'] ?? null,
172
+ planFile: values.config ?? null,
173
+ json,
174
+ }, output);
175
+ }
176
+ if (values.live === true &&
177
+ !(command === 'collab' && collaborationAction === 'capabilities:derive')) {
178
+ failure(output, json, 'invalid_arguments', '--live is only valid for collab capabilities derive.');
179
+ return 2;
180
+ }
291
181
  if (command !== 'init' &&
292
182
  (values['no-interactive'] === true ||
293
183
  values['print-choices'] === true ||
@@ -312,20 +202,42 @@ export async function runCli(args, output) {
312
202
  failure(output, json, 'invalid_arguments', '--hosts, --apply-host, --dry-run and --print-handoff are only valid for onboard.');
313
203
  return 2;
314
204
  }
315
- if (command !== 'host' && values.out !== undefined) {
316
- failure(output, json, 'invalid_arguments', '--out is only valid for host.');
205
+ if (command !== 'host' && values['bootstrap-config'] !== undefined) {
206
+ failure(output, json, 'invalid_arguments', '--bootstrap-config is only valid for host bundle.');
317
207
  return 2;
318
208
  }
319
- if (values.scope !== undefined &&
320
- values.scope !== 'project' &&
321
- values.scope !== 'user') {
322
- failure(output, json, 'invalid_arguments', '--scope accepts project or user.');
209
+ if (command !== 'host' && values['recovery-config'] !== undefined) {
210
+ failure(output, json, 'invalid_arguments', '--recovery-config is only valid for host bundle.');
323
211
  return 2;
324
212
  }
325
- if (command !== 'host' && values.scope !== undefined) {
326
- failure(output, json, 'invalid_arguments', '--scope is only valid for host.');
213
+ if (command !== 'host' && values['transition-extension'] === true) {
214
+ failure(output, json, 'invalid_arguments', '--transition-extension is only valid for host bundle.');
327
215
  return 2;
328
216
  }
217
+ if (command !== 'host' && values.out !== undefined) {
218
+ failure(output, json, 'invalid_arguments', '--out is only valid for host.');
219
+ return 2;
220
+ }
221
+ if (values.scope !== undefined) {
222
+ // `--scope` is command-family scoped: host wiring uses project|user, knowledge
223
+ // documents use private|shared, and docs itself still restricts it to forget.
224
+ if (command === 'host') {
225
+ if (values.scope !== 'project' && values.scope !== 'user') {
226
+ failure(output, json, 'invalid_arguments', '--scope accepts project or user.');
227
+ return 2;
228
+ }
229
+ }
230
+ else if (command === 'docs') {
231
+ if (values.scope !== 'private' && values.scope !== 'shared') {
232
+ failure(output, json, 'invalid_arguments', '--scope accepts private or shared for docs.');
233
+ return 2;
234
+ }
235
+ }
236
+ else {
237
+ failure(output, json, 'invalid_arguments', '--scope is only valid for host or docs.');
238
+ return 2;
239
+ }
240
+ }
329
241
  if (command !== 'host' && values.marketplace === true) {
330
242
  failure(output, json, 'invalid_arguments', '--marketplace is only valid for host bundle.');
331
243
  return 2;
@@ -351,6 +263,25 @@ export async function runCli(args, output) {
351
263
  failure(output, json, 'invalid_arguments', '--from, --tarball, --bind and --force are only valid for runtime.');
352
264
  return 2;
353
265
  }
266
+ const rpcRequestTimeout = values['rpc-request-timeout-ms'];
267
+ const rpcOperationTimeout = values['rpc-operation-timeout-ms'];
268
+ for (const [name, value, maximum] of [
269
+ ['rpc-request-timeout-ms', rpcRequestTimeout, 60_000],
270
+ ['rpc-operation-timeout-ms', rpcOperationTimeout, 86_400_000],
271
+ ]) {
272
+ if (value === undefined)
273
+ continue;
274
+ if (command !== 'collab' ||
275
+ collaborationAction !== 'run' ||
276
+ values.controller !== 'pi-rpc' ||
277
+ !/^[0-9]+$/.test(value) ||
278
+ !Number.isSafeInteger(Number(value)) ||
279
+ Number(value) < 1 ||
280
+ Number(value) > maximum) {
281
+ failure(output, json, 'invalid_arguments', `--${name} requires collab run --controller pi-rpc and an integer from 1 to ${maximum}.`);
282
+ return 2;
283
+ }
284
+ }
354
285
  let info;
355
286
  try {
356
287
  info = getPackageInfo();
@@ -367,44 +298,40 @@ export async function runCli(args, output) {
367
298
  output.stdout(json ? `${JSON.stringify(info)}\n` : `${info.version}\n`);
368
299
  return 0;
369
300
  }
301
+ if (command !== 'collab' &&
302
+ (values['task-root'] !== undefined ||
303
+ values.message !== undefined ||
304
+ values['message-id'] !== undefined ||
305
+ values.binding !== undefined ||
306
+ values.retry === true ||
307
+ values['caller-pane'] !== undefined ||
308
+ values.assignment !== undefined ||
309
+ values['max-age-minutes'] !== undefined ||
310
+ values.harness !== undefined ||
311
+ values.template !== undefined ||
312
+ values.execution !== undefined ||
313
+ values.events !== undefined ||
314
+ values.request !== undefined ||
315
+ values['owner-epoch'] !== undefined ||
316
+ values['subtask-id'] !== undefined ||
317
+ values.attempt !== undefined ||
318
+ values['task-id'] !== undefined ||
319
+ values.record !== undefined ||
320
+ values.roots !== undefined)) {
321
+ failure(output, json, 'invalid_arguments', '--task-root, --message, --message-id, --binding, --retry, --caller-pane, --assignment, --max-age-minutes, --harness, --template, --execution, --events, --request, --owner-epoch, --subtask-id, --attempt, --task-id, --record and --roots are only valid for collab.');
322
+ return 2;
323
+ }
370
324
  if (command === 'collab') {
371
- if (values.help) {
372
- if (json) {
373
- output.stdout(`${JSON.stringify({ ...info, commands: ['collab'], usage: collaborationUsage })}\n`);
374
- }
375
- else {
376
- output.stdout(collaborationUsage);
377
- }
378
- return 0;
379
- }
380
- const action = collaborationAction === 'prepare' ||
381
- collaborationAction === 'run' ||
382
- collaborationAction === 'query'
383
- ? collaborationAction
384
- : null;
385
- if (action === null ||
386
- values.version ||
387
- values.config !== undefined ||
388
- values['install-runtime'] === true ||
389
- values['runtime-tarball'] !== undefined ||
390
- values['runtime-version'] !== undefined ||
391
- values.root !== undefined ||
392
- values['include-private'] === true ||
393
- values['include-archived'] === true ||
394
- hasContinuityOptions(values)) {
395
- failure(output, json, 'invalid_arguments', 'collab requires prepare/run/query and only collab options.');
396
- return 2;
397
- }
398
- return runCollaborationCommand({
399
- cwd: process.cwd(),
400
- action,
325
+ return routeCollaboration({
326
+ values,
327
+ action: collaborationAction,
328
+ args,
329
+ info,
330
+ rpcRequestTimeout,
331
+ rpcOperationTimeout,
332
+ output,
401
333
  json,
402
- goalFile: values.goal ?? null,
403
- preparedFile: values.prepared ?? null,
404
- capabilitiesFile: values.capabilities ?? null,
405
- controller: values.controller ?? null,
406
- domainRoot: values['domain-root'] ?? null,
407
- }, output);
334
+ });
408
335
  }
409
336
  if (command === 'docs') {
410
337
  if (values.version ||
@@ -414,7 +341,7 @@ export async function runCli(args, output) {
414
341
  values['runtime-version'] !== undefined ||
415
342
  values.root !== undefined ||
416
343
  hasContinuityOptions(values)) {
417
- failure(output, json, 'invalid_arguments', 'docs only accepts list/check/archive/scan, --include-private, --include-archived, --apply (scan only), --help, and --json.');
344
+ failure(output, json, 'invalid_arguments', 'docs accepts list/check/archive/scan/relocate/forget, --include-private, --include-archived, --apply, --help, and --json.');
418
345
  return 2;
419
346
  }
420
347
  if (values.help) {
@@ -430,6 +357,8 @@ export async function runCli(args, output) {
430
357
  cwd: process.cwd(),
431
358
  action: docsAction,
432
359
  argument: docsArgument,
360
+ targetPath: 'docsTarget' in parsed ? parsed.docsTarget : null,
361
+ scope: values.scope ?? null,
433
362
  json,
434
363
  includePrivate: values['include-private'] === true,
435
364
  includeArchived: values['include-archived'] === true,
@@ -524,7 +453,7 @@ export async function runCli(args, output) {
524
453
  values.rebuild === true ||
525
454
  values.host !== undefined ||
526
455
  hasContinuityOptions(values)) {
527
- failure(output, json, 'invalid_arguments', 'mcp accepts only --root, --help, and --json.');
456
+ failure(output, json, 'invalid_arguments', 'mcp accepts --root, --allow-workspace-writes, --help, and --json.');
528
457
  return 2;
529
458
  }
530
459
  if (values.help) {
@@ -540,7 +469,12 @@ export async function runCli(args, output) {
540
469
  failure(output, json, 'invalid_arguments', '--version cannot be combined with mcp.');
541
470
  return 2;
542
471
  }
543
- return runMcpCommand({ cwd: process.cwd(), root: values.root ?? null, json }, output);
472
+ return runMcpCommand({
473
+ cwd: process.cwd(),
474
+ root: values.root ?? null,
475
+ json,
476
+ allowWorkspaceWrites: values['allow-workspace-writes'] === true,
477
+ }, output);
544
478
  }
545
479
  if (command === 'onboard') {
546
480
  if (values.apply === true ||
@@ -648,13 +582,14 @@ export async function runCli(args, output) {
648
582
  values.query !== undefined ||
649
583
  values.kind !== undefined ||
650
584
  hasContinuityOptions(values)) {
651
- failure(output, json, 'invalid_arguments', 'runtime accepts only --from, --tarball, --version, --apply, --bind, --force, --help, and --json.');
585
+ failure(output, json, 'invalid_arguments', 'runtime accepts only --from, --tarball, --runtime-version, --apply, --bind, --force, --help, and --json.');
652
586
  return 2;
653
587
  }
654
588
  const action = runtimeAction === 'install' ||
655
589
  runtimeAction === 'status' ||
656
590
  runtimeAction === 'verify' ||
657
- runtimeAction === 'remove'
591
+ runtimeAction === 'remove' ||
592
+ runtimeAction === 'gc'
658
593
  ? runtimeAction
659
594
  : null;
660
595
  return runRuntimeCommand({
@@ -847,6 +782,7 @@ export async function runCli(args, output) {
847
782
  'describe',
848
783
  'plan',
849
784
  'install',
785
+ 'uninstall',
850
786
  'verify',
851
787
  'bundle',
852
788
  'mcp',
@@ -855,6 +791,10 @@ export async function runCli(args, output) {
855
791
  const action = allowedActions.find((item) => item === hostAction) ?? null;
856
792
  const parsedHost = hostNameSchema.safeParse(values.host);
857
793
  const host = parsedHost.success ? parsedHost.data : null;
794
+ const duplicatedBootstrapConfig = args.filter((arg) => arg === '--bootstrap-config' || arg.startsWith('--bootstrap-config=')).length > 1;
795
+ const duplicatedRecoveryConfig = args.filter((arg) => arg === '--recovery-config' || arg.startsWith('--recovery-config=')).length > 1;
796
+ const duplicatedTransitionExtension = args.filter((arg) => arg === '--transition-extension' ||
797
+ arg.startsWith('--transition-extension=')).length > 1;
858
798
  const invalid = values.version ||
859
799
  values.config !== undefined ||
860
800
  values['install-runtime'] === true ||
@@ -870,15 +810,42 @@ export async function runCli(args, output) {
870
810
  values['max-bytes'] !== undefined ||
871
811
  values.rebuild === true ||
872
812
  hasContinuityOptions(values) ||
873
- (values.apply === true && action !== 'install' && action !== 'mcp') ||
813
+ (values.apply === true &&
814
+ action !== 'install' &&
815
+ action !== 'uninstall' &&
816
+ action !== 'mcp') ||
874
817
  (values.mode !== undefined && action !== 'install') ||
875
818
  (values.marketplace === true && action !== 'bundle') ||
819
+ (values['bootstrap-config'] !== undefined &&
820
+ (action !== 'bundle' ||
821
+ values.marketplace === true ||
822
+ values.mode !== undefined ||
823
+ values.apply === true ||
824
+ values['recovery-config'] !== undefined ||
825
+ values['transition-extension'] === true)) ||
826
+ (values['recovery-config'] !== undefined &&
827
+ (action !== 'bundle' ||
828
+ host !== 'pi' ||
829
+ values.marketplace === true ||
830
+ values.mode !== undefined ||
831
+ values.apply === true)) ||
832
+ (values['transition-extension'] === true &&
833
+ (action !== 'bundle' ||
834
+ host !== 'pi' ||
835
+ values.marketplace === true ||
836
+ values.mode !== undefined ||
837
+ values.apply === true ||
838
+ values['bootstrap-config'] !== undefined)) ||
876
839
  (values.scope !== undefined &&
877
840
  action !== 'plan' &&
878
841
  action !== 'install' &&
842
+ action !== 'uninstall' &&
879
843
  action !== 'verify') ||
880
844
  (values['host-root'] !== undefined && action === null) ||
881
- (values['host-version'] !== undefined && action === null);
845
+ (values['host-version'] !== undefined && action === null) ||
846
+ duplicatedBootstrapConfig ||
847
+ duplicatedRecoveryConfig ||
848
+ duplicatedTransitionExtension;
882
849
  if (values.help) {
883
850
  if (json) {
884
851
  output.stdout(`${JSON.stringify({ ...info, commands: ['host'], usage: hostUsage })}\n`);
@@ -889,7 +856,7 @@ export async function runCli(args, output) {
889
856
  return 0;
890
857
  }
891
858
  if (action === null || host === null || invalid) {
892
- failure(output, json, 'invalid_arguments', 'host requires detect/describe/plan/install/verify/bundle, --host, and action-compatible options.');
859
+ failure(output, json, 'invalid_arguments', 'host requires detect/describe/probe/plan/install/verify/uninstall/bundle/mcp, --host, and action-compatible options.');
893
860
  return 2;
894
861
  }
895
862
  return runHostCommand({
@@ -906,6 +873,9 @@ export async function runCli(args, output) {
906
873
  mode: values.mode === 'project-settings' || values.mode === 'plugin'
907
874
  ? values.mode
908
875
  : null,
876
+ bootstrapConfig: values['bootstrap-config'] ?? null,
877
+ recoveryConfig: values['recovery-config'] ?? null,
878
+ transitionExtension: values['transition-extension'] === true,
909
879
  marketplace: values.marketplace === true,
910
880
  scope: values.scope === 'project' || values.scope === 'user'
911
881
  ? values.scope
@@ -930,16 +900,16 @@ export async function runCli(args, output) {
930
900
  }
931
901
  if (values.help) {
932
902
  if (json) {
933
- output.stdout(`${JSON.stringify({ ...info, usage: globalUsage, commands: ['init', 'doctor', 'docs', 'checkpoint', 'resume', 'code', 'host', 'collab'] })}\n`);
903
+ output.stdout(`${JSON.stringify({ ...info, usage: globalUsage, commands: ['init', 'onboard', 'doctor', 'repair', 'docs', 'checkpoint', 'resume', 'code', 'host', 'runtime', 'task', 'mcp', 'collab', 'session'] })}\n`);
934
904
  }
935
905
  else {
936
- output.stdout(`${info.name} ${info.version}\n${info.description}\n\nUsage:\n ${globalUsage.replaceAll('\n', '\n ')}\n\nOptions:\n -h, --help Show help\n -v, --version Show version\n --json Output JSON\n\nCommands:\n init Plan workspace initialization\n doctor Read-only workspace and installation diagnostics\n docs List, check, and archive registered documents\n`);
937
- output.stdout(' checkpoint Save a private task checkpoint\n resume Read a bounded recovery packet without starting an agent\n code Inspect or prepare selected code intelligence\n host Detect, plan, install, or verify a selected host integration\n collab Prepare, run, or query a bounded collaboration goal\n');
906
+ output.stdout(`${info.name} ${info.version}\n${info.description}\n\nUsage:\n ${globalUsage.replaceAll('\n', '\n ')}\n\nOptions:\n -h, --help Show help\n -v, --version Show version\n --json Output JSON\n\nCommands:\n init Plan workspace initialization\n onboard Discover and connect supported hosts\n doctor Read-only workspace and installation diagnostics\n repair Inspect and repair interrupted state\n docs Scan, relocate, forget and inspect knowledge\n runtime Install, verify and remove durable runtimes\n task Select a private task and auto-resume preference\n mcp Serve workspace tools over stdio\n`);
907
+ output.stdout(' checkpoint Save a private task checkpoint\n resume Read a bounded recovery packet without starting an agent\n code Inspect or prepare selected code intelligence\n host Detect, plan, install, or verify a selected host integration\n collab Prepare, run, query, message, preflight, state, recovery and bindings\n session Launch and control an owned visible native Pi session\n');
938
908
  }
939
909
  return 0;
940
910
  }
941
911
  if (json) {
942
- output.stdout(`${JSON.stringify({ ...info, usage: globalUsage, commands: ['init', 'doctor', 'docs', 'checkpoint', 'resume', 'code', 'host', 'collab'] })}\n`);
912
+ output.stdout(`${JSON.stringify({ ...info, usage: globalUsage, commands: ['init', 'onboard', 'doctor', 'repair', 'docs', 'checkpoint', 'resume', 'code', 'host', 'runtime', 'task', 'mcp', 'collab', 'session'] })}\n`);
943
913
  }
944
914
  else {
945
915
  output.stdout(`${info.name} ${info.version}\n${info.description}\n\nUsage:\n ${globalUsage}\n\nRun pappra --help for all options.\n`);