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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/README.md +134 -15
  2. package/assets/integrations/skills/pappra/SKILL.md +28 -7
  3. package/assets/integrations/skills/pappra/references/collaboration.md +633 -0
  4. package/assets/integrations/skills/pappra/references/environment.md +360 -0
  5. package/assets/integrations/skills/pappra/references/hosts.md +20 -0
  6. package/assets/integrations/skills/pappra/references/operations.md +36 -5
  7. package/dist/adapters/pi/recovery-extension.d.ts +65 -0
  8. package/dist/adapters/pi/recovery-extension.js +238 -0
  9. package/dist/adapters/pi/session-transition-extension.d.ts +30 -0
  10. package/dist/adapters/pi/session-transition-extension.js +265 -0
  11. package/dist/app/automatic-handoff-events.d.ts +26 -0
  12. package/dist/app/automatic-handoff-events.js +134 -0
  13. package/dist/app/bounded-file.d.ts +2 -0
  14. package/dist/app/bounded-file.js +2 -0
  15. package/dist/app/capability-evidence/claude.d.ts +37 -0
  16. package/dist/app/capability-evidence/claude.js +206 -0
  17. package/dist/app/capability-evidence/codex.d.ts +35 -0
  18. package/dist/app/capability-evidence/codex.js +193 -0
  19. package/dist/app/capability-evidence/index.d.ts +33 -0
  20. package/dist/app/capability-evidence/index.js +117 -0
  21. package/dist/app/capability-evidence/pi.d.ts +73 -0
  22. package/dist/app/capability-evidence/pi.js +669 -0
  23. package/dist/app/capability-evidence/shared.d.ts +69 -0
  24. package/dist/app/capability-evidence/shared.js +195 -0
  25. package/dist/app/collab-auto-handoff.d.ts +55 -0
  26. package/dist/app/collab-auto-handoff.js +384 -0
  27. package/dist/app/collab-bindings.d.ts +57 -0
  28. package/dist/app/collab-bindings.js +1006 -0
  29. package/dist/app/collab-bootstrap-transport.d.ts +163 -0
  30. package/dist/app/collab-bootstrap-transport.js +769 -0
  31. package/dist/app/collab-bootstrap.d.ts +137 -0
  32. package/dist/app/collab-bootstrap.js +3455 -0
  33. package/dist/app/collab-handoff.d.ts +12 -0
  34. package/dist/app/collab-handoff.js +511 -0
  35. package/dist/app/collab-messages.d.ts +2 -0
  36. package/dist/app/collab-messages.js +2 -0
  37. package/dist/app/collab-notify.d.ts +156 -0
  38. package/dist/app/collab-notify.js +1208 -0
  39. package/dist/app/collab-preflight.d.ts +34 -0
  40. package/dist/app/collab-preflight.js +96 -0
  41. package/dist/app/collab-recovery-executor.d.ts +161 -0
  42. package/dist/app/collab-recovery-executor.js +1153 -0
  43. package/dist/app/collab-recovery-projection.d.ts +103 -0
  44. package/dist/app/collab-recovery-projection.js +659 -0
  45. package/dist/app/collab-recovery.d.ts +25 -0
  46. package/dist/app/collab-recovery.js +429 -0
  47. package/dist/app/collab-resources.d.ts +16 -0
  48. package/dist/app/collab-resources.js +278 -0
  49. package/dist/app/collab-role-events.d.ts +22 -0
  50. package/dist/app/collab-role-events.js +329 -0
  51. package/dist/app/collab-role-orchestration.d.ts +53 -0
  52. package/dist/app/collab-role-orchestration.js +601 -0
  53. package/dist/app/collab-role-plan.d.ts +81 -0
  54. package/dist/app/collab-role-plan.js +504 -0
  55. package/dist/app/collab-role-repair.d.ts +109 -0
  56. package/dist/app/collab-role-repair.js +821 -0
  57. package/dist/app/collab-rollover.d.ts +263 -0
  58. package/dist/app/collab-rollover.js +1112 -0
  59. package/dist/app/collab-route.d.ts +64 -0
  60. package/dist/app/collab-route.js +240 -0
  61. package/dist/app/collab-session-transition.d.ts +221 -0
  62. package/dist/app/collab-session-transition.js +3334 -0
  63. package/dist/app/collab-state.d.ts +7 -0
  64. package/dist/app/collab-state.js +162 -0
  65. package/dist/app/collab-task-store.d.ts +22 -0
  66. package/dist/app/collab-task-store.js +204 -0
  67. package/dist/app/collab-work-execution.d.ts +127 -0
  68. package/dist/app/collab-work-execution.js +1027 -0
  69. package/dist/app/collab-work-plan.d.ts +87 -0
  70. package/dist/app/collab-work-plan.js +437 -0
  71. package/dist/app/collaboration.d.ts +8 -2
  72. package/dist/app/collaboration.js +101 -12
  73. package/dist/app/doctor.js +108 -5
  74. package/dist/app/host-mcp.js +34 -8
  75. package/dist/app/host-probe.js +4 -4
  76. package/dist/app/init.d.ts +58 -4
  77. package/dist/app/init.js +768 -155
  78. package/dist/app/managed-pi-bootstrap-admission.d.ts +14 -0
  79. package/dist/app/managed-pi-bootstrap-admission.js +104 -0
  80. package/dist/app/managed-pi-bootstrap-refresh.d.ts +10 -0
  81. package/dist/app/managed-pi-bootstrap-refresh.js +78 -0
  82. package/dist/app/managed-pi-delivery.d.ts +8 -0
  83. package/dist/app/managed-pi-delivery.js +110 -0
  84. package/dist/app/managed-pi-handoff-receiver.d.ts +15 -0
  85. package/dist/app/managed-pi-handoff-receiver.js +263 -0
  86. package/dist/app/managed-pi-handoff-reference.d.ts +3 -0
  87. package/dist/app/managed-pi-handoff-reference.js +60 -0
  88. package/dist/app/managed-pi-herdr.d.ts +21 -0
  89. package/dist/app/managed-pi-herdr.js +185 -0
  90. package/dist/app/managed-pi-initial-admission.d.ts +28 -0
  91. package/dist/app/managed-pi-initial-admission.js +416 -0
  92. package/dist/app/managed-pi-initial-launch.d.ts +5 -0
  93. package/dist/app/managed-pi-initial-launch.js +61 -0
  94. package/dist/app/managed-pi-native-observation.d.ts +36 -0
  95. package/dist/app/managed-pi-native-observation.js +191 -0
  96. package/dist/app/managed-pi-readiness.d.ts +29 -0
  97. package/dist/app/managed-pi-readiness.js +288 -0
  98. package/dist/app/managed-pi-repair-stop.d.ts +21 -0
  99. package/dist/app/managed-pi-repair-stop.js +371 -0
  100. package/dist/app/managed-pi-resume-admission.d.ts +32 -0
  101. package/dist/app/managed-pi-resume-admission.js +618 -0
  102. package/dist/app/managed-pi-retirement.d.ts +28 -0
  103. package/dist/app/managed-pi-retirement.js +112 -0
  104. package/dist/app/managed-pi-sdk-control.d.ts +7 -0
  105. package/dist/app/managed-pi-sdk-control.js +169 -0
  106. package/dist/app/managed-pi-sdk-runtime.d.ts +3 -0
  107. package/dist/app/managed-pi-sdk-runtime.js +483 -0
  108. package/dist/app/managed-pi-source-admission.d.ts +14 -0
  109. package/dist/app/managed-pi-source-admission.js +323 -0
  110. package/dist/app/managed-pi-transition-host.d.ts +36 -0
  111. package/dist/app/managed-pi-transition-host.js +292 -0
  112. package/dist/app/managed-pi.d.ts +54 -0
  113. package/dist/app/managed-pi.js +248 -0
  114. package/dist/app/shell-readiness.d.ts +66 -0
  115. package/dist/app/shell-readiness.js +368 -0
  116. package/dist/app/task-pin.d.ts +2 -23
  117. package/dist/app/task-pin.js +2 -113
  118. package/dist/cli/commands/collaboration-binding.d.ts +13 -0
  119. package/dist/cli/commands/collaboration-binding.js +118 -0
  120. package/dist/cli/commands/collaboration-bootstrap.d.ts +10 -0
  121. package/dist/cli/commands/collaboration-bootstrap.js +84 -0
  122. package/dist/cli/commands/collaboration-capabilities.d.ts +13 -0
  123. package/dist/cli/commands/collaboration-capabilities.js +127 -0
  124. package/dist/cli/commands/collaboration-handoff.d.ts +13 -0
  125. package/dist/cli/commands/collaboration-handoff.js +102 -0
  126. package/dist/cli/commands/collaboration-message.d.ts +17 -0
  127. package/dist/cli/commands/collaboration-message.js +177 -0
  128. package/dist/cli/commands/collaboration-plan.d.ts +8 -0
  129. package/dist/cli/commands/collaboration-plan.js +108 -0
  130. package/dist/cli/commands/collaboration-preflight.d.ts +10 -0
  131. package/dist/cli/commands/collaboration-preflight.js +167 -0
  132. package/dist/cli/commands/collaboration-recovery-run.d.ts +46 -0
  133. package/dist/cli/commands/collaboration-recovery-run.js +224 -0
  134. package/dist/cli/commands/collaboration-recovery.d.ts +11 -0
  135. package/dist/cli/commands/collaboration-recovery.js +104 -0
  136. package/dist/cli/commands/collaboration-resources.d.ts +11 -0
  137. package/dist/cli/commands/collaboration-resources.js +96 -0
  138. package/dist/cli/commands/collaboration-role-plan.d.ts +9 -0
  139. package/dist/cli/commands/collaboration-role-plan.js +69 -0
  140. package/dist/cli/commands/collaboration-role-run.d.ts +11 -0
  141. package/dist/cli/commands/collaboration-role-run.js +128 -0
  142. package/dist/cli/commands/collaboration-rollover.d.ts +10 -0
  143. package/dist/cli/commands/collaboration-rollover.js +103 -0
  144. package/dist/cli/commands/collaboration-state.d.ts +10 -0
  145. package/dist/cli/commands/collaboration-state.js +96 -0
  146. package/dist/cli/commands/collaboration-transition.d.ts +10 -0
  147. package/dist/cli/commands/collaboration-transition.js +75 -0
  148. package/dist/cli/commands/collaboration-work-run.d.ts +34 -0
  149. package/dist/cli/commands/collaboration-work-run.js +178 -0
  150. package/dist/cli/commands/collaboration.d.ts +4 -0
  151. package/dist/cli/commands/collaboration.js +39 -4
  152. package/dist/cli/commands/continuity.js +2 -6
  153. package/dist/cli/commands/docs.d.ts +2 -0
  154. package/dist/cli/commands/docs.js +89 -15
  155. package/dist/cli/commands/host.d.ts +7 -1
  156. package/dist/cli/commands/host.js +122 -7
  157. package/dist/cli/commands/init.d.ts +20 -3
  158. package/dist/cli/commands/init.js +897 -232
  159. package/dist/cli/commands/mcp.d.ts +1 -0
  160. package/dist/cli/commands/mcp.js +11 -5
  161. package/dist/cli/commands/repair.d.ts +12 -0
  162. package/dist/cli/commands/repair.js +41 -0
  163. package/dist/cli/commands/runtime.d.ts +1 -1
  164. package/dist/cli/commands/runtime.js +139 -38
  165. package/dist/cli/commands/session.d.ts +7 -0
  166. package/dist/cli/commands/session.js +82 -0
  167. package/dist/cli/commands/task.js +19 -5
  168. package/dist/cli/run.js +866 -24
  169. package/dist/code/identity.d.ts +7 -0
  170. package/dist/code/identity.js +7 -3
  171. package/dist/code/registration.js +7 -0
  172. package/dist/code/service.d.ts +9 -0
  173. package/dist/code/service.js +16 -3
  174. package/dist/code/text.js +19 -7
  175. package/dist/collab/admission.d.ts +91 -66
  176. package/dist/collab/admission.js +21 -6
  177. package/dist/collab/canonical.d.ts +1 -1
  178. package/dist/collab/canonical.js +44 -3
  179. package/dist/collab/envelope.d.ts +2 -2
  180. package/dist/collab/envelope.js +12 -12
  181. package/dist/collab/first-work.d.ts +3 -0
  182. package/dist/collab/first-work.js +15 -0
  183. package/dist/collab/handoff.d.ts +16 -0
  184. package/dist/collab/handoff.js +39 -5
  185. package/dist/collab/index.d.ts +97 -1
  186. package/dist/collab/index.js +9 -1
  187. package/dist/collab/messages.js +126 -3
  188. package/dist/collab/persisted-messages.d.ts +123 -0
  189. package/dist/collab/persisted-messages.js +496 -0
  190. package/dist/collab/preflight.d.ts +1 -1
  191. package/dist/collab/resources.d.ts +13 -3
  192. package/dist/collab/resources.js +37 -6
  193. package/dist/collab/rollover.d.ts +311 -0
  194. package/dist/collab/rollover.js +1024 -0
  195. package/dist/collab/store.d.ts +1 -0
  196. package/dist/collab/store.js +1 -4
  197. package/dist/collab/types.d.ts +2 -354
  198. package/dist/collab/validation.d.ts +2 -10
  199. package/dist/collab/validation.js +2 -303
  200. package/dist/collab/work-plan.d.ts +105 -0
  201. package/dist/collab/work-plan.js +843 -0
  202. package/dist/continuity/context.d.ts +11 -2
  203. package/dist/continuity/context.js +100 -13
  204. package/dist/continuity/handoff-bundle.d.ts +296 -0
  205. package/dist/continuity/handoff-bundle.js +477 -0
  206. package/dist/continuity/index.d.ts +2 -0
  207. package/dist/continuity/index.js +1 -0
  208. package/dist/continuity/paths.js +10 -2
  209. package/dist/continuity/service.js +91 -15
  210. package/dist/continuity/task-pin.d.ts +24 -0
  211. package/dist/continuity/task-pin.js +590 -0
  212. package/dist/doctor.d.ts +1 -0
  213. package/dist/doctor.js +6 -0
  214. package/dist/experimental/index.d.ts +13 -0
  215. package/dist/experimental/index.js +25 -0
  216. package/dist/experimental/pi.d.ts +4 -0
  217. package/dist/experimental/pi.js +12 -0
  218. package/dist/hosts/claude/native.js +1 -1
  219. package/dist/hosts/codex/native.js +1 -1
  220. package/dist/hosts/codex/protocol.js +1 -1
  221. package/dist/hosts/integration/bootstrap-config.d.ts +58 -0
  222. package/dist/hosts/integration/bootstrap-config.js +254 -0
  223. package/dist/hosts/integration/bundle-export.d.ts +44 -0
  224. package/dist/hosts/integration/bundle-export.js +366 -3
  225. package/dist/hosts/integration/bundle.js +3 -0
  226. package/dist/hosts/integration/hook.js +36 -9
  227. package/dist/hosts/integration/pappra-bootstrap-extension.mjs +80 -0
  228. package/dist/hosts/integration/pappra-extension-runtime.mjs +59 -24631
  229. package/dist/hosts/integration/pappra-hook.mjs +61 -24749
  230. package/dist/hosts/integration/pappra-recovery-extension.mjs +259 -0
  231. package/dist/hosts/integration/pappra-session-transition-extension.mjs +276 -0
  232. package/dist/hosts/integration/pi-bootstrap-extension.d.ts +36 -0
  233. package/dist/hosts/integration/pi-bootstrap-extension.js +101 -0
  234. package/dist/hosts/integration/pi-bootstrap-guard.d.ts +125 -0
  235. package/dist/hosts/integration/pi-bootstrap-guard.js +438 -0
  236. package/dist/hosts/integration/pi-bootstrap-runtime.d.ts +63 -0
  237. package/dist/hosts/integration/pi-bootstrap-runtime.js +223 -0
  238. package/dist/hosts/integration/pi-native-events.d.ts +112 -0
  239. package/dist/hosts/integration/pi-native-events.js +348 -0
  240. package/dist/hosts/integration/pi-rollover-extension.d.ts +166 -0
  241. package/dist/hosts/integration/pi-rollover-extension.js +431 -0
  242. package/dist/hosts/integration/recovery-config.d.ts +48 -0
  243. package/dist/hosts/integration/recovery-config.js +117 -0
  244. package/dist/hosts/integration/service.d.ts +6 -1
  245. package/dist/hosts/integration/service.js +485 -35
  246. package/dist/hosts/integration/support.d.ts +7 -0
  247. package/dist/hosts/integration/support.js +9 -1
  248. package/dist/hosts/integration/templates.d.ts +3 -0
  249. package/dist/hosts/integration/templates.js +26 -3
  250. package/dist/hosts/pi/managed-host-identity.d.ts +2 -0
  251. package/dist/hosts/pi/managed-host-identity.js +40 -0
  252. package/dist/hosts/pi/managed-provider-diagnostics.d.ts +6 -0
  253. package/dist/hosts/pi/managed-provider-diagnostics.js +184 -0
  254. package/dist/hosts/pi/managed-sdk-session.d.ts +335 -0
  255. package/dist/hosts/pi/managed-sdk-session.js +1639 -0
  256. package/dist/hosts/pi/managed-session-extension.d.ts +20 -0
  257. package/dist/hosts/pi/managed-session-extension.js +84 -0
  258. package/dist/hosts/pi/managed-session.d.ts +177 -0
  259. package/dist/hosts/pi/managed-session.js +1557 -0
  260. package/dist/hosts/pi/protocol.js +1 -1
  261. package/dist/hosts/pi/query-result.js +1 -1
  262. package/dist/hosts/pi/resume-capability.d.ts +41 -0
  263. package/dist/hosts/pi/resume-capability.js +33 -0
  264. package/dist/hosts/pi/rpc.d.ts +182 -134
  265. package/dist/hosts/pi/rpc.js +230 -37
  266. package/dist/hosts/pilot.d.ts +97 -74
  267. package/dist/hosts/pilot.js +5 -1
  268. package/dist/hosts/version.d.ts +3 -0
  269. package/dist/hosts/version.js +18 -0
  270. package/dist/index.d.ts +0 -1
  271. package/dist/index.js +0 -1
  272. package/dist/infra/bounded-file.d.ts +19 -0
  273. package/dist/infra/bounded-file.js +66 -0
  274. package/dist/infra/fs.js +10 -2
  275. package/dist/infra/git.d.ts +29 -0
  276. package/dist/infra/git.js +45 -9
  277. package/dist/infra/json-property.d.ts +2 -0
  278. package/dist/infra/json-property.js +69 -0
  279. package/dist/infra/json.d.ts +4 -0
  280. package/dist/infra/json.js +24 -0
  281. package/dist/infra/owned-process-group.js +1 -1
  282. package/dist/infra/private-lock.d.ts +16 -0
  283. package/dist/infra/private-lock.js +148 -0
  284. package/dist/infra/private-state.d.ts +7 -0
  285. package/dist/infra/private-state.js +146 -0
  286. package/dist/infra/process-identity.d.ts +12 -0
  287. package/dist/infra/process-identity.js +142 -0
  288. package/dist/infra/validation.d.ts +5 -0
  289. package/dist/infra/validation.js +15 -0
  290. package/dist/init.d.ts +1 -0
  291. package/dist/init.js +6 -0
  292. package/dist/install/apply.d.ts +9 -1
  293. package/dist/install/apply.js +176 -12
  294. package/dist/install/dependencies.d.ts +38 -0
  295. package/dist/install/dependencies.js +282 -0
  296. package/dist/install/ownership.js +30 -1
  297. package/dist/install/references.d.ts +31 -0
  298. package/dist/install/references.js +208 -0
  299. package/dist/install/repair.d.ts +37 -0
  300. package/dist/install/repair.js +798 -0
  301. package/dist/install/reset-local.d.ts +16 -0
  302. package/dist/install/reset-local.js +304 -0
  303. package/dist/install/rollback.d.ts +3 -0
  304. package/dist/install/rollback.js +9 -3
  305. package/dist/install/runtime.d.ts +10 -6
  306. package/dist/install/runtime.js +299 -59
  307. package/dist/install/source-fingerprint.d.ts +2 -0
  308. package/dist/install/source-fingerprint.js +103 -0
  309. package/dist/knowledge/catalog.d.ts +1 -0
  310. package/dist/knowledge/catalog.js +143 -10
  311. package/dist/knowledge/journal.js +17 -7
  312. package/dist/knowledge/paths.js +2 -1
  313. package/dist/knowledge/refs.js +4 -0
  314. package/dist/knowledge/register-batch.d.ts +4 -0
  315. package/dist/knowledge/register-batch.js +225 -0
  316. package/dist/knowledge/relocate.d.ts +5 -0
  317. package/dist/knowledge/relocate.js +92 -0
  318. package/dist/knowledge/scan.js +103 -47
  319. package/dist/knowledge/service.d.ts +3 -0
  320. package/dist/knowledge/service.js +33 -1
  321. package/dist/knowledge/write.d.ts +4 -1
  322. package/dist/knowledge/write.js +1 -1
  323. package/dist/mcp/server.d.ts +4 -2
  324. package/dist/mcp/server.js +87 -136
  325. package/dist/schemas/collaboration-state-validation.d.ts +6 -0
  326. package/dist/schemas/collaboration-state-validation.js +342 -0
  327. package/dist/schemas/collaboration-state.d.ts +436 -0
  328. package/dist/schemas/collaboration-state.js +1 -0
  329. package/dist/schemas/collaboration.d.ts +335 -0
  330. package/dist/schemas/collaboration.js +272 -0
  331. package/dist/schemas/continuity.d.ts +8 -0
  332. package/dist/schemas/continuity.js +13 -3
  333. package/dist/schemas/doctor.d.ts +1 -0
  334. package/dist/schemas/doctor.js +1 -0
  335. package/dist/schemas/document.d.ts +61 -0
  336. package/dist/schemas/document.js +9 -0
  337. package/dist/schemas/errors.d.ts +1 -0
  338. package/dist/schemas/errors.js +1 -0
  339. package/dist/schemas/host.d.ts +24 -0
  340. package/dist/schemas/host.js +19 -0
  341. package/dist/schemas/install.d.ts +8 -2
  342. package/dist/schemas/install.js +11 -1
  343. package/dist/schemas/managed-pi-execution.d.ts +16 -0
  344. package/dist/schemas/managed-pi-execution.js +2 -0
  345. package/dist/schemas/outcome.d.ts +9 -5
  346. package/dist/workspace/config-file.js +1 -3
  347. package/dist/workspace/documents.js +12 -2
  348. package/dist/workspace/repositories.d.ts +7 -0
  349. package/dist/workspace/repositories.js +14 -5
  350. package/package.json +35 -35
  351. package/skills/pappra/SKILL.md +28 -7
  352. package/skills/pappra/references/collaboration.md +633 -0
  353. package/skills/pappra/references/environment.md +360 -0
  354. package/skills/pappra/references/hosts.md +20 -0
  355. package/skills/pappra/references/operations.md +36 -5
  356. package/dist/app/collab-from.d.ts +0 -35
  357. package/dist/app/collab-from.js +0 -84
@@ -0,0 +1,12 @@
1
+ import { type CollaborationHandoffRequest } from '../schemas/collaboration.js';
2
+ import { type TaskStoreResult } from './collab-task-store.js';
3
+ export declare const COLLAB_HANDOFF_SCHEMA = "pappra/collaboration-handoff/1";
4
+ export type HandoffAction = 'begin' | 'stopped' | 'rebind' | 'transfer' | 'confirm' | 'complete' | 'abort' | 'release-dispatch';
5
+ export interface LoadedHandoffRequest {
6
+ readonly request: CollaborationHandoffRequest;
7
+ readonly path: string;
8
+ }
9
+ export declare function loadHandoffRequest(file: string, expectedAction: HandoffAction): TaskStoreResult<LoadedHandoffRequest>;
10
+ export declare function planHandoffRequest(taskRoot: string, request: CollaborationHandoffRequest): Promise<TaskStoreResult<Record<string, unknown>>>;
11
+ export declare function applyHandoffRequest(taskRoot: string, request: CollaborationHandoffRequest): Promise<TaskStoreResult<Record<string, unknown>>>;
12
+ export declare function readHandoffInventory(taskRoot: string, subtaskId: string | null, attempt: number | null): Promise<TaskStoreResult<Record<string, unknown>>>;
@@ -0,0 +1,511 @@
1
+ import path from 'node:path';
2
+ import { collaborationHandoffRequestSchema, } from '../schemas/collaboration.js';
3
+ import { contentDigest } from '../collab/envelope.js';
4
+ import { abortHandoff, beginHandoff, completeHandoff, confirmReceiver, findHandoff, handoffInventory, markOldWriterStopped, markTransferring, rebindReceiver, releaseDispatchFreeze, } from '../collab/handoff.js';
5
+ import { checkOwnerEpoch } from '../collab/lifecycle.js';
6
+ import { transact } from '../collab/store.js';
7
+ import { readRegisteredMessageSafe, } from './collab-messages.js';
8
+ import { assertTaskStoreCurrent, openTaskStore, } from './collab-task-store.js';
9
+ import { readBoundedFile } from './bounded-file.js';
10
+ export const COLLAB_HANDOFF_SCHEMA = 'pappra/collaboration-handoff/1';
11
+ const MAX_REQUEST_BYTES = 1024 * 1024;
12
+ const MAX_INVENTORY_ROWS = 50;
13
+ const ACCEPTED_MESSAGE_STATES = new Set(['applied', 'recorded']);
14
+ function invalidRequest(message, nextAction) {
15
+ return {
16
+ ok: false,
17
+ code: 'invalid_request',
18
+ message,
19
+ nextAction,
20
+ };
21
+ }
22
+ export function loadHandoffRequest(file, expectedAction) {
23
+ if (!path.isAbsolute(file)) {
24
+ return invalidRequest('Handoff request path must be absolute.', 'Pass an absolute request JSON path.');
25
+ }
26
+ const read = readBoundedFile(file, MAX_REQUEST_BYTES);
27
+ if (!read.ok) {
28
+ return invalidRequest('Handoff request must be a readable regular JSON file no larger than 1 MiB.', 'Inspect the request path and file kind; nothing was written.');
29
+ }
30
+ let parsed;
31
+ try {
32
+ parsed = JSON.parse(read.text);
33
+ }
34
+ catch {
35
+ return invalidRequest('Handoff request is not valid JSON.', 'Rewrite the request as strict JSON; nothing was written.');
36
+ }
37
+ const validated = collaborationHandoffRequestSchema.safeParse(parsed);
38
+ if (!validated.success) {
39
+ const issues = validated.error.issues
40
+ .slice(0, 8)
41
+ .map((issue) => {
42
+ const field = issue.path.length ? issue.path.join('.') : '(root)';
43
+ return `${field}:${issue.code}`;
44
+ })
45
+ .join(', ');
46
+ return invalidRequest(`Handoff request does not match the strict schema (${issues || 'invalid shape'}).`, 'Fix the request schema; nothing was written.');
47
+ }
48
+ const request = validated.data;
49
+ if (request.action !== expectedAction) {
50
+ return invalidRequest('Handoff request action does not match the invoked handoff command.', `Use a ${expectedAction} request; nothing was written.`);
51
+ }
52
+ if (request.action === 'begin' &&
53
+ request.kind === 'writer' &&
54
+ (!request.subtask_id || !request.attempt)) {
55
+ return invalidRequest('A writer handoff begin request requires subtask_id and attempt.', 'Identify the writer attempt being handed over; nothing was written.');
56
+ }
57
+ return { ok: true, value: { request, path: file } };
58
+ }
59
+ function identity(value) {
60
+ return {
61
+ agent_id: value.agent_id,
62
+ session_id: value.session_id,
63
+ harness: value.harness ?? null,
64
+ };
65
+ }
66
+ function requestSummary(request) {
67
+ const common = {
68
+ actor: request.actor,
69
+ owner_epoch: request.owner_epoch,
70
+ ...(request.expect_revision === undefined
71
+ ? {}
72
+ : { expect_revision: request.expect_revision }),
73
+ };
74
+ switch (request.action) {
75
+ case 'begin':
76
+ return {
77
+ ...common,
78
+ action: request.action,
79
+ handoff_id: request.handoff_id,
80
+ kind: request.kind,
81
+ from: identity(request.from),
82
+ to: identity(request.to),
83
+ resource_count: request.resources?.length ?? 0,
84
+ subtask_id: request.subtask_id ?? null,
85
+ attempt: request.attempt ?? null,
86
+ };
87
+ case 'stopped':
88
+ return {
89
+ ...common,
90
+ action: request.action,
91
+ handoff_id: request.handoff_id,
92
+ observation: request.observation,
93
+ evidence_ref: request.evidence_ref,
94
+ };
95
+ case 'rebind':
96
+ return {
97
+ ...common,
98
+ action: request.action,
99
+ handoff_id: request.handoff_id,
100
+ to: identity(request.to),
101
+ evidence_ref: request.evidence_ref,
102
+ };
103
+ case 'transfer':
104
+ return {
105
+ ...common,
106
+ action: request.action,
107
+ handoff_id: request.handoff_id,
108
+ partial_outputs: request.partial_outputs?.length ?? 0,
109
+ inflight: request.inflight?.length ?? 0,
110
+ pending_approvals: request.pending_approvals?.length ?? 0,
111
+ };
112
+ case 'confirm':
113
+ return {
114
+ ...common,
115
+ action: request.action,
116
+ handoff_id: request.handoff_id,
117
+ confirmation_message_id: request.confirmation_message_id,
118
+ };
119
+ case 'complete':
120
+ return {
121
+ ...common,
122
+ action: request.action,
123
+ handoff_id: request.handoff_id,
124
+ };
125
+ case 'abort':
126
+ return {
127
+ ...common,
128
+ action: request.action,
129
+ handoff_id: request.handoff_id,
130
+ };
131
+ case 'release-dispatch':
132
+ return { ...common, action: request.action };
133
+ }
134
+ }
135
+ function identityMatches(actual, expected) {
136
+ if (!actual || !expected)
137
+ return false;
138
+ if (actual.agent_id !== expected.agent_id ||
139
+ actual.session_id !== expected.session_id)
140
+ return false;
141
+ if (expected.harness !== null && actual.harness !== expected.harness)
142
+ return false;
143
+ return true;
144
+ }
145
+ /**
146
+ * Additional public boundary checks for a receiver confirmation. Core
147
+ * confirmReceiver still validates type/from and advances the sequence; this
148
+ * function requires the message to be stored as an accepted/recorded protocol
149
+ * entry and explicitly correlated to this handoff.
150
+ */
151
+ function validateConfirmation(record, message, request) {
152
+ const entry = findHandoff(record, request.handoff_id);
153
+ if (!entry)
154
+ return {
155
+ ok: false,
156
+ code: 'confirmation_handoff_unknown',
157
+ message: 'The handoff is not present in the task record.',
158
+ nextAction: 'Read the handoff inventory; nothing was transferred.',
159
+ };
160
+ if (message.task_id !== record.task_id)
161
+ return {
162
+ ok: false,
163
+ code: 'confirmation_task_mismatch',
164
+ message: 'The confirmation message belongs to another task.',
165
+ nextAction: 'Use a confirmation registered for this task; nothing was transferred.',
166
+ };
167
+ if (!['ACK', 'HANDOFF'].includes(message.type))
168
+ return {
169
+ ok: false,
170
+ code: 'confirmation_type_invalid',
171
+ message: 'The confirmation must be an ACK or HANDOFF message.',
172
+ nextAction: 'Register an explicit receiver confirmation; nothing was transferred.',
173
+ };
174
+ if (message.type === 'HANDOFF' &&
175
+ (typeof message.body?.phase !== 'string' ||
176
+ message.body.phase === 'request'))
177
+ return {
178
+ ok: false,
179
+ code: 'confirmation_phase_invalid',
180
+ message: 'A HANDOFF confirmation must use a non-request phase.',
181
+ nextAction: 'Use a HANDOFF confirmation phase such as confirmation; nothing was transferred.',
182
+ };
183
+ const bodyHandoffId = message.body?.handoff_id;
184
+ if (bodyHandoffId !== undefined &&
185
+ bodyHandoffId !== null &&
186
+ bodyHandoffId !== request.handoff_id)
187
+ return {
188
+ ok: false,
189
+ code: 'confirmation_handoff_mismatch',
190
+ message: 'The confirmation references a different handoff.',
191
+ nextAction: 'Use a confirmation for this handoff; nothing was transferred.',
192
+ };
193
+ if ((bodyHandoffId === undefined || bodyHandoffId === null) &&
194
+ message.reply_to !== request.handoff_id)
195
+ return {
196
+ ok: false,
197
+ code: 'confirmation_correlation_missing',
198
+ message: 'The confirmation does not explicitly reference this handoff.',
199
+ nextAction: 'Set body.handoff_id or reply_to to the handoff id; nothing was transferred.',
200
+ };
201
+ if (!identityMatches(message.from, entry.to))
202
+ return {
203
+ ok: false,
204
+ code: 'confirmation_identity_mismatch',
205
+ message: 'The confirmation sender is not the handoff receiver.',
206
+ nextAction: 'Use the receiver identity; nothing was transferred.',
207
+ };
208
+ const coordinator = record.coordinator ?? null;
209
+ if (!identityMatches(message.to, coordinator))
210
+ return {
211
+ ok: false,
212
+ code: 'confirmation_recipient_mismatch',
213
+ message: 'The confirmation is not addressed to the current coordinator.',
214
+ nextAction: 'Use the current coordinator recipient; nothing was transferred.',
215
+ };
216
+ if (message.owner_epoch === null ||
217
+ message.owner_epoch === undefined ||
218
+ message.owner_epoch !== request.owner_epoch ||
219
+ record.coordinator?.owner_epoch !== request.owner_epoch)
220
+ return {
221
+ ok: false,
222
+ code: 'confirmation_epoch_mismatch',
223
+ message: 'The confirmation does not carry the current owner epoch.',
224
+ nextAction: 'Use a confirmation from the current epoch; nothing was transferred.',
225
+ };
226
+ const recorded = (record.messages ?? []).find((item) => item.message_id === message.message_id);
227
+ if (!recorded || !ACCEPTED_MESSAGE_STATES.has(recorded.state))
228
+ return {
229
+ ok: false,
230
+ code: 'confirmation_not_recorded',
231
+ message: 'The confirmation is not an accepted/recorded protocol entry.',
232
+ nextAction: 'Register and apply the confirmation through the product message route first.',
233
+ };
234
+ if (recorded.type !== message.type ||
235
+ recorded.content_digest !== contentDigest(message))
236
+ return {
237
+ ok: false,
238
+ code: 'confirmation_not_recorded',
239
+ message: 'The confirmation file does not match its stored protocol entry.',
240
+ nextAction: 'Re-register the exact confirmation; nothing was transferred.',
241
+ };
242
+ return null;
243
+ }
244
+ function asTransactionFailure(failure) {
245
+ return {
246
+ ok: false,
247
+ reason: failure.code,
248
+ code: failure.code,
249
+ message: failure.message,
250
+ nextAction: failure.nextAction,
251
+ };
252
+ }
253
+ function applyPrimitive(record, request, confirmation) {
254
+ switch (request.action) {
255
+ case 'begin':
256
+ return beginHandoff(record, {
257
+ handoffId: request.handoff_id,
258
+ kind: request.kind,
259
+ subtaskId: request.subtask_id ?? null,
260
+ attempt: request.attempt ?? null,
261
+ from: identity(request.from),
262
+ to: identity(request.to),
263
+ resources: request.resources ?? [],
264
+ ownerEpoch: request.owner_epoch,
265
+ reason: request.reason ?? null,
266
+ });
267
+ case 'stopped':
268
+ return markOldWriterStopped(record, {
269
+ handoffId: request.handoff_id,
270
+ observation: request.observation,
271
+ evidenceRef: request.evidence_ref,
272
+ detail: request.detail ?? null,
273
+ actor: request.actor,
274
+ });
275
+ case 'rebind':
276
+ return rebindReceiver(record, {
277
+ handoffId: request.handoff_id,
278
+ to: identity(request.to),
279
+ evidenceRef: request.evidence_ref,
280
+ actor: request.actor,
281
+ });
282
+ case 'transfer':
283
+ return markTransferring(record, {
284
+ handoffId: request.handoff_id,
285
+ partialOutputs: request.partial_outputs ?? [],
286
+ inflight: request.inflight ?? [],
287
+ pendingApprovals: request.pending_approvals ?? [],
288
+ actor: request.actor,
289
+ });
290
+ case 'confirm':
291
+ if (!confirmation)
292
+ return {
293
+ ok: false,
294
+ reason: 'confirmation_message_required',
295
+ };
296
+ return confirmReceiver(record, {
297
+ handoffId: request.handoff_id,
298
+ message: confirmation,
299
+ });
300
+ case 'complete':
301
+ return completeHandoff(record, {
302
+ handoffId: request.handoff_id,
303
+ actor: request.actor,
304
+ });
305
+ case 'abort':
306
+ return abortHandoff(record, {
307
+ handoffId: request.handoff_id,
308
+ actor: request.actor,
309
+ ...(request.reason === undefined || request.reason === null
310
+ ? {}
311
+ : { reason: request.reason }),
312
+ });
313
+ case 'release-dispatch':
314
+ return releaseDispatchFreeze(record, {
315
+ actor: request.actor,
316
+ ownerEpoch: request.owner_epoch,
317
+ });
318
+ }
319
+ }
320
+ export async function planHandoffRequest(taskRoot, request) {
321
+ const opened = await openTaskStore(taskRoot);
322
+ if (!opened.ok)
323
+ return opened;
324
+ return {
325
+ ok: true,
326
+ value: {
327
+ schema: COLLAB_HANDOFF_SCHEMA,
328
+ ok: true,
329
+ action: request.action,
330
+ applied: false,
331
+ status: 'planned',
332
+ task_root: opened.value.taskRoot,
333
+ task_id: opened.value.record.task_id,
334
+ request: requestSummary(request),
335
+ limits: ['plan_validates_request_and_namespace_only', 'no_reservation'],
336
+ },
337
+ };
338
+ }
339
+ export async function applyHandoffRequest(taskRoot, request) {
340
+ const opened = await openTaskStore(taskRoot);
341
+ if (!opened.ok)
342
+ return opened;
343
+ let confirmation = null;
344
+ let current = opened.value;
345
+ if (request.action === 'confirm') {
346
+ const loaded = await readRegisteredMessageSafe(current, request.confirmation_message_id);
347
+ if (!loaded.ok)
348
+ return loaded;
349
+ confirmation = loaded.value.message;
350
+ const boundary = validateConfirmation(current.record, confirmation, request);
351
+ if (boundary)
352
+ return boundary;
353
+ }
354
+ const changed = await assertTaskStoreCurrent(current);
355
+ if (changed !== null)
356
+ return changed;
357
+ if (request.action === 'confirm') {
358
+ const fresh = await openTaskStore(taskRoot);
359
+ if (!fresh.ok)
360
+ return fresh;
361
+ current = fresh.value;
362
+ const loaded = await readRegisteredMessageSafe(current, request.confirmation_message_id);
363
+ if (!loaded.ok)
364
+ return loaded;
365
+ confirmation = loaded.value.message;
366
+ const boundary = validateConfirmation(current.record, confirmation, request);
367
+ if (boundary)
368
+ return boundary;
369
+ }
370
+ let outcome;
371
+ try {
372
+ outcome = transact(current.taskRoot, {
373
+ actor: request.actor,
374
+ purpose: `handoff:${request.action}`,
375
+ expectRevision: request.expect_revision,
376
+ apply: (record) => {
377
+ const epoch = checkOwnerEpoch(record, request.owner_epoch);
378
+ if (!epoch.ok)
379
+ return {
380
+ ok: false,
381
+ reason: 'stale_epoch',
382
+ expected: epoch.expected,
383
+ actual: epoch.actual,
384
+ };
385
+ if (request.action === 'confirm') {
386
+ const boundary = validateConfirmation(record, confirmation, request);
387
+ if (boundary)
388
+ return asTransactionFailure(boundary);
389
+ }
390
+ const result = applyPrimitive(record, request, confirmation);
391
+ if (!result.ok)
392
+ return result;
393
+ return {
394
+ record,
395
+ op: `handoff:${request.action}`,
396
+ summary: {
397
+ handoff_id: 'handoff_id' in request ? request.handoff_id : null,
398
+ },
399
+ result,
400
+ };
401
+ },
402
+ });
403
+ }
404
+ catch {
405
+ return {
406
+ ok: false,
407
+ code: 'handoff_operation_failed',
408
+ message: 'The handoff operation could not be completed.',
409
+ nextAction: 'Inspect the task and handoff state; no transfer is promised.',
410
+ };
411
+ }
412
+ const { state_revision, result, ...rest } = outcome;
413
+ return {
414
+ ok: true,
415
+ value: {
416
+ schema: COLLAB_HANDOFF_SCHEMA,
417
+ ok: outcome.ok === true,
418
+ action: request.action,
419
+ applied: outcome.ok === true,
420
+ status: outcome.ok === true ? 'applied' : 'refused',
421
+ task_root: current.taskRoot,
422
+ task_id: current.record.task_id,
423
+ ...(outcome.ok === true
424
+ ? { state_revision, result: result ?? null }
425
+ : rest),
426
+ limits: ['cooperative_record_mutation_only', 'no_native_control'],
427
+ },
428
+ };
429
+ }
430
+ function bounded(items) {
431
+ return {
432
+ rows: items.slice(0, MAX_INVENTORY_ROWS),
433
+ total: items.length,
434
+ omitted: Math.max(0, items.length - MAX_INVENTORY_ROWS),
435
+ truncated: items.length > MAX_INVENTORY_ROWS,
436
+ };
437
+ }
438
+ export async function readHandoffInventory(taskRoot, subtaskId, attempt) {
439
+ const opened = await openTaskStore(taskRoot);
440
+ if (!opened.ok)
441
+ return opened;
442
+ const inventory = handoffInventory(opened.value.record, {
443
+ subtaskId,
444
+ attempt,
445
+ });
446
+ const inflight = bounded(inventory.inflight.map((item) => ({
447
+ subtask_id: item.subtask_id,
448
+ attempt: item.attempt,
449
+ state: item.state,
450
+ })));
451
+ const closed = bounded(inventory.closed);
452
+ const approvals = bounded(inventory.pending_approvals);
453
+ const uncertainty = bounded(inventory.uncertainty);
454
+ const resources = bounded(inventory.resources);
455
+ const results = bounded(inventory.results.map((item) => ({
456
+ subtask_id: item.subtask_id,
457
+ attempt: item.attempt,
458
+ status: item.status,
459
+ classification: item.classification,
460
+ message_id: item.message_id,
461
+ output_count: Array.isArray(item.outputs) ? item.outputs.length : 0,
462
+ })));
463
+ const handoffs = bounded(inventory.handoffs);
464
+ return {
465
+ ok: true,
466
+ value: {
467
+ schema: COLLAB_HANDOFF_SCHEMA,
468
+ ok: true,
469
+ action: 'inventory',
470
+ task_root: opened.value.taskRoot,
471
+ task_id: opened.value.record.task_id,
472
+ subtask_id: subtaskId,
473
+ attempt,
474
+ coordinator: inventory.coordinator,
475
+ epoch_semantics: inventory.epoch_semantics,
476
+ inflight: inflight.rows,
477
+ closed: closed.rows,
478
+ pending_approvals: approvals.rows,
479
+ uncertainty: uncertainty.rows,
480
+ resources: resources.rows,
481
+ results: results.rows,
482
+ handoffs: handoffs.rows,
483
+ counts: {
484
+ inflight: inflight.total,
485
+ closed: closed.total,
486
+ pending_approvals: approvals.total,
487
+ uncertainty: uncertainty.total,
488
+ resources: resources.total,
489
+ results: results.total,
490
+ handoffs: handoffs.total,
491
+ },
492
+ omitted: {
493
+ inflight: inflight.omitted,
494
+ closed: closed.omitted,
495
+ pending_approvals: approvals.omitted,
496
+ uncertainty: uncertainty.omitted,
497
+ resources: resources.omitted,
498
+ results: results.omitted,
499
+ handoffs: handoffs.omitted,
500
+ },
501
+ truncated: inflight.truncated ||
502
+ closed.truncated ||
503
+ approvals.truncated ||
504
+ uncertainty.truncated ||
505
+ resources.truncated ||
506
+ results.truncated ||
507
+ handoffs.truncated,
508
+ limits: ['stored_state_only', 'no_native_query', 'no_message_bodies'],
509
+ },
510
+ };
511
+ }
@@ -0,0 +1,2 @@
1
+ /** Persisted protocol operations are independent of application orchestration. */
2
+ export * from '../collab/persisted-messages.js';
@@ -0,0 +1,2 @@
1
+ /** Persisted protocol operations are independent of application orchestration. */
2
+ export * from '../collab/persisted-messages.js';
@@ -0,0 +1,156 @@
1
+ import { type CollabDeliveryStatus } from '../schemas/collaboration.js';
2
+ import { type MessageServiceResult } from './collab-messages.js';
3
+ export interface HerdrAgentObservation {
4
+ readonly nativeIdentityProvenance?: 'owned-pi-sdk-control';
5
+ readonly name: string | null;
6
+ readonly harness: string;
7
+ readonly paneId: string | null;
8
+ readonly cwd: string | null;
9
+ /** Native session evidence as reported by Herdr; often a session file path. */
10
+ readonly sessionValue: string | null;
11
+ /** Reported session kind (`path`, `id`, ...); null when Herdr reports none. */
12
+ readonly sessionKind: string | null;
13
+ readonly status: string;
14
+ readonly focused: boolean;
15
+ }
16
+ export interface HerdrCallerObservation {
17
+ readonly nativeIdentityProvenance?: 'owned-pi-sdk-control';
18
+ readonly paneId: string;
19
+ readonly workspaceId: string | null;
20
+ readonly tabId: string | null;
21
+ readonly harness: string | null;
22
+ readonly cwd: string | null;
23
+ readonly sessionKind: string | null;
24
+ readonly sessionValue: string | null;
25
+ /** How the routing candidate was selected; not proof of process affiliation. */
26
+ readonly source: 'current' | 'explicit';
27
+ }
28
+ export type HerdrCallerResult = {
29
+ readonly ok: true;
30
+ readonly caller: HerdrCallerObservation;
31
+ } | {
32
+ readonly ok: false;
33
+ readonly status: 'unavailable' | 'unverified';
34
+ readonly code: string;
35
+ readonly detail: string;
36
+ };
37
+ export interface HerdrPromptResult {
38
+ readonly status: 'submitted' | 'blocked' | 'refused' | 'unknown' | 'failed' | 'unavailable';
39
+ readonly detail: string | null;
40
+ }
41
+ export type HerdrListResult = {
42
+ readonly ok: true;
43
+ readonly agents: readonly HerdrAgentObservation[];
44
+ } | {
45
+ readonly ok: false;
46
+ readonly status: 'unavailable' | 'failed';
47
+ readonly detail: string;
48
+ };
49
+ export interface HerdrTransport {
50
+ readonly id: string;
51
+ /**
52
+ * Resolves the routing candidate before any other agent is inspected. Without
53
+ * `paneId` it requires the inherited caller context; an explicit id is used as
54
+ * supplied and never overrides focus or the environment.
55
+ */
56
+ verifyCaller(options?: {
57
+ readonly paneId?: string;
58
+ }): Promise<HerdrCallerResult>;
59
+ list(): Promise<HerdrListResult>;
60
+ prompt(agent: string, text: string, registered?: {
61
+ readonly taskRoot: string;
62
+ readonly messageId: string;
63
+ readonly digest: string;
64
+ readonly sessionId: string;
65
+ }): Promise<HerdrPromptResult>;
66
+ }
67
+ export interface CommandResult {
68
+ readonly spawned: boolean;
69
+ readonly code: number | null;
70
+ readonly signal: string | null;
71
+ readonly stdout: string;
72
+ readonly stderr: string;
73
+ readonly timedOut: boolean;
74
+ readonly spawnError: string | null;
75
+ }
76
+ export type CommandRunner = (command: string, args: readonly string[], timeoutMs: number) => Promise<CommandResult>;
77
+ /** Shared bounded Herdr command runner for additive bootstrap transport operations. */
78
+ export declare const runHerdrCommand: CommandRunner;
79
+ /** Default transport: the installed Herdr CLI, argv only, never `--wait`. */
80
+ export declare function createHerdrTransport(options?: {
81
+ readonly env?: NodeJS.ProcessEnv;
82
+ readonly run?: CommandRunner;
83
+ readonly taskRoot?: string;
84
+ }): HerdrTransport;
85
+ /**
86
+ * Derives the native identity Herdr reports. A path is not matched by substring:
87
+ * Pi session files end with `_<session-id>.jsonl`, so only that final segment is
88
+ * the native identity. Other shapes stay unknown unless Herdr reports an id.
89
+ */
90
+ export declare function reportedSessionIdentity(kind: string | null, value: string | null): {
91
+ readonly status: 'match' | 'mismatch' | 'unknown';
92
+ readonly identity: string | null;
93
+ };
94
+ export interface NotifyOptions {
95
+ readonly taskRoot: string;
96
+ readonly messageId: string;
97
+ readonly bindingFile: string;
98
+ readonly apply: boolean;
99
+ readonly retry: boolean;
100
+ /** Explicit routing candidate for stale inherited context; notify-only. */
101
+ readonly callerPane?: string | null;
102
+ readonly transport?: HerdrTransport;
103
+ readonly clock?: number;
104
+ }
105
+ export interface NotifyCallerEvidence {
106
+ readonly source: 'current' | 'explicit';
107
+ readonly paneId: string;
108
+ readonly harness: string | null;
109
+ readonly cwd: string | null;
110
+ readonly observedAt: string;
111
+ readonly nativeSession: 'match' | 'unknown';
112
+ readonly nativeSessionKind: string | null;
113
+ /** Pane selection is routing; no process-affiliation proof is claimed. */
114
+ readonly processAffiliation: 'not-established';
115
+ }
116
+ export interface NotifyTarget {
117
+ readonly herdr_agent: string;
118
+ readonly pane_id: string;
119
+ readonly harness: string;
120
+ readonly cwd: string;
121
+ readonly native_session: 'match' | 'unknown';
122
+ readonly native_session_kind: string | null;
123
+ }
124
+ export interface NotifyResult {
125
+ readonly status: 'planned' | 'submitted' | 'blocked' | 'refused' | 'unknown' | 'failed' | 'herdr_unavailable' | 'herdr_caller_unverified' | 'already_recorded' | 'in_flight_unknown' | 'retry_limit';
126
+ readonly messageId: string;
127
+ readonly messagePath: string;
128
+ readonly messageDigest: string;
129
+ readonly taskId: string;
130
+ readonly recipient: {
131
+ readonly agent_id: string;
132
+ readonly harness: string;
133
+ };
134
+ readonly target: NotifyTarget | null;
135
+ readonly caller: NotifyCallerEvidence | null;
136
+ readonly transport: 'herdr' | 'none';
137
+ readonly deliveryPath: string | null;
138
+ readonly attempts: number;
139
+ readonly priorStatus: CollabDeliveryStatus | null;
140
+ readonly detail: string | null;
141
+ /** Notification never proves consumption, execution or acceptance. */
142
+ readonly consumed: false;
143
+ readonly taskAccepted: false;
144
+ }
145
+ export declare function buildNotificationText(input: {
146
+ readonly taskId: string;
147
+ readonly type: string;
148
+ readonly messagePath: string;
149
+ readonly digest: string;
150
+ }): string;
151
+ /**
152
+ * Verifies the caller and recipient against live Herdr metadata and, with apply,
153
+ * sends exactly one pointer-only prompt. Repeating a notification reports the
154
+ * recorded outcome; an in-flight or crashed reservation is never overwritten.
155
+ */
156
+ export declare function notifyRegisteredMessage(options: NotifyOptions): Promise<MessageServiceResult<NotifyResult>>;