@north-light/crouter 0.3.154

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 (1643) hide show
  1. package/README.md +48 -0
  2. package/bin/crouter +4 -0
  3. package/bin/crtr +4 -0
  4. package/bin/crtrd +4 -0
  5. package/bin/runtime-generation-manifest.mjs +263 -0
  6. package/bin/runtime-selector.mjs +378 -0
  7. package/dist/api/__tests__/client.test.d.ts +1 -0
  8. package/dist/api/__tests__/client.test.js +274 -0
  9. package/dist/api/client.d.ts +249 -0
  10. package/dist/api/client.js +616 -0
  11. package/dist/api/dto/attach.d.ts +16 -0
  12. package/dist/api/dto/attach.js +13 -0
  13. package/dist/api/dto/broker.d.ts +45 -0
  14. package/dist/api/dto/broker.js +20 -0
  15. package/dist/api/dto/canvas.d.ts +253 -0
  16. package/dist/api/dto/canvas.js +2 -0
  17. package/dist/api/dto/common.d.ts +27 -0
  18. package/dist/api/dto/common.js +15 -0
  19. package/dist/api/dto/config.d.ts +19 -0
  20. package/dist/api/dto/config.js +3 -0
  21. package/dist/api/dto/crons.d.ts +124 -0
  22. package/dist/api/dto/crons.js +10 -0
  23. package/dist/api/dto/files.d.ts +11 -0
  24. package/dist/api/dto/files.js +7 -0
  25. package/dist/api/dto/focus.d.ts +24 -0
  26. package/dist/api/dto/focus.js +10 -0
  27. package/dist/api/dto/health.d.ts +41 -0
  28. package/dist/api/dto/health.js +2 -0
  29. package/dist/api/dto/human.d.ts +57 -0
  30. package/dist/api/dto/human.js +4 -0
  31. package/dist/api/dto/inbox.d.ts +105 -0
  32. package/dist/api/dto/inbox.js +10 -0
  33. package/dist/api/dto/lifecycle.d.ts +79 -0
  34. package/dist/api/dto/lifecycle.js +3 -0
  35. package/dist/api/dto/messages.d.ts +55 -0
  36. package/dist/api/dto/messages.js +2 -0
  37. package/dist/api/dto/modelauth.d.ts +41 -0
  38. package/dist/api/dto/modelauth.js +3 -0
  39. package/dist/api/dto/nodes.d.ts +209 -0
  40. package/dist/api/dto/nodes.js +3 -0
  41. package/dist/api/dto/profiles.d.ts +14 -0
  42. package/dist/api/dto/profiles.js +3 -0
  43. package/dist/api/dto/reports.d.ts +41 -0
  44. package/dist/api/dto/reports.js +2 -0
  45. package/dist/api/dto/subscriptions.d.ts +14 -0
  46. package/dist/api/dto/subscriptions.js +2 -0
  47. package/dist/api/dto/worktree.d.ts +19 -0
  48. package/dist/api/dto/worktree.js +6 -0
  49. package/dist/api/errors.d.ts +19 -0
  50. package/dist/api/errors.js +30 -0
  51. package/dist/api/index.d.ts +24 -0
  52. package/dist/api/index.js +25 -0
  53. package/dist/api/routes.d.ts +64 -0
  54. package/dist/api/routes.js +92 -0
  55. package/dist/build-root.d.ts +43 -0
  56. package/dist/build-root.js +96 -0
  57. package/dist/builtin-memory/00-runtime-base.md +51 -0
  58. package/dist/builtin-memory/01-spine/00-has-manager.md +23 -0
  59. package/dist/builtin-memory/01-spine/01-no-manager.md +10 -0
  60. package/dist/builtin-memory/02-lifecycle/00-terminal.md +19 -0
  61. package/dist/builtin-memory/02-lifecycle/01-resident.md +10 -0
  62. package/dist/builtin-memory/04-base-worker.md +18 -0
  63. package/dist/builtin-memory/04-orchestration-kernel.md +109 -0
  64. package/dist/builtin-memory/05-kinds/advisor/00-base.md +19 -0
  65. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +26 -0
  66. package/dist/builtin-memory/05-kinds/design/00-base.md +20 -0
  67. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +13 -0
  68. package/dist/builtin-memory/05-kinds/developer/00-base.md +22 -0
  69. package/dist/builtin-memory/05-kinds/developer/01-orchestrator.md +21 -0
  70. package/dist/builtin-memory/05-kinds/explore/00-base.md +20 -0
  71. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +16 -0
  72. package/dist/builtin-memory/05-kinds/general/00-base.md +15 -0
  73. package/dist/builtin-memory/05-kinds/general/01-orchestrator.md +11 -0
  74. package/dist/builtin-memory/05-kinds/plan/00-base.md +20 -0
  75. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +17 -0
  76. package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +17 -0
  77. package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +17 -0
  78. package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +19 -0
  79. package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +17 -0
  80. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +20 -0
  81. package/dist/builtin-memory/05-kinds/product/00-base.md +25 -0
  82. package/dist/builtin-memory/05-kinds/product/01-orchestrator.md +15 -0
  83. package/dist/builtin-memory/05-kinds/product/teardown.md +15 -0
  84. package/dist/builtin-memory/05-kinds/review/00-base.md +19 -0
  85. package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +17 -0
  86. package/dist/builtin-memory/05-kinds/spec/00-base.md +20 -0
  87. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +15 -0
  88. package/dist/builtin-memory/05-kinds/spec/requirements.md +13 -0
  89. package/dist/builtin-memory/design.md +62 -0
  90. package/dist/builtin-memory/development.md +120 -0
  91. package/dist/builtin-memory/internal/INDEX.md +26 -0
  92. package/dist/builtin-memory/internal/agent-shaping.md +77 -0
  93. package/dist/builtin-memory/internal/examples/INDEX.md +15 -0
  94. package/dist/builtin-memory/internal/examples/imessage-assistant.md +100 -0
  95. package/dist/builtin-memory/internal/marketplaces.md +164 -0
  96. package/dist/builtin-memory/internal/nodes-and-canvas.md +51 -0
  97. package/dist/builtin-memory/internal/plugins.md +249 -0
  98. package/dist/builtin-memory/internal/storage-tiers.md +41 -0
  99. package/dist/builtin-memory/planning.md +43 -0
  100. package/dist/builtin-memory/product.md +80 -0
  101. package/dist/builtin-memory/spec.md +98 -0
  102. package/dist/builtin-memory/wedged-child-on-runaway-bash.md +34 -0
  103. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +47 -0
  104. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/claude-plugin-commands.test.ts +49 -0
  105. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +93 -0
  106. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/memory-slash-commands.test.ts +194 -0
  107. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +2632 -0
  108. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/statusline.test.ts +68 -0
  109. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +492 -0
  110. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crouter-help.ts +95 -0
  111. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/filters.json +7 -0
  112. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/index.ts +191 -0
  113. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +448 -0
  114. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/test.ts +119 -0
  115. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +195 -0
  116. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +1232 -0
  117. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +255 -0
  118. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/strip-skills-docs.ts +47 -0
  119. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/sysprompt-window.ts +19 -0
  120. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/package.json +3 -0
  121. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.js +1 -0
  122. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.ts +2 -0
  123. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/LICENSE +13 -0
  124. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/README.md +172 -0
  125. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/bin.mjs +11 -0
  126. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
  127. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
  128. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
  129. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
  130. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/composer.js +219 -0
  131. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
  132. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
  133. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
  134. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
  135. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
  136. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +225 -0
  137. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
  138. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
  139. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
  140. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
  141. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
  142. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/Document.js +335 -0
  143. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
  144. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
  145. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
  146. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/doc/directives.js +176 -0
  147. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/errors.js +57 -0
  148. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/index.js +17 -0
  149. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/log.js +11 -0
  150. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Alias.js +116 -0
  151. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
  152. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
  153. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
  154. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
  155. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
  156. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
  157. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
  158. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
  159. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
  160. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
  161. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
  162. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
  163. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/cst.js +98 -0
  164. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
  165. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
  166. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/parse/parser.js +975 -0
  167. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/public-api.js +102 -0
  168. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
  169. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
  170. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
  171. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
  172. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
  173. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
  174. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
  175. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
  176. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
  177. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
  178. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/tags.js +96 -0
  179. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
  180. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
  181. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
  182. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
  183. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
  184. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
  185. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
  186. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
  187. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
  188. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
  189. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
  190. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
  191. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
  192. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
  193. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
  194. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
  195. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
  196. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
  197. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/util.js +11 -0
  198. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/dist/visit.js +233 -0
  199. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/index.js +5 -0
  200. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/browser/package.json +3 -0
  201. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/cli.d.ts +8 -0
  202. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/cli.mjs +201 -0
  203. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
  204. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-collection.js +90 -0
  205. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
  206. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-doc.js +45 -0
  207. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
  208. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-node.js +112 -0
  209. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
  210. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
  211. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/composer.d.ts +63 -0
  212. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/composer.js +224 -0
  213. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  214. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
  215. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  216. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
  217. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  218. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
  219. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
  220. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-end.js +39 -0
  221. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  222. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
  223. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  224. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-flow-scalar.js +227 -0
  225. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
  226. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/resolve-props.js +148 -0
  227. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  228. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
  229. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  230. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
  231. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  232. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
  233. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
  234. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
  235. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/Document.d.ts +141 -0
  236. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/Document.js +337 -0
  237. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
  238. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/anchors.js +76 -0
  239. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
  240. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/applyReviver.js +57 -0
  241. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
  242. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/createNode.js +90 -0
  243. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/directives.d.ts +49 -0
  244. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/doc/directives.js +178 -0
  245. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/errors.d.ts +21 -0
  246. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/errors.js +62 -0
  247. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/index.d.ts +25 -0
  248. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/index.js +50 -0
  249. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/log.d.ts +3 -0
  250. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/log.js +19 -0
  251. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
  252. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Alias.js +118 -0
  253. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
  254. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Collection.js +151 -0
  255. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
  256. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Node.js +40 -0
  257. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
  258. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Pair.js +39 -0
  259. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
  260. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/Scalar.js +27 -0
  261. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  262. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
  263. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  264. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
  265. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  266. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
  267. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
  268. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/identity.js +53 -0
  269. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
  270. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/nodes/toJS.js +39 -0
  271. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/options.d.ts +350 -0
  272. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
  273. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
  274. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
  275. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
  276. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
  277. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst-visit.js +99 -0
  278. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst.d.ts +109 -0
  279. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/cst.js +112 -0
  280. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
  281. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/lexer.js +723 -0
  282. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
  283. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/line-counter.js +41 -0
  284. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/parser.d.ts +84 -0
  285. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/parse/parser.js +980 -0
  286. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/public-api.d.ts +44 -0
  287. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/public-api.js +107 -0
  288. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
  289. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/Schema.js +39 -0
  290. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
  291. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/map.js +19 -0
  292. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
  293. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/null.js +17 -0
  294. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
  295. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/seq.js +19 -0
  296. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
  297. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/common/string.js +16 -0
  298. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
  299. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/bool.js +21 -0
  300. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
  301. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/float.js +47 -0
  302. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
  303. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/int.js +42 -0
  304. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
  305. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/core/schema.js +25 -0
  306. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
  307. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/json/schema.js +64 -0
  308. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
  309. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/tags.d.ts +48 -0
  310. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/tags.js +99 -0
  311. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/types.d.ts +92 -0
  312. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  313. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
  314. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  315. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  316. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  317. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
  318. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  319. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
  320. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
  321. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
  322. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
  323. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  324. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  325. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  326. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  327. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
  328. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  329. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
  330. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  331. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  332. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  333. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
  334. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
  335. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringify.js +132 -0
  336. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  337. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
  338. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  339. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
  340. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  341. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
  342. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  343. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
  344. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  345. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
  346. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
  347. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
  348. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/test-events.d.ts +4 -0
  349. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/test-events.js +134 -0
  350. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/util.d.ts +16 -0
  351. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/util.js +28 -0
  352. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/visit.d.ts +102 -0
  353. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/dist/visit.js +236 -0
  354. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/package.json +97 -0
  355. package/dist/builtin-pi-packages/pi-crtr-extensions/node_modules/yaml/util.js +2 -0
  356. package/dist/builtin-pi-packages/pi-crtr-extensions/package-lock.json +3385 -0
  357. package/dist/builtin-pi-packages/pi-crtr-extensions/package.json +25 -0
  358. package/dist/builtin-pi-packages/pi-crtr-extensions/tsconfig.json +10 -0
  359. package/dist/builtin-pi-packages/pi-mode-switch/README.md +36 -0
  360. package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +36 -0
  361. package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +449 -0
  362. package/dist/builtin-pi-packages/pi-mode-switch/package.json +14 -0
  363. package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +9 -0
  364. package/dist/builtin-views/_lib/states.mjs +161 -0
  365. package/dist/builtin-views/canvas/core.mjs +657 -0
  366. package/dist/builtin-views/canvas/text.mjs +58 -0
  367. package/dist/builtin-views/canvas/tui.mjs +168 -0
  368. package/dist/builtin-views/canvas/web.jsx +121 -0
  369. package/dist/builtin-views/chat/core.mjs +684 -0
  370. package/dist/builtin-views/chat/text.mjs +101 -0
  371. package/dist/builtin-views/chat/tui.mjs +360 -0
  372. package/dist/builtin-views/chat/web.jsx +362 -0
  373. package/dist/builtin-views/git-pr/core.mjs +673 -0
  374. package/dist/builtin-views/git-pr/text.mjs +84 -0
  375. package/dist/builtin-views/git-pr/tui.mjs +301 -0
  376. package/dist/builtin-views/git-pr/web.jsx +216 -0
  377. package/dist/builtin-views/inbox/_lib/render.mjs +175 -0
  378. package/dist/builtin-views/inbox/core.mjs +1273 -0
  379. package/dist/builtin-views/inbox/text.mjs +73 -0
  380. package/dist/builtin-views/inbox/tui.mjs +314 -0
  381. package/dist/builtin-views/inbox/web.jsx +188 -0
  382. package/dist/builtin-views/linkedin/core.mjs +906 -0
  383. package/dist/builtin-views/linkedin/text.mjs +69 -0
  384. package/dist/builtin-views/linkedin/tui.mjs +413 -0
  385. package/dist/builtin-views/linkedin/web.jsx +206 -0
  386. package/dist/builtin-views/prompt-review/core.mjs +735 -0
  387. package/dist/builtin-views/prompt-review/text.mjs +15 -0
  388. package/dist/builtin-views/prompt-review/tui.mjs +196 -0
  389. package/dist/builtin-views/prompt-review/web.jsx +484 -0
  390. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.d.ts +1 -0
  391. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +50 -0
  392. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +53 -0
  393. package/dist/builtin-views/workspace-sidebar/core.mjs +670 -0
  394. package/dist/builtin-views/workspace-sidebar/text.mjs +53 -0
  395. package/dist/builtin-views/workspace-sidebar/tui.mjs +141 -0
  396. package/dist/builtin-views/workspace-sidebar/web.jsx +109 -0
  397. package/dist/cli.d.ts +2 -0
  398. package/dist/cli.js +86 -0
  399. package/dist/clients/attach/__tests__/attach-chrome-remote.test.d.ts +1 -0
  400. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +467 -0
  401. package/dist/clients/attach/__tests__/attach-keybindings.test.d.ts +1 -0
  402. package/dist/clients/attach/__tests__/attach-keybindings.test.js +141 -0
  403. package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +1 -0
  404. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +191 -0
  405. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +1 -0
  406. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +236 -0
  407. package/dist/clients/attach/__tests__/context-message.test.d.ts +1 -0
  408. package/dist/clients/attach/__tests__/context-message.test.js +46 -0
  409. package/dist/clients/attach/__tests__/crtr-output-coverage.test.d.ts +1 -0
  410. package/dist/clients/attach/__tests__/crtr-output-coverage.test.js +55 -0
  411. package/dist/clients/attach/__tests__/crtr-output.test.d.ts +1 -0
  412. package/dist/clients/attach/__tests__/crtr-output.test.js +2103 -0
  413. package/dist/clients/attach/__tests__/diagram.test.d.ts +1 -0
  414. package/dist/clients/attach/__tests__/diagram.test.js +42 -0
  415. package/dist/clients/attach/__tests__/markdown-headings.test.d.ts +1 -0
  416. package/dist/clients/attach/__tests__/markdown-headings.test.js +27 -0
  417. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +1 -0
  418. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +133 -0
  419. package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +1 -0
  420. package/dist/clients/attach/__tests__/prompt-preview.test.js +87 -0
  421. package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +1 -0
  422. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +176 -0
  423. package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +1 -0
  424. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +271 -0
  425. package/dist/clients/attach/__tests__/visible-paths.test.d.ts +1 -0
  426. package/dist/clients/attach/__tests__/visible-paths.test.js +19 -0
  427. package/dist/clients/attach/chrome/bash-jobs.d.ts +9 -0
  428. package/dist/clients/attach/chrome/bash-jobs.js +43 -0
  429. package/dist/clients/attach/chrome/canvas-panels.d.ts +36 -0
  430. package/dist/clients/attach/chrome/canvas-panels.js +172 -0
  431. package/dist/clients/attach/chrome/completion-bell.d.ts +10 -0
  432. package/dist/clients/attach/chrome/completion-bell.js +89 -0
  433. package/dist/clients/attach/chrome/cron-wait.d.ts +3 -0
  434. package/dist/clients/attach/chrome/cron-wait.js +34 -0
  435. package/dist/clients/attach/chrome/git-info.d.ts +20 -0
  436. package/dist/clients/attach/chrome/git-info.js +44 -0
  437. package/dist/clients/attach/chrome/roster.d.ts +26 -0
  438. package/dist/clients/attach/chrome/roster.js +233 -0
  439. package/dist/clients/attach/chrome/status-line.d.ts +35 -0
  440. package/dist/clients/attach/chrome/status-line.js +133 -0
  441. package/dist/clients/attach/chrome/widgets.d.ts +9 -0
  442. package/dist/clients/attach/chrome/widgets.js +61 -0
  443. package/dist/clients/attach/command.d.ts +2 -0
  444. package/dist/clients/attach/command.js +96 -0
  445. package/dist/clients/attach/config.d.ts +91 -0
  446. package/dist/clients/attach/config.js +271 -0
  447. package/dist/clients/attach/input/clipboard-image.d.ts +55 -0
  448. package/dist/clients/attach/input/clipboard-image.js +237 -0
  449. package/dist/clients/attach/input/controller.d.ts +210 -0
  450. package/dist/clients/attach/input/controller.js +689 -0
  451. package/dist/clients/attach/input/ref-autocomplete.d.ts +75 -0
  452. package/dist/clients/attach/input/ref-autocomplete.js +135 -0
  453. package/dist/clients/attach/input/titled-editor.d.ts +209 -0
  454. package/dist/clients/attach/input/titled-editor.js +801 -0
  455. package/dist/clients/attach/overlays/auth.d.ts +13 -0
  456. package/dist/clients/attach/overlays/auth.js +245 -0
  457. package/dist/clients/attach/overlays/dialogs.d.ts +27 -0
  458. package/dist/clients/attach/overlays/dialogs.js +102 -0
  459. package/dist/clients/attach/overlays/file-review.d.ts +9 -0
  460. package/dist/clients/attach/overlays/file-review.js +181 -0
  461. package/dist/clients/attach/overlays/graph.d.ts +76 -0
  462. package/dist/clients/attach/overlays/graph.js +657 -0
  463. package/dist/clients/attach/overlays/mcp.d.ts +32 -0
  464. package/dist/clients/attach/overlays/mcp.js +310 -0
  465. package/dist/clients/attach/overlays/pickers.d.ts +59 -0
  466. package/dist/clients/attach/overlays/pickers.js +170 -0
  467. package/dist/clients/attach/render/chat-view.d.ts +185 -0
  468. package/dist/clients/attach/render/chat-view.js +946 -0
  469. package/dist/clients/attach/render/context-message.d.ts +14 -0
  470. package/dist/clients/attach/render/context-message.js +81 -0
  471. package/dist/clients/attach/render/crtr-output.d.ts +48 -0
  472. package/dist/clients/attach/render/crtr-output.js +694 -0
  473. package/dist/clients/attach/render/diagram.d.ts +14 -0
  474. package/dist/clients/attach/render/diagram.js +135 -0
  475. package/dist/clients/attach/render/edit-diff.d.ts +6 -0
  476. package/dist/clients/attach/render/edit-diff.js +263 -0
  477. package/dist/clients/attach/render/frozen-history.d.ts +38 -0
  478. package/dist/clients/attach/render/frozen-history.js +100 -0
  479. package/dist/clients/attach/render/markdown-headings.d.ts +11 -0
  480. package/dist/clients/attach/render/markdown-headings.js +82 -0
  481. package/dist/clients/attach/session/banner.d.ts +9 -0
  482. package/dist/clients/attach/session/banner.js +29 -0
  483. package/dist/clients/attach/session/bindings.d.ts +12 -0
  484. package/dist/clients/attach/session/bindings.js +52 -0
  485. package/dist/clients/attach/session/chrome-refresh.d.ts +34 -0
  486. package/dist/clients/attach/session/chrome-refresh.js +93 -0
  487. package/dist/clients/attach/session/connection.d.ts +44 -0
  488. package/dist/clients/attach/session/connection.js +178 -0
  489. package/dist/clients/attach/session/context.d.ts +54 -0
  490. package/dist/clients/attach/session/context.js +16 -0
  491. package/dist/clients/attach/session/editor-frame.d.ts +43 -0
  492. package/dist/clients/attach/session/editor-frame.js +136 -0
  493. package/dist/clients/attach/session/editor-inventory.d.ts +59 -0
  494. package/dist/clients/attach/session/editor-inventory.js +161 -0
  495. package/dist/clients/attach/session/focus-events.d.ts +4 -0
  496. package/dist/clients/attach/session/focus-events.js +12 -0
  497. package/dist/clients/attach/session/frames.d.ts +43 -0
  498. package/dist/clients/attach/session/frames.js +170 -0
  499. package/dist/clients/attach/session/identity.d.ts +16 -0
  500. package/dist/clients/attach/session/identity.js +25 -0
  501. package/dist/clients/attach/session/input-wiring.d.ts +31 -0
  502. package/dist/clients/attach/session/input-wiring.js +128 -0
  503. package/dist/clients/attach/session/keys.d.ts +22 -0
  504. package/dist/clients/attach/session/keys.js +60 -0
  505. package/dist/clients/attach/session/layout.d.ts +20 -0
  506. package/dist/clients/attach/session/layout.js +56 -0
  507. package/dist/clients/attach/session/mode.d.ts +25 -0
  508. package/dist/clients/attach/session/mode.js +97 -0
  509. package/dist/clients/attach/session/pane-tag.d.ts +15 -0
  510. package/dist/clients/attach/session/pane-tag.js +43 -0
  511. package/dist/clients/attach/session/pi-assets.d.ts +1 -0
  512. package/dist/clients/attach/session/pi-assets.js +24 -0
  513. package/dist/clients/attach/session/pi-oauth-flows.d.ts +1 -0
  514. package/dist/clients/attach/session/pi-oauth-flows.js +21 -0
  515. package/dist/clients/attach/session/reconnect.d.ts +37 -0
  516. package/dist/clients/attach/session/reconnect.js +127 -0
  517. package/dist/clients/attach/session/state-sync.d.ts +38 -0
  518. package/dist/clients/attach/session/state-sync.js +68 -0
  519. package/dist/clients/attach/session/teardown.d.ts +30 -0
  520. package/dist/clients/attach/session/teardown.js +96 -0
  521. package/dist/clients/attach/slash/dispatch.d.ts +124 -0
  522. package/dist/clients/attach/slash/dispatch.js +696 -0
  523. package/dist/clients/attach/slash/prompt-preview.d.ts +30 -0
  524. package/dist/clients/attach/slash/prompt-preview.js +121 -0
  525. package/dist/clients/attach/viewer.d.ts +8 -0
  526. package/dist/clients/attach/viewer.js +1559 -0
  527. package/dist/clients/attach/visible-paths.d.ts +9 -0
  528. package/dist/clients/attach/visible-paths.js +76 -0
  529. package/dist/clients/web/__tests__/push-engine.test.d.ts +1 -0
  530. package/dist/clients/web/__tests__/push-engine.test.js +302 -0
  531. package/dist/clients/web/__tests__/push-registry.test.d.ts +1 -0
  532. package/dist/clients/web/__tests__/push-registry.test.js +177 -0
  533. package/dist/clients/web/dev-server.d.ts +7 -0
  534. package/dist/clients/web/dev-server.js +60 -0
  535. package/dist/clients/web/events.d.ts +19 -0
  536. package/dist/clients/web/events.js +165 -0
  537. package/dist/clients/web/push-engine.d.ts +108 -0
  538. package/dist/clients/web/push-engine.js +256 -0
  539. package/dist/clients/web/push-registry.d.ts +89 -0
  540. package/dist/clients/web/push-registry.js +378 -0
  541. package/dist/clients/web/server.d.ts +19 -0
  542. package/dist/clients/web/server.js +693 -0
  543. package/dist/clients/web/web-client/shared/protocol.d.ts +322 -0
  544. package/dist/clients/web/web-client/shared/protocol.js +8 -0
  545. package/dist/clients/web/web-cmd.d.ts +2 -0
  546. package/dist/clients/web/web-cmd.js +141 -0
  547. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +1 -0
  548. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +96 -0
  549. package/dist/commands/__tests__/canvas-config.test.d.ts +1 -0
  550. package/dist/commands/__tests__/canvas-config.test.js +107 -0
  551. package/dist/commands/__tests__/human.test.d.ts +1 -0
  552. package/dist/commands/__tests__/human.test.js +344 -0
  553. package/dist/commands/__tests__/node-no-kickoff-flag.test.d.ts +1 -0
  554. package/dist/commands/__tests__/node-no-kickoff-flag.test.js +73 -0
  555. package/dist/commands/__tests__/node-worktree-flag.test.d.ts +1 -0
  556. package/dist/commands/__tests__/node-worktree-flag.test.js +49 -0
  557. package/dist/commands/__tests__/revive-now-gate.test.d.ts +1 -0
  558. package/dist/commands/__tests__/revive-now-gate.test.js +60 -0
  559. package/dist/commands/api-client.d.ts +100 -0
  560. package/dist/commands/api-client.js +377 -0
  561. package/dist/commands/attention.d.ts +2 -0
  562. package/dist/commands/attention.js +223 -0
  563. package/dist/commands/canvas-browse.d.ts +2 -0
  564. package/dist/commands/canvas-browse.js +95 -0
  565. package/dist/commands/canvas-config.d.ts +2 -0
  566. package/dist/commands/canvas-config.js +210 -0
  567. package/dist/commands/canvas-history/grep.d.ts +1 -0
  568. package/dist/commands/canvas-history/grep.js +104 -0
  569. package/dist/commands/canvas-history/read.d.ts +1 -0
  570. package/dist/commands/canvas-history/read.js +48 -0
  571. package/dist/commands/canvas-history/search.d.ts +1 -0
  572. package/dist/commands/canvas-history/search.js +118 -0
  573. package/dist/commands/canvas-history/shared.d.ts +27 -0
  574. package/dist/commands/canvas-history/shared.js +76 -0
  575. package/dist/commands/canvas-history.d.ts +2 -0
  576. package/dist/commands/canvas-history.js +30 -0
  577. package/dist/commands/canvas-issue.d.ts +2 -0
  578. package/dist/commands/canvas-issue.js +149 -0
  579. package/dist/commands/canvas-prune.d.ts +2 -0
  580. package/dist/commands/canvas-prune.js +108 -0
  581. package/dist/commands/canvas-rebuild-index.d.ts +2 -0
  582. package/dist/commands/canvas-rebuild-index.js +46 -0
  583. package/dist/commands/canvas-roster.d.ts +2 -0
  584. package/dist/commands/canvas-roster.js +62 -0
  585. package/dist/commands/canvas-snapshot.d.ts +2 -0
  586. package/dist/commands/canvas-snapshot.js +34 -0
  587. package/dist/commands/canvas-use.d.ts +1 -0
  588. package/dist/commands/canvas-use.js +63 -0
  589. package/dist/commands/canvas.d.ts +3 -0
  590. package/dist/commands/canvas.js +50 -0
  591. package/dist/commands/chord.d.ts +2 -0
  592. package/dist/commands/chord.js +242 -0
  593. package/dist/commands/cron.d.ts +2 -0
  594. package/dist/commands/cron.js +524 -0
  595. package/dist/commands/dashboard.d.ts +2 -0
  596. package/dist/commands/dashboard.js +80 -0
  597. package/dist/commands/human/prompts.d.ts +8 -0
  598. package/dist/commands/human/prompts.js +427 -0
  599. package/dist/commands/human/queue.d.ts +12 -0
  600. package/dist/commands/human/queue.js +531 -0
  601. package/dist/commands/human/shared.d.ts +80 -0
  602. package/dist/commands/human/shared.js +194 -0
  603. package/dist/commands/human.d.ts +2 -0
  604. package/dist/commands/human.js +44 -0
  605. package/dist/commands/memory/delete.d.ts +1 -0
  606. package/dist/commands/memory/delete.js +77 -0
  607. package/dist/commands/memory/find.d.ts +1 -0
  608. package/dist/commands/memory/find.js +192 -0
  609. package/dist/commands/memory/lint.d.ts +9 -0
  610. package/dist/commands/memory/lint.js +217 -0
  611. package/dist/commands/memory/list.d.ts +1 -0
  612. package/dist/commands/memory/list.js +84 -0
  613. package/dist/commands/memory/origin.d.ts +1 -0
  614. package/dist/commands/memory/origin.js +100 -0
  615. package/dist/commands/memory/read.d.ts +1 -0
  616. package/dist/commands/memory/read.js +72 -0
  617. package/dist/commands/memory/shared.d.ts +54 -0
  618. package/dist/commands/memory/shared.js +225 -0
  619. package/dist/commands/memory/write.d.ts +1 -0
  620. package/dist/commands/memory/write.js +142 -0
  621. package/dist/commands/memory.d.ts +2 -0
  622. package/dist/commands/memory.js +26 -0
  623. package/dist/commands/node-context.d.ts +2 -0
  624. package/dist/commands/node-context.js +157 -0
  625. package/dist/commands/node-inspect-artifacts.d.ts +1 -0
  626. package/dist/commands/node-inspect-artifacts.js +109 -0
  627. package/dist/commands/node-lifecycle-revive.d.ts +12 -0
  628. package/dist/commands/node-lifecycle-revive.js +287 -0
  629. package/dist/commands/node-snapshot.d.ts +2 -0
  630. package/dist/commands/node-snapshot.js +37 -0
  631. package/dist/commands/node-transcript.d.ts +2 -0
  632. package/dist/commands/node-transcript.js +62 -0
  633. package/dist/commands/node-worktree.d.ts +2 -0
  634. package/dist/commands/node-worktree.js +102 -0
  635. package/dist/commands/node.d.ts +44 -0
  636. package/dist/commands/node.js +1943 -0
  637. package/dist/commands/pkg/cli-inspect.d.ts +17 -0
  638. package/dist/commands/pkg/cli-inspect.js +190 -0
  639. package/dist/commands/pkg/cli-manage.d.ts +3 -0
  640. package/dist/commands/pkg/cli-manage.js +206 -0
  641. package/dist/commands/pkg/cli.d.ts +1 -0
  642. package/dist/commands/pkg/cli.js +14 -0
  643. package/dist/commands/pkg/market-inspect.d.ts +2 -0
  644. package/dist/commands/pkg/market-inspect.js +141 -0
  645. package/dist/commands/pkg/market-manage.d.ts +3 -0
  646. package/dist/commands/pkg/market-manage.js +224 -0
  647. package/dist/commands/pkg/market.d.ts +1 -0
  648. package/dist/commands/pkg/market.js +14 -0
  649. package/dist/commands/pkg/plugin-inspect.d.ts +2 -0
  650. package/dist/commands/pkg/plugin-inspect.js +150 -0
  651. package/dist/commands/pkg/plugin-manage.d.ts +19 -0
  652. package/dist/commands/pkg/plugin-manage.js +398 -0
  653. package/dist/commands/pkg/plugin.d.ts +1 -0
  654. package/dist/commands/pkg/plugin.js +14 -0
  655. package/dist/commands/pkg/shared.d.ts +5 -0
  656. package/dist/commands/pkg/shared.js +61 -0
  657. package/dist/commands/pkg.d.ts +2 -0
  658. package/dist/commands/pkg.js +24 -0
  659. package/dist/commands/profile/default.d.ts +2 -0
  660. package/dist/commands/profile/default.js +143 -0
  661. package/dist/commands/profile/delete.d.ts +1 -0
  662. package/dist/commands/profile/delete.js +39 -0
  663. package/dist/commands/profile/env.d.ts +2 -0
  664. package/dist/commands/profile/env.js +194 -0
  665. package/dist/commands/profile/list.d.ts +1 -0
  666. package/dist/commands/profile/list.js +35 -0
  667. package/dist/commands/profile/new.d.ts +1 -0
  668. package/dist/commands/profile/new.js +75 -0
  669. package/dist/commands/profile/project.d.ts +2 -0
  670. package/dist/commands/profile/project.js +97 -0
  671. package/dist/commands/profile/rename.d.ts +1 -0
  672. package/dist/commands/profile/rename.js +42 -0
  673. package/dist/commands/profile/show.d.ts +1 -0
  674. package/dist/commands/profile/show.js +50 -0
  675. package/dist/commands/profile.d.ts +2 -0
  676. package/dist/commands/profile.js +37 -0
  677. package/dist/commands/push.d.ts +2 -0
  678. package/dist/commands/push.js +166 -0
  679. package/dist/commands/revive.d.ts +2 -0
  680. package/dist/commands/revive.js +174 -0
  681. package/dist/commands/search/answer.d.ts +1 -0
  682. package/dist/commands/search/answer.js +50 -0
  683. package/dist/commands/search/contents.d.ts +1 -0
  684. package/dist/commands/search/contents.js +96 -0
  685. package/dist/commands/search/exa.d.ts +53 -0
  686. package/dist/commands/search/exa.js +157 -0
  687. package/dist/commands/search/puremd.d.ts +11 -0
  688. package/dist/commands/search/puremd.js +53 -0
  689. package/dist/commands/search/web.d.ts +1 -0
  690. package/dist/commands/search/web.js +65 -0
  691. package/dist/commands/search.d.ts +2 -0
  692. package/dist/commands/search.js +24 -0
  693. package/dist/commands/surface-edit.d.ts +2 -0
  694. package/dist/commands/surface-edit.js +159 -0
  695. package/dist/commands/surface-inspect.d.ts +2 -0
  696. package/dist/commands/surface-inspect.js +38 -0
  697. package/dist/commands/surface-node.d.ts +2 -0
  698. package/dist/commands/surface-node.js +16 -0
  699. package/dist/commands/surface-reload.d.ts +2 -0
  700. package/dist/commands/surface-reload.js +127 -0
  701. package/dist/commands/surface-tmux-spread.d.ts +2 -0
  702. package/dist/commands/surface-tmux-spread.js +220 -0
  703. package/dist/commands/surface.d.ts +2 -0
  704. package/dist/commands/surface.js +48 -0
  705. package/dist/commands/sys/__tests__/config-broker-thresholds.test.d.ts +1 -0
  706. package/dist/commands/sys/__tests__/config-broker-thresholds.test.js +95 -0
  707. package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +1 -0
  708. package/dist/commands/sys/__tests__/config-keybindings.test.js +55 -0
  709. package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +1 -0
  710. package/dist/commands/sys/__tests__/config-model-ladders.test.js +121 -0
  711. package/dist/commands/sys/__tests__/helpers/setup-runtime.d.ts +5 -0
  712. package/dist/commands/sys/__tests__/helpers/setup-runtime.js +19 -0
  713. package/dist/commands/sys/__tests__/setup-core.test.d.ts +1 -0
  714. package/dist/commands/sys/__tests__/setup-core.test.js +291 -0
  715. package/dist/commands/sys/__tests__/setup-front-door.test.d.ts +1 -0
  716. package/dist/commands/sys/__tests__/setup-front-door.test.js +137 -0
  717. package/dist/commands/sys/__tests__/setup-models.test.d.ts +1 -0
  718. package/dist/commands/sys/__tests__/setup-models.test.js +205 -0
  719. package/dist/commands/sys/__tests__/setup-providers-viewport.test.d.ts +1 -0
  720. package/dist/commands/sys/__tests__/setup-providers-viewport.test.js +155 -0
  721. package/dist/commands/sys/__tests__/sync-deps.test.d.ts +1 -0
  722. package/dist/commands/sys/__tests__/sync-deps.test.js +188 -0
  723. package/dist/commands/sys/__tests__/sync-import.test.d.ts +1 -0
  724. package/dist/commands/sys/__tests__/sync-import.test.js +314 -0
  725. package/dist/commands/sys/config.d.ts +1 -0
  726. package/dist/commands/sys/config.js +292 -0
  727. package/dist/commands/sys/daemon.d.ts +2 -0
  728. package/dist/commands/sys/daemon.js +188 -0
  729. package/dist/commands/sys/doctor.d.ts +1 -0
  730. package/dist/commands/sys/doctor.js +528 -0
  731. package/dist/commands/sys/feedback.d.ts +1 -0
  732. package/dist/commands/sys/feedback.js +174 -0
  733. package/dist/commands/sys/logs.d.ts +1 -0
  734. package/dist/commands/sys/logs.js +127 -0
  735. package/dist/commands/sys/prompt-review.d.ts +1 -0
  736. package/dist/commands/sys/prompt-review.js +291 -0
  737. package/dist/commands/sys/promptstudio.d.ts +2 -0
  738. package/dist/commands/sys/promptstudio.js +65 -0
  739. package/dist/commands/sys/setup-core.d.ts +138 -0
  740. package/dist/commands/sys/setup-core.js +582 -0
  741. package/dist/commands/sys/setup-wizard.d.ts +130 -0
  742. package/dist/commands/sys/setup-wizard.js +2310 -0
  743. package/dist/commands/sys/setup.d.ts +6 -0
  744. package/dist/commands/sys/setup.js +36 -0
  745. package/dist/commands/sys/shared.d.ts +51 -0
  746. package/dist/commands/sys/shared.js +81 -0
  747. package/dist/commands/sys/support/prepare.d.ts +13 -0
  748. package/dist/commands/sys/support/prepare.js +235 -0
  749. package/dist/commands/sys/support/submit.d.ts +19 -0
  750. package/dist/commands/sys/support/submit.js +525 -0
  751. package/dist/commands/sys/support.d.ts +2 -0
  752. package/dist/commands/sys/support.js +18 -0
  753. package/dist/commands/sys/sync-deps.d.ts +19 -0
  754. package/dist/commands/sys/sync-deps.js +508 -0
  755. package/dist/commands/sys/sync-project-guidance.d.ts +1 -0
  756. package/dist/commands/sys/sync-project-guidance.js +345 -0
  757. package/dist/commands/sys/sync-shared.d.ts +7 -0
  758. package/dist/commands/sys/sync-shared.js +49 -0
  759. package/dist/commands/sys/sync-skills.d.ts +1 -0
  760. package/dist/commands/sys/sync-skills.js +306 -0
  761. package/dist/commands/sys/sync.d.ts +2 -0
  762. package/dist/commands/sys/sync.js +18 -0
  763. package/dist/commands/sys/sysprompt.d.ts +1 -0
  764. package/dist/commands/sys/sysprompt.js +97 -0
  765. package/dist/commands/sys/update.d.ts +2 -0
  766. package/dist/commands/sys/update.js +139 -0
  767. package/dist/commands/sys.d.ts +2 -0
  768. package/dist/commands/sys.js +30 -0
  769. package/dist/commands/view-cycle.d.ts +2 -0
  770. package/dist/commands/view-cycle.js +130 -0
  771. package/dist/commands/view-list.d.ts +2 -0
  772. package/dist/commands/view-list.js +66 -0
  773. package/dist/commands/view-new.d.ts +2 -0
  774. package/dist/commands/view-new.js +74 -0
  775. package/dist/commands/view-pick.d.ts +6 -0
  776. package/dist/commands/view-pick.js +129 -0
  777. package/dist/commands/view-run.d.ts +2 -0
  778. package/dist/commands/view-run.js +214 -0
  779. package/dist/commands/view.d.ts +2 -0
  780. package/dist/commands/view.js +31 -0
  781. package/dist/commands/workspace.d.ts +2 -0
  782. package/dist/commands/workspace.js +165 -0
  783. package/dist/core/__tests__/base-worker-prompt.test.d.ts +1 -0
  784. package/dist/core/__tests__/base-worker-prompt.test.js +60 -0
  785. package/dist/core/__tests__/boot-fault-attempt.test.d.ts +1 -0
  786. package/dist/core/__tests__/boot-fault-attempt.test.js +83 -0
  787. package/dist/core/__tests__/boot.test.d.ts +1 -0
  788. package/dist/core/__tests__/boot.test.js +275 -0
  789. package/dist/core/__tests__/branded-host-concurrency.test.d.ts +1 -0
  790. package/dist/core/__tests__/branded-host-concurrency.test.js +72 -0
  791. package/dist/core/__tests__/broker-fork-seam.test.d.ts +1 -0
  792. package/dist/core/__tests__/broker-fork-seam.test.js +118 -0
  793. package/dist/core/__tests__/broker-launch-candidates.test.d.ts +1 -0
  794. package/dist/core/__tests__/broker-launch-candidates.test.js +241 -0
  795. package/dist/core/__tests__/broker-preflight.test.d.ts +1 -0
  796. package/dist/core/__tests__/broker-preflight.test.js +95 -0
  797. package/dist/core/__tests__/broker-sdk-wiring.test.d.ts +1 -0
  798. package/dist/core/__tests__/broker-sdk-wiring.test.js +732 -0
  799. package/dist/core/__tests__/broker-snapshot-history.test.d.ts +1 -0
  800. package/dist/core/__tests__/broker-snapshot-history.test.js +213 -0
  801. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +1 -0
  802. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +502 -0
  803. package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +1 -0
  804. package/dist/core/__tests__/canvas-inbox-watcher.test.js +255 -0
  805. package/dist/core/__tests__/canvas.test.d.ts +1 -0
  806. package/dist/core/__tests__/canvas.test.js +201 -0
  807. package/dist/core/__tests__/chat-view-reconnect.test.d.ts +1 -0
  808. package/dist/core/__tests__/chat-view-reconnect.test.js +105 -0
  809. package/dist/core/__tests__/child-death-wake.test.d.ts +1 -0
  810. package/dist/core/__tests__/child-death-wake.test.js +161 -0
  811. package/dist/core/__tests__/close.test.d.ts +1 -0
  812. package/dist/core/__tests__/close.test.js +254 -0
  813. package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +1 -0
  814. package/dist/core/__tests__/command-plugins-surfaces.test.js +325 -0
  815. package/dist/core/__tests__/command-plugins.test.d.ts +1 -0
  816. package/dist/core/__tests__/command-plugins.test.js +448 -0
  817. package/dist/core/__tests__/connection-reconnect-resume.test.d.ts +1 -0
  818. package/dist/core/__tests__/connection-reconnect-resume.test.js +36 -0
  819. package/dist/core/__tests__/context-intro.test.d.ts +1 -0
  820. package/dist/core/__tests__/context-intro.test.js +256 -0
  821. package/dist/core/__tests__/cron-broker-capacity.test.d.ts +1 -0
  822. package/dist/core/__tests__/cron-broker-capacity.test.js +100 -0
  823. package/dist/core/__tests__/daemon-boot.test.d.ts +1 -0
  824. package/dist/core/__tests__/daemon-boot.test.js +374 -0
  825. package/dist/core/__tests__/daemon-wedge.test.d.ts +1 -0
  826. package/dist/core/__tests__/daemon-wedge.test.js +104 -0
  827. package/dist/core/__tests__/dead-node-policy-table.test.d.ts +1 -0
  828. package/dist/core/__tests__/dead-node-policy-table.test.js +103 -0
  829. package/dist/core/__tests__/deferred-no-wake.test.d.ts +1 -0
  830. package/dist/core/__tests__/deferred-no-wake.test.js +514 -0
  831. package/dist/core/__tests__/events-contract.test.d.ts +1 -0
  832. package/dist/core/__tests__/events-contract.test.js +76 -0
  833. package/dist/core/__tests__/fault-classifier.test.d.ts +1 -0
  834. package/dist/core/__tests__/fault-classifier.test.js +71 -0
  835. package/dist/core/__tests__/finalization-migration.test.d.ts +1 -0
  836. package/dist/core/__tests__/finalization-migration.test.js +38 -0
  837. package/dist/core/__tests__/fixtures/api-server-host.d.ts +1 -0
  838. package/dist/core/__tests__/fixtures/api-server-host.js +47 -0
  839. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +2 -0
  840. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +34 -0
  841. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +2 -0
  842. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +8 -0
  843. package/dist/core/__tests__/fixtures/extra-extension.d.ts +1 -0
  844. package/dist/core/__tests__/fixtures/extra-extension.js +3 -0
  845. package/dist/core/__tests__/fixtures/fake-engine.d.ts +310 -0
  846. package/dist/core/__tests__/fixtures/fake-engine.js +1210 -0
  847. package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +2 -0
  848. package/dist/core/__tests__/fixtures/fake-pi-host.js +311 -0
  849. package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +1 -0
  850. package/dist/core/__tests__/fixtures/metadata-migration-race.js +49 -0
  851. package/dist/core/__tests__/fixtures/spawn-proof-target.test.d.ts +1 -0
  852. package/dist/core/__tests__/fixtures/spawn-proof-target.test.js +15 -0
  853. package/dist/core/__tests__/flagship-lifecycle.test.d.ts +1 -0
  854. package/dist/core/__tests__/flagship-lifecycle.test.js +303 -0
  855. package/dist/core/__tests__/focuses.test.d.ts +1 -0
  856. package/dist/core/__tests__/focuses.test.js +208 -0
  857. package/dist/core/__tests__/fork.test.d.ts +1 -0
  858. package/dist/core/__tests__/fork.test.js +108 -0
  859. package/dist/core/__tests__/full/broker-attach-limits.test.d.ts +1 -0
  860. package/dist/core/__tests__/full/broker-attach-limits.test.js +147 -0
  861. package/dist/core/__tests__/full/broker-attach-stream.test.d.ts +1 -0
  862. package/dist/core/__tests__/full/broker-attach-stream.test.js +133 -0
  863. package/dist/core/__tests__/full/broker-crash-teardown.test.d.ts +1 -0
  864. package/dist/core/__tests__/full/broker-crash-teardown.test.js +122 -0
  865. package/dist/core/__tests__/full/broker-deliver-ack.test.d.ts +1 -0
  866. package/dist/core/__tests__/full/broker-deliver-ack.test.js +73 -0
  867. package/dist/core/__tests__/full/broker-dialogs.test.d.ts +1 -0
  868. package/dist/core/__tests__/full/broker-dialogs.test.js +180 -0
  869. package/dist/core/__tests__/full/broker-display-snapshot.test.d.ts +1 -0
  870. package/dist/core/__tests__/full/broker-display-snapshot.test.js +75 -0
  871. package/dist/core/__tests__/full/broker-dormant-wake.test.d.ts +1 -0
  872. package/dist/core/__tests__/full/broker-dormant-wake.test.js +130 -0
  873. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +1 -0
  874. package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +57 -0
  875. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +1 -0
  876. package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +80 -0
  877. package/dist/core/__tests__/full/broker-pane-resolution.test.d.ts +1 -0
  878. package/dist/core/__tests__/full/broker-pane-resolution.test.js +155 -0
  879. package/dist/core/__tests__/full/broker-provider-retry.test.d.ts +1 -0
  880. package/dist/core/__tests__/full/broker-provider-retry.test.js +387 -0
  881. package/dist/core/__tests__/full/cascade-close.test.d.ts +1 -0
  882. package/dist/core/__tests__/full/cascade-close.test.js +240 -0
  883. package/dist/core/__tests__/full/consult-startup-failure.test.d.ts +1 -0
  884. package/dist/core/__tests__/full/consult-startup-failure.test.js +124 -0
  885. package/dist/core/__tests__/full/detach-focus.test.d.ts +1 -0
  886. package/dist/core/__tests__/full/detach-focus.test.js +126 -0
  887. package/dist/core/__tests__/full/idle-release-settlement.test.d.ts +1 -0
  888. package/dist/core/__tests__/full/idle-release-settlement.test.js +108 -0
  889. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.d.ts +1 -0
  890. package/dist/core/__tests__/full/issue-146-yield-spawn-focus.test.js +107 -0
  891. package/dist/core/__tests__/full/park-clock-release.test.d.ts +1 -0
  892. package/dist/core/__tests__/full/park-clock-release.test.js +56 -0
  893. package/dist/core/__tests__/full/yield-message-transaction.test.d.ts +1 -0
  894. package/dist/core/__tests__/full/yield-message-transaction.test.js +70 -0
  895. package/dist/core/__tests__/helpers/broker-clients.d.ts +43 -0
  896. package/dist/core/__tests__/helpers/broker-clients.js +182 -0
  897. package/dist/core/__tests__/helpers/fleet.d.ts +12 -0
  898. package/dist/core/__tests__/helpers/fleet.js +45 -0
  899. package/dist/core/__tests__/helpers/harness.d.ts +128 -0
  900. package/dist/core/__tests__/helpers/harness.js +867 -0
  901. package/dist/core/__tests__/helpers/viewer-panes.d.ts +12 -0
  902. package/dist/core/__tests__/helpers/viewer-panes.js +133 -0
  903. package/dist/core/__tests__/history-inbox.test.d.ts +1 -0
  904. package/dist/core/__tests__/history-inbox.test.js +105 -0
  905. package/dist/core/__tests__/host-teardown-process-group.test.d.ts +1 -0
  906. package/dist/core/__tests__/host-teardown-process-group.test.js +476 -0
  907. package/dist/core/__tests__/human-cancel-guard.test.d.ts +1 -0
  908. package/dist/core/__tests__/human-cancel-guard.test.js +71 -0
  909. package/dist/core/__tests__/human-deliver-e2e.test.d.ts +1 -0
  910. package/dist/core/__tests__/human-deliver-e2e.test.js +123 -0
  911. package/dist/core/__tests__/human-deliver.test.d.ts +1 -0
  912. package/dist/core/__tests__/human-deliver.test.js +399 -0
  913. package/dist/core/__tests__/human-node-not-supervised.test.d.ts +1 -0
  914. package/dist/core/__tests__/human-node-not-supervised.test.js +94 -0
  915. package/dist/core/__tests__/inline-memory-refs.test.d.ts +1 -0
  916. package/dist/core/__tests__/inline-memory-refs.test.js +320 -0
  917. package/dist/core/__tests__/kickoff.test.d.ts +1 -0
  918. package/dist/core/__tests__/kickoff.test.js +148 -0
  919. package/dist/core/__tests__/lifecycle.test.d.ts +1 -0
  920. package/dist/core/__tests__/lifecycle.test.js +165 -0
  921. package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +1 -0
  922. package/dist/core/__tests__/live-lifecycle-prompt.test.js +51 -0
  923. package/dist/core/__tests__/live-mutation-verbs.test.d.ts +1 -0
  924. package/dist/core/__tests__/live-mutation-verbs.test.js +195 -0
  925. package/dist/core/__tests__/live-mutation.test.d.ts +1 -0
  926. package/dist/core/__tests__/live-mutation.test.js +197 -0
  927. package/dist/core/__tests__/memory-index-render.test.d.ts +1 -0
  928. package/dist/core/__tests__/memory-index-render.test.js +60 -0
  929. package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +1 -0
  930. package/dist/core/__tests__/memory-resolver-precedence.test.js +169 -0
  931. package/dist/core/__tests__/migration.test.d.ts +1 -0
  932. package/dist/core/__tests__/migration.test.js +717 -0
  933. package/dist/core/__tests__/model-pin-durability.test.d.ts +1 -0
  934. package/dist/core/__tests__/model-pin-durability.test.js +124 -0
  935. package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +1 -0
  936. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +67 -0
  937. package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +1 -0
  938. package/dist/core/__tests__/on-read-dedup-resume.test.js +121 -0
  939. package/dist/core/__tests__/on-read-identity.test.d.ts +1 -0
  940. package/dist/core/__tests__/on-read-identity.test.js +68 -0
  941. package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +1 -0
  942. package/dist/core/__tests__/parse-argv-stdin-secret.test.js +26 -0
  943. package/dist/core/__tests__/passive-subscription.test.d.ts +1 -0
  944. package/dist/core/__tests__/passive-subscription.test.js +212 -0
  945. package/dist/core/__tests__/pid-identity-match.test.d.ts +1 -0
  946. package/dist/core/__tests__/pid-identity-match.test.js +145 -0
  947. package/dist/core/__tests__/pid-zombie.test.d.ts +1 -0
  948. package/dist/core/__tests__/pid-zombie.test.js +42 -0
  949. package/dist/core/__tests__/preview-registry-sync.test.d.ts +1 -0
  950. package/dist/core/__tests__/preview-registry-sync.test.js +65 -0
  951. package/dist/core/__tests__/prune-to-limit.test.d.ts +1 -0
  952. package/dist/core/__tests__/prune-to-limit.test.js +126 -0
  953. package/dist/core/__tests__/prune.test.d.ts +1 -0
  954. package/dist/core/__tests__/prune.test.js +135 -0
  955. package/dist/core/__tests__/push-final-guard.test.d.ts +1 -0
  956. package/dist/core/__tests__/push-final-guard.test.js +184 -0
  957. package/dist/core/__tests__/refresh-stall-recycle.test.d.ts +1 -0
  958. package/dist/core/__tests__/refresh-stall-recycle.test.js +101 -0
  959. package/dist/core/__tests__/relaunch-root.test.d.ts +1 -0
  960. package/dist/core/__tests__/relaunch-root.test.js +114 -0
  961. package/dist/core/__tests__/remote-canvas-target.test.d.ts +1 -0
  962. package/dist/core/__tests__/remote-canvas-target.test.js +87 -0
  963. package/dist/core/__tests__/reset.test.d.ts +1 -0
  964. package/dist/core/__tests__/reset.test.js +69 -0
  965. package/dist/core/__tests__/respawn-throttle.test.d.ts +1 -0
  966. package/dist/core/__tests__/respawn-throttle.test.js +154 -0
  967. package/dist/core/__tests__/review-model-floor.test.d.ts +1 -0
  968. package/dist/core/__tests__/review-model-floor.test.js +104 -0
  969. package/dist/core/__tests__/revive-all.test.d.ts +1 -0
  970. package/dist/core/__tests__/revive-all.test.js +147 -0
  971. package/dist/core/__tests__/revive.test.d.ts +1 -0
  972. package/dist/core/__tests__/revive.test.js +575 -0
  973. package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +1 -0
  974. package/dist/core/__tests__/scope-crouter-home-fence.test.js +55 -0
  975. package/dist/core/__tests__/secrets.test.d.ts +1 -0
  976. package/dist/core/__tests__/secrets.test.js +55 -0
  977. package/dist/core/__tests__/session-branch.test.d.ts +1 -0
  978. package/dist/core/__tests__/session-branch.test.js +61 -0
  979. package/dist/core/__tests__/session-cycles.test.d.ts +1 -0
  980. package/dist/core/__tests__/session-cycles.test.js +77 -0
  981. package/dist/core/__tests__/session-model.test.d.ts +1 -0
  982. package/dist/core/__tests__/session-model.test.js +129 -0
  983. package/dist/core/__tests__/spawn-no-kickoff.test.d.ts +1 -0
  984. package/dist/core/__tests__/spawn-no-kickoff.test.js +119 -0
  985. package/dist/core/__tests__/spawn-root.test.d.ts +1 -0
  986. package/dist/core/__tests__/spawn-root.test.js +320 -0
  987. package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +1 -0
  988. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +59 -0
  989. package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +1 -0
  990. package/dist/core/__tests__/stdin-body-no-discard.test.js +33 -0
  991. package/dist/core/__tests__/stdout-errors.test.d.ts +1 -0
  992. package/dist/core/__tests__/stdout-errors.test.js +16 -0
  993. package/dist/core/__tests__/steer-note.test.d.ts +1 -0
  994. package/dist/core/__tests__/steer-note.test.js +41 -0
  995. package/dist/core/__tests__/stop-guard.test.d.ts +1 -0
  996. package/dist/core/__tests__/stop-guard.test.js +157 -0
  997. package/dist/core/__tests__/stream-watchdog.test.d.ts +1 -0
  998. package/dist/core/__tests__/stream-watchdog.test.js +154 -0
  999. package/dist/core/__tests__/subcommand-tier.test.d.ts +1 -0
  1000. package/dist/core/__tests__/subcommand-tier.test.js +99 -0
  1001. package/dist/core/__tests__/subscription-delivery.test.d.ts +1 -0
  1002. package/dist/core/__tests__/subscription-delivery.test.js +211 -0
  1003. package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +1 -0
  1004. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +94 -0
  1005. package/dist/core/__tests__/test-runner-cheap-sharding.test.d.ts +1 -0
  1006. package/dist/core/__tests__/test-runner-cheap-sharding.test.js +97 -0
  1007. package/dist/core/__tests__/tmux-surface.test.d.ts +1 -0
  1008. package/dist/core/__tests__/tmux-surface.test.js +470 -0
  1009. package/dist/core/__tests__/wake-bearings.test.d.ts +1 -0
  1010. package/dist/core/__tests__/wake-bearings.test.js +102 -0
  1011. package/dist/core/__tests__/worktree.test.d.ts +1 -0
  1012. package/dist/core/__tests__/worktree.test.js +876 -0
  1013. package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +1 -0
  1014. package/dist/core/__tests__/yield-ensures-daemon.test.js +54 -0
  1015. package/dist/core/auth-file.d.ts +40 -0
  1016. package/dist/core/auth-file.js +177 -0
  1017. package/dist/core/auth-interaction.d.ts +19 -0
  1018. package/dist/core/auth-interaction.js +94 -0
  1019. package/dist/core/auto-update.d.ts +1 -0
  1020. package/dist/core/auto-update.js +93 -0
  1021. package/dist/core/bash-jobs.d.ts +55 -0
  1022. package/dist/core/bash-jobs.js +150 -0
  1023. package/dist/core/bootstrap.d.ts +5 -0
  1024. package/dist/core/bootstrap.js +98 -0
  1025. package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +1 -0
  1026. package/dist/core/broker-client/__tests__/transport-relay.test.js +213 -0
  1027. package/dist/core/broker-client/client.d.ts +97 -0
  1028. package/dist/core/broker-client/client.js +189 -0
  1029. package/dist/core/broker-client/index.d.ts +1 -0
  1030. package/dist/core/broker-client/index.js +13 -0
  1031. package/dist/core/broker-client/transport-relay.d.ts +51 -0
  1032. package/dist/core/broker-client/transport-relay.js +169 -0
  1033. package/dist/core/broker-client/transport-socket.d.ts +29 -0
  1034. package/dist/core/broker-client/transport-socket.js +164 -0
  1035. package/dist/core/broker-client/transport.d.ts +32 -0
  1036. package/dist/core/broker-client/transport.js +26 -0
  1037. package/dist/core/canvas/__tests__/attention.test.d.ts +1 -0
  1038. package/dist/core/canvas/__tests__/attention.test.js +97 -0
  1039. package/dist/core/canvas/__tests__/human-work-outbox.test.d.ts +1 -0
  1040. package/dist/core/canvas/__tests__/human-work-outbox.test.js +123 -0
  1041. package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +1 -0
  1042. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +372 -0
  1043. package/dist/core/canvas/__tests__/remote-event-stream.test.d.ts +1 -0
  1044. package/dist/core/canvas/__tests__/remote-event-stream.test.js +146 -0
  1045. package/dist/core/canvas/__tests__/render-remote.test.d.ts +1 -0
  1046. package/dist/core/canvas/__tests__/render-remote.test.js +241 -0
  1047. package/dist/core/canvas/__tests__/source-resolve.test.d.ts +1 -0
  1048. package/dist/core/canvas/__tests__/source-resolve.test.js +77 -0
  1049. package/dist/core/canvas/attention.d.ts +19 -0
  1050. package/dist/core/canvas/attention.js +87 -0
  1051. package/dist/core/canvas/boot-id.d.ts +6 -0
  1052. package/dist/core/canvas/boot-id.js +26 -0
  1053. package/dist/core/canvas/boot.d.ts +93 -0
  1054. package/dist/core/canvas/boot.js +190 -0
  1055. package/dist/core/canvas/browse/__tests__/model.test.d.ts +1 -0
  1056. package/dist/core/canvas/browse/__tests__/model.test.js +290 -0
  1057. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.d.ts +1 -0
  1058. package/dist/core/canvas/browse/__tests__/rebuild-coalescer.test.js +134 -0
  1059. package/dist/core/canvas/browse/__tests__/render.test.d.ts +1 -0
  1060. package/dist/core/canvas/browse/__tests__/render.test.js +111 -0
  1061. package/dist/core/canvas/browse/app.d.ts +41 -0
  1062. package/dist/core/canvas/browse/app.js +916 -0
  1063. package/dist/core/canvas/browse/model.d.ts +169 -0
  1064. package/dist/core/canvas/browse/model.js +485 -0
  1065. package/dist/core/canvas/browse/pins.d.ts +4 -0
  1066. package/dist/core/canvas/browse/pins.js +29 -0
  1067. package/dist/core/canvas/browse/rebuild-coalescer.d.ts +7 -0
  1068. package/dist/core/canvas/browse/rebuild-coalescer.js +61 -0
  1069. package/dist/core/canvas/browse/render.d.ts +59 -0
  1070. package/dist/core/canvas/browse/render.js +550 -0
  1071. package/dist/core/canvas/canvas.d.ts +358 -0
  1072. package/dist/core/canvas/canvas.js +897 -0
  1073. package/dist/core/canvas/crons.d.ts +222 -0
  1074. package/dist/core/canvas/crons.js +367 -0
  1075. package/dist/core/canvas/daemon-owner.d.ts +67 -0
  1076. package/dist/core/canvas/daemon-owner.js +141 -0
  1077. package/dist/core/canvas/db.d.ts +30 -0
  1078. package/dist/core/canvas/db.js +1167 -0
  1079. package/dist/core/canvas/extensions.d.ts +5 -0
  1080. package/dist/core/canvas/extensions.js +39 -0
  1081. package/dist/core/canvas/focuses.d.ts +22 -0
  1082. package/dist/core/canvas/focuses.js +81 -0
  1083. package/dist/core/canvas/history.d.ts +91 -0
  1084. package/dist/core/canvas/history.js +490 -0
  1085. package/dist/core/canvas/human-work-outbox.d.ts +73 -0
  1086. package/dist/core/canvas/human-work-outbox.js +261 -0
  1087. package/dist/core/canvas/index.d.ts +11 -0
  1088. package/dist/core/canvas/index.js +13 -0
  1089. package/dist/core/canvas/install-id.d.ts +9 -0
  1090. package/dist/core/canvas/install-id.js +84 -0
  1091. package/dist/core/canvas/labels.d.ts +28 -0
  1092. package/dist/core/canvas/labels.js +38 -0
  1093. package/dist/core/canvas/meta-file.d.ts +20 -0
  1094. package/dist/core/canvas/meta-file.js +98 -0
  1095. package/dist/core/canvas/nav-model.d.ts +55 -0
  1096. package/dist/core/canvas/nav-model.js +284 -0
  1097. package/dist/core/canvas/nav-render.d.ts +124 -0
  1098. package/dist/core/canvas/nav-render.js +266 -0
  1099. package/dist/core/canvas/paths.d.ts +81 -0
  1100. package/dist/core/canvas/paths.js +164 -0
  1101. package/dist/core/canvas/pid.d.ts +335 -0
  1102. package/dist/core/canvas/pid.js +636 -0
  1103. package/dist/core/canvas/remote-canvas-source.d.ts +62 -0
  1104. package/dist/core/canvas/remote-canvas-source.js +231 -0
  1105. package/dist/core/canvas/remote-event-stream.d.ts +24 -0
  1106. package/dist/core/canvas/remote-event-stream.js +94 -0
  1107. package/dist/core/canvas/render-source.d.ts +132 -0
  1108. package/dist/core/canvas/render-source.js +457 -0
  1109. package/dist/core/canvas/render.d.ts +47 -0
  1110. package/dist/core/canvas/render.js +237 -0
  1111. package/dist/core/canvas/source.d.ts +35 -0
  1112. package/dist/core/canvas/source.js +44 -0
  1113. package/dist/core/canvas/status-glyph.d.ts +42 -0
  1114. package/dist/core/canvas/status-glyph.js +116 -0
  1115. package/dist/core/canvas/telemetry.d.ts +14 -0
  1116. package/dist/core/canvas/telemetry.js +35 -0
  1117. package/dist/core/canvas/types.d.ts +302 -0
  1118. package/dist/core/canvas/types.js +8 -0
  1119. package/dist/core/clipboard-text.d.ts +3 -0
  1120. package/dist/core/clipboard-text.js +39 -0
  1121. package/dist/core/command-manifests/registry.d.ts +43 -0
  1122. package/dist/core/command-manifests/registry.js +103 -0
  1123. package/dist/core/command-manifests/schema.d.ts +87 -0
  1124. package/dist/core/command-manifests/schema.js +849 -0
  1125. package/dist/core/command-plugins/adapter.d.ts +22 -0
  1126. package/dist/core/command-plugins/adapter.js +160 -0
  1127. package/dist/core/command-plugins/compose.d.ts +11 -0
  1128. package/dist/core/command-plugins/compose.js +88 -0
  1129. package/dist/core/command-plugins/discovery.d.ts +74 -0
  1130. package/dist/core/command-plugins/discovery.js +291 -0
  1131. package/dist/core/command.d.ts +175 -0
  1132. package/dist/core/command.js +636 -0
  1133. package/dist/core/config.d.ts +125 -0
  1134. package/dist/core/config.js +620 -0
  1135. package/dist/core/configured-clis/cache.d.ts +16 -0
  1136. package/dist/core/configured-clis/cache.js +57 -0
  1137. package/dist/core/configured-clis/compose.d.ts +14 -0
  1138. package/dist/core/configured-clis/compose.js +60 -0
  1139. package/dist/core/configured-clis/discovery.d.ts +47 -0
  1140. package/dist/core/configured-clis/discovery.js +173 -0
  1141. package/dist/core/configured-clis/fetch.d.ts +51 -0
  1142. package/dist/core/configured-clis/fetch.js +156 -0
  1143. package/dist/core/configured-clis/invoker.d.ts +36 -0
  1144. package/dist/core/configured-clis/invoker.js +547 -0
  1145. package/dist/core/configured-clis/manifest.d.ts +24 -0
  1146. package/dist/core/configured-clis/manifest.js +284 -0
  1147. package/dist/core/configured-clis/registration.d.ts +40 -0
  1148. package/dist/core/configured-clis/registration.js +201 -0
  1149. package/dist/core/errors.d.ts +27 -0
  1150. package/dist/core/errors.js +48 -0
  1151. package/dist/core/events/emit.d.ts +4 -0
  1152. package/dist/core/events/emit.js +17 -0
  1153. package/dist/core/events/envelope.d.ts +2 -0
  1154. package/dist/core/events/envelope.js +84 -0
  1155. package/dist/core/events/errors.d.ts +4 -0
  1156. package/dist/core/events/errors.js +69 -0
  1157. package/dist/core/events/index.d.ts +5 -0
  1158. package/dist/core/events/index.js +4 -0
  1159. package/dist/core/events/operation-id.d.ts +4 -0
  1160. package/dist/core/events/operation-id.js +24 -0
  1161. package/dist/core/events/read.d.ts +40 -0
  1162. package/dist/core/events/read.js +639 -0
  1163. package/dist/core/events/serialize.d.ts +4 -0
  1164. package/dist/core/events/serialize.js +199 -0
  1165. package/dist/core/events/source.d.ts +18 -0
  1166. package/dist/core/events/source.js +47 -0
  1167. package/dist/core/events/types.d.ts +68 -0
  1168. package/dist/core/events/types.js +11 -0
  1169. package/dist/core/fault-classifier.d.ts +43 -0
  1170. package/dist/core/fault-classifier.js +143 -0
  1171. package/dist/core/feed/__tests__/coalesce-human.test.d.ts +1 -0
  1172. package/dist/core/feed/__tests__/coalesce-human.test.js +36 -0
  1173. package/dist/core/feed/__tests__/empty-node-guard.test.d.ts +1 -0
  1174. package/dist/core/feed/__tests__/empty-node-guard.test.js +45 -0
  1175. package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +1 -0
  1176. package/dist/core/feed/__tests__/inbox-migrate.test.js +53 -0
  1177. package/dist/core/feed/feed.d.ts +31 -0
  1178. package/dist/core/feed/feed.js +159 -0
  1179. package/dist/core/feed/inbox-migrate.d.ts +11 -0
  1180. package/dist/core/feed/inbox-migrate.js +135 -0
  1181. package/dist/core/feed/inbox.d.ts +84 -0
  1182. package/dist/core/feed/inbox.js +407 -0
  1183. package/dist/core/feed/passive.d.ts +14 -0
  1184. package/dist/core/feed/passive.js +114 -0
  1185. package/dist/core/frontmatter.d.ts +8 -0
  1186. package/dist/core/frontmatter.js +35 -0
  1187. package/dist/core/fs-utils.d.ts +21 -0
  1188. package/dist/core/fs-utils.js +149 -0
  1189. package/dist/core/git.d.ts +22 -0
  1190. package/dist/core/git.js +72 -0
  1191. package/dist/core/help.d.ts +223 -0
  1192. package/dist/core/help.js +275 -0
  1193. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.d.ts +1 -0
  1194. package/dist/core/host-exports/__tests__/export-prunes-boot-skill.test.js +84 -0
  1195. package/dist/core/host-exports/builtins.d.ts +50 -0
  1196. package/dist/core/host-exports/builtins.js +68 -0
  1197. package/dist/core/host-exports/export.d.ts +32 -0
  1198. package/dist/core/host-exports/export.js +128 -0
  1199. package/dist/core/inspector/core.d.ts +23 -0
  1200. package/dist/core/inspector/core.js +148 -0
  1201. package/dist/core/inspector/model.d.ts +54 -0
  1202. package/dist/core/inspector/model.js +182 -0
  1203. package/dist/core/inspector/text.d.ts +5 -0
  1204. package/dist/core/inspector/text.js +32 -0
  1205. package/dist/core/inspector/tui.d.ts +3 -0
  1206. package/dist/core/inspector/tui.js +220 -0
  1207. package/dist/core/io.d.ts +73 -0
  1208. package/dist/core/io.js +254 -0
  1209. package/dist/core/keybindings/__tests__/bespoke-consumers.test.d.ts +1 -0
  1210. package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +40 -0
  1211. package/dist/core/keybindings/__tests__/inbox-affordance.test.d.ts +1 -0
  1212. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +38 -0
  1213. package/dist/core/keybindings/__tests__/resolve.test.d.ts +1 -0
  1214. package/dist/core/keybindings/__tests__/resolve.test.js +233 -0
  1215. package/dist/core/keybindings/background-bash.d.ts +13 -0
  1216. package/dist/core/keybindings/background-bash.js +34 -0
  1217. package/dist/core/keybindings/catalog.d.ts +15 -0
  1218. package/dist/core/keybindings/catalog.js +285 -0
  1219. package/dist/core/keybindings/inbox.d.ts +21 -0
  1220. package/dist/core/keybindings/inbox.js +35 -0
  1221. package/dist/core/keybindings/index.d.ts +7 -0
  1222. package/dist/core/keybindings/index.js +6 -0
  1223. package/dist/core/keybindings/match.d.ts +29 -0
  1224. package/dist/core/keybindings/match.js +105 -0
  1225. package/dist/core/keybindings/persistence.d.ts +14 -0
  1226. package/dist/core/keybindings/persistence.js +31 -0
  1227. package/dist/core/keybindings/resolve.d.ts +22 -0
  1228. package/dist/core/keybindings/resolve.js +333 -0
  1229. package/dist/core/keybindings/types.d.ts +37 -0
  1230. package/dist/core/keybindings/types.js +1 -0
  1231. package/dist/core/locked-file.d.ts +24 -0
  1232. package/dist/core/locked-file.js +91 -0
  1233. package/dist/core/log.d.ts +3 -0
  1234. package/dist/core/log.js +27 -0
  1235. package/dist/core/manifest.d.ts +5 -0
  1236. package/dist/core/manifest.js +15 -0
  1237. package/dist/core/memory/inline-ref-grammar.d.ts +53 -0
  1238. package/dist/core/memory/inline-ref-grammar.js +99 -0
  1239. package/dist/core/memory/inline-ref-guidance.d.ts +8 -0
  1240. package/dist/core/memory/inline-ref-guidance.js +35 -0
  1241. package/dist/core/memory/inline-ref-inventory.d.ts +13 -0
  1242. package/dist/core/memory/inline-ref-inventory.js +79 -0
  1243. package/dist/core/memory-resolver.d.ts +106 -0
  1244. package/dist/core/memory-resolver.js +422 -0
  1245. package/dist/core/output.d.ts +35 -0
  1246. package/dist/core/output.js +99 -0
  1247. package/dist/core/pagination.d.ts +33 -0
  1248. package/dist/core/pagination.js +89 -0
  1249. package/dist/core/pool-credential-store.d.ts +34 -0
  1250. package/dist/core/pool-credential-store.js +116 -0
  1251. package/dist/core/predicate.d.ts +65 -0
  1252. package/dist/core/predicate.js +191 -0
  1253. package/dist/core/preview-registry.d.ts +25 -0
  1254. package/dist/core/preview-registry.js +2841 -0
  1255. package/dist/core/profiles/__tests__/env-store.test.d.ts +1 -0
  1256. package/dist/core/profiles/__tests__/env-store.test.js +97 -0
  1257. package/dist/core/profiles/__tests__/root-profile.test.d.ts +1 -0
  1258. package/dist/core/profiles/__tests__/root-profile.test.js +69 -0
  1259. package/dist/core/profiles/default-binding.d.ts +6 -0
  1260. package/dist/core/profiles/default-binding.js +46 -0
  1261. package/dist/core/profiles/env-store.d.ts +22 -0
  1262. package/dist/core/profiles/env-store.js +157 -0
  1263. package/dist/core/profiles/manifest.d.ts +35 -0
  1264. package/dist/core/profiles/manifest.js +371 -0
  1265. package/dist/core/profiles/select.d.ts +42 -0
  1266. package/dist/core/profiles/select.js +673 -0
  1267. package/dist/core/profiles/state-block.d.ts +4 -0
  1268. package/dist/core/profiles/state-block.js +16 -0
  1269. package/dist/core/provider-management.d.ts +12 -0
  1270. package/dist/core/provider-management.js +22 -0
  1271. package/dist/core/render.d.ts +12 -0
  1272. package/dist/core/render.js +127 -0
  1273. package/dist/core/resolver.d.ts +14 -0
  1274. package/dist/core/resolver.js +136 -0
  1275. package/dist/core/runtime/__tests__/command-expansion.test.d.ts +1 -0
  1276. package/dist/core/runtime/__tests__/command-expansion.test.js +25 -0
  1277. package/dist/core/runtime/__tests__/engine-route.test.d.ts +1 -0
  1278. package/dist/core/runtime/__tests__/engine-route.test.js +36 -0
  1279. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +1 -0
  1280. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +41 -0
  1281. package/dist/core/runtime/__tests__/node-env.test.d.ts +1 -0
  1282. package/dist/core/runtime/__tests__/node-env.test.js +73 -0
  1283. package/dist/core/runtime/__tests__/spawn-at-given-id.test.d.ts +1 -0
  1284. package/dist/core/runtime/__tests__/spawn-at-given-id.test.js +34 -0
  1285. package/dist/core/runtime/__tests__/spawn-env.test.d.ts +1 -0
  1286. package/dist/core/runtime/__tests__/spawn-env.test.js +268 -0
  1287. package/dist/core/runtime/auth-reload.d.ts +7 -0
  1288. package/dist/core/runtime/auth-reload.js +67 -0
  1289. package/dist/core/runtime/banner.d.ts +13 -0
  1290. package/dist/core/runtime/banner.js +51 -0
  1291. package/dist/core/runtime/bearings.d.ts +99 -0
  1292. package/dist/core/runtime/bearings.js +429 -0
  1293. package/dist/core/runtime/boot-root.d.ts +24 -0
  1294. package/dist/core/runtime/boot-root.js +102 -0
  1295. package/dist/core/runtime/branded-host.d.ts +25 -0
  1296. package/dist/core/runtime/branded-host.js +342 -0
  1297. package/dist/core/runtime/broker-cli.d.ts +1 -0
  1298. package/dist/core/runtime/broker-cli.js +81 -0
  1299. package/dist/core/runtime/broker-protocol.d.ts +642 -0
  1300. package/dist/core/runtime/broker-protocol.js +146 -0
  1301. package/dist/core/runtime/broker-request.d.ts +37 -0
  1302. package/dist/core/runtime/broker-request.js +85 -0
  1303. package/dist/core/runtime/broker-sdk.d.ts +36 -0
  1304. package/dist/core/runtime/broker-sdk.js +128 -0
  1305. package/dist/core/runtime/broker.d.ts +245 -0
  1306. package/dist/core/runtime/broker.js +3711 -0
  1307. package/dist/core/runtime/busy.d.ts +32 -0
  1308. package/dist/core/runtime/busy.js +107 -0
  1309. package/dist/core/runtime/canvas-extensions.d.ts +20 -0
  1310. package/dist/core/runtime/canvas-extensions.js +70 -0
  1311. package/dist/core/runtime/close.d.ts +34 -0
  1312. package/dist/core/runtime/close.js +223 -0
  1313. package/dist/core/runtime/command-expansion.d.ts +19 -0
  1314. package/dist/core/runtime/command-expansion.js +104 -0
  1315. package/dist/core/runtime/connectivity.d.ts +12 -0
  1316. package/dist/core/runtime/connectivity.js +73 -0
  1317. package/dist/core/runtime/deliver-live.d.ts +26 -0
  1318. package/dist/core/runtime/deliver-live.js +63 -0
  1319. package/dist/core/runtime/fault-recovery-nudge.d.ts +3 -0
  1320. package/dist/core/runtime/fault-recovery-nudge.js +3 -0
  1321. package/dist/core/runtime/fault-recovery.d.ts +23 -0
  1322. package/dist/core/runtime/fault-recovery.js +83 -0
  1323. package/dist/core/runtime/fault.d.ts +64 -0
  1324. package/dist/core/runtime/fault.js +260 -0
  1325. package/dist/core/runtime/fleet.d.ts +57 -0
  1326. package/dist/core/runtime/fleet.js +35 -0
  1327. package/dist/core/runtime/front-door.d.ts +16 -0
  1328. package/dist/core/runtime/front-door.js +186 -0
  1329. package/dist/core/runtime/host.d.ts +43 -0
  1330. package/dist/core/runtime/host.js +432 -0
  1331. package/dist/core/runtime/interactive-deliver.d.ts +15 -0
  1332. package/dist/core/runtime/interactive-deliver.js +41 -0
  1333. package/dist/core/runtime/kickoff.d.ts +53 -0
  1334. package/dist/core/runtime/kickoff.js +289 -0
  1335. package/dist/core/runtime/launch-prompt.d.ts +8 -0
  1336. package/dist/core/runtime/launch-prompt.js +13 -0
  1337. package/dist/core/runtime/launch.d.ts +191 -0
  1338. package/dist/core/runtime/launch.js +442 -0
  1339. package/dist/core/runtime/lifecycle.d.ts +12 -0
  1340. package/dist/core/runtime/lifecycle.js +121 -0
  1341. package/dist/core/runtime/managed-provider-cooling.d.ts +38 -0
  1342. package/dist/core/runtime/managed-provider-cooling.js +81 -0
  1343. package/dist/core/runtime/memory.d.ts +3 -0
  1344. package/dist/core/runtime/memory.js +18 -0
  1345. package/dist/core/runtime/model-selection.d.ts +41 -0
  1346. package/dist/core/runtime/model-selection.js +118 -0
  1347. package/dist/core/runtime/model-swap.d.ts +27 -0
  1348. package/dist/core/runtime/model-swap.js +70 -0
  1349. package/dist/core/runtime/naming-persist.d.ts +11 -0
  1350. package/dist/core/runtime/naming-persist.js +41 -0
  1351. package/dist/core/runtime/naming.d.ts +26 -0
  1352. package/dist/core/runtime/naming.js +174 -0
  1353. package/dist/core/runtime/node-read.d.ts +36 -0
  1354. package/dist/core/runtime/node-read.js +255 -0
  1355. package/dist/core/runtime/nodes.d.ts +113 -0
  1356. package/dist/core/runtime/nodes.js +330 -0
  1357. package/dist/core/runtime/package-health.d.ts +49 -0
  1358. package/dist/core/runtime/package-health.js +217 -0
  1359. package/dist/core/runtime/persona.d.ts +25 -0
  1360. package/dist/core/runtime/persona.js +132 -0
  1361. package/dist/core/runtime/pi-cli.d.ts +8 -0
  1362. package/dist/core/runtime/pi-cli.js +65 -0
  1363. package/dist/core/runtime/pi-vendored.d.ts +26 -0
  1364. package/dist/core/runtime/pi-vendored.js +77 -0
  1365. package/dist/core/runtime/placement-tmux.d.ts +42 -0
  1366. package/dist/core/runtime/placement-tmux.js +151 -0
  1367. package/dist/core/runtime/placement.d.ts +97 -0
  1368. package/dist/core/runtime/placement.js +394 -0
  1369. package/dist/core/runtime/promote.d.ts +44 -0
  1370. package/dist/core/runtime/promote.js +176 -0
  1371. package/dist/core/runtime/recap.d.ts +8 -0
  1372. package/dist/core/runtime/recap.js +136 -0
  1373. package/dist/core/runtime/recycle.d.ts +14 -0
  1374. package/dist/core/runtime/recycle.js +158 -0
  1375. package/dist/core/runtime/reopen.d.ts +32 -0
  1376. package/dist/core/runtime/reopen.js +119 -0
  1377. package/dist/core/runtime/reset.d.ts +68 -0
  1378. package/dist/core/runtime/reset.js +198 -0
  1379. package/dist/core/runtime/resume-root.d.ts +6 -0
  1380. package/dist/core/runtime/resume-root.js +292 -0
  1381. package/dist/core/runtime/revive-all.d.ts +61 -0
  1382. package/dist/core/runtime/revive-all.js +106 -0
  1383. package/dist/core/runtime/revive.d.ts +58 -0
  1384. package/dist/core/runtime/revive.js +357 -0
  1385. package/dist/core/runtime/roadmap.d.ts +13 -0
  1386. package/dist/core/runtime/roadmap.js +45 -0
  1387. package/dist/core/runtime/session-branch.d.ts +13 -0
  1388. package/dist/core/runtime/session-branch.js +46 -0
  1389. package/dist/core/runtime/session-cycles.d.ts +30 -0
  1390. package/dist/core/runtime/session-cycles.js +77 -0
  1391. package/dist/core/runtime/session-list-cache.d.ts +53 -0
  1392. package/dist/core/runtime/session-list-cache.js +406 -0
  1393. package/dist/core/runtime/situational-context.d.ts +12 -0
  1394. package/dist/core/runtime/situational-context.js +48 -0
  1395. package/dist/core/runtime/situational-live.d.ts +9 -0
  1396. package/dist/core/runtime/situational-live.js +40 -0
  1397. package/dist/core/runtime/spawn-env.d.ts +31 -0
  1398. package/dist/core/runtime/spawn-env.js +179 -0
  1399. package/dist/core/runtime/spawn.d.ts +118 -0
  1400. package/dist/core/runtime/spawn.js +473 -0
  1401. package/dist/core/runtime/stop-guard.d.ts +18 -0
  1402. package/dist/core/runtime/stop-guard.js +77 -0
  1403. package/dist/core/runtime/stop-signals.d.ts +14 -0
  1404. package/dist/core/runtime/stop-signals.js +46 -0
  1405. package/dist/core/runtime/stream-watchdog.d.ts +55 -0
  1406. package/dist/core/runtime/stream-watchdog.js +140 -0
  1407. package/dist/core/runtime/structured-output.d.ts +12 -0
  1408. package/dist/core/runtime/structured-output.js +90 -0
  1409. package/dist/core/runtime/surface-bg.d.ts +11 -0
  1410. package/dist/core/runtime/surface-bg.js +68 -0
  1411. package/dist/core/runtime/tmux-chrome.d.ts +1 -0
  1412. package/dist/core/runtime/tmux-chrome.js +4 -0
  1413. package/dist/core/runtime/tmux.d.ts +247 -0
  1414. package/dist/core/runtime/tmux.js +858 -0
  1415. package/dist/core/runtime/warm-pool.d.ts +51 -0
  1416. package/dist/core/runtime/warm-pool.js +373 -0
  1417. package/dist/core/scope.d.ts +47 -0
  1418. package/dist/core/scope.js +255 -0
  1419. package/dist/core/secrets.d.ts +25 -0
  1420. package/dist/core/secrets.js +55 -0
  1421. package/dist/core/self-update.d.ts +21 -0
  1422. package/dist/core/self-update.js +105 -0
  1423. package/dist/core/session-model/session-state.d.ts +51 -0
  1424. package/dist/core/session-model/session-state.js +170 -0
  1425. package/dist/core/spawn.d.ts +16 -0
  1426. package/dist/core/spawn.js +30 -0
  1427. package/dist/core/stdout-errors.d.ts +3 -0
  1428. package/dist/core/stdout-errors.js +14 -0
  1429. package/dist/core/subscription-state.d.ts +138 -0
  1430. package/dist/core/subscription-state.js +918 -0
  1431. package/dist/core/substrate/ceiling.d.ts +20 -0
  1432. package/dist/core/substrate/ceiling.js +69 -0
  1433. package/dist/core/substrate/gate.d.ts +13 -0
  1434. package/dist/core/substrate/gate.js +21 -0
  1435. package/dist/core/substrate/index.d.ts +11 -0
  1436. package/dist/core/substrate/index.js +25 -0
  1437. package/dist/core/substrate/injected-store.d.ts +10 -0
  1438. package/dist/core/substrate/injected-store.js +55 -0
  1439. package/dist/core/substrate/on-read.d.ts +14 -0
  1440. package/dist/core/substrate/on-read.js +404 -0
  1441. package/dist/core/substrate/render-node.d.ts +11 -0
  1442. package/dist/core/substrate/render-node.js +29 -0
  1443. package/dist/core/substrate/render.d.ts +21 -0
  1444. package/dist/core/substrate/render.js +547 -0
  1445. package/dist/core/substrate/schema.d.ts +125 -0
  1446. package/dist/core/substrate/schema.js +191 -0
  1447. package/dist/core/substrate/session-cache.d.ts +25 -0
  1448. package/dist/core/substrate/session-cache.js +101 -0
  1449. package/dist/core/substrate/subject-fields.d.ts +45 -0
  1450. package/dist/core/substrate/subject-fields.js +38 -0
  1451. package/dist/core/substrate/subject.d.ts +12 -0
  1452. package/dist/core/substrate/subject.js +47 -0
  1453. package/dist/core/timing.d.ts +11 -0
  1454. package/dist/core/timing.js +94 -0
  1455. package/dist/core/tui/__tests__/host-keybindings.test.d.ts +1 -0
  1456. package/dist/core/tui/__tests__/host-keybindings.test.js +113 -0
  1457. package/dist/core/tui/draw.d.ts +100 -0
  1458. package/dist/core/tui/draw.js +359 -0
  1459. package/dist/core/tui/host.d.ts +66 -0
  1460. package/dist/core/tui/host.js +689 -0
  1461. package/dist/core/tui/terminal.d.ts +23 -0
  1462. package/dist/core/tui/terminal.js +101 -0
  1463. package/dist/core/view/__tests__/transport-cache.test.d.ts +1 -0
  1464. package/dist/core/view/__tests__/transport-cache.test.js +62 -0
  1465. package/dist/core/view/__tests__/transport-remote.test.d.ts +1 -0
  1466. package/dist/core/view/__tests__/transport-remote.test.js +98 -0
  1467. package/dist/core/view/bridge.d.ts +10 -0
  1468. package/dist/core/view/bridge.js +31 -0
  1469. package/dist/core/view/chrome.d.ts +9 -0
  1470. package/dist/core/view/chrome.js +22 -0
  1471. package/dist/core/view/contract.d.ts +205 -0
  1472. package/dist/core/view/contract.js +23 -0
  1473. package/dist/core/view/loader.d.ts +31 -0
  1474. package/dist/core/view/loader.js +188 -0
  1475. package/dist/core/view/remote-canvas-target.d.ts +4 -0
  1476. package/dist/core/view/remote-canvas-target.js +30 -0
  1477. package/dist/core/view/stream-local.d.ts +3 -0
  1478. package/dist/core/view/stream-local.js +231 -0
  1479. package/dist/core/view/transport-cache.d.ts +8 -0
  1480. package/dist/core/view/transport-cache.js +38 -0
  1481. package/dist/core/view/transport-local.d.ts +7 -0
  1482. package/dist/core/view/transport-local.js +83 -0
  1483. package/dist/core/view/transport-remote.d.ts +2 -0
  1484. package/dist/core/view/transport-remote.js +58 -0
  1485. package/dist/core/view/transport.d.ts +10 -0
  1486. package/dist/core/view/transport.js +15 -0
  1487. package/dist/core/wake.d.ts +86 -0
  1488. package/dist/core/wake.js +307 -0
  1489. package/dist/core/worktree.d.ts +111 -0
  1490. package/dist/core/worktree.js +732 -0
  1491. package/dist/daemon/__tests__/broker-ownership.test.d.ts +1 -0
  1492. package/dist/daemon/__tests__/broker-ownership.test.js +25 -0
  1493. package/dist/daemon/__tests__/daemon-ownership.test.d.ts +1 -0
  1494. package/dist/daemon/__tests__/daemon-ownership.test.js +27 -0
  1495. package/dist/daemon/api/__tests__/error-seam.test.d.ts +1 -0
  1496. package/dist/daemon/api/__tests__/error-seam.test.js +56 -0
  1497. package/dist/daemon/api/__tests__/full/api-server.test.d.ts +1 -0
  1498. package/dist/daemon/api/__tests__/full/api-server.test.js +369 -0
  1499. package/dist/daemon/api/__tests__/full/b10-attach-modelauth.test.d.ts +1 -0
  1500. package/dist/daemon/api/__tests__/full/b10-attach-modelauth.test.js +220 -0
  1501. package/dist/daemon/api/__tests__/full/push-parity.test.d.ts +1 -0
  1502. package/dist/daemon/api/__tests__/full/push-parity.test.js +199 -0
  1503. package/dist/daemon/api/__tests__/full/worktree-parity.test.d.ts +1 -0
  1504. package/dist/daemon/api/__tests__/full/worktree-parity.test.js +160 -0
  1505. package/dist/daemon/api/__tests__/inbox.test.d.ts +1 -0
  1506. package/dist/daemon/api/__tests__/inbox.test.js +578 -0
  1507. package/dist/daemon/api/bridge.d.ts +21 -0
  1508. package/dist/daemon/api/bridge.js +351 -0
  1509. package/dist/daemon/api/handlers/attach.d.ts +2 -0
  1510. package/dist/daemon/api/handlers/attach.js +56 -0
  1511. package/dist/daemon/api/handlers/canvas.d.ts +2 -0
  1512. package/dist/daemon/api/handlers/canvas.js +463 -0
  1513. package/dist/daemon/api/handlers/crons.d.ts +2 -0
  1514. package/dist/daemon/api/handlers/crons.js +354 -0
  1515. package/dist/daemon/api/handlers/daemon.d.ts +2 -0
  1516. package/dist/daemon/api/handlers/daemon.js +35 -0
  1517. package/dist/daemon/api/handlers/files.d.ts +2 -0
  1518. package/dist/daemon/api/handlers/files.js +64 -0
  1519. package/dist/daemon/api/handlers/focus.d.ts +2 -0
  1520. package/dist/daemon/api/handlers/focus.js +92 -0
  1521. package/dist/daemon/api/handlers/health.d.ts +2 -0
  1522. package/dist/daemon/api/handlers/health.js +65 -0
  1523. package/dist/daemon/api/handlers/human.d.ts +12 -0
  1524. package/dist/daemon/api/handlers/human.js +741 -0
  1525. package/dist/daemon/api/handlers/inbox.d.ts +2 -0
  1526. package/dist/daemon/api/handlers/inbox.js +423 -0
  1527. package/dist/daemon/api/handlers/messages.d.ts +2 -0
  1528. package/dist/daemon/api/handlers/messages.js +290 -0
  1529. package/dist/daemon/api/handlers/modelauth.d.ts +2 -0
  1530. package/dist/daemon/api/handlers/modelauth.js +116 -0
  1531. package/dist/daemon/api/handlers/nodes.d.ts +2 -0
  1532. package/dist/daemon/api/handlers/nodes.js +540 -0
  1533. package/dist/daemon/api/handlers/profiles.d.ts +2 -0
  1534. package/dist/daemon/api/handlers/profiles.js +69 -0
  1535. package/dist/daemon/api/handlers/reports.d.ts +2 -0
  1536. package/dist/daemon/api/handlers/reports.js +144 -0
  1537. package/dist/daemon/api/handlers/subscriptions.d.ts +2 -0
  1538. package/dist/daemon/api/handlers/subscriptions.js +53 -0
  1539. package/dist/daemon/api/handlers/worktree.d.ts +2 -0
  1540. package/dist/daemon/api/handlers/worktree.js +40 -0
  1541. package/dist/daemon/api/map.d.ts +100 -0
  1542. package/dist/daemon/api/map.js +360 -0
  1543. package/dist/daemon/api/router.d.ts +56 -0
  1544. package/dist/daemon/api/router.js +190 -0
  1545. package/dist/daemon/api/server.d.ts +23 -0
  1546. package/dist/daemon/api/server.js +258 -0
  1547. package/dist/daemon/control.d.ts +21 -0
  1548. package/dist/daemon/control.js +22 -0
  1549. package/dist/daemon/cron-run.d.ts +64 -0
  1550. package/dist/daemon/cron-run.js +944 -0
  1551. package/dist/daemon/cron-sink.d.ts +26 -0
  1552. package/dist/daemon/cron-sink.js +43 -0
  1553. package/dist/daemon/crtrd-cli.d.ts +1 -0
  1554. package/dist/daemon/crtrd-cli.js +18 -0
  1555. package/dist/daemon/crtrd.d.ts +89 -0
  1556. package/dist/daemon/crtrd.js +1953 -0
  1557. package/dist/daemon/fleet.d.ts +81 -0
  1558. package/dist/daemon/fleet.js +405 -0
  1559. package/dist/daemon/manage.d.ts +103 -0
  1560. package/dist/daemon/manage.js +389 -0
  1561. package/dist/daemon/pidfile.d.ts +8 -0
  1562. package/dist/daemon/pidfile.js +37 -0
  1563. package/dist/daemon/supervise-cadence.d.ts +1 -0
  1564. package/dist/daemon/supervise-cadence.js +6 -0
  1565. package/dist/index.d.ts +23 -0
  1566. package/dist/index.js +44 -0
  1567. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +1 -0
  1568. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +31 -0
  1569. package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +1 -0
  1570. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +182 -0
  1571. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +1 -0
  1572. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +467 -0
  1573. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +1 -0
  1574. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +121 -0
  1575. package/dist/pi-extensions/canvas-bash-valve.d.ts +8 -0
  1576. package/dist/pi-extensions/canvas-bash-valve.js +297 -0
  1577. package/dist/pi-extensions/canvas-context-intro.d.ts +91 -0
  1578. package/dist/pi-extensions/canvas-context-intro.js +230 -0
  1579. package/dist/pi-extensions/canvas-doc-substrate.d.ts +44 -0
  1580. package/dist/pi-extensions/canvas-doc-substrate.js +151 -0
  1581. package/dist/pi-extensions/canvas-goal-capture.d.ts +21 -0
  1582. package/dist/pi-extensions/canvas-goal-capture.js +83 -0
  1583. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +25 -0
  1584. package/dist/pi-extensions/canvas-inbox-watcher.js +942 -0
  1585. package/dist/pi-extensions/canvas-passive-context.d.ts +32 -0
  1586. package/dist/pi-extensions/canvas-passive-context.js +134 -0
  1587. package/dist/pi-extensions/canvas-recap.d.ts +41 -0
  1588. package/dist/pi-extensions/canvas-recap.js +263 -0
  1589. package/dist/pi-extensions/canvas-stophook.d.ts +53 -0
  1590. package/dist/pi-extensions/canvas-stophook.js +985 -0
  1591. package/dist/pi-extensions/canvas-structured-output.d.ts +9 -0
  1592. package/dist/pi-extensions/canvas-structured-output.js +155 -0
  1593. package/dist/prompts/review.d.ts +2 -0
  1594. package/dist/prompts/review.js +130 -0
  1595. package/dist/prompts/view.d.ts +7 -0
  1596. package/dist/prompts/view.js +172 -0
  1597. package/dist/suppress-experimental-warnings.d.ts +1 -0
  1598. package/dist/suppress-experimental-warnings.js +15 -0
  1599. package/dist/types.d.ts +297 -0
  1600. package/dist/types.js +153 -0
  1601. package/dist/web/ViewChrome.d.ts +7 -0
  1602. package/dist/web/ViewChrome.js +28 -0
  1603. package/dist/web/ViewPane.d.ts +39 -0
  1604. package/dist/web/ViewPane.js +48 -0
  1605. package/dist/web/index.d.ts +8 -0
  1606. package/dist/web/index.js +22 -0
  1607. package/dist/web/runtime.d.ts +39 -0
  1608. package/dist/web/runtime.js +232 -0
  1609. package/dist/web/states.d.ts +24 -0
  1610. package/dist/web/states.js +24 -0
  1611. package/dist/web/transport-http.d.ts +5 -0
  1612. package/dist/web/transport-http.js +34 -0
  1613. package/dist/web/transport-stream.d.ts +3 -0
  1614. package/dist/web/transport-stream.js +204 -0
  1615. package/dist/web-client/apple-touch-icon.png +0 -0
  1616. package/dist/web-client/assets/fragment-mono-latin-400-normal-BYwT3kSJ.woff +0 -0
  1617. package/dist/web-client/assets/fragment-mono-latin-400-normal-yxdJ5AmL.woff2 +0 -0
  1618. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-BbKYyvR9.woff2 +0 -0
  1619. package/dist/web-client/assets/fragment-mono-latin-ext-400-normal-CT4YFKeK.woff +0 -0
  1620. package/dist/web-client/assets/index-BpyZGBhI.js +79 -0
  1621. package/dist/web-client/assets/index-CpEl9LTS.css +2 -0
  1622. package/dist/web-client/assets/martian-mono-cyrillic-wght-normal-B84CD5C_.woff2 +0 -0
  1623. package/dist/web-client/assets/martian-mono-latin-ext-wght-normal-DlL6xMw5.woff2 +0 -0
  1624. package/dist/web-client/assets/martian-mono-latin-wght-normal-5W32yIyr.woff2 +0 -0
  1625. package/dist/web-client/assets/workbox-window.prod.es5-Bd17z0YL.js +2 -0
  1626. package/dist/web-client/icon-192.png +0 -0
  1627. package/dist/web-client/icon-512.png +0 -0
  1628. package/dist/web-client/icon-maskable-512.png +0 -0
  1629. package/dist/web-client/index.html +17 -0
  1630. package/dist/web-client/manifest.webmanifest +1 -0
  1631. package/dist/web-client/sw.js +1 -0
  1632. package/docs/compat/hearth-crtr-v1.md +187 -0
  1633. package/docs/compat/hearth-crtr-v2.md +185 -0
  1634. package/docs/compat/hearth-crtr-v3.md +184 -0
  1635. package/docs/compat/hearth-crtr-v4.md +188 -0
  1636. package/docs/compat/hearth-crtr-v5.md +175 -0
  1637. package/docs/public-api.md +77 -0
  1638. package/package.json +156 -0
  1639. package/runtime.lock.json +12919 -0
  1640. package/scripts/install-runtime.mjs +308 -0
  1641. package/scripts/patch-pi-tree-root-ordering.mjs +57 -0
  1642. package/scripts/postinstall.mjs +33 -0
  1643. package/scripts/runtime-lock.mjs +26 -0
@@ -0,0 +1,2103 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import { visibleWidth } from '@earendil-works/pi-tui';
4
+ import { createCrtrBashToolDefinition, isCrtrBashCommand, isCrtrHelpInvocation, renderCrtrOutputText, } from '../render/crtr-output.js';
5
+ import { HELP_ICON, iconForPath } from '../../../core/preview-registry.js';
6
+ const theme = {
7
+ // `text` and `dim` are the preview's base hierarchy roles; leave them
8
+ // transparent here so assertions can still match the underlying receipt.
9
+ // Semantic colors remain tagged and are asserted where state matters.
10
+ fg(name, text) { return name === 'text' || name === 'dim' ? text : `<${name}>${text}</${name}>`; },
11
+ bg(_name, text) { return text; },
12
+ bold(text) { return `<b>${text}</b>`; },
13
+ };
14
+ const plainTheme = {
15
+ fg(_name, text) { return text; },
16
+ bg(_name, text) { return text; },
17
+ bold(text) { return text; },
18
+ };
19
+ function stripAnsi(text) {
20
+ return text.replace(/\x1b\[[0-9;]*m/g, '');
21
+ }
22
+ test('detects crtr in bash command position, not heredoc body prose', () => {
23
+ assert.equal(isCrtrBashCommand('crtr node new -h'), true);
24
+ assert.equal(isCrtrBashCommand('crtr node inspect snapshot --node abc'), true);
25
+ assert.equal(isCrtrBashCommand('crtr sys daemon status'), true);
26
+ assert.equal(isCrtrBashCommand('npm test && /usr/local/bin/crouter surface view run inbox'), true);
27
+ assert.equal(isCrtrBashCommand("cat <<'EOF'\nask about crtr node new\nEOF\necho done"), false);
28
+ assert.equal(isCrtrBashCommand('echo crtr node new'), false);
29
+ });
30
+ test('returns a viewer tool definition only for crtr bash commands', () => {
31
+ assert.equal(createCrtrBashToolDefinition({ command: 'echo hi' }), undefined);
32
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard' });
33
+ assert.equal(typeof def.renderCall, 'function');
34
+ const rendered = def.renderCall({ command: 'crtr canvas dashboard' }, theme).render(80).join('\n');
35
+ assert.equal(rendered.trimEnd().split('\n').length, 1);
36
+ assert.match(rendered, new RegExp(iconForPath(['canvas', 'dashboard'])));
37
+ assert.match(rendered, /crtr/);
38
+ assert.match(rendered, /canvas dashboard/);
39
+ assert.doesNotMatch(rendered, /◆/);
40
+ assert.match(def.renderResult({ content: [{ type: 'text', text: '<command name="canvas">' }], details: undefined }, { expanded: true }, theme, {}).render(80).join('\n'), /<accent><b><command/);
41
+ });
42
+ test('styles crtr structural output and status glyphs', () => {
43
+ const rendered = renderCrtrOutputText('<command name="node">\nInput\n● active\nCommand exited with code 1', theme);
44
+ assert.match(rendered, /<accent><b><command/);
45
+ assert.match(rendered, /<toolTitle><b>Input/);
46
+ assert.match(rendered, /<success>● active/);
47
+ assert.match(rendered, /<error>Command exited/);
48
+ });
49
+ // Help output is structural schema text, never a command result, so the
50
+ // viewer detects it from the invocation itself and gives it help-specific
51
+ // collapsed chrome rather than treating it as a normal result preview.
52
+ test('detects a bare -h/--help token in a crtr invocation', () => {
53
+ assert.equal(isCrtrHelpInvocation('crtr node new -h'), true);
54
+ assert.equal(isCrtrHelpInvocation('crtr node inspect snapshot --node abc --help'), true);
55
+ assert.equal(isCrtrHelpInvocation('crtr canvas dashboard'), false);
56
+ assert.equal(isCrtrHelpInvocation('echo crtr node new -h'), false);
57
+ });
58
+ // Help-token detection is scoped to the extracted crtr segment's own tokens,
59
+ // with quote boundaries respected, so unrelated shell siblings and quoted
60
+ // prompt text do not affect the crtr preview.
61
+ test('does not misclassify -h/--help outside the crtr invocation\'s own argv as help', () => {
62
+ assert.equal(isCrtrHelpInvocation('echo -h && crtr canvas snapshot'), false);
63
+ assert.equal(isCrtrHelpInvocation('crtr canvas snapshot && echo --help'), false);
64
+ assert.equal(isCrtrHelpInvocation('crtr node new "write about -h flags"'), false);
65
+ // Sanity: the real thing one token over still trips it.
66
+ assert.equal(isCrtrHelpInvocation('crtr node new -h'), true);
67
+ assert.equal(isCrtrHelpInvocation('crtr node new --help'), true);
68
+ });
69
+ // Realistic leaf schema (renderLeafArgv shape: `name: summary.` then an
70
+ // Input-headed param block) — a stand-in for e.g. `crtr canvas dashboard -h`.
71
+ const LEAF_SCHEMA = 'canvas dashboard: render the canvas as an ASCII subscription tree.\n\n' +
72
+ 'Input\n' +
73
+ ' --root ROOT string, optional. Node id to use as the tree root.\n\n' +
74
+ 'Output (fields carried in the rendered result)\n' +
75
+ ' tree string. Multi-line ASCII tree.\n\n' +
76
+ 'Effects\n' +
77
+ ' Read-only: queries canvas.db.';
78
+ // Realistic branch schema (renderBranch shape: one <command description=...>
79
+ // card with self-closing <subcommand .../> rows) — a stand-in for e.g.
80
+ // `crtr node inspect -h`.
81
+ const BRANCH_SCHEMA = '<command name="node inspect" description="read the canvas graph">\n' +
82
+ '<subcommand name="list" description="list nodes on the canvas" whenToUse="a very long rubric that is not part of the preview at all"/>\n\n' +
83
+ '<subcommand name="show" description="show a node + its spine neighbors" whenToUse="another long rubric"/>\n' +
84
+ '</command>';
85
+ test('collapsed help preview never parrots the call header or dumps the raw schema, and stays within the line cap', () => {
86
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard -h' });
87
+ const collapsed = def
88
+ .renderResult({ content: [{ type: 'text', text: LEAF_SCHEMA }] }, { expanded: false }, theme, {})
89
+ .render(80)
90
+ .join('\n');
91
+ // The call header already carries the help glyph header; the collapsed body is
92
+ // JUST the synthesized preview content, no repeated status/help label.
93
+ assert.doesNotMatch(collapsed, new RegExp(`${HELP_ICON} crtr help`));
94
+ assert.match(collapsed, /ctrl\+o to expand/);
95
+ assert.doesNotMatch(collapsed, /<success>✓ crtr done/);
96
+ // No raw schema dump leaking into the body.
97
+ assert.doesNotMatch(collapsed, /<command/);
98
+ // A useful synthesized slice IS present: the leaf's own summary line.
99
+ assert.match(collapsed, /render the canvas as an ASCII subscription/);
100
+ assert.match(collapsed, /Params: --root/);
101
+ assert.ok(collapsed.split('\n').length <= 20, `expected <=20 lines, got ${collapsed.split('\n').length}`);
102
+ // Full schema remains readable on demand.
103
+ const expanded = def
104
+ .renderResult({ content: [{ type: 'text', text: LEAF_SCHEMA }] }, { expanded: true }, theme, {})
105
+ .render(80)
106
+ .join('\n');
107
+ assert.match(expanded, /Node id to use as the tree root/);
108
+ assert.match(expanded, /Read-only: queries canvas\.db/);
109
+ });
110
+ test('collapsed branch/root help synthesizes a subcommand/description preview, not the raw <subcommand> tags', () => {
111
+ const def = createCrtrBashToolDefinition({ command: 'crtr node inspect -h' });
112
+ const collapsed = def
113
+ .renderResult({ content: [{ type: 'text', text: BRANCH_SCHEMA }] }, { expanded: false }, theme, {})
114
+ .render(80)
115
+ .join('\n');
116
+ assert.doesNotMatch(collapsed, /<command/);
117
+ assert.doesNotMatch(collapsed, /<subcommand/);
118
+ assert.doesNotMatch(collapsed, /whenToUse/);
119
+ // Useful preview: branch description plus name — description subcommand rows.
120
+ assert.match(collapsed, /read the canvas graph/);
121
+ assert.match(collapsed, /list.*—.*list nodes on the canvas/s);
122
+ assert.match(collapsed, /show.*—.*show a node \+ its spine neighbors/s);
123
+ assert.ok(collapsed.split('\n').length <= 20, `expected <=20 lines, got ${collapsed.split('\n').length}`);
124
+ });
125
+ // Realistic root schema (renderRoot shape: a tagline, then one
126
+ // `<command name="X">\n<concept>\nuse when ...` block per subtree, NO
127
+ // description attribute on the tag) — a stand-in for `crtr -h`.
128
+ const ROOT_SCHEMA = 'crtr: agentic runtime.\n\n' +
129
+ '<command name="memory">\n' +
130
+ 'a memory document you read on demand\n' +
131
+ 'use when a task matches stored knowledge or a preference\n' +
132
+ '</command>\n\n' +
133
+ '<command name="node">\n' +
134
+ 'a unit of the agent runtime\n' +
135
+ 'use when delegating work\n' +
136
+ '</command>\n\n' +
137
+ 'Globals\n' +
138
+ ' -h print help\n\n' +
139
+ 'I/O contract: ...';
140
+ test('collapsed root help synthesizes a tagline + name/concept preview, not the raw <command> blocks', () => {
141
+ const def = createCrtrBashToolDefinition({ command: 'crtr -h' });
142
+ const collapsed = def
143
+ .renderResult({ content: [{ type: 'text', text: ROOT_SCHEMA }] }, { expanded: false }, theme, {})
144
+ .render(80)
145
+ .join('\n');
146
+ assert.doesNotMatch(collapsed, /<command/);
147
+ assert.match(collapsed, /crtr: agentic runtime/);
148
+ assert.match(collapsed, /memory.*—.*a memory document you read on demand/s);
149
+ assert.match(collapsed, /node.*—.*a unit of the agent runtime/s);
150
+ assert.ok(collapsed.split('\n').length <= 20, `expected <=20 lines, got ${collapsed.split('\n').length}`);
151
+ });
152
+ test('a branch help preview with more subcommands than the line cap truncates with an expand hint, never mid-tag', () => {
153
+ const def = createCrtrBashToolDefinition({ command: 'crtr node -h' });
154
+ const manySubs = Array.from({ length: 30 }, (_, i) => `<subcommand name="sub${i}" description="description for subcommand ${i}" whenToUse="long rubric ${i}"/>`).join('\n\n');
155
+ const bigBranchSchema = `<command name="node" description="spawn and navigate canvas nodes">\n${manySubs}\n</command>`;
156
+ const collapsed = def
157
+ .renderResult({ content: [{ type: 'text', text: bigBranchSchema }] }, { expanded: false }, theme, {})
158
+ .render(80)
159
+ .join('\n');
160
+ assert.doesNotMatch(collapsed, /<subcommand/);
161
+ assert.match(collapsed, /ctrl\+o to expand/);
162
+ assert.ok(collapsed.split('\n').length <= 20, `expected <=20 lines, got ${collapsed.split('\n').length}`);
163
+ });
164
+ // Contract: outer bash redirects are shell plumbing, not crtr argv, so the
165
+ // displayed crtr path and help detection include only the command segment.
166
+ test('a shell redirect on the outer bash call never leaks into the displayed crtr path or help detection', () => {
167
+ const def = createCrtrBashToolDefinition({ command: 'crtr push -h 2>&1' });
168
+ const rendered = def.renderCall({ command: 'crtr push -h 2>&1' }, theme).render(80).join('\n');
169
+ assert.match(rendered, new RegExp(HELP_ICON));
170
+ assert.match(rendered, /crtr help/);
171
+ assert.match(rendered, /<b>push<\/b>/);
172
+ assert.doesNotMatch(rendered, /2>/);
173
+ assert.doesNotMatch(rendered, />&1/);
174
+ assert.equal(isCrtrHelpInvocation('crtr push -h 2>&1'), true);
175
+ // Other redirect shapes on the outer call, and mid-argv redirects, must
176
+ // never survive into the path either.
177
+ const other = createCrtrBashToolDefinition({ command: 'crtr node new --name foo > /tmp/log 2>&1' });
178
+ const otherRendered = other.renderCall({ command: 'crtr node new --name foo > /tmp/log 2>&1' }, theme).render(80).join('\n');
179
+ assert.match(otherRendered, /node new --name foo/);
180
+ assert.doesNotMatch(otherRendered, /tmp\/log/);
181
+ // Redirect operators glued to their target with NO space (`2>/tmp/out`,
182
+ // `>/tmp/log`) are still shell plumbing and never displayed as path text.
183
+ const noSpace = createCrtrBashToolDefinition({ command: 'crtr push -h 2>/tmp/out' });
184
+ const noSpaceRendered = noSpace.renderCall({ command: 'crtr push -h 2>/tmp/out' }, theme).render(80).join('\n');
185
+ assert.match(noSpaceRendered, /<b>push<\/b>/);
186
+ assert.doesNotMatch(noSpaceRendered, /2>/);
187
+ assert.doesNotMatch(noSpaceRendered, /tmp\/out/);
188
+ const noSpaceMid = createCrtrBashToolDefinition({ command: 'crtr node new --name foo >/tmp/log' });
189
+ const noSpaceMidRendered = noSpaceMid.renderCall({ command: 'crtr node new --name foo >/tmp/log' }, theme).render(80).join('\n');
190
+ assert.match(noSpaceMidRendered, /node new --name foo/);
191
+ assert.doesNotMatch(noSpaceMidRendered, /tmp\/log/);
192
+ });
193
+ // Contract: the call header owns the help glyph label; the collapsed result
194
+ // body contains only synthesized preview content, never a repeated header.
195
+ test('a collapsed help card never shows the help label twice (header + body)', () => {
196
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard -h' });
197
+ const header = def.renderCall({ command: 'crtr canvas dashboard -h' }, theme).render(80).join('\n');
198
+ const body = def
199
+ .renderResult({ content: [{ type: 'text', text: LEAF_SCHEMA }] }, { expanded: false }, theme, {})
200
+ .render(80)
201
+ .join('\n');
202
+ const helpLabel = new RegExp(`${HELP_ICON} crtr help`, 'g');
203
+ const headerLabelCount = (header.match(helpLabel) ?? []).length;
204
+ const bodyLabelCount = (body.match(helpLabel) ?? []).length;
205
+ assert.equal(headerLabelCount, 1);
206
+ assert.equal(bodyLabelCount, 0);
207
+ });
208
+ // REQUIREMENT: expanded (ctrl+o) is raw truth — the exact invoked command
209
+ // (redirects and all) plus the exact, unsummarized output, for both help and
210
+ // normal commands.
211
+ test('expanded view shows the original raw command (redirects included) plus the raw output', () => {
212
+ const def = createCrtrBashToolDefinition({ command: 'crtr push -h 2>&1' });
213
+ const expanded = def
214
+ .renderResult({ content: [{ type: 'text', text: LEAF_SCHEMA }] }, { expanded: true }, theme, {})
215
+ .render(80)
216
+ .join('\n');
217
+ assert.match(expanded, /\$ crtr push -h 2>&1/);
218
+ assert.match(expanded, /render the canvas as an ASCII subscription/);
219
+ assert.match(expanded, /Read-only: queries canvas\.db/);
220
+ // Normal (non-help) command: expanded still carries the raw invocation.
221
+ const normalDef = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard' });
222
+ const normalExpanded = normalDef
223
+ .renderResult({ content: [{ type: 'text', text: 'a normal-sized dashboard body' }] }, { expanded: true }, theme, {})
224
+ .render(80)
225
+ .join('\n');
226
+ assert.match(normalExpanded, /\$ crtr canvas dashboard/);
227
+ assert.match(normalExpanded, /a normal-sized dashboard body/);
228
+ });
229
+ test('a running or failed crtr -h invocation never gets the muted help status', () => {
230
+ const def = createCrtrBashToolDefinition({ command: 'crtr node new -h' });
231
+ const running = def
232
+ .renderResult({ content: [{ type: 'text', text: '' }] }, { expanded: false, isPartial: true }, theme, {})
233
+ .render(80)
234
+ .join('\n');
235
+ assert.match(running, /<warning>⟳ crtr running<\/warning>/);
236
+ });
237
+ // BUG regression (Silas, 2026-07-01): a SUCCESSFUL normal crtr call showed a
238
+ // "✓ crtr done" body status line — pure noise, since the header already names
239
+ // the command and the output is right there. Success (help or normal) carries
240
+ // no body status; only running/failed do.
241
+ test('a successful crtr call shows no "crtr done" body status line', () => {
242
+ const def = createCrtrBashToolDefinition({ command: 'crtr push update' });
243
+ const collapsed = def
244
+ .renderResult({ content: [{ type: 'text', text: 'some push output' }] }, { expanded: false }, theme, {})
245
+ .render(80)
246
+ .join('\n');
247
+ assert.doesNotMatch(collapsed, /crtr done/);
248
+ assert.match(collapsed, /some push output/);
249
+ const expanded = def
250
+ .renderResult({ content: [{ type: 'text', text: 'some push output' }] }, { expanded: true }, theme, {})
251
+ .render(80)
252
+ .join('\n');
253
+ assert.doesNotMatch(expanded, /crtr done/);
254
+ });
255
+ // Command-owned preview: a leaf declares `help.preview.suppressOutput` next
256
+ // to its own definition (e.g. canvas snapshot, node inspect snapshot —
257
+ // machine-readable dumps, not agent glances). The viewer reads this
258
+ // synchronously from the bundle-safe static registry (preview-registry.ts,
259
+ // kept honest by preview-registry-sync.test.ts) keyed by the real leaf path.
260
+ test('command-owned suppressOutput collapses a successful result, never on failure', () => {
261
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas snapshot' });
262
+ const component = def.renderResult({ content: [{ type: 'text', text: '{"nodes":[/* huge */]}' }] }, { expanded: false }, theme, {});
263
+ const collapsed = component.render(80).join('\n');
264
+ // A successful call shows no body status line at all (✓ crtr done is noise).
265
+ assert.doesNotMatch(collapsed, /crtr done/);
266
+ assert.doesNotMatch(collapsed, /huge/);
267
+ // A failed run is never collapsed, even when the leaf opts into suppressOutput.
268
+ const failedComponent = def.renderResult({ content: [{ type: 'text', text: 'huge dump on failure too' }] }, { expanded: false }, theme, { isError: true });
269
+ assert.match(failedComponent.render(80).join('\n'), /huge dump on failure too/);
270
+ });
271
+ test('command-owned suppressOutput matches the leaf name even with positional args after it', () => {
272
+ // node inspect snapshot takes a required positional id; the lookup must
273
+ // match the leaf-name prefix and ignore the argument that follows it.
274
+ const def = createCrtrBashToolDefinition({ command: 'crtr node inspect snapshot abc' });
275
+ const component = def.renderResult({ content: [{ type: 'text', text: '{"snapshot":{/* huge */}}' }] }, { expanded: false }, theme, {});
276
+ const collapsed = component.render(80).join('\n');
277
+ assert.doesNotMatch(collapsed, /crtr done/);
278
+ assert.doesNotMatch(collapsed, /huge/);
279
+ });
280
+ // Command-owned preview (Silas, 2026-07-01, option C): a `crtr memory read`
281
+ // collapsed card is a tidy frontmatter glance — `name · kind · scope` identity
282
+ // line (path dropped as noise, follow_up hint dropped) + a short content
283
+ // teaser — not the full doc body, which ctrl+o reveals.
284
+ const MEMORY_READ_OUTPUT = [
285
+ '- name: no-flag-and-defer',
286
+ '- kind: preference',
287
+ '- scope: user',
288
+ '- path: /Users/silasrhyneer/.crouter/memory/no-flag-and-defer.md',
289
+ '',
290
+ '**content:** Fix issues in the same pass you find them — never "flagged for later".',
291
+ '',
292
+ '',
293
+ '**follow_up:** Use --frontmatter on this same command to inspect the YAML frontmatter, or edit `path` directly for a body-only tweak. Browse the inventory with `crtr memory list`.',
294
+ ].join('\n');
295
+ test('a crtr memory read card previews a tidy frontmatter glance, not the raw block or body dump', () => {
296
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory read no-flag-and-defer' });
297
+ const collapsed = def
298
+ .renderResult({ content: [{ type: 'text', text: MEMORY_READ_OUTPUT }] }, { expanded: false }, theme, {})
299
+ .render(120)
300
+ .join('\n');
301
+ // Curated frontmatter identity line: name · kind · scope, path/follow_up gone.
302
+ assert.match(collapsed, /no-flag-and-defer · preference · user/);
303
+ assert.doesNotMatch(collapsed, /\/Users\//);
304
+ assert.doesNotMatch(collapsed, /follow_up/);
305
+ assert.doesNotMatch(collapsed, /Use --frontmatter/);
306
+ // A slice of the content is teased, and the raw `**content:**` marker is gone.
307
+ assert.match(collapsed, /Fix issues in the same pass/);
308
+ assert.doesNotMatch(collapsed, /\*\*content:\*\*/);
309
+ // No spurious success status line.
310
+ assert.doesNotMatch(collapsed, /crtr done/);
311
+ assert.match(collapsed, /ctrl\+o to expand/);
312
+ // A long doc body is teased, then clipped with an ellipsis — never dumped whole.
313
+ const longOutput = [
314
+ '- name: pi-frontmatter-rules',
315
+ '- kind: knowledge',
316
+ '- scope: user',
317
+ '- path: /x/pi-frontmatter-rules.md',
318
+ '',
319
+ '**content:** # Title',
320
+ 'line one',
321
+ 'line two',
322
+ 'line three',
323
+ 'line four',
324
+ 'line five',
325
+ ].join('\n');
326
+ const longCollapsed = def
327
+ .renderResult({ content: [{ type: 'text', text: longOutput }] }, { expanded: false }, theme, {})
328
+ .render(120)
329
+ .join('\n');
330
+ assert.match(longCollapsed, /pi-frontmatter-rules · knowledge · user/);
331
+ assert.match(longCollapsed, /…/);
332
+ assert.doesNotMatch(longCollapsed, /line five/);
333
+ });
334
+ // REQUIREMENT: the memory read summarizer must return null (not a blank
335
+ // summary) when its expected metadata/content markers are absent — an error
336
+ // result (missing/ambiguous doc name, etc.) has none of the `- name:`/
337
+ // `**content:**` shape, so it must fall back to the raw output.
338
+ test('a crtr memory read error output falls back to raw, never a blank summary card', () => {
339
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory read nonexistent-doc' });
340
+ const collapsed = def
341
+ .renderResult({ content: [{ type: 'text', text: 'crtr: memory read: no document found matching "nonexistent-doc"' }] }, { expanded: false }, theme, { isError: true })
342
+ .render(120)
343
+ .join('\n');
344
+ assert.match(collapsed, /no document found matching/);
345
+ });
346
+ test('an expanded crtr memory read shows the full raw output, not the frontmatter glance', () => {
347
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory read no-flag-and-defer' });
348
+ const expanded = def
349
+ .renderResult({ content: [{ type: 'text', text: MEMORY_READ_OUTPUT }] }, { expanded: true }, theme, {})
350
+ .render(120)
351
+ .join('\n');
352
+ // Raw truth: the path, the content marker, and the follow_up hint are all present.
353
+ assert.match(expanded, /\$ crtr memory read no-flag-and-defer/);
354
+ assert.match(expanded, /\.crouter\/memory\/no-flag-and-defer\.md/);
355
+ assert.match(expanded, /\*\*follow_up:\*\*/);
356
+ });
357
+ const MEMORY_LINT_CLEAN_OUTPUT = [
358
+ '- checked: 261',
359
+ '- corpora: {"memory_stores":261}',
360
+ '',
361
+ 'Corpus green — zero invalid frontmatter docs.',
362
+ '',
363
+ '0 findings.',
364
+ ].join('\n');
365
+ const MEMORY_LINT_FINDINGS_OUTPUT = [
366
+ 'crtr: memory lint: /tmp/lint-test/.crouter/memory/bad-doc.md: invalid kind: "bogus" (expected knowledge|preference)',
367
+ 'crtr: memory lint: /tmp/lint-test/.crouter/memory/bad-doc2.md: missing `when-and-why-to-read`: one read-routing line',
368
+ '<error code="error">',
369
+ 'memory lint: 2 finding(s) across 229 files',
370
+ 'Next: Fix each doc (quote YAML values containing `: `; use a valid kind/rung/gate), then re-run `crtr memory lint`.',
371
+ '</error>',
372
+ ].join('\n');
373
+ test('a clean crtr memory lint collapses to PASS and docs checked, with semantic tones', () => {
374
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory lint' });
375
+ const collapsed = def
376
+ .renderResult({ content: [{ type: 'text', text: MEMORY_LINT_CLEAN_OUTPUT }] }, { expanded: false }, theme, {})
377
+ .render(120)
378
+ .join('\n');
379
+ assert.match(collapsed, /<success>PASS<\/success>/);
380
+ assert.match(collapsed, /<muted>261 docs checked<\/muted>/);
381
+ assert.doesNotMatch(collapsed, /- checked:/);
382
+ assert.doesNotMatch(collapsed, /- corpora:/);
383
+ assert.doesNotMatch(collapsed, /0 findings\./);
384
+ assert.match(collapsed, /ctrl\+o to expand/);
385
+ const expanded = def
386
+ .renderResult({ content: [{ type: 'text', text: MEMORY_LINT_CLEAN_OUTPUT }] }, { expanded: true }, theme, {})
387
+ .render(120)
388
+ .join('\n');
389
+ assert.match(expanded, /checked: 261/);
390
+ assert.match(expanded, /corpora: \{"memory_stores":261\}/);
391
+ assert.match(expanded, /0 findings\./);
392
+ });
393
+ // REQUIREMENT: a real failed `crtr memory lint` (delivered to the renderer as
394
+ // `{ isError: true }` — see render/chat-view.ts) must still collapse to the
395
+ // command-owned findings summary, not fall through to the raw failed output;
396
+ // only a command with no summarizer (or a shape neither summarizer branch
397
+ // recognizes) stays raw on failure.
398
+ test('a crtr memory lint with findings collapses to a findings count and warnings even on the real failed-command path', () => {
399
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory lint' });
400
+ const collapsed = def
401
+ .renderResult({ content: [{ type: 'text', text: MEMORY_LINT_FINDINGS_OUTPUT }] }, { expanded: false }, theme, { isError: true })
402
+ .render(120)
403
+ .join('\n');
404
+ assert.match(collapsed, /<error>2 findings<\/error>/);
405
+ assert.match(collapsed, /<warning>[^<]*invalid kind: "bogus"[^<]*<\/warning>/);
406
+ assert.match(collapsed, /<warning>[^<]*missing `when-and-why-to-read`[^<]*<\/warning>/);
407
+ assert.match(collapsed, /<muted>229 docs checked<\/muted>/);
408
+ assert.doesNotMatch(collapsed, /PASS/);
409
+ // No raw error block/XML leaks into the collapsed summary.
410
+ assert.doesNotMatch(collapsed, /code="error"/);
411
+ assert.doesNotMatch(collapsed, /Next: Fix each doc/);
412
+ });
413
+ // Help must look like help at the call header itself, not only once the
414
+ // (possibly collapsed) result renders.
415
+ test('renderCall shows a help-specific header for a -h/--help invocation, no bash chrome', () => {
416
+ const def = createCrtrBashToolDefinition({ command: 'crtr node config -h' });
417
+ const rendered = def.renderCall({ command: 'crtr node config -h' }, theme).render(80).join('\n');
418
+ assert.equal(rendered.trimEnd().split('\n').length, 1);
419
+ assert.match(rendered, new RegExp(HELP_ICON));
420
+ assert.match(rendered, /crtr help/);
421
+ assert.doesNotMatch(rendered, /via bash/);
422
+ assert.doesNotMatch(rendered, /\$ crtr/);
423
+ assert.doesNotMatch(rendered, /-h/);
424
+ assert.match(rendered, /node config/);
425
+ });
426
+ // Table-driven header coverage across every mapped root family (rule 12: real
427
+ // Nerd Font glyphs, never the generic ◆) — includes `memory lint` (the
428
+ // motivating case for the memory-lint summarizer above), not just `canvas`/
429
+ // `node`.
430
+ test('renderCall uses a mapped Nerd Font glyph and one line for every mapped root family, never the generic ◆', () => {
431
+ const cases = [
432
+ { command: 'crtr memory lint', iconTokens: ['memory', 'lint'], path: 'memory lint' },
433
+ { command: 'crtr canvas dashboard', iconTokens: ['canvas', 'dashboard'], path: 'canvas dashboard' },
434
+ { command: 'crtr node yield', iconTokens: ['node', 'yield'], path: 'node yield' },
435
+ { command: 'crtr human ask', iconTokens: ['human', 'ask'], path: 'human ask' },
436
+ { command: 'crtr node config set foo bar', iconTokens: ['node', 'config'], path: 'node config set foo bar' },
437
+ { command: 'crtr pkg plugin list', iconTokens: ['pkg', 'plugin', 'list'], path: 'pkg plugin list' },
438
+ { command: 'crtr push update', iconTokens: ['push', 'update'], path: 'push update' },
439
+ { command: 'crtr search web', iconTokens: ['search', 'web'], path: 'search web' },
440
+ { command: 'crtr surface view list', iconTokens: ['surface', 'view', 'list'], path: 'surface view list' },
441
+ { command: 'crtr sys doctor', iconTokens: ['sys', 'doctor'], path: 'sys doctor' },
442
+ ];
443
+ for (const { command, iconTokens, path } of cases) {
444
+ const def = createCrtrBashToolDefinition({ command });
445
+ // Width 200 (not 80): this test's fake theme wraps each styled span in
446
+ // literal `<tag>...</tag>` text (not real ANSI escapes the wrapper would
447
+ // strip for width purposes), so the visible-width accounting used by the
448
+ // real Text component's word-wrap counts that markup as content width —
449
+ // a generous width keeps every case here well clear of an unrelated wrap.
450
+ const rendered = def.renderCall({ command }, theme).render(200).join('\n');
451
+ assert.equal(rendered.trimEnd().split('\n').length, 1, `expected one line for ${command}`);
452
+ assert.match(rendered, new RegExp(iconForPath(iconTokens)), `expected the ${iconTokens.join(' ')} glyph in ${command}`);
453
+ assert.match(rendered, /crtr/, `expected "crtr" in ${command}`);
454
+ assert.match(rendered, new RegExp(path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')), `expected path "${path}" on the same line`);
455
+ assert.doesNotMatch(rendered, /◆/, `unexpected generic diamond for ${command}`);
456
+ }
457
+ });
458
+ test('renderCall for a normal invocation previews the crtr path, not a raw bash echo', () => {
459
+ const def = createCrtrBashToolDefinition({ command: 'crtr node config set foo bar' });
460
+ const rendered = def.renderCall({ command: 'crtr node config set foo bar' }, theme).render(200).join('\n');
461
+ assert.equal(rendered.trimEnd().split('\n').length, 1);
462
+ assert.match(rendered, new RegExp(iconForPath(['node', 'config'])));
463
+ assert.match(rendered, /crtr/);
464
+ assert.match(rendered, /node config set foo bar/);
465
+ assert.doesNotMatch(rendered, /◆/);
466
+ assert.doesNotMatch(rendered, /via bash/);
467
+ assert.doesNotMatch(rendered, /\$ crtr/);
468
+ });
469
+ test('a leaf that does not declare suppressOutput is never collapsed', () => {
470
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard' });
471
+ const component = def.renderResult({ content: [{ type: 'text', text: 'a normal-sized dashboard body' }] }, { expanded: false }, theme, {});
472
+ assert.match(component.render(80).join('\n'), /a normal-sized dashboard body/);
473
+ });
474
+ test('expanded crtr output clamps long single lines to the terminal width', () => {
475
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard' });
476
+ const longLine = 'x'.repeat(442);
477
+ const lines = def
478
+ .renderResult({ content: [{ type: 'text', text: longLine }] }, { expanded: true }, theme, {})
479
+ .render(70);
480
+ assert.ok(lines.length > 0);
481
+ for (const line of lines) {
482
+ assert.ok(visibleWidth(line) <= 70, `line exceeded width: ${visibleWidth(line)} > 70`);
483
+ }
484
+ });
485
+ test('collapsed crtr output clamps all rendered chrome to the terminal width', () => {
486
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard' });
487
+ const longLine = 'y'.repeat(442);
488
+ const lines = def
489
+ .renderResult({ content: [{ type: 'text', text: longLine }] }, { expanded: false }, theme, {})
490
+ .render(70);
491
+ assert.ok(lines.length > 0);
492
+ for (const line of lines) {
493
+ assert.ok(visibleWidth(line) <= 70, `line exceeded width: ${visibleWidth(line)} > 70`);
494
+ }
495
+ });
496
+ const WIDE_GENERIC_TABLE_OUTPUT = [
497
+ '24 plugins:',
498
+ '',
499
+ '| name | version | description | status |',
500
+ '| --- | --- | --- | --- |',
501
+ ...Array.from({ length: 24 }, (_, i) => `| plugin-${String(i).padStart(2, '0')} | 1.0.${i} | This is a deliberately over-wide description cell that used to wrap the collapsed card mid-cell for row ${i} | ${i % 2 === 0 ? 'enabled' : 'disabled'} |`),
502
+ ].join('\n');
503
+ test('generic collapsed fallback renders wide GFM tables aligned, clipped, and row-capped instead of raw pipe rows', () => {
504
+ const def = createCrtrBashToolDefinition({ command: 'crtr surface view run catalog' });
505
+ const rendered = def
506
+ .renderResult({ content: [{ type: 'text', text: WIDE_GENERIC_TABLE_OUTPUT }] }, { expanded: false }, plainTheme, {})
507
+ .render(58)
508
+ .join('\n');
509
+ assert.doesNotMatch(rendered, /\|/);
510
+ assert.match(rendered, /plugin-00\s+1\.0\.0\s+.*…/);
511
+ assert.match(rendered, /more lines/);
512
+ assert.doesNotMatch(rendered, /plugin-23/);
513
+ assert.ok(rendered.split('\n').length <= 20, `expected <=20 lines, got ${rendered.split('\n').length}`);
514
+ const row0 = rendered.split('\n').find((line) => line.includes('plugin-00')) ?? '';
515
+ const row1 = rendered.split('\n').find((line) => line.includes('plugin-01')) ?? '';
516
+ assert.notEqual(row0, '');
517
+ assert.notEqual(row1, '');
518
+ assert.equal(row0.indexOf('1.0.0'), row1.indexOf('1.0.1'));
519
+ for (const line of rendered.split('\n')) {
520
+ assert.ok(visibleWidth(line) <= 58, `line exceeded width: ${visibleWidth(line)} > 58: ${line}`);
521
+ }
522
+ });
523
+ const HEADERLESS_TABLE_TAIL_OUTPUT = [
524
+ '| mr2iy5tw-a1f5e1f0 | batch-a-implementation | /Users/silasrhyneer/Code/cli/crouter | active |',
525
+ '| mr147q9d-c7681b04 | initial-session-setup | /Users/silasrhyneer/Code/cli/crouter | idle |',
526
+ '| mr2ejzaw-6f70e858 | preview-roadmap | /Users/silasrhyneer/Code/cli/crouter | done |',
527
+ ].join('\n');
528
+ test('generic collapsed fallback aligns a header-less truncated table tail by column count', () => {
529
+ const def = createCrtrBashToolDefinition({ command: 'crtr surface view run catalog' });
530
+ const rendered = def
531
+ .renderResult({ content: [{ type: 'text', text: HEADERLESS_TABLE_TAIL_OUTPUT }] }, { expanded: false }, plainTheme, {})
532
+ .render(64)
533
+ .join('\n');
534
+ assert.doesNotMatch(rendered, /\|/);
535
+ assert.match(rendered, /batch-a-implemen/);
536
+ const rows = rendered.split('\n').filter((line) => line.includes('mr')).map(stripAnsi);
537
+ assert.equal(rows.length, 3);
538
+ assert.equal(rows[0].indexOf('/Users'), rows[1].indexOf('/Users'));
539
+ assert.equal(rows[1].indexOf('/Users'), rows[2].indexOf('/Users'));
540
+ });
541
+ test('generic collapsed fallback renders the pi truncation marker as one muted line', () => {
542
+ const def = createCrtrBashToolDefinition({ command: 'crtr surface view run catalog' });
543
+ const marker = '[Showing lines 951-1000 of 1000 (50.0KB limit). Full output: /tmp/pi-bash-output.log]';
544
+ const rendered = def
545
+ .renderResult({ content: [{ type: 'text', text: `last retained line\n${marker}` }] }, { expanded: false }, theme, {})
546
+ .render(240)
547
+ .join('\n');
548
+ assert.match(rendered, /<muted>\[Showing lines 951-1000 of 1000 \(50\.0KB limit\)\. Full output: \/tmp\/pi-bash-output\.log\]<\/muted>/);
549
+ assert.equal((rendered.match(/Showing lines/g) ?? []).length, 1);
550
+ });
551
+ const NO_EDGE_PIPE_TABLE_OUTPUT = [
552
+ 'name | version | status',
553
+ '--- | --- | ---',
554
+ 'alpha | 1.0.0 | enabled',
555
+ 'beta | 2.1.0 | disabled',
556
+ ].join('\n');
557
+ test('generic collapsed fallback aligns a GFM table whose rows omit both outer pipes', () => {
558
+ const def = createCrtrBashToolDefinition({ command: 'crtr surface view run catalog' });
559
+ const rendered = def
560
+ .renderResult({ content: [{ type: 'text', text: NO_EDGE_PIPE_TABLE_OUTPUT }] }, { expanded: false }, plainTheme, {})
561
+ .render(60)
562
+ .join('\n');
563
+ assert.doesNotMatch(rendered, /\|/);
564
+ assert.doesNotMatch(rendered, /---/);
565
+ const rows = rendered.split('\n').filter((line) => line.trim() !== '');
566
+ const alphaRow = rows.find((line) => line.includes('alpha')) ?? '';
567
+ const betaRow = rows.find((line) => line.includes('beta')) ?? '';
568
+ assert.notEqual(alphaRow, '');
569
+ assert.notEqual(betaRow, '');
570
+ assert.equal(alphaRow.indexOf('1.0.0'), betaRow.indexOf('2.1.0'));
571
+ });
572
+ test('a stray line containing a single literal pipe is not mistaken for a table row', () => {
573
+ const def = createCrtrBashToolDefinition({ command: 'crtr surface view run catalog' });
574
+ const rendered = def
575
+ .renderResult({ content: [{ type: 'text', text: 'warning: use x | y instead' }] }, { expanded: false }, plainTheme, {})
576
+ .render(60)
577
+ .join('\n');
578
+ assert.match(rendered, /warning: use x \| y instead/);
579
+ });
580
+ test('icon lookup uses per-leaf glyphs before family glyphs, with help unchanged', () => {
581
+ assert.equal(iconForPath(['canvas', 'dashboard']), String.fromCodePoint(0xf0e4));
582
+ assert.notEqual(iconForPath(['canvas', 'dashboard']), iconForPath(['canvas']));
583
+ assert.equal(iconForPath(['node', 'inspect', 'list']), String.fromCodePoint(0xf03a));
584
+ assert.notEqual(iconForPath(['node', 'inspect', 'list']), iconForPath(['node']));
585
+ assert.equal(iconForPath(['sys', 'doctor']), String.fromCodePoint(0xf0f1));
586
+ assert.equal(HELP_ICON, String.fromCodePoint(0xf059));
587
+ });
588
+ // ---------------------------------------------------------------------------
589
+ // canvas/node runtime cockpit summaries (first non-memory batch, Silas's
590
+ // 2026-07-01 reframe: collapsed cards are computed status digests, not
591
+ // decorated stdout). Fixtures below are literal renderResult() output shapes
592
+ // (core/render.ts: a `- field: N` scalar bullet, an `N <label>:` count
593
+ // lead-in + GFM table for an array of objects) — not the live command tree,
594
+ // so these stay independent of what actually runs on a real canvas.
595
+ // ---------------------------------------------------------------------------
596
+ const DASHBOARD_OUTPUT = [
597
+ '- nodes: 4',
598
+ '',
599
+ '● root-node [developer/orchestrator] ctx 5k',
600
+ '├─ ✓ child-a ...',
601
+ '└─ ○ child-b ...',
602
+ '',
603
+ '4 rows:',
604
+ '',
605
+ '| node_id | name | status | kind | mode | ctx_tokens | asks | cwd | created |',
606
+ '| --- | --- | --- | --- | --- | --- | --- | --- | --- |',
607
+ '| n1 | root-node | active | developer | orchestrator | 5000 | 0 | /Users/x/proj | 2026-01-01T00:00:00.000Z |',
608
+ '| n2 | child-a | active | developer | base | 12000 | 3 | /Users/x/proj | 2026-01-01T00:00:00.000Z |',
609
+ '| n3 | child-b | done | advisor | base | 8000 | 0 | /Users/x/proj | 2026-01-01T00:00:00.000Z |',
610
+ '| n4 | child-c | idle | reviewer | base | 3000 | 0 | /Users/x/proj | 2026-01-01T00:00:00.000Z |',
611
+ ].join('\n');
612
+ test('a crtr canvas dashboard card collapses to a status-count digest, not the raw tree/table', () => {
613
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas dashboard' });
614
+ const collapsed = def
615
+ .renderResult({ content: [{ type: 'text', text: DASHBOARD_OUTPUT }] }, { expanded: false }, theme, {})
616
+ .render(120)
617
+ .join('\n');
618
+ assert.match(collapsed, /2 active/);
619
+ assert.match(collapsed, /1 idle/);
620
+ assert.match(collapsed, /1 done/);
621
+ assert.match(collapsed, /<muted>largest ctx: 12k tokens<\/muted>/);
622
+ assert.match(collapsed, /<warning>3 pending asks<\/warning>/);
623
+ assert.doesNotMatch(collapsed, /\| ---/);
624
+ assert.doesNotMatch(collapsed, /node_id/);
625
+ assert.doesNotMatch(collapsed, /crtr done/);
626
+ assert.match(collapsed, /ctrl\+o to expand/);
627
+ const expanded = def
628
+ .renderResult({ content: [{ type: 'text', text: DASHBOARD_OUTPUT }] }, { expanded: true }, theme, {})
629
+ .render(120)
630
+ .join('\n');
631
+ assert.match(expanded, /\$ crtr canvas dashboard/);
632
+ assert.match(expanded, /\| node_id \| name \|/);
633
+ assert.match(expanded, /root-node \[developer\/orchestrator\]/);
634
+ });
635
+ const NODE_LIST_OUTPUT = [
636
+ '4 nodes:',
637
+ '',
638
+ '| node_id | name | status | kind | mode | lifecycle | cwd | created | hanging |',
639
+ '| --- | --- | --- | --- | --- | --- | --- | --- | --- |',
640
+ '| n1 | alpha | active | developer | orchestrator | terminal | /a | 2026-01-01T00:00:00.000Z | none |',
641
+ '| n2 | beta | active | developer | base | terminal | /a | 2026-01-01T00:00:00.000Z | none |',
642
+ '| n3 | gamma | done | advisor | base | terminal | /a | 2026-01-01T00:00:00.000Z | none |',
643
+ '| n4 | delta | idle | reviewer | base | resident | /a | 2026-01-01T00:00:00.000Z | none |',
644
+ ].join('\n');
645
+ test('a crtr node inspect list card collapses to status + kind digests, not the raw table', () => {
646
+ const def = createCrtrBashToolDefinition({ command: 'crtr node inspect list' });
647
+ const collapsed = def
648
+ .renderResult({ content: [{ type: 'text', text: NODE_LIST_OUTPUT }] }, { expanded: false }, theme, {})
649
+ .render(120)
650
+ .join('\n');
651
+ assert.match(collapsed, /2 active/);
652
+ assert.match(collapsed, /1 idle/);
653
+ assert.match(collapsed, /1 done/);
654
+ assert.match(collapsed, /<muted>kinds: developer×2, advisor×1, reviewer×1<\/muted>/);
655
+ assert.doesNotMatch(collapsed, /\| ---/);
656
+ assert.doesNotMatch(collapsed, /node_id/);
657
+ assert.doesNotMatch(collapsed, /crtr done/);
658
+ assert.match(collapsed, /ctrl\+o to expand/);
659
+ });
660
+ test('a crtr canvas attention count card renders a computed health tone, error when pending, success when clear', () => {
661
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas attention count' });
662
+ const pending = def
663
+ .renderResult({ content: [{ type: 'text', text: '- count: 14' }] }, { expanded: false }, theme, {})
664
+ .render(120)
665
+ .join('\n');
666
+ assert.match(pending, /<error>14 pending asks<\/error>/);
667
+ assert.match(pending, /ctrl\+o to expand/);
668
+ const clear = def
669
+ .renderResult({ content: [{ type: 'text', text: '- count: 0' }] }, { expanded: false }, theme, {})
670
+ .render(120)
671
+ .join('\n');
672
+ assert.match(clear, /<success>PASS · no pending asks<\/success>/);
673
+ assert.doesNotMatch(clear, /0 pending asks/);
674
+ });
675
+ const ATTENTION_LIST_OUTPUT = [
676
+ '- total: 14',
677
+ '',
678
+ '5 items:',
679
+ '',
680
+ '| node_id | name | cwd | count |',
681
+ '| --- | --- | --- | --- |',
682
+ '| mq3geac4-9b947921 | general | /Users/silasrhyneer/Code/alaria-map-site | 7 |',
683
+ '| mqa7c632-24f0e384 | general | /Users/silasrhyneer/Code/cli/crouter | 3 |',
684
+ '| mqa9w9qy-e1cafda1 | general | /Users/silasrhyneer/Code/godot/StarTheory2 | 2 |',
685
+ '| mqt6lz47-09daf181 | developer | /Users/silasrhyneer/Code/godot/StarTheory2-worktrees/escape-pod-selection | 1 |',
686
+ '| mr0v8vxi-580c7572 | general | /Users/silasrhyneer/Code/northlight | 1 |',
687
+ ].join('\n');
688
+ test('a crtr canvas attention list card collapses to total/hottest/digest, not the raw table', () => {
689
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas attention list' });
690
+ const collapsed = def
691
+ .renderResult({ content: [{ type: 'text', text: ATTENTION_LIST_OUTPUT }] }, { expanded: false }, theme, {})
692
+ .render(120)
693
+ .join('\n');
694
+ assert.match(collapsed, /14 total · 5 cwds/);
695
+ assert.match(collapsed, /<warning>hottest: alaria-map-site \(7\)<\/warning>/);
696
+ assert.match(collapsed, /<muted>other cwds: [^<]*crouter[^<]*<\/muted>/);
697
+ assert.doesNotMatch(collapsed, /\| ---/);
698
+ assert.doesNotMatch(collapsed, /node_id/);
699
+ assert.match(collapsed, /ctrl\+o to expand/);
700
+ const empty = def
701
+ .renderResult({ content: [{ type: 'text', text: ['- total: 0', '', '0 items.'].join('\n') }] }, { expanded: false }, theme, {})
702
+ .render(120)
703
+ .join('\n');
704
+ assert.match(empty, /<success>PASS · no pending asks<\/success>/);
705
+ });
706
+ // Command-owned preview: `node inspect show` inlines a full node meta object
707
+ // (system prompt + every telemetry field) with no useful human-glance slice —
708
+ // same rationale as canvas snapshot / node inspect snapshot, mirrored in the
709
+ // bundle-safe SUPPRESS_OUTPUT_LEAVES registry.
710
+ test('node inspect show is command-owned suppressOutput, never on failure', () => {
711
+ const def = createCrtrBashToolDefinition({ command: 'crtr node inspect show abc' });
712
+ const collapsed = def.renderResult({ content: [{ type: 'text', text: '{"node":{/* huge */}}' }] }, { expanded: false }, theme, {});
713
+ const rendered = collapsed.render(80).join('\n');
714
+ assert.doesNotMatch(rendered, /crtr done/);
715
+ assert.doesNotMatch(rendered, /huge/);
716
+ assert.match(rendered, /suppressed — ctrl\+o to expand/);
717
+ const failed = def.renderResult({ content: [{ type: 'text', text: 'huge dump on failure too' }] }, { expanded: false }, theme, { isError: true });
718
+ assert.match(failed.render(80).join('\n'), /huge dump on failure too/);
719
+ });
720
+ // ---------------------------------------------------------------------------
721
+ // Batch B: canvas/node/push runtime cockpit summaries (Silas's
722
+ // 2026-07-01 reframe continued). Fixtures below are literal render() output
723
+ // shapes copied from the real command source (see preview-registry.ts's
724
+ // per-summarizer doc comments for the exact file:line), not the live command
725
+ // tree — these stay independent of what actually runs on a real canvas.
726
+ // ---------------------------------------------------------------------------
727
+ test('a crtr canvas attention map card collapses to a hottest-id digest, PASS when all zero', () => {
728
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas attention map --view mq1' });
729
+ const collapsed = def
730
+ .renderResult({ content: [{ type: 'text', text: '- counts: {"n1":0,"n2":3,"n3":5}' }] }, { expanded: false }, theme, {})
731
+ .render(120)
732
+ .join('\n');
733
+ assert.match(collapsed, /8 asks across 2 nodes/);
734
+ assert.match(collapsed, /<warning>hottest: n3 \(5\)<\/warning>/);
735
+ const zero = def
736
+ .renderResult({ content: [{ type: 'text', text: '- counts: {"n1":0,"n2":0}' }] }, { expanded: false }, theme, {})
737
+ .render(120)
738
+ .join('\n');
739
+ assert.match(zero, /<success>PASS · no pending asks<\/success>/);
740
+ const zeroExpanded = def
741
+ .renderResult({ content: [{ type: 'text', text: '- counts: {"n1":0,"n2":0}' }] }, { expanded: true }, theme, {})
742
+ .render(120)
743
+ .join('\n');
744
+ assert.match(zeroExpanded, /counts: \{"n1":0,"n2":0\}/);
745
+ const expanded = def
746
+ .renderResult({ content: [{ type: 'text', text: '- counts: {"n1":0,"n2":3,"n3":5}' }] }, { expanded: true }, theme, {})
747
+ .render(120)
748
+ .join('\n');
749
+ assert.match(expanded, /counts: \{"n1":0,"n2":3,"n3":5\}/);
750
+ });
751
+ test('a crtr node lifecycle revive card collapses to a kicked/revived status line, argv-recovered id', () => {
752
+ const kickedDef = createCrtrBashToolDefinition({ command: 'crtr node lifecycle revive mq2jpqz5-87fa626e --now' });
753
+ const kicked = kickedDef
754
+ .renderResult({ content: [{ type: 'text', text: ['- session: mysession', '- kicked: true', '', 'Sent SIGTERM to worker-a (mq2jpqz5-87fa626e, pid 456).'].join('\n') }] }, { expanded: false }, theme, {})
755
+ .render(120)
756
+ .join('\n');
757
+ assert.match(kicked, /<warning>kicked — daemon resumes in ~20s<\/warning>/);
758
+ const kickedExpanded = kickedDef
759
+ .renderResult({ content: [{ type: 'text', text: ['- session: mysession', '- kicked: true', '', 'Sent SIGTERM to worker-a (mq2jpqz5-87fa626e, pid 456).'].join('\n') }] }, { expanded: true }, theme, {})
760
+ .render(120)
761
+ .join('\n');
762
+ assert.match(kickedExpanded, /Sent SIGTERM to worker-a \(mq2jpqz5-87fa626e, pid 456\)\./);
763
+ const revivedDef = createCrtrBashToolDefinition({ command: 'crtr node lifecycle revive mq2jpqz5-87fa626e' });
764
+ const revived = revivedDef
765
+ .renderResult({ content: [{ type: 'text', text: ['- session: mysession', '- resumed: true', '- ready: true'].join('\n') }] }, { expanded: false }, theme, {})
766
+ .render(120)
767
+ .join('\n');
768
+ assert.match(revived, /<success>revived mq2jpqz5-87fa626e<\/success>/);
769
+ assert.doesNotMatch(revived, /not yet attachable/);
770
+ const revivedExpanded = revivedDef
771
+ .renderResult({ content: [{ type: 'text', text: ['- session: mysession', '- resumed: true', '- ready: true'].join('\n') }] }, { expanded: true }, theme, {})
772
+ .render(120)
773
+ .join('\n');
774
+ assert.match(revivedExpanded, /session: mysession/);
775
+ const notReady = revivedDef
776
+ .renderResult({ content: [{ type: 'text', text: ['- resumed: false', '- ready: false'].join('\n') }] }, { expanded: false }, theme, {})
777
+ .render(120)
778
+ .join('\n');
779
+ assert.match(notReady, /<warning>not yet attachable \(socket not ready\)<\/warning>/);
780
+ const notReadyExpanded = revivedDef
781
+ .renderResult({ content: [{ type: 'text', text: ['- resumed: false', '- ready: false'].join('\n') }] }, { expanded: true }, theme, {})
782
+ .render(120)
783
+ .join('\n');
784
+ assert.match(notReadyExpanded, /resumed: false/);
785
+ assert.match(notReadyExpanded, /ready: false/);
786
+ // `canvas revive --all` carries a `- mode:` bullet; no summarizer is
787
+ // registered for it (rare admin path) — falls through to generic
788
+ // truncation, raw `mode` text survives.
789
+ const allDef = createCrtrBashToolDefinition({ command: 'crtr canvas revive --all' });
790
+ const allPreview = allDef
791
+ .renderResult({ content: [{ type: 'text', text: '- mode: preview\n- candidates: mq1' }] }, { expanded: false }, theme, {})
792
+ .render(120)
793
+ .join('\n');
794
+ assert.match(allPreview, /mode: preview/);
795
+ const allPreviewExpanded = revivedDef
796
+ .renderResult({ content: [{ type: 'text', text: '- mode: preview\n- candidates: mq1' }] }, { expanded: true }, theme, {})
797
+ .render(120)
798
+ .join('\n');
799
+ assert.match(allPreviewExpanded, /candidates: mq1/);
800
+ });
801
+ const HISTORY_SEARCH_HITS_OUTPUT = [
802
+ '3 of 10 hits:',
803
+ '',
804
+ '| ref | node | kind | source | ts | snippet |',
805
+ '| --- | --- | --- | --- | --- | --- |',
806
+ '| n1:reports/a.md | alpha (n1) | developer | report:final | 2026-01-01T00:00:00.000Z | did a thing |',
807
+ '| n2:reports/b.md | beta (n2) | developer | doc | 2026-01-02T00:00:00.000Z | did another |',
808
+ '| n3:reports/c.md | gamma (n3) | advisor | report:update | 2026-01-03T00:00:00.000Z | did a third |',
809
+ '',
810
+ '- next_cursor: abc123',
811
+ '- total: 10',
812
+ '',
813
+ 'Read a hit with `canvas history read <ref>`; narrow with `canvas history search -h`.',
814
+ ].join('\n');
815
+ test('a crtr canvas history search card collapses to a hit count + top rows, not the raw table', () => {
816
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas history search foo' });
817
+ const collapsed = def
818
+ .renderResult({ content: [{ type: 'text', text: HISTORY_SEARCH_HITS_OUTPUT }] }, { expanded: false }, theme, {})
819
+ .render(140)
820
+ .join('\n');
821
+ assert.match(collapsed, /10 hits/);
822
+ assert.match(collapsed, /<muted>alpha \(n1\) · developer · 2026-01-01T00:00:00\.000Z<\/muted>/);
823
+ assert.doesNotMatch(collapsed, /\| ref \|/);
824
+ const expanded = def
825
+ .renderResult({ content: [{ type: 'text', text: HISTORY_SEARCH_HITS_OUTPUT }] }, { expanded: true }, theme, {})
826
+ .render(140)
827
+ .join('\n');
828
+ assert.match(expanded, /\| ref \| node \| kind \| source \| ts \| snippet \|/);
829
+ assert.match(expanded, /did a thing/);
830
+ const zero = def
831
+ .renderResult({ content: [{ type: 'text', text: ['0 hits.', '', '- next_cursor: null\n- total: 0', 'Read a hit…'].join('\n\n') }] }, { expanded: false }, theme, {})
832
+ .render(120)
833
+ .join('\n');
834
+ assert.match(zero, /<muted>0 hits<\/muted>/);
835
+ const zeroExpanded = def
836
+ .renderResult({ content: [{ type: 'text', text: ['0 hits.', '', '- next_cursor: null\n- total: 0', 'Read a hit…'].join('\n\n') }] }, { expanded: true }, theme, {})
837
+ .render(120)
838
+ .join('\n');
839
+ assert.match(zeroExpanded, /total: 0/);
840
+ // --full mode shares the same `N of M hits:` lead-in but has no table —
841
+ // deliberately skipped (null), raw survives.
842
+ const full = def
843
+ .renderResult({ content: [{ type: 'text', text: '1 of 1 hits:\n\n### n1:reports/a.md\n- node: alpha (n1) | kind: developer | source: doc | ts: 2026-01-01\n\nfull body here' }] }, { expanded: false }, theme, {})
844
+ .render(120)
845
+ .join('\n');
846
+ assert.match(full, /full body here/);
847
+ const fullExpanded = def
848
+ .renderResult({ content: [{ type: 'text', text: '1 of 1 hits:\n\n### n1:reports/a.md\n- node: alpha (n1) | kind: developer | source: doc | ts: 2026-01-01\n\nfull body here' }] }, { expanded: true }, theme, {})
849
+ .render(120)
850
+ .join('\n');
851
+ assert.match(fullExpanded, /full body here/);
852
+ // Lead-in says 3 displayed hits, but the table only has 2 rows — a
853
+ // truncated/mismatched render is a shape mismatch, not a partial summary:
854
+ // skipped (null), raw survives even collapsed.
855
+ const truncated = def
856
+ .renderResult({
857
+ content: [
858
+ {
859
+ type: 'text',
860
+ text: [
861
+ '3 of 10 hits:',
862
+ '',
863
+ '| ref | node | kind | source | ts | snippet |',
864
+ '| --- | --- | --- | --- | --- | --- |',
865
+ '| n1:reports/a.md | alpha (n1) | developer | report:final | 2026-01-01T00:00:00.000Z | did a thing |',
866
+ '| n2:reports/b.md | beta (n2) | developer | doc | 2026-01-02T00:00:00.000Z | did another |',
867
+ '',
868
+ '- next_cursor: abc123',
869
+ '- total: 10',
870
+ ].join('\n'),
871
+ },
872
+ ],
873
+ }, { expanded: false }, theme, {})
874
+ .render(140)
875
+ .join('\n');
876
+ assert.match(truncated, /3 of 10 hits:/);
877
+ assert.doesNotMatch(truncated, /<muted>alpha \(n1\) · developer/);
878
+ });
879
+ const HISTORY_READ_OUTPUT = [
880
+ 'alpha (n1) | source: report:final | ts: 2026-01-01T00:00:00.000Z | ref: n1:reports/a.md',
881
+ '',
882
+ 'Line one of body.',
883
+ 'Line two of body.',
884
+ 'Line three of body.',
885
+ 'Line four of body.',
886
+ ].join('\n');
887
+ test('a crtr canvas history read card previews an identity line + content teaser', () => {
888
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas history read n1:reports/a.md' });
889
+ const collapsed = def
890
+ .renderResult({ content: [{ type: 'text', text: HISTORY_READ_OUTPUT }] }, { expanded: false }, theme, {})
891
+ .render(120)
892
+ .join('\n');
893
+ assert.match(collapsed, /alpha \(n1\) · report:final · 2026-01-01T00:00:00\.000Z/);
894
+ assert.match(collapsed, /Line one of body\./);
895
+ assert.match(collapsed, /…/);
896
+ assert.doesNotMatch(collapsed, /Line four of body\./);
897
+ const expanded = def
898
+ .renderResult({ content: [{ type: 'text', text: HISTORY_READ_OUTPUT }] }, { expanded: true }, theme, {})
899
+ .render(120)
900
+ .join('\n');
901
+ assert.match(expanded, /Line four of body\./);
902
+ });
903
+ const HISTORY_SHOW_OUTPUT = [
904
+ 'node: alpha (n1)',
905
+ '',
906
+ '4 artifacts:',
907
+ '',
908
+ '| ref | source | ts | detail |',
909
+ '| --- | --- | --- | --- |',
910
+ '| n1:reports/a.md | report:final | 2026-01-01T00:00:00.000Z | Final report (120B) |',
911
+ '| n1:reports/b.md | report:update | 2026-01-02T00:00:00.000Z | Update (80B) |',
912
+ '| n1:docs/design.md | doc | 2026-01-03T00:00:00.000Z | Design doc |',
913
+ '| n1:roadmap.md | roadmap | 2026-01-04T00:00:00.000Z | Roadmap |',
914
+ '',
915
+ 'Read one with `canvas history read <ref>`; reopen the node with `node lifecycle revive n1`.',
916
+ ].join('\n');
917
+ test('a crtr node inspect artifacts card collapses to a node line + type-count digest, not the raw table', () => {
918
+ const def = createCrtrBashToolDefinition({ command: 'crtr node inspect artifacts n1' });
919
+ const collapsed = def
920
+ .renderResult({ content: [{ type: 'text', text: HISTORY_SHOW_OUTPUT }] }, { expanded: false }, theme, {})
921
+ .render(120)
922
+ .join('\n');
923
+ assert.match(collapsed, /4 artifacts/);
924
+ assert.match(collapsed, /<muted>reports×2, docs×1, roadmaps×1<\/muted>/);
925
+ assert.doesNotMatch(collapsed, /\| ref \|/);
926
+ const expanded = def
927
+ .renderResult({ content: [{ type: 'text', text: HISTORY_SHOW_OUTPUT }] }, { expanded: true }, theme, {})
928
+ .render(120)
929
+ .join('\n');
930
+ assert.match(expanded, /\| ref \| source \| ts \| detail \|/);
931
+ assert.match(expanded, /Final report {2}\(120B\)/);
932
+ const empty = def
933
+ .renderResult({ content: [{ type: 'text', text: ['node: alpha (n1)', '', '0 artifacts.', '', 'Read one…'].join('\n\n') }] }, { expanded: false }, theme, {})
934
+ .render(120)
935
+ .join('\n');
936
+ assert.match(empty, /<muted>alpha \(n1\) · 0 artifacts<\/muted>/);
937
+ // Lead-in says 4 artifacts, but the table only has 3 rows — a
938
+ // truncated/mismatched render is a shape mismatch, not a partial summary:
939
+ // skipped (null), raw survives even collapsed.
940
+ const truncated = def
941
+ .renderResult({
942
+ content: [
943
+ {
944
+ type: 'text',
945
+ text: [
946
+ 'node: alpha (n1)',
947
+ '',
948
+ '4 artifacts:',
949
+ '',
950
+ '| ref | source | ts | detail |',
951
+ '| --- | --- | --- | --- |',
952
+ '| n1:reports/a.md | report:final | 2026-01-01T00:00:00.000Z | Final report (120B) |',
953
+ '| n1:reports/b.md | report:update | 2026-01-02T00:00:00.000Z | Update (80B) |',
954
+ '| n1:docs/design.md | doc | 2026-01-03T00:00:00.000Z | Design doc |',
955
+ ].join('\n'),
956
+ },
957
+ ],
958
+ }, { expanded: false }, theme, {})
959
+ .render(120)
960
+ .join('\n');
961
+ assert.match(truncated, /4 artifacts:/);
962
+ assert.doesNotMatch(truncated, /<muted>reports×/);
963
+ const emptyExpanded = def
964
+ .renderResult({ content: [{ type: 'text', text: ['node: alpha (n1)', '', '0 artifacts.', '', 'Read one…'].join('\n\n') }] }, { expanded: true }, theme, {})
965
+ .render(120)
966
+ .join('\n');
967
+ assert.match(emptyExpanded, /0 artifacts\./);
968
+ });
969
+ test('crtr sys daemon start/status/stop cards collapse to a one-line pid status', () => {
970
+ const start = createCrtrBashToolDefinition({ command: 'crtr sys daemon start' });
971
+ assert.match(start.renderResult({ content: [{ type: 'text', text: '- started: true\n- pid: 4242' }] }, { expanded: false }, theme, {}).render(120).join('\n'), /<success>started · pid 4242<\/success>/);
972
+ assert.match(start.renderResult({ content: [{ type: 'text', text: '- started: false\n- existing_pid: 99' }] }, { expanded: false }, theme, {}).render(120).join('\n'), /<muted>already running · pid 99<\/muted>/);
973
+ assert.match(start.renderResult({ content: [{ type: 'text', text: '- started: false\n- existing_pid: 99' }] }, { expanded: true }, theme, {}).render(120).join('\n'), /existing_pid: 99/);
974
+ const startExpanded = start
975
+ .renderResult({ content: [{ type: 'text', text: '- started: true\n- pid: 4242' }] }, { expanded: true }, theme, {})
976
+ .render(120)
977
+ .join('\n');
978
+ assert.match(startExpanded, /started: true/);
979
+ assert.match(startExpanded, /pid: 4242/);
980
+ const status = createCrtrBashToolDefinition({ command: 'crtr sys daemon status' });
981
+ assert.match(status.renderResult({ content: [{ type: 'text', text: '- running: true\n- pid: 4242' }] }, { expanded: false }, theme, {}).render(120).join('\n'), /<success>running · pid 4242<\/success>/);
982
+ assert.match(status.renderResult({ content: [{ type: 'text', text: '- running: false' }] }, { expanded: false }, theme, {}).render(120).join('\n'), /<error>not running<\/error>/);
983
+ assert.match(status.renderResult({ content: [{ type: 'text', text: '- running: false' }] }, { expanded: true }, theme, {}).render(120).join('\n'), /running: false/);
984
+ const statusExpanded = status
985
+ .renderResult({ content: [{ type: 'text', text: '- running: true\n- pid: 4242' }] }, { expanded: true }, theme, {})
986
+ .render(120)
987
+ .join('\n');
988
+ assert.match(statusExpanded, /running: true/);
989
+ assert.match(statusExpanded, /pid: 4242/);
990
+ const stop = createCrtrBashToolDefinition({ command: 'crtr sys daemon stop' });
991
+ assert.match(stop.renderResult({ content: [{ type: 'text', text: '- stopped: true\n- pid: 4242' }] }, { expanded: false }, theme, {}).render(120).join('\n'), /stopped · pid 4242/);
992
+ assert.match(stop.renderResult({ content: [{ type: 'text', text: '- stopped: false' }] }, { expanded: false }, theme, {}).render(120).join('\n'), /<muted>was not running<\/muted>/);
993
+ assert.match(stop.renderResult({ content: [{ type: 'text', text: '- stopped: false' }] }, { expanded: true }, theme, {}).render(120).join('\n'), /stopped: false/);
994
+ const stopExpanded = stop
995
+ .renderResult({ content: [{ type: 'text', text: '- stopped: true\n- pid: 4242' }] }, { expanded: true }, theme, {})
996
+ .render(120)
997
+ .join('\n');
998
+ assert.match(stopExpanded, /stopped: true/);
999
+ assert.match(stopExpanded, /pid: 4242/);
1000
+ });
1001
+ test('a crtr canvas issue new card collapses to an issue/note confirmation, not the raw bullets', () => {
1002
+ const def = createCrtrBashToolDefinition({ command: 'crtr canvas issue new --type bug' });
1003
+ const github = def
1004
+ .renderResult({
1005
+ content: [
1006
+ {
1007
+ type: 'text',
1008
+ text: '- created: true\n- target: github\n- type: bug\n- title: Fix the thing\n- url: https://github.com/acme/repo/issues/42',
1009
+ },
1010
+ ],
1011
+ }, { expanded: false }, theme, {})
1012
+ .render(120)
1013
+ .join('\n');
1014
+ assert.match(github, /<success>issue #42<\/success>/);
1015
+ assert.match(github, /<muted>https:\/\/github\.com\/acme\/repo\/issues\/42<\/muted>/);
1016
+ const githubExpanded = def
1017
+ .renderResult({
1018
+ content: [
1019
+ {
1020
+ type: 'text',
1021
+ text: '- created: true\n- target: github\n- type: bug\n- title: Fix the thing\n- url: https://github.com/acme/repo/issues/42',
1022
+ },
1023
+ ],
1024
+ }, { expanded: true }, theme, {})
1025
+ .render(120)
1026
+ .join('\n');
1027
+ assert.match(githubExpanded, /url: https:\/\/github\.com\/acme\/repo\/issues\/42/);
1028
+ const file = def
1029
+ .renderResult({
1030
+ content: [
1031
+ {
1032
+ type: 'text',
1033
+ text: '- created: true\n- target: file\n- type: idea\n- title: Add the thing\n- path: /Users/x/proj/.todos/20260101-add-the-thing.md',
1034
+ },
1035
+ ],
1036
+ }, { expanded: false }, theme, {})
1037
+ .render(120)
1038
+ .join('\n');
1039
+ assert.match(file, /<success>note saved<\/success>/);
1040
+ assert.match(file, /<muted>20260101-add-the-thing\.md<\/muted>/);
1041
+ const fileExpanded = def
1042
+ .renderResult({
1043
+ content: [
1044
+ {
1045
+ type: 'text',
1046
+ text: '- created: true\n- target: file\n- type: idea\n- title: Add the thing\n- path: /Users/x/proj/.todos/20260101-add-the-thing.md',
1047
+ },
1048
+ ],
1049
+ }, { expanded: true }, theme, {})
1050
+ .render(120)
1051
+ .join('\n');
1052
+ assert.match(fileExpanded, /path: \/Users\/x\/proj\/\.todos\/20260101-add-the-thing\.md/);
1053
+ const empty = def
1054
+ .renderResult({ content: [{ type: 'text', text: '- created: false' }] }, { expanded: false }, theme, {})
1055
+ .render(120)
1056
+ .join('\n');
1057
+ assert.match(empty, /<muted>nothing captured<\/muted>/);
1058
+ const emptyExpanded = def
1059
+ .renderResult({ content: [{ type: 'text', text: '- created: false' }] }, { expanded: true }, theme, {})
1060
+ .render(120)
1061
+ .join('\n');
1062
+ assert.match(emptyExpanded, /created: false/);
1063
+ });
1064
+ test('a crtr node new card collapses to a spawned status line, not the raw follow_up prose', () => {
1065
+ const def = createCrtrBashToolDefinition({ command: 'crtr node new --kind developer' });
1066
+ const spawned = def
1067
+ .renderResult({ content: [{ type: 'text', text: ['Spawned "worker-a" (mq2jpqz5-87fa626e) — active.', '', 'Independent root spawned — hand it off and move on.'].join('\n') }] }, { expanded: false }, theme, {})
1068
+ .render(120)
1069
+ .join('\n');
1070
+ assert.match(spawned, /<success>spawned worker-a \(mq2jpqz5-87fa626e\) · active<\/success>/);
1071
+ const spawnedExpanded = def
1072
+ .renderResult({ content: [{ type: 'text', text: ['Spawned "worker-a" (mq2jpqz5-87fa626e) — active.', '', 'Independent root spawned — hand it off and move on.'].join('\n') }] }, { expanded: true }, theme, {})
1073
+ .render(120)
1074
+ .join('\n');
1075
+ assert.match(spawnedExpanded, /Independent root spawned — hand it off and move on\./);
1076
+ });
1077
+ test('a crtr node message send card collapses to a delivered status line, not the raw guidance prose', () => {
1078
+ const def = createCrtrBashToolDefinition({ command: 'crtr node message send --to mq123' });
1079
+ const delivered = def
1080
+ .renderResult({ content: [{ type: 'text', text: 'Delivered.' }] }, { expanded: false }, theme, {})
1081
+ .render(120)
1082
+ .join('\n');
1083
+ assert.match(delivered, /<success>delivered<\/success>/);
1084
+ const deliveredExpanded = def
1085
+ .renderResult({ content: [{ type: 'text', text: 'Delivered.' }] }, { expanded: true }, theme, {})
1086
+ .render(120)
1087
+ .join('\n');
1088
+ assert.match(deliveredExpanded, /Delivered\./);
1089
+ const revived = def
1090
+ .renderResult({ content: [{ type: 'text', text: 'Delivered — the dormant target was revived to receive it.' }] }, { expanded: false }, theme, {})
1091
+ .render(120)
1092
+ .join('\n');
1093
+ assert.match(revived, /<success>delivered · revived<\/success>/);
1094
+ const revivedExpanded = def
1095
+ .renderResult({ content: [{ type: 'text', text: 'Delivered — the dormant target was revived to receive it.' }] }, { expanded: true }, theme, {})
1096
+ .render(120)
1097
+ .join('\n');
1098
+ assert.match(revivedExpanded, /Delivered — the dormant target was revived to receive it\./);
1099
+ const deferredHeld = def
1100
+ .renderResult({ content: [{ type: 'text', text: "Delivered — held for the target's next natural cycle; not revived (deferred)." }] }, { expanded: false }, theme, {})
1101
+ .render(120)
1102
+ .join('\n');
1103
+ assert.match(deferredHeld, /<accent>delivered · held \(deferred\)<\/accent>/);
1104
+ const deferredHeldExpanded = def
1105
+ .renderResult({ content: [{ type: 'text', text: "Delivered — held for the target's next natural cycle; not revived (deferred)." }] }, { expanded: true }, theme, {})
1106
+ .render(120)
1107
+ .join('\n');
1108
+ assert.match(deferredHeldExpanded, /Delivered — held for the target's next natural cycle; not revived \(deferred\)\./);
1109
+ });
1110
+ test('a crtr node yield card collapses to a refresh-armed status line, not the raw bullets', () => {
1111
+ const def = createCrtrBashToolDefinition({ command: 'crtr node yield' });
1112
+ const withExtras = def
1113
+ .renderResult({ content: [{ type: 'text', text: '- node_id: mq123\n- promoted: true\n- model: strong\n- will_refresh: true' }] }, { expanded: false }, theme, {})
1114
+ .render(120)
1115
+ .join('\n');
1116
+ assert.match(withExtras, /<accent>yield armed — refreshes on next wake<\/accent>/);
1117
+ assert.match(withExtras, /<muted>promoted → orchestrator · model: strong<\/muted>/);
1118
+ const withExtrasExpanded = def
1119
+ .renderResult({ content: [{ type: 'text', text: '- node_id: mq123\n- promoted: true\n- model: strong\n- will_refresh: true' }] }, { expanded: true }, theme, {})
1120
+ .render(120)
1121
+ .join('\n');
1122
+ assert.match(withExtrasExpanded, /promoted: true/);
1123
+ assert.match(withExtrasExpanded, /model: strong/);
1124
+ const plain = def
1125
+ .renderResult({ content: [{ type: 'text', text: '- node_id: mq123\n- will_refresh: true' }] }, { expanded: false }, theme, {})
1126
+ .render(120)
1127
+ .join('\n');
1128
+ assert.match(plain, /<accent>yield armed — refreshes on next wake<\/accent>/);
1129
+ assert.doesNotMatch(plain, /promoted/);
1130
+ const plainExpanded = def
1131
+ .renderResult({ content: [{ type: 'text', text: '- node_id: mq123\n- will_refresh: true' }] }, { expanded: true }, theme, {})
1132
+ .render(120)
1133
+ .join('\n');
1134
+ assert.match(plainExpanded, /node_id: mq123/);
1135
+ });
1136
+ test('a crtr node lifecycle close card collapses to a cascade digest, not the raw prose sentence', () => {
1137
+ const def = createCrtrBashToolDefinition({ command: 'crtr node lifecycle close --node mq123' });
1138
+ const cascade = def
1139
+ .renderResult({ content: [{ type: 'text', text: 'Closed mq123 and its exclusive subtree — 3 node(s) closed, 1 spared (still managed from outside the subtree).' }] }, { expanded: false }, theme, {})
1140
+ .render(120)
1141
+ .join('\n');
1142
+ assert.match(cascade, /<success>closed mq123<\/success>/);
1143
+ assert.match(cascade, /<warning>2 descendants canceled<\/warning>/);
1144
+ assert.match(cascade, /<muted>1 spared \(managed elsewhere\)<\/muted>/);
1145
+ const cascadeExpanded = def
1146
+ .renderResult({ content: [{ type: 'text', text: 'Closed mq123 and its exclusive subtree — 3 node(s) closed, 1 spared (still managed from outside the subtree).' }] }, { expanded: true }, theme, {})
1147
+ .render(120)
1148
+ // Expanded lines WRAP rather than clip, so rejoin the wrap to assert the
1149
+ // full sentence survived intact.
1150
+ .join(' ')
1151
+ .replace(/\s+/g, ' ');
1152
+ assert.match(cascadeExpanded, /Closed mq123 and its exclusive subtree — 3 node\(s\) closed, 1 spared \(still managed from outside the subtree\)/);
1153
+ const solo = def
1154
+ .renderResult({ content: [{ type: 'text', text: 'Closed mq123 and its exclusive subtree — 1 node(s) closed.' }] }, { expanded: false }, theme, {})
1155
+ .render(120)
1156
+ .join('\n');
1157
+ assert.match(solo, /<success>closed mq123<\/success>/);
1158
+ assert.doesNotMatch(solo, /descendants? canceled/);
1159
+ const soloExpanded = def
1160
+ .renderResult({ content: [{ type: 'text', text: 'Closed mq123 and its exclusive subtree — 1 node(s) closed.' }] }, { expanded: true }, theme, {})
1161
+ .render(120)
1162
+ .join('\n');
1163
+ assert.match(soloExpanded, /Closed mq123 and its exclusive subtree — 1 node\(s\) closed\./);
1164
+ });
1165
+ test('crtr push urgent/final cards collapse to a one-line outcome + report basename', () => {
1166
+ const urgentDef = createCrtrBashToolDefinition({ command: 'crtr push urgent' });
1167
+ const urgent = urgentDef
1168
+ .renderResult({ content: [{ type: 'text', text: 'Urgent report fanned to 3 subscriber(s) — they are force-woken.\n\n- report: /Users/x/nodes/mq1/reports/20260101-urgent.md' }] }, { expanded: false }, theme, {})
1169
+ .render(120)
1170
+ .join('\n');
1171
+ assert.match(urgent, /<warning>urgent → 3 subscribers woken<\/warning>/);
1172
+ const urgentExpanded = urgentDef
1173
+ .renderResult({ content: [{ type: 'text', text: 'Urgent report fanned to 3 subscriber(s) — they are force-woken.\n\n- report: /Users/x/nodes/mq1/reports/20260101-urgent.md' }] }, { expanded: true }, theme, {})
1174
+ .render(120)
1175
+ .join('\n');
1176
+ assert.match(urgentExpanded, /report: \/Users\/x\/nodes\/mq1\/reports\/20260101-urgent\.md/);
1177
+ const finalDef = createCrtrBashToolDefinition({ command: 'crtr push final' });
1178
+ const final = finalDef
1179
+ .renderResult({
1180
+ content: [
1181
+ {
1182
+ type: 'text',
1183
+ text: 'Result recorded — node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.\n\n- report: /Users/x/nodes/mq1/reports/20260101-final.md',
1184
+ },
1185
+ ],
1186
+ }, { expanded: false }, theme, {})
1187
+ .render(120)
1188
+ .join('\n');
1189
+ assert.match(final, /<success>final pushed · node done<\/success>/);
1190
+ assert.match(final, /<muted>20260101-final\.md<\/muted>/);
1191
+ const finalExpanded = finalDef
1192
+ .renderResult({
1193
+ content: [
1194
+ {
1195
+ type: 'text',
1196
+ text: 'Result recorded — node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.\n\n- report: /Users/x/nodes/mq1/reports/20260101-final.md',
1197
+ },
1198
+ ],
1199
+ }, { expanded: true }, theme, {})
1200
+ .render(120)
1201
+ .join('\n');
1202
+ assert.match(finalExpanded, /report: \/Users\/x\/nodes\/mq1\/reports\/20260101-final\.md/);
1203
+ });
1204
+ // ---------------------------------------------------------------------------
1205
+ // Batch C — human/memory/pkg summarizers (preview-registry.ts "Batch C")
1206
+ // ---------------------------------------------------------------------------
1207
+ // Ask and review share the queuedFollowUp road-sign (prompts.ts): arrival is
1208
+ // always just durable queue state, so the card collapses to one posted line.
1209
+ // The summarizer keys on the stable `Queued for the human` prefix; the inbox-
1210
+ // affordance tail resolves per call, so this fixture pins one resolved form.
1211
+ const QUEUED_FOLLOW_UP = 'Queued for the human. Their answer is pushed to your inbox and wakes you when they respond — never poll, verify it opened, or block. To see the queue, press ⌥I (or run `hl inbox open` at a terminal).';
1212
+ const HUMAN_ASK_QUEUED_OUTPUT = [
1213
+ '- job_id: mrASK0001',
1214
+ '',
1215
+ '**dir:** /Users/silas/Code/cli/crouter',
1216
+ '',
1217
+ `**follow_up:** ${QUEUED_FOLLOW_UP}`,
1218
+ ].join('\n');
1219
+ test('a crtr human ask card collapses to a posted status + question teaser, not the raw fields', () => {
1220
+ const def = createCrtrBashToolDefinition({ command: 'crtr human ask "Should we ship the preview rollout now?"' });
1221
+ const collapsed = def
1222
+ .renderResult({ content: [{ type: 'text', text: HUMAN_ASK_QUEUED_OUTPUT }] }, { expanded: false }, theme, {})
1223
+ .render(140)
1224
+ .join('\n');
1225
+ assert.match(collapsed, /<accent>ask posted → waiting on human<\/accent>/);
1226
+ assert.match(collapsed, /<muted>Should we ship the preview rollout now\?<\/muted>/);
1227
+ assert.doesNotMatch(collapsed, /- job_id:/);
1228
+ const expanded = def
1229
+ .renderResult({ content: [{ type: 'text', text: HUMAN_ASK_QUEUED_OUTPUT }] }, { expanded: true }, theme, {})
1230
+ .render(140)
1231
+ .join('\n');
1232
+ assert.match(expanded, /job_id: mrASK0001/);
1233
+ assert.match(expanded, /wakes you when they respond/);
1234
+ });
1235
+ const HUMAN_REVIEW_QUEUED_OUTPUT = [
1236
+ '- job_id: mrREV0001',
1237
+ '',
1238
+ '**dir:** /Users/silas/Code/cli/crouter',
1239
+ '',
1240
+ '**output:** /Users/silas/Code/cli/crouter/spec.review.md',
1241
+ '',
1242
+ `**follow_up:** ${QUEUED_FOLLOW_UP}`,
1243
+ ].join('\n');
1244
+ test('a crtr human review card collapses to a posted status + file basename, not the raw fields', () => {
1245
+ const def = createCrtrBashToolDefinition({ command: 'crtr human review /Users/silas/Code/cli/crouter/spec.md' });
1246
+ const collapsed = def
1247
+ .renderResult({ content: [{ type: 'text', text: HUMAN_REVIEW_QUEUED_OUTPUT }] }, { expanded: false }, theme, {})
1248
+ .render(140)
1249
+ .join('\n');
1250
+ assert.match(collapsed, /<accent>review posted: spec\.md → waiting on human<\/accent>/);
1251
+ assert.doesNotMatch(collapsed, /- job_id:/);
1252
+ const expanded = def
1253
+ .renderResult({ content: [{ type: 'text', text: HUMAN_REVIEW_QUEUED_OUTPUT }] }, { expanded: true }, theme, {})
1254
+ .render(140)
1255
+ .join('\n');
1256
+ assert.match(expanded, /job_id: mrREV0001/);
1257
+ assert.match(expanded, /wakes you when they respond/);
1258
+ });
1259
+ const HUMAN_LIST_OUTPUT = [
1260
+ '- total: 2',
1261
+ '',
1262
+ '2 items:',
1263
+ '',
1264
+ '| id | job_id | dir | title | kind | blocked_since | asking_node_id | asking_node_name | conversation_id | conversation_title | interaction_count |',
1265
+ '| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |',
1266
+ '| h1 | mrJOB1 | /Users/silas/Code/cli/crouter | Ship the rollout? | decision | 2026-06-30T12:00:00.000Z | mrNODE1 | orchestrator | c1 | Rollout plan | 3 |',
1267
+ '| h2 | mrJOB2 | /Users/silas/Code/cli/crouter | Quick check | | 2026-06-30T12:05:00.000Z | mrNODE2 | reviewer | c2 | Spec review | 1 |',
1268
+ ].join('\n');
1269
+ test('a crtr human list card collapses to a pending count + kind digest, not the raw table', () => {
1270
+ const def = createCrtrBashToolDefinition({ command: 'crtr human list' });
1271
+ const collapsed = def
1272
+ .renderResult({ content: [{ type: 'text', text: HUMAN_LIST_OUTPUT }] }, { expanded: false }, theme, {})
1273
+ .render(140)
1274
+ .join('\n');
1275
+ assert.match(collapsed, /2 pending/);
1276
+ assert.match(collapsed, /<muted>decision×1<\/muted>/);
1277
+ assert.doesNotMatch(collapsed, /\| id \|/);
1278
+ const expanded = def
1279
+ .renderResult({ content: [{ type: 'text', text: HUMAN_LIST_OUTPUT }] }, { expanded: true }, theme, {})
1280
+ .render(140)
1281
+ .join('\n');
1282
+ assert.match(expanded, /\| id \| job_id \| dir \|/);
1283
+ const none = def
1284
+ .renderResult({ content: [{ type: 'text', text: '- total: 0\n\n0 items.' }] }, { expanded: false }, theme, {})
1285
+ .render(140)
1286
+ .join('\n');
1287
+ assert.match(none, /<success>none pending<\/success>/);
1288
+ // REQUIREMENT: total is nonzero but the page is empty (exhausted
1289
+ // pagination) — must NOT collapse to "none pending" (that's only correct
1290
+ // for a true zero total); fall back to the generic renderer instead.
1291
+ const exhausted = def
1292
+ .renderResult({ content: [{ type: 'text', text: '- total: 3\n\n0 items.' }] }, { expanded: false }, theme, {})
1293
+ .render(140)
1294
+ .join('\n');
1295
+ assert.doesNotMatch(exhausted, /none pending/);
1296
+ });
1297
+ const HUMAN_DECK_OUTPUT = [
1298
+ '- id: h1',
1299
+ '- title: Ship the rollout?',
1300
+ '- kind: decision',
1301
+ '- interaction_count: 1',
1302
+ '',
1303
+ '1 interactions:',
1304
+ '',
1305
+ '| id | kind | prompt | options | allow_freetext |',
1306
+ '| --- | --- | --- | --- | --- |',
1307
+ '| i1 | decision | Ship it? | {"id":"yes","label":"Yes"}, {"id":"no","label":"No"} | false |',
1308
+ ].join('\n');
1309
+ const HUMAN_DECK_MULTI_OUTPUT = [
1310
+ '- id: h1',
1311
+ '- title: Ship the rollout?',
1312
+ '- kind: decision',
1313
+ '- interaction_count: 2',
1314
+ '',
1315
+ '2 interactions:',
1316
+ '',
1317
+ '| id | kind | prompt | options | allow_freetext |',
1318
+ '| --- | --- | --- | --- | --- |',
1319
+ '| i1 | decision | Ship it? | {"id":"yes","label":"Yes"}, {"id":"no","label":"No"} | true |',
1320
+ '| i2 | question | Any concerns? | | true |',
1321
+ ].join('\n');
1322
+ test('a crtr human deck card collapses to a prompt teaser + option/freetext digest, not the raw table', () => {
1323
+ const def = createCrtrBashToolDefinition({ command: 'crtr human deck h1' });
1324
+ const collapsed = def
1325
+ .renderResult({ content: [{ type: 'text', text: HUMAN_DECK_OUTPUT }] }, { expanded: false }, theme, {})
1326
+ .render(140)
1327
+ .join('\n');
1328
+ assert.match(collapsed, /Ship it\?/);
1329
+ assert.match(collapsed, /<muted>2 options<\/muted>/);
1330
+ assert.doesNotMatch(collapsed, /\| id \| kind \|/);
1331
+ const expanded = def
1332
+ .renderResult({ content: [{ type: 'text', text: HUMAN_DECK_OUTPUT }] }, { expanded: true }, theme, {})
1333
+ .render(140)
1334
+ .join('\n');
1335
+ assert.match(expanded, /\| id \| kind \| prompt \| options \| allow_freetext \|/);
1336
+ const multi = def
1337
+ .renderResult({ content: [{ type: 'text', text: HUMAN_DECK_MULTI_OUTPUT }] }, { expanded: false }, theme, {})
1338
+ .render(140)
1339
+ .join('\n');
1340
+ assert.match(multi, /Ship it\?/);
1341
+ assert.match(multi, /<muted>2 options · freetext · 2 interactions<\/muted>/);
1342
+ // REQUIREMENT: a malformed/truncated `allow_freetext` cell (neither
1343
+ // `true` nor `false`) must not silently default to "no freetext" — it
1344
+ // must fall back to the generic renderer instead.
1345
+ const malformedFreetext = [
1346
+ '- id: h1',
1347
+ '- title: Ship the rollout?',
1348
+ '- kind: decision',
1349
+ '- interaction_count: 1',
1350
+ '',
1351
+ '1 interactions:',
1352
+ '',
1353
+ '| id | kind | prompt | options | allow_freetext |',
1354
+ '| --- | --- | --- | --- | --- |',
1355
+ '| i1 | decision | Ship it? | {"id":"yes","label":"Yes"}, {"id":"no","label":"No"} | |',
1356
+ ].join('\n');
1357
+ const malformed = def
1358
+ .renderResult({ content: [{ type: 'text', text: malformedFreetext }] }, { expanded: false }, theme, {})
1359
+ .render(140)
1360
+ .join('\n');
1361
+ assert.doesNotMatch(malformed, /<muted>2 options<\/muted>/);
1362
+ });
1363
+ const MEMORY_LIST_OUTPUT = [
1364
+ '- total: 3',
1365
+ '',
1366
+ 'Read one in full with `crtr memory read <name>`, or pass --paths for its file path to edit directly. Narrow with --kind / --scope, page with --cursor, or search a topic with `crtr memory find <query>`.',
1367
+ '',
1368
+ '3 items:',
1369
+ '',
1370
+ '| name | short_form | kind | scope | is_dir |',
1371
+ '| --- | --- | --- | --- | --- |',
1372
+ '| ai/x | AI helpers reference | knowledge | user | false |',
1373
+ '| taste/y | Taste doc | preference | project | false |',
1374
+ '| todos/z | Todo doc | knowledge | node | false |',
1375
+ ].join('\n');
1376
+ test('a crtr memory list card collapses to a doc count + kind/scope digest, not the raw table', () => {
1377
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory list' });
1378
+ const collapsed = def
1379
+ .renderResult({ content: [{ type: 'text', text: MEMORY_LIST_OUTPUT }] }, { expanded: false }, theme, {})
1380
+ .render(140)
1381
+ .join('\n');
1382
+ assert.match(collapsed, /3 docs/);
1383
+ assert.match(collapsed, /<muted>knowledge×2, preference×1 \/ node×1, project×1, user×1<\/muted>/);
1384
+ assert.doesNotMatch(collapsed, /\| name \|/);
1385
+ const expanded = def
1386
+ .renderResult({ content: [{ type: 'text', text: MEMORY_LIST_OUTPUT }] }, { expanded: true }, theme, {})
1387
+ .render(140)
1388
+ .join('\n');
1389
+ assert.match(expanded, /\| name \| short_form \| kind \|/);
1390
+ });
1391
+ const MEMORY_FIND_OUTPUT = [
1392
+ '- query: batch c fixtures',
1393
+ '- matches: 12',
1394
+ '',
1395
+ 'Matches ranked by relevance.',
1396
+ '',
1397
+ '2 hits:',
1398
+ '',
1399
+ '| name | kind | scope | score | short_form |',
1400
+ '| --- | --- | --- | --- | --- |',
1401
+ '| ai/x | knowledge | user | 18 | AI helpers reference |',
1402
+ '| taste/y | preference | project | 11 | Taste doc |',
1403
+ ].join('\n');
1404
+ const MEMORY_FIND_EMPTY_OUTPUT = ['- query: nonexistent thing', '', 'Matches ranked by relevance.', '', '0 hits.'].join('\n');
1405
+ const MEMORY_FIND_GREP_OUTPUT = [
1406
+ '- query: TODO',
1407
+ '- matches: 1',
1408
+ '',
1409
+ 'Matches ranked by relevance.',
1410
+ '',
1411
+ '1 hits:',
1412
+ '',
1413
+ '| name | scope | line | text |',
1414
+ '| --- | --- | --- | --- |',
1415
+ '| notes/a | project | 12 | TODO: fix this |',
1416
+ ].join('\n');
1417
+ test('a crtr memory find card collapses to a hit count + name digest, not the raw table', () => {
1418
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory find "batch c fixtures"' });
1419
+ const collapsed = def
1420
+ .renderResult({ content: [{ type: 'text', text: MEMORY_FIND_OUTPUT }] }, { expanded: false }, theme, {})
1421
+ .render(140)
1422
+ .join('\n');
1423
+ assert.match(collapsed, /2 hits for "batch c fixtures"/);
1424
+ assert.match(collapsed, /<muted>ai\/x, taste\/y<\/muted>/);
1425
+ assert.doesNotMatch(collapsed, /\| name \|/);
1426
+ const expanded = def
1427
+ .renderResult({ content: [{ type: 'text', text: MEMORY_FIND_OUTPUT }] }, { expanded: true }, theme, {})
1428
+ .render(140)
1429
+ .join('\n');
1430
+ assert.match(expanded, /\| name \| kind \| scope \|/);
1431
+ assert.doesNotMatch(expanded, /\| path \|/);
1432
+ const empty = def
1433
+ .renderResult({ content: [{ type: 'text', text: MEMORY_FIND_EMPTY_OUTPUT }] }, { expanded: false }, theme, {})
1434
+ .render(140)
1435
+ .join('\n');
1436
+ assert.match(empty, /<muted>0 hits for "nonexistent thing"<\/muted>/);
1437
+ const grepDef = createCrtrBashToolDefinition({ command: 'crtr memory find TODO --grep' });
1438
+ const grepCollapsed = grepDef
1439
+ .renderResult({ content: [{ type: 'text', text: MEMORY_FIND_GREP_OUTPUT }] }, { expanded: false }, theme, {})
1440
+ .render(140)
1441
+ .join('\n');
1442
+ assert.doesNotMatch(grepCollapsed, /hits for "TODO"/);
1443
+ assert.match(grepCollapsed, /TODO: fix this/);
1444
+ });
1445
+ const MEMORY_WRITE_CREATED_OUTPUT = [
1446
+ '- name: taste/batch-c-fixtures',
1447
+ '- kind: knowledge',
1448
+ '- scope: node',
1449
+ '- created: true',
1450
+ '',
1451
+ '**path:** /Users/silas/Code/cli/crouter/.crouter/memory/taste/batch-c-fixtures.md',
1452
+ '',
1453
+ '**follow_up:** Written. Read it back with `crtr memory read taste/batch-c-fixtures`.',
1454
+ '',
1455
+ '4 frontmatter:',
1456
+ '',
1457
+ '| key | value |',
1458
+ '| --- | --- |',
1459
+ '| kind | knowledge |',
1460
+ '| when-and-why-to-read | When changing batch C fixtures, read this because the stable contract prevents rework. |',
1461
+ '| system-prompt-visibility | preview |',
1462
+ '| file-read-visibility | none |',
1463
+ ].join('\n');
1464
+ const MEMORY_WRITE_UPDATED_OUTPUT = [
1465
+ '- name: taste/batch-c-fixtures',
1466
+ '- kind: knowledge',
1467
+ '- scope: node',
1468
+ '- created: false',
1469
+ '',
1470
+ '**path:** /Users/silas/Code/cli/crouter/.crouter/memory/taste/batch-c-fixtures.md',
1471
+ '',
1472
+ '**follow_up:** Updated. Read it back with `crtr memory read taste/batch-c-fixtures`.',
1473
+ '',
1474
+ '1 frontmatter:',
1475
+ '',
1476
+ '| key | value |',
1477
+ '| --- | --- |',
1478
+ '| kind | knowledge |',
1479
+ ].join('\n');
1480
+ test('a crtr memory write card shows selected frontmatter as aligned key/value pairs', () => {
1481
+ const def = createCrtrBashToolDefinition({ command: 'crtr memory write taste/batch-c-fixtures \\\n --kind knowledge \\\n --system-prompt-visibility preview' });
1482
+ const collapsed = def
1483
+ .renderResult({ content: [{ type: 'text', text: MEMORY_WRITE_CREATED_OUTPUT }] }, { expanded: false }, theme, {})
1484
+ .render(140)
1485
+ .join('\n');
1486
+ assert.match(collapsed, /<success>wrote taste\/batch-c-fixtures<\/success>/);
1487
+ assert.match(collapsed, /kind\s*: knowledge/);
1488
+ assert.match(collapsed, /when-and-why-to-read\s*: When changing batch C fixtures/);
1489
+ assert.match(collapsed, /system-prompt-visibility\s*: preview/);
1490
+ assert.match(collapsed, /file-read-visibility\s*: none/);
1491
+ assert.doesNotMatch(collapsed, /\/Users\/silas/);
1492
+ assert.doesNotMatch(collapsed, /- created:/);
1493
+ const expanded = def
1494
+ .renderResult({ content: [{ type: 'text', text: MEMORY_WRITE_CREATED_OUTPUT }] }, { expanded: true }, theme, {})
1495
+ .render(140)
1496
+ .join('\n');
1497
+ assert.match(expanded, /created: true/);
1498
+ assert.match(expanded, /4 frontmatter:/);
1499
+ const updated = def
1500
+ .renderResult({ content: [{ type: 'text', text: MEMORY_WRITE_UPDATED_OUTPUT }] }, { expanded: false }, theme, {})
1501
+ .render(140)
1502
+ .join('\n');
1503
+ assert.match(updated, /<success>updated taste\/batch-c-fixtures<\/success>/);
1504
+ assert.match(updated, /kind\s*: knowledge/);
1505
+ });
1506
+ test('configuration mutations share an outcome-first aligned key/value preview', () => {
1507
+ const cases = [
1508
+ {
1509
+ command: 'crtr node config --node n1 --model strong --mode orchestrator',
1510
+ output: 'Configured n1 — model=anthropic/claude-opus-4-6, mode=orchestrator',
1511
+ expected: [/configured n1/, /model\s*: anthropic\/claude-opus-4-6/, /mode\s*: orchestrator/],
1512
+ },
1513
+ {
1514
+ command: 'crtr sys config set auto_update.crtr --value apply',
1515
+ output: '- key: auto_update.crtr\n- value: apply\n- scope: user',
1516
+ expected: [/updated config/, /auto_update\.crtr\s*: apply/, /scope\s*: user/],
1517
+ },
1518
+ {
1519
+ command: 'crtr canvas config add prod --preview https://prod.example --relay-token -',
1520
+ output: "Registered remote canvas target 'prod' → https://prod.example (token stored).",
1521
+ expected: [/registered prod/, /preview\s*: https:\/\/prod\.example/, /relay-token\s*: stored/],
1522
+ },
1523
+ {
1524
+ command: 'crtr canvas config remove old',
1525
+ output: "Removed remote canvas target 'old'.",
1526
+ expected: [/removed old/],
1527
+ },
1528
+ {
1529
+ command: 'crtr canvas use prod',
1530
+ output: 'Active canvas: prod.',
1531
+ expected: [/active canvas: prod/],
1532
+ },
1533
+ ];
1534
+ for (const item of cases) {
1535
+ const def = createCrtrBashToolDefinition({ command: item.command });
1536
+ const collapsed = def
1537
+ .renderResult({ content: [{ type: 'text', text: item.output }] }, { expanded: false }, theme, {})
1538
+ .render(140)
1539
+ .join('\n');
1540
+ for (const expected of item.expected)
1541
+ assert.match(collapsed, expected);
1542
+ }
1543
+ });
1544
+ test('node and package mutations share compact outcome-first receipts', () => {
1545
+ const cases = [
1546
+ ['crtr node subscription add pub --subscriber sub --passive', 'Subscribed sub → pub (passive).', [/subscribed/, /subscriber\s*: sub/, /publisher\s*: pub/, /mode\s*: passive/]],
1547
+ ['crtr node subscription remove pub --subscriber sub', 'Unsubscribed sub from pub.', [/unsubscribed/, /subscriber\s*: sub/, /publisher\s*: pub/]],
1548
+ ['crtr node promote --kind plan --resident', '- node_id: n1\n- kind: plan\n- mode: orchestrator\n- lifecycle: resident\n- roadmap_written: true\n\n**roadmap_path:** /tmp/roadmap.md\n\n**goal_path:** /tmp/goal.md', [/promoted n1/, /kind\s*: plan/, /lifecycle\s*: resident/, /roadmap\s*: seeded/]],
1549
+ ['crtr node lifecycle demote --node n1 --detach', 'Demoted n1 — lifecycle now terminal (in place), viewer closed (broker still running off-screen).', [/demoted n1/, /lifecycle\s*: terminal/, /viewer\s*: detached/]],
1550
+ ['crtr node lifecycle recycle --node n1', 'Recycled the pane — finished n1.\n- finalized: true\n- delivered: 2\n- new root: n2', [/recycled n1/, /finalized\s*: true/, /delivered\s*: 2/, /new root\s*: n2/]],
1551
+ ['crtr pkg plugin enable ai', '- name: ai\n- scope: user\n- enabled: true', [/enabled ai/, /scope\s*: user/]],
1552
+ ['crtr pkg plugin disable ai', '- name: ai\n- scope: project\n- enabled: false', [/disabled ai/, /scope\s*: project/]],
1553
+ ['crtr pkg plugin remove ai', '- removed: true\n\n1 scopes:\n- user', [/removed ai/, /scopes\s*: user/]],
1554
+ ['crtr pkg market add https://example.test/m.git', '- name: official\n- scope: user\n\n/Users/silas/.crouter/marketplaces/official', [/added marketplace official/, /scope\s*: user/]],
1555
+ ['crtr pkg market remove official', '- name: official\n- removed: true', [/removed marketplace official/]],
1556
+ ['crtr pkg market update --name official', '1 updated:\n\n| name | updated | sha |\n| --- | --- | --- |\n| official | true | abcdef123 |', [/updated official/, /abcdef1/]],
1557
+ ];
1558
+ for (const [command, output, expected] of cases) {
1559
+ const def = createCrtrBashToolDefinition({ command });
1560
+ const collapsed = def.renderResult({ content: [{ type: 'text', text: output }] }, { expanded: false }, theme, {}).render(140).join('\n');
1561
+ for (const pattern of expected)
1562
+ assert.match(collapsed, pattern, command);
1563
+ assert.match(collapsed, /ctrl\+o to expand/, command);
1564
+ }
1565
+ });
1566
+ const PKG_PLUGIN_INSTALL_OUTPUT = ['- name: ai', '- scope: user', '', '/Users/silas/.crouter/plugins/ai'].join('\n');
1567
+ const PKG_PLUGIN_INSTALL_SHORT_PATH_OUTPUT = ['- name: ai', '- scope: user', '- path: /a'].join('\n');
1568
+ test('a crtr pkg plugin install card collapses to an installed status + scope/path digest, not the raw fields', () => {
1569
+ const def = createCrtrBashToolDefinition({ command: 'crtr pkg plugin install ai' });
1570
+ const collapsed = def
1571
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_INSTALL_OUTPUT }] }, { expanded: false }, theme, {})
1572
+ .render(140)
1573
+ .join('\n');
1574
+ assert.match(collapsed, /<success>installed ai<\/success>/);
1575
+ assert.match(collapsed, /<muted>user · \/Users\/silas\/\.crouter\/plugins\/ai<\/muted>/);
1576
+ assert.doesNotMatch(collapsed, /- name:/);
1577
+ const expanded = def
1578
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_INSTALL_OUTPUT }] }, { expanded: true }, theme, {})
1579
+ .render(140)
1580
+ .join('\n');
1581
+ assert.match(expanded, /\/Users\/silas\/\.crouter\/plugins\/ai/);
1582
+ const shortPath = def
1583
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_INSTALL_SHORT_PATH_OUTPUT }] }, { expanded: false }, theme, {})
1584
+ .render(140)
1585
+ .join('\n');
1586
+ assert.match(shortPath, /<muted>user · \/a<\/muted>/);
1587
+ });
1588
+ const PKG_PLUGIN_UPDATE_UPDATED_OUTPUT = ['1 updated:', '', '| name | updated | sha |', '| --- | --- | --- |', '| ai | true | def5678 |'].join('\n');
1589
+ const PKG_PLUGIN_UPDATE_CURRENT_OUTPUT = ['1 updated:', '', '| name | updated | sha |', '| --- | --- | --- |', '| ai | false | abc1234 |'].join('\n');
1590
+ const PKG_PLUGIN_UPDATE_MULTI_OUTPUT = [
1591
+ '3 updated:',
1592
+ '',
1593
+ '| name | updated | sha |',
1594
+ '| --- | --- | --- |',
1595
+ '| ai | true | aaa1111 |',
1596
+ '| beta | false | bbb2222 |',
1597
+ '| gamma | true | ccc3333 |',
1598
+ ].join('\n');
1599
+ test('a crtr pkg plugin update card collapses to an updated/current status + sha, not the raw table', () => {
1600
+ const def = createCrtrBashToolDefinition({ command: 'crtr pkg plugin update --name ai' });
1601
+ const collapsed = def
1602
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_UPDATE_UPDATED_OUTPUT }] }, { expanded: false }, theme, {})
1603
+ .render(140)
1604
+ .join('\n');
1605
+ assert.match(collapsed, /<success>updated ai<\/success>/);
1606
+ assert.match(collapsed, /<muted>def5678<\/muted>/);
1607
+ assert.doesNotMatch(collapsed, /\| name \| updated \|/);
1608
+ const expanded = def
1609
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_UPDATE_UPDATED_OUTPUT }] }, { expanded: true }, theme, {})
1610
+ .render(140)
1611
+ .join('\n');
1612
+ assert.match(expanded, /\| name \| updated \| sha \|/);
1613
+ const current = def
1614
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_UPDATE_CURRENT_OUTPUT }] }, { expanded: false }, theme, {})
1615
+ .render(140)
1616
+ .join('\n');
1617
+ assert.match(current, /<muted>ai already current<\/muted>/);
1618
+ assert.match(current, /<muted>abc1234<\/muted>/);
1619
+ const multiDef = createCrtrBashToolDefinition({ command: 'crtr pkg plugin update' });
1620
+ const multi = multiDef
1621
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_UPDATE_MULTI_OUTPUT }] }, { expanded: false }, theme, {})
1622
+ .render(140)
1623
+ .join('\n');
1624
+ assert.match(multi, /2 updated · 1 already current/);
1625
+ const empty = multiDef
1626
+ .renderResult({ content: [{ type: 'text', text: '0 updated.' }] }, { expanded: false }, theme, {})
1627
+ .render(140)
1628
+ .join('\n');
1629
+ assert.match(empty, /<muted>nothing to update<\/muted>/);
1630
+ // REQUIREMENT: a malformed `updated` cell (neither `true` nor `false`) in
1631
+ // a multi-row table must not be silently counted as "already current" —
1632
+ // the multi-row loop must reject exactly like the single-row path does.
1633
+ const malformedUpdate = [
1634
+ '3 updated:',
1635
+ '',
1636
+ '| name | updated | sha |',
1637
+ '| --- | --- | --- |',
1638
+ '| ai | true | aaa1111 |',
1639
+ '| beta | maybe | bbb2222 |',
1640
+ '| gamma | false | ccc3333 |',
1641
+ ].join('\n');
1642
+ const malformed = multiDef
1643
+ .renderResult({ content: [{ type: 'text', text: malformedUpdate }] }, { expanded: false }, theme, {})
1644
+ .render(140)
1645
+ .join('\n');
1646
+ assert.doesNotMatch(malformed, /already current/);
1647
+ });
1648
+ const PKG_PLUGIN_LIST_OUTPUT = [
1649
+ '- total: 3',
1650
+ '',
1651
+ '3 items:',
1652
+ '',
1653
+ '| name | scope | version | enabled | source_marketplace | path |',
1654
+ '| --- | --- | --- | --- | --- | --- |',
1655
+ '| ai | user | 0.7.1 | true | crouter-official-marketplace | /Users/silas/.crouter/plugins/ai |',
1656
+ '| beta | user | 1.0.0 | false | crouter-official-marketplace | /Users/silas/.crouter/plugins/beta |',
1657
+ '| gamma | project | 2.3.0 | true | custom-market | /Users/silas/Code/cli/crouter/.crouter/plugins/gamma |',
1658
+ ].join('\n');
1659
+ test('a crtr pkg plugin list card collapses to a plugin/enabled count + name digest, not the raw table', () => {
1660
+ const def = createCrtrBashToolDefinition({ command: 'crtr pkg plugin list' });
1661
+ const collapsed = def
1662
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_LIST_OUTPUT }] }, { expanded: false }, theme, {})
1663
+ .render(140)
1664
+ .join('\n');
1665
+ assert.match(collapsed, /3 plugins · 2 enabled/);
1666
+ assert.match(collapsed, /<muted>ai, beta, gamma<\/muted>/);
1667
+ assert.doesNotMatch(collapsed, /\| name \| scope \|/);
1668
+ const expanded = def
1669
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_LIST_OUTPUT }] }, { expanded: true }, theme, {})
1670
+ .render(140)
1671
+ .join('\n');
1672
+ assert.match(expanded, /\| name \| scope \| version \|/);
1673
+ const empty = def
1674
+ .renderResult({ content: [{ type: 'text', text: '- total: 0\n\n0 items.' }] }, { expanded: false }, theme, {})
1675
+ .render(140)
1676
+ .join('\n');
1677
+ assert.match(empty, /<muted>0 plugins<\/muted>/);
1678
+ // REQUIREMENT: nonzero total with an empty page (exhausted pagination)
1679
+ // must NOT collapse to "0 plugins" — fall back to the generic renderer.
1680
+ const exhausted = def
1681
+ .renderResult({ content: [{ type: 'text', text: '- total: 3\n\n0 items.' }] }, { expanded: false }, theme, {})
1682
+ .render(140)
1683
+ .join('\n');
1684
+ assert.doesNotMatch(exhausted, /0 plugins/);
1685
+ });
1686
+ const PKG_PLUGIN_SHOW_OUTPUT = [
1687
+ '- name: ai',
1688
+ '- scope: user',
1689
+ '- path: /Users/silas/.crouter/plugins/ai',
1690
+ '- enabled: true',
1691
+ '- manifest: {"name":"ai","version":"0.7.1","description":"AI helpers"}',
1692
+ '',
1693
+ '2 docs:',
1694
+ '',
1695
+ '| name | path |',
1696
+ '| --- | --- |',
1697
+ '| ai/x | /Users/silas/.crouter/plugins/ai/memory/ai/x.md |',
1698
+ '| ai/y | /Users/silas/.crouter/plugins/ai/memory/ai/y.md |',
1699
+ ].join('\n');
1700
+ const PKG_PLUGIN_SHOW_DISABLED_OUTPUT = [
1701
+ '- name: beta',
1702
+ '- scope: user',
1703
+ '- path: /Users/silas/.crouter/plugins/beta',
1704
+ '- enabled: false',
1705
+ '- manifest: {"name":"beta","version":"1.0.0","description":"Beta helpers"}',
1706
+ '',
1707
+ '0 docs.',
1708
+ ].join('\n');
1709
+ test('a crtr pkg plugin show card collapses to a name@version + enabled status + doc count, not the raw fields', () => {
1710
+ const def = createCrtrBashToolDefinition({ command: 'crtr pkg plugin show ai' });
1711
+ const collapsed = def
1712
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_SHOW_OUTPUT }] }, { expanded: false }, theme, {})
1713
+ .render(140)
1714
+ .join('\n');
1715
+ assert.match(collapsed, /<success>ai@0\.7\.1 · enabled<\/success>/);
1716
+ assert.match(collapsed, /<muted>2 substrate docs<\/muted>/);
1717
+ assert.doesNotMatch(collapsed, /\| name \| path \|/);
1718
+ const expanded = def
1719
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_SHOW_OUTPUT }] }, { expanded: true }, theme, {})
1720
+ .render(140)
1721
+ .join('\n');
1722
+ assert.match(expanded, /\| name \| path \|/);
1723
+ const disabledDef = createCrtrBashToolDefinition({ command: 'crtr pkg plugin show beta' });
1724
+ const disabled = disabledDef
1725
+ .renderResult({ content: [{ type: 'text', text: PKG_PLUGIN_SHOW_DISABLED_OUTPUT }] }, { expanded: false }, theme, {})
1726
+ .render(140)
1727
+ .join('\n');
1728
+ assert.match(disabled, /<muted>beta@1\.0\.0 · disabled<\/muted>/);
1729
+ assert.match(disabled, /<muted>0 substrate docs<\/muted>/);
1730
+ });
1731
+ const PKG_MARKET_LIST_OUTPUT = [
1732
+ '- total: 2',
1733
+ '',
1734
+ '2 items:',
1735
+ '',
1736
+ '| name | scope | url | ref | path |',
1737
+ '| --- | --- | --- | --- | --- |',
1738
+ '| crouter-official-marketplace | user | https://github.com/crouton-labs/crouter-official-marketplace | main | /Users/silas/.crouter/marketplaces/crouter-official-marketplace |',
1739
+ '| custom-market | project | https://github.com/example/custom-market | main | /Users/silas/Code/cli/crouter/.crouter/marketplaces/custom-market |',
1740
+ ].join('\n');
1741
+ test('a crtr pkg market list card collapses to a marketplace count + name digest, not the raw table', () => {
1742
+ const def = createCrtrBashToolDefinition({ command: 'crtr pkg market list' });
1743
+ const collapsed = def
1744
+ .renderResult({ content: [{ type: 'text', text: PKG_MARKET_LIST_OUTPUT }] }, { expanded: false }, theme, {})
1745
+ .render(140)
1746
+ .join('\n');
1747
+ assert.match(collapsed, /2 marketplaces/);
1748
+ assert.match(collapsed, /<muted>crouter-official-marketplace, custom-market<\/muted>/);
1749
+ assert.doesNotMatch(collapsed, /\| name \| scope \|/);
1750
+ const expanded = def
1751
+ .renderResult({ content: [{ type: 'text', text: PKG_MARKET_LIST_OUTPUT }] }, { expanded: true }, theme, {})
1752
+ .render(140)
1753
+ .join('\n');
1754
+ assert.match(expanded, /\| name \| scope \| url \|/);
1755
+ const empty = def
1756
+ .renderResult({ content: [{ type: 'text', text: '- total: 0\n\n0 items.' }] }, { expanded: false }, theme, {})
1757
+ .render(140)
1758
+ .join('\n');
1759
+ assert.match(empty, /<muted>0 marketplaces<\/muted>/);
1760
+ // REQUIREMENT: nonzero total with an empty page (exhausted pagination)
1761
+ // must NOT collapse to "0 marketplaces" — fall back to the generic renderer.
1762
+ const exhausted = def
1763
+ .renderResult({ content: [{ type: 'text', text: '- total: 3\n\n0 items.' }] }, { expanded: false }, theme, {})
1764
+ .render(140)
1765
+ .join('\n');
1766
+ assert.doesNotMatch(exhausted, /0 marketplaces/);
1767
+ });
1768
+ const PKG_MARKET_BROWSE_ROWS = Array.from({ length: 11 }, (_, i) => {
1769
+ const n = i + 1;
1770
+ return `| p${n} | main | github | 0.${n}.0 | Plugin ${n} | tag${n} | false | |`;
1771
+ });
1772
+ const PKG_MARKET_BROWSE_OUTPUT = [
1773
+ '- marketplace: crouter-official-marketplace',
1774
+ '- total: 11',
1775
+ '',
1776
+ '11 items:',
1777
+ '',
1778
+ '| name | ref | source | version | description | keywords | installed | installed_scope |',
1779
+ '| --- | --- | --- | --- | --- | --- | --- | --- |',
1780
+ ...PKG_MARKET_BROWSE_ROWS,
1781
+ ].join('\n');
1782
+ test('a crtr pkg market browse card collapses to a plugin count in <market> + capped name digest, not the raw table', () => {
1783
+ const def = createCrtrBashToolDefinition({ command: 'crtr pkg market browse crouter-official-marketplace' });
1784
+ const collapsed = def
1785
+ .renderResult({ content: [{ type: 'text', text: PKG_MARKET_BROWSE_OUTPUT }] }, { expanded: false }, theme, {})
1786
+ .render(140)
1787
+ .join('\n');
1788
+ assert.match(collapsed, /11 plugins in crouter-official-marketplace/);
1789
+ assert.match(collapsed, /<muted>p1, p2, p3, p4, p5, p6, p7, p8, … 3 more<\/muted>/);
1790
+ assert.doesNotMatch(collapsed, /\| name \| ref \|/);
1791
+ const expanded = def
1792
+ .renderResult({ content: [{ type: 'text', text: PKG_MARKET_BROWSE_OUTPUT }] }, { expanded: true }, theme, {})
1793
+ .render(140)
1794
+ .join('\n');
1795
+ assert.match(expanded, /\| name \| ref \| source \|/);
1796
+ const empty = def
1797
+ .renderResult({ content: [{ type: 'text', text: '- marketplace: crouter-official-marketplace\n- total: 0\n\n0 items.' }] }, { expanded: false }, theme, {})
1798
+ .render(140)
1799
+ .join('\n');
1800
+ assert.match(empty, /<muted>0 plugins in crouter-official-marketplace<\/muted>/);
1801
+ // REQUIREMENT: nonzero total with an empty page (exhausted pagination)
1802
+ // must NOT collapse to "0 plugins in <market>" — fall back to generic.
1803
+ const exhausted = def
1804
+ .renderResult({ content: [{ type: 'text', text: '- marketplace: crouter-official-marketplace\n- total: 3\n\n0 items.' }] }, { expanded: false }, theme, {})
1805
+ .render(140)
1806
+ .join('\n');
1807
+ assert.doesNotMatch(exhausted, /0 plugins in crouter-official-marketplace/);
1808
+ });
1809
+ // ---------------------------------------------------------------------------
1810
+ // Batch D — search/sys/surface summarizers + sys sysprompt suppression.
1811
+ // ---------------------------------------------------------------------------
1812
+ test('sys sysprompt is command-owned suppressOutput, never on failure', () => {
1813
+ const def = createCrtrBashToolDefinition({ command: 'crtr sys sysprompt abc' });
1814
+ const component = def.renderResult({ content: [{ type: 'text', text: '- node_id: abc\n- captured_at: 2026-07-01T00:00:00.000Z\n- chars: 40000\n\n# System prompt\n...(huge prompt dump)...' }] }, { expanded: false }, theme, {});
1815
+ const collapsed = component.render(80).join('\n');
1816
+ assert.doesNotMatch(collapsed, /huge prompt dump/);
1817
+ assert.match(collapsed, /suppressed — ctrl\+o to expand/);
1818
+ const failedComponent = def.renderResult({ content: [{ type: 'text', text: 'huge dump on failure too' }] }, { expanded: false }, theme, { isError: true });
1819
+ assert.match(failedComponent.render(80).join('\n'), /huge dump on failure too/);
1820
+ });
1821
+ const SEARCH_WEB_OUTPUT = [
1822
+ '2 results for "test query":',
1823
+ '',
1824
+ '### 1. First Result Title',
1825
+ 'https://example.com/page1 · 2024-01-15 · Jane Doe',
1826
+ '- highlight one text here',
1827
+ '- highlight two text here',
1828
+ '',
1829
+ '### 2. Second Result Title',
1830
+ 'https://other.org/page2',
1831
+ '- another highlight',
1832
+ '',
1833
+ 'Fetch full content for selected result URLs with the contents leaf after checking its schema. No good hits? Broaden the query, drop domain filters, or try --type deep.',
1834
+ ].join('\n');
1835
+ test('a crtr search web card collapses to a result count + title — domain digest, not the raw sections', () => {
1836
+ const def = createCrtrBashToolDefinition({ command: 'crtr search web "test query"' });
1837
+ const collapsed = def
1838
+ .renderResult({ content: [{ type: 'text', text: SEARCH_WEB_OUTPUT }] }, { expanded: false }, theme, {})
1839
+ .render(140)
1840
+ .join('\n');
1841
+ assert.match(collapsed, /2 results/);
1842
+ assert.match(collapsed, /<muted>First Result Title — example\.com<\/muted>/);
1843
+ assert.match(collapsed, /<muted>Second Result Title — other\.org<\/muted>/);
1844
+ assert.doesNotMatch(collapsed, /### 1\./);
1845
+ const expanded = def
1846
+ .renderResult({ content: [{ type: 'text', text: SEARCH_WEB_OUTPUT }] }, { expanded: true }, theme, {})
1847
+ .render(140)
1848
+ .join('\n');
1849
+ assert.match(expanded, /### 1\. First Result Title/);
1850
+ assert.match(expanded, /### 2\. Second Result Title/);
1851
+ const empty = def
1852
+ .renderResult({ content: [{ type: 'text', text: 'No results for "empty query".\n\nFetch full content for selected result URLs with the contents leaf after checking its schema. No good hits? Broaden the query, drop domain filters, or try --type deep.' }] }, { expanded: false }, theme, {})
1853
+ .render(140)
1854
+ .join('\n');
1855
+ assert.match(empty, /<muted>0 results for "empty query"<\/muted>/);
1856
+ });
1857
+ const SEARCH_ANSWER_OUTPUT = [
1858
+ 'The answer is 42, according to the sources below.',
1859
+ '',
1860
+ 'Sources (2):',
1861
+ '1. Deep Thought Paper — https://example.com/paper',
1862
+ '2. Hitchhiker Wiki — https://wiki.example.org/guide',
1863
+ '',
1864
+ 'Read any cited source in full with the contents leaf after checking its schema. Want raw ranked results instead of a synthesized answer? Use the web leaf.',
1865
+ ].join('\n');
1866
+ test('a crtr search answer card collapses to the answer teaser + citation count, not the raw sources list', () => {
1867
+ const def = createCrtrBashToolDefinition({ command: 'crtr search answer "what is the answer"' });
1868
+ const collapsed = def
1869
+ .renderResult({ content: [{ type: 'text', text: SEARCH_ANSWER_OUTPUT }] }, { expanded: false }, theme, {})
1870
+ .render(140)
1871
+ .join('\n');
1872
+ assert.match(collapsed, /The answer is 42, according to the sources below\./);
1873
+ assert.match(collapsed, /<muted>2 citations<\/muted>/);
1874
+ assert.doesNotMatch(collapsed, /Sources \(2\):/);
1875
+ const expanded = def
1876
+ .renderResult({ content: [{ type: 'text', text: SEARCH_ANSWER_OUTPUT }] }, { expanded: true }, theme, {})
1877
+ .render(140)
1878
+ .join('\n');
1879
+ assert.match(expanded, /Sources \(2\):/);
1880
+ assert.match(expanded, /Deep Thought Paper/);
1881
+ const noAnswer = def
1882
+ .renderResult({ content: [{ type: 'text', text: 'No answer was returned.\n\nRead any cited source in full with the contents leaf after checking its schema. Want raw ranked results instead of a synthesized answer? Use the web leaf.' }] }, { expanded: false }, theme, {})
1883
+ .render(140)
1884
+ .join('\n');
1885
+ assert.match(noAnswer, /<muted>no answer returned<\/muted>/);
1886
+ });
1887
+ const SEARCH_CONTENTS_OUTPUT = [
1888
+ 'Extracted 2 URLs:',
1889
+ '',
1890
+ '### 1. Example Page',
1891
+ 'https://example.com/a',
1892
+ 'Some highlight text about the page contents that is reasonably long for testing chars count.',
1893
+ '',
1894
+ '### 2. Another Page',
1895
+ 'https://example.org/b',
1896
+ '- bullet one',
1897
+ '- bullet two',
1898
+ '',
1899
+ 'Stale or empty content? Re-run with --max-age-hours 0 to force a fresh crawl. Need to find more pages? Use the web leaf after checking its schema.',
1900
+ ].join('\n');
1901
+ test('a crtr search contents card collapses to a per-URL title + char-count digest, not the raw sections', () => {
1902
+ const def = createCrtrBashToolDefinition({ command: 'crtr search contents https://example.com/a,https://example.org/b' });
1903
+ const collapsed = def
1904
+ .renderResult({ content: [{ type: 'text', text: SEARCH_CONTENTS_OUTPUT }] }, { expanded: false }, theme, {})
1905
+ .render(140)
1906
+ .join('\n');
1907
+ assert.match(collapsed, /extracted 2 URLs/);
1908
+ assert.match(collapsed, /<muted>Example Page · \d+ chars<\/muted>/);
1909
+ assert.match(collapsed, /<muted>Another Page · \d+ chars<\/muted>/);
1910
+ assert.doesNotMatch(collapsed, /### 1\./);
1911
+ const expanded = def
1912
+ .renderResult({ content: [{ type: 'text', text: SEARCH_CONTENTS_OUTPUT }] }, { expanded: true }, theme, {})
1913
+ .render(140)
1914
+ .join('\n');
1915
+ assert.match(expanded, /### 1\. Example Page/);
1916
+ const failed = def
1917
+ .renderResult({
1918
+ content: [{
1919
+ type: 'text',
1920
+ text: [
1921
+ 'No content extracted.',
1922
+ 'Failed (2):',
1923
+ '- https://dead.example.com — 404 Not Found',
1924
+ '- https://slow.example.com — timeout',
1925
+ '',
1926
+ 'Stale or empty content? Re-run with --max-age-hours 0 to force a fresh crawl. Need to find more pages? Use the web leaf after checking its schema.',
1927
+ ].join('\n'),
1928
+ }],
1929
+ }, { expanded: false }, theme, {})
1930
+ .render(140)
1931
+ .join('\n');
1932
+ assert.match(failed, /<error>0 extracted · 2 failed<\/error>/);
1933
+ const nothingAtAll = def
1934
+ .renderResult({ content: [{ type: 'text', text: 'No content extracted.\n\nStale or empty content? Re-run with --max-age-hours 0 to force a fresh crawl. Need to find more pages? Use the web leaf after checking its schema.' }] }, { expanded: false }, theme, {})
1935
+ .render(140)
1936
+ .join('\n');
1937
+ assert.match(nothingAtAll, /<muted>no content extracted<\/muted>/);
1938
+ });
1939
+ const SYS_SETUP_OUTPUT = [
1940
+ 'crtr sys setup (non-interactive)',
1941
+ '',
1942
+ 'Packages:',
1943
+ '- pi-crtr-extensions — crtr companion extensions. (installed)',
1944
+ '- pi-mode-switch — Alt+Shift+P mode cycling. (installed)',
1945
+ '- pi-claude-oauth-adapter — OAuth adapter. (not installed)',
1946
+ '',
1947
+ 'System deps:',
1948
+ '- tmux: ✓ installed',
1949
+ '- nvim: brew install neovim',
1950
+ '',
1951
+ '- Exa key: write to /Users/example/.crouter/exa.key or set EXA_API_KEY',
1952
+ 'Run `crtr sys setup` in a TTY to open the wizard.',
1953
+ ].join('\n');
1954
+ test('a crtr sys setup card collapses to an ok/pending step digest, not the raw sections', () => {
1955
+ const def = createCrtrBashToolDefinition({ command: 'crtr sys setup' });
1956
+ const collapsed = def
1957
+ .renderResult({ content: [{ type: 'text', text: SYS_SETUP_OUTPUT }] }, { expanded: false }, theme, {})
1958
+ .render(140)
1959
+ .join('\n');
1960
+ assert.match(collapsed, /<warning>3 ok · 2 pending<\/warning>/);
1961
+ assert.match(collapsed, /<muted>pi-claude-oauth-adapter, nvim<\/muted>/);
1962
+ assert.doesNotMatch(collapsed, /Packages:/);
1963
+ const expanded = def
1964
+ .renderResult({ content: [{ type: 'text', text: SYS_SETUP_OUTPUT }] }, { expanded: true }, theme, {})
1965
+ .render(140)
1966
+ .join('\n');
1967
+ assert.match(expanded, /Packages:/);
1968
+ assert.match(expanded, /System deps:/);
1969
+ const allOk = def
1970
+ .renderResult({ content: [{ type: 'text', text: SYS_SETUP_OUTPUT.replace('(not installed)', '(installed)').replace('brew install neovim', '✓ installed') }] }, { expanded: false }, theme, {})
1971
+ .render(140)
1972
+ .join('\n');
1973
+ assert.match(allOk, /<success>5 steps ok<\/success>/);
1974
+ });
1975
+ const SYS_DOCTOR_PASS_OUTPUT = [
1976
+ '- ok: true',
1977
+ '- failed: 0',
1978
+ '',
1979
+ '2 checks:',
1980
+ '',
1981
+ '| scope | name | status | message | remediation |',
1982
+ '| --- | --- | --- | --- | --- |',
1983
+ '| user | plugin:ai:dir | pass | directory exists | |',
1984
+ '| user | plugin:ai:manifest | pass | manifest valid | |',
1985
+ ].join('\n');
1986
+ const SYS_DOCTOR_FAIL_OUTPUT = [
1987
+ '- ok: false',
1988
+ '- failed: 1',
1989
+ '',
1990
+ '2 checks:',
1991
+ '',
1992
+ '| scope | name | status | message | remediation |',
1993
+ '| --- | --- | --- | --- | --- |',
1994
+ '| user | plugin:ai:dir | pass | directory exists | |',
1995
+ '| user | plugin:beta:dir | fail | directory missing: /path/to/beta | |',
1996
+ ].join('\n');
1997
+ test('a crtr sys doctor card collapses to PASS or an issue digest, not the raw checks table', () => {
1998
+ const def = createCrtrBashToolDefinition({ command: 'crtr sys doctor' });
1999
+ const pass = def
2000
+ .renderResult({ content: [{ type: 'text', text: SYS_DOCTOR_PASS_OUTPUT }] }, { expanded: false }, theme, {})
2001
+ .render(140)
2002
+ .join('\n');
2003
+ assert.match(pass, /<success>PASS · 2 checks<\/success>/);
2004
+ assert.doesNotMatch(pass, /\| scope \| name \|/);
2005
+ const fail = def
2006
+ .renderResult({ content: [{ type: 'text', text: SYS_DOCTOR_FAIL_OUTPUT }] }, { expanded: false }, theme, {})
2007
+ .render(140)
2008
+ .join('\n');
2009
+ assert.match(fail, /<error>1 issue<\/error>/);
2010
+ assert.match(fail, /<warning>plugin:beta:dir: directory missing: \/path\/to\/beta<\/warning>/);
2011
+ const expanded = def
2012
+ .renderResult({ content: [{ type: 'text', text: SYS_DOCTOR_FAIL_OUTPUT }] }, { expanded: true }, theme, {})
2013
+ .render(140)
2014
+ .join('\n');
2015
+ assert.match(expanded, /\| scope \| name \| status \|/);
2016
+ });
2017
+ const SYS_UPDATE_CHECK_OUTPUT = [
2018
+ '- up_to_date: false',
2019
+ '',
2020
+ '2 updates:',
2021
+ '',
2022
+ '| name | kind | current | latest | up_to_date | unreachable |',
2023
+ '| --- | --- | --- | --- | --- | --- |',
2024
+ '| @north-light/crouter | self | 0.3.34 | 0.3.35 | false | false |',
2025
+ '| some-marketplace | marketplace | abc123 | abc123 | true | false |',
2026
+ ].join('\n');
2027
+ test('a crtr sys update --check card collapses to an outdated/checked digest, not the raw table', () => {
2028
+ const def = createCrtrBashToolDefinition({ command: 'crtr sys update --check' });
2029
+ const collapsed = def
2030
+ .renderResult({ content: [{ type: 'text', text: SYS_UPDATE_CHECK_OUTPUT }] }, { expanded: false }, theme, {})
2031
+ .render(140)
2032
+ .join('\n');
2033
+ assert.match(collapsed, /<warning>1 outdated · 2 checked<\/warning>/);
2034
+ assert.match(collapsed, /<muted>@north-light\/crouter: 0\.3\.34 → 0\.3\.35<\/muted>/);
2035
+ assert.doesNotMatch(collapsed, /\| name \| kind \|/);
2036
+ const expanded = def
2037
+ .renderResult({ content: [{ type: 'text', text: SYS_UPDATE_CHECK_OUTPUT }] }, { expanded: true }, theme, {})
2038
+ .render(140)
2039
+ .join('\n');
2040
+ assert.match(expanded, /\| name \| kind \| current \|/);
2041
+ const upToDate = def
2042
+ .renderResult({ content: [{ type: 'text', text: '- up_to_date: true\n\n1 updates:\n\n| name | kind | current | latest | up_to_date | unreachable |\n| --- | --- | --- | --- | --- | --- |\n| a | self | 1.0.0 | 1.0.0 | true | false |' }] }, { expanded: false }, theme, {})
2043
+ .render(140)
2044
+ .join('\n');
2045
+ assert.match(upToDate, /<success>PASS · 1 up to date<\/success>/);
2046
+ const applyDone = def
2047
+ .renderResult({ content: [{ type: 'text', text: '- target: all\n- status: done' }] }, { expanded: false }, theme, {})
2048
+ .render(140)
2049
+ .join('\n');
2050
+ assert.match(applyDone, /<success>updated · all<\/success>/);
2051
+ const applyFailed = def
2052
+ .renderResult({ content: [{ type: 'text', text: '- target: self\n- status: failed\n- error: network unreachable' }] }, { expanded: false }, theme, {})
2053
+ .render(140)
2054
+ .join('\n');
2055
+ assert.match(applyFailed, /<error>update failed · self<\/error>/);
2056
+ assert.match(applyFailed, /<muted>network unreachable<\/muted>/);
2057
+ });
2058
+ test('a crtr sys feedback card collapses to a filed/saved-locally pointer, not the raw fields', () => {
2059
+ const def = createCrtrBashToolDefinition({ command: 'crtr sys feedback "crtr crashed"' });
2060
+ const filed = def
2061
+ .renderResult({ content: [{ type: 'text', text: '- status: filed\n- url: https://github.com/crouton-labs/crouter/issues/123' }] }, { expanded: false }, theme, {})
2062
+ .render(140)
2063
+ .join('\n');
2064
+ assert.match(filed, /<success>issue filed<\/success>/);
2065
+ assert.match(filed, /<muted>https:\/\/github\.com\/crouton-labs\/crouter\/issues\/123<\/muted>/);
2066
+ const savedText = '- status: saved-locally\n- path: /Users/example/.crouter/feedback/2026-07-01T00-00-00-000Z.md\n- error: gh not available: not found';
2067
+ const saved = def
2068
+ .renderResult({ content: [{ type: 'text', text: savedText }] }, { expanded: false }, theme, {})
2069
+ .render(140)
2070
+ .join('\n');
2071
+ assert.match(saved, /<warning>saved locally — not filed<\/warning>/);
2072
+ assert.match(saved, /<muted>2026-07-01T00-00-00-000Z\.md<\/muted>/);
2073
+ const expanded = def
2074
+ .renderResult({ content: [{ type: 'text', text: savedText }] }, { expanded: true }, theme, {})
2075
+ .render(140)
2076
+ .join('\n');
2077
+ assert.match(expanded, /gh not available: not found/);
2078
+ });
2079
+ const SURFACE_VIEW_LIST_OUTPUT = [
2080
+ 'canvas Canvas [builtin] Live agent graph — who is working, who is blocked',
2081
+ 'chat Chat [builtin] Portable chat-as-a-view core',
2082
+ 'workspace-sidebar Workspace [builtin] Left rail for `crtr workspace` — this graph + other agents in this cwd',
2083
+ ].join('\n');
2084
+ test('a crtr surface view list card collapses to a view count + id digest, not the raw rows', () => {
2085
+ const def = createCrtrBashToolDefinition({ command: 'crtr surface view list' });
2086
+ const collapsed = def
2087
+ .renderResult({ content: [{ type: 'text', text: SURFACE_VIEW_LIST_OUTPUT }] }, { expanded: false }, theme, {})
2088
+ .render(140)
2089
+ .join('\n');
2090
+ assert.match(collapsed, /3 views/);
2091
+ assert.match(collapsed, /<muted>canvas, chat, workspace-sidebar<\/muted>/);
2092
+ assert.doesNotMatch(collapsed, /Live agent graph/);
2093
+ const expanded = def
2094
+ .renderResult({ content: [{ type: 'text', text: SURFACE_VIEW_LIST_OUTPUT }] }, { expanded: true }, theme, {})
2095
+ .render(140)
2096
+ .join('\n');
2097
+ assert.match(expanded, /Live agent graph/);
2098
+ const empty = def
2099
+ .renderResult({ content: [{ type: 'text', text: 'No views found. Scaffold one with the view new leaf.' }] }, { expanded: false }, theme, {})
2100
+ .render(140)
2101
+ .join('\n');
2102
+ assert.match(empty, /No views found/);
2103
+ });