@llblab/pi-kit 0.1.0

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 (523) hide show
  1. package/AGENTS.md +35 -0
  2. package/BACKLOG.md +3 -0
  3. package/CHANGELOG.md +9 -0
  4. package/LICENSE +21 -0
  5. package/README.md +43 -0
  6. package/node_modules/@llblab/pi-actors/AGENTS.md +150 -0
  7. package/node_modules/@llblab/pi-actors/BACKLOG.md +6 -0
  8. package/node_modules/@llblab/pi-actors/CHANGELOG.md +865 -0
  9. package/node_modules/@llblab/pi-actors/README.md +231 -0
  10. package/node_modules/@llblab/pi-actors/banner.jpg +0 -0
  11. package/node_modules/@llblab/pi-actors/dist/fixtures/protocol/artifact-manifest.json +9 -0
  12. package/node_modules/@llblab/pi-actors/dist/fixtures/protocol/control-endpoint.json +6 -0
  13. package/node_modules/@llblab/pi-actors/dist/fixtures/protocol/control-record.json +9 -0
  14. package/node_modules/@llblab/pi-actors/dist/fixtures/protocol/recipe-summary.json +8 -0
  15. package/node_modules/@llblab/pi-actors/dist/fixtures/protocol/run-state.json +10 -0
  16. package/node_modules/@llblab/pi-actors/dist/fixtures/protocol/trace-event.json +9 -0
  17. package/node_modules/@llblab/pi-actors/dist/index.d.ts +7 -0
  18. package/node_modules/@llblab/pi-actors/dist/index.js +17 -0
  19. package/node_modules/@llblab/pi-actors/dist/lib/async-runs.d.ts +146 -0
  20. package/node_modules/@llblab/pi-actors/dist/lib/async-runs.js +800 -0
  21. package/node_modules/@llblab/pi-actors/dist/lib/automatic-review-runtime.d.ts +20 -0
  22. package/node_modules/@llblab/pi-actors/dist/lib/automatic-review-runtime.js +103 -0
  23. package/node_modules/@llblab/pi-actors/dist/lib/command-templates.d.ts +85 -0
  24. package/node_modules/@llblab/pi-actors/dist/lib/command-templates.js +804 -0
  25. package/node_modules/@llblab/pi-actors/dist/lib/config.d.ts +34 -0
  26. package/node_modules/@llblab/pi-actors/dist/lib/config.js +216 -0
  27. package/node_modules/@llblab/pi-actors/dist/lib/control-projection.d.ts +20 -0
  28. package/node_modules/@llblab/pi-actors/dist/lib/control-projection.js +66 -0
  29. package/node_modules/@llblab/pi-actors/dist/lib/control.d.ts +15 -0
  30. package/node_modules/@llblab/pi-actors/dist/lib/control.js +97 -0
  31. package/node_modules/@llblab/pi-actors/dist/lib/draft-consolidation-transaction.d.ts +65 -0
  32. package/node_modules/@llblab/pi-actors/dist/lib/draft-consolidation-transaction.js +610 -0
  33. package/node_modules/@llblab/pi-actors/dist/lib/draft-consolidation.d.ts +35 -0
  34. package/node_modules/@llblab/pi-actors/dist/lib/draft-consolidation.js +126 -0
  35. package/node_modules/@llblab/pi-actors/dist/lib/draft-review.d.ts +56 -0
  36. package/node_modules/@llblab/pi-actors/dist/lib/draft-review.js +254 -0
  37. package/node_modules/@llblab/pi-actors/dist/lib/draft-sleep.d.ts +65 -0
  38. package/node_modules/@llblab/pi-actors/dist/lib/draft-sleep.js +467 -0
  39. package/node_modules/@llblab/pi-actors/dist/lib/execution-output.d.ts +25 -0
  40. package/node_modules/@llblab/pi-actors/dist/lib/execution-output.js +88 -0
  41. package/node_modules/@llblab/pi-actors/dist/lib/execution-sessions.d.ts +17 -0
  42. package/node_modules/@llblab/pi-actors/dist/lib/execution-sessions.js +85 -0
  43. package/node_modules/@llblab/pi-actors/dist/lib/execution.d.ts +99 -0
  44. package/node_modules/@llblab/pi-actors/dist/lib/execution.js +725 -0
  45. package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.d.ts +21 -0
  46. package/node_modules/@llblab/pi-actors/dist/lib/extension-runtime.js +141 -0
  47. package/node_modules/@llblab/pi-actors/dist/lib/file-state.d.ts +18 -0
  48. package/node_modules/@llblab/pi-actors/dist/lib/file-state.js +310 -0
  49. package/node_modules/@llblab/pi-actors/dist/lib/identity.d.ts +9 -0
  50. package/node_modules/@llblab/pi-actors/dist/lib/identity.js +27 -0
  51. package/node_modules/@llblab/pi-actors/dist/lib/inspector-actions.d.ts +16 -0
  52. package/node_modules/@llblab/pi-actors/dist/lib/inspector-actions.js +57 -0
  53. package/node_modules/@llblab/pi-actors/dist/lib/inspector-command.d.ts +7 -0
  54. package/node_modules/@llblab/pi-actors/dist/lib/inspector-command.js +37 -0
  55. package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.d.ts +100 -0
  56. package/node_modules/@llblab/pi-actors/dist/lib/inspector-overlay.js +824 -0
  57. package/node_modules/@llblab/pi-actors/dist/lib/inspector.d.ts +20 -0
  58. package/node_modules/@llblab/pi-actors/dist/lib/inspector.js +136 -0
  59. package/node_modules/@llblab/pi-actors/dist/lib/limits.d.ts +28 -0
  60. package/node_modules/@llblab/pi-actors/dist/lib/limits.js +28 -0
  61. package/node_modules/@llblab/pi-actors/dist/lib/model-context.d.ts +56 -0
  62. package/node_modules/@llblab/pi-actors/dist/lib/model-context.js +220 -0
  63. package/node_modules/@llblab/pi-actors/dist/lib/observability.d.ts +186 -0
  64. package/node_modules/@llblab/pi-actors/dist/lib/observability.js +951 -0
  65. package/node_modules/@llblab/pi-actors/dist/lib/paths.d.ts +27 -0
  66. package/node_modules/@llblab/pi-actors/dist/lib/paths.js +72 -0
  67. package/node_modules/@llblab/pi-actors/dist/lib/pi.d.ts +19 -0
  68. package/node_modules/@llblab/pi-actors/dist/lib/pi.js +21 -0
  69. package/node_modules/@llblab/pi-actors/dist/lib/preflight-diagnostics.d.ts +27 -0
  70. package/node_modules/@llblab/pi-actors/dist/lib/preflight-diagnostics.js +86 -0
  71. package/node_modules/@llblab/pi-actors/dist/lib/prompts.d.ts +24 -0
  72. package/node_modules/@llblab/pi-actors/dist/lib/prompts.js +49 -0
  73. package/node_modules/@llblab/pi-actors/dist/lib/recipe-control.d.ts +7 -0
  74. package/node_modules/@llblab/pi-actors/dist/lib/recipe-control.js +43 -0
  75. package/node_modules/@llblab/pi-actors/dist/lib/recipes-context.d.ts +36 -0
  76. package/node_modules/@llblab/pi-actors/dist/lib/recipes-context.js +197 -0
  77. package/node_modules/@llblab/pi-actors/dist/lib/recipes-discovery.d.ts +77 -0
  78. package/node_modules/@llblab/pi-actors/dist/lib/recipes-discovery.js +783 -0
  79. package/node_modules/@llblab/pi-actors/dist/lib/recipes-references.d.ts +113 -0
  80. package/node_modules/@llblab/pi-actors/dist/lib/recipes-references.js +1108 -0
  81. package/node_modules/@llblab/pi-actors/dist/lib/recipes-usage.d.ts +21 -0
  82. package/node_modules/@llblab/pi-actors/dist/lib/recipes-usage.js +494 -0
  83. package/node_modules/@llblab/pi-actors/dist/lib/registry.d.ts +67 -0
  84. package/node_modules/@llblab/pi-actors/dist/lib/registry.js +504 -0
  85. package/node_modules/@llblab/pi-actors/dist/lib/review-control.d.ts +14 -0
  86. package/node_modules/@llblab/pi-actors/dist/lib/review-control.js +110 -0
  87. package/node_modules/@llblab/pi-actors/dist/lib/review-diagnostics.d.ts +11 -0
  88. package/node_modules/@llblab/pi-actors/dist/lib/review-diagnostics.js +148 -0
  89. package/node_modules/@llblab/pi-actors/dist/lib/review-projection.d.ts +14 -0
  90. package/node_modules/@llblab/pi-actors/dist/lib/review-projection.js +166 -0
  91. package/node_modules/@llblab/pi-actors/dist/lib/run-evidence-policy.d.ts +95 -0
  92. package/node_modules/@llblab/pi-actors/dist/lib/run-evidence-policy.js +177 -0
  93. package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.d.ts +18 -0
  94. package/node_modules/@llblab/pi-actors/dist/lib/run-ui-runtime.js +125 -0
  95. package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.d.ts +21 -0
  96. package/node_modules/@llblab/pi-actors/dist/lib/runs-artifacts.js +68 -0
  97. package/node_modules/@llblab/pi-actors/dist/lib/runs-control-delivery.d.ts +28 -0
  98. package/node_modules/@llblab/pi-actors/dist/lib/runs-control-delivery.js +150 -0
  99. package/node_modules/@llblab/pi-actors/dist/lib/runs-control.d.ts +21 -0
  100. package/node_modules/@llblab/pi-actors/dist/lib/runs-control.js +89 -0
  101. package/node_modules/@llblab/pi-actors/dist/lib/runs-controls.d.ts +39 -0
  102. package/node_modules/@llblab/pi-actors/dist/lib/runs-controls.js +283 -0
  103. package/node_modules/@llblab/pi-actors/dist/lib/runs-identity.d.ts +5 -0
  104. package/node_modules/@llblab/pi-actors/dist/lib/runs-identity.js +11 -0
  105. package/node_modules/@llblab/pi-actors/dist/lib/runs-index.d.ts +27 -0
  106. package/node_modules/@llblab/pi-actors/dist/lib/runs-index.js +142 -0
  107. package/node_modules/@llblab/pi-actors/dist/lib/runs-ownership.d.ts +7 -0
  108. package/node_modules/@llblab/pi-actors/dist/lib/runs-ownership.js +96 -0
  109. package/node_modules/@llblab/pi-actors/dist/lib/runs-parent-teardown.d.ts +51 -0
  110. package/node_modules/@llblab/pi-actors/dist/lib/runs-parent-teardown.js +172 -0
  111. package/node_modules/@llblab/pi-actors/dist/lib/runs-process.d.ts +22 -0
  112. package/node_modules/@llblab/pi-actors/dist/lib/runs-process.js +125 -0
  113. package/node_modules/@llblab/pi-actors/dist/lib/runs-retention.d.ts +18 -0
  114. package/node_modules/@llblab/pi-actors/dist/lib/runs-retention.js +108 -0
  115. package/node_modules/@llblab/pi-actors/dist/lib/runs-start.d.ts +12 -0
  116. package/node_modules/@llblab/pi-actors/dist/lib/runs-start.js +68 -0
  117. package/node_modules/@llblab/pi-actors/dist/lib/runs-status.d.ts +10 -0
  118. package/node_modules/@llblab/pi-actors/dist/lib/runs-status.js +68 -0
  119. package/node_modules/@llblab/pi-actors/dist/lib/runs-trace.d.ts +48 -0
  120. package/node_modules/@llblab/pi-actors/dist/lib/runs-trace.js +491 -0
  121. package/node_modules/@llblab/pi-actors/dist/lib/runtime-identity.d.ts +7 -0
  122. package/node_modules/@llblab/pi-actors/dist/lib/runtime-identity.js +35 -0
  123. package/node_modules/@llblab/pi-actors/dist/lib/runtime-triage.d.ts +29 -0
  124. package/node_modules/@llblab/pi-actors/dist/lib/runtime-triage.js +60 -0
  125. package/node_modules/@llblab/pi-actors/dist/lib/runtime.d.ts +69 -0
  126. package/node_modules/@llblab/pi-actors/dist/lib/runtime.js +339 -0
  127. package/node_modules/@llblab/pi-actors/dist/lib/schema.d.ts +60 -0
  128. package/node_modules/@llblab/pi-actors/dist/lib/schema.js +428 -0
  129. package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.d.ts +45 -0
  130. package/node_modules/@llblab/pi-actors/dist/lib/session-evidence.js +204 -0
  131. package/node_modules/@llblab/pi-actors/dist/lib/state-readers.d.ts +21 -0
  132. package/node_modules/@llblab/pi-actors/dist/lib/state-readers.js +74 -0
  133. package/node_modules/@llblab/pi-actors/dist/lib/temp.d.ts +10 -0
  134. package/node_modules/@llblab/pi-actors/dist/lib/temp.js +90 -0
  135. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-lineage-transaction.d.ts +27 -0
  136. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-lineage-transaction.js +597 -0
  137. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-lineage.d.ts +24 -0
  138. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-lineage.js +98 -0
  139. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-scheduler.d.ts +80 -0
  140. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-scheduler.js +494 -0
  141. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-transaction.d.ts +50 -0
  142. package/node_modules/@llblab/pi-actors/dist/lib/tool-review-transaction.js +362 -0
  143. package/node_modules/@llblab/pi-actors/dist/lib/tool-review.d.ts +56 -0
  144. package/node_modules/@llblab/pi-actors/dist/lib/tool-review.js +197 -0
  145. package/node_modules/@llblab/pi-actors/dist/lib/tools-access.d.ts +19 -0
  146. package/node_modules/@llblab/pi-actors/dist/lib/tools-access.js +44 -0
  147. package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.d.ts +15 -0
  148. package/node_modules/@llblab/pi-actors/dist/lib/tools-inspect.js +532 -0
  149. package/node_modules/@llblab/pi-actors/dist/lib/tools-local.d.ts +17 -0
  150. package/node_modules/@llblab/pi-actors/dist/lib/tools-local.js +191 -0
  151. package/node_modules/@llblab/pi-actors/dist/lib/tools-message.d.ts +9 -0
  152. package/node_modules/@llblab/pi-actors/dist/lib/tools-message.js +139 -0
  153. package/node_modules/@llblab/pi-actors/dist/lib/tools-register.d.ts +18 -0
  154. package/node_modules/@llblab/pi-actors/dist/lib/tools-register.js +41 -0
  155. package/node_modules/@llblab/pi-actors/dist/lib/tools-response.d.ts +20 -0
  156. package/node_modules/@llblab/pi-actors/dist/lib/tools-response.js +243 -0
  157. package/node_modules/@llblab/pi-actors/dist/lib/tools-spawn.d.ts +15 -0
  158. package/node_modules/@llblab/pi-actors/dist/lib/tools-spawn.js +133 -0
  159. package/node_modules/@llblab/pi-actors/dist/lib/tools.d.ts +28 -0
  160. package/node_modules/@llblab/pi-actors/dist/lib/tools.js +49 -0
  161. package/node_modules/@llblab/pi-actors/dist/lib/trace-projection.d.ts +22 -0
  162. package/node_modules/@llblab/pi-actors/dist/lib/trace-projection.js +231 -0
  163. package/node_modules/@llblab/pi-actors/dist/pi-actors/index.js +1 -0
  164. package/node_modules/@llblab/pi-actors/dist/scripts/async-runner.mjs +555 -0
  165. package/node_modules/@llblab/pi-actors/dist/scripts/build-dist.mjs +60 -0
  166. package/node_modules/@llblab/pi-actors/dist/scripts/conformance.mjs +63 -0
  167. package/node_modules/@llblab/pi-actors/dist/skills/actors/SKILL.md +126 -0
  168. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/command-validate.json +13 -0
  169. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/jsonl-tail.json +10 -0
  170. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/recipe-validate.json +11 -0
  171. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/resource-locker-snapshot.json +11 -0
  172. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/resource-locker.json +25 -0
  173. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/run-ops-snapshot.json +15 -0
  174. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/run-state-files.json +13 -0
  175. package/node_modules/@llblab/pi-actors/dist/skills/actors/recipes/run-summary.json +9 -0
  176. package/node_modules/@llblab/pi-actors/dist/skills/actors/references/diagnostics.md +44 -0
  177. package/node_modules/@llblab/pi-actors/dist/skills/actors/references/persistent-tools.md +76 -0
  178. package/node_modules/@llblab/pi-actors/dist/skills/actors/references/recipes.md +51 -0
  179. package/node_modules/@llblab/pi-actors/dist/skills/actors/references/runs.md +41 -0
  180. package/node_modules/@llblab/pi-actors/dist/skills/actors/scripts/resource-locker.mjs +425 -0
  181. package/node_modules/@llblab/pi-actors/dist/skills/actors/scripts/run-utils.mjs +164 -0
  182. package/node_modules/@llblab/pi-actors/dist/skills/actors/scripts/validate-recipe.mjs +370 -0
  183. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/SKILL.md +33 -0
  184. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/recipes/bundle.json +77 -0
  185. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/recipes/file-write.json +14 -0
  186. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/recipes/manifest.json +14 -0
  187. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/recipes/report.json +39 -0
  188. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/recipes/write.json +53 -0
  189. package/node_modules/@llblab/pi-actors/dist/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  190. package/node_modules/@llblab/pi-actors/dist/skills/music-player/SKILL.md +57 -0
  191. package/node_modules/@llblab/pi-actors/dist/skills/music-player/genapps/music-player.mjs +360 -0
  192. package/node_modules/@llblab/pi-actors/dist/skills/music-player/recipes/playback.json +29 -0
  193. package/node_modules/@llblab/pi-actors/dist/skills/music-player/scripts/playback-client.mjs +143 -0
  194. package/node_modules/@llblab/pi-actors/dist/skills/music-player/scripts/playback.mjs +1446 -0
  195. package/node_modules/@llblab/pi-actors/dist/skills/project-work/SKILL.md +37 -0
  196. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/changelog-head.json +11 -0
  197. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/changelog-section.json +11 -0
  198. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/docs-maintenance.json +66 -0
  199. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/git-log.json +11 -0
  200. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/git-status.json +9 -0
  201. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/markdown-index.json +14 -0
  202. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/package-summary.json +9 -0
  203. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/release-readiness.json +115 -0
  204. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/release-summary.json +74 -0
  205. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/repo-health.json +75 -0
  206. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/run-ops.json +56 -0
  207. package/node_modules/@llblab/pi-actors/dist/skills/project-work/recipes/skill-summary.json +11 -0
  208. package/node_modules/@llblab/pi-actors/dist/skills/project-work/scripts/project-utils.mjs +89 -0
  209. package/node_modules/@llblab/pi-actors/dist/skills/recipe-memory/SKILL.md +36 -0
  210. package/node_modules/@llblab/pi-actors/dist/skills/recipe-memory/recipes/draft-review.json +14 -0
  211. package/node_modules/@llblab/pi-actors/dist/skills/recipe-memory/recipes/tool-review.json +14 -0
  212. package/node_modules/@llblab/pi-actors/dist/skills/swarm/SKILL.md +84 -0
  213. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/architect.json +82 -0
  214. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/checkpoint-continuation.json +51 -0
  215. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/development-tasking.json +67 -0
  216. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/lens-review.json +63 -0
  217. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/quorum-review.json +65 -0
  218. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/research-synthesis.json +81 -0
  219. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/review-readiness.json +59 -0
  220. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-artifact.json +21 -0
  221. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-checkpoint.json +21 -0
  222. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-conflict-report.json +19 -0
  223. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-contradiction-map.json +20 -0
  224. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-critic.json +22 -0
  225. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-evidence-map.json +20 -0
  226. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-followup.json +21 -0
  227. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-judge.json +22 -0
  228. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-merge.json +24 -0
  229. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-normalize.json +20 -0
  230. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-plan.json +20 -0
  231. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-preflight.json +18 -0
  232. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-prompt.json +16 -0
  233. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-prompts.json +39 -0
  234. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-quorum.json +31 -0
  235. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-review-coordinator.json +170 -0
  236. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-review.json +26 -0
  237. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-task-card.json +22 -0
  238. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-tools.json +15 -0
  239. package/node_modules/@llblab/pi-actors/dist/skills/swarm/recipes/subagent-verify.json +23 -0
  240. package/node_modules/@llblab/pi-actors/dist/skills/swarm/references/development-swarm.md +189 -0
  241. package/node_modules/@llblab/pi-actors/dist/skills/swarm/references/review-swarms.md +115 -0
  242. package/node_modules/@llblab/pi-actors/docs/README.md +20 -0
  243. package/node_modules/@llblab/pi-actors/docs/actor-inspector.md +50 -0
  244. package/node_modules/@llblab/pi-actors/docs/async-runs.md +141 -0
  245. package/node_modules/@llblab/pi-actors/docs/command-templates.md +321 -0
  246. package/node_modules/@llblab/pi-actors/docs/recipe-library.md +89 -0
  247. package/node_modules/@llblab/pi-actors/docs/releasing.md +28 -0
  248. package/node_modules/@llblab/pi-actors/docs/template-recipes.md +175 -0
  249. package/node_modules/@llblab/pi-actors/docs/tool-registry.md +90 -0
  250. package/node_modules/@llblab/pi-actors/fixtures/protocol/artifact-manifest.json +9 -0
  251. package/node_modules/@llblab/pi-actors/fixtures/protocol/control-endpoint.json +6 -0
  252. package/node_modules/@llblab/pi-actors/fixtures/protocol/control-record.json +9 -0
  253. package/node_modules/@llblab/pi-actors/fixtures/protocol/recipe-summary.json +8 -0
  254. package/node_modules/@llblab/pi-actors/fixtures/protocol/run-state.json +10 -0
  255. package/node_modules/@llblab/pi-actors/fixtures/protocol/trace-event.json +9 -0
  256. package/node_modules/@llblab/pi-actors/index.ts +30 -0
  257. package/node_modules/@llblab/pi-actors/lib/async-runs.ts +1245 -0
  258. package/node_modules/@llblab/pi-actors/lib/automatic-review-runtime.ts +148 -0
  259. package/node_modules/@llblab/pi-actors/lib/command-templates.ts +1116 -0
  260. package/node_modules/@llblab/pi-actors/lib/config.ts +261 -0
  261. package/node_modules/@llblab/pi-actors/lib/control-projection.ts +105 -0
  262. package/node_modules/@llblab/pi-actors/lib/control.ts +117 -0
  263. package/node_modules/@llblab/pi-actors/lib/draft-consolidation-transaction.ts +821 -0
  264. package/node_modules/@llblab/pi-actors/lib/draft-consolidation.ts +181 -0
  265. package/node_modules/@llblab/pi-actors/lib/draft-review.ts +325 -0
  266. package/node_modules/@llblab/pi-actors/lib/draft-sleep.ts +575 -0
  267. package/node_modules/@llblab/pi-actors/lib/execution-output.ts +123 -0
  268. package/node_modules/@llblab/pi-actors/lib/execution-sessions.ts +111 -0
  269. package/node_modules/@llblab/pi-actors/lib/execution.ts +1153 -0
  270. package/node_modules/@llblab/pi-actors/lib/extension-runtime.ts +181 -0
  271. package/node_modules/@llblab/pi-actors/lib/file-state.ts +306 -0
  272. package/node_modules/@llblab/pi-actors/lib/identity.ts +29 -0
  273. package/node_modules/@llblab/pi-actors/lib/inspector-actions.ts +79 -0
  274. package/node_modules/@llblab/pi-actors/lib/inspector-command.ts +54 -0
  275. package/node_modules/@llblab/pi-actors/lib/inspector-overlay.ts +901 -0
  276. package/node_modules/@llblab/pi-actors/lib/inspector.ts +204 -0
  277. package/node_modules/@llblab/pi-actors/lib/limits.ts +29 -0
  278. package/node_modules/@llblab/pi-actors/lib/model-context.ts +359 -0
  279. package/node_modules/@llblab/pi-actors/lib/observability.ts +1337 -0
  280. package/node_modules/@llblab/pi-actors/lib/paths.ts +111 -0
  281. package/node_modules/@llblab/pi-actors/lib/pi.ts +47 -0
  282. package/node_modules/@llblab/pi-actors/lib/preflight-diagnostics.ts +132 -0
  283. package/node_modules/@llblab/pi-actors/lib/prompts.ts +69 -0
  284. package/node_modules/@llblab/pi-actors/lib/recipe-control.ts +52 -0
  285. package/node_modules/@llblab/pi-actors/lib/recipes-context.ts +268 -0
  286. package/node_modules/@llblab/pi-actors/lib/recipes-discovery.ts +1060 -0
  287. package/node_modules/@llblab/pi-actors/lib/recipes-references.ts +1598 -0
  288. package/node_modules/@llblab/pi-actors/lib/recipes-usage.ts +638 -0
  289. package/node_modules/@llblab/pi-actors/lib/registry.ts +806 -0
  290. package/node_modules/@llblab/pi-actors/lib/review-control.ts +136 -0
  291. package/node_modules/@llblab/pi-actors/lib/review-diagnostics.ts +164 -0
  292. package/node_modules/@llblab/pi-actors/lib/review-projection.ts +196 -0
  293. package/node_modules/@llblab/pi-actors/lib/run-evidence-policy.ts +242 -0
  294. package/node_modules/@llblab/pi-actors/lib/run-ui-runtime.ts +155 -0
  295. package/node_modules/@llblab/pi-actors/lib/runs-artifacts.ts +96 -0
  296. package/node_modules/@llblab/pi-actors/lib/runs-control-delivery.ts +209 -0
  297. package/node_modules/@llblab/pi-actors/lib/runs-control.ts +148 -0
  298. package/node_modules/@llblab/pi-actors/lib/runs-controls.ts +282 -0
  299. package/node_modules/@llblab/pi-actors/lib/runs-identity.ts +14 -0
  300. package/node_modules/@llblab/pi-actors/lib/runs-index.ts +192 -0
  301. package/node_modules/@llblab/pi-actors/lib/runs-ownership.ts +136 -0
  302. package/node_modules/@llblab/pi-actors/lib/runs-parent-teardown.ts +257 -0
  303. package/node_modules/@llblab/pi-actors/lib/runs-process.ts +174 -0
  304. package/node_modules/@llblab/pi-actors/lib/runs-retention.ts +140 -0
  305. package/node_modules/@llblab/pi-actors/lib/runs-start.ts +113 -0
  306. package/node_modules/@llblab/pi-actors/lib/runs-status.ts +101 -0
  307. package/node_modules/@llblab/pi-actors/lib/runs-trace.ts +611 -0
  308. package/node_modules/@llblab/pi-actors/lib/runtime-identity.ts +39 -0
  309. package/node_modules/@llblab/pi-actors/lib/runtime-triage.ts +106 -0
  310. package/node_modules/@llblab/pi-actors/lib/runtime.ts +430 -0
  311. package/node_modules/@llblab/pi-actors/lib/schema.ts +525 -0
  312. package/node_modules/@llblab/pi-actors/lib/session-evidence.ts +302 -0
  313. package/node_modules/@llblab/pi-actors/lib/state-readers.ts +93 -0
  314. package/node_modules/@llblab/pi-actors/lib/temp.ts +99 -0
  315. package/node_modules/@llblab/pi-actors/lib/tool-review-lineage-transaction.ts +881 -0
  316. package/node_modules/@llblab/pi-actors/lib/tool-review-lineage.ts +145 -0
  317. package/node_modules/@llblab/pi-actors/lib/tool-review-scheduler.ts +635 -0
  318. package/node_modules/@llblab/pi-actors/lib/tool-review-transaction.ts +563 -0
  319. package/node_modules/@llblab/pi-actors/lib/tool-review.ts +270 -0
  320. package/node_modules/@llblab/pi-actors/lib/tools-access.ts +68 -0
  321. package/node_modules/@llblab/pi-actors/lib/tools-inspect.ts +673 -0
  322. package/node_modules/@llblab/pi-actors/lib/tools-local.ts +303 -0
  323. package/node_modules/@llblab/pi-actors/lib/tools-message.ts +176 -0
  324. package/node_modules/@llblab/pi-actors/lib/tools-register.ts +63 -0
  325. package/node_modules/@llblab/pi-actors/lib/tools-response.ts +285 -0
  326. package/node_modules/@llblab/pi-actors/lib/tools-spawn.ts +212 -0
  327. package/node_modules/@llblab/pi-actors/lib/tools.ts +88 -0
  328. package/node_modules/@llblab/pi-actors/lib/trace-projection.ts +306 -0
  329. package/node_modules/@llblab/pi-actors/package.json +76 -0
  330. package/node_modules/@llblab/pi-actors/scripts/async-runner.mjs +555 -0
  331. package/node_modules/@llblab/pi-actors/scripts/build-dist.mjs +60 -0
  332. package/node_modules/@llblab/pi-actors/scripts/conformance.mjs +63 -0
  333. package/node_modules/@llblab/pi-actors/skills/actors/SKILL.md +126 -0
  334. package/node_modules/@llblab/pi-actors/skills/actors/recipes/command-validate.json +13 -0
  335. package/node_modules/@llblab/pi-actors/skills/actors/recipes/jsonl-tail.json +10 -0
  336. package/node_modules/@llblab/pi-actors/skills/actors/recipes/recipe-validate.json +11 -0
  337. package/node_modules/@llblab/pi-actors/skills/actors/recipes/resource-locker-snapshot.json +11 -0
  338. package/node_modules/@llblab/pi-actors/skills/actors/recipes/resource-locker.json +25 -0
  339. package/node_modules/@llblab/pi-actors/skills/actors/recipes/run-ops-snapshot.json +15 -0
  340. package/node_modules/@llblab/pi-actors/skills/actors/recipes/run-state-files.json +13 -0
  341. package/node_modules/@llblab/pi-actors/skills/actors/recipes/run-summary.json +9 -0
  342. package/node_modules/@llblab/pi-actors/skills/actors/references/diagnostics.md +44 -0
  343. package/node_modules/@llblab/pi-actors/skills/actors/references/persistent-tools.md +76 -0
  344. package/node_modules/@llblab/pi-actors/skills/actors/references/recipes.md +51 -0
  345. package/node_modules/@llblab/pi-actors/skills/actors/references/runs.md +41 -0
  346. package/node_modules/@llblab/pi-actors/skills/actors/scripts/resource-locker.mjs +425 -0
  347. package/node_modules/@llblab/pi-actors/skills/actors/scripts/run-utils.mjs +164 -0
  348. package/node_modules/@llblab/pi-actors/skills/actors/scripts/validate-recipe.mjs +370 -0
  349. package/node_modules/@llblab/pi-actors/skills/artifacts/SKILL.md +33 -0
  350. package/node_modules/@llblab/pi-actors/skills/artifacts/recipes/bundle.json +77 -0
  351. package/node_modules/@llblab/pi-actors/skills/artifacts/recipes/file-write.json +14 -0
  352. package/node_modules/@llblab/pi-actors/skills/artifacts/recipes/manifest.json +14 -0
  353. package/node_modules/@llblab/pi-actors/skills/artifacts/recipes/report.json +39 -0
  354. package/node_modules/@llblab/pi-actors/skills/artifacts/recipes/write.json +53 -0
  355. package/node_modules/@llblab/pi-actors/skills/artifacts/scripts/artifact-utils.mjs +63 -0
  356. package/node_modules/@llblab/pi-actors/skills/music-player/SKILL.md +57 -0
  357. package/node_modules/@llblab/pi-actors/skills/music-player/genapps/music-player.mjs +360 -0
  358. package/node_modules/@llblab/pi-actors/skills/music-player/recipes/playback.json +29 -0
  359. package/node_modules/@llblab/pi-actors/skills/music-player/scripts/playback-client.mjs +143 -0
  360. package/node_modules/@llblab/pi-actors/skills/music-player/scripts/playback.mjs +1446 -0
  361. package/node_modules/@llblab/pi-actors/skills/project-work/SKILL.md +37 -0
  362. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/changelog-head.json +11 -0
  363. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/changelog-section.json +11 -0
  364. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/docs-maintenance.json +66 -0
  365. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/git-log.json +11 -0
  366. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/git-status.json +9 -0
  367. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/markdown-index.json +14 -0
  368. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/package-summary.json +9 -0
  369. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/release-readiness.json +115 -0
  370. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/release-summary.json +74 -0
  371. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/repo-health.json +75 -0
  372. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/run-ops.json +56 -0
  373. package/node_modules/@llblab/pi-actors/skills/project-work/recipes/skill-summary.json +11 -0
  374. package/node_modules/@llblab/pi-actors/skills/project-work/scripts/project-utils.mjs +89 -0
  375. package/node_modules/@llblab/pi-actors/skills/recipe-memory/SKILL.md +36 -0
  376. package/node_modules/@llblab/pi-actors/skills/recipe-memory/recipes/draft-review.json +14 -0
  377. package/node_modules/@llblab/pi-actors/skills/recipe-memory/recipes/tool-review.json +14 -0
  378. package/node_modules/@llblab/pi-actors/skills/swarm/SKILL.md +84 -0
  379. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/architect.json +82 -0
  380. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/checkpoint-continuation.json +51 -0
  381. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/development-tasking.json +67 -0
  382. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/lens-review.json +63 -0
  383. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/quorum-review.json +65 -0
  384. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/research-synthesis.json +81 -0
  385. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/review-readiness.json +59 -0
  386. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-artifact.json +21 -0
  387. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-checkpoint.json +21 -0
  388. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-conflict-report.json +19 -0
  389. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-contradiction-map.json +20 -0
  390. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-critic.json +22 -0
  391. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-evidence-map.json +20 -0
  392. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-followup.json +21 -0
  393. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-judge.json +22 -0
  394. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-merge.json +24 -0
  395. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-normalize.json +20 -0
  396. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-plan.json +20 -0
  397. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-preflight.json +18 -0
  398. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-prompt.json +16 -0
  399. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-prompts.json +39 -0
  400. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-quorum.json +31 -0
  401. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-review-coordinator.json +170 -0
  402. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-review.json +26 -0
  403. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-task-card.json +22 -0
  404. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-tools.json +15 -0
  405. package/node_modules/@llblab/pi-actors/skills/swarm/recipes/subagent-verify.json +23 -0
  406. package/node_modules/@llblab/pi-actors/skills/swarm/references/development-swarm.md +189 -0
  407. package/node_modules/@llblab/pi-actors/skills/swarm/references/review-swarms.md +115 -0
  408. package/node_modules/@llblab/pi-codex-usage/AGENTS.md +17 -0
  409. package/node_modules/@llblab/pi-codex-usage/BACKLOG.md +8 -0
  410. package/node_modules/@llblab/pi-codex-usage/CHANGELOG.md +80 -0
  411. package/node_modules/@llblab/pi-codex-usage/LICENSE +22 -0
  412. package/node_modules/@llblab/pi-codex-usage/README.md +113 -0
  413. package/node_modules/@llblab/pi-codex-usage/banner.jpg +0 -0
  414. package/node_modules/@llblab/pi-codex-usage/index.ts +1525 -0
  415. package/node_modules/@llblab/pi-codex-usage/package.json +59 -0
  416. package/node_modules/@llblab/pi-grow-loop/AGENTS.md +56 -0
  417. package/node_modules/@llblab/pi-grow-loop/BACKLOG.md +3 -0
  418. package/node_modules/@llblab/pi-grow-loop/CHANGELOG.md +126 -0
  419. package/node_modules/@llblab/pi-grow-loop/README.md +216 -0
  420. package/node_modules/@llblab/pi-grow-loop/banner.jpg +0 -0
  421. package/node_modules/@llblab/pi-grow-loop/index.ts +219 -0
  422. package/node_modules/@llblab/pi-grow-loop/package.json +64 -0
  423. package/node_modules/@llblab/pi-grow-loop/skills/grow-loop/SKILL.md +131 -0
  424. package/node_modules/@llblab/pi-grow-loop/skills/while-true/SKILL.md +233 -0
  425. package/node_modules/@llblab/pi-telegram/AGENTS.md +157 -0
  426. package/node_modules/@llblab/pi-telegram/BACKLOG.md +15 -0
  427. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +886 -0
  428. package/node_modules/@llblab/pi-telegram/README.md +330 -0
  429. package/node_modules/@llblab/pi-telegram/api/activity.ts +15 -0
  430. package/node_modules/@llblab/pi-telegram/api/commands.ts +11 -0
  431. package/node_modules/@llblab/pi-telegram/api/delivery.ts +21 -0
  432. package/node_modules/@llblab/pi-telegram/api/inbound.ts +14 -0
  433. package/node_modules/@llblab/pi-telegram/api/keyboard.ts +11 -0
  434. package/node_modules/@llblab/pi-telegram/api/outbound.ts +11 -0
  435. package/node_modules/@llblab/pi-telegram/api/sections.ts +17 -0
  436. package/node_modules/@llblab/pi-telegram/api/status.ts +12 -0
  437. package/node_modules/@llblab/pi-telegram/api/updates.ts +16 -0
  438. package/node_modules/@llblab/pi-telegram/api/voice.ts +24 -0
  439. package/node_modules/@llblab/pi-telegram/docs/README.md +25 -0
  440. package/node_modules/@llblab/pi-telegram/docs/activity.md +304 -0
  441. package/node_modules/@llblab/pi-telegram/docs/architecture.md +418 -0
  442. package/node_modules/@llblab/pi-telegram/docs/callback-namespaces.md +48 -0
  443. package/node_modules/@llblab/pi-telegram/docs/command-templates.md +365 -0
  444. package/node_modules/@llblab/pi-telegram/docs/compact-matrix-literal.md +176 -0
  445. package/node_modules/@llblab/pi-telegram/docs/delivery.md +225 -0
  446. package/node_modules/@llblab/pi-telegram/docs/generative-apps.md +310 -0
  447. package/node_modules/@llblab/pi-telegram/docs/inbound.md +136 -0
  448. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +467 -0
  449. package/node_modules/@llblab/pi-telegram/docs/outbound.md +193 -0
  450. package/node_modules/@llblab/pi-telegram/docs/public-api.md +599 -0
  451. package/node_modules/@llblab/pi-telegram/docs/sections.md +452 -0
  452. package/node_modules/@llblab/pi-telegram/docs/ui-style.md +256 -0
  453. package/node_modules/@llblab/pi-telegram/docs/updates.md +171 -0
  454. package/node_modules/@llblab/pi-telegram/docs/voice.md +217 -0
  455. package/node_modules/@llblab/pi-telegram/index.ts +1336 -0
  456. package/node_modules/@llblab/pi-telegram/lib/activity-verbosity.ts +714 -0
  457. package/node_modules/@llblab/pi-telegram/lib/activity.ts +782 -0
  458. package/node_modules/@llblab/pi-telegram/lib/agent-messages.ts +121 -0
  459. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +1129 -0
  460. package/node_modules/@llblab/pi-telegram/lib/bus-api.ts +379 -0
  461. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +1941 -0
  462. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +2119 -0
  463. package/node_modules/@llblab/pi-telegram/lib/bus-transport.ts +244 -0
  464. package/node_modules/@llblab/pi-telegram/lib/bus.ts +2645 -0
  465. package/node_modules/@llblab/pi-telegram/lib/command-templates.ts +954 -0
  466. package/node_modules/@llblab/pi-telegram/lib/commands.ts +1854 -0
  467. package/node_modules/@llblab/pi-telegram/lib/config.ts +1143 -0
  468. package/node_modules/@llblab/pi-telegram/lib/delivery.ts +891 -0
  469. package/node_modules/@llblab/pi-telegram/lib/generative-app-worker.mjs +104 -0
  470. package/node_modules/@llblab/pi-telegram/lib/generative-apps.ts +958 -0
  471. package/node_modules/@llblab/pi-telegram/lib/inbound.ts +824 -0
  472. package/node_modules/@llblab/pi-telegram/lib/journal.ts +3140 -0
  473. package/node_modules/@llblab/pi-telegram/lib/keyboard.ts +59 -0
  474. package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +623 -0
  475. package/node_modules/@llblab/pi-telegram/lib/locks.ts +1422 -0
  476. package/node_modules/@llblab/pi-telegram/lib/logs.ts +393 -0
  477. package/node_modules/@llblab/pi-telegram/lib/media.ts +921 -0
  478. package/node_modules/@llblab/pi-telegram/lib/menu-model.ts +1182 -0
  479. package/node_modules/@llblab/pi-telegram/lib/menu-queue.ts +926 -0
  480. package/node_modules/@llblab/pi-telegram/lib/menu-settings.ts +876 -0
  481. package/node_modules/@llblab/pi-telegram/lib/menu-status.ts +274 -0
  482. package/node_modules/@llblab/pi-telegram/lib/menu-thinking.ts +185 -0
  483. package/node_modules/@llblab/pi-telegram/lib/menu.ts +867 -0
  484. package/node_modules/@llblab/pi-telegram/lib/model.ts +672 -0
  485. package/node_modules/@llblab/pi-telegram/lib/outbound-attachments.ts +981 -0
  486. package/node_modules/@llblab/pi-telegram/lib/outbound-buttons.ts +331 -0
  487. package/node_modules/@llblab/pi-telegram/lib/outbound-markup.ts +515 -0
  488. package/node_modules/@llblab/pi-telegram/lib/outbound-voice.ts +285 -0
  489. package/node_modules/@llblab/pi-telegram/lib/outbound.ts +1007 -0
  490. package/node_modules/@llblab/pi-telegram/lib/ownership.ts +298 -0
  491. package/node_modules/@llblab/pi-telegram/lib/paths.ts +127 -0
  492. package/node_modules/@llblab/pi-telegram/lib/pi.ts +197 -0
  493. package/node_modules/@llblab/pi-telegram/lib/polling.ts +1588 -0
  494. package/node_modules/@llblab/pi-telegram/lib/preview.ts +846 -0
  495. package/node_modules/@llblab/pi-telegram/lib/prompt-templates.ts +158 -0
  496. package/node_modules/@llblab/pi-telegram/lib/prompts.ts +218 -0
  497. package/node_modules/@llblab/pi-telegram/lib/queue.ts +3075 -0
  498. package/node_modules/@llblab/pi-telegram/lib/recovery.ts +464 -0
  499. package/node_modules/@llblab/pi-telegram/lib/rendering.ts +1213 -0
  500. package/node_modules/@llblab/pi-telegram/lib/replies.ts +892 -0
  501. package/node_modules/@llblab/pi-telegram/lib/routing.ts +2889 -0
  502. package/node_modules/@llblab/pi-telegram/lib/runtime.ts +628 -0
  503. package/node_modules/@llblab/pi-telegram/lib/sections.ts +710 -0
  504. package/node_modules/@llblab/pi-telegram/lib/setup.ts +220 -0
  505. package/node_modules/@llblab/pi-telegram/lib/skills.ts +21 -0
  506. package/node_modules/@llblab/pi-telegram/lib/status.ts +1550 -0
  507. package/node_modules/@llblab/pi-telegram/lib/sync.ts +883 -0
  508. package/node_modules/@llblab/pi-telegram/lib/target.ts +49 -0
  509. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +1747 -0
  510. package/node_modules/@llblab/pi-telegram/lib/text-groups.ts +487 -0
  511. package/node_modules/@llblab/pi-telegram/lib/thread-reconciler.ts +1002 -0
  512. package/node_modules/@llblab/pi-telegram/lib/threads.ts +3183 -0
  513. package/node_modules/@llblab/pi-telegram/lib/time-injection.ts +78 -0
  514. package/node_modules/@llblab/pi-telegram/lib/turns.ts +753 -0
  515. package/node_modules/@llblab/pi-telegram/lib/updates.ts +4950 -0
  516. package/node_modules/@llblab/pi-telegram/lib/voice.ts +340 -0
  517. package/node_modules/@llblab/pi-telegram/package.json +83 -0
  518. package/node_modules/@llblab/pi-telegram/screenshot.png +0 -0
  519. package/node_modules/@llblab/pi-telegram/scripts/check-downgrade.mjs +435 -0
  520. package/node_modules/@llblab/pi-telegram/skills/generated-control-surface/SKILL.md +241 -0
  521. package/node_modules/@llblab/pi-telegram/skills/generative-apps/SKILL.md +114 -0
  522. package/node_modules/@llblab/pi-telegram/skills/telegram-bridge/SKILL.md +149 -0
  523. package/package.json +67 -0
@@ -0,0 +1,256 @@
1
+ # UI Style Guide
2
+
3
+ Small standard for inline buttons, menu rows, state controls, cards, and confirmation dialogs.
4
+
5
+ ## Principles
6
+
7
+ - Keep UI compact and phone-readable.
8
+ - Put emoji where they help scanning, not everywhere.
9
+ - Use one strong indicator for current selection; avoid emoji noise on every option.
10
+ - Match label casing to control role.
11
+ - Prefer minimal, clear configuration UI over exhaustive explanation.
12
+ - Preserve domain-owned callback prefixes and behavior in the owning module.
13
+
14
+ ## Emoji Semantics
15
+
16
+ Use emoji as stable semantic markers, not decoration. Emoji carry transportable meaning across command descriptions, inline menu rows, message headings, status copy, and tests. Before adding a new UI emoji, either reuse one below or extend this registry in the same change.
17
+
18
+ ### Domain Markers
19
+
20
+ | Emoji | Meaning | Canonical surfaces | Notes |
21
+ | --- | --- | --- | --- |
22
+ | `🧵` | Telegram/Pi thread routing | Thread chooser headings, unbound-thread warnings, thread lifecycle/status copy | Canonical thread marker. Do not add it to every concrete target button; target buttons use `threadName` or slot fallback. |
23
+ | `📡` | Telegram transport / bridge connection | Instance connected notices, polling/transport role, bridge online copy | Transport is not thread identity; use `🧵` for thread concepts. |
24
+ | `📊` | Status / overview | `/status` command description, status cards or status rows | Use for status summaries, not queue priority. |
25
+ | `🤖` | Model selection | `/model`, model menu headings, model status rows | Keep model-control surfaces visually distinct from thinking. |
26
+ | `🧠` | Thinking level | `/thinking`, thinking menu headings, thinking status rows | Use only for reasoning/thinking controls. |
27
+ | `🔢` | Queue list / ordered work | `/queue`, queue menu entrypoints | Queue item rows may also use numeric labels. |
28
+ | `⏱️` | Queue is ticking / current work is active | Inline main-menu Queue row only | Running-clock queue state: the narrow present moment is being worked now. |
29
+ | `⏳` | Queue has waiting prompts | Inline main-menu Queue row only | Hourglass queue state: sand above the neck is future work still waiting. |
30
+ | `⌛` | Queue is empty / standing idle | Inline main-menu Queue row only | Standing hourglass queue state: no future work is waiting above the neck. |
31
+ | `⚙️` | Settings / configuration | Settings menu headings and Settings navigation rows | Extension-injected rows appear before the built-in `⚙️ Settings` row. |
32
+ | `🧩` | Extension-provided surface | Extension command examples, extension section examples | Companion extensions may choose their own emoji, but `🧩` means generic extension/plugin. |
33
+ | `👄` | Voice reply policy | Voice reply settings row and detail card | Not a generic audio attachment marker. |
34
+ | `🕒` | Time injection / wall-clock context | Time injection settings row and detail card | Clock-face marker with hands; not a generic duration/progress marker. |
35
+ | `📌` | Proactive push / pinned behavior | Proactive push settings row and detail card | Not generic active/selected state. |
36
+ | `🔬` | Activity / technical detail | Activity settings row and detail card | Chooses quiet, thinking, tools, or verbose bridge activity; not a generic diagnostics marker. |
37
+ | `🧠` | Model thinking controls | Thinking menus and status rows | Thinking activity quotes omit this icon and their header entirely to minimize chat height. |
38
+ | `📎` | Attachment | Attachment summaries, queue rows for attachment-only turns | Not for thread binding. |
39
+
40
+ ### Command And Control Actions
41
+
42
+ | Emoji | Meaning | Canonical surfaces | Notes |
43
+ | --- | --- | --- | --- |
44
+ | `🟢` | Start / active / current positive state | `/start`, active row, current selected option, active `On` toggle | In command context it means “open/start menu”; in state context it means selected/active. |
45
+ | `🗜` | Compact session | `/compact`, compact confirmation action | Do not use for generic cleanup/delete. |
46
+ | `⏩` | Force next queued turn | `/next` command and matching menu action | Means skip/advance to next waiting item. |
47
+ | `▶️` | Continue/resume generation | `/continue` command and matching menu action | Means resume/continue current session flow, not force-next. |
48
+ | `⏹️` | Abort current Pi work | `/abort` command description | Stops active work but is not a destructive queue clear by itself. |
49
+ | `🟥` | Stop / abort-and-clear danger | `/stop` command description | Stronger than `⏹️`; use for disruptive stop/clear semantics. |
50
+ | `🆕` | New session / fresh start | Reserved visible extension command example for `/new`-like flows | Same-thread Telegram `/new` is currently blocked by Pi core API; keep this meaning reserved. |
51
+ | `🌀` | Refresh | Queue refresh row and future refresh buttons | Re-fetch/re-render current surface, not transport reconnect. |
52
+ | `↪️` | Reroute to an existing target | Thread chooser buttons that send a captured command/message from one thread to another live thread | Curved arrow means the message arrived here but bends to another target. |
53
+ | `🔁` | Replace/restore mode | Thread replace/restore chooser entrypoints | Opens a second step for moving a Pi instance binding to the current source thread. |
54
+ | `➡️` | Choose replacement target | Thread replace/restore target buttons that select which Pi instance should move to the current thread | Use inside the second replace/restore chooser, not for ordinary reroutes. |
55
+ | `☑️` | Activate / choose this item | Model detail activation action, generated button-only choice heading | Positive selection cue; use `🟢 Active` for already-current state. |
56
+ | `❌` | No / cancel | Confirmation cancel buttons | Use for safe cancellation, not destructive removal. |
57
+ | `🗑` | Delete / defer removal | Destructive confirmations and removal reaction | In the queue menu, reversible Keep/Skip selectors replace immediate deletion. |
58
+
59
+ ### State Indicators And Button Grammars
60
+
61
+ | Emoji | Meaning | Canonical surfaces | Notes |
62
+ | --- | --- | --- | --- |
63
+ | `🟢` | Current/active/enabled `On` | Current option in vertical lists, active state rows, active `On` toggle | One strong current marker per option list. |
64
+ | `🟡` | Active `Off` or elevated/filter state | Active `Off` toggle, Priority/Scoped active tab | Yellow means intentionally not-normal or off/default-caution, not error. |
65
+ | `🔴` | Active destructive/deferred disposition | Active queue `Skip` selector | Red distinguishes a prompt that will be discarded at dispatch from reversible neutral or elevated state. |
66
+ | `🟣` | Normal/default active tab | Normal priority tab, All/default scope tab, active page picker | Use for neutral active tabs. |
67
+ | `⚫️` | Inactive placeholder | Inactive toggle values and inactive tabs | Keeps row width stable. |
68
+ | `⬆️` | Navigate upward | `⬆️ Main menu`, `⬆️ Back` | Always first row in submenus. |
69
+
70
+ ### Queue Reaction Shortcuts
71
+
72
+ Queue reactions are shortcut controls for waiting turns. Preserve their semantics across Telegram reactions, queue-menu rows, status previews, and tests. Positive emoji control the Priority/Normal lane; negative emoji control Keep/Skip. These categories are independent, may coexist, and mutate only their own dimension. Crossing lanes appends the prompt at the destination FIFO tail; changing Keep/Skip or changing emoji within one category preserves lane position. Skip wins only when dispatch reaches the prompt.
73
+
74
+ Queue item detail renders two independent selector rows:
75
+
76
+ - `🟡 Priority` / `⚫️ Normal` or `⚫️ Priority` / `🟣 Normal` selects the lane.
77
+ - `🟢 Keep` / `⚫️ Skip` or `⚫️ Keep` / `🔴 Skip` selects dispatch disposition.
78
+
79
+ The menu may clear internal Skip but cannot remove a reaction created by the user through Telegram's Bot API.
80
+
81
+ | Emoji | Meaning | Canonical surfaces | Notes |
82
+ | --- | --- | --- | --- |
83
+ | `👍` | Promote to priority | Queue reaction shortcut | Normalized from variants like `👍️`. |
84
+ | `⚡` | Promote to priority / fast lane | Queue reaction shortcut, priority fallback badge | Also used as the default priority badge when no specific priority emoji is stored. |
85
+ | `❤` / `❤️` | Promote to priority | Queue reaction shortcut | Normalize display consistently where code normalizes reactions. |
86
+ | `🕊` / `🕊️` | Promote to priority | Queue reaction shortcut | Soft/peaceful promotion gesture. |
87
+ | `🔥` | Promote to priority | Queue reaction shortcut | Urgent/hot promotion gesture. |
88
+ | `👎` | Defer removal of waiting turn | Queue reaction shortcut and queue emoji marker | Reversible until the marked turn reaches dispatch; not negative feedback to the agent. |
89
+ | `👻` | Defer removal of waiting turn | Queue reaction shortcut and queue emoji marker | Disappear/remove metaphor. |
90
+ | `💔` | Defer removal of waiting turn | Queue reaction shortcut and queue emoji marker | Reversible cancel metaphor. |
91
+ | `💩` | Defer removal of waiting turn | Queue reaction shortcut and queue emoji marker | Reversible reject metaphor. |
92
+ | `🗑` | Defer removal | Queue reaction shortcut and queue emoji marker | Like Skip, the reaction remains reversible until dispatch reaches the marked turn. |
93
+
94
+ ### Decorative Or Local-Example Emoji
95
+
96
+ Some emoji are intentionally local examples or decorative variants, not global semantics. Empty-queue rotating messages (`🫙`, `🍃`, `🕳`, `🦗`, `🌙`, `🧘`, `🪐`, `🧺`, `🔭`, `🫧`, `🛸`) are copy flavor only and must not become controls. Example extension icons such as `🧪`, `🔧`, and `🗂` are documentation fixtures for companion extensions, not built-in pi-telegram meanings.
97
+
98
+ Thread UI rule: when a message heading, chooser, or status line is specifically about Telegram/Pi threads or target thread selection, start the heading with `🧵`. Button labels for concrete thread targets should stay clean (`threadName` or slot fallback) and should not add `🧵` to every target button unless the row would otherwise be ambiguous.
99
+
100
+ ## Action Buttons
101
+
102
+ Action buttons perform an operation.
103
+
104
+ Rules:
105
+
106
+ - Use an emoji plus capitalized action text.
107
+ - Prefer direct verb or action noun.
108
+ - Keep labels short.
109
+
110
+ Examples:
111
+
112
+ - `🗜 Yes, compact`
113
+ - `❌ No`
114
+ - `🗑 Yes, delete`
115
+ - `☑️ Activate`
116
+
117
+ ## State & Navigation Buttons
118
+
119
+ State buttons show the current state and navigate to a submenu or detail rather than performing an operation directly.
120
+
121
+ Rules:
122
+
123
+ - Use an emoji that reflects the current state.
124
+ - Use Capitalized, descriptive state text.
125
+ - Tapping opens a submenu or returns to the parent list.
126
+
127
+ Examples:
128
+
129
+ - `🟢 Active` — model detail, navigates back to model list
130
+ - `📌 Proactive push: On` — settings row, opens the toggle submenu
131
+ - `👄 Voice reply: Mirror` — settings row, opens the option list
132
+
133
+ ## Boolean Toggles
134
+
135
+ Boolean settings use a horizontal `On` / `Off` pair.
136
+
137
+ Rules:
138
+
139
+ - Keep the pair in one row: `On` left, `Off` right.
140
+ - Use Capitalized labels.
141
+ - Always show an indicator on both buttons to avoid horizontal label shift.
142
+ - Mark active `On` with `🟢`.
143
+ - Mark active `Off` with `🟡`.
144
+ - Mark the inactive value with `⚫️`.
145
+
146
+ Examples:
147
+
148
+ - `🟢 On` / `⚫️ Off`
149
+ - `⚫️ On` / `🟡 Off`
150
+
151
+ ## Horizontal Tabs
152
+
153
+ Tabs or small mutually-exclusive scopes use a horizontal row.
154
+
155
+ Rules:
156
+
157
+ - Use Capitalized labels.
158
+ - Always show an indicator on every tab to avoid horizontal label shift.
159
+ - Use active tab color to convey semantics:
160
+ - `🟣` for the default / normal state (All models, Normal priority).
161
+ - `🟡` for an elevated or filtered state (Scoped models, Priority).
162
+ - `🟣` for neutral navigation controls (page picker).
163
+ - Mark inactive tabs with `⚫️`.
164
+
165
+ Examples:
166
+
167
+ - `🟡 Scoped` / `⚫️ All`
168
+ - `⚫️ Priority` / `🟣 Normal`
169
+ - `1` / `🟣 2` / `3`
170
+
171
+ ## Vertical Option Lists
172
+
173
+ Vertical option lists choose one value from a potentially longer list, for example model selection, thinking level, voice reply mode, or time injection mode.
174
+
175
+ Rules:
176
+
177
+ - Put each option on its own row.
178
+ - Mark only the current value with `🟢`.
179
+ - Leave non-current values without emoji.
180
+ - Use lowercase labels when the option is a value.
181
+
182
+ Examples:
183
+
184
+ - `hidden`
185
+ - `🟢 mirror`
186
+ - `always`
187
+
188
+ ## Generated Prompt Buttons
189
+
190
+ A button-only assistant reply uses the standard Rich Markdown heading `☑️ **Choose an option:**`: semantic icon first, one space, bold heading text, and a final colon. Assistant-generated prompt buttons use the default app style before selection. After queue admission, edit only the selected button to its agent-configured `selected_style`: `primary` (default/blue), `success` (green), or `danger` (red). Preserve its agent-authored text and emoji, leave other choices at their default style, and always queue the selected prompt regardless of color. The callback acknowledgement remains the compatibility fallback when a client does not render button styles.
191
+
192
+ ## Navigation
193
+
194
+ Inline submenu navigation is hierarchical.
195
+
196
+ Rules:
197
+
198
+ - Put the navigation row first.
199
+ - First-level submenus opened from the main inline menu start with `⬆️ Main menu`.
200
+ - Deeper submenus start with `⬆️ Back`.
201
+ - `Main menu` returns to the root inline menu.
202
+ - `Back` returns one level up, never directly to the root unless the parent is the root.
203
+
204
+ Examples:
205
+
206
+ - Main menu → Settings: first row is `⬆️ Main menu`.
207
+ - Settings → Voice reply mode: first row is `⬆️ Back`.
208
+
209
+ ## Message Cards
210
+
211
+ Message cards sent by the bot should start with a strong heading.
212
+
213
+ Rules:
214
+
215
+ - Start with a bold heading or, for dialogs, a bold question.
216
+ - Setting detail cards may include an emoji in the heading, then a colon and the current value in `<code>`.
217
+ - Explain what the setting does and what the options mean only as much as needed.
218
+ - Order setting value descriptions exactly like the chooser: rows top-to-bottom and values in a shared row left-to-right. Keep `(default)` on the actual default wherever it falls; default status never changes order.
219
+ - Keep descriptions short and clear.
220
+
221
+ Examples:
222
+
223
+ ```html
224
+ <b>👄 Voice reply mode:</b> <code>mirror</code>
225
+ ```
226
+
227
+ ```html
228
+ <b>Queue</b>
229
+ ```
230
+
231
+ ## Confirmation Dialogs
232
+
233
+ Confirmation dialogs protect risky or disruptive actions.
234
+
235
+ Rules:
236
+
237
+ - Body text is one bold text-only question.
238
+ - Do not put emoji in the dialog question.
239
+ - Do not add explanatory body copy unless the risk cannot be understood from the question and action labels.
240
+ - Put emoji on the buttons, not in the question.
241
+ - Preserve dialog-specific button order by intent.
242
+
243
+ Example:
244
+
245
+ ```html
246
+ <b>Compact session?</b>
247
+ ```
248
+
249
+ Buttons:
250
+
251
+ - `🗜 Yes, compact`
252
+ - `❌ No`
253
+
254
+ ## Callback Ownership
255
+
256
+ UI style does not change callback ownership. Callback prefixes remain owned by their feature domain and must be listed in callback namespace documentation when they become public collision risks.
@@ -0,0 +1,171 @@
1
+ # Updates
2
+
3
+ `updates` owns Telegram update classification, default-routing plans, and the public update-handler registry. The internal `polling` domain owns the actual `getUpdates` loop, offsets, and abort/controller state.
4
+
5
+ `pi-telegram` owns a single `getUpdates` long-poll connection per bot. Other pi extensions cannot open a competing polling connection against the same bot — the Telegram Bot API uses a per-bot `offset` cursor, and two loops race each other and lose updates.
6
+
7
+ This document describes the registry that lets layered pi extensions running in the same pi process hook into `pi-telegram`'s polling loop and react to inbound Telegram updates **before** `pi-telegram`'s default routing fires.
8
+
9
+ The `0.28.0` transport/execution split is specified in [Durable Admission And Recovery](./architecture.md#durable-admission-and-recovery). Polling durably admits and advances batches before the independent worker invokes this registry. The worker binds source ids only after public interception passes, supplies public and built-in handlers with the same optional execution fence, settles late grouping under its exact generation, and publishes durable queue readiness. This document describes the executable public registry contract.
10
+
11
+ It is the runtime counterpart to [Callback Namespaces](./callback-namespaces.md): callback namespaces define how to share `callback_data` cleanly; update handlers define how to observe and optionally short-circuit the dispatch of those updates.
12
+
13
+ ## When to use it
14
+
15
+ Use it when a layered extension needs to:
16
+
17
+ - Resolve out-of-band state, for example a `tool_call` approval Promise, the moment a Telegram callback arrives, rather than waiting for the next agent turn.
18
+ - Suppress `pi-telegram`'s default routing for callbacks owned by the layered extension, so `pi-telegram` does not also forward them as `[callback] <data>` text.
19
+ - Observe arbitrary update types such as messages, edits, channel posts, or reactions without owning the polling connection.
20
+
21
+ If the layered extension only needs to read assistant-visible callbacks, the existing `[callback] <data>` fallback documented in [Callback Namespaces](./callback-namespaces.md) is enough.
22
+
23
+ If the extension needs a durable top-level Telegram menu section with managed rendering, callback routing, authorization, and diagnostics, use the higher-level [Telegram Extension Sections](./sections.md) contract instead of a raw update handler.
24
+
25
+ ## Constraints
26
+
27
+ - One bot profile has one leader-owned `getUpdates` loop. This process-local registry neither creates another transport nor replaces the Threaded Mode leader/follower bus.
28
+ - Handlers run before built-in routing in the independent semantic worker. They must return promptly because a long await delays later handler/routing execution for that source order, but it does not delay `getUpdates` admission or offset persistence. Replacement generations wait for the unsettled handler rather than executing the same update concurrently.
29
+ - Handler errors are caught and logged silently so polling never breaks. If you need durable error reporting, do it inside your handler.
30
+ - Typed handlers receive an optional second `execution` argument with `signal`, `updateId`, `generation`, `isCurrent()`, and `assertCurrent()`. Pass `signal` into cancellable work and call `assertCurrent()` immediately before irreversible effects. The runtime also rejects a verdict returned after cancellation. Legacy one-argument and zero-coupling handlers remain compatible, but any effect they commit while still awaiting is their responsibility; replacement replay still waits for that handler's actual settlement.
31
+ - The registry lives on `globalThis`. Module instance identity is not required, so layered extensions can reach it without importing `@llblab/pi-telegram`.
32
+
33
+ ## Verdicts
34
+
35
+ Each handler returns one of:
36
+
37
+ - `"consume"` — `pi-telegram` skips its default routing for this update.
38
+ - `"pass"` or `void` / `undefined` — `pi-telegram` routes the update normally. Other handlers registered after this one still run for the same update.
39
+
40
+ The first handler that returns `"consume"` wins; later handlers are not called for that update.
41
+
42
+ ## Registering a handler
43
+
44
+ Two equivalent paths.
45
+
46
+ ### Typed import (recommended when you can depend on `@llblab/pi-telegram`)
47
+
48
+ ```ts
49
+ import { registerTelegramUpdateHandler } from "@llblab/pi-telegram/updates";
50
+
51
+ const off = registerTelegramUpdateHandler(async (update, execution) => {
52
+ const cb = (update as { callback_query?: { id?: string; data?: string } })
53
+ .callback_query;
54
+ if (!cb?.data?.startsWith("myext:")) return "pass";
55
+ await resolveMyApproval(cb, execution?.signal);
56
+ execution?.assertCurrent();
57
+ return "consume";
58
+ });
59
+
60
+ // Later, when your extension shuts down:
61
+ off();
62
+ ```
63
+
64
+ ### Zero-coupling globalThis lookup
65
+
66
+ When the layered extension prefers no `import` from `@llblab/pi-telegram`, so load order between the two extensions does not matter and either can be installed first, it must implement the **full v1 registry contract**, not just `version` and `add`. pi-telegram's polling runtime calls `dispatch` on whatever object it finds at `globalThis.__piTelegramUpdateHandlerRegistry__`, so a partial object would silently break the first update.
67
+
68
+ pi-telegram defensively re-creates the registry if the object on `globalThis` is missing `add` or `dispatch`, validated as `version === 1`, `typeof add === "function"`, and `typeof dispatch === "function"`. Handlers registered against a malformed object are dropped — make sure your bootstrap implements all three fields.
69
+
70
+ ```ts
71
+ type PiTelegramVerdict =
72
+ | "consume"
73
+ | "pass"
74
+ | void
75
+ | Promise<"consume" | "pass" | void>;
76
+ type PiTelegramUpdateExecutionFence = {
77
+ readonly generation: number;
78
+ readonly updateId: number;
79
+ readonly signal: AbortSignal;
80
+ isCurrent: () => boolean;
81
+ assertCurrent: () => void;
82
+ };
83
+ type PiTelegramUpdateHandler = (
84
+ update: unknown,
85
+ execution?: PiTelegramUpdateExecutionFence,
86
+ ) => PiTelegramVerdict;
87
+
88
+ interface PiTelegramUpdateHandlerRegistry {
89
+ readonly version: 1;
90
+ add: (handler: PiTelegramUpdateHandler) => () => void;
91
+ // Required: pi-telegram's polling loop calls this on every update.
92
+ dispatch: (
93
+ update: unknown,
94
+ execution?: PiTelegramUpdateExecutionFence,
95
+ ) => Promise<"consume" | "pass">;
96
+ }
97
+
98
+ const REGISTRY_KEY = "__piTelegramUpdateHandlerRegistry__";
99
+
100
+ function getOrCreateRegistry(): PiTelegramUpdateHandlerRegistry {
101
+ const g = globalThis as Record<string, unknown>;
102
+ const existing = g[REGISTRY_KEY] as
103
+ | PiTelegramUpdateHandlerRegistry
104
+ | undefined;
105
+ if (
106
+ existing &&
107
+ existing.version === 1 &&
108
+ typeof existing.add === "function" &&
109
+ typeof existing.dispatch === "function"
110
+ ) {
111
+ return existing;
112
+ }
113
+ const handlers = new Set<PiTelegramUpdateHandler>();
114
+ const registry: PiTelegramUpdateHandlerRegistry = {
115
+ version: 1,
116
+ add(handler) {
117
+ handlers.add(handler);
118
+ return () => handlers.delete(handler);
119
+ },
120
+ async dispatch(update, execution) {
121
+ for (const handler of handlers) {
122
+ execution?.assertCurrent();
123
+ try {
124
+ const result = await handler(update, execution);
125
+ if (result === "consume") return "consume";
126
+ } catch {
127
+ // Never break polling because of a handler error.
128
+ }
129
+ }
130
+ return "pass";
131
+ },
132
+ };
133
+ g[REGISTRY_KEY] = registry;
134
+ return registry;
135
+ }
136
+
137
+ const off = getOrCreateRegistry().add((update) => {
138
+ /* … */
139
+ return "pass";
140
+ });
141
+ ```
142
+
143
+ The registry object on `globalThis.__piTelegramUpdateHandlerRegistry__` is versioned (`version: 1`) and stable across pi-telegram releases; the optional second arguments preserve existing v1 callers and implementations. Internal adapters can capture one stable check with `createTelegramUpdateExecutionFenceGuard(update)` or transfer the hidden binding across an unavoidable clone with `carryTelegramUpdateExecutionFence(source, target)`, while `getTelegramUpdateExecutionFence` and `assertTelegramUpdateExecutionCurrent` serve carriers that retain it. Future breaking changes will use a new schema version and a new key.
144
+
145
+ ## Interaction with built-in routing
146
+
147
+ `pi-telegram` invokes registered handlers first, then routes the update through its own handlers: commands, app menu, queue menu, model menu, default prompt routing, and callback namespace fallback. If any handler returns `"consume"`, `pi-telegram` skips the rest of routing for that update.
148
+
149
+ This means:
150
+
151
+ - Extensions can claim callback namespaces that `pi-telegram` would otherwise forward as `[callback] <data>` text.
152
+ - Extensions can observe updates by always returning `"pass"`.
153
+ - Extensions must not consume updates that belong to `pi-telegram`'s own prefixes (`compact:`, `tgbtn:`, `menu:`, `model:`, `thinking:`, `status:`, `queue:`, `settings:`, `section:`) unless they are deliberately replacing that behavior.
154
+
155
+ ## Ownership semantics
156
+
157
+ The handler registry is ownership-agnostic and does not interact with the extension-local transport owner slots documented in [Architecture](./architecture.md#configuration-and-ownership). When the polling runtime loses its `owners.json` slot and stops `getUpdates`, handlers stop receiving updates because no updates are being fetched; they are not unregistered.
158
+
159
+ If a layered extension needs to react to ownership changes, it should observe `pi-telegram` lifecycle events through the standard pi extension hooks rather than through the handler registry.
160
+
161
+ ## Not a transport multiplexer
162
+
163
+ This registry does not bypass Telegram's single-polling-connection-per-bot constraint and does not route updates between processes. Threaded Mode provides the separate profile-scoped leader/follower bus: the leader owns `getUpdates`, applies its process-local update registry, and then routes retained built-in traffic to the owning instance. The registry remains an in-process extension interception surface only.
164
+
165
+ ## Relationship to extension sections
166
+
167
+ Update handlers are the raw update primitive. Extension sections are the structured Telegram UI layer above that primitive.
168
+
169
+ Use update handlers for immediate update interception, custom callback namespaces, out-of-band Promise resolution, and update types that should not become a Telegram menu surface.
170
+
171
+ Use extension sections when the desired behavior is a menu-integrated UI: `render(ctx)`, managed callback dispatch, safe runtime ports, stale-callback handling, and diagnostics owned by `pi-telegram`.
@@ -0,0 +1,217 @@
1
+ # Voice Integration
2
+
3
+ Voice messages flow through an **inbound transcription → outbound voice reply** pipeline. This document describes the bridge's role in that pipeline; provider-specific mechanics (TTS/STT backends, voice IDs, languages) are owned by voice provider extensions. This is a first-class extension surface: one companion extension can provide STT fallbacks for inbound voice/audio files and TTS fallbacks for outbound Telegram voice replies without owning a second bot polling loop.
4
+
5
+ ## Overview
6
+
7
+ 1. **Inbound:** A voice message arrives via Telegram. Inbound handlers transcribe it to text.
8
+ 2. **Processing:** The transcription becomes the agent prompt. The bridge tags the turn if it originated from voice.
9
+ 3. **Outbound:** If voice replies are enabled, the agent's text response is converted to voice and sent back. No text draft appears in Telegram during generation.
10
+
11
+ The bridge owns Telegram transport, queue integration, reply-mode policy, preview suppression, fallback text delivery, and Settings UI. Provider extensions own STT/TTS calls, speech rewriting, provider-specific menus, transcript preference, and OGG/Opus conversion.
12
+
13
+ ## Voice Detection
14
+
15
+ Voice messages arrive as `message.voice` in Telegram updates. The bridge's media processing detects these and sets `kind: "voice"` on the downloaded file. Regular audio files (`message.audio`) get `kind: "audio"`; `mirror` mode treats both voice notes and audio uploads as voice input for reply-policy tagging.
16
+
17
+ Inbound handlers match `kind: "voice"` or `mime: "audio/*"` to run a transcription command:
18
+
19
+ ```json
20
+ {
21
+ "inboundHandlers": [
22
+ {
23
+ "mime": "audio/*",
24
+ "template": ["/path/to/stt", "--file={file}", "--mime={mime}"]
25
+ }
26
+ ]
27
+ }
28
+ ```
29
+
30
+ The transcription output becomes the raw text of the prompt.
31
+
32
+ Voice provider extensions can also register STT backends with `registerTelegramVoiceTranscriptionProvider()` from `@llblab/pi-telegram/voice`. Inbound command-template handlers and programmatic inbound handlers remain the stronger generic paths and run first; if no matching handler produces output for a voice/audio file, registered transcription providers are tried as fallback in registration order. The first provider that returns non-empty text wins; providers that return `undefined` pass to the next provider, and provider failures are recorded before trying the next provider. This lets a full voice extension provide both TTS and STT without requiring `telegram.json` handler templates, while still preserving operator-configured inbound handlers as the stronger choice.
33
+
34
+ ## Voice Reply Policy
35
+
36
+ The bridge decides **when** to reply with voice from `voice.replyMode` in `TelegramConfig` (stored in `telegram.json`). Missing, invalid, `hidden`, and legacy `manual` values resolve to the silent `hidden` default.
37
+
38
+ ### Modes
39
+
40
+ - **`hidden` (default):** no `voice.replyMode` is stored and no automatic voice context is added; explicit agent-authored `telegram_voice` actions still work.
41
+ - **`mirror`:** voice/audio input activates automatic voice delivery. Text input follows `hidden` behavior.
42
+ - **`always`:** every Telegram turn activates automatic voice delivery.
43
+
44
+ **Warning:** In `always` mode, the bridge transparently intercepts ALL text replies and converts them to voice on success. Users will only receive voice messages when voice generation succeeds. If voice generation fails, the bridge falls back to sending the planned text reply.
45
+
46
+ When a message is received, the bridge resolves the active voice reply mode and tags the turn:
47
+
48
+ - `voiceReplyPreferred`: `true` when mode is `mirror` and the turn has a voice file
49
+ - `voiceReplyRequired`: `true` when mode is `always`
50
+
51
+ At `agent_end`, if the turn is voice-tagged and the agent response has no explicit `telegram_voice` markup, the bridge transparently intercepts the text reply and converts it to voice. If the agent uses multiple `telegram_voice` blocks, each becomes a separate voice message. The same reply-mode decision applies to both registered voice synthesis providers and configured outbound voice handlers.
52
+
53
+ ### Preview Suppression
54
+
55
+ When a turn is voice-tagged, the bridge suppresses text preview streaming during LLM generation. This prevents draft text from appearing in Telegram before the voice message is delivered.
56
+
57
+ ## Voice Provider Extension Surface
58
+
59
+ A voice extension may combine three public seams:
60
+
61
+ - `registerTelegramVoiceTranscriptionProvider()` for inbound STT fallback on voice/audio files
62
+ - `registerTelegramVoiceSynthesisProvider()` for outbound TTS/synthesis fallback to Telegram voice messages
63
+ - `registerTelegramSection()` for provider-specific Telegram UI such as voice, language, style, transcript, or provider on/off controls
64
+
65
+ The reply policy itself remains a built-in pi-telegram setting (`voice.replyMode`) rather than a provider-owned menu.
66
+
67
+ ## Outbound Voice Synthesis Provider Registration
68
+
69
+ Voice synthesis provider extensions register themselves through `registerTelegramVoiceSynthesisProvider()`. The bridge only provides the registration seam and the actual delivery to Telegram. **The provider is fully responsible for**:
70
+
71
+ - Text optimisation / speech-style rewriting
72
+ - Adding speech tags (when desired)
73
+ - Running TTS + ffmpeg conversion to OGG/Opus
74
+ - Deciding whether to return `transcriptText` at all based on the bridge-owned `voice.sendTranscript` preference when the provider has access to the current Telegram config
75
+ - `transcriptText` (when returned) is attached by the bridge as the voice message **caption** only. Separate transcript messages are no longer sent.
76
+
77
+ The bridge shows a `record_voice` action while delivering and sends the final audio with Telegram `sendVoice`. When a provider returns `transcriptText`, the bridge attaches it as the voice caption.
78
+
79
+ Providers can implement `getVoicePromptContribution(view)` to inject voice-specific instructions into voice-tagged prompts (for example: "Reply only with the spoken text"). The bridge appends the first non-empty provider contribution when `mirror` or `always` mode tags the turn.
80
+
81
+ Import provider APIs from `@llblab/pi-telegram/voice`; see the TSDoc on `registerTelegramVoiceSynthesisProvider` and `TelegramVoiceSynthesisProviderResult` there for the exact interface.
82
+
83
+ The provider receives the raw agent text plus optional `{ lang?, rate? }`.
84
+
85
+ It must return one of:
86
+
87
+ - `string` — path to a ready `.ogg` or `.opus` file
88
+ - `{ audioPath: string, transcriptText?: string }` — `audioPath` must be OGG/Opus. When `transcriptText` is present it is attached as the voice message **caption**. Providers should treat pi-telegram's `voice.sendTranscript` as the bridge-owned transcript preference instead of inventing a second reply-policy UI.
89
+ - `undefined` — skip this text block
90
+
91
+ **Important:** Providers are fully responsible for producing a clean, TTS-optimised native voice file. The bridge may also run configured outbound voice command templates for users who prefer process-boundary handlers instead of provider extensions.
92
+
93
+ **File format:** Telegram `sendVoice` requires **OGG/Opus** to display the message as a native voice note (waveform, inline playback). MP3 and other formats are accepted by the API but render as regular audio attachments (music note icon, filename visible). **Providers and outbound voice handlers must return `.ogg` or `.opus` files.** Returning non-OGG files causes the bridge to throw and fall back to text delivery.
94
+
95
+ Registration returns a disposer function for cleanup. Stable provider registrations pass a durable `id` in options; omitted ids remain a compatibility path for older providers and receive generated session-local ids. Extensions should call disposers on shutdown or re-register safely on session start when their runtime is recreated.
96
+
97
+ ## Outbound Voice Handlers
98
+
99
+ Users can also configure `outboundHandlers` with `type: "voice"` in `telegram.json`. This is the command-template path for TTS without a provider extension. Reply modes (`hidden`, `mirror`, `always`) affect these handlers the same way they affect providers: explicit `telegram_voice` blocks and automatic mirror/always interception both produce a voice reply plan, then delivery tries configured outbound voice handlers first and registered synthesis providers as progressive fallbacks.
100
+
101
+ Voice handlers receive the text on stdin in composed pipelines and can use `{text}`, `{lang}`, `{rate}`, `{mp3}`, and `{ogg}` placeholders. Set `output` to `"ogg"` or another placeholder name when the template writes to a known path:
102
+
103
+ ```json
104
+ {
105
+ "voice": { "replyMode": "mirror" },
106
+ "outboundHandlers": [
107
+ {
108
+ "type": "voice",
109
+ "template": [
110
+ "/path/to/tts --write-media {mp3}",
111
+ "ffmpeg -y -i {mp3} -c:a libopus -b:a 32k -ar 16000 -ac 1 {ogg}"
112
+ ],
113
+ "output": "ogg"
114
+ }
115
+ ]
116
+ }
117
+ ```
118
+
119
+ Priority for outbound voice delivery is: configured `outboundHandlers` with `type: "voice"` in their `telegram.json` order, then programmatic `voice` outbound handlers, then registered voice synthesis providers. Provider extensions are the zero-config tail of the same pipeline: they handle voice when no explicit configured handler succeeds, but they do not override operator-configured handlers. If multiple providers are registered, only one handles a given voice reply: the first provider that returns a valid `.ogg`/`.opus` artifact wins. Providers that return `undefined` explicitly pass to the next provider; providers that throw or return invalid output are recorded and the next fallback is tried.
120
+
121
+ ### Provider with transcript caption (controlled by user toggle)
122
+
123
+ When the user's "Send Transcript" toggle is ON, return the clean spoken text as `transcriptText`. The bridge attaches it as the caption on the voice message. When the toggle is OFF, return only the audio path (no `transcriptText`).
124
+
125
+ ```typescript
126
+ import {
127
+ getTelegramVoiceSendTranscript,
128
+ registerTelegramVoiceSynthesisProvider,
129
+ } from "@llblab/pi-telegram/voice";
130
+
131
+ registerTelegramVoiceSynthesisProvider(
132
+ async (text, options) => {
133
+ const rewritten = rewriteWithSpeechTags(text);
134
+ const audioPath = await myTTS(rewritten, { language: options?.lang });
135
+ const sendTranscript = getTelegramVoiceSendTranscript(
136
+ getCurrentTelegramConfigView(),
137
+ );
138
+ return sendTranscript ? { audioPath, transcriptText: text } : { audioPath };
139
+ },
140
+ { id: "my-voice-provider/tts" },
141
+ );
142
+ ```
143
+
144
+ `getCurrentTelegramConfigView()` represents whatever current `TelegramConfig` view your extension already owns or receives; pi-telegram does not require providers to read config directly. The bridge never sends a separate transcript message. Caption-only is the "ON" behavior.
145
+
146
+ ### Surfacing provider diagnostics
147
+
148
+ Voice provider extensions can record runtime events that appear in `/telegram-status` alongside pi-telegram's own events:
149
+
150
+ ```typescript
151
+ import { recordTelegramRuntimeEvent } from "@llblab/pi-telegram/outbound";
152
+
153
+ recordTelegramRuntimeEvent("voice-provider", new Error("TTS failed"), {
154
+ phase: "tts",
155
+ text: text.slice(0, 50),
156
+ });
157
+ ```
158
+
159
+ `recordTelegramRuntimeEvent` writes to the same event ring that pi-telegram uses. Events are visible via `/telegram-status` in Telegram. Calls are silently dropped if pi-telegram is not loaded.
160
+
161
+ ## Voice Extension Section
162
+
163
+ Voice provider extensions can register a Voice Extension Section (settings UI) via `registerTelegramSection`. The section can expose provider-specific controls such as TTS voice, language, speech style, transcript behavior, or STT/TTS enablement. Reply mode is a core pi-telegram setting and belongs in the built-in Settings menu.
164
+
165
+ **Note on resume:** Because the previous automatic persistent re-registration system has been removed, extensions are responsible for re-registering their Voice Extension Section on `session_start` if they want the menu to survive a `pi resume`. See `registerTelegramSection` from `@llblab/pi-telegram/sections`.
166
+
167
+ ## Prompt Guidance
168
+
169
+ The bridge keeps voice prompt context compact, effective, and policy-owned. `hidden` and text-originated `mirror` turns add no voice line. Voice/audio-originated `mirror` turns and every `always` turn add exactly `[voice] delivery: automatic voice`, describing the current delivery environment without exposing the underlying mode matrix or an instruction list. The marker is appended after `[outputs]` when handler output exists, otherwise after `[attachments]`. Voice inputs also appear in `[attachments]` with their downloaded file names, MIME data, and handler output, so agents can infer concrete voice-file context from attachment metadata.
170
+
171
+ Voice synthesis providers can supply prompt guidance through `getVoicePromptContribution(view)`, but provider text should stay optional and provider-specific. Reply-mode context belongs to pi-telegram.
172
+
173
+ ## Fallback Behavior
174
+
175
+ ### If voice generation fails
176
+
177
+ 1. The bridge records the failure via `recordRuntimeEvent`
178
+ 2. The voice sender throws an error, which the runtime catches
179
+ 3. The runtime falls back to sending the planned text reply (outbound markup stripped, `replyMarkup` preserved)
180
+
181
+ ### If no voice synthesis provider is registered
182
+
183
+ - The voice sender throws because no configured handler or synthesis provider can deliver the voice reply
184
+ - The runtime catches the error and falls back to text delivery
185
+
186
+ ### If the provider returns a non-OGG file
187
+
188
+ - `ensureTelegramVoiceFileFormat` rejects the file (only `.ogg` and `.opus` are accepted)
189
+ - The voice sender throws and the runtime falls back to text delivery
190
+ - The provider should handle format conversion internally before returning the path
191
+
192
+ ## Telegram Voice Limits
193
+
194
+ - **Duration:** Up to ~60 minutes per voice message
195
+ - **File size:** Up to 20 MB for voice uploads via `sendVoice`
196
+ - **Format:** OGG Opus is native; MP3 and other formats render as regular audio attachments
197
+ - **Splitting:** The bridge does not split long responses into multiple voice messages. Chunking is the provider's responsibility
198
+
199
+ ## Configuration
200
+
201
+ ### Bridge config (`telegram.json`)
202
+
203
+ ```json
204
+ {
205
+ "voice": {
206
+ "replyMode": "mirror"
207
+ }
208
+ }
209
+ ```
210
+
211
+ Valid modes are `"hidden"`, `"mirror"`, and `"always"`; selecting `hidden` removes the key. Missing, invalid, and legacy `"manual"` values resolve to `hidden` and stay silent in prompt context.
212
+
213
+ The bridge reads `voice.replyMode` from the config when building a turn.
214
+
215
+ ### Provider config
216
+
217
+ Provider-specific settings (voice ID, language, speech style, transcript behavior, STT/TTS enablement) are owned by the voice provider extension. Reply mode is owned by pi-telegram's `voice.replyMode` and configured from the built-in pi-telegram Settings menu, not duplicated in provider UIs.