@crouton-kit/crouter 0.3.33 → 0.3.34

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 (566) hide show
  1. package/README.md +2 -2
  2. package/dist/build-root.js +3 -6
  3. package/dist/builtin-memory/crouter-development/marketplaces.md +6 -6
  4. package/dist/builtin-memory/crouter-development/plugins.md +13 -13
  5. package/dist/builtin-memory/internal/examples/imessage-assistant.md +3 -3
  6. package/dist/builtin-memory/internal/nodes-and-canvas.md +4 -4
  7. package/dist/builtin-personas/developer/PERSONA.md +1 -1
  8. package/dist/builtin-personas/orchestration-kernel.md +1 -1
  9. package/dist/builtin-personas/waiting.md +1 -1
  10. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +71 -0
  11. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-help-gate.test.ts +41 -0
  12. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +663 -0
  13. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +52 -0
  14. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +418 -0
  15. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crouter-help.ts +87 -0
  16. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/filters.json +7 -0
  17. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/index.ts +174 -0
  18. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-help-gate.ts +408 -0
  19. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +442 -0
  20. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +119 -0
  21. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/nested-context.ts +327 -0
  22. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +574 -0
  23. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +260 -0
  24. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/strip-skills-docs.ts +40 -0
  25. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/sysprompt-window.ts +19 -0
  26. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/package.json +3 -0
  27. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.js +1 -0
  28. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.ts +479 -0
  29. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/LICENSE +13 -0
  30. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/README.md +172 -0
  31. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/bin.mjs +11 -0
  32. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/composer.js +219 -0
  37. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
  38. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
  39. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
  40. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
  41. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
  42. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +225 -0
  43. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
  44. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
  47. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
  48. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/Document.js +335 -0
  49. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
  50. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
  51. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
  52. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/directives.js +176 -0
  53. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/errors.js +57 -0
  54. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/index.js +17 -0
  55. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/log.js +11 -0
  56. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Alias.js +116 -0
  57. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
  58. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
  59. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
  60. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
  61. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
  62. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
  63. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
  64. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
  65. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
  66. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
  67. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
  68. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
  69. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst.js +98 -0
  70. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
  71. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
  72. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/parser.js +975 -0
  73. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/public-api.js +102 -0
  74. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
  75. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
  76. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
  77. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
  78. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
  79. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
  80. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
  81. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
  82. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
  83. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
  84. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/tags.js +96 -0
  85. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
  86. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
  87. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
  88. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
  89. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
  90. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
  91. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
  92. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
  93. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
  94. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
  95. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
  96. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
  97. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
  98. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
  99. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
  100. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
  101. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
  102. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
  103. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/util.js +11 -0
  104. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/visit.js +233 -0
  105. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/index.js +5 -0
  106. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/package.json +3 -0
  107. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/cli.d.ts +8 -0
  108. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/cli.mjs +201 -0
  109. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
  110. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-collection.js +90 -0
  111. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
  112. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-doc.js +45 -0
  113. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
  114. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-node.js +112 -0
  115. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
  116. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
  117. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/composer.d.ts +63 -0
  118. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/composer.js +224 -0
  119. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  120. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
  121. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  122. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
  123. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  124. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
  125. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
  126. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-end.js +39 -0
  127. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  128. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
  129. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  130. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-scalar.js +227 -0
  131. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
  132. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-props.js +148 -0
  133. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  134. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
  135. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  136. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
  137. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  138. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
  139. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
  140. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
  141. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/Document.d.ts +141 -0
  142. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/Document.js +337 -0
  143. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
  144. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/anchors.js +76 -0
  145. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
  146. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/applyReviver.js +57 -0
  147. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
  148. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/createNode.js +90 -0
  149. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/directives.d.ts +49 -0
  150. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/directives.js +178 -0
  151. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/errors.d.ts +21 -0
  152. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/errors.js +62 -0
  153. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/index.d.ts +25 -0
  154. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/index.js +50 -0
  155. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/log.d.ts +3 -0
  156. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/log.js +19 -0
  157. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
  158. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Alias.js +118 -0
  159. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
  160. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Collection.js +151 -0
  161. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
  162. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Node.js +40 -0
  163. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
  164. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Pair.js +39 -0
  165. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
  166. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Scalar.js +27 -0
  167. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  168. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
  169. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  170. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
  171. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  172. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
  173. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
  174. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/identity.js +53 -0
  175. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
  176. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/toJS.js +39 -0
  177. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/options.d.ts +350 -0
  178. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
  179. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
  180. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
  181. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
  182. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
  183. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-visit.js +99 -0
  184. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst.d.ts +109 -0
  185. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst.js +112 -0
  186. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
  187. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/lexer.js +723 -0
  188. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
  189. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/line-counter.js +41 -0
  190. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/parser.d.ts +84 -0
  191. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/parser.js +980 -0
  192. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/public-api.d.ts +44 -0
  193. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/public-api.js +107 -0
  194. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
  195. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/Schema.js +39 -0
  196. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
  197. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/map.js +19 -0
  198. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
  199. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/null.js +17 -0
  200. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
  201. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/seq.js +19 -0
  202. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
  203. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/string.js +16 -0
  204. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
  205. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/bool.js +21 -0
  206. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
  207. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/float.js +47 -0
  208. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
  209. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/int.js +42 -0
  210. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
  211. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/schema.js +25 -0
  212. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
  213. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/json/schema.js +64 -0
  214. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
  215. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/tags.d.ts +48 -0
  216. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/tags.js +99 -0
  217. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/types.d.ts +92 -0
  218. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  219. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
  220. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  221. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  222. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  223. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
  224. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  225. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
  226. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
  227. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
  228. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
  229. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  230. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  231. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  232. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  233. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
  234. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  235. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
  236. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  237. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  238. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  239. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
  240. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
  241. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringify.js +132 -0
  242. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  243. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
  244. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  245. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
  246. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  247. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
  248. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  249. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
  250. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  251. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
  252. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
  253. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
  254. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/test-events.d.ts +4 -0
  255. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/test-events.js +134 -0
  256. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/util.d.ts +16 -0
  257. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/util.js +28 -0
  258. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/visit.d.ts +102 -0
  259. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/visit.js +236 -0
  260. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/package.json +97 -0
  261. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/util.js +2 -0
  262. package/dist/builtin-pi-packages/pi-crtr-extensions/package-lock.json +3385 -0
  263. package/dist/builtin-pi-packages/pi-crtr-extensions/package.json +25 -0
  264. package/dist/builtin-pi-packages/pi-mode-switch/README.md +64 -0
  265. package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +40 -0
  266. package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +422 -0
  267. package/dist/builtin-pi-packages/pi-mode-switch/package.json +13 -0
  268. package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +55 -0
  269. package/dist/clients/attach/__tests__/crtr-output-render.test.js +2340 -0
  270. package/dist/clients/attach/attach-cmd.js +826 -754
  271. package/dist/clients/attach/auth-pickers.js +2 -2
  272. package/dist/clients/attach/canvas-panels.js +1 -1
  273. package/dist/clients/attach/chat-view.d.ts +3 -2
  274. package/dist/clients/attach/chat-view.js +30 -10
  275. package/dist/clients/attach/clipboard-image.js +1 -1
  276. package/dist/clients/attach/clipboard-text.js +1 -1
  277. package/dist/clients/attach/config-load.js +1 -1
  278. package/dist/clients/attach/crtr-output-render.d.ts +48 -0
  279. package/dist/clients/attach/crtr-output-render.js +646 -0
  280. package/dist/clients/attach/extension-dialogs.js +1 -1
  281. package/dist/clients/attach/graph-overlay.js +3 -3
  282. package/dist/clients/attach/input-controller.js +1 -1
  283. package/dist/clients/attach/pickers.js +1 -1
  284. package/dist/clients/attach/slash-commands.js +5 -6
  285. package/dist/clients/attach/titled-editor.d.ts +4 -0
  286. package/dist/clients/attach/titled-editor.js +13 -1
  287. package/dist/clients/attach/view-socket.js +1 -1
  288. package/dist/clients/web/__tests__/source-cache.test.js +5 -5
  289. package/dist/clients/web/server.js +29 -5
  290. package/dist/clients/web/source-cache.js +3 -3
  291. package/dist/clients/web/web-cmd.js +7 -7
  292. package/dist/commands/canvas-issue.js +1 -1
  293. package/dist/commands/canvas-prune.js +24 -2
  294. package/dist/commands/canvas-snapshot.js +3 -0
  295. package/dist/commands/canvas-tmux-spread.js +3 -3
  296. package/dist/commands/human.js +1 -1
  297. package/dist/commands/memory/lint.js +15 -8
  298. package/dist/commands/memory/origin.d.ts +1 -0
  299. package/dist/commands/memory/origin.js +88 -0
  300. package/dist/commands/memory/shared.d.ts +8 -0
  301. package/dist/commands/memory/shared.js +22 -1
  302. package/dist/commands/memory/write.js +17 -12
  303. package/dist/commands/memory.js +4 -3
  304. package/dist/commands/node-context.js +4 -4
  305. package/dist/commands/node-snapshot.js +4 -1
  306. package/dist/commands/node.d.ts +2 -2
  307. package/dist/commands/node.js +814 -606
  308. package/dist/commands/pkg/market-inspect.d.ts +2 -1
  309. package/dist/commands/pkg/market-inspect.js +14 -32
  310. package/dist/commands/pkg/market-manage.d.ts +3 -1
  311. package/dist/commands/pkg/market-manage.js +58 -154
  312. package/dist/commands/pkg/market.js +7 -7
  313. package/dist/commands/pkg/plugin-inspect.d.ts +2 -1
  314. package/dist/commands/pkg/plugin-inspect.js +8 -24
  315. package/dist/commands/pkg/plugin-manage.d.ts +5 -1
  316. package/dist/commands/pkg/plugin-manage.js +245 -171
  317. package/dist/commands/pkg/plugin.js +6 -6
  318. package/dist/commands/pkg.js +5 -5
  319. package/dist/commands/revive.js +5 -3
  320. package/dist/commands/search/answer.js +1 -1
  321. package/dist/commands/search/contents.js +1 -1
  322. package/dist/commands/search/web.js +2 -2
  323. package/dist/commands/search.js +1 -1
  324. package/dist/commands/surface.d.ts +2 -0
  325. package/dist/commands/surface.js +43 -0
  326. package/dist/commands/sys/promptstudio.js +1 -1
  327. package/dist/commands/sys/settings.js +2 -2
  328. package/dist/commands/sys/setup-core.d.ts +88 -0
  329. package/dist/commands/sys/setup-core.js +352 -0
  330. package/dist/commands/sys/setup.d.ts +2 -0
  331. package/dist/commands/sys/setup.js +516 -0
  332. package/dist/commands/sys/sysprompt.js +3 -0
  333. package/dist/commands/sys.js +3 -2
  334. package/dist/commands/view-cycle.js +5 -5
  335. package/dist/commands/view-list.js +3 -3
  336. package/dist/commands/view-new.js +5 -5
  337. package/dist/commands/view-pick.js +6 -6
  338. package/dist/commands/view-run.js +14 -14
  339. package/dist/commands/view.js +3 -3
  340. package/dist/commands/workspace.js +10 -10
  341. package/dist/core/__tests__/boot.test.js +140 -0
  342. package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -27
  343. package/dist/core/__tests__/daemon-boot.test.js +22 -0
  344. package/dist/core/__tests__/fixtures/fake-engine.js +1 -1
  345. package/dist/core/__tests__/full/broker-attach-limits.test.js +1 -1
  346. package/dist/core/__tests__/full/broker-attach-stream.test.js +1 -1
  347. package/dist/core/__tests__/full/broker-crash-teardown.test.js +10 -5
  348. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +1 -1
  349. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +1 -1
  350. package/dist/core/__tests__/full/broker-pane-resolution.test.js +1 -1
  351. package/dist/core/__tests__/full/cascade-close.test.js +31 -18
  352. package/dist/core/__tests__/full/detach-focus.test.js +2 -2
  353. package/dist/core/__tests__/hearth-bootstrap.test.js +136 -0
  354. package/dist/core/__tests__/helpers/harness.js +1 -1
  355. package/dist/core/__tests__/live-mutation-verbs.test.js +10 -10
  356. package/dist/core/__tests__/live-mutation.test.js +8 -8
  357. package/dist/core/__tests__/migration.test.js +124 -0
  358. package/dist/core/__tests__/on-read-dedup-resume.test.js +40 -0
  359. package/dist/core/__tests__/preview-registry-sync.test.js +36 -0
  360. package/dist/core/__tests__/prune-to-limit.test.js +91 -0
  361. package/dist/core/__tests__/revive.test.js +64 -21
  362. package/dist/core/__tests__/trigger-migration.test.js +48 -0
  363. package/dist/core/__tests__/wake-bearings.test.js +23 -21
  364. package/dist/core/__tests__/wake-origin.test.js +36 -33
  365. package/dist/core/canvas/boot.d.ts +48 -0
  366. package/dist/core/canvas/boot.js +157 -0
  367. package/dist/core/canvas/canvas.d.ts +27 -1
  368. package/dist/core/canvas/canvas.js +86 -5
  369. package/dist/core/canvas/db.js +86 -1
  370. package/dist/core/canvas/index.d.ts +1 -1
  371. package/dist/core/canvas/index.js +1 -1
  372. package/dist/core/canvas/nav-model.js +1 -1
  373. package/dist/core/canvas/pid.d.ts +6 -0
  374. package/dist/core/canvas/pid.js +13 -0
  375. package/dist/core/canvas/triggers.d.ts +108 -0
  376. package/dist/core/canvas/triggers.js +320 -0
  377. package/dist/core/canvas/types.d.ts +128 -46
  378. package/dist/core/command.js +13 -4
  379. package/dist/core/hearth/__tests__/model-auth-guest.test.js +151 -0
  380. package/dist/core/hearth/config.d.ts +1 -0
  381. package/dist/core/hearth/config.js +36 -0
  382. package/dist/core/hearth/guest-env.d.ts +7 -0
  383. package/dist/core/hearth/guest-env.js +17 -1
  384. package/dist/core/hearth/model-auth-guest.d.ts +8 -0
  385. package/dist/core/hearth/model-auth-guest.js +435 -0
  386. package/dist/core/hearth/provider.d.ts +13 -6
  387. package/dist/core/hearth/providers/blaxel-bootstrap.d.ts +2 -0
  388. package/dist/core/hearth/providers/blaxel-bootstrap.js +127 -19
  389. package/dist/core/hearth/providers/blaxel-home.d.ts +8 -4
  390. package/dist/core/hearth/providers/blaxel-home.js +85 -75
  391. package/dist/core/hearth/providers/blaxel.d.ts +5 -0
  392. package/dist/core/hearth/providers/blaxel.js +86 -12
  393. package/dist/core/hearth/providers/types.d.ts +6 -1
  394. package/dist/core/hearth/registry.js +2 -1
  395. package/dist/core/hearth/types.d.ts +35 -0
  396. package/dist/core/help.d.ts +16 -0
  397. package/dist/core/help.js +2 -0
  398. package/dist/core/memory-resolver.d.ts +8 -8
  399. package/dist/core/memory-resolver.js +58 -26
  400. package/dist/core/preview-registry.d.ts +25 -0
  401. package/dist/core/preview-registry.js +2047 -0
  402. package/dist/core/resolver.d.ts +1 -0
  403. package/dist/core/resolver.js +23 -16
  404. package/dist/core/runtime/bearings.d.ts +11 -10
  405. package/dist/core/runtime/bearings.js +8 -8
  406. package/dist/core/runtime/broker-protocol.d.ts +2 -2
  407. package/dist/core/runtime/broker-protocol.js +2 -2
  408. package/dist/core/runtime/close.js +2 -2
  409. package/dist/core/runtime/kickoff.js +1 -1
  410. package/dist/core/runtime/launch.d.ts +9 -3
  411. package/dist/core/runtime/launch.js +17 -9
  412. package/dist/core/runtime/lifecycle.js +7 -7
  413. package/dist/core/runtime/model-swap.js +1 -1
  414. package/dist/core/runtime/placement.d.ts +5 -5
  415. package/dist/core/runtime/placement.js +10 -10
  416. package/dist/core/runtime/recycle.js +7 -7
  417. package/dist/core/runtime/reset.d.ts +1 -1
  418. package/dist/core/runtime/reset.js +3 -3
  419. package/dist/core/runtime/revive-all.d.ts +5 -2
  420. package/dist/core/runtime/revive-all.js +5 -2
  421. package/dist/core/runtime/revive.d.ts +15 -8
  422. package/dist/core/runtime/revive.js +52 -16
  423. package/dist/core/runtime/spawn.d.ts +1 -1
  424. package/dist/core/runtime/spawn.js +7 -7
  425. package/dist/core/runtime/stop-guard.js +5 -5
  426. package/dist/core/runtime/surface-bg.js +1 -1
  427. package/dist/core/runtime/tmux.d.ts +1 -1
  428. package/dist/core/runtime/tmux.js +4 -4
  429. package/dist/core/scope.d.ts +9 -0
  430. package/dist/core/scope.js +37 -15
  431. package/dist/core/substrate/on-read.js +23 -21
  432. package/dist/core/substrate/render.js +3 -3
  433. package/dist/core/view/loader.js +2 -2
  434. package/dist/core/wake.d.ts +2 -2
  435. package/dist/core/wake.js +7 -7
  436. package/dist/daemon/__tests__/predicate-eval.test.js +109 -0
  437. package/dist/daemon/crtrd.js +222 -103
  438. package/dist/daemon/predicate-eval.d.ts +52 -0
  439. package/dist/daemon/predicate-eval.js +248 -0
  440. package/dist/hearth/control-plane/__tests__/node-message.test.js +60 -0
  441. package/dist/hearth/control-plane/__tests__/rate-limit-recurrence.test.js +49 -0
  442. package/dist/hearth/control-plane/__tests__/relay-security.test.js +314 -0
  443. package/dist/hearth/control-plane/__tests__/scheduler-scan-loop.test.js +133 -0
  444. package/dist/hearth/control-plane/__tests__/trigger-delivery.test.js +170 -0
  445. package/dist/hearth/control-plane/__tests__/webhook-ingress.test.js +167 -0
  446. package/dist/hearth/control-plane/config.d.ts +21 -0
  447. package/dist/hearth/control-plane/config.js +77 -0
  448. package/dist/hearth/control-plane/db.d.ts +30 -0
  449. package/dist/hearth/control-plane/db.js +534 -0
  450. package/dist/hearth/control-plane/ingress/rate-limit.d.ts +24 -0
  451. package/dist/hearth/control-plane/ingress/rate-limit.js +100 -0
  452. package/dist/hearth/control-plane/ingress/route-store.d.ts +31 -0
  453. package/dist/hearth/control-plane/ingress/route-store.js +61 -0
  454. package/dist/hearth/control-plane/ingress/webhook-delivery-store.d.ts +41 -0
  455. package/dist/hearth/control-plane/ingress/webhook-delivery-store.js +69 -0
  456. package/dist/hearth/control-plane/ingress/webhook-route.d.ts +55 -0
  457. package/dist/hearth/control-plane/ingress/webhook-route.js +285 -0
  458. package/dist/hearth/control-plane/main.js +88 -0
  459. package/dist/hearth/control-plane/node-message.d.ts +31 -0
  460. package/dist/hearth/control-plane/node-message.js +98 -0
  461. package/dist/hearth/control-plane/register.d.ts +15 -0
  462. package/dist/hearth/control-plane/register.js +34 -0
  463. package/dist/hearth/control-plane/registry.d.ts +17 -0
  464. package/dist/hearth/control-plane/registry.js +161 -0
  465. package/dist/hearth/control-plane/relay.d.ts +40 -0
  466. package/dist/hearth/control-plane/relay.js +642 -0
  467. package/dist/hearth/control-plane/scheduler/fire-store.d.ts +36 -0
  468. package/dist/hearth/control-plane/scheduler/fire-store.js +73 -0
  469. package/dist/hearth/control-plane/scheduler/recurrence.d.ts +7 -0
  470. package/dist/hearth/control-plane/scheduler/recurrence.js +58 -0
  471. package/dist/hearth/control-plane/scheduler/scan-loop.d.ts +38 -0
  472. package/dist/hearth/control-plane/scheduler/scan-loop.js +138 -0
  473. package/dist/hearth/control-plane/scheduler/schedule-store.d.ts +32 -0
  474. package/dist/hearth/control-plane/scheduler/schedule-store.js +66 -0
  475. package/dist/hearth/control-plane/secrets.d.ts +17 -0
  476. package/dist/hearth/control-plane/secrets.js +113 -0
  477. package/dist/hearth/control-plane/server.d.ts +27 -0
  478. package/dist/hearth/control-plane/server.js +346 -0
  479. package/dist/hearth/control-plane/session.d.ts +68 -0
  480. package/dist/hearth/control-plane/session.js +273 -0
  481. package/dist/hearth/control-plane/triggers/acl.d.ts +14 -0
  482. package/dist/hearth/control-plane/triggers/acl.js +52 -0
  483. package/dist/hearth/control-plane/triggers/audit-store.d.ts +38 -0
  484. package/dist/hearth/control-plane/triggers/audit-store.js +79 -0
  485. package/dist/hearth/control-plane/triggers/deliver.d.ts +43 -0
  486. package/dist/hearth/control-plane/triggers/deliver.js +76 -0
  487. package/dist/hearth/control-plane/triggers/envelope.d.ts +29 -0
  488. package/dist/hearth/control-plane/triggers/envelope.js +38 -0
  489. package/dist/hearth/control-plane/types.d.ts +66 -0
  490. package/dist/hearth/control-plane/wake.d.ts +80 -0
  491. package/dist/hearth/control-plane/wake.js +312 -0
  492. package/dist/hearth/wake-proxy/__tests__/guest-source.test.js +2 -2
  493. package/dist/hearth/wake-proxy/home.d.ts +2 -8
  494. package/dist/hearth/wake-proxy/home.js +48 -12
  495. package/dist/pi-extensions/canvas-doc-substrate.js +28 -2
  496. package/dist/pi-extensions/canvas-nav.js +1 -1
  497. package/dist/prompts/view.js +7 -8
  498. package/dist/types.js +4 -4
  499. package/dist/web-client/assets/{index-D36PNBj4.js → index-BRKxe-hy.js} +2 -2
  500. package/dist/web-client/index.html +1 -1
  501. package/package.json +12 -8
  502. package/scripts/postinstall.mjs +8 -0
  503. package/dist/clients/attach/__tests__/action-parity.test.js +0 -48
  504. package/dist/clients/attach/__tests__/autocomplete-and-bash-mode.test.js +0 -96
  505. package/dist/clients/attach/__tests__/bash-bang-routing.test.js +0 -58
  506. package/dist/clients/attach/__tests__/bundle-pi-tui-dedup.test.js +0 -56
  507. package/dist/clients/attach/__tests__/clipboard-image.test.js +0 -76
  508. package/dist/clients/attach/__tests__/editor-newline.test.js +0 -82
  509. package/dist/clients/attach/__tests__/git-info.test.js +0 -31
  510. package/dist/clients/attach/__tests__/onrequest-wired.test.js +0 -20
  511. package/dist/clients/attach/__tests__/reconnect-giveup.test.js +0 -30
  512. package/dist/clients/attach/__tests__/slash-quit-copy.test.js +0 -42
  513. package/dist/clients/attach/__tests__/titled-editor.test.js +0 -60
  514. package/dist/commands/memory/__tests__/lint-schema.test.js +0 -52
  515. package/dist/core/__tests__/argv-parser.test.js +0 -217
  516. package/dist/core/__tests__/artifact-paths.test.js +0 -44
  517. package/dist/core/__tests__/draw-style.test.js +0 -258
  518. package/dist/core/__tests__/editor-label.test.js +0 -26
  519. package/dist/core/__tests__/fault-marker.test.js +0 -112
  520. package/dist/core/__tests__/fault-retry-rewind.test.d.ts +0 -1
  521. package/dist/core/__tests__/fault-retry-rewind.test.js +0 -123
  522. package/dist/core/__tests__/frame-decoder-perf.test.d.ts +0 -1
  523. package/dist/core/__tests__/frame-decoder-perf.test.js +0 -224
  524. package/dist/core/__tests__/keystone.test.d.ts +0 -1
  525. package/dist/core/__tests__/keystone.test.js +0 -185
  526. package/dist/core/__tests__/listing-completeness.test.d.ts +0 -1
  527. package/dist/core/__tests__/listing-completeness.test.js +0 -31
  528. package/dist/core/__tests__/memory-resolver.test.d.ts +0 -1
  529. package/dist/core/__tests__/memory-resolver.test.js +0 -119
  530. package/dist/core/__tests__/memory.test.d.ts +0 -1
  531. package/dist/core/__tests__/memory.test.js +0 -60
  532. package/dist/core/__tests__/model-ladders.test.d.ts +0 -1
  533. package/dist/core/__tests__/model-ladders.test.js +0 -160
  534. package/dist/core/__tests__/node-env.test.d.ts +0 -1
  535. package/dist/core/__tests__/node-env.test.js +0 -26
  536. package/dist/core/__tests__/pane-column.test.d.ts +0 -1
  537. package/dist/core/__tests__/pane-column.test.js +0 -153
  538. package/dist/core/__tests__/persona-compose.test.d.ts +0 -1
  539. package/dist/core/__tests__/persona-compose.test.js +0 -53
  540. package/dist/core/__tests__/persona-subkind.test.d.ts +0 -1
  541. package/dist/core/__tests__/persona-subkind.test.js +0 -65
  542. package/dist/core/__tests__/persona.test.d.ts +0 -1
  543. package/dist/core/__tests__/persona.test.js +0 -107
  544. package/dist/core/__tests__/unknown-path.test.d.ts +0 -1
  545. package/dist/core/__tests__/unknown-path.test.js +0 -58
  546. package/dist/core/canvas/wakeups.d.ts +0 -76
  547. package/dist/core/canvas/wakeups.js +0 -185
  548. package/dist/hearth/wake-proxy/__tests__/source-bridge-gate.test.d.ts +0 -1
  549. package/dist/hearth/wake-proxy/__tests__/source-bridge-gate.test.js +0 -455
  550. /package/dist/clients/attach/__tests__/{action-parity.test.d.ts → crtr-output-coverage.test.d.ts} +0 -0
  551. /package/dist/clients/attach/__tests__/{autocomplete-and-bash-mode.test.d.ts → crtr-output-render.test.d.ts} +0 -0
  552. /package/dist/{clients/attach/__tests__/bash-bang-routing.test.d.ts → core/__tests__/boot.test.d.ts} +0 -0
  553. /package/dist/{clients/attach/__tests__/bundle-pi-tui-dedup.test.d.ts → core/__tests__/hearth-bootstrap.test.d.ts} +0 -0
  554. /package/dist/{clients/attach/__tests__/clipboard-image.test.d.ts → core/__tests__/preview-registry-sync.test.d.ts} +0 -0
  555. /package/dist/{clients/attach/__tests__/editor-newline.test.d.ts → core/__tests__/prune-to-limit.test.d.ts} +0 -0
  556. /package/dist/{clients/attach/__tests__/git-info.test.d.ts → core/__tests__/trigger-migration.test.d.ts} +0 -0
  557. /package/dist/{clients/attach/__tests__/onrequest-wired.test.d.ts → core/hearth/__tests__/model-auth-guest.test.d.ts} +0 -0
  558. /package/dist/{clients/attach/__tests__/reconnect-giveup.test.d.ts → daemon/__tests__/predicate-eval.test.d.ts} +0 -0
  559. /package/dist/{clients/attach/__tests__/slash-quit-copy.test.d.ts → hearth/control-plane/__tests__/node-message.test.d.ts} +0 -0
  560. /package/dist/{clients/attach/__tests__/titled-editor.test.d.ts → hearth/control-plane/__tests__/rate-limit-recurrence.test.d.ts} +0 -0
  561. /package/dist/{commands/memory/__tests__/lint-schema.test.d.ts → hearth/control-plane/__tests__/relay-security.test.d.ts} +0 -0
  562. /package/dist/{core/__tests__/argv-parser.test.d.ts → hearth/control-plane/__tests__/scheduler-scan-loop.test.d.ts} +0 -0
  563. /package/dist/{core/__tests__/artifact-paths.test.d.ts → hearth/control-plane/__tests__/trigger-delivery.test.d.ts} +0 -0
  564. /package/dist/{core/__tests__/draw-style.test.d.ts → hearth/control-plane/__tests__/webhook-ingress.test.d.ts} +0 -0
  565. /package/dist/{core/__tests__/editor-label.test.d.ts → hearth/control-plane/main.d.ts} +0 -0
  566. /package/dist/{core/__tests__/fault-marker.test.d.ts → hearth/control-plane/types.js} +0 -0
@@ -0,0 +1,642 @@
1
+ // control-plane/relay.ts — the CP→home HTTP+WS relay engine (P4.3 / part-plan
2
+ // T3.2). Implements the `RelayDispatcher` seam `server.ts` defines: every
3
+ // call here already passed `respondDynamicLane`'s/`handleUpgrade`'s
4
+ // session+registry gate (P4.1) — `home` is the registry row resolved FRESH
5
+ // from the caller's own session this request, never from anything client-
6
+ // supplied (R-CP-2). This module's only job is wake (P4.2's `ensureAwake`)
7
+ // plus the actual byte/frame relay to `home.preview_endpoint`, generalizing
8
+ // M0 `wake-proxy/proxy.ts` from a single-tenant/single-home proxy onto the
9
+ // CP's per-request resolved `Home` row.
10
+ //
11
+ // Re-binding (R-CP-6 / criterion 5): the upstream origin is always
12
+ // `home.preview_endpoint` (resolved by `ensureAwake`, never the request URL)
13
+ // and the WS node target is always `home.home_agent_target` — both read off
14
+ // the `home` row this function was called with. A client cannot widen or
15
+ // redirect the route by supplying `?target=` or a different `/node/<id>`
16
+ // path segment: this design's home model is a single resident root per home
17
+ // (design.md F1 — `home_agent_target` is the only legitimate relay target),
18
+ // and home selection itself is entirely session-derived upstream of this
19
+ // module (server.ts resolves `home` from the session on every call, never
20
+ // from the client). Re-deriving the target from the client path here would
21
+ // only reintroduce the cross-home surface this design avoids; a session for
22
+ // home A can therefore never reach home B's broker through this relay no
23
+ // matter what `?target=`/path id it sends — home B's `preview_endpoint` is
24
+ // never even looked up for that session.
25
+ //
26
+ // Two credentials, two legs (S4): the relay token is resolved by
27
+ // `ensureAwake` (via `secrets.ts`, from `relay_auth_ref`) and injected as the
28
+ // CP→home `Authorization: Bearer` header; the browser/worker leg's own
29
+ // Authorization/Cookie/Proxy-* headers are stripped before the request ever
30
+ // reaches the upstream fetch/WS call (R-CP-3). The browser/worker leg never
31
+ // sees or reflects the relay token.
32
+ import { Readable } from 'node:stream';
33
+ import { WebSocket, WebSocketServer } from 'ws';
34
+ import { BROKER_READ_CAPS } from '../../core/runtime/broker-protocol.js';
35
+ import { general } from '../../core/errors.js';
36
+ import { loadControlPlaneConfig } from './config.js';
37
+ import { ensureAwake, invalidateWarmVerdict, resolveRunning } from './wake.js';
38
+ import { redactSecrets } from './secrets.js';
39
+ import { tenantSessionAuthRedactedMessage } from './session.js';
40
+ const hopByHopHeaders = new Set([
41
+ 'connection',
42
+ 'keep-alive',
43
+ 'proxy-authenticate',
44
+ 'proxy-authorization',
45
+ 'proxy-connection',
46
+ 'te',
47
+ 'trailer',
48
+ 'transfer-encoding',
49
+ 'upgrade',
50
+ ]);
51
+ function redact(message) {
52
+ return redactSecrets(tenantSessionAuthRedactedMessage(message));
53
+ }
54
+ function redactDeep(value) {
55
+ if (typeof value === 'string')
56
+ return redact(value);
57
+ if (Array.isArray(value))
58
+ return value.map((entry) => redactDeep(entry));
59
+ if (value !== null && typeof value === 'object') {
60
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, redactDeep(entry)]));
61
+ }
62
+ return value;
63
+ }
64
+ /** Log a relay-side failure server-side only — never sent to the browser
65
+ * (callers always respond with a generic status + short body). Every field
66
+ * is redacted so a resolved relay token, a session cookie/bearer value, or
67
+ * an `Authorization:`/`?token=` fragment captured in an upstream error
68
+ * message can never reach stderr unredacted (criterion 7). */
69
+ function logError(message, details = {}) {
70
+ process.stderr.write(`${JSON.stringify({ level: 'error', message, details: redactDeep(details) })}\n`);
71
+ }
72
+ function requestPath(req) {
73
+ return req.url ?? '/';
74
+ }
75
+ function decodePathForValidation(raw) {
76
+ for (let i = 0; i < raw.length; i += 1) {
77
+ const ch = raw[i];
78
+ if (ch === '%') {
79
+ const a = raw[i + 1];
80
+ const b = raw[i + 2];
81
+ if (a === undefined || b === undefined || !/[0-9A-Fa-f]/.test(a) || !/[0-9A-Fa-f]/.test(b)) {
82
+ throw general('relay rejected malformed percent-encoding in request target', { requestUrl: '[redacted]' });
83
+ }
84
+ const decoded = Number.parseInt(`${a}${b}`, 16);
85
+ if (decoded <= 0x1f || decoded === 0x7f || decoded === 0x5c) {
86
+ throw general('relay rejected control or backslash characters in request target', { requestUrl: '[redacted]' });
87
+ }
88
+ i += 2;
89
+ continue;
90
+ }
91
+ if (ch === '\\' || ch === '\u0000' || ch < ' ' || ch === '\u007f') {
92
+ throw general('relay rejected control characters in request target', { requestUrl: '[redacted]' });
93
+ }
94
+ }
95
+ }
96
+ /** Origin-form-only request target validation (criterion 4): rejects
97
+ * scheme-relative (`//evil`) and any target that doesn't start with `/`,
98
+ * and rejects control/backslash characters (raw or percent-encoded) before
99
+ * the target is ever joined onto the upstream origin. */
100
+ function validateOriginFormRequestTarget(rawRequestUrl) {
101
+ const raw = rawRequestUrl === undefined || rawRequestUrl === '' ? '/' : rawRequestUrl;
102
+ if (!raw.startsWith('/')) {
103
+ throw general('relay only accepts origin-form request targets', { requestUrl: raw.replace(/\?.*$/, '') });
104
+ }
105
+ if (raw.startsWith('//')) {
106
+ throw general('relay rejected scheme-relative request target', { requestUrl: raw.replace(/\?.*$/, '') });
107
+ }
108
+ decodePathForValidation(raw);
109
+ return raw;
110
+ }
111
+ /** Join the validated origin-form request target onto `previewEndpoint` and
112
+ * reject anything that would escape that origin (criterion 4: "reject
113
+ * scheme-relative/absolute external escapes"). */
114
+ export function buildUpstreamHttpUrl(previewEndpoint, rawRequestUrl) {
115
+ const route = new URL(previewEndpoint);
116
+ const raw = validateOriginFormRequestTarget(rawRequestUrl);
117
+ const upstream = new URL(raw, route);
118
+ if (upstream.origin !== route.origin) {
119
+ throw general('relay rejected request target that escapes the upstream origin', { requestUrl: raw.replace(/\?.*$/, '') });
120
+ }
121
+ upstream.searchParams.delete('token');
122
+ return upstream;
123
+ }
124
+ /** Strip every browser-leg auth header (Authorization/Cookie/Proxy-*) and
125
+ * every client-supplied forwarding/host-metadata header (Forwarded,
126
+ * X-Forwarded-*, X-Real-IP) before forwarding upstream — the relay is a
127
+ * single hop behind the CP, so the home should see no forwarding metadata
128
+ * at all rather than an attacker-controlled one — then inject the CP→home
129
+ * relay token as the sole Authorization header (criterion 2). */
130
+ function filteredRequestHeaders(req, relayToken) {
131
+ const headers = new Headers();
132
+ for (const [name, value] of Object.entries(req.headers)) {
133
+ if (value === undefined)
134
+ continue;
135
+ const lower = name.toLowerCase();
136
+ if (lower === 'host' ||
137
+ lower === 'authorization' ||
138
+ lower === 'cookie' ||
139
+ lower === 'referer' ||
140
+ lower === 'referrer' ||
141
+ lower === 'forwarded' ||
142
+ lower === 'x-real-ip' ||
143
+ lower.startsWith('proxy-') ||
144
+ lower.startsWith('sec-websocket-') ||
145
+ lower.startsWith('x-forwarded-') ||
146
+ hopByHopHeaders.has(lower)) {
147
+ continue;
148
+ }
149
+ headers.set(lower, Array.isArray(value) ? value.join(',') : value);
150
+ }
151
+ headers.set('authorization', `Bearer ${relayToken}`);
152
+ headers.set('accept-encoding', 'identity');
153
+ return headers;
154
+ }
155
+ /** Rewrite an upstream redirect to stay same-origin on the CP (criterion 3).
156
+ * A relative Location is forwarded verbatim (already same-origin to
157
+ * whatever origin the browser/worker considers itself on). An absolute
158
+ * Location back to the upstream route origin is rewritten to a CP-relative
159
+ * path so the browser never learns/visits the upstream origin directly; any
160
+ * other absolute origin is dropped. */
161
+ function sanitizeLocation(location, upstreamOrigin) {
162
+ if (location.startsWith('/') && !location.startsWith('//') && !location.includes('\\'))
163
+ return location;
164
+ try {
165
+ const abs = new URL(location, upstreamOrigin);
166
+ if (abs.origin === upstreamOrigin)
167
+ return `${abs.pathname}${abs.search}${abs.hash}`;
168
+ }
169
+ catch {
170
+ /* malformed Location — drop it */
171
+ }
172
+ return null;
173
+ }
174
+ function applyResponseHeaders(res, headers, upstreamOrigin) {
175
+ headers.forEach((value, key) => {
176
+ const lower = key.toLowerCase();
177
+ if (lower === 'set-cookie' || lower === 'authorization' || hopByHopHeaders.has(lower) || lower.startsWith('proxy-'))
178
+ return;
179
+ if (lower === 'location') {
180
+ const sanitized = sanitizeLocation(value, upstreamOrigin);
181
+ if (sanitized !== null)
182
+ res.setHeader('location', sanitized);
183
+ return;
184
+ }
185
+ res.setHeader(lower, value);
186
+ });
187
+ const contentType = headers.get('content-type');
188
+ if (contentType !== null && !res.hasHeader('content-type'))
189
+ res.setHeader('content-type', contentType);
190
+ }
191
+ function tuneStreamingHeaders(res, isEventStream) {
192
+ if (!isEventStream)
193
+ return;
194
+ const cacheControl = res.getHeader('cache-control');
195
+ if (typeof cacheControl === 'string') {
196
+ if (!/no-transform/i.test(cacheControl))
197
+ res.setHeader('cache-control', `${cacheControl}, no-transform`);
198
+ }
199
+ else if (cacheControl === undefined) {
200
+ res.setHeader('cache-control', 'no-cache, no-transform');
201
+ }
202
+ res.setHeader('connection', 'keep-alive');
203
+ res.setHeader('x-accel-buffering', 'no');
204
+ res.socket?.setNoDelay(true);
205
+ }
206
+ async function waitForDrain(res, signal) {
207
+ await new Promise((resolve, reject) => {
208
+ const cleanup = () => {
209
+ res.off('drain', onDrain);
210
+ res.off('close', onClose);
211
+ res.off('error', onError);
212
+ signal.removeEventListener('abort', onAbort);
213
+ };
214
+ const onDrain = () => {
215
+ cleanup();
216
+ resolve();
217
+ };
218
+ const onClose = () => {
219
+ cleanup();
220
+ reject(new Error('response closed while streaming'));
221
+ };
222
+ const onError = (error) => {
223
+ cleanup();
224
+ reject(error instanceof Error ? error : new Error(String(error)));
225
+ };
226
+ const onAbort = () => {
227
+ cleanup();
228
+ reject(new Error('response aborted while streaming'));
229
+ };
230
+ res.once('drain', onDrain);
231
+ res.once('close', onClose);
232
+ res.once('error', onError);
233
+ signal.addEventListener('abort', onAbort, { once: true });
234
+ });
235
+ }
236
+ async function streamResponseBody(body, res, signal) {
237
+ const reader = body.getReader();
238
+ try {
239
+ while (true) {
240
+ const { value, done } = await reader.read();
241
+ if (done)
242
+ return;
243
+ if (!res.write(Buffer.from(value))) {
244
+ await waitForDrain(res, signal);
245
+ }
246
+ }
247
+ }
248
+ finally {
249
+ reader.releaseLock();
250
+ }
251
+ }
252
+ async function withTimeout(work, timeoutMs, label) {
253
+ if (timeoutMs <= 0)
254
+ return work;
255
+ let timer = null;
256
+ try {
257
+ return await Promise.race([
258
+ work,
259
+ new Promise((_, reject) => {
260
+ timer = setTimeout(() => reject(general(`${label} timed out`, { timeoutMs })), timeoutMs);
261
+ timer.unref();
262
+ }),
263
+ ]);
264
+ }
265
+ finally {
266
+ if (timer !== null)
267
+ clearTimeout(timer);
268
+ }
269
+ }
270
+ function closeHttpWithError(res, statusCode, message) {
271
+ if (!res.headersSent) {
272
+ res.writeHead(statusCode, { 'content-type': 'text/plain; charset=utf-8', 'cache-control': 'no-store' });
273
+ }
274
+ res.end(`${message}\n`);
275
+ }
276
+ function addRequestAbort(req, res, controller) {
277
+ const abort = () => controller.abort();
278
+ req.once('aborted', abort);
279
+ res.once('close', abort);
280
+ return () => {
281
+ req.off('aborted', abort);
282
+ res.off('close', abort);
283
+ };
284
+ }
285
+ /**
286
+ * Forward one HTTP request to the already-awakened home and stream the
287
+ * response back. Returns normally once the response is fully relayed;
288
+ * throws on a genuine upstream/network failure (connect refused/reset, DNS,
289
+ * body-stream error) — an app-level 4xx/5xx is a RESOLVED fetch and is
290
+ * relayed verbatim, never thrown here.
291
+ */
292
+ async function forwardUpstream(req, res, awakened, controller) {
293
+ const upstreamUrl = buildUpstreamHttpUrl(awakened.preview_endpoint, requestPath(req));
294
+ const method = req.method ?? 'GET';
295
+ const canHaveBody = method !== 'GET' && method !== 'HEAD';
296
+ const requestInit = {
297
+ method,
298
+ headers: filteredRequestHeaders(req, awakened.relayToken),
299
+ body: canHaveBody ? Readable.toWeb(req) : undefined,
300
+ signal: controller.signal,
301
+ redirect: 'manual',
302
+ };
303
+ if (canHaveBody)
304
+ requestInit.duplex = 'half';
305
+ const response = await fetch(upstreamUrl, requestInit);
306
+ const responseHeaders = new Headers(response.headers);
307
+ const isEventStream = /text\/event-stream/i.test(responseHeaders.get('content-type') ?? '');
308
+ if (isEventStream)
309
+ responseHeaders.delete('content-length');
310
+ res.statusCode = response.status;
311
+ res.statusMessage = response.statusText;
312
+ applyResponseHeaders(res, responseHeaders, new URL(awakened.preview_endpoint).origin);
313
+ tuneStreamingHeaders(res, isEventStream);
314
+ if (response.body === null || method === 'HEAD') {
315
+ res.end();
316
+ return;
317
+ }
318
+ res.flushHeaders?.();
319
+ await streamResponseBody(response.body, res, controller.signal);
320
+ if (!res.writableEnded)
321
+ res.end();
322
+ }
323
+ /** Forward one HTTP request to `home` (criterion 1: only after the caller's
324
+ * session/registry gate already resolved `home`, and only after
325
+ * `ensureAwake(home.home_id)` succeeds). Mirrors M0 `proxy.ts`'s
326
+ * fast-path-then-escalate shape: a fresh warm-verdict cache hit
327
+ * (`resolveRunning`, P4.2) is forwarded directly without re-entering the
328
+ * wake pipeline; only a missing/stale verdict, or a running route that just
329
+ * failed on a safely-replayable method, escalates to a bounded
330
+ * `ensureAwake`. */
331
+ export async function proxyHttp(req, res, home, deps = {}) {
332
+ const ensureAwakeImpl = deps.ensureAwake ?? ensureAwake;
333
+ const resolveRunningImpl = deps.resolveRunning ?? resolveRunning;
334
+ const invalidate = deps.invalidateWarmVerdict ?? invalidateWarmVerdict;
335
+ const config = (deps.loadConfig ?? loadControlPlaneConfig)();
336
+ const controller = new AbortController();
337
+ const cleanup = addRequestAbort(req, res, controller);
338
+ try {
339
+ const running = resolveRunningImpl(home.home_id);
340
+ if (running !== null) {
341
+ try {
342
+ await forwardUpstream(req, res, running, controller);
343
+ return;
344
+ }
345
+ catch (error) {
346
+ const method = req.method ?? 'GET';
347
+ const replayable = method === 'GET' || method === 'HEAD';
348
+ if (res.headersSent || controller.signal.aborted || !replayable)
349
+ throw error;
350
+ logError('hearth control plane relay running-route forward failed; escalating to deliberate wake', {
351
+ home_id: home.home_id,
352
+ path: requestPath(req).replace(/\?.*$/, ''),
353
+ error: error instanceof Error ? error.message : String(error),
354
+ });
355
+ invalidate(home.home_id);
356
+ }
357
+ }
358
+ const awakened = await withTimeout(ensureAwakeImpl(home.home_id), config.wakeTimeoutMs, 'control plane relay wake');
359
+ if (controller.signal.aborted)
360
+ throw general('request closed while waking');
361
+ await forwardUpstream(req, res, awakened, controller);
362
+ }
363
+ catch (error) {
364
+ const message = error instanceof Error ? error.message : String(error);
365
+ logError('hearth control plane relay HTTP request failed', {
366
+ home_id: home.home_id,
367
+ path: requestPath(req).replace(/\?.*$/, ''),
368
+ error: message,
369
+ });
370
+ if (!message.startsWith('relay '))
371
+ invalidate(home.home_id);
372
+ if (/timed out/i.test(message)) {
373
+ closeHttpWithError(res, 504, 'wake timeout');
374
+ return;
375
+ }
376
+ if (!res.headersSent) {
377
+ closeHttpWithError(res, message.startsWith('relay ') ? 400 : 502, message.startsWith('relay ') ? 'bad request' : 'bad gateway');
378
+ return;
379
+ }
380
+ try {
381
+ res.destroy();
382
+ }
383
+ catch {
384
+ /* ignore */
385
+ }
386
+ }
387
+ finally {
388
+ cleanup();
389
+ }
390
+ }
391
+ // --- WebSocket relay --------------------------------------------------
392
+ /** Build the upstream `wss://`/`ws://` URL for the home's single resident-
393
+ * root target. `target` is always `home.home_agent_target` (server-derived,
394
+ * never the client's request path — see module header). */
395
+ function toWssUrl(previewEndpoint, target) {
396
+ const url = new URL(previewEndpoint);
397
+ url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
398
+ url.pathname = `/node/${encodeURIComponent(target)}`;
399
+ url.search = '';
400
+ url.hash = '';
401
+ return url.toString();
402
+ }
403
+ function sendableCloseCode(code) {
404
+ if (!Number.isInteger(code) || code === 1005 || code === 1006 || code < 1000 || code > 4999)
405
+ return 1000;
406
+ return code;
407
+ }
408
+ function sendSocketClose(socket, code, reason) {
409
+ try {
410
+ socket.close(sendableCloseCode(code), reason.slice(0, 123));
411
+ }
412
+ catch {
413
+ try {
414
+ socket.terminate();
415
+ }
416
+ catch {
417
+ /* ignore */
418
+ }
419
+ }
420
+ }
421
+ const wsKeepaliveIntervalMs = 25_000;
422
+ /** 25s ping/pong keepalive (M0 shape, kept verbatim — criterion 4). A socket
423
+ * that never pongs back is terminated rather than left to leak. */
424
+ function attachWsKeepalive(socket, context, options = {}) {
425
+ const intervalMs = options.intervalMs ?? wsKeepaliveIntervalMs;
426
+ let alive = true;
427
+ let stopped = false;
428
+ let timer = null;
429
+ const stop = () => {
430
+ if (stopped)
431
+ return;
432
+ stopped = true;
433
+ if (timer !== null)
434
+ clearInterval(timer);
435
+ socket.off('pong', onPong);
436
+ };
437
+ const onPong = () => {
438
+ alive = true;
439
+ };
440
+ const terminateStaleSocket = (message) => {
441
+ logError(message, { ...context, readyState: socket.readyState });
442
+ options.onStale?.();
443
+ try {
444
+ socket.terminate();
445
+ }
446
+ catch {
447
+ /* ignore */
448
+ }
449
+ stop();
450
+ };
451
+ const pingOrTerminate = () => {
452
+ if (stopped || socket.readyState !== WebSocket.OPEN)
453
+ return;
454
+ if (!alive) {
455
+ terminateStaleSocket('hearth control plane relay ws keepalive stale');
456
+ return;
457
+ }
458
+ alive = false;
459
+ try {
460
+ socket.ping();
461
+ }
462
+ catch {
463
+ terminateStaleSocket('hearth control plane relay ws keepalive ping failed');
464
+ }
465
+ };
466
+ socket.on('pong', onPong);
467
+ timer = setInterval(pingOrTerminate, intervalMs);
468
+ timer.unref?.();
469
+ return stop;
470
+ }
471
+ function createUpgradeServer() {
472
+ return new WebSocketServer({ noServer: true, maxPayload: BROKER_READ_CAPS.maxLineBytes });
473
+ }
474
+ /** Bridge one already-upgraded browser WebSocket to the home's resident-root
475
+ * broker over `wss://<preview_endpoint>/node/<home_agent_target>`, carrying
476
+ * the relay token as the upstream Authorization header (never reflected
477
+ * back to the browser leg). Keepalive/teardown/close-code handling mirrors
478
+ * M0 `proxy.ts`'s `proxyWebSocketBrowser` (criterion 4). */
479
+ async function proxyWebSocketBrowser(browserWs, home, deps = {}) {
480
+ const ensureAwakeImpl = deps.ensureAwake ?? ensureAwake;
481
+ const config = (deps.loadConfig ?? loadControlPlaneConfig)();
482
+ const createUpstream = deps.createUpstream ??
483
+ ((url, relayToken) => new WebSocket(url, {
484
+ headers: { authorization: `Bearer ${relayToken}` },
485
+ perMessageDeflate: false,
486
+ handshakeTimeout: config.readyTimeoutMs,
487
+ maxPayload: BROKER_READ_CAPS.maxLineBytes,
488
+ }));
489
+ const handshakeAt = Date.now();
490
+ let upstream = null;
491
+ let teardownStarted = false;
492
+ let upstreamOpenAt = null;
493
+ let browserClose = null;
494
+ let upstreamClose = null;
495
+ const queued = [];
496
+ let stopBrowserKeepalive = () => { };
497
+ let stopUpstreamKeepalive = () => { };
498
+ const stopKeepalives = () => {
499
+ stopBrowserKeepalive();
500
+ stopUpstreamKeepalive();
501
+ };
502
+ const beginTeardown = () => {
503
+ if (teardownStarted)
504
+ return;
505
+ teardownStarted = true;
506
+ stopKeepalives();
507
+ };
508
+ stopBrowserKeepalive = attachWsKeepalive(browserWs, { home_id: home.home_id, leg: 'browser' }, { onStale: beginTeardown });
509
+ const logClose = (leg, code, reason) => {
510
+ logError('hearth control plane relay ws close', {
511
+ home_id: home.home_id,
512
+ leg,
513
+ code,
514
+ reason,
515
+ handshakeToUpstreamOpenMs: upstreamOpenAt === null ? null : upstreamOpenAt - handshakeAt,
516
+ browserCloseCode: browserClose?.code ?? null,
517
+ browserCloseReason: browserClose?.reason ?? null,
518
+ upstreamCloseCode: upstreamClose?.code ?? null,
519
+ upstreamCloseReason: upstreamClose?.reason ?? null,
520
+ browserReadyState: browserWs.readyState,
521
+ upstreamReadyState: upstream?.readyState ?? 'none',
522
+ teardownStarted,
523
+ });
524
+ };
525
+ const closeBoth = (code, reason) => {
526
+ beginTeardown();
527
+ if (browserWs.readyState === WebSocket.OPEN || browserWs.readyState === WebSocket.CONNECTING) {
528
+ sendSocketClose(browserWs, code, reason);
529
+ }
530
+ if (upstream !== null && (upstream.readyState === WebSocket.OPEN || upstream.readyState === WebSocket.CONNECTING)) {
531
+ sendSocketClose(upstream, code, reason);
532
+ }
533
+ };
534
+ browserWs.on('message', (data, isBinary) => {
535
+ if (upstream === null || upstream.readyState !== WebSocket.OPEN) {
536
+ queued.push({ data, isBinary });
537
+ return;
538
+ }
539
+ try {
540
+ upstream.send(data, { binary: isBinary });
541
+ }
542
+ catch {
543
+ closeBoth(1011, 'failed to relay browser frame');
544
+ }
545
+ });
546
+ browserWs.on('close', (code, reason) => {
547
+ const closeReason = reason.toString('utf8').slice(0, 123);
548
+ browserClose = { code, reason: closeReason };
549
+ logClose('browser', code, closeReason);
550
+ beginTeardown();
551
+ if (upstream !== null && (upstream.readyState === WebSocket.OPEN || upstream.readyState === WebSocket.CONNECTING)) {
552
+ sendSocketClose(upstream, code, closeReason);
553
+ }
554
+ });
555
+ browserWs.on('error', (error) => {
556
+ logError('hearth control plane relay browser websocket failed', { home_id: home.home_id, error: error instanceof Error ? error.message : String(error) });
557
+ closeBoth(1011, 'browser websocket error');
558
+ });
559
+ try {
560
+ const awakened = await withTimeout(ensureAwakeImpl(home.home_id), config.wakeTimeoutMs, 'control plane relay websocket wake');
561
+ const target = home.home_agent_target?.trim() ?? '';
562
+ if (target === '')
563
+ throw general(`home ${home.home_id} is missing home_agent_target — cannot relay`, { home_id: home.home_id });
564
+ if (browserWs.readyState !== WebSocket.OPEN) {
565
+ beginTeardown();
566
+ return;
567
+ }
568
+ upstream = createUpstream(toWssUrl(awakened.preview_endpoint, target), awakened.relayToken);
569
+ upstream.on('open', () => {
570
+ if (teardownStarted || browserWs.readyState !== WebSocket.OPEN) {
571
+ beginTeardown();
572
+ if (upstream !== null && (upstream.readyState === WebSocket.OPEN || upstream.readyState === WebSocket.CONNECTING)) {
573
+ sendSocketClose(upstream, 1000, 'browser websocket closed before upstream open');
574
+ }
575
+ return;
576
+ }
577
+ upstreamOpenAt = Date.now();
578
+ stopUpstreamKeepalive = attachWsKeepalive(upstream, { home_id: home.home_id, leg: 'upstream' }, { onStale: beginTeardown });
579
+ for (const frame of queued.splice(0, queued.length)) {
580
+ try {
581
+ upstream.send(frame.data, { binary: frame.isBinary });
582
+ }
583
+ catch {
584
+ closeBoth(1011, 'failed to flush buffered browser frame');
585
+ return;
586
+ }
587
+ }
588
+ });
589
+ upstream.on('message', (data, isBinary) => {
590
+ if (browserWs.readyState !== WebSocket.OPEN)
591
+ return;
592
+ browserWs.send(data, { binary: isBinary });
593
+ });
594
+ upstream.on('close', (code, reason) => {
595
+ const closeReason = reason.toString('utf8').slice(0, 123);
596
+ upstreamClose = { code, reason: closeReason };
597
+ logClose('upstream', code, closeReason);
598
+ beginTeardown();
599
+ if (browserWs.readyState === WebSocket.OPEN || browserWs.readyState === WebSocket.CONNECTING) {
600
+ sendSocketClose(browserWs, code, closeReason);
601
+ }
602
+ });
603
+ upstream.on('error', (error) => {
604
+ logError('hearth control plane relay ws upstream failed', { home_id: home.home_id, error: error instanceof Error ? error.message : String(error) });
605
+ (deps.invalidateWarmVerdict ?? invalidateWarmVerdict)(home.home_id);
606
+ closeBoth(1011, 'upstream websocket error');
607
+ });
608
+ }
609
+ catch (error) {
610
+ const message = error instanceof Error ? error.message : String(error);
611
+ logError('hearth control plane relay websocket wake failed', { home_id: home.home_id, error: message });
612
+ (deps.invalidateWarmVerdict ?? invalidateWarmVerdict)(home.home_id);
613
+ closeBoth(/timed out/i.test(message) ? 1013 : 1011, /timed out/i.test(message) ? 'wake timeout' : 'wake failed');
614
+ }
615
+ }
616
+ /** `RelayDispatcher.proxyUpgrade`: complete the WS handshake on the already
617
+ * session+registry-gated socket (`server.ts`'s `handleUpgrade`), then bridge
618
+ * it to the home. Errors after this point close the browser socket in-band
619
+ * with a WS close code (1011/1013) rather than a raw TCP reset, so the
620
+ * client sees a clean failure (criterion 4: "keep ... close behavior from
621
+ * M0 where applicable"). */
622
+ export function proxyUpgrade(req, socket, head, home, deps = {}) {
623
+ const wss = createUpgradeServer();
624
+ wss.handleUpgrade(req, socket, head, (browserWs) => {
625
+ void proxyWebSocketBrowser(browserWs, home, deps).catch((error) => {
626
+ logError('hearth control plane relay websocket bridge failed', { home_id: home.home_id, error: error instanceof Error ? error.message : String(error) });
627
+ try {
628
+ browserWs.terminate();
629
+ }
630
+ catch {
631
+ /* ignore */
632
+ }
633
+ });
634
+ });
635
+ }
636
+ /** The real `RelayDispatcher` `main.ts` wires in once the CP server is built
637
+ * — `server.ts`'s default (`notImplementedRelay`) is only ever used when a
638
+ * caller (test/smoke) doesn't inject one. */
639
+ export const controlPlaneRelay = {
640
+ proxyHttp,
641
+ proxyUpgrade,
642
+ };
@@ -0,0 +1,36 @@
1
+ export type ScheduleFireState = 'pending' | 'waking' | 'delivered' | 'failed';
2
+ export interface ScheduleFireRow {
3
+ fire_id: string;
4
+ schedule_id: string;
5
+ home_id: string;
6
+ tenant_id: string;
7
+ user_id: string;
8
+ scheduled_for: string;
9
+ state: ScheduleFireState;
10
+ attempts: number;
11
+ last_error: string | null;
12
+ delivered_at: string | null;
13
+ created_at: string;
14
+ updated_at: string;
15
+ }
16
+ export interface ClaimFireInput {
17
+ fire_id?: string;
18
+ schedule_id: string;
19
+ scheduled_for: string;
20
+ now?: string;
21
+ }
22
+ export interface ClaimFireResult {
23
+ fire: ScheduleFireRow;
24
+ claimed: boolean;
25
+ }
26
+ export interface SetFireStateOptions {
27
+ last_error?: string | null;
28
+ delivered_at?: string | null;
29
+ increment_attempts?: boolean;
30
+ now?: string;
31
+ }
32
+ export declare function claimFire(input: ClaimFireInput): ClaimFireResult;
33
+ export declare function getFireById(fireId: string): ScheduleFireRow | null;
34
+ export declare function getFireByScheduleSlot(scheduleId: string, scheduledFor: string): ScheduleFireRow | null;
35
+ export declare function setFireState(fireId: string, state: ScheduleFireState, options?: SetFireStateOptions): void;
36
+ export declare function selectResumableFires(limit?: number): ScheduleFireRow[];