@cmodjs/core 0.3.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/docs/commands.md +50 -10
  2. package/docs/dependencies.md +12 -12
  3. package/docs/hooks.md +39 -27
  4. package/docs/index.md +29 -25
  5. package/docs/install-steps.md +9 -7
  6. package/docs/jobs.md +59 -111
  7. package/docs/mod.md +200 -174
  8. package/docs/options.md +2 -2
  9. package/docs/permissions.md +27 -16
  10. package/docs/session.md +248 -0
  11. package/docs/state.md +11 -7
  12. package/docs/testing.md +65 -22
  13. package/docs/ui.md +108 -76
  14. package/jobs/check.d.ts.map +1 -1
  15. package/jobs/check.js +5 -2
  16. package/jobs/context.d.ts +7 -8
  17. package/jobs/context.d.ts.map +1 -1
  18. package/jobs/context.js +23 -73
  19. package/jobs/permissions/decide-permission.d.ts +5 -3
  20. package/jobs/permissions/decide-permission.d.ts.map +1 -1
  21. package/jobs/permissions/decide-permission.js +6 -4
  22. package/jobs/permissions/find-project-scope.d.ts +1 -1
  23. package/jobs/permissions/find-project-scope.d.ts.map +1 -1
  24. package/jobs/permissions/find-project-scope.js +8 -11
  25. package/jobs/permissions/match-target.d.ts +2 -2
  26. package/jobs/permissions/match-target.d.ts.map +1 -1
  27. package/jobs/permissions.d.ts +1 -1
  28. package/jobs/permissions.d.ts.map +1 -1
  29. package/jobs/permissions.js +6 -4
  30. package/jobs/program.d.ts.map +1 -1
  31. package/jobs/program.js +8 -3
  32. package/jobs/prompt.d.ts +4 -2
  33. package/jobs/prompt.d.ts.map +1 -1
  34. package/jobs/prompt.js +16 -15
  35. package/jobs/schedule.d.ts +2 -2
  36. package/jobs/schedule.d.ts.map +1 -1
  37. package/jobs/schedule.js +9 -9
  38. package/jobs/slash-command.d.ts +4 -4
  39. package/jobs/slash-command.d.ts.map +1 -1
  40. package/jobs/slash-command.js +14 -9
  41. package/jobs/status-line.d.ts +1 -11
  42. package/jobs/status-line.d.ts.map +1 -1
  43. package/jobs/status-line.js +8 -12
  44. package/jobs/tool.d.ts +2 -2
  45. package/jobs/tool.d.ts.map +1 -1
  46. package/jobs/tool.js +15 -9
  47. package/mod.d.ts +154 -75
  48. package/mod.d.ts.map +1 -1
  49. package/mod.js +94 -3
  50. package/options.d.ts +2 -2
  51. package/options.js +19 -19
  52. package/package.json +3 -3
  53. package/records.d.ts +10 -8
  54. package/records.d.ts.map +1 -1
  55. package/records.js +28 -17
  56. package/register.d.ts.map +1 -1
  57. package/register.js +17 -5
  58. package/runtime/announce.d.ts +18 -0
  59. package/runtime/announce.d.ts.map +1 -0
  60. package/runtime/announce.js +66 -0
  61. package/runtime/bound.d.ts +4 -0
  62. package/runtime/bound.d.ts.map +1 -0
  63. package/runtime/bound.js +9 -0
  64. package/runtime/claude.d.ts +3 -2
  65. package/runtime/claude.d.ts.map +1 -1
  66. package/runtime/conversations.d.ts +16 -0
  67. package/runtime/conversations.d.ts.map +1 -0
  68. package/runtime/conversations.js +291 -0
  69. package/runtime/deadline.d.ts +0 -1
  70. package/runtime/deadline.d.ts.map +1 -1
  71. package/runtime/deadline.js +1 -1
  72. package/runtime/dependencies.d.ts +2 -0
  73. package/runtime/dependencies.d.ts.map +1 -1
  74. package/runtime/dependencies.js +9 -0
  75. package/runtime/engine.d.ts +17 -0
  76. package/runtime/engine.d.ts.map +1 -0
  77. package/runtime/engine.js +10 -0
  78. package/runtime/grants.d.ts +4 -0
  79. package/runtime/grants.d.ts.map +1 -1
  80. package/runtime/grants.js +63 -26
  81. package/runtime/hooks.d.ts +5 -4
  82. package/runtime/hooks.d.ts.map +1 -1
  83. package/runtime/hooks.js +10 -5
  84. package/runtime/installer.d.ts.map +1 -1
  85. package/runtime/installer.js +11 -9
  86. package/runtime/lifecycle.d.ts +3 -1
  87. package/runtime/lifecycle.d.ts.map +1 -1
  88. package/runtime/lifecycle.js +316 -185
  89. package/runtime/metadata.d.ts +3 -1
  90. package/runtime/metadata.d.ts.map +1 -1
  91. package/runtime/metadata.js +21 -11
  92. package/runtime/options.d.ts +3 -1
  93. package/runtime/options.d.ts.map +1 -1
  94. package/runtime/options.js +4 -4
  95. package/runtime/programs.d.ts +8 -0
  96. package/runtime/programs.d.ts.map +1 -1
  97. package/runtime/programs.js +39 -1
  98. package/runtime/router.d.ts +2 -1
  99. package/runtime/router.d.ts.map +1 -1
  100. package/runtime/router.js +11 -3
  101. package/runtime/sessions.d.ts +36 -0
  102. package/runtime/sessions.d.ts.map +1 -0
  103. package/runtime/sessions.js +235 -0
  104. package/runtime/state.d.ts +6 -2
  105. package/runtime/state.d.ts.map +1 -1
  106. package/runtime/state.js +46 -13
  107. package/runtime/toaster.d.ts +31 -0
  108. package/runtime/toaster.d.ts.map +1 -0
  109. package/runtime/toaster.js +176 -0
  110. package/runtime/ui.d.ts +6 -17
  111. package/runtime/ui.d.ts.map +1 -1
  112. package/runtime/ui.js +36 -112
  113. package/session/context/context.d.ts +10 -0
  114. package/session/context/context.d.ts.map +1 -0
  115. package/session/context/context.js +2 -0
  116. package/session/context/turn/message/document.d.ts +7 -0
  117. package/session/context/turn/message/document.d.ts.map +1 -0
  118. package/session/context/turn/message/document.js +1 -0
  119. package/session/context/turn/message/message.d.ts +54 -0
  120. package/session/context/turn/message/message.d.ts.map +1 -0
  121. package/session/context/turn/message/message.js +137 -0
  122. package/session/context/turn/message/note.d.ts +8 -0
  123. package/session/context/turn/message/note.d.ts.map +1 -0
  124. package/session/context/turn/message/note.js +1 -0
  125. package/session/context/turn/message/notice.d.ts +6 -0
  126. package/session/context/turn/message/notice.d.ts.map +1 -0
  127. package/session/context/turn/message/notice.js +1 -0
  128. package/session/context/turn/message/prompt.d.ts +8 -0
  129. package/session/context/turn/message/prompt.d.ts.map +1 -0
  130. package/session/context/turn/message/prompt.js +1 -0
  131. package/session/context/turn/message/reply.d.ts +6 -0
  132. package/session/context/turn/message/reply.d.ts.map +1 -0
  133. package/session/context/turn/message/reply.js +1 -0
  134. package/session/context/turn/message/sender.d.ts +14 -0
  135. package/session/context/turn/message/sender.d.ts.map +1 -0
  136. package/session/context/turn/message/sender.js +30 -0
  137. package/session/context/turn/message/skill.d.ts +7 -0
  138. package/session/context/turn/message/skill.d.ts.map +1 -0
  139. package/session/context/turn/message/skill.js +1 -0
  140. package/session/context/turn/message/tool-call.d.ts +9 -0
  141. package/session/context/turn/message/tool-call.d.ts.map +1 -0
  142. package/session/context/turn/message/tool-call.js +1 -0
  143. package/session/context/turn/message/tool-result.d.ts +8 -0
  144. package/session/context/turn/message/tool-result.d.ts.map +1 -0
  145. package/session/context/turn/message/tool-result.js +1 -0
  146. package/session/context/turn/turn.d.ts +12 -0
  147. package/session/context/turn/turn.d.ts.map +1 -0
  148. package/session/context/turn/turn.js +2 -0
  149. package/session/conversation.d.ts +64 -0
  150. package/session/conversation.d.ts.map +1 -0
  151. package/session/conversation.js +123 -0
  152. package/session/goal/goal.d.ts +10 -0
  153. package/session/goal/goal.d.ts.map +1 -0
  154. package/session/goal/goal.js +1 -0
  155. package/session/goal/task.d.ts +16 -0
  156. package/session/goal/task.d.ts.map +1 -0
  157. package/session/goal/task.js +3 -0
  158. package/session/session.d.ts +99 -0
  159. package/session/session.d.ts.map +1 -0
  160. package/session/session.js +1 -0
  161. package/src/jobs/check.ts +7 -4
  162. package/src/jobs/context.ts +24 -82
  163. package/src/jobs/permissions/decide-permission.ts +10 -8
  164. package/src/jobs/permissions/find-project-scope.ts +8 -14
  165. package/src/jobs/permissions/match-target.ts +3 -3
  166. package/src/jobs/permissions.ts +8 -6
  167. package/src/jobs/program.ts +7 -3
  168. package/src/jobs/prompt.ts +21 -24
  169. package/src/jobs/schedule.ts +14 -14
  170. package/src/jobs/slash-command.ts +20 -14
  171. package/src/jobs/status-line.ts +9 -21
  172. package/src/jobs/tool.ts +17 -11
  173. package/src/mod.ts +209 -97
  174. package/src/options.ts +22 -22
  175. package/src/records.ts +35 -23
  176. package/src/register.ts +17 -5
  177. package/src/runtime/announce.ts +74 -0
  178. package/src/runtime/bound.ts +12 -0
  179. package/src/runtime/claude.ts +4 -2
  180. package/src/runtime/conversations.ts +302 -0
  181. package/src/runtime/deadline.ts +2 -2
  182. package/src/runtime/dependencies.ts +12 -0
  183. package/src/runtime/engine.ts +22 -0
  184. package/src/runtime/grants.ts +66 -24
  185. package/src/runtime/hooks.ts +19 -10
  186. package/src/runtime/installer.ts +10 -9
  187. package/src/runtime/lifecycle.ts +312 -180
  188. package/src/runtime/metadata.ts +33 -11
  189. package/src/runtime/options.ts +19 -4
  190. package/src/runtime/programs.ts +40 -1
  191. package/src/runtime/router.ts +11 -4
  192. package/src/runtime/sessions.ts +242 -0
  193. package/src/runtime/state.ts +50 -14
  194. package/src/runtime/toaster.ts +218 -0
  195. package/src/runtime/ui.ts +42 -139
  196. package/src/session/context/context.ts +12 -0
  197. package/src/session/context/turn/message/document.ts +8 -0
  198. package/src/session/context/turn/message/message.ts +165 -0
  199. package/src/session/context/turn/message/note.ts +9 -0
  200. package/src/session/context/turn/message/notice.ts +7 -0
  201. package/src/session/context/turn/message/prompt.ts +9 -0
  202. package/src/session/context/turn/message/reply.ts +7 -0
  203. package/src/session/context/turn/message/sender.ts +38 -0
  204. package/src/session/context/turn/message/skill.ts +8 -0
  205. package/src/session/context/turn/message/tool-call.ts +10 -0
  206. package/src/session/context/turn/message/tool-result.ts +9 -0
  207. package/src/session/context/turn/turn.ts +14 -0
  208. package/src/session/conversation.ts +169 -0
  209. package/src/session/goal/goal.ts +9 -0
  210. package/src/session/goal/task.ts +19 -0
  211. package/src/session/session.ts +94 -0
  212. package/src/testing/fake-claude.ts +22 -16
  213. package/src/testing/fake-elements.ts +3 -2
  214. package/src/testing/fake-files.ts +1 -1
  215. package/src/testing/fake-sessions.ts +203 -0
  216. package/src/testing.ts +112 -33
  217. package/src/ui/components.ts +3 -3
  218. package/src/ui/elements.ts +22 -8
  219. package/src/ui/markdown.ts +22 -26
  220. package/src/ui/places.ts +49 -0
  221. package/src/utils/call-effects.ts +3 -3
  222. package/src/utils/changelog.ts +32 -0
  223. package/src/utils/matcher.ts +37 -0
  224. package/src/utils/metadata.ts +17 -15
  225. package/src/utils/parse-shell.ts +9 -8
  226. package/src/utils/paths.ts +15 -1
  227. package/src/utils/text.ts +4 -0
  228. package/testing/fake-claude.d.ts +4 -1
  229. package/testing/fake-claude.d.ts.map +1 -1
  230. package/testing/fake-claude.js +18 -11
  231. package/testing/fake-elements.js +4 -2
  232. package/testing/fake-files.js +1 -1
  233. package/testing/fake-sessions.d.ts +74 -0
  234. package/testing/fake-sessions.d.ts.map +1 -0
  235. package/testing/fake-sessions.js +170 -0
  236. package/testing.d.ts +33 -13
  237. package/testing.d.ts.map +1 -1
  238. package/testing.js +92 -21
  239. package/ui/components.d.ts +2 -3
  240. package/ui/components.d.ts.map +1 -1
  241. package/ui/components.js +3 -3
  242. package/ui/elements.d.ts.map +1 -1
  243. package/ui/elements.js +19 -9
  244. package/ui/markdown.d.ts +35 -33
  245. package/ui/markdown.d.ts.map +1 -1
  246. package/ui/markdown.js +14 -16
  247. package/ui/places.d.ts +43 -0
  248. package/ui/places.d.ts.map +1 -0
  249. package/ui/places.js +31 -0
  250. package/utils/call-effects.d.ts +1 -1
  251. package/utils/call-effects.d.ts.map +1 -1
  252. package/utils/call-effects.js +2 -2
  253. package/utils/changelog.d.ts +9 -0
  254. package/utils/changelog.d.ts.map +1 -0
  255. package/utils/changelog.js +29 -0
  256. package/utils/matcher.d.ts +13 -0
  257. package/utils/matcher.d.ts.map +1 -0
  258. package/utils/matcher.js +32 -0
  259. package/utils/metadata.d.ts +3 -3
  260. package/utils/metadata.js +18 -14
  261. package/utils/parse-shell.js +9 -7
  262. package/utils/paths.d.ts +2 -0
  263. package/utils/paths.d.ts.map +1 -1
  264. package/utils/paths.js +13 -1
  265. package/utils/text.d.ts +1 -0
  266. package/utils/text.d.ts.map +1 -1
  267. package/utils/text.js +3 -0
  268. package/src/ui/slots.ts +0 -36
  269. package/ui/slots.d.ts +0 -208
  270. package/ui/slots.d.ts.map +0 -1
  271. package/ui/slots.js +0 -19
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/ui/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEjD,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/D,KAAK,YAAY,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC,CAAA;AAYjI,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAA;AAElH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,CAAA;AAEzJ,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,cAAc,CAAA;CAC5C,CAAA;AAoID,eAAO,MAAM,aAAa;IACxB,OAAO;wBAtJoB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;;IAuJhD,SAAS;IACT,SAAS;uBAvJc,MAAM,GAAG,SAAS;uBAAiB,MAAM,GAAG,SAAS;wBAAkB,MAAM;;IAwJpG,UAAU;IACV,IAAI;0BAxJsB,OAAO;wBAAkB,MAAM,GAAG,SAAS;yBAAmB,OAAO;;IAyJ/F,KAAK;wBAxJoB,SAAS,CAAC,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE;;IAyJxE,aAAa;IACb,SAAS;wBAzJe,MAAM;;CA0J/B,CAAA;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAG7G"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/ui/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE/D,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;IAClD,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACtG,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAA;IACjG,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAA;KAAE,CAAA;IAC1E,IAAI,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,MAAM,WAAW,GAAG,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;AAEhH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAA;AAElH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,CAAA;AAEzJ,MAAM,MAAM,aAAa,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,YAAY,IAAI,cAAc,CAAA;CAC/B,CAAA;AAMD,eAAO,MAAM,OAAO,0BAAsC,CAAA;AAC1D,eAAO,MAAM,SAAS,4BAA0C,CAAA;AAChE,eAAO,MAAM,SAAS,uBAAqC,CAAA;AAC3D,eAAO,MAAM,UAAU,6BAA4C,CAAA;AACnE,eAAO,MAAM,IAAI,uBAAgC,CAAA;AACjD,eAAO,MAAM,KAAK,wBAAkC,CAAA;AACpD,eAAO,MAAM,aAAa,gCAAkD,CAAA;AAC5E,eAAO,MAAM,SAAS,uBAAqC,CAAA;AA4B3D,wBAAgB,YAAY,IAAI,cAAc,CA0C7C;AA0DD,wBAAgB,cAAc,CAAC,CAAC,SAAS,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAGhH"}
package/ui/markdown.js CHANGED
@@ -1,4 +1,15 @@
1
1
  import { fromMarkdown, gfm, gfmFromMarkdown, toString } from '../vendor-markdown.js';
2
+ function markdownPlace(name, markdown) {
3
+ return { name, markdown, createReader };
4
+ }
5
+ export const Heading = markdownPlace('Heading', 'heading');
6
+ export const Paragraph = markdownPlace('Paragraph', 'paragraph');
7
+ export const CodeBlock = markdownPlace('CodeBlock', 'code');
8
+ export const BlockQuote = markdownPlace('BlockQuote', 'blockquote');
9
+ export const List = markdownPlace('List', 'list');
10
+ export const Table = markdownPlace('Table', 'table');
11
+ export const ThematicBreak = markdownPlace('ThematicBreak', 'thematicBreak');
12
+ export const HtmlBlock = markdownPlace('HtmlBlock', 'html');
2
13
  const keptReplies = 64;
3
14
  const extensions = [gfm()];
4
15
  const mdastExtensions = [gfmFromMarkdown()];
@@ -6,7 +17,7 @@ const lineByLine = new Set(['list', 'listItem', 'blockquote', 'table', 'tableRow
6
17
  const definitions = new Set(['definition', 'footnoteDefinition']);
7
18
  const blankLine = /\n[^\S\n]*\n/;
8
19
  const fence = /^ {0,3}(`{3}|~{3})/;
9
- function createReader() {
20
+ export function createReader() {
10
21
  const replies = [];
11
22
  const remember = (reply) => {
12
23
  replies.push(reply);
@@ -109,20 +120,7 @@ function plainText(node) {
109
120
  return toString(node);
110
121
  return node.children.map(plainText).join(node.type === 'tableRow' ? '\t' : '\n');
111
122
  }
112
- function markdownSlot(name, type) {
113
- return { markdown: { name, type, createReader } };
114
- }
115
- export const markdownSlots = {
116
- Heading: markdownSlot('Heading', 'heading'),
117
- Paragraph: markdownSlot('Paragraph', 'paragraph'),
118
- CodeBlock: markdownSlot('CodeBlock', 'code'),
119
- BlockQuote: markdownSlot('BlockQuote', 'blockquote'),
120
- List: markdownSlot('List', 'list'),
121
- Table: markdownSlot('Table', 'table'),
122
- ThematicBreak: markdownSlot('ThematicBreak', 'thematicBreak'),
123
- HtmlBlock: markdownSlot('HtmlBlock', 'html'),
124
- };
125
- export function markdownBlocks(text, slot) {
126
- const blocks = parsed(text, 0).filter((block) => block.type === slot.markdown.type);
123
+ export function markdownBlocks(text, place) {
124
+ const blocks = parsed(text, 0).filter((block) => block.type === place.markdown);
127
125
  return blocks.map((block) => block.props);
128
126
  }
package/ui/places.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code';
2
+ import type { BlockProps, MarkdownPlace } from './markdown.js';
3
+ export declare const ToolGroup = "toolGroup";
4
+ export declare const ToolProgress = "toolProgress";
5
+ export declare const CommandOutput = "commandOutput";
6
+ export declare const AskUserQuestion = "askUserQuestion";
7
+ export declare const Spinner = "spinner";
8
+ export declare const TurnDuration = "turnDuration";
9
+ export declare const SessionMode = "sessionMode";
10
+ export declare const PromptHint = "promptHint";
11
+ export declare const AbovePrompt = "abovePrompt";
12
+ declare const components: {
13
+ readonly prompt: 'UserMessage';
14
+ readonly reply: 'AssistantMessage';
15
+ readonly toolCall: 'ToolUse';
16
+ readonly toolResult: 'ToolResult';
17
+ readonly notice: 'InfoNotice';
18
+ readonly toolGroup: 'ToolGroup';
19
+ readonly toolProgress: 'ToolProgress';
20
+ readonly commandOutput: 'CommandOutput';
21
+ readonly askUserQuestion: 'AskUserQuestion';
22
+ readonly spinner: 'Spinner';
23
+ readonly turnDuration: 'TurnDuration';
24
+ readonly sessionMode: 'SessionMode';
25
+ readonly promptHint: 'PromptHint';
26
+ readonly abovePrompt: 'AbovePrompt';
27
+ };
28
+ export type ComponentPlace = keyof typeof components;
29
+ export type Place = ComponentPlace | MarkdownPlace;
30
+ type ComponentProps = {
31
+ readonly [P in ComponentPlace]: RenderPropsOf[(typeof components)[P]];
32
+ };
33
+ type PropsOf<P extends Place> = P extends ComponentPlace ? ComponentProps[P] : P extends MarkdownPlace<infer Type> ? BlockProps<Type> : never;
34
+ type DefaultOf<P extends Place> = P extends ComponentPlace ? Partial<Omit<ComponentProps[P], 'onScreen'>> : {
35
+ readonly source?: string;
36
+ };
37
+ export type PlaceProps<P extends Place> = Frozen<PropsOf<P>> & {
38
+ readonly Default: (props: Frozen<DefaultOf<P>>) => RenderElement;
39
+ };
40
+ export declare function componentOf(place: Place): Exclude<RenderComponent, 'Pane'> | undefined;
41
+ export declare function nameOf(place: Place): string;
42
+ export {};
43
+ //# sourceMappingURL=places.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"places.d.ts","sourceRoot":"","sources":["../src/ui/places.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE9D,eAAO,MAAM,SAAS,cAAc,CAAA;AACpC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAC5C,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAChD,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,WAAW,gBAAgB,CAAA;AACxC,eAAO,MAAM,UAAU,eAAe,CAAA;AACtC,eAAO,MAAM,WAAW,gBAAgB,CAAA;AAExC,QAAA,MAAM,UAAU;qBACN,aAAa;oBACd,kBAAkB;uBACf,SAAS;yBACP,YAAY;qBAChB,YAAY;wBACP,WAAW;2BACR,cAAc;4BACb,eAAe;8BACb,iBAAiB;sBACzB,SAAS;2BACJ,cAAc;0BACf,aAAa;yBACd,YAAY;0BACX,aAAa;CACiD,CAAA;AAE/E,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,UAAU,CAAA;AAEpD,MAAM,MAAM,KAAK,GAAG,cAAc,GAAG,aAAa,CAAA;AAElD,KAAK,cAAc,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,cAAc,GAAG,aAAa,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE/F,KAAK,OAAO,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,aAAa,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;AAE7I,KAAK,SAAS,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAExI,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAA;CAAE,CAAA;AAEnI,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,SAAS,CAEtF;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAE3C"}
package/ui/places.js ADDED
@@ -0,0 +1,31 @@
1
+ export const ToolGroup = 'toolGroup';
2
+ export const ToolProgress = 'toolProgress';
3
+ export const CommandOutput = 'commandOutput';
4
+ export const AskUserQuestion = 'askUserQuestion';
5
+ export const Spinner = 'spinner';
6
+ export const TurnDuration = 'turnDuration';
7
+ export const SessionMode = 'sessionMode';
8
+ export const PromptHint = 'promptHint';
9
+ export const AbovePrompt = 'abovePrompt';
10
+ const components = {
11
+ prompt: 'UserMessage',
12
+ reply: 'AssistantMessage',
13
+ toolCall: 'ToolUse',
14
+ toolResult: 'ToolResult',
15
+ notice: 'InfoNotice',
16
+ [ToolGroup]: 'ToolGroup',
17
+ [ToolProgress]: 'ToolProgress',
18
+ [CommandOutput]: 'CommandOutput',
19
+ [AskUserQuestion]: 'AskUserQuestion',
20
+ [Spinner]: 'Spinner',
21
+ [TurnDuration]: 'TurnDuration',
22
+ [SessionMode]: 'SessionMode',
23
+ [PromptHint]: 'PromptHint',
24
+ [AbovePrompt]: 'AbovePrompt',
25
+ };
26
+ export function componentOf(place) {
27
+ return typeof place === 'string' && Object.hasOwn(components, place) ? components[place] : undefined;
28
+ }
29
+ export function nameOf(place) {
30
+ return typeof place === 'string' ? `${place.charAt(0).toUpperCase()}${place.slice(1)}` : place.name;
31
+ }
@@ -18,7 +18,7 @@ export type FileCall = CallBase & {
18
18
  export type FetchCall = CallBase & {
19
19
  url: string;
20
20
  };
21
- export type ToolCall = CommandCall | FileCall | FetchCall | CallBase;
21
+ export type Call = CommandCall | FileCall | FetchCall | CallBase;
22
22
  export type Contents = {
23
23
  content?: string;
24
24
  previousContent?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"call-effects.d.ts","sourceRoot":"","sources":["../src/utils/call-effects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAGxD,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACvH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG;IAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CAAA;AAClG,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAC9F,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAClD,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEpE,MAAM,MAAM,QAAQ,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACrE,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAA;CAAE,CAAA;AAC1F,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAA;IACrF,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B,CAAA;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,GAAG,WAAW,CAsChH;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAEzE;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,QAAQ,GAAG,QAAQ,CAElF"}
1
+ {"version":3,"file":"call-effects.d.ts","sourceRoot":"","sources":["../src/utils/call-effects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAyB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAGnE,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACvH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG;IAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CAAA;AAClG,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAC9F,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAClD,MAAM,MAAM,IAAI,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEhE,MAAM,MAAM,QAAQ,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AACrE,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAA;CAAE,CAAA;AAC1F,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,YAAY,EAAE,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAA;IACrF,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B,CAAA;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,GAAG,WAAW,CAsChH;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAEzE;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,QAAQ,GAAG,QAAQ,CAElF"}
@@ -1,5 +1,5 @@
1
1
  import { parseShell } from './parse-shell.js';
2
- import { expandHome } from './paths.js';
2
+ import { expandHome, ifMissing } from './paths.js';
3
3
  import { resolve } from '../vendor.js';
4
4
  export function callEffects(use, workspace) {
5
5
  const { fs } = workspace;
@@ -69,7 +69,7 @@ async function editedContents(use, path, fs) {
69
69
  return contentsOf(content, previousContent);
70
70
  }
71
71
  async function previousContentOf(path, fs) {
72
- const stat = await fs.stat(path).catch(() => undefined);
72
+ const stat = await fs.stat(path).catch(ifMissing(undefined));
73
73
  return stat?.kind === 'file' ? fs.read(path) : undefined;
74
74
  }
75
75
  function contentsOf(content, previousContent) {
@@ -0,0 +1,9 @@
1
+ export type ChangelogSection = {
2
+ readonly version: string;
3
+ readonly date?: string;
4
+ readonly text: string;
5
+ };
6
+ export declare const unreleased = "Unreleased";
7
+ export declare function changelogSections(markdown: string): ChangelogSection[];
8
+ export declare function changeLines(text: string): string[];
9
+ //# sourceMappingURL=changelog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changelog.d.ts","sourceRoot":"","sources":["../src/utils/changelog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1G,eAAO,MAAM,UAAU,eAAe,CAAA;AAMtC,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAQtE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAalD"}
@@ -0,0 +1,29 @@
1
+ export const unreleased = 'Unreleased';
2
+ const heading = /^##\s+\[?([^\]\s]+)\]?(?:\s+-\s+(\S+))?\s*$/;
3
+ const linkReference = /^\[[^\]]+\]:\s/;
4
+ export function changelogSections(markdown) {
5
+ const sections = [];
6
+ for (const line of markdown.split('\n')) {
7
+ const match = heading.exec(line);
8
+ if (match !== null)
9
+ sections.push({ version: match[1], date: match[2], lines: [] });
10
+ else if (!linkReference.test(line))
11
+ sections.at(-1)?.lines.push(line);
12
+ }
13
+ return sections.map(({ version, date, lines }) => ({ version, ...(date === undefined ? {} : { date }), text: lines.join('\n').trim() }));
14
+ }
15
+ export function changeLines(text) {
16
+ let group;
17
+ return text.split('\n').flatMap((line) => {
18
+ const trimmed = line.trim();
19
+ const subheading = /^###\s+(.+)$/.exec(trimmed)?.[1];
20
+ if (subheading !== undefined) {
21
+ group = subheading;
22
+ return [];
23
+ }
24
+ const item = /^[-*]\s+(.+)$/.exec(trimmed)?.[1] ?? trimmed;
25
+ if (item === '')
26
+ return [];
27
+ return [group === undefined ? item : `${group}: ${item}`];
28
+ });
29
+ }
@@ -0,0 +1,13 @@
1
+ export type Matcher<Value> = Value extends string ? string | RegExp : Value extends number | boolean | null | undefined ? Value : Value extends readonly (infer Item)[] ? Matcher<Item> : Value extends (...args: never[]) => unknown ? never : Value extends object ? {
2
+ readonly [Key in keyof Value]?: Matcher<Value[Key]>;
3
+ } : Value;
4
+ export type SentMatcher = string | number | boolean | null | {
5
+ readonly regexp: string;
6
+ readonly flags: string;
7
+ } | {
8
+ readonly [key: string]: SentMatcher;
9
+ } | readonly SentMatcher[];
10
+ export declare function matches(value: unknown, matcher: unknown): boolean;
11
+ export declare function sentMatcher(matcher: unknown): SentMatcher;
12
+ export declare function receivedMatcher(sent: SentMatcher): unknown;
13
+ //# sourceMappingURL=matcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../src/utils/matcher.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,KAAK,IAAI,KAAK,SAAS,MAAM,GAC7C,MAAM,GAAG,MAAM,GACf,KAAK,SAAS,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAC/C,KAAK,GACL,KAAK,SAAS,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC,GACb,KAAK,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GACzC,KAAK,GACL,KAAK,SAAS,MAAM,GAClB;IAAE,QAAQ,EAAE,GAAG,IAAI,MAAM,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;CAAE,GACvD,KAAK,CAAA;AAEjB,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GAAG,SAAS,WAAW,EAAE,CAAA;AAEnL,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAOjE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAKzD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAM1D"}
@@ -0,0 +1,32 @@
1
+ export function matches(value, matcher) {
2
+ if (matcher instanceof RegExp)
3
+ return matcher.test(String(value));
4
+ if (Array.isArray(matcher))
5
+ return matcher.some((each) => matches(value, each));
6
+ if (typeof matcher !== 'object' || matcher === null)
7
+ return value === matcher;
8
+ if (Array.isArray(value))
9
+ return value.some((each) => matches(each, matcher));
10
+ if (typeof value !== 'object' || value === null)
11
+ return false;
12
+ return Object.entries(matcher).every(([key, wanted]) => wanted === undefined || matches(value[key], wanted));
13
+ }
14
+ export function sentMatcher(matcher) {
15
+ if (matcher instanceof RegExp)
16
+ return { regexp: matcher.source, flags: matcher.flags };
17
+ if (Array.isArray(matcher))
18
+ return matcher.map(sentMatcher);
19
+ if (typeof matcher !== 'object' || matcher === null)
20
+ return matcher;
21
+ return Object.fromEntries(Object.entries(matcher).filter(([, value]) => value !== undefined).map(([key, value]) => [key, sentMatcher(value)]));
22
+ }
23
+ export function receivedMatcher(sent) {
24
+ if (Array.isArray(sent))
25
+ return sent.map(receivedMatcher);
26
+ if (typeof sent !== 'object' || sent === null)
27
+ return sent;
28
+ const fields = sent;
29
+ if (typeof fields['regexp'] === 'string' && typeof fields['flags'] === 'string' && Object.keys(fields).length === 2)
30
+ return new RegExp(fields['regexp'], fields['flags']);
31
+ return Object.fromEntries(Object.entries(fields).map(([key, value]) => [key, receivedMatcher(value)]));
32
+ }
@@ -1,10 +1,10 @@
1
1
  export type MetadataFormat = {
2
- readonly kind: 'frontmatter';
2
+ readonly type: 'frontmatter';
3
3
  } | {
4
- readonly kind: 'comment';
4
+ readonly type: 'comment';
5
5
  readonly prefix: string;
6
6
  } | {
7
- readonly kind: 'sidecar';
7
+ readonly type: 'sidecar';
8
8
  };
9
9
  export type ReadMetadata = {
10
10
  readonly metadata: Readonly<Record<string, string>>;
package/utils/metadata.js CHANGED
@@ -16,34 +16,34 @@ export function formatOf(path, firstLine) {
16
16
  const dot = name.lastIndexOf('.');
17
17
  const extension = dot <= 0 ? '' : name.slice(dot + 1).toLowerCase();
18
18
  if (markdown.includes(extension))
19
- return { kind: 'frontmatter' };
19
+ return { type: 'frontmatter' };
20
20
  if (hashComments.includes(extension) || hashCommentNames.includes(name))
21
- return { kind: 'comment', prefix: '#' };
21
+ return { type: 'comment', prefix: '#' };
22
22
  if (slashComments.includes(extension))
23
- return { kind: 'comment', prefix: '//' };
23
+ return { type: 'comment', prefix: '//' };
24
24
  if (dashComments.includes(extension))
25
- return { kind: 'comment', prefix: '--' };
25
+ return { type: 'comment', prefix: '--' };
26
26
  if (extension === '' && firstLine?.startsWith('#!') === true)
27
- return { kind: 'comment', prefix: '#' };
28
- return { kind: 'sidecar' };
27
+ return { type: 'comment', prefix: '#' };
28
+ return { type: 'sidecar' };
29
29
  }
30
30
  export function readMetadata(text, format) {
31
31
  const lines = text.split('\n');
32
- if (format.kind === 'comment') {
32
+ if (format.type === 'comment') {
33
33
  const region = commentRegion(lines, format.prefix);
34
34
  return { metadata: region === undefined ? {} : asRecord(mapEntries(region.lines, region.start + 2, 0)) };
35
35
  }
36
- const region = format.kind === 'frontmatter' ? frontmatterRegion(lines) : { start: -1, end: lines.length, lines };
36
+ const region = format.type === 'frontmatter' ? frontmatterRegion(lines) : { start: -1, end: lines.length, lines };
37
37
  if (region === undefined)
38
38
  return { metadata: {} };
39
39
  const block = metadataBlock(region);
40
- const name = format.kind === 'frontmatter' ? topLevelScalar(region, 'name') : undefined;
40
+ const name = format.type === 'frontmatter' ? topLevelScalar(region, 'name') : undefined;
41
41
  return { metadata: block === undefined ? {} : asRecord(block.entries), ...(name === undefined ? {} : { name }) };
42
42
  }
43
43
  export function writeMetadata(text, format, metadata) {
44
44
  const lines = text.split('\n');
45
45
  const entries = Object.entries(metadata);
46
- if (format.kind === 'comment') {
46
+ if (format.type === 'comment') {
47
47
  const { prefix } = format;
48
48
  const block = entries.length === 0 ? [] : [`${prefix} /// metadata`, ...entries.map(([key, value]) => `${prefix} ${scalar(key)}: ${scalar(value)}`), `${prefix} ///`];
49
49
  const region = commentRegion(lines, prefix);
@@ -55,7 +55,7 @@ export function writeMetadata(text, format, metadata) {
55
55
  return [...lines.slice(0, at), ...block, ...lines.slice(at)].join('\n');
56
56
  }
57
57
  const map = entries.length === 0 ? [] : ['metadata:', ...entries.map(([key, value]) => ` ${scalar(key)}: ${scalar(value)}`)];
58
- if (format.kind === 'sidecar') {
58
+ if (format.type === 'sidecar') {
59
59
  const block = metadataBlock({ start: -1, end: lines.length, lines });
60
60
  const rest = block === undefined ? lines : [...lines.slice(0, block.start), ...lines.slice(block.end)];
61
61
  const kept = rest.join('\n').trim();
@@ -214,7 +214,9 @@ function unquoted(text, lineNumber) {
214
214
  try {
215
215
  return JSON.parse(text);
216
216
  }
217
- catch {
217
+ catch (error) {
218
+ if (!(error instanceof SyntaxError))
219
+ throw error;
218
220
  throw new MetadataError(lineNumber, `${text} is not a double-quoted text. Escape a " inside it as \\".`);
219
221
  }
220
222
  }
@@ -235,8 +237,10 @@ function topLevelScalar(region, key) {
235
237
  try {
236
238
  return unquoted(text, region.start + 2 + at);
237
239
  }
238
- catch {
239
- return undefined;
240
+ catch (error) {
241
+ if (error instanceof MetadataError)
242
+ return undefined;
243
+ throw error;
240
244
  }
241
245
  }
242
246
  function asRecord(entries) {
@@ -175,7 +175,9 @@ function parseLine(line, folder, result) {
175
175
  const { text, markers } = scan(line, 0, false);
176
176
  walk(parse(text, (name) => (name === '' ? undefined : `$${name}`)), markers, folder, result);
177
177
  }
178
- catch {
178
+ catch (error) {
179
+ if (!(error instanceof SyntaxError) && !(error instanceof Error && error.message.startsWith('Bad substitution: ')))
180
+ throw error;
179
181
  result.isFullyParsed = false;
180
182
  }
181
183
  }
@@ -541,7 +543,7 @@ function finish(command, operator, folder, result) {
541
543
  if (first === undefined || first.text === 'for' || first.text === 'select')
542
544
  return folder;
543
545
  const here = command.redirects.findLast((redirect) => redirect.operator === '<<<');
544
- const stdin = here !== undefined ? { kind: 'text', text: here.target.text } : command.pipe !== undefined ? { kind: 'pipe' } : undefined;
546
+ const stdin = here !== undefined ? { type: 'text', text: here.target.text } : command.pipe !== undefined ? { type: 'pipe' } : undefined;
545
547
  const reader = result.commands.length;
546
548
  const changed = addCommand(first, args, folder, stdin, result);
547
549
  const read = result.commands[reader];
@@ -635,7 +637,7 @@ function findStarts(args) {
635
637
  }
636
638
  function addWrapper(first, program, args, folder, stdin, result) {
637
639
  const wrapper = wrappers.get(program);
638
- if (program === 'xargs' && stdin?.kind !== 'text')
640
+ if (program === 'xargs' && stdin?.type !== 'text')
639
641
  result.isFullyParsed = false;
640
642
  const { options, operands } = readArguments(args, wrapper, true);
641
643
  let start = args.length - operands.length;
@@ -691,8 +693,8 @@ function addEffects(program, args, flags, folder, stdin, result) {
691
693
  if (program === 'perl' && readArguments(args, perl, false).options.some((option) => option.name === '-i'))
692
694
  addFileArguments(perl, args, folder, result);
693
695
  const script = args.find((word) => !word.text.startsWith('-') || word.text === '-');
694
- const readsCodeFromPipe = stdin?.kind === 'pipe' && (script === undefined || script.text === '-');
695
- if (flags.some((flag) => inlineFlags.includes(flag)) || stdin?.kind === 'text' || readsCodeFromPipe)
696
+ const readsCodeFromPipe = stdin?.type === 'pipe' && (script === undefined || script.text === '-');
697
+ if (flags.some((flag) => inlineFlags.includes(flag)) || stdin?.type === 'text' || readsCodeFromPipe)
696
698
  result.isFullyParsed = false;
697
699
  }
698
700
  }
@@ -726,9 +728,9 @@ function addFetches(fetcher, args, result) {
726
728
  result.fetches.push(/^[a-z][a-z0-9+.-]*:\/\//i.test(url.text) ? url.text : `http://${url.text}`);
727
729
  }
728
730
  function addStdinCode(stdin, folder, result) {
729
- if (stdin?.kind === 'text')
731
+ if (stdin?.type === 'text')
730
732
  parseLine(stdin.text, folder, result);
731
- if (stdin?.kind === 'pipe')
733
+ if (stdin?.type === 'pipe')
732
734
  result.isFullyParsed = false;
733
735
  }
734
736
  function addCopy(program, args, folder, result) {
package/utils/paths.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export declare function isMissing(error: unknown): boolean;
2
+ export declare function ifMissing<Value>(value: Value): (error: unknown) => Value;
1
3
  export type FileSystem = {
2
4
  read: (path: string) => Promise<string>;
3
5
  stat: (path: string) => Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/utils/paths.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtF,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC3C,CAAA;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAK1F"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/utils/paths.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEjD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,CAKxE;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtF,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC3C,CAAA;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAK1F"}
package/utils/paths.js CHANGED
@@ -1,4 +1,16 @@
1
1
  import { basename, dirname, resolve } from '../vendor.js';
2
+ import { messageOf } from './text.js';
3
+ const missingPath = /(?:^|: )(?:ENOENT|ENOTDIR)\b/;
4
+ export function isMissing(error) {
5
+ return missingPath.test(messageOf(error));
6
+ }
7
+ export function ifMissing(value) {
8
+ return (error) => {
9
+ if (isMissing(error))
10
+ return value;
11
+ throw error;
12
+ };
13
+ }
2
14
  export function expandHome(path, home) {
3
15
  const prefix = /^(~|\$HOME)(?=\/|$)/.exec(path)?.[0];
4
16
  return prefix === undefined ? path : `${home}${path.slice(prefix.length)}`;
@@ -10,7 +22,7 @@ export function relativePath(base, path) {
10
22
  return path.startsWith(prefix) ? path.slice(prefix.length) : undefined;
11
23
  }
12
24
  export async function realPathOf(path, fs) {
13
- const stat = await fs.stat(path).catch(() => undefined);
25
+ const stat = await fs.stat(path).catch(ifMissing(undefined));
14
26
  if (stat !== undefined || path === '/')
15
27
  return stat?.realPath;
16
28
  const folder = await realPathOf(dirname(path), fs);
package/utils/text.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare function listed(items: readonly string[]): string;
2
+ export declare function firstLine(text: string): string;
2
3
  export declare function messageOf(error: unknown): string;
3
4
  export declare function formatExit(code: number | null, reason: string): string;
4
5
  //# sourceMappingURL=text.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/utils/text.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGvD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAItE"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/utils/text.ts"],"names":[],"mappings":"AAAA,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAGvD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAItE"}
package/utils/text.js CHANGED
@@ -3,6 +3,9 @@ export function listed(items) {
3
3
  return items.join('');
4
4
  return `${items.slice(0, -1).join(', ')} and ${items.at(-1)}`;
5
5
  }
6
+ export function firstLine(text) {
7
+ return text.split('\n').find((line) => line.trim() !== '')?.trim() ?? '';
8
+ }
6
9
  export function messageOf(error) {
7
10
  return error instanceof Error ? error.message : String(error);
8
11
  }
package/src/ui/slots.ts DELETED
@@ -1,36 +0,0 @@
1
- import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code'
2
- import type { MarkdownKind } from './markdown.js'
3
-
4
- declare const props: unique symbol
5
-
6
- declare const defaultProps: unique symbol
7
-
8
- type Place = { readonly component: RenderComponent } | { readonly markdown: MarkdownKind }
9
-
10
- export type Slot<Props extends object = object, DefaultProps extends object = object, Where extends Place = Place> = Where & {
11
- readonly [props]: Props
12
- readonly [defaultProps]: DefaultProps
13
- }
14
-
15
- export type SlotProps<S extends Slot> = Frozen<S[typeof props]> & { readonly Default: (props: Frozen<S[typeof defaultProps]>) => RenderElement }
16
-
17
- function slot<Component extends Exclude<RenderComponent, 'Pane'>>(component: Component): Slot<RenderPropsOf[Component], Partial<Omit<RenderPropsOf[Component], 'onScreen'>>, { readonly component: Component }> {
18
- return { component } as Slot<RenderPropsOf[Component], Partial<Omit<RenderPropsOf[Component], 'onScreen'>>, { readonly component: Component }>
19
- }
20
-
21
- export const slots = {
22
- AssistantMessage: slot('AssistantMessage'),
23
- UserMessage: slot('UserMessage'),
24
- ToolUse: slot('ToolUse'),
25
- ToolResult: slot('ToolResult'),
26
- ToolGroup: slot('ToolGroup'),
27
- ToolProgress: slot('ToolProgress'),
28
- CommandOutput: slot('CommandOutput'),
29
- AskUserQuestion: slot('AskUserQuestion'),
30
- InfoNotice: slot('InfoNotice'),
31
- Spinner: slot('Spinner'),
32
- TurnDuration: slot('TurnDuration'),
33
- SessionMode: slot('SessionMode'),
34
- PromptHint: slot('PromptHint'),
35
- AbovePrompt: slot('AbovePrompt'),
36
- }