@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
@@ -2,12 +2,14 @@ import type { Diagnostic } from '../schemas/diagnostics.js';
2
2
  import type { Checkpoint } from '../schemas/continuity.js';
3
3
  import type { MachineConfig } from '../schemas/machine.js';
4
4
  import type { WorkspaceConfig } from '../schemas/workspace.js';
5
- import type { DiscoveredRepository } from '../workspace/types.js';
5
+ import type { DiscoveredRepository, UnresolvedRepository } from '../workspace/types.js';
6
6
  export interface ContinuityWorkspace {
7
7
  readonly root: string;
8
8
  readonly config: WorkspaceConfig;
9
9
  readonly machine: MachineConfig | null;
10
10
  readonly repositories: readonly DiscoveredRepository[];
11
+ readonly unresolvedRepositories: readonly UnresolvedRepository[];
12
+ readonly discoveryTruncated: boolean;
11
13
  readonly diagnostics: readonly Diagnostic[];
12
14
  }
13
15
  export interface ContinuityWorkspaceResult {
@@ -20,5 +22,12 @@ export interface RepositorySnapshot {
20
22
  readonly patchBytes: Buffer | null;
21
23
  }
22
24
  export declare function loadContinuityWorkspace(root: string): Promise<ContinuityWorkspaceResult>;
23
- export declare function snapshotRepository(workspace: ContinuityWorkspace, repository: DiscoveredRepository, index: number): Promise<RepositorySnapshot>;
25
+ /**
26
+ * Assigns stable identities that never shadow a configured logical ID. The
27
+ * normal fallback remains unchanged when collision-free; an automatic
28
+ * repository whose preferred fallback is reserved receives the first free
29
+ * `workspace-N` identity instead. Capture and resume must use the same list.
30
+ */
31
+ export declare function repositoryIdentities(repositories: readonly DiscoveredRepository[], reservedIds?: readonly string[]): readonly string[];
32
+ export declare function snapshotRepository(workspace: ContinuityWorkspace, repository: DiscoveredRepository, index: number, assignedId?: string): Promise<RepositorySnapshot>;
24
33
  export declare function continuityDiagnostic(message: string, source: string, hint: string): Diagnostic;
@@ -38,6 +38,8 @@ export async function loadContinuityWorkspace(root) {
38
38
  config: config.value,
39
39
  machine: machine.value,
40
40
  repositories: repositories.repositories,
41
+ unresolvedRepositories: repositories.unresolved,
42
+ discoveryTruncated: repositories.truncated,
41
43
  diagnostics,
42
44
  },
43
45
  diagnostics,
@@ -46,15 +48,74 @@ export async function loadContinuityWorkspace(root) {
46
48
  function repoId(repository, index) {
47
49
  return (repository.id ?? (index === 0 ? 'workspace' : `workspace-${index + 1}`));
48
50
  }
51
+ /**
52
+ * Assigns stable identities that never shadow a configured logical ID. The
53
+ * normal fallback remains unchanged when collision-free; an automatic
54
+ * repository whose preferred fallback is reserved receives the first free
55
+ * `workspace-N` identity instead. Capture and resume must use the same list.
56
+ */
57
+ export function repositoryIdentities(repositories, reservedIds = []) {
58
+ const used = new Set([
59
+ ...reservedIds,
60
+ ...repositories.flatMap((repository) => repository.id === null ? [] : [repository.id]),
61
+ ]);
62
+ return repositories.map((repository, index) => {
63
+ if (repository.id !== null)
64
+ return repository.id;
65
+ const preferred = index === 0 ? 'workspace' : `workspace-${index + 1}`;
66
+ let candidate = preferred;
67
+ let suffix = 1;
68
+ while (used.has(candidate)) {
69
+ candidate = `workspace-${suffix}`;
70
+ suffix += 1;
71
+ }
72
+ used.add(candidate);
73
+ return candidate;
74
+ });
75
+ }
49
76
  function repoScope(repository) {
50
77
  return repository.external ? 'external' : 'workspace';
51
78
  }
52
- export async function snapshotRepository(workspace, repository, index) {
79
+ /**
80
+ * Parses `git status --porcelain=v1 -z` untracked paths without display
81
+ * unquoting. Rename/copy records carry a second NUL-delimited original path;
82
+ * that continuation is skipped so it can never be treated as a status row.
83
+ */
84
+ function untrackedPathsFromNulStatus(statusText) {
85
+ if (statusText === '')
86
+ return [];
87
+ if (!statusText.endsWith('\0'))
88
+ return null;
89
+ const fields = statusText.split('\0');
90
+ fields.pop();
91
+ const paths = [];
92
+ for (let index = 0; index < fields.length; index += 1) {
93
+ const entry = fields[index];
94
+ if (entry === undefined || entry.length < 3 || entry[2] !== ' ') {
95
+ return null;
96
+ }
97
+ const code = entry.slice(0, 2);
98
+ const path = entry.slice(3);
99
+ if (path.length === 0)
100
+ return null;
101
+ if (code === '??')
102
+ paths.push(path);
103
+ if (code[0] === 'R' || code[0] === 'C') {
104
+ const continuation = fields[index + 1];
105
+ if (continuation === undefined || continuation.length === 0)
106
+ return null;
107
+ index += 1;
108
+ }
109
+ }
110
+ return paths;
111
+ }
112
+ export async function snapshotRepository(workspace, repository, index, assignedId) {
53
113
  const status = await runGit({
54
114
  cwd: repository.root,
55
115
  args: [
56
116
  'status',
57
117
  '--porcelain=v1',
118
+ '-z',
58
119
  '--untracked-files=all',
59
120
  '--',
60
121
  '.',
@@ -68,6 +129,8 @@ export async function snapshotRepository(workspace, repository, index) {
68
129
  cwd: repository.root,
69
130
  args: [
70
131
  'diff',
132
+ '--no-ext-diff',
133
+ '--no-textconv',
71
134
  '--binary',
72
135
  'HEAD',
73
136
  '--',
@@ -82,12 +145,15 @@ export async function snapshotRepository(workspace, repository, index) {
82
145
  const diffText = diff.ok ? diff.value.stdout : '';
83
146
  const dirty = status.ok ? statusText.trim().length > 0 : repository.git.dirty;
84
147
  let captureStatus = status.ok && diff.ok ? 'complete' : 'unknown';
148
+ const untracked = status.ok ? untrackedPathsFromNulStatus(statusText) : null;
149
+ if (status.ok && untracked === null)
150
+ captureStatus = 'partial';
85
151
  let patchBytes = null;
86
152
  if (dirty === true && status.ok && diff.ok) {
87
153
  const statusBytes = Buffer.from(statusText, 'utf8');
88
154
  const diffBytes = Buffer.from(diffText, 'utf8');
89
155
  const parts = [
90
- Buffer.from(`PAPPRA-UNTRACKED/2\nP ${statusBytes.length} ${diffBytes.length}\n`, 'utf8'),
156
+ Buffer.from(`PAPPRA-UNTRACKED/3\nP ${statusBytes.length} ${diffBytes.length}\n`, 'utf8'),
91
157
  statusBytes,
92
158
  diffBytes,
93
159
  ];
@@ -95,11 +161,7 @@ export async function snapshotRepository(workspace, repository, index) {
95
161
  if (total > CONTINUITY_PAYLOAD_MAX_BYTES) {
96
162
  captureStatus = 'partial';
97
163
  }
98
- const untracked = statusText
99
- .split('\n')
100
- .filter((line) => line.startsWith('?? '))
101
- .map((line) => line.slice(3));
102
- for (const path of untracked) {
164
+ for (const path of untracked ?? []) {
103
165
  if (total > CONTINUITY_PAYLOAD_MAX_BYTES)
104
166
  break;
105
167
  const absolute = join(repository.root, path);
@@ -120,7 +182,7 @@ export async function snapshotRepository(workspace, repository, index) {
120
182
  captureStatus = 'partial';
121
183
  continue;
122
184
  }
123
- body = read.value.bytes;
185
+ body = Buffer.from(read.value.digest, 'utf8');
124
186
  entryKind = 'F';
125
187
  }
126
188
  else if (observation.kind === 'symlink') {
@@ -129,17 +191,42 @@ export async function snapshotRepository(workspace, repository, index) {
129
191
  captureStatus = 'partial';
130
192
  continue;
131
193
  }
132
- body = Buffer.from(target, 'utf8');
194
+ body = Buffer.from(sha256Digest(target), 'utf8');
133
195
  entryKind = 'L';
134
196
  }
197
+ else if (observation.kind === 'directory') {
198
+ // Git reports an embedded, non-submodule checkout as one untracked
199
+ // directory. Capture its own Git identity, never recurse into its bytes.
200
+ const head = await runGit({
201
+ cwd: absolute,
202
+ args: ['rev-parse', '--show-toplevel', 'HEAD'],
203
+ timeoutMs: 5000,
204
+ maxOutputBytes: 8192,
205
+ });
206
+ const nestedStatus = await runGit({
207
+ cwd: absolute,
208
+ args: ['status', '--porcelain=v1', '-z', '--untracked-files=all'],
209
+ timeoutMs: 5000,
210
+ maxOutputBytes: 2 * 1024 * 1024,
211
+ });
212
+ if (!head.ok ||
213
+ !nestedStatus.ok ||
214
+ head.value.stdout.split('\n')[0]?.replace(/\/$/, '') !==
215
+ absolute.replace(/\/$/, '')) {
216
+ captureStatus = 'partial';
217
+ continue;
218
+ }
219
+ body = Buffer.from(sha256Digest(`${head.value.stdout}\n${nestedStatus.value.stdout}`), 'utf8');
220
+ entryKind = 'R';
221
+ }
135
222
  else {
136
223
  captureStatus = 'partial';
137
224
  continue;
138
225
  }
139
226
  const pathBytes = Buffer.from(path, 'utf8');
140
- // F/L is part of the identity: a regular file body and a symlink target
141
- // with identical bytes are still different source objects. The target
142
- // text is read with readlink and never resolved or opened.
227
+ // Untracked bytes (including symlink targets) never enter the payload.
228
+ // Frame only their path, type and digest; F/L keeps distinct object kinds
229
+ // separate even when a file's bytes equal a symlink's target text.
143
230
  const header = Buffer.from(`${entryKind} ${pathBytes.length} ${body.length}\n`, 'utf8');
144
231
  if (total + header.length + pathBytes.length + body.length >
145
232
  CONTINUITY_PAYLOAD_MAX_BYTES) {
@@ -155,7 +242,7 @@ export async function snapshotRepository(workspace, repository, index) {
155
242
  const checkoutId = workspace.machine?.checkoutId ?? sha256Digest(repository.root);
156
243
  return {
157
244
  record: {
158
- repoId: repoId(repository, index),
245
+ repoId: assignedId ?? repoId(repository, index),
159
246
  checkoutId,
160
247
  root: repository.root,
161
248
  head: repository.git.head,
@@ -0,0 +1,296 @@
1
+ import { z } from 'zod';
2
+ import { type Outcome } from '../schemas/outcome.js';
3
+ import { type ContinuityWriteOptions } from './paths.js';
4
+ /**
5
+ * Linked private handoff bundles.
6
+ *
7
+ * A bundle is a separately versioned manifest that *links* one existing durable
8
+ * checkpoint to a collaboration task/attempt and the source native session, and
9
+ * carries the bounded additional handoff snapshot (claims, pending work, next
10
+ * action, recovery). It never duplicates checkpoint content, transfers
11
+ * authority, launches a replacement, archives a session or grants execution.
12
+ * Reading or verifying a bundle is purely advisory: it never returns execution
13
+ * permission or native control. The later rollover orchestrator (E3-B) must
14
+ * independently revalidate current authority, quiescence, ACK and transfer.
15
+ *
16
+ * Bundles are published immutably and exclusively under the existing
17
+ * workspace-private continuity task namespace
18
+ * (`.pappra/local/tasks/<continuityTaskId>/handoff-bundles/<bundleId>.json`),
19
+ * reusing the guarded continuity filesystem helpers. There is no latest
20
+ * pointer, alternate task record or mutable authority store.
21
+ */
22
+ export declare const HANDOFF_BUNDLE_SCHEMA = "pappra/handoff-bundle/1";
23
+ /** Subdirectory holding immutable handoff bundles inside a private task dir. */
24
+ export declare const HANDOFF_BUNDLES_DIRNAME = "handoff-bundles";
25
+ /**
26
+ * Upper bound for a serialized bundle. The manifest only links a checkpoint and
27
+ * carries a bounded snapshot, so it stays well under the shared continuity
28
+ * payload cap; an oversized file is rejected without inspecting its content.
29
+ */
30
+ export declare const HANDOFF_BUNDLE_MAX_BYTES: number;
31
+ /** The bound reference to one existing, schema-valid checkpoint. */
32
+ export declare const handoffCheckpointReferenceSchema: z.ZodObject<{
33
+ checkpointId: z.ZodUUID;
34
+ taskId: z.ZodString;
35
+ workspaceId: z.ZodUUID;
36
+ ref: z.ZodString;
37
+ digest: z.ZodString;
38
+ authorSession: z.ZodNullable<z.ZodString>;
39
+ contextCompleteness: z.ZodEnum<{
40
+ complete: "complete";
41
+ partial: "partial";
42
+ }>;
43
+ }, z.core.$strict>;
44
+ export type HandoffCheckpointReference = z.infer<typeof handoffCheckpointReferenceSchema>;
45
+ /** The collaboration task/attempt/input/owner-epoch this handoff belongs to. */
46
+ export declare const handoffCollaborationBindingSchema: z.ZodObject<{
47
+ taskId: z.ZodString;
48
+ attempt: z.ZodNumber;
49
+ ownerEpoch: z.ZodNumber;
50
+ subtaskId: z.ZodNullable<z.ZodString>;
51
+ inputRevision: z.ZodNullable<z.ZodString>;
52
+ association: z.ZodNullable<z.ZodString>;
53
+ }, z.core.$strict>;
54
+ export type HandoffCollaborationBinding = z.infer<typeof handoffCollaborationBindingSchema>;
55
+ /** The source native session. Model/provider are advisory observations only. */
56
+ export declare const handoffSourceNativeSessionSchema: z.ZodObject<{
57
+ harness: z.ZodEnum<{
58
+ claude: "claude";
59
+ codex: "codex";
60
+ pi: "pi";
61
+ unknown: "unknown";
62
+ }>;
63
+ sessionId: z.ZodString;
64
+ agentId: z.ZodNullable<z.ZodString>;
65
+ paneId: z.ZodNullable<z.ZodString>;
66
+ surface: z.ZodNullable<z.ZodString>;
67
+ configurationId: z.ZodNullable<z.ZodString>;
68
+ modelObservation: z.ZodObject<{
69
+ model: z.ZodNullable<z.ZodString>;
70
+ provider: z.ZodNullable<z.ZodString>;
71
+ reasoning: z.ZodNullable<z.ZodString>;
72
+ }, z.core.$strict>;
73
+ }, z.core.$strict>;
74
+ export type HandoffSourceNativeSession = z.infer<typeof handoffSourceNativeSessionSchema>;
75
+ /** The bounded additional snapshot carried alongside the linked checkpoint. */
76
+ export declare const handoffSnapshotSchema: z.ZodObject<{
77
+ claims: z.ZodArray<z.ZodObject<{
78
+ claimId: z.ZodString;
79
+ resource: z.ZodString;
80
+ resourceEpoch: z.ZodNumber;
81
+ holder: z.ZodNullable<z.ZodString>;
82
+ }, z.core.$strict>>;
83
+ claimsCompleteness: z.ZodEnum<{
84
+ complete: "complete";
85
+ partial: "partial";
86
+ unknown: "unknown";
87
+ }>;
88
+ pendingTools: z.ZodObject<{
89
+ items: z.ZodArray<z.ZodString>;
90
+ completeness: z.ZodEnum<{
91
+ complete: "complete";
92
+ partial: "partial";
93
+ unknown: "unknown";
94
+ }>;
95
+ }, z.core.$strict>;
96
+ pendingMessages: z.ZodObject<{
97
+ items: z.ZodArray<z.ZodString>;
98
+ completeness: z.ZodEnum<{
99
+ complete: "complete";
100
+ partial: "partial";
101
+ unknown: "unknown";
102
+ }>;
103
+ }, z.core.$strict>;
104
+ pendingApprovals: z.ZodObject<{
105
+ items: z.ZodArray<z.ZodString>;
106
+ completeness: z.ZodEnum<{
107
+ complete: "complete";
108
+ partial: "partial";
109
+ unknown: "unknown";
110
+ }>;
111
+ }, z.core.$strict>;
112
+ nextAction: z.ZodString;
113
+ recovery: z.ZodArray<z.ZodString>;
114
+ executionAuthority: z.ZodLiteral<"none">;
115
+ advisory: z.ZodLiteral<true>;
116
+ }, z.core.$strict>;
117
+ export type HandoffSnapshot = z.infer<typeof handoffSnapshotSchema>;
118
+ /** The complete linked handoff bundle manifest. */
119
+ export declare const handoffBundleSchema: z.ZodObject<{
120
+ schema: z.ZodLiteral<"pappra/handoff-bundle/1">;
121
+ bundleId: z.ZodUUID;
122
+ createdAt: z.ZodISODateTime;
123
+ continuityTaskId: z.ZodString;
124
+ checkpoint: z.ZodObject<{
125
+ checkpointId: z.ZodUUID;
126
+ taskId: z.ZodString;
127
+ workspaceId: z.ZodUUID;
128
+ ref: z.ZodString;
129
+ digest: z.ZodString;
130
+ authorSession: z.ZodNullable<z.ZodString>;
131
+ contextCompleteness: z.ZodEnum<{
132
+ complete: "complete";
133
+ partial: "partial";
134
+ }>;
135
+ }, z.core.$strict>;
136
+ collaboration: z.ZodObject<{
137
+ taskId: z.ZodString;
138
+ attempt: z.ZodNumber;
139
+ ownerEpoch: z.ZodNumber;
140
+ subtaskId: z.ZodNullable<z.ZodString>;
141
+ inputRevision: z.ZodNullable<z.ZodString>;
142
+ association: z.ZodNullable<z.ZodString>;
143
+ }, z.core.$strict>;
144
+ sourceNativeSession: z.ZodObject<{
145
+ harness: z.ZodEnum<{
146
+ claude: "claude";
147
+ codex: "codex";
148
+ pi: "pi";
149
+ unknown: "unknown";
150
+ }>;
151
+ sessionId: z.ZodString;
152
+ agentId: z.ZodNullable<z.ZodString>;
153
+ paneId: z.ZodNullable<z.ZodString>;
154
+ surface: z.ZodNullable<z.ZodString>;
155
+ configurationId: z.ZodNullable<z.ZodString>;
156
+ modelObservation: z.ZodObject<{
157
+ model: z.ZodNullable<z.ZodString>;
158
+ provider: z.ZodNullable<z.ZodString>;
159
+ reasoning: z.ZodNullable<z.ZodString>;
160
+ }, z.core.$strict>;
161
+ }, z.core.$strict>;
162
+ handoff: z.ZodObject<{
163
+ claims: z.ZodArray<z.ZodObject<{
164
+ claimId: z.ZodString;
165
+ resource: z.ZodString;
166
+ resourceEpoch: z.ZodNumber;
167
+ holder: z.ZodNullable<z.ZodString>;
168
+ }, z.core.$strict>>;
169
+ claimsCompleteness: z.ZodEnum<{
170
+ complete: "complete";
171
+ partial: "partial";
172
+ unknown: "unknown";
173
+ }>;
174
+ pendingTools: z.ZodObject<{
175
+ items: z.ZodArray<z.ZodString>;
176
+ completeness: z.ZodEnum<{
177
+ complete: "complete";
178
+ partial: "partial";
179
+ unknown: "unknown";
180
+ }>;
181
+ }, z.core.$strict>;
182
+ pendingMessages: z.ZodObject<{
183
+ items: z.ZodArray<z.ZodString>;
184
+ completeness: z.ZodEnum<{
185
+ complete: "complete";
186
+ partial: "partial";
187
+ unknown: "unknown";
188
+ }>;
189
+ }, z.core.$strict>;
190
+ pendingApprovals: z.ZodObject<{
191
+ items: z.ZodArray<z.ZodString>;
192
+ completeness: z.ZodEnum<{
193
+ complete: "complete";
194
+ partial: "partial";
195
+ unknown: "unknown";
196
+ }>;
197
+ }, z.core.$strict>;
198
+ nextAction: z.ZodString;
199
+ recovery: z.ZodArray<z.ZodString>;
200
+ executionAuthority: z.ZodLiteral<"none">;
201
+ advisory: z.ZodLiteral<true>;
202
+ }, z.core.$strict>;
203
+ limitations: z.ZodArray<z.ZodString>;
204
+ notes: z.ZodNullable<z.ZodString>;
205
+ }, z.core.$strict>;
206
+ export type HandoffBundle = z.infer<typeof handoffBundleSchema>;
207
+ export interface SaveHandoffBundleInput {
208
+ readonly root: string;
209
+ readonly continuityTaskId: string;
210
+ readonly checkpoint: HandoffCheckpointReference;
211
+ readonly collaboration: HandoffCollaborationBinding;
212
+ readonly sourceNativeSession: HandoffSourceNativeSession;
213
+ readonly handoff: HandoffSnapshot;
214
+ readonly limitations?: readonly string[];
215
+ readonly notes?: string | null;
216
+ /** Optional explicit id (uuid); a fresh one is generated otherwise. */
217
+ readonly bundleId?: string;
218
+ /** Clock seam; defaults to the wall clock. */
219
+ readonly now?: () => Date;
220
+ /** Fault-injection seam forwarded to the exclusive publish. */
221
+ readonly writeOptions?: ContinuityWriteOptions;
222
+ }
223
+ export interface SaveHandoffBundleResult {
224
+ readonly bundleId: string;
225
+ readonly path: string;
226
+ readonly relativeRef: string;
227
+ readonly digest: string;
228
+ readonly bundle: HandoffBundle;
229
+ }
230
+ export interface ReadHandoffBundleResult {
231
+ readonly bundle: HandoffBundle;
232
+ readonly digest: string;
233
+ readonly path: string;
234
+ }
235
+ export interface HandoffArtifactCheck {
236
+ readonly path: string;
237
+ readonly status: 'unchanged' | 'changed' | 'missing' | 'unsafe' | 'unreadable';
238
+ }
239
+ export interface HandoffCompletenessSummary {
240
+ readonly claims: 'complete' | 'partial' | 'unknown';
241
+ readonly pendingTools: 'complete' | 'partial' | 'unknown';
242
+ readonly pendingMessages: 'complete' | 'partial' | 'unknown';
243
+ readonly pendingApprovals: 'complete' | 'partial' | 'unknown';
244
+ }
245
+ export interface VerifyHandoffBundleResult {
246
+ readonly bundleId: string;
247
+ readonly continuityTaskId: string;
248
+ readonly checkpointPresent: true;
249
+ readonly checkpointDigestMatches: true;
250
+ readonly checkpointSchemaValid: true;
251
+ readonly associationValid: true;
252
+ readonly workspaceIdentityMatches: true;
253
+ readonly checkpointContextCompleteness: 'complete' | 'partial';
254
+ readonly artifactChecks: readonly HandoffArtifactCheck[];
255
+ /**
256
+ * Truthful overall context assessment: 'complete' only when the checkpoint is
257
+ * itself complete and every referenced artifact is unchanged; 'unknown' when
258
+ * an artifact is unsafe or unreadable; otherwise 'incomplete'. A partial
259
+ * checkpoint or a missing/changed artifact is never reported as complete.
260
+ */
261
+ readonly contextIntegrity: 'complete' | 'incomplete' | 'unknown';
262
+ /** Verification never grants execution or native control. */
263
+ readonly executionAllowed: false;
264
+ readonly completeness: HandoffCompletenessSummary;
265
+ }
266
+ export declare function serializeHandoffBundle(bundle: HandoffBundle): Buffer;
267
+ export declare function handoffBundleRelativeRef(bundleId: string): string;
268
+ /** Build and validate a bundle manifest without touching the filesystem. */
269
+ export declare function buildHandoffBundle(input: SaveHandoffBundleInput): Outcome<HandoffBundle>;
270
+ /** Parse untrusted bytes into a validated bundle without leaking content. */
271
+ export declare function parseHandoffBundle(raw: unknown): Outcome<HandoffBundle>;
272
+ /**
273
+ * Validate the referenced checkpoint, then publish the bundle immutably and
274
+ * exclusively. A missing, changed or mismatched checkpoint fails before any
275
+ * write; an existing bundle id is never replaced.
276
+ */
277
+ export declare function saveHandoffBundle(input: SaveHandoffBundleInput): Promise<Outcome<SaveHandoffBundleResult>>;
278
+ /** Read and validate one stored bundle; private content is never leaked. */
279
+ export declare function readHandoffBundle(options: {
280
+ readonly root: string;
281
+ readonly continuityTaskId: string;
282
+ readonly bundleId: string;
283
+ }): Promise<Outcome<ReadHandoffBundleResult>>;
284
+ /**
285
+ * Re-validate a bundle against its referenced checkpoint. Any missing, changed,
286
+ * mismatched or invalid checkpoint fails verification, so a defective bundle is
287
+ * never reported as complete. Success never implies execution authority.
288
+ */
289
+ export declare function verifyHandoffBundle(options: {
290
+ readonly root: string;
291
+ readonly continuityTaskId: string;
292
+ readonly bundleId: string;
293
+ } | {
294
+ readonly root: string;
295
+ readonly bundle: HandoffBundle;
296
+ }): Promise<Outcome<VerifyHandoffBundleResult>>;