@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,430 @@
1
+ // model-auth-guest.ts — Hearth product seam: the in-guest model-auth lane.
2
+ //
3
+ // Handles GET/POST /__hearth/model-auth/anthropic/{status,start,finish}, mounted
4
+ // by src/clients/web/server.ts (the crtr web substrate provides only routing +
5
+ // relay-token enforcement there; ALL Hearth/OAuth product logic lives here).
6
+ //
7
+ // This handler runs IN the guest: it performs the PKCE/OAuth exchange itself
8
+ // and talks to pi's AuthStorage directly to read/write the credential — no
9
+ // exec round-trip to another process. There is no tenantId/owner-auth
10
+ // resolution: the relay token already gates the whole lane one layer up, and
11
+ // a guest serves exactly one home.
12
+ //
13
+ // This module must not import anything from src/clients/web (the seam runs the
14
+ // other direction: server.ts imports `handleHearthModelAuthRequest` from here)
15
+ // — it is a standalone, self-contained Hearth handler.
16
+ import { createHash, randomBytes as nodeRandomBytes } from 'node:crypto';
17
+ import { AuthStorage } from '@earendil-works/pi-coding-agent';
18
+ const ANTHROPIC_CLIENT_ID = '9d1c250a-e61b-44d9-88ed-5944d1962f5e';
19
+ const ANTHROPIC_AUTHORIZE_URL = 'https://claude.ai/oauth/authorize';
20
+ const ANTHROPIC_TOKEN_URL = 'https://platform.claude.com/v1/oauth/token';
21
+ const ANTHROPIC_REDIRECT_URI = 'http://localhost:53692/callback';
22
+ const ANTHROPIC_SCOPES = 'org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload';
23
+ const ANTHROPIC_SESSION_TTL_MS = 10 * 60_000;
24
+ const ANTHROPIC_CALLBACK_MAX_URL_LENGTH = 2048;
25
+ const ANTHROPIC_TOKEN_TIMEOUT_MS = 30_000;
26
+ const ANTHROPIC_TOKEN_SKEW_MS = 5 * 60_000;
27
+ const BODY_LIMIT_BYTES = 16 * 1024;
28
+ // ── Redaction ────────────────────────────────────────────────────────────
29
+ // Never let a raw access/refresh token, bearer header, auth.json path, or
30
+ // OAuth query param reach a log line or an HTTP response body.
31
+ const REDIRECT_URL_RE = /https?:\/\/localhost:53692\/callback[^\s"'`<>)]*/gi;
32
+ const BEARER_RE = /\bBearer\s+[A-Za-z0-9._~+/-]+=?=?/gi;
33
+ const TOKEN_QUERY_RE = /([?&](?:token|code|state|code_verifier)=)[^&#\s]+/gi;
34
+ const JSON_TOKEN_RE = /("(?:access_token|refresh_token|access|refresh|code|state|code_verifier)"\s*:\s*")[^"]+(")/gi;
35
+ const ASSIGN_TOKEN_RE = /\b(?:access_token|refresh_token|access|refresh|code|state|code_verifier)\s*[:=]\s*[^\s,&}]+/gi;
36
+ const AUTH_JSON_RE = /\bauth\.json\b/gi;
37
+ const SHA256_RE = /\bsha256:[0-9a-f]{64}\b/gi;
38
+ function redact(message) {
39
+ return message
40
+ .replace(REDIRECT_URL_RE, '[redacted redirect url]')
41
+ .replace(BEARER_RE, 'Bearer [redacted]')
42
+ .replace(TOKEN_QUERY_RE, '$1[redacted]')
43
+ .replace(JSON_TOKEN_RE, '$1[redacted]$2')
44
+ .replace(ASSIGN_TOKEN_RE, (value) => value.replace(/[:=]\s*[^\s,&}]+$/, ': [redacted]'))
45
+ .replace(AUTH_JSON_RE, '[redacted auth.json]')
46
+ .replace(SHA256_RE, 'sha256:[redacted]');
47
+ }
48
+ function redactedErrorMessage(error) {
49
+ return redact(error instanceof Error ? error.message : String(error));
50
+ }
51
+ let currentSession;
52
+ function defaultRandomBytes(size) {
53
+ return nodeRandomBytes(size);
54
+ }
55
+ function defaultSha256(value) {
56
+ return createHash('sha256').update(value, 'utf8').digest();
57
+ }
58
+ function purgeExpiredSession(now) {
59
+ if (currentSession !== undefined && currentSession.expiresAt <= now) {
60
+ currentSession = undefined;
61
+ }
62
+ }
63
+ function buildAuthUrl(session, challenge) {
64
+ const params = new URLSearchParams({
65
+ // claude.ai/oauth/authorize requires `code=true` (the Claude Code authorize
66
+ // flow param); omitting it makes the endpoint reject with "Invalid request
67
+ // format". Claude Code also requires `state` to be the PKCE verifier so the
68
+ // authorize request satisfies `code_challenge === S256(state)`; the
69
+ // installed @earendil-works/pi-ai adapter does the same (`state: verifier`).
70
+ code: 'true',
71
+ client_id: ANTHROPIC_CLIENT_ID,
72
+ response_type: 'code',
73
+ redirect_uri: ANTHROPIC_REDIRECT_URI,
74
+ scope: ANTHROPIC_SCOPES,
75
+ state: session.state,
76
+ code_challenge: challenge,
77
+ code_challenge_method: 'S256',
78
+ });
79
+ return `${ANTHROPIC_AUTHORIZE_URL}?${params.toString()}`;
80
+ }
81
+ function failure(status, error) {
82
+ return { ok: false, status, error: redact(error) };
83
+ }
84
+ function parseCallbackUrl(raw) {
85
+ if (raw.length > ANTHROPIC_CALLBACK_MAX_URL_LENGTH) {
86
+ return failure(400, 'Anthropic callback URL is too long');
87
+ }
88
+ let url;
89
+ try {
90
+ url = new URL(raw);
91
+ }
92
+ catch {
93
+ return failure(400, 'Anthropic callback URL is invalid');
94
+ }
95
+ if (url.protocol !== 'http:' || url.hostname !== 'localhost' || url.port !== '53692' || url.pathname !== '/callback') {
96
+ return failure(400, 'Anthropic callback URL must be http://localhost:53692/callback');
97
+ }
98
+ const error = url.searchParams.get('error');
99
+ if (error !== null && error.trim() !== '') {
100
+ return failure(400, `Anthropic callback reported error=${error}`);
101
+ }
102
+ const code = url.searchParams.get('code')?.trim() ?? '';
103
+ const state = url.searchParams.get('state')?.trim() ?? '';
104
+ if (code === '' || state === '') {
105
+ return failure(400, 'Anthropic callback is missing code or state');
106
+ }
107
+ return { code, state };
108
+ }
109
+ async function postTokenExchange(body) {
110
+ const controller = new AbortController();
111
+ const timeout = setTimeout(() => {
112
+ controller.abort(new Error('Anthropic OAuth token exchange timed out'));
113
+ }, ANTHROPIC_TOKEN_TIMEOUT_MS);
114
+ timeout.unref();
115
+ try {
116
+ const response = await fetch(ANTHROPIC_TOKEN_URL, {
117
+ method: 'POST',
118
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
119
+ body: JSON.stringify(body),
120
+ signal: controller.signal,
121
+ });
122
+ const responseBody = await response.text();
123
+ if (!response.ok) {
124
+ return failure(502, `Anthropic token exchange failed with HTTP ${response.status} ${response.statusText}${responseBody.trim() === '' ? '' : `: ${responseBody}`}`);
125
+ }
126
+ return { ok: true, body: responseBody };
127
+ }
128
+ catch (error) {
129
+ return failure(502, `Anthropic token exchange request failed: ${redactedErrorMessage(error)}`);
130
+ }
131
+ finally {
132
+ clearTimeout(timeout);
133
+ }
134
+ }
135
+ function validateTokenExchangeResponse(body, now) {
136
+ let parsed;
137
+ try {
138
+ parsed = JSON.parse(body);
139
+ }
140
+ catch {
141
+ return failure(502, `Anthropic token exchange returned invalid JSON: ${body}`);
142
+ }
143
+ const access = typeof parsed.access_token === 'string' ? parsed.access_token.trim() : '';
144
+ const refresh = typeof parsed.refresh_token === 'string' ? parsed.refresh_token.trim() : '';
145
+ const expiresIn = typeof parsed.expires_in === 'number' ? parsed.expires_in : Number.NaN;
146
+ if (access === '' || refresh === '' || !Number.isFinite(expiresIn) || expiresIn <= 0) {
147
+ return failure(502, 'Anthropic token exchange response is missing access_token, refresh_token, or positive expires_in');
148
+ }
149
+ return { type: 'oauth', access, refresh, expires: now + expiresIn * 1000 - ANTHROPIC_TOKEN_SKEW_MS };
150
+ }
151
+ function startAnthropicOAuthSession(now) {
152
+ purgeExpiredSession(now);
153
+ const sessionId = defaultRandomBytes(16).toString('base64url');
154
+ const verifier = defaultRandomBytes(32).toString('base64url');
155
+ const session = {
156
+ sessionId,
157
+ state: verifier,
158
+ verifier,
159
+ createdAt: now,
160
+ expiresAt: now + ANTHROPIC_SESSION_TTL_MS,
161
+ };
162
+ const challenge = defaultSha256(verifier).toString('base64url');
163
+ currentSession = session;
164
+ return { sessionId, authUrl: buildAuthUrl(session, challenge), expiresAt: session.expiresAt };
165
+ }
166
+ async function finishAnthropicOAuthSession(sessionId, redirectUrl) {
167
+ const now = Date.now();
168
+ purgeExpiredSession(now);
169
+ const session = currentSession;
170
+ if (session === undefined) {
171
+ return failure(400, 'Anthropic OAuth session not found or expired');
172
+ }
173
+ // Delete on first use regardless of outcome below — a session is single-shot.
174
+ currentSession = undefined;
175
+ if (session.sessionId !== sessionId) {
176
+ return failure(400, 'Anthropic OAuth session id does not match the active session');
177
+ }
178
+ const parsed = parseCallbackUrl(redirectUrl);
179
+ if ('status' in parsed)
180
+ return parsed;
181
+ if (parsed.state !== session.state) {
182
+ return failure(400, 'Anthropic OAuth callback state mismatch');
183
+ }
184
+ const result = await postTokenExchange({
185
+ grant_type: 'authorization_code',
186
+ client_id: ANTHROPIC_CLIENT_ID,
187
+ code: parsed.code,
188
+ state: parsed.state,
189
+ redirect_uri: ANTHROPIC_REDIRECT_URI,
190
+ code_verifier: session.verifier,
191
+ });
192
+ if ('status' in result)
193
+ return result;
194
+ const credential = validateTokenExchangeResponse(result.body, now);
195
+ if ('status' in credential)
196
+ return credential;
197
+ return { ok: true, sessionId: session.sessionId, credential };
198
+ }
199
+ // ── AuthStorage (direct, in-guest) ──────────────────────────────────────────
200
+ function readAnthropicStatus() {
201
+ const storage = AuthStorage.create();
202
+ const credential = storage.get('anthropic');
203
+ const errors = storage.drainErrors();
204
+ if (errors.length > 0) {
205
+ throw new Error(errors.map((error) => error.message).join('; '));
206
+ }
207
+ const adapterConfigured = storage.getOAuthProviders().some((provider) => provider.id === 'anthropic');
208
+ const storedOauth = credential?.type === 'oauth';
209
+ const expiresAt = storedOauth ? credential.expires : null;
210
+ return { storedOauth, expiresAt, adapterConfigured };
211
+ }
212
+ function writeAnthropicCredential(credential) {
213
+ const storage = AuthStorage.create();
214
+ // pi-ai's `OAuthCredentials` carries a `[key: string]: unknown` index
215
+ // signature for adapter-specific extra fields; our narrower
216
+ // AnthropicOAuthCredential is otherwise structurally identical (`type`,
217
+ // `refresh`, `access`, `expires`), so this is a safe widen, not a cast away
218
+ // from a real type mismatch.
219
+ storage.set('anthropic', credential);
220
+ const errors = storage.drainErrors();
221
+ if (errors.length > 0) {
222
+ throw new Error(errors.map((error) => error.message).join('; '));
223
+ }
224
+ // set() mutates in-memory state before persistence — re-read through a FRESH
225
+ // AuthStorage instance to verify the write actually round-tripped to disk.
226
+ const reread = AuthStorage.create();
227
+ const stored = reread.get('anthropic');
228
+ const rereadErrors = reread.drainErrors();
229
+ if (rereadErrors.length > 0) {
230
+ throw new Error(rereadErrors.map((error) => error.message).join('; '));
231
+ }
232
+ if (stored === undefined ||
233
+ stored.type !== 'oauth' ||
234
+ stored.refresh !== credential.refresh ||
235
+ stored.access !== credential.access ||
236
+ stored.expires !== credential.expires) {
237
+ throw new Error('stored anthropic oauth credential did not round-trip');
238
+ }
239
+ return { storedOauth: true, expiresAt: stored.expires };
240
+ }
241
+ // ── HTTP plumbing ───────────────────────────────────────────────────────
242
+ function respondJson(res, statusCode, value) {
243
+ const body = `${JSON.stringify(value, null, 2)}\n`;
244
+ res.writeHead(statusCode, {
245
+ 'content-type': 'application/json; charset=utf-8',
246
+ 'content-length': Buffer.byteLength(body),
247
+ 'cache-control': 'no-store',
248
+ });
249
+ res.end(body);
250
+ }
251
+ function respondText(res, statusCode, message) {
252
+ const body = `${redact(message)}\n`;
253
+ res.writeHead(statusCode, {
254
+ 'content-type': 'text/plain; charset=utf-8',
255
+ 'content-length': Buffer.byteLength(body),
256
+ 'cache-control': 'no-store',
257
+ });
258
+ res.end(body);
259
+ }
260
+ /** Read a request body up to `limitBytes`, rejecting (and destroying the
261
+ * socket) if it grows past the cap. */
262
+ function readJsonBody(req, limitBytes) {
263
+ return new Promise((resolve, reject) => {
264
+ const chunks = [];
265
+ let bytes = 0;
266
+ const cleanup = () => {
267
+ req.off('data', onData);
268
+ req.off('end', onEnd);
269
+ req.off('error', onError);
270
+ req.off('aborted', onAbort);
271
+ };
272
+ const onData = (chunk) => {
273
+ bytes += chunk.byteLength;
274
+ if (bytes > limitBytes) {
275
+ cleanup();
276
+ req.destroy();
277
+ reject(new Error(`request body too large (limit ${limitBytes} bytes)`));
278
+ return;
279
+ }
280
+ chunks.push(chunk);
281
+ };
282
+ const onEnd = () => {
283
+ cleanup();
284
+ try {
285
+ const text = Buffer.concat(chunks).toString('utf8');
286
+ resolve(text === '' ? {} : JSON.parse(text));
287
+ }
288
+ catch (error) {
289
+ reject(error instanceof Error ? error : new Error(String(error)));
290
+ }
291
+ };
292
+ const onError = (error) => {
293
+ cleanup();
294
+ reject(error instanceof Error ? error : new Error(String(error)));
295
+ };
296
+ const onAbort = () => {
297
+ cleanup();
298
+ reject(new Error('request aborted while reading body'));
299
+ };
300
+ req.on('data', onData);
301
+ req.once('end', onEnd);
302
+ req.once('error', onError);
303
+ req.once('aborted', onAbort);
304
+ });
305
+ }
306
+ function isPlainObject(value) {
307
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
308
+ }
309
+ function parseFinishBody(body) {
310
+ if (!isPlainObject(body))
311
+ return null;
312
+ if (Object.keys(body).length !== 2)
313
+ return null;
314
+ const sessionId = typeof body.sessionId === 'string' ? body.sessionId.trim() : '';
315
+ const redirectUrl = typeof body.redirectUrl === 'string' ? body.redirectUrl.trim() : '';
316
+ if (sessionId === '' || redirectUrl === '')
317
+ return null;
318
+ return { sessionId, redirectUrl };
319
+ }
320
+ async function handleStatus(req, res) {
321
+ if (req.method !== 'GET') {
322
+ respondText(res, 405, 'method not allowed');
323
+ return;
324
+ }
325
+ try {
326
+ respondJson(res, 200, readAnthropicStatus());
327
+ }
328
+ catch (error) {
329
+ respondJson(res, 502, { error: redactedErrorMessage(error) });
330
+ }
331
+ }
332
+ async function handleStart(req, res) {
333
+ if (req.method !== 'POST') {
334
+ respondText(res, 405, 'method not allowed');
335
+ return;
336
+ }
337
+ let body;
338
+ try {
339
+ body = await readJsonBody(req, BODY_LIMIT_BYTES);
340
+ }
341
+ catch (error) {
342
+ respondJson(res, 400, { error: redactedErrorMessage(error) });
343
+ return;
344
+ }
345
+ if (!isPlainObject(body)) {
346
+ respondJson(res, 400, { error: 'start request must be empty or a JSON object' });
347
+ return;
348
+ }
349
+ try {
350
+ const started = startAnthropicOAuthSession(Date.now());
351
+ respondJson(res, 200, {
352
+ provider: 'anthropic',
353
+ sessionId: started.sessionId,
354
+ authUrl: started.authUrl,
355
+ expiresAt: started.expiresAt,
356
+ });
357
+ }
358
+ catch (error) {
359
+ respondJson(res, 502, { error: redactedErrorMessage(error) });
360
+ }
361
+ }
362
+ async function handleFinish(req, res) {
363
+ if (req.method !== 'POST') {
364
+ respondText(res, 405, 'method not allowed');
365
+ return;
366
+ }
367
+ let body;
368
+ try {
369
+ body = await readJsonBody(req, BODY_LIMIT_BYTES);
370
+ }
371
+ catch (error) {
372
+ respondJson(res, 400, { error: redactedErrorMessage(error) });
373
+ return;
374
+ }
375
+ const parsed = parseFinishBody(body);
376
+ if (parsed === null) {
377
+ respondJson(res, 400, { error: 'finish request must be { sessionId, redirectUrl }' });
378
+ return;
379
+ }
380
+ try {
381
+ const finished = await finishAnthropicOAuthSession(parsed.sessionId, parsed.redirectUrl);
382
+ if (!finished.ok) {
383
+ respondJson(res, finished.status, { error: finished.error });
384
+ return;
385
+ }
386
+ const stored = writeAnthropicCredential(finished.credential);
387
+ respondJson(res, 200, {
388
+ ok: true,
389
+ provider: 'anthropic',
390
+ sessionId: finished.sessionId,
391
+ storedOauth: stored.storedOauth,
392
+ expiresAt: stored.expiresAt,
393
+ });
394
+ }
395
+ catch (error) {
396
+ respondJson(res, 502, { error: redactedErrorMessage(error) });
397
+ }
398
+ }
399
+ /** Dispatch one `/__hearth/model-auth/anthropic/{status,start,finish}` request.
400
+ * The caller (src/clients/web/server.ts) has already matched the path prefix
401
+ * and enforced the relay token — this function assumes both are done and
402
+ * handles ONLY routing-within-the-lane, method checks, and the Hearth/OAuth
403
+ * product logic. Always writes a response; never throws (errors become a
404
+ * redacted 502/500 JSON body). */
405
+ export async function handleHearthModelAuthRequest(req, res) {
406
+ const pathname = new URL(req.url ?? '/', 'http://127.0.0.1').pathname;
407
+ try {
408
+ if (pathname === '/__hearth/model-auth/anthropic/status') {
409
+ await handleStatus(req, res);
410
+ return;
411
+ }
412
+ if (pathname === '/__hearth/model-auth/anthropic/start') {
413
+ await handleStart(req, res);
414
+ return;
415
+ }
416
+ if (pathname === '/__hearth/model-auth/anthropic/finish') {
417
+ await handleFinish(req, res);
418
+ return;
419
+ }
420
+ respondText(res, 404, 'not found');
421
+ }
422
+ catch (error) {
423
+ if (!res.headersSent) {
424
+ respondJson(res, 500, { error: redactedErrorMessage(error) });
425
+ }
426
+ else {
427
+ res.destroy();
428
+ }
429
+ }
430
+ }
@@ -1,4 +1,5 @@
1
- import type { MachineId, MachineRef, M0Config, TenantId } from './types.js';
1
+ import type { HomeProviderDescriptor, HomeProviderRefresh, MachineId, MachineRef, M0Config } from './types.js';
2
+ import type { ExecInput, ExecResult } from './providers/types.js';
2
3
  /**
3
4
  * The Hearth home backend seam. The wake-proxy front door (token auth, origin checks,
4
5
  * SSE/WS forwarding, the source gate) is vendor-neutral and drives a home purely through
@@ -6,14 +7,20 @@ import type { MachineId, MachineRef, M0Config, TenantId } from './types.js';
6
7
  */
7
8
  export interface HomeBackend {
8
9
  /**
9
- * Bring the tenant's home up and serving — warm-resume or recreate as the backend decides —
10
- * refresh its public route, and persist `webRoute` + `relayToken` to the registry.
10
+ * Bring a CP-resolved home up and serving — warm-resume or recreate as the backend decides —
11
+ * and return refreshed provider pointers for the CP registry to persist.
11
12
  */
12
- wake(tenantId: TenantId): Promise<void>;
13
- /** Pause the tenant's home. */
14
- suspend(tenantId: TenantId): Promise<void>;
13
+ wake(home: HomeProviderDescriptor): Promise<HomeProviderRefresh>;
14
+ /** Pause the home and return refreshed provider pointers for the CP registry to persist. */
15
+ suspend(home: HomeProviderDescriptor): Promise<HomeProviderRefresh>;
15
16
  /** Machine resources (cpu/mem) for status, or null when unavailable. */
16
17
  getMachine(machineId: MachineId): Promise<MachineRef | null>;
18
+ /**
19
+ * The P2.6 stdin-capable provider exec seam, exposed through this vendor-neutral interface
20
+ * so CP code (P4.4 `wakeAndExecNodeMessage`) never imports a concrete sandbox SDK to run an
21
+ * in-guest command. Callers pass untrusted bodies via `input.stdin`, never `input.command`.
22
+ */
23
+ exec(machineId: MachineId, input: ExecInput): Promise<ExecResult>;
17
24
  }
18
25
  /**
19
26
  * Resolve the configured home backend.
@@ -5,6 +5,8 @@ export interface BuildBootstrapScriptOpts {
5
5
  webPort: number;
6
6
  nodeId?: string | null;
7
7
  piAuthJson?: string | null;
8
+ piPackages?: string[];
9
+ modelLaddersJson?: string | null;
8
10
  isFirstProvision: boolean;
9
11
  }
10
12
  export declare function buildBootstrapScript(opts: BuildBootstrapScriptOpts): string;
@@ -1,39 +1,147 @@
1
- import { join } from 'node:path';
1
+ import { dirname, join } from 'node:path';
2
+ import { general } from '../../errors.js';
3
+ import { guestEnv } from '../guest-env.js';
4
+ // The baked, read-only product layer (deploy/hearth-blaxel/Dockerfile WORKDIR,
5
+ // and config.ts's ENV.guestCode default). Bootstrap never installs anything
6
+ // here at runtime — it only reads what the image already baked.
7
+ const GUEST_CODE_PATH = '/opt/crouter';
8
+ // The baked crtr binary's fixed, image-symlinked path (deploy/hearth-blaxel/Dockerfile
9
+ // `ln -sf /opt/crouter/node_modules/.bin/crtr /usr/local/bin/crtr`). Every crtr
10
+ // invocation this script makes targets this exact path rather than a bare `crtr`
11
+ // PATH lookup: guest-env.ts's PATH still lists a legacy `$HOME/.crtr-runtime/bin`
12
+ // dir ahead of /usr/local/bin — a holdover from the pre-cutover boot-time `npm
13
+ // install --prefix` flow that P3.1 deleted — and nothing populates that directory
14
+ // anymore, but a volume provisioned before this cutover can still have a stale
15
+ // crtr binary sitting there. Targeting the baked path directly makes PATH order
16
+ // irrelevant for this script's own invocations.
17
+ const BAKED_CRTR_PATH = '/usr/local/bin/crtr';
2
18
  function shellQuote(value) {
3
19
  return `'${value.replace(/'/g, `'"'"'`)}'`;
4
20
  }
21
+ function uniqueStrings(values) {
22
+ const result = [];
23
+ const seen = new Set();
24
+ for (const value of values) {
25
+ const trimmed = value?.trim();
26
+ if (!trimmed || seen.has(trimmed))
27
+ continue;
28
+ seen.add(trimmed);
29
+ result.push(trimmed);
30
+ }
31
+ return result;
32
+ }
33
+ function appendJsonSeed(lines, path, marker, content) {
34
+ const raw = content?.trim();
35
+ if (!raw)
36
+ return;
37
+ lines.push(`cat > ${shellQuote(path)} <<'${marker}'`, raw, marker);
38
+ }
39
+ /** Fail-fast assertion: baked crtr is on PATH and pinned to the exact
40
+ * expected version, and the bootstrap command surface it depends on
41
+ * (`crtr surface web serve`) actually exists. No install, no fallback to an
42
+ * older command name — command drift fails the boot instead of silently
43
+ * taking a different path (the M0 published-install incident this replaces). */
44
+ function appendCommandSurfaceAssertions(lines, crtrVersion) {
45
+ const crtr = shellQuote(BAKED_CRTR_PATH);
46
+ lines.push(`if [ ! -x ${crtr} ]; then`, ` printf "baked crtr not found at %s\\n" ${crtr} >&2`, ' exit 1', 'fi',
47
+ // Stale-PATH shadow guard: even though every invocation below targets the
48
+ // baked path directly, assert that a bare `crtr` lookup ALSO resolves
49
+ // there — catches a stale volume-installed binary shadowing the baked one
50
+ // ahead of time, before anything downstream of this script (e.g. a node
51
+ // engine spawned later in this session) could be tricked by it.
52
+ 'resolved_crtr="$(command -v crtr 2>/dev/null || true)"', `if [ "$resolved_crtr" != ${crtr} ]; then`, ` printf "stale crtr shadowing baked binary: PATH resolves crtr to %s, expected %s\\n" "$resolved_crtr" ${crtr} >&2`, ' exit 1', 'fi', `actual_crtr_version="$(${crtr} --json sys version | node -e 'let s="";process.stdin.on("data",c=>s+=c);process.stdin.on("end",()=>{process.stdout.write(JSON.parse(s).version)})')"`, `if [ "$actual_crtr_version" != ${shellQuote(crtrVersion)} ]; then`, ` printf "crtr version assertion FAILED: baked %s, expected %s\\n" "$actual_crtr_version" ${shellQuote(crtrVersion)} >&2`, ' exit 1', 'fi', `if ! ${crtr} surface web -h >/dev/null 2>&1 || ! ${crtr} surface web serve -h >/dev/null 2>&1; then`, ' printf "command surface assertion FAILED: crtr surface web serve not exposed\\n" >&2', ' exit 1', 'fi');
53
+ }
54
+ /** Cache-prime the baked pi Claude OAuth adapter into pi's user npm install
55
+ * root (`$HOME/.pi/agent/npm/node_modules/pi-claude-oauth-adapter`) so pi's
56
+ * package manager finds it already present and skips a network install
57
+ * (see @earendil-works/pi-coding-agent's getNpmInstallPath/needsInstall:
58
+ * scope "user" resolves to exactly this path and is used as-is when it
59
+ * exists). Existence-gated and unconditional (not first-boot-only) so a
60
+ * volume provisioned before this priming existed self-heals on its next
61
+ * boot; never overwrites an already-primed copy. */
62
+ function appendOauthAdapterCachePrime(lines, guestHome) {
63
+ const bakedDir = join(GUEST_CODE_PATH, 'node_modules', 'pi-claude-oauth-adapter');
64
+ const cacheDir = join(guestHome, '.pi', 'agent', 'npm', 'node_modules', 'pi-claude-oauth-adapter');
65
+ lines.push(`if [ -d ${shellQuote(bakedDir)} ] && [ ! -d ${shellQuote(cacheDir)} ]; then`, ` mkdir -p ${shellQuote(dirname(cacheDir))}`, ` cp -R ${shellQuote(bakedDir)} ${shellQuote(cacheDir)}`, 'fi');
66
+ }
5
67
  export function buildBootstrapScript(opts) {
68
+ if (opts.relayToken.trim() === '') {
69
+ throw general('buildBootstrapScript: relayToken must not be empty — the web lane must never bind without relay-token enforcement', {
70
+ guestHome: opts.guestHome,
71
+ });
72
+ }
73
+ const nodeId = (opts.nodeId ?? '').trim();
74
+ if (!opts.isFirstProvision && nodeId === '') {
75
+ throw general('buildBootstrapScript: nodeId is required when isFirstProvision is false', { guestHome: opts.guestHome });
76
+ }
77
+ // Single source of truth for the home env table (HOME/CRTR_HOME on the
78
+ // durable volume; CRTR_SOCK_DIR/CRTR_PIDFILE on tmpfs; CRTR_CANVAS_DB left
79
+ // unset) — see guest-env.ts. Re-exported here because this script is its
80
+ // own provider exec, not guaranteed to inherit the sandbox-level envs set
81
+ // at machine creation. `guestEnv` only dereferences `guestHome`, so a
82
+ // minimal config stand-in is enough.
83
+ const env = guestEnv({ guestHome: opts.guestHome });
84
+ // Override the PATH guestEnv() emits: it still lists the legacy (dead)
85
+ // `$HOME/.crtr-runtime/bin` ahead of /usr/local/bin (see BAKED_CRTR_PATH
86
+ // above). This script's own crtr invocations target the baked path
87
+ // directly regardless, but fix the exported PATH too so anything else
88
+ // spawned downstream in this session (e.g. the daemon and the node
89
+ // engines it launches) that calls bare `crtr` also resolves to the baked
90
+ // binary, not a stale volume copy.
91
+ env['PATH'] = '/usr/local/bin:/usr/bin:/bin';
6
92
  const runtimeDir = join(opts.guestHome, '.crtr-runtime');
7
- const versionMarker = join(runtimeDir, '.crtr-version');
93
+ const settingsPath = join(opts.guestHome, '.pi', 'agent', 'settings.json');
94
+ const builtinPiExtensionsDir = join(GUEST_CODE_PATH, 'node_modules', '@crouton-kit', 'crouter', 'dist', 'builtin-pi-packages');
95
+ const packages = uniqueStrings([
96
+ ...(opts.piPackages ?? []),
97
+ join(builtinPiExtensionsDir, 'pi-crtr-extensions'),
98
+ ]);
99
+ const settingsJson = JSON.stringify({
100
+ packages,
101
+ defaultProvider: 'anthropic',
102
+ defaultModel: 'claude-opus-4-8',
103
+ defaultThinkingLevel: 'high',
104
+ enableSkillCommands: true,
105
+ steeringMode: 'all',
106
+ quietStartup: true,
107
+ theme: 'dark',
108
+ }, null, 2);
8
109
  const lines = [
9
110
  'set -e',
10
- `export HOME=${shellQuote(opts.guestHome)}`,
11
- 'export CRTR_HOME="$HOME/.crouter"',
12
- 'export PI_CODING_AGENT_DIR="$HOME/.pi/agent"',
13
- 'export PATH="$HOME/.crtr-runtime/bin:/usr/local/bin:/usr/bin:/bin"',
14
- 'export SANDBOX_DISABLE_PROCESS_LOGGING=true',
15
- 'mkdir -p "$HOME/.crouter" "$HOME/.pi/agent" "$HOME/.crtr-runtime/bin"',
111
+ ...Object.entries(env).map(([key, value]) => `export ${key}=${shellQuote(value)}`),
112
+ // Defense-in-depth: CRTR_CANVAS_DB must stay unset on the guest so
113
+ // canvas.db follows CRTR_HOME onto the durable volume (its fcntl/WAL
114
+ // locks need real local-disk semantics) rather than a stray NFS path.
115
+ 'unset CRTR_CANVAS_DB 2>/dev/null || true',
116
+ `mkdir -p "$HOME/.crouter" "$HOME/.pi/agent" ${shellQuote(env['CRTR_SOCK_DIR'] ?? '')} ${shellQuote(dirname(env['CRTR_PIDFILE'] ?? ''))} ${shellQuote(runtimeDir)}`,
16
117
  // The provisioner launches this script as a detached (background) exec, so its stdout is not
17
- // captured. Redirect everything to a log on the durable volume so install/seed/node-new
118
+ // captured. Redirect everything to a log on the durable volume so seed/daemon/node-new
18
119
  // failures are inspectable, and so the first-provision node id can be read from a file (below).
19
120
  'exec >>"$HOME/.crtr-runtime/bootstrap.log" 2>&1',
20
- `if [ ! -x "$HOME/.crtr-runtime/bin/crtr" ] || [ "$(cat ${shellQuote(versionMarker)} 2>/dev/null || true)" != ${shellQuote(opts.crtrVersion)} ]; then`,
21
- ` npm install -g --prefix ${shellQuote(runtimeDir)} @crouton-kit/crouter@${shellQuote(opts.crtrVersion)}`,
22
- ` printf '%s\n' ${shellQuote(opts.crtrVersion)} > ${shellQuote(versionMarker)}`,
23
- 'fi',
24
121
  ];
25
- if (opts.isFirstProvision && (opts.piAuthJson?.trim() ?? '') !== '') {
26
- lines.push('if [ ! -f "$PI_CODING_AGENT_DIR/auth.json" ]; then', ' cat > "$PI_CODING_AGENT_DIR/auth.json" <<\'PI_AUTH_JSON\'', opts.piAuthJson.trim(), 'PI_AUTH_JSON', 'fi');
122
+ appendCommandSurfaceAssertions(lines, opts.crtrVersion);
123
+ if (opts.isFirstProvision) {
124
+ appendJsonSeed(lines, settingsPath, 'PI_SETTINGS_JSON', settingsJson);
125
+ appendJsonSeed(lines, join(opts.guestHome, '.crouter', 'config.json'), 'CRTR_CONFIG_JSON', opts.modelLaddersJson);
126
+ if ((opts.piAuthJson?.trim() ?? '') !== '') {
127
+ appendJsonSeed(lines, join(opts.guestHome, '.pi', 'agent', 'auth.json'), 'PI_AUTH_JSON', opts.piAuthJson);
128
+ }
27
129
  }
28
- lines.push('setsid --fork crtr canvas daemon start </dev/null >>"$HOME/.crtr-runtime/daemon.log" 2>&1');
130
+ appendOauthAdapterCachePrime(lines, opts.guestHome);
131
+ // Tmpfs sock/pidfile dirs are already mkdir'd above, before this line.
132
+ lines.push(`${shellQuote(BAKED_CRTR_PATH)} canvas daemon start </dev/null >>"$HOME/.crtr-runtime/daemon.log" 2>&1`);
29
133
  if (opts.isFirstProvision) {
30
- lines.push('home_node_output="$(', "crtr node new --root --kind general --name home <<'SEED'", 'Hearth home seed for the Blaxel home backend.', 'SEED', ')"', 'home_node_id="$(printf %s\\n "$home_node_output" | grep -Eo \'__HEARTH_NODE_ID__=[^[:space:]]+|node_id[:=][[:space:]]*[^[:space:]]+|node_id[[:space:]]+[A-Za-z0-9-]+\' | tail -n 1 | sed -E \'s/^(__HEARTH_NODE_ID__=|node_id[:=][[:space:]]*|node_id[[:space:]]+)//\')"', 'if [ -z "$home_node_id" ]; then', ' printf "failed to parse home node id from crtr node new output\n%s\n" "$home_node_output" >&2', ' exit 1', 'fi', 'printf "__HEARTH_NODE_ID__=%s\n" "$home_node_id"',
134
+ lines.push('home_node_output="$(', `${shellQuote(BAKED_CRTR_PATH)} --json node new --root --kind general --name home <<'SEED'`, 'Hearth home seed for the Blaxel home backend.', 'SEED', ')"', "home_node_id=\"$(node -e 'const o = JSON.parse(process.argv[1]); process.stdout.write(String(o.node_id ?? o.nodeId ?? o.id ?? \"\"));' \"$home_node_output\")\"", 'if [ -z "$home_node_id" ]; then', ' printf "failed to parse home node id from crtr node new output\n%s\n" "$home_node_output" >&2', ' exit 1', 'fi', 'printf "__HEARTH_NODE_ID__=%s\n" "$home_node_id"',
31
135
  // The provisioner polls this file (background exec stdout is not captured).
32
136
  'printf "%s\n" "$home_node_id" > "$HOME/.crtr-runtime/home-node-id"');
33
137
  }
34
138
  else {
35
- lines.push('if [ -z ' + shellQuote((opts.nodeId ?? '').trim()) + ' ]; then', ' printf "missing nodeId for bootstrap revive\n" >&2', ' exit 1', 'fi', `crtr canvas revive ${shellQuote((opts.nodeId ?? '').trim())}`);
139
+ lines.push(`${shellQuote(BAKED_CRTR_PATH)} canvas revive ${shellQuote(nodeId)}`);
36
140
  }
37
- lines.push(`setsid --fork crtr web serve --host 0.0.0.0 --port ${opts.webPort} --token ${shellQuote(opts.relayToken)} </dev/null >>"$HOME/.crtr-runtime/web.log" 2>&1`);
141
+ // `crtr surface web serve` is asserted present above; never fall back to the
142
+ // retired top-level `crtr web serve` alias. --token is always passed and
143
+ // always non-empty (checked above) so every lane (bridge/SSE/relay) enforces
144
+ // the relay token on this non-loopback bind.
145
+ lines.push(`${shellQuote(BAKED_CRTR_PATH)} surface web serve --host 0.0.0.0 --port ${opts.webPort} --token ${shellQuote(opts.relayToken)} </dev/null >>"$HOME/.crtr-runtime/web.log" 2>&1`);
38
146
  return lines.join('\n');
39
147
  }
@@ -1,11 +1,15 @@
1
- import type { M0Config, MachineRef, TenantId } from '../types.js';
1
+ import type { HomeProviderDescriptor, HomeProviderRefresh, M0Config, MachineRef } from '../types.js';
2
2
  import { BlaxelMachineProvider } from './blaxel.js';
3
+ import type { ExecInput, ExecResult } from './types.js';
3
4
  export declare class BlaxelHomeBackend {
4
5
  private readonly config;
5
6
  private readonly provider;
6
- private readonly crtrVersion;
7
7
  constructor(config: M0Config, provider?: BlaxelMachineProvider);
8
- wake(tenantId: TenantId): Promise<void>;
9
- suspend(tenantId: TenantId): Promise<void>;
8
+ wake(homeInput: HomeProviderDescriptor): Promise<HomeProviderRefresh>;
9
+ suspend(homeInput: HomeProviderDescriptor): Promise<HomeProviderRefresh>;
10
10
  getMachine(machineId: string): Promise<MachineRef | null>;
11
+ /** P2.6 stdin-capable exec seam, passed through verbatim — the `HomeBackend` interface is the
12
+ * only door CP code uses to reach it (see `provider.ts`), so callers never import
13
+ * `BlaxelMachineProvider` directly. */
14
+ exec(machineId: string, input: ExecInput): Promise<ExecResult>;
11
15
  }