@crouton-kit/crouter 0.3.33 → 0.3.35

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 (617) 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 +427 -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 +843 -743
  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 +19 -9
  345. package/dist/core/__tests__/flagship-lifecycle.test.js +4 -1
  346. package/dist/core/__tests__/full/broker-attach-limits.test.js +1 -1
  347. package/dist/core/__tests__/full/broker-attach-stream.test.js +1 -1
  348. package/dist/core/__tests__/full/broker-crash-teardown.test.js +10 -5
  349. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +1 -1
  350. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +2 -2
  351. package/dist/core/__tests__/full/broker-pane-resolution.test.js +1 -1
  352. package/dist/core/__tests__/full/cascade-close.test.js +31 -18
  353. package/dist/core/__tests__/full/detach-focus.test.js +17 -3
  354. package/dist/core/__tests__/hearth-bootstrap.test.js +136 -0
  355. package/dist/core/__tests__/helpers/harness.js +1 -1
  356. package/dist/core/__tests__/live-mutation-verbs.test.js +17 -11
  357. package/dist/core/__tests__/live-mutation.test.js +15 -10
  358. package/dist/core/__tests__/migration.test.js +124 -0
  359. package/dist/core/__tests__/on-read-dedup-resume.test.js +40 -0
  360. package/dist/core/__tests__/preview-registry-sync.test.js +36 -0
  361. package/dist/core/__tests__/prune-to-limit.test.js +91 -0
  362. package/dist/core/__tests__/revive.test.js +64 -21
  363. package/dist/core/__tests__/trigger-migration.test.js +48 -0
  364. package/dist/core/__tests__/wake-bearings.test.js +23 -21
  365. package/dist/core/__tests__/wake-origin.test.js +36 -33
  366. package/dist/core/canvas/boot.d.ts +48 -0
  367. package/dist/core/canvas/boot.js +157 -0
  368. package/dist/core/canvas/canvas.d.ts +27 -1
  369. package/dist/core/canvas/canvas.js +86 -5
  370. package/dist/core/canvas/db.js +86 -1
  371. package/dist/core/canvas/index.d.ts +1 -1
  372. package/dist/core/canvas/index.js +1 -1
  373. package/dist/core/canvas/nav-model.js +1 -1
  374. package/dist/core/canvas/pid.d.ts +6 -0
  375. package/dist/core/canvas/pid.js +13 -0
  376. package/dist/core/canvas/triggers.d.ts +108 -0
  377. package/dist/core/canvas/triggers.js +320 -0
  378. package/dist/core/canvas/types.d.ts +128 -46
  379. package/dist/core/command.js +13 -4
  380. package/dist/core/hearth/__tests__/model-auth-guest.test.js +151 -0
  381. package/dist/core/hearth/config.d.ts +1 -0
  382. package/dist/core/hearth/config.js +36 -3
  383. package/dist/core/hearth/guest-env.d.ts +7 -0
  384. package/dist/core/hearth/guest-env.js +17 -1
  385. package/dist/core/hearth/index.d.ts +0 -1
  386. package/dist/core/hearth/index.js +0 -1
  387. package/dist/core/hearth/model-auth-guest.d.ts +8 -0
  388. package/dist/core/hearth/model-auth-guest.js +430 -0
  389. package/dist/core/hearth/provider.d.ts +13 -6
  390. package/dist/core/hearth/providers/blaxel-bootstrap.d.ts +2 -0
  391. package/dist/core/hearth/providers/blaxel-bootstrap.js +127 -19
  392. package/dist/core/hearth/providers/blaxel-home.d.ts +8 -4
  393. package/dist/core/hearth/providers/blaxel-home.js +85 -75
  394. package/dist/core/hearth/providers/blaxel.d.ts +5 -0
  395. package/dist/core/hearth/providers/blaxel.js +86 -12
  396. package/dist/core/hearth/providers/types.d.ts +6 -1
  397. package/dist/core/hearth/types.d.ts +35 -1
  398. package/dist/core/help.d.ts +16 -0
  399. package/dist/core/help.js +2 -0
  400. package/dist/core/memory-resolver.d.ts +8 -8
  401. package/dist/core/memory-resolver.js +58 -26
  402. package/dist/core/preview-registry.d.ts +25 -0
  403. package/dist/core/preview-registry.js +2047 -0
  404. package/dist/core/resolver.d.ts +1 -0
  405. package/dist/core/resolver.js +23 -16
  406. package/dist/core/runtime/bearings.d.ts +11 -10
  407. package/dist/core/runtime/bearings.js +8 -8
  408. package/dist/core/runtime/broker-protocol.d.ts +2 -2
  409. package/dist/core/runtime/broker-protocol.js +2 -2
  410. package/dist/core/runtime/close.js +2 -2
  411. package/dist/core/runtime/kickoff.js +1 -1
  412. package/dist/core/runtime/launch.d.ts +9 -3
  413. package/dist/core/runtime/launch.js +17 -9
  414. package/dist/core/runtime/lifecycle.js +7 -7
  415. package/dist/core/runtime/model-swap.js +1 -1
  416. package/dist/core/runtime/placement.d.ts +5 -5
  417. package/dist/core/runtime/placement.js +10 -10
  418. package/dist/core/runtime/recycle.js +7 -7
  419. package/dist/core/runtime/reset.d.ts +1 -1
  420. package/dist/core/runtime/reset.js +3 -3
  421. package/dist/core/runtime/revive-all.d.ts +5 -2
  422. package/dist/core/runtime/revive-all.js +5 -2
  423. package/dist/core/runtime/revive.d.ts +15 -8
  424. package/dist/core/runtime/revive.js +52 -16
  425. package/dist/core/runtime/spawn.d.ts +1 -1
  426. package/dist/core/runtime/spawn.js +7 -7
  427. package/dist/core/runtime/stop-guard.js +5 -5
  428. package/dist/core/runtime/surface-bg.js +1 -1
  429. package/dist/core/runtime/tmux.d.ts +1 -1
  430. package/dist/core/runtime/tmux.js +4 -4
  431. package/dist/core/scope.d.ts +9 -0
  432. package/dist/core/scope.js +37 -15
  433. package/dist/core/substrate/on-read.js +23 -21
  434. package/dist/core/substrate/render.js +3 -3
  435. package/dist/core/view/loader.js +2 -2
  436. package/dist/core/wake.d.ts +2 -2
  437. package/dist/core/wake.js +7 -7
  438. package/dist/daemon/__tests__/predicate-eval.test.js +109 -0
  439. package/dist/daemon/crtrd.js +222 -103
  440. package/dist/daemon/predicate-eval.d.ts +52 -0
  441. package/dist/daemon/predicate-eval.js +248 -0
  442. package/dist/hearth/control-plane/__tests__/node-message.test.js +60 -0
  443. package/dist/hearth/control-plane/__tests__/rate-limit-recurrence.test.js +49 -0
  444. package/dist/hearth/control-plane/__tests__/relay-security.test.js +314 -0
  445. package/dist/hearth/control-plane/__tests__/scheduler-scan-loop.test.js +133 -0
  446. package/dist/hearth/control-plane/__tests__/trigger-delivery.test.js +170 -0
  447. package/dist/hearth/control-plane/__tests__/webhook-ingress.test.js +167 -0
  448. package/dist/hearth/control-plane/config.d.ts +21 -0
  449. package/dist/hearth/control-plane/config.js +77 -0
  450. package/dist/hearth/control-plane/db.d.ts +30 -0
  451. package/dist/hearth/control-plane/db.js +534 -0
  452. package/dist/hearth/control-plane/ingress/rate-limit.d.ts +24 -0
  453. package/dist/hearth/control-plane/ingress/rate-limit.js +100 -0
  454. package/dist/hearth/control-plane/ingress/route-store.d.ts +31 -0
  455. package/dist/hearth/control-plane/ingress/route-store.js +61 -0
  456. package/dist/hearth/control-plane/ingress/webhook-delivery-store.d.ts +41 -0
  457. package/dist/hearth/control-plane/ingress/webhook-delivery-store.js +69 -0
  458. package/dist/hearth/control-plane/ingress/webhook-route.d.ts +55 -0
  459. package/dist/hearth/control-plane/ingress/webhook-route.js +285 -0
  460. package/dist/hearth/control-plane/main.js +88 -0
  461. package/dist/hearth/control-plane/node-message.d.ts +31 -0
  462. package/dist/hearth/control-plane/node-message.js +98 -0
  463. package/dist/hearth/control-plane/register.d.ts +15 -0
  464. package/dist/hearth/control-plane/register.js +34 -0
  465. package/dist/hearth/control-plane/registry.d.ts +17 -0
  466. package/dist/hearth/control-plane/registry.js +161 -0
  467. package/dist/hearth/control-plane/relay.d.ts +40 -0
  468. package/dist/hearth/{wake-proxy/proxy.js → control-plane/relay.js} +201 -275
  469. package/dist/hearth/control-plane/scheduler/fire-store.d.ts +36 -0
  470. package/dist/hearth/control-plane/scheduler/fire-store.js +73 -0
  471. package/dist/hearth/control-plane/scheduler/recurrence.d.ts +7 -0
  472. package/dist/hearth/control-plane/scheduler/recurrence.js +58 -0
  473. package/dist/hearth/control-plane/scheduler/scan-loop.d.ts +38 -0
  474. package/dist/hearth/control-plane/scheduler/scan-loop.js +138 -0
  475. package/dist/hearth/control-plane/scheduler/schedule-store.d.ts +32 -0
  476. package/dist/hearth/control-plane/scheduler/schedule-store.js +66 -0
  477. package/dist/hearth/control-plane/secrets.d.ts +17 -0
  478. package/dist/hearth/control-plane/secrets.js +113 -0
  479. package/dist/hearth/control-plane/server.d.ts +27 -0
  480. package/dist/hearth/control-plane/server.js +346 -0
  481. package/dist/hearth/control-plane/session.d.ts +68 -0
  482. package/dist/hearth/control-plane/session.js +273 -0
  483. package/dist/hearth/control-plane/triggers/acl.d.ts +14 -0
  484. package/dist/hearth/control-plane/triggers/acl.js +52 -0
  485. package/dist/hearth/control-plane/triggers/audit-store.d.ts +38 -0
  486. package/dist/hearth/control-plane/triggers/audit-store.js +79 -0
  487. package/dist/hearth/control-plane/triggers/deliver.d.ts +43 -0
  488. package/dist/hearth/control-plane/triggers/deliver.js +76 -0
  489. package/dist/hearth/control-plane/triggers/envelope.d.ts +29 -0
  490. package/dist/hearth/control-plane/triggers/envelope.js +38 -0
  491. package/dist/hearth/control-plane/types.d.ts +66 -0
  492. package/dist/hearth/control-plane/wake.d.ts +80 -0
  493. package/dist/hearth/control-plane/wake.js +312 -0
  494. package/dist/pi-extensions/canvas-doc-substrate.js +28 -2
  495. package/dist/pi-extensions/canvas-nav.js +1 -1
  496. package/dist/prompts/view.js +7 -8
  497. package/dist/types.js +4 -4
  498. package/dist/web-client/assets/index-DUThOUzU.css +2 -0
  499. package/dist/web-client/assets/index-IAJVtuVe.js +80 -0
  500. package/dist/web-client/index.html +2 -2
  501. package/package.json +12 -9
  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.d.ts +0 -1
  519. package/dist/core/__tests__/editor-label.test.js +0 -26
  520. package/dist/core/__tests__/fault-marker.test.d.ts +0 -1
  521. package/dist/core/__tests__/fault-marker.test.js +0 -112
  522. package/dist/core/__tests__/fault-retry-rewind.test.d.ts +0 -1
  523. package/dist/core/__tests__/fault-retry-rewind.test.js +0 -123
  524. package/dist/core/__tests__/frame-decoder-perf.test.d.ts +0 -1
  525. package/dist/core/__tests__/frame-decoder-perf.test.js +0 -224
  526. package/dist/core/__tests__/keystone.test.d.ts +0 -1
  527. package/dist/core/__tests__/keystone.test.js +0 -185
  528. package/dist/core/__tests__/listing-completeness.test.d.ts +0 -1
  529. package/dist/core/__tests__/listing-completeness.test.js +0 -31
  530. package/dist/core/__tests__/memory-resolver.test.d.ts +0 -1
  531. package/dist/core/__tests__/memory-resolver.test.js +0 -119
  532. package/dist/core/__tests__/memory.test.d.ts +0 -1
  533. package/dist/core/__tests__/memory.test.js +0 -60
  534. package/dist/core/__tests__/model-ladders.test.d.ts +0 -1
  535. package/dist/core/__tests__/model-ladders.test.js +0 -160
  536. package/dist/core/__tests__/node-env.test.d.ts +0 -1
  537. package/dist/core/__tests__/node-env.test.js +0 -26
  538. package/dist/core/__tests__/pane-column.test.d.ts +0 -1
  539. package/dist/core/__tests__/pane-column.test.js +0 -153
  540. package/dist/core/__tests__/persona-compose.test.d.ts +0 -1
  541. package/dist/core/__tests__/persona-compose.test.js +0 -53
  542. package/dist/core/__tests__/persona-subkind.test.d.ts +0 -1
  543. package/dist/core/__tests__/persona-subkind.test.js +0 -65
  544. package/dist/core/__tests__/persona.test.d.ts +0 -1
  545. package/dist/core/__tests__/persona.test.js +0 -107
  546. package/dist/core/__tests__/unknown-path.test.d.ts +0 -1
  547. package/dist/core/__tests__/unknown-path.test.js +0 -58
  548. package/dist/core/canvas/wakeups.d.ts +0 -76
  549. package/dist/core/canvas/wakeups.js +0 -185
  550. package/dist/core/hearth/registry.d.ts +0 -15
  551. package/dist/core/hearth/registry.js +0 -179
  552. package/dist/hearth/wake-proxy/__tests__/anthropic-oauth.test.d.ts +0 -1
  553. package/dist/hearth/wake-proxy/__tests__/anthropic-oauth.test.js +0 -289
  554. package/dist/hearth/wake-proxy/__tests__/config-timeout.test.d.ts +0 -1
  555. package/dist/hearth/wake-proxy/__tests__/config-timeout.test.js +0 -34
  556. package/dist/hearth/wake-proxy/__tests__/guest-source.test.d.ts +0 -1
  557. package/dist/hearth/wake-proxy/__tests__/guest-source.test.js +0 -203
  558. package/dist/hearth/wake-proxy/__tests__/hardening.test.d.ts +0 -1
  559. package/dist/hearth/wake-proxy/__tests__/hardening.test.js +0 -59
  560. package/dist/hearth/wake-proxy/__tests__/hearth-status-route.test.d.ts +0 -1
  561. package/dist/hearth/wake-proxy/__tests__/hearth-status-route.test.js +0 -372
  562. package/dist/hearth/wake-proxy/__tests__/http-running-route-fast-path.test.d.ts +0 -1
  563. package/dist/hearth/wake-proxy/__tests__/http-running-route-fast-path.test.js +0 -258
  564. package/dist/hearth/wake-proxy/__tests__/model-auth-routes.test.d.ts +0 -1
  565. package/dist/hearth/wake-proxy/__tests__/model-auth-routes.test.js +0 -437
  566. package/dist/hearth/wake-proxy/__tests__/source-bridge-gate.test.d.ts +0 -1
  567. package/dist/hearth/wake-proxy/__tests__/source-bridge-gate.test.js +0 -455
  568. package/dist/hearth/wake-proxy/__tests__/static-asset-allowlist.test.d.ts +0 -1
  569. package/dist/hearth/wake-proxy/__tests__/static-asset-allowlist.test.js +0 -15
  570. package/dist/hearth/wake-proxy/__tests__/warm-path-concurrency.test.d.ts +0 -1
  571. package/dist/hearth/wake-proxy/__tests__/warm-path-concurrency.test.js +0 -141
  572. package/dist/hearth/wake-proxy/__tests__/ws-teardown-accounting.test.d.ts +0 -1
  573. package/dist/hearth/wake-proxy/__tests__/ws-teardown-accounting.test.js +0 -143
  574. package/dist/hearth/wake-proxy/anthropic-oauth.d.ts +0 -58
  575. package/dist/hearth/wake-proxy/anthropic-oauth.js +0 -189
  576. package/dist/hearth/wake-proxy/auth.d.ts +0 -22
  577. package/dist/hearth/wake-proxy/auth.js +0 -128
  578. package/dist/hearth/wake-proxy/config.d.ts +0 -2
  579. package/dist/hearth/wake-proxy/config.js +0 -151
  580. package/dist/hearth/wake-proxy/guest-source.d.ts +0 -14
  581. package/dist/hearth/wake-proxy/guest-source.js +0 -130
  582. package/dist/hearth/wake-proxy/hearth-status.d.ts +0 -44
  583. package/dist/hearth/wake-proxy/hearth-status.js +0 -267
  584. package/dist/hearth/wake-proxy/home.d.ts +0 -67
  585. package/dist/hearth/wake-proxy/home.js +0 -297
  586. package/dist/hearth/wake-proxy/main.js +0 -134
  587. package/dist/hearth/wake-proxy/model-auth.d.ts +0 -13
  588. package/dist/hearth/wake-proxy/model-auth.js +0 -345
  589. package/dist/hearth/wake-proxy/proxy.d.ts +0 -35
  590. package/dist/hearth/wake-proxy/public-source-gate.d.ts +0 -9
  591. package/dist/hearth/wake-proxy/public-source-gate.js +0 -409
  592. package/dist/hearth/wake-proxy/redact.d.ts +0 -1
  593. package/dist/hearth/wake-proxy/redact.js +0 -17
  594. package/dist/hearth/wake-proxy/server.d.ts +0 -11
  595. package/dist/hearth/wake-proxy/server.js +0 -142
  596. package/dist/hearth/wake-proxy/state.d.ts +0 -18
  597. package/dist/hearth/wake-proxy/state.js +0 -342
  598. package/dist/hearth/wake-proxy/types.d.ts +0 -76
  599. package/dist/web-client/assets/index-BZUxTkv5.css +0 -2
  600. package/dist/web-client/assets/index-D36PNBj4.js +0 -80
  601. /package/dist/clients/attach/__tests__/{action-parity.test.d.ts → crtr-output-coverage.test.d.ts} +0 -0
  602. /package/dist/clients/attach/__tests__/{autocomplete-and-bash-mode.test.d.ts → crtr-output-render.test.d.ts} +0 -0
  603. /package/dist/{clients/attach/__tests__/bash-bang-routing.test.d.ts → core/__tests__/boot.test.d.ts} +0 -0
  604. /package/dist/{clients/attach/__tests__/bundle-pi-tui-dedup.test.d.ts → core/__tests__/hearth-bootstrap.test.d.ts} +0 -0
  605. /package/dist/{clients/attach/__tests__/clipboard-image.test.d.ts → core/__tests__/preview-registry-sync.test.d.ts} +0 -0
  606. /package/dist/{clients/attach/__tests__/editor-newline.test.d.ts → core/__tests__/prune-to-limit.test.d.ts} +0 -0
  607. /package/dist/{clients/attach/__tests__/git-info.test.d.ts → core/__tests__/trigger-migration.test.d.ts} +0 -0
  608. /package/dist/{clients/attach/__tests__/onrequest-wired.test.d.ts → core/hearth/__tests__/model-auth-guest.test.d.ts} +0 -0
  609. /package/dist/{clients/attach/__tests__/reconnect-giveup.test.d.ts → daemon/__tests__/predicate-eval.test.d.ts} +0 -0
  610. /package/dist/{clients/attach/__tests__/slash-quit-copy.test.d.ts → hearth/control-plane/__tests__/node-message.test.d.ts} +0 -0
  611. /package/dist/{clients/attach/__tests__/titled-editor.test.d.ts → hearth/control-plane/__tests__/rate-limit-recurrence.test.d.ts} +0 -0
  612. /package/dist/{commands/memory/__tests__/lint-schema.test.d.ts → hearth/control-plane/__tests__/relay-security.test.d.ts} +0 -0
  613. /package/dist/{core/__tests__/argv-parser.test.d.ts → hearth/control-plane/__tests__/scheduler-scan-loop.test.d.ts} +0 -0
  614. /package/dist/{core/__tests__/artifact-paths.test.d.ts → hearth/control-plane/__tests__/trigger-delivery.test.d.ts} +0 -0
  615. /package/dist/{core/__tests__/draw-style.test.d.ts → hearth/control-plane/__tests__/webhook-ingress.test.d.ts} +0 -0
  616. /package/dist/hearth/{wake-proxy → control-plane}/main.d.ts +0 -0
  617. /package/dist/hearth/{wake-proxy → control-plane}/types.js +0 -0
@@ -0,0 +1,133 @@
1
+ import assert from 'node:assert/strict';
2
+ import { test } from 'node:test';
3
+ import { runSchedulerScan } from '../scheduler/scan-loop.js';
4
+ // Category-3 test (CLAUDE.md "Testing policy" #3 — load-bearing Hearth/CP
5
+ // regression). Invariant: master plan P5.4 / part-plan T-C1 R-CRON-3 — the CP
6
+ // cron scan is idempotent and restart-safe. A due schedule fires exactly once
7
+ // per slot even across repeated scans, and a fire left `waking` by a crashed
8
+ // CP is re-driven to a SINGLE delivery, never a double. A regression here is
9
+ // silent (still typechecks) and directly re-introduces the double-fire failure
10
+ // mode this ledger exists to prevent.
11
+ const SCHEDULE = {
12
+ schedule_id: 's1',
13
+ tenant_id: 't1',
14
+ user_id: 'u1',
15
+ home_id: 'h1',
16
+ label: 'nightly',
17
+ recurrence: '*/5 * * * *',
18
+ timezone: 'UTC',
19
+ delivery_payload: { hello: 'world' },
20
+ next_fire_at: '2026-06-30T12:00:00.000Z',
21
+ last_fired_at: null,
22
+ enabled: true,
23
+ created_at: '2026-06-30T00:00:00.000Z',
24
+ updated_at: '2026-06-30T00:00:00.000Z',
25
+ };
26
+ function fireFor(schedule, state) {
27
+ return {
28
+ fire_id: 'f1',
29
+ schedule_id: schedule.schedule_id,
30
+ home_id: schedule.home_id,
31
+ tenant_id: schedule.tenant_id,
32
+ user_id: schedule.user_id,
33
+ scheduled_for: schedule.next_fire_at,
34
+ state,
35
+ attempts: 0,
36
+ last_error: null,
37
+ delivered_at: null,
38
+ created_at: schedule.created_at,
39
+ updated_at: schedule.updated_at,
40
+ };
41
+ }
42
+ function makeDeps(rec, overrides, outcome = { outcome: 'delivered' }) {
43
+ return {
44
+ selectDueSchedules: () => [],
45
+ getScheduleById: (id) => (id === SCHEDULE.schedule_id ? SCHEDULE : null),
46
+ claimFire: (input) => {
47
+ rec.claimCount += 1;
48
+ return { fire: fireFor(SCHEDULE, 'pending'), claimed: rec.claimCount === 1 };
49
+ },
50
+ setFireState: (fire_id, state) => {
51
+ rec.fireStates.push({ fire_id, state });
52
+ },
53
+ advanceNextFire: (schedule_id, next, last) => {
54
+ rec.advances.push({ schedule_id, next, last });
55
+ },
56
+ selectResumableFires: () => [],
57
+ computeNextFire: () => '2026-06-30T12:05:00.000Z',
58
+ deliverTrigger: async (input) => {
59
+ rec.deliveries.push({
60
+ home_id: input.home_id,
61
+ source_ref: input.source_ref,
62
+ trigger_id: input.envelope.trigger_id,
63
+ tier: input.tier,
64
+ source: input.envelope.source,
65
+ payload: input.envelope.payload,
66
+ });
67
+ return outcome;
68
+ },
69
+ now: () => '2026-06-30T12:00:01.000Z',
70
+ intervalMs: 15_000,
71
+ ...overrides,
72
+ };
73
+ }
74
+ function makeRecorder() {
75
+ return { deliveries: [], fireStates: [], advances: [], claimCount: 0 };
76
+ }
77
+ test('a due schedule fires exactly once with urgent tier and trigger_id == fire_id', async () => {
78
+ const rec = makeRecorder();
79
+ const deps = makeDeps(rec, { selectDueSchedules: () => [SCHEDULE] });
80
+ await runSchedulerScan(deps);
81
+ assert.equal(rec.deliveries.length, 1);
82
+ const d = rec.deliveries[0];
83
+ assert.equal(d.tier, 'urgent');
84
+ assert.equal(d.source, 'cron');
85
+ assert.equal(d.trigger_id, 'f1'); // R-CRON-5: envelope trigger_id is the durable fire_id
86
+ assert.equal(d.home_id, 'h1');
87
+ assert.deepEqual(d.payload, { hello: 'world' });
88
+ // next_fire_at advanced before delivery so the slot cannot be re-selected.
89
+ assert.deepEqual(rec.advances, [{ schedule_id: 's1', next: '2026-06-30T12:05:00.000Z', last: '2026-06-30T12:00:00.000Z' }]);
90
+ assert.deepEqual(rec.fireStates.map((s) => s.state), ['waking', 'delivered']);
91
+ });
92
+ test('the same due slot is claimed only once across repeated scans (no double fire)', async () => {
93
+ const rec = makeRecorder();
94
+ // Both scans see the schedule as due, but claimFire grants the slot once.
95
+ const deps = makeDeps(rec, { selectDueSchedules: () => [SCHEDULE] });
96
+ await runSchedulerScan(deps);
97
+ await runSchedulerScan(deps);
98
+ assert.equal(rec.claimCount, 2); // both passes attempted a claim
99
+ assert.equal(rec.deliveries.length, 1); // only the winning claim delivered
100
+ });
101
+ test('a fire left waking by a crashed CP is resumed to a single delivery, not doubled', async () => {
102
+ const rec = makeRecorder();
103
+ let resumables = [fireFor(SCHEDULE, 'waking')];
104
+ const deps = makeDeps(rec, {
105
+ selectResumableFires: () => {
106
+ const out = resumables;
107
+ resumables = []; // next scan finds it resolved
108
+ return out;
109
+ },
110
+ selectDueSchedules: () => [], // slot already advanced/claimed pre-crash
111
+ });
112
+ await runSchedulerScan(deps);
113
+ await runSchedulerScan(deps);
114
+ assert.equal(rec.claimCount, 0); // resume path never re-claims
115
+ assert.equal(rec.deliveries.length, 1); // exactly one delivery for the stranded fire
116
+ assert.equal(rec.deliveries[0].trigger_id, 'f1');
117
+ });
118
+ test('a failed delivery marks the fire failed with an incremented attempt, no retry storm', async () => {
119
+ const rec = makeRecorder();
120
+ const attemptFlags = [];
121
+ const deps = makeDeps(rec, {
122
+ selectDueSchedules: () => [SCHEDULE],
123
+ setFireState: (fire_id, state, options) => {
124
+ rec.fireStates.push({ fire_id, state });
125
+ if (options?.increment_attempts !== undefined)
126
+ attemptFlags.push(options.increment_attempts);
127
+ },
128
+ }, { outcome: 'failed', reason: 'boom' });
129
+ await runSchedulerScan(deps);
130
+ assert.deepEqual(rec.fireStates.map((s) => s.state), ['waking', 'failed']);
131
+ assert.deepEqual(attemptFlags, [true]);
132
+ assert.equal(rec.deliveries.length, 1); // one attempt; the natural next tick is the only re-fire
133
+ });
@@ -0,0 +1,170 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdtempSync, rmSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { test } from 'node:test';
6
+ // Category-3 test (CLAUDE.md "Testing policy" #3 — load-bearing Hearth/CP
7
+ // security regression). Invariants: master plan P5.2/P5.3, part-plan T-B2/T-B4,
8
+ // R-TRIG-1/R-TRIG-4. (1) The delivery chokepoint carries the envelope on STDIN
9
+ // via the P4.4 primitive, never in argv — and only for an AUTHORIZED trigger.
10
+ // (2) The FK-integrity ACL rejects cross-home targeting and terminated homes.
11
+ // (3) An unauthorized trigger NEVER execs and writes a `rejected` audit row; an
12
+ // authorized one writes a `delivered` row. Silent regressions here defeat the
13
+ // R-TRIG-4 auth/audit boundary that all cron+webhook delivery funnels through.
14
+ let dbDir;
15
+ function setupDb() {
16
+ dbDir = mkdtempSync(join(tmpdir(), 'crtr-cp-trigger-'));
17
+ process.env['CRTR_HEARTH_CP_DB_PATH'] = join(dbDir, 'control-plane.db');
18
+ }
19
+ function teardownDb(dbPath) {
20
+ // Lazy import to avoid pinning the module before env is set.
21
+ void dbPath;
22
+ rmSync(dbDir, { recursive: true, force: true });
23
+ delete process.env['CRTR_HEARTH_CP_DB_PATH'];
24
+ }
25
+ test('deliverTrigger carries the serialized envelope on stdin at the requested tier for an authorized trigger', async () => {
26
+ const { deliverTrigger, deliverInternals } = await import('../triggers/deliver.js');
27
+ const { buildTriggerEnvelope, serializeEnvelope } = await import('../triggers/envelope.js');
28
+ const orig = { ...deliverInternals };
29
+ const execCalls = [];
30
+ const audits = [];
31
+ deliverInternals.authorizeTrigger = () => ({ ok: true });
32
+ deliverInternals.wakeAndExecNodeMessage = async (home_id, body, tier) => {
33
+ execCalls.push({ home_id, body, tier });
34
+ };
35
+ deliverInternals.recordTriggerAudit = ((entry) => {
36
+ audits.push({ outcome: entry.outcome, trigger_id: entry.trigger_id, source_ref: entry.source_ref });
37
+ return {};
38
+ });
39
+ try {
40
+ const envelope = buildTriggerEnvelope({ source: 'webhook', trigger_id: 'r1:abc', payload: { a: 1, quote: 'has "quotes" & spaces' } });
41
+ const result = await deliverTrigger({ home_id: 'h1', source_ref: 'r1', envelope, tier: 'urgent' });
42
+ assert.equal(result.outcome, 'delivered');
43
+ assert.equal(execCalls.length, 1);
44
+ // The envelope travels as the exec STDIN body verbatim, never in argv.
45
+ assert.equal(execCalls[0].body, serializeEnvelope(envelope));
46
+ assert.equal(execCalls[0].tier, 'urgent');
47
+ assert.equal(execCalls[0].home_id, 'h1');
48
+ assert.equal(audits.length, 1);
49
+ assert.equal(audits[0].outcome, 'delivered');
50
+ assert.equal(audits[0].trigger_id, 'r1:abc');
51
+ }
52
+ finally {
53
+ Object.assign(deliverInternals, orig);
54
+ }
55
+ });
56
+ test('an unauthorized trigger never execs and records a rejected audit', async () => {
57
+ const { deliverTrigger, deliverInternals } = await import('../triggers/deliver.js');
58
+ const { buildTriggerEnvelope } = await import('../triggers/envelope.js');
59
+ const orig = { ...deliverInternals };
60
+ let execCalled = false;
61
+ const audits = [];
62
+ deliverInternals.authorizeTrigger = () => ({ ok: false, reason: 'cross-home targeting rejected' });
63
+ deliverInternals.wakeAndExecNodeMessage = async () => {
64
+ execCalled = true;
65
+ };
66
+ deliverInternals.recordTriggerAudit = ((entry) => {
67
+ audits.push({ outcome: entry.outcome, reason: entry.reason ?? null });
68
+ return {};
69
+ });
70
+ try {
71
+ const envelope = buildTriggerEnvelope({ source: 'cron', trigger_id: 'f1', payload: {} });
72
+ const result = await deliverTrigger({ home_id: 'h2', source_ref: 'f1', envelope, tier: 'urgent' });
73
+ assert.equal(result.outcome, 'rejected');
74
+ assert.equal(execCalled, false); // unauthorized never reaches the exec primitive
75
+ assert.equal(audits.length, 1);
76
+ assert.equal(audits[0].outcome, 'rejected');
77
+ assert.equal(audits[0].reason, 'cross-home targeting rejected');
78
+ }
79
+ finally {
80
+ Object.assign(deliverInternals, orig);
81
+ }
82
+ });
83
+ test('authorizeTrigger enforces the FK-integrity guard against a real CP db', async () => {
84
+ setupDb();
85
+ const dbPath = process.env['CRTR_HEARTH_CP_DB_PATH'];
86
+ try {
87
+ const { getControlPlaneDb, closeControlPlaneDb } = await import('../db.js');
88
+ const { createHome, setHomeStatus } = await import('../registry.js');
89
+ const { createSchedule } = await import('../scheduler/schedule-store.js');
90
+ const { claimFire } = await import('../scheduler/fire-store.js');
91
+ const { authorizeTrigger } = await import('../triggers/acl.js');
92
+ getControlPlaneDb(); // open + migrate
93
+ createHome({ home_id: 'h1', tenant_id: 't1', user_id: 'u1', status: 'running' });
94
+ createHome({ home_id: 'h2', tenant_id: 't2', user_id: 'u2', status: 'running' });
95
+ const schedule = createSchedule({
96
+ home_id: 'h1',
97
+ label: 'x',
98
+ recurrence: '*/5 * * * *',
99
+ timezone: 'UTC',
100
+ delivery_payload: {},
101
+ next_fire_at: '2026-06-30T12:00:00.000Z',
102
+ });
103
+ const claim = claimFire({ schedule_id: schedule.schedule_id, scheduled_for: schedule.next_fire_at });
104
+ const fireId = claim.fire.fire_id;
105
+ // Matching target home → authorized.
106
+ assert.deepEqual(authorizeTrigger('cron', fireId, 'h1'), { ok: true });
107
+ // Cross-home targeting → rejected.
108
+ assert.equal(authorizeTrigger('cron', fireId, 'h2').ok, false);
109
+ // Absent source row → rejected.
110
+ assert.equal(authorizeTrigger('cron', 'no-such-fire', 'h1').ok, false);
111
+ // Terminated target home → rejected even though the FK matches.
112
+ setHomeStatus('h1', 'terminated');
113
+ assert.equal(authorizeTrigger('cron', fireId, 'h1').ok, false);
114
+ closeControlPlaneDb(dbPath);
115
+ }
116
+ finally {
117
+ teardownDb(dbPath);
118
+ }
119
+ });
120
+ test('deliverTrigger writes real delivered/rejected audit rows through the chokepoint', async () => {
121
+ setupDb();
122
+ const dbPath = process.env['CRTR_HEARTH_CP_DB_PATH'];
123
+ try {
124
+ const { getControlPlaneDb, closeControlPlaneDb } = await import('../db.js');
125
+ const { createHome } = await import('../registry.js');
126
+ const { createSchedule } = await import('../scheduler/schedule-store.js');
127
+ const { claimFire } = await import('../scheduler/fire-store.js');
128
+ const { listTriggerAudit } = await import('../triggers/audit-store.js');
129
+ const { deliverTrigger, deliverInternals } = await import('../triggers/deliver.js');
130
+ const { buildTriggerEnvelope } = await import('../triggers/envelope.js');
131
+ getControlPlaneDb();
132
+ createHome({ home_id: 'h1', tenant_id: 't1', user_id: 'u1', status: 'running' });
133
+ createHome({ home_id: 'h2', tenant_id: 't2', user_id: 'u2', status: 'running' });
134
+ const schedule = createSchedule({
135
+ home_id: 'h1',
136
+ label: 'x',
137
+ recurrence: '*/5 * * * *',
138
+ timezone: 'UTC',
139
+ delivery_payload: { secret: 'never-persisted-raw' },
140
+ next_fire_at: '2026-06-30T12:00:00.000Z',
141
+ });
142
+ const fireId = claimFire({ schedule_id: schedule.schedule_id, scheduled_for: schedule.next_fire_at }).fire.fire_id;
143
+ const orig = { ...deliverInternals };
144
+ deliverInternals.wakeAndExecNodeMessage = async () => { }; // fake the provider exec only
145
+ try {
146
+ const okEnv = buildTriggerEnvelope({ source: 'cron', trigger_id: fireId, payload: { secret: 'never-persisted-raw' } });
147
+ const okRes = await deliverTrigger({ home_id: 'h1', source_ref: fireId, envelope: okEnv, tier: 'urgent' });
148
+ assert.equal(okRes.outcome, 'delivered');
149
+ // Cross-home target → chokepoint rejects (real ACL) and never execs.
150
+ const badEnv = buildTriggerEnvelope({ source: 'cron', trigger_id: fireId, payload: {} });
151
+ const badRes = await deliverTrigger({ home_id: 'h2', source_ref: fireId, envelope: badEnv, tier: 'urgent' });
152
+ assert.equal(badRes.outcome, 'rejected');
153
+ }
154
+ finally {
155
+ Object.assign(deliverInternals, orig);
156
+ }
157
+ const rows = listTriggerAudit('h1');
158
+ const outcomes = rows.map((r) => r.outcome).sort();
159
+ assert.deepEqual(outcomes, ['delivered', 'rejected']);
160
+ // No raw payload persisted — only a hash.
161
+ for (const row of rows) {
162
+ assert.equal(row.payload_sha256 !== null && row.payload_sha256.length === 64, true);
163
+ assert.equal(JSON.stringify(row).includes('never-persisted-raw'), false);
164
+ }
165
+ closeControlPlaneDb(dbPath);
166
+ }
167
+ finally {
168
+ teardownDb(dbPath);
169
+ }
170
+ });
@@ -0,0 +1,167 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createHmac } from 'node:crypto';
3
+ import { test } from 'node:test';
4
+ import { extractRoutingKey, processWebhookDelivery, } from '../ingress/webhook-route.js';
5
+ import { serializeEnvelope } from '../triggers/envelope.js';
6
+ // Category-3 test (CLAUDE.md "Testing policy" #3 — load-bearing Hearth/CP
7
+ // security regression). Invariants: master plan P5.5 / part-plan T-C3 R-ING-1/
8
+ // R-ING-3. (1) A webhook is delivered ONLY after HMAC-over-raw-body
9
+ // verification; a bad signature never reaches route delivery or the replay
10
+ // ledger. (2) Replay/idempotency: a duplicate delivery is acknowledged and NOT
11
+ // re-delivered. (3) The routing key is NEVER present in the envelope the home
12
+ // receives. (4) The pre-resolution rate limit sheds a flood before any route
13
+ // lookup. Every one of these is a silent-if-regressed security boundary.
14
+ const SECRET = 'whsec_test_value';
15
+ const ROUTE = {
16
+ route_id: 'r1',
17
+ tenant_id: 't1',
18
+ user_id: 'u1',
19
+ home_id: 'h1',
20
+ channel: 'webhook',
21
+ routing_key: 'my-public-routing-key',
22
+ routing_key_kind: 'opaque',
23
+ channel_secret_ref: 'ref-r1',
24
+ delivery_template: null,
25
+ enabled: true,
26
+ created_at: '2026-06-30T00:00:00.000Z',
27
+ updated_at: '2026-06-30T00:00:00.000Z',
28
+ };
29
+ function sign(body) {
30
+ return createHmac('sha256', SECRET).update(Buffer.from(body, 'utf8')).digest('hex');
31
+ }
32
+ function makeRequest(overrides = {}) {
33
+ const rawBody = Buffer.from(JSON.stringify({ event: 'ping', n: 1 }), 'utf8');
34
+ return {
35
+ routingKey: ROUTE.routing_key,
36
+ rawBody,
37
+ signatureHeader: sign(rawBody.toString('utf8')),
38
+ deliveryIdHeader: 'delivery-abc',
39
+ contentType: 'application/json',
40
+ ...overrides,
41
+ };
42
+ }
43
+ function makeDeps(cap, overrides = {}) {
44
+ return {
45
+ checkRate: () => ({ ok: true }),
46
+ resolveRoute: (channel, key) => {
47
+ cap.routeLookups += 1;
48
+ return channel === 'webhook' && key === ROUTE.routing_key ? ROUTE : null;
49
+ },
50
+ resolveSecret: (ref) => {
51
+ if (ref !== ROUTE.channel_secret_ref)
52
+ throw new Error(`unknown handle ${ref}`);
53
+ return SECRET;
54
+ },
55
+ claimWebhookDelivery: (input) => {
56
+ cap.claims += 1;
57
+ return {
58
+ delivery: {
59
+ delivery_id: 'd1',
60
+ route_id: input.route_id,
61
+ tenant_id: 't1',
62
+ user_id: 'u1',
63
+ home_id: 'h1',
64
+ replay_key: input.replay_key,
65
+ replay_window_start: input.replay_window_start,
66
+ payload_sha256: input.payload_sha256 ?? null,
67
+ signature_sha256: input.signature_sha256 ?? null,
68
+ state: 'received',
69
+ received_at: input.received_at ?? '2026-06-30T12:00:00.000Z',
70
+ delivered_at: null,
71
+ last_error: null,
72
+ created_at: '2026-06-30T12:00:00.000Z',
73
+ updated_at: '2026-06-30T12:00:00.000Z',
74
+ },
75
+ claimed: true,
76
+ };
77
+ },
78
+ setWebhookDeliveryState: () => { },
79
+ deliverTrigger: async (input) => {
80
+ cap.deliveries.push({ home_id: input.home_id, source_ref: input.source_ref, envelope: input.envelope, serialized: serializeEnvelope(input.envelope) });
81
+ return { outcome: 'delivered' };
82
+ },
83
+ now: () => new Date('2026-06-30T12:00:00.000Z'),
84
+ ...overrides,
85
+ };
86
+ }
87
+ function makeCaptured() {
88
+ return { deliveries: [], routeLookups: 0, claims: 0 };
89
+ }
90
+ test('a validly-signed webhook delivers once; envelope carries NO routing key', async () => {
91
+ const cap = makeCaptured();
92
+ const res = await processWebhookDelivery(makeRequest(), makeDeps(cap));
93
+ assert.equal(res.status, 202);
94
+ assert.equal(cap.deliveries.length, 1);
95
+ const d = cap.deliveries[0];
96
+ assert.equal(d.home_id, 'h1');
97
+ assert.equal(d.source_ref, 'r1');
98
+ const parsed = JSON.parse(d.serialized);
99
+ // R-ING-3: exactly the four canonical fields, no routing key anywhere.
100
+ assert.deepEqual(Object.keys(parsed).sort(), ['payload', 'received_at', 'source', 'trigger_id']);
101
+ assert.equal(d.serialized.includes(ROUTE.routing_key), false);
102
+ assert.equal(parsed['source'], 'webhook');
103
+ assert.equal(parsed['trigger_id'], `r1:delivery-abc`); // stable route-derived + per-delivery
104
+ assert.deepEqual(parsed['payload'], { event: 'ping', n: 1 });
105
+ });
106
+ test('a bad signature is rejected with no delivery and no replay-ledger write', async () => {
107
+ const cap = makeCaptured();
108
+ const res = await processWebhookDelivery(makeRequest({ signatureHeader: 'deadbeef' }), makeDeps(cap));
109
+ assert.equal(res.status, 401);
110
+ assert.equal(cap.deliveries.length, 0);
111
+ assert.equal(cap.claims, 0); // no webhook_delivery row for an unverified request
112
+ });
113
+ test('a missing signature is rejected', async () => {
114
+ const cap = makeCaptured();
115
+ const res = await processWebhookDelivery(makeRequest({ signatureHeader: null }), makeDeps(cap));
116
+ assert.equal(res.status, 401);
117
+ assert.equal(cap.deliveries.length, 0);
118
+ });
119
+ test('a replayed delivery is acknowledged idempotently and not re-delivered', async () => {
120
+ const cap = makeCaptured();
121
+ const deps = makeDeps(cap, {
122
+ claimWebhookDelivery: (input) => ({
123
+ delivery: {
124
+ delivery_id: 'd1',
125
+ route_id: input.route_id,
126
+ tenant_id: 't1',
127
+ user_id: 'u1',
128
+ home_id: 'h1',
129
+ replay_key: input.replay_key,
130
+ replay_window_start: input.replay_window_start,
131
+ payload_sha256: null,
132
+ signature_sha256: null,
133
+ state: 'delivered',
134
+ received_at: '2026-06-30T11:00:00.000Z',
135
+ delivered_at: '2026-06-30T11:00:00.000Z',
136
+ last_error: null,
137
+ created_at: '2026-06-30T11:00:00.000Z',
138
+ updated_at: '2026-06-30T11:00:00.000Z',
139
+ },
140
+ claimed: false, // slot already held → replay
141
+ }),
142
+ });
143
+ const res = await processWebhookDelivery(makeRequest(), deps);
144
+ assert.equal(res.status, 200);
145
+ assert.equal(cap.deliveries.length, 0);
146
+ });
147
+ test('an unknown routing key is a 404 with no delivery', async () => {
148
+ const cap = makeCaptured();
149
+ const res = await processWebhookDelivery(makeRequest({ routingKey: 'nope' }), makeDeps(cap));
150
+ assert.equal(res.status, 404);
151
+ assert.equal(cap.deliveries.length, 0);
152
+ });
153
+ test('the pre-resolution rate limit sheds before any route lookup', async () => {
154
+ const cap = makeCaptured();
155
+ const deps = makeDeps(cap, { checkRate: () => ({ ok: false, retryAfterMs: 1_000 }) });
156
+ const res = await processWebhookDelivery(makeRequest(), deps);
157
+ assert.equal(res.status, 429);
158
+ assert.equal(cap.routeLookups, 0); // rate limit is evaluated before resolveRoute
159
+ assert.equal(cap.deliveries.length, 0);
160
+ });
161
+ test('extractRoutingKey rejects traversal / multi-segment / empty keys', () => {
162
+ assert.equal(extractRoutingKey('/webhook/abc'), 'abc');
163
+ assert.equal(extractRoutingKey('/webhook/a%2Fb'), null); // decoded embedded slash
164
+ assert.equal(extractRoutingKey('/webhook/a/b'), null);
165
+ assert.equal(extractRoutingKey('/webhook/'), null);
166
+ assert.equal(extractRoutingKey('/webhook'), null);
167
+ });
@@ -0,0 +1,21 @@
1
+ export interface ControlPlaneConfig {
2
+ host: string;
3
+ port: number;
4
+ publicOrigin: string;
5
+ /** Whether the Hearth session cookie should carry `Secure` — true whenever
6
+ * `publicOrigin` is `https://`, mirroring the wake-proxy's rule. */
7
+ cookieSecure: boolean;
8
+ /** Upper bound P4.2's wake orchestration (`ensureAwake`) uses for a
9
+ * resume/recreate cycle before giving up. Not read by this module or by
10
+ * server.ts in this phase — carried here so the CP has exactly one config
11
+ * object once wake.ts lands. */
12
+ wakeTimeoutMs: number;
13
+ /** Ready-probe retry window P4.2's wake orchestration uses against
14
+ * `/node/<target>`. Not read by this module or by server.ts in this
15
+ * phase. */
16
+ readyTimeoutMs: number;
17
+ }
18
+ /** Load the CP server config from the environment (defaults applied for
19
+ * dogfood: loopback bind, port 8080). Throws on an invalid/missing value
20
+ * rather than silently falling back to an insecure default. */
21
+ export declare function loadControlPlaneConfig(env?: NodeJS.ProcessEnv): ControlPlaneConfig;
@@ -0,0 +1,77 @@
1
+ // control-plane/config.ts — the CP server's own config: bind address, public
2
+ // origin (used by session.ts for cookie security and state-changing
3
+ // browser-origin checks), and the wake/ready timeout knobs P4.2's wake
4
+ // orchestration will read off this same config object. Deliberately does
5
+ // NOT duplicate CP data-path resolution: the CP db path
6
+ // (`CRTR_HEARTH_CP_DATA_DIR`/`CRTR_HEARTH_CP_DB_PATH`, db.ts) and the
7
+ // secrets-file path (`CRTR_HEARTH_CP_SECRETS_FILE`, secrets.ts) are each
8
+ // resolved by their own module — callers go to those modules directly
9
+ // rather than threading a second, possibly-divergent copy through here.
10
+ import { general } from '../../core/errors.js';
11
+ const ENV = {
12
+ host: 'CRTR_HEARTH_CP_HOST',
13
+ port: 'CRTR_HEARTH_CP_PORT',
14
+ publicOrigin: 'CRTR_HEARTH_CP_PUBLIC_ORIGIN',
15
+ wakeTimeoutMs: 'CRTR_HEARTH_CP_WAKE_TIMEOUT_MS',
16
+ readyTimeoutMs: 'CRTR_HEARTH_CP_READY_TIMEOUT_MS',
17
+ };
18
+ function parsePort(value, fallback) {
19
+ if (value === undefined || value.trim() === '')
20
+ return fallback;
21
+ const parsed = Number(value);
22
+ if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) {
23
+ throw general(`invalid ${ENV.port}: ${value}`, { env: ENV.port });
24
+ }
25
+ return parsed;
26
+ }
27
+ function parseDuration(value, fallback, name) {
28
+ if (value === undefined || value.trim() === '')
29
+ return fallback;
30
+ const parsed = Number(value);
31
+ if (!Number.isInteger(parsed) || parsed < 0) {
32
+ throw general(`invalid ${name}: ${value}`, { env: name });
33
+ }
34
+ return parsed;
35
+ }
36
+ function isLoopbackHostname(hostname) {
37
+ return hostname === '127.0.0.1' || hostname === 'localhost' || hostname === '::1' || hostname === '::ffff:127.0.0.1' || hostname.startsWith('127.');
38
+ }
39
+ function parsePublicOrigin(env, host, port) {
40
+ const raw = env[ENV.publicOrigin]?.trim() ?? '';
41
+ if (raw !== '') {
42
+ let parsed;
43
+ try {
44
+ parsed = new URL(raw);
45
+ }
46
+ catch {
47
+ throw general(`invalid ${ENV.publicOrigin}: must be a valid URL`, { env: ENV.publicOrigin });
48
+ }
49
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
50
+ throw general(`invalid ${ENV.publicOrigin}: scheme must be http: or https:`, { env: ENV.publicOrigin, scheme: parsed.protocol });
51
+ }
52
+ const origin = parsed.origin;
53
+ if (origin === 'null' || origin === '') {
54
+ throw general(`invalid ${ENV.publicOrigin}: must be a valid web origin`, { env: ENV.publicOrigin });
55
+ }
56
+ if (parsed.protocol !== 'https:' && !isLoopbackHostname(parsed.hostname)) {
57
+ throw general(`${ENV.publicOrigin} must use https: for a non-loopback origin`, { env: ENV.publicOrigin, hostname: parsed.hostname });
58
+ }
59
+ return { publicOrigin: origin, cookieSecure: parsed.protocol === 'https:' };
60
+ }
61
+ if (isLoopbackHostname(host)) {
62
+ const origin = `http://127.0.0.1:${port}`;
63
+ return { publicOrigin: origin, cookieSecure: false };
64
+ }
65
+ throw general(`${ENV.publicOrigin} is required when ${ENV.host} is bound off-loopback`, { env: ENV.publicOrigin, host });
66
+ }
67
+ /** Load the CP server config from the environment (defaults applied for
68
+ * dogfood: loopback bind, port 8080). Throws on an invalid/missing value
69
+ * rather than silently falling back to an insecure default. */
70
+ export function loadControlPlaneConfig(env = process.env) {
71
+ const host = (env[ENV.host] ?? '127.0.0.1').trim() || '127.0.0.1';
72
+ const port = parsePort(env[ENV.port], 8080);
73
+ const { publicOrigin, cookieSecure } = parsePublicOrigin(env, host, port);
74
+ const wakeTimeoutMs = parseDuration(env[ENV.wakeTimeoutMs], 150_000, ENV.wakeTimeoutMs);
75
+ const readyTimeoutMs = parseDuration(env[ENV.readyTimeoutMs], 8_000, ENV.readyTimeoutMs);
76
+ return { host, port, publicOrigin, cookieSecure, wakeTimeoutMs, readyTimeoutMs };
77
+ }
@@ -0,0 +1,30 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ /** Resolve the CP SQLite db file path: an explicit `CRTR_HEARTH_CP_DB_PATH`
3
+ * override, else `<dataDir>/control-plane.db` where `dataDir` follows the
4
+ * same `CRTR_HEARTH_CP_DATA_DIR` convention `secrets.ts` uses. Deliberately
5
+ * independent of `canvasDbPath()` / `CRTR_HOME` — the control plane is not a
6
+ * canvas node and must not share or collide with a home's canvas db. */
7
+ export declare function controlPlaneDbPath(env?: NodeJS.ProcessEnv): string;
8
+ /** The ordered migration list. Index `i` is migration version `i + 1`; the
9
+ * db's `user_version` tracks how many have been applied. Append only. */
10
+ export declare const MIGRATIONS: ReadonlyArray<(db: DatabaseSync) => void>;
11
+ /** Bring `db` up to the latest schema version. Reads `user_version`, runs
12
+ * each pending migration in order, and bumps `user_version` after each so
13
+ * the work is gated and idempotent: re-running is a no-op once
14
+ * `user_version` reaches `MIGRATIONS.length`. Forward-only. */
15
+ export declare function migrate(db: DatabaseSync): void;
16
+ /** Open (or reuse) the CP db at `path`, initializing WAL + schema on first
17
+ * open. This is the SOLE function in the codebase that may construct a
18
+ * `DatabaseSync` against the CP db file — every CP store goes through this
19
+ * (directly or via `getControlPlaneDb()`) and never opens its own
20
+ * connection. Keyed by path so tests with distinct temp dbs get independent
21
+ * handles, exactly like `src/core/canvas/db.ts`'s `openDb()`. */
22
+ export declare function openControlPlaneDb(path: string): DatabaseSync;
23
+ /** The cached handle accessor every CP store (registry, scheduler, ingress)
24
+ * imports — resolves the db path the standard way and opens/reuses the one
25
+ * connection for it. Never construct a second `DatabaseSync` against the CP
26
+ * db elsewhere in the codebase. */
27
+ export declare function getControlPlaneDb(env?: NodeJS.ProcessEnv): DatabaseSync;
28
+ /** Close and forget the handle for `path` (defaults to the standard
29
+ * resolved path). Mainly for tests. */
30
+ export declare function closeControlPlaneDb(path?: string): void;