@adecore/agents-react 0.31.11 → 0.32.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 (404) hide show
  1. package/dist/agents/AccountDot.js +57 -6
  2. package/dist/agents/AgentIcon.js +88 -12
  3. package/dist/agents/ModelOptionControl.js +153 -18
  4. package/dist/agents/ProviderLogo.js +49 -4
  5. package/dist/agents/account-limits.js +17 -14
  6. package/dist/agents/accounts.js +99 -67
  7. package/dist/agents/agent-marks.js +5 -3
  8. package/dist/agents/model-name.js +42 -31
  9. package/dist/agents/model-options.js +8 -8
  10. package/dist/agents/model-requirement.js +17 -14
  11. package/dist/agents/option-words.d.ts +7 -0
  12. package/dist/agents/option-words.js +35 -0
  13. package/dist/agents/provider-paths.js +6 -6
  14. package/dist/agents/status-look.js +32 -12
  15. package/dist/chat/account-choice.d.ts +13 -0
  16. package/dist/chat/account-choice.js +90 -20
  17. package/dist/chat/actions.js +126 -59
  18. package/dist/chat/activity.js +5 -5
  19. package/dist/chat/attachments.js +74 -53
  20. package/dist/chat/bookmarks.js +58 -48
  21. package/dist/chat/chat-client.js +344 -263
  22. package/dist/chat/chat-references.js +3 -3
  23. package/dist/chat/composer-effort.d.ts +5 -0
  24. package/dist/chat/composer-effort.js +26 -0
  25. package/dist/chat/composer-send.js +13 -13
  26. package/dist/chat/drafts.js +115 -79
  27. package/dist/chat/forks.js +81 -24
  28. package/dist/chat/guards.js +15 -43
  29. package/dist/chat/index.d.ts +3 -1
  30. package/dist/chat/index.js +3 -2
  31. package/dist/chat/logic/ansi.js +170 -167
  32. package/dist/chat/logic/answers.js +2 -2
  33. package/dist/chat/logic/bookmarks.js +19 -19
  34. package/dist/chat/logic/command-looks.js +138 -96
  35. package/dist/chat/logic/context-usage.js +13 -9
  36. package/dist/chat/logic/continue-after-stop.js +15 -19
  37. package/dist/chat/logic/effort.d.ts +14 -0
  38. package/dist/chat/logic/effort.js +34 -0
  39. package/dist/chat/logic/embedded-code.js +387 -326
  40. package/dist/chat/logic/fork.js +134 -110
  41. package/dist/chat/logic/generated-image.js +54 -23
  42. package/dist/chat/logic/goal.js +28 -20
  43. package/dist/chat/logic/handback.js +6 -6
  44. package/dist/chat/logic/json.js +2 -2
  45. package/dist/chat/logic/limit.js +46 -30
  46. package/dist/chat/logic/picker-entries.d.ts +5 -3
  47. package/dist/chat/logic/picker-entries.js +83 -43
  48. package/dist/chat/logic/resume-compaction.d.ts +14 -1
  49. package/dist/chat/logic/resume-compaction.js +93 -24
  50. package/dist/chat/logic/scrubber.js +188 -136
  51. package/dist/chat/logic/thought.js +13 -16
  52. package/dist/chat/logic/thread-cards.js +60 -48
  53. package/dist/chat/logic/timeline-copy.js +30 -38
  54. package/dist/chat/logic/timeline-target.js +92 -63
  55. package/dist/chat/logic/timeline.js +499 -355
  56. package/dist/chat/logic/tool-catalog.js +54 -34
  57. package/dist/chat/logic/tools.js +106 -82
  58. package/dist/chat/logic/visual-height.js +18 -18
  59. package/dist/chat/logic/visual-viewport.js +6 -3
  60. package/dist/chat/logic/welcome.js +9 -9
  61. package/dist/chat/logic/workflow.js +45 -34
  62. package/dist/chat/mentions.js +149 -109
  63. package/dist/chat/persisted-json.js +51 -54
  64. package/dist/chat/preferences.d.ts +4 -0
  65. package/dist/chat/preferences.js +162 -84
  66. package/dist/chat/prompt-hold.js +9 -9
  67. package/dist/chat/quote.js +21 -30
  68. package/dist/chat/reading-width.js +12 -10
  69. package/dist/chat/recent-messages.js +34 -21
  70. package/dist/chat/resume-compaction-dismissals.js +25 -5
  71. package/dist/chat/runtime-modes.js +3 -3
  72. package/dist/chat/send-key.js +11 -7
  73. package/dist/chat/stash.js +89 -69
  74. package/dist/chat/subagent-conversation.js +181 -139
  75. package/dist/chat/subagent-list.js +65 -67
  76. package/dist/chat/subagent-support.js +12 -7
  77. package/dist/chat/subagent-view.js +132 -44
  78. package/dist/chat/thumbnails.js +88 -60
  79. package/dist/chat/timeline-flash.js +24 -12
  80. package/dist/chat/timeline-scroll.js +116 -86
  81. package/dist/chat/ui/AccountPill.js +126 -15
  82. package/dist/chat/ui/AnsiOutput.js +62 -6
  83. package/dist/chat/ui/BookmarkMarker.js +231 -41
  84. package/dist/chat/ui/BookmarkSubmenu.js +165 -18
  85. package/dist/chat/ui/ChatActivity.js +649 -70
  86. package/dist/chat/ui/ChatReferenceChip.js +104 -9
  87. package/dist/chat/ui/CodeBlock.js +132 -58
  88. package/dist/chat/ui/Composer.js +866 -132
  89. package/dist/chat/ui/ComposerInput.js +309 -120
  90. package/dist/chat/ui/DiffPool.js +75 -14
  91. package/dist/chat/ui/EditDiff.js +160 -21
  92. package/dist/chat/ui/FadingWords.js +32 -3
  93. package/dist/chat/ui/GoalDock.js +235 -42
  94. package/dist/chat/ui/ImageView.js +617 -61
  95. package/dist/chat/ui/LimitState.js +446 -72
  96. package/dist/chat/ui/Markdown.js +991 -173
  97. package/dist/chat/ui/MermaidBlock.js +238 -68
  98. package/dist/chat/ui/MessageActions.js +251 -39
  99. package/dist/chat/ui/ModelMarks.js +55 -5
  100. package/dist/chat/ui/Pickers.js +664 -113
  101. package/dist/chat/ui/PromptComposer.js +281 -51
  102. package/dist/chat/ui/QuoteButton.js +151 -57
  103. package/dist/chat/ui/ResumeCompactionDock.d.ts +6 -2
  104. package/dist/chat/ui/ResumeCompactionDock.js +141 -6
  105. package/dist/chat/ui/RowTime.js +59 -5
  106. package/dist/chat/ui/RunSettings.js +1744 -154
  107. package/dist/chat/ui/Scrubber.js +517 -88
  108. package/dist/chat/ui/ShellCommand.js +183 -107
  109. package/dist/chat/ui/SubagentControls.js +212 -24
  110. package/dist/chat/ui/SubagentInfo.js +170 -13
  111. package/dist/chat/ui/SubagentStopButton.js +115 -24
  112. package/dist/chat/ui/SubagentTimeline.js +357 -91
  113. package/dist/chat/ui/Timeline.js +988 -476
  114. package/dist/chat/ui/TimelineMenu.js +552 -37
  115. package/dist/chat/ui/UnifiedDiff.js +234 -27
  116. package/dist/chat/ui/UploadThumb.js +37 -7
  117. package/dist/chat/ui/VisualDialogs.js +251 -20
  118. package/dist/chat/ui/VisualFrame.js +321 -95
  119. package/dist/chat/ui/Welcome.js +72 -7
  120. package/dist/chat/ui/chips.js +1 -1
  121. package/dist/chat/ui/code-lines.js +36 -36
  122. package/dist/chat/ui/code-streaming.js +1 -1
  123. package/dist/chat/ui/code-theme.js +7 -7
  124. package/dist/chat/ui/composer/ComposerControls.js +329 -21
  125. package/dist/chat/ui/composer/ComposerMenu.js +358 -30
  126. package/dist/chat/ui/composer/DraftParts.js +185 -11
  127. package/dist/chat/ui/composer/QueuedMessages.js +138 -13
  128. package/dist/chat/ui/composer/chips.js +29 -19
  129. package/dist/chat/ui/composer/editor.js +79 -63
  130. package/dist/chat/ui/composer/insert.js +26 -12
  131. package/dist/chat/ui/composer/key-handler.js +180 -127
  132. package/dist/chat/ui/composer/keys.js +90 -73
  133. package/dist/chat/ui/composer/menu-aria.js +18 -9
  134. package/dist/chat/ui/composer/placeholder.js +78 -31
  135. package/dist/chat/ui/composer/surface.js +13 -37
  136. package/dist/chat/ui/composer/use-chat-controls.js +230 -90
  137. package/dist/chat/ui/composer/use-compaction-offer.js +50 -18
  138. package/dist/chat/ui/composer/use-composer-draft.js +65 -34
  139. package/dist/chat/ui/composer/use-composer-menus.js +478 -193
  140. package/dist/chat/ui/composer/use-composer-submit.js +251 -109
  141. package/dist/chat/ui/composer/use-continuable-turn.js +33 -6
  142. package/dist/chat/ui/composer/use-draft-files.js +245 -93
  143. package/dist/chat/ui/composer/use-effort-stepper.d.ts +13 -0
  144. package/dist/chat/ui/composer/use-effort-stepper.js +88 -0
  145. package/dist/chat/ui/composer/use-notice.js +61 -16
  146. package/dist/chat/ui/composer/use-pending-requests.js +38 -17
  147. package/dist/chat/ui/composer/use-prompt-history.js +117 -45
  148. package/dist/chat/ui/composer/use-prompt-hold.js +119 -35
  149. package/dist/chat/ui/composer/use-take-back.js +94 -72
  150. package/dist/chat/ui/diff/ApprovalReview.js +101 -23
  151. package/dist/chat/ui/diff/DiffFallbackBoundary.js +21 -13
  152. package/dist/chat/ui/diff/DiffOmitted.js +56 -6
  153. package/dist/chat/ui/diff/DiffStack.js +92 -8
  154. package/dist/chat/ui/diff/DiffUnavailable.js +56 -6
  155. package/dist/chat/ui/diff/EditorEditDiff.js +263 -51
  156. package/dist/chat/ui/diff/EditorPatchDiff.js +39 -14
  157. package/dist/chat/ui/diff/LegacyDiffPool.js +27 -10
  158. package/dist/chat/ui/diff/LegacyEditDiff.js +97 -20
  159. package/dist/chat/ui/diff/LegacyUnifiedDiff.js +172 -42
  160. package/dist/chat/ui/diff/RawDiff.js +65 -5
  161. package/dist/chat/ui/diff/ReviewDiff.js +77 -5
  162. package/dist/chat/ui/diff/diff-props.js +1 -1
  163. package/dist/chat/ui/diff/diff-source-budget.js +46 -35
  164. package/dist/chat/ui/diff/editor-edit-model.js +18 -14
  165. package/dist/chat/ui/diff/review-plan.js +63 -40
  166. package/dist/chat/ui/diff/review-settle.js +24 -9
  167. package/dist/chat/ui/diff/syntax-runtime.js +236 -201
  168. package/dist/chat/ui/diff/use-review-stack.js +146 -25
  169. package/dist/chat/ui/diff-syntax.js +70 -58
  170. package/dist/chat/ui/diff-theme.js +31 -12
  171. package/dist/chat/ui/file-links.js +39 -10
  172. package/dist/chat/ui/find-reveal.js +29 -8
  173. package/dist/chat/ui/full-diff.js +17 -12
  174. package/dist/chat/ui/highlighter.js +143 -113
  175. package/dist/chat/ui/icons.js +16 -7
  176. package/dist/chat/ui/index.js +1 -1
  177. package/dist/chat/ui/intelligent-ui/UiBlockFrame.js +556 -82
  178. package/dist/chat/ui/intelligent-ui/UiFallbackPart.js +73 -5
  179. package/dist/chat/ui/intelligent-ui/UiReply.js +666 -262
  180. package/dist/chat/ui/intelligent-ui/block-local.js +59 -31
  181. package/dist/chat/ui/intelligent-ui/chart-data.js +77 -67
  182. package/dist/chat/ui/intelligent-ui/node-text.js +77 -91
  183. package/dist/chat/ui/intelligent-ui/registry.js +46 -46
  184. package/dist/chat/ui/intelligent-ui/render-context.js +1 -1
  185. package/dist/chat/ui/intelligent-ui/renderers/base-land.js +1 -1
  186. package/dist/chat/ui/intelligent-ui/renderers/binding.js +3 -3
  187. package/dist/chat/ui/intelligent-ui/renderers/chart.js +1223 -123
  188. package/dist/chat/ui/intelligent-ui/renderers/choices.js +312 -34
  189. package/dist/chat/ui/intelligent-ui/renderers/content.js +1241 -86
  190. package/dist/chat/ui/intelligent-ui/renderers/data.js +619 -54
  191. package/dist/chat/ui/intelligent-ui/renderers/inputs.js +868 -67
  192. package/dist/chat/ui/intelligent-ui/renderers/links.js +366 -62
  193. package/dist/chat/ui/intelligent-ui/renderers/map-slots.js +118 -60
  194. package/dist/chat/ui/intelligent-ui/renderers/map-style.js +85 -78
  195. package/dist/chat/ui/intelligent-ui/renderers/map-view.js +282 -217
  196. package/dist/chat/ui/intelligent-ui/renderers/map.js +621 -69
  197. package/dist/chat/ui/intelligent-ui/renderers/place-point.js +15 -8
  198. package/dist/chat/ui/intelligent-ui/renderers/structure.js +262 -20
  199. package/dist/chat/ui/intelligent-ui/renderers/text.js +674 -49
  200. package/dist/chat/ui/intelligent-ui/reply-parts.js +24 -15
  201. package/dist/chat/ui/intelligent-ui/table-data.js +97 -57
  202. package/dist/chat/ui/intelligent-ui/tones.js +31 -31
  203. package/dist/chat/ui/intelligent-ui/use-in-view.js +30 -12
  204. package/dist/chat/ui/intelligent-ui/use-later.js +28 -13
  205. package/dist/chat/ui/intelligent-ui/use-truncated.js +45 -21
  206. package/dist/chat/ui/intelligent-ui/use-ui-links.js +296 -109
  207. package/dist/chat/ui/intelligent-ui/use-ui-queries.js +256 -246
  208. package/dist/chat/ui/markdown-blocks.js +296 -262
  209. package/dist/chat/ui/mermaid.js +60 -72
  210. package/dist/chat/ui/quote-selection.js +32 -29
  211. package/dist/chat/ui/rehype-chips.js +35 -23
  212. package/dist/chat/ui/rehype-fade.js +28 -17
  213. package/dist/chat/ui/remark-html-as-text.js +22 -15
  214. package/dist/chat/ui/reply-context.js +1 -1
  215. package/dist/chat/ui/reveal.js +161 -72
  216. package/dist/chat/ui/rows/ForksRow.js +226 -24
  217. package/dist/chat/ui/rows/GeneratedImageRow.js +541 -87
  218. package/dist/chat/ui/rows/MessageRows.js +1706 -159
  219. package/dist/chat/ui/rows/RowContainer.js +57 -7
  220. package/dist/chat/ui/rows/Rows.js +463 -54
  221. package/dist/chat/ui/rows/SubagentRow.js +577 -60
  222. package/dist/chat/ui/rows/TaskRow.js +359 -40
  223. package/dist/chat/ui/rows/VisualRow.js +233 -11
  224. package/dist/chat/ui/rows/WorkRows.js +1946 -163
  225. package/dist/chat/ui/rows/WorkflowRow.js +293 -34
  226. package/dist/chat/ui/rows/row-rhythm.js +27 -17
  227. package/dist/chat/ui/theme-watch.js +26 -23
  228. package/dist/chat/ui/timestamp-format.js +4 -1
  229. package/dist/chat/ui/use-diff-source-tokens.js +70 -34
  230. package/dist/chat/ui/useToggleSet.js +51 -19
  231. package/dist/chat/ui/visual-theme.js +153 -128
  232. package/dist/chat/visual-bridge.js +123 -123
  233. package/dist/chat/visual-viewport.js +94 -83
  234. package/dist/chat/visuals.js +13 -5
  235. package/dist/host-hooks.d.ts +29 -0
  236. package/dist/host-hooks.js +78 -0
  237. package/dist/host.js +120 -48
  238. package/dist/index.js +1 -1
  239. package/dist/lazy.js +38 -32
  240. package/dist/locales/en/agent-chat.d.ts +35 -0
  241. package/dist/locales/en/agent-chat.js +747 -712
  242. package/dist/locales/en/agent-prompts.js +42 -42
  243. package/dist/locales/en/agent-providers.d.ts +1 -0
  244. package/dist/locales/en/agent-providers.js +166 -165
  245. package/dist/locales/en/agent-usage.d.ts +6 -0
  246. package/dist/locales/en/agent-usage.js +129 -123
  247. package/dist/locales/nl/agent-chat.d.ts +35 -0
  248. package/dist/locales/nl/agent-chat.js +747 -712
  249. package/dist/locales/nl/agent-prompts.js +42 -42
  250. package/dist/locales/nl/agent-providers.d.ts +1 -0
  251. package/dist/locales/nl/agent-providers.js +166 -165
  252. package/dist/locales/nl/agent-usage.d.ts +6 -0
  253. package/dist/locales/nl/agent-usage.js +129 -123
  254. package/dist/locales.js +14 -14
  255. package/dist/mounted-registry.js +31 -30
  256. package/dist/port-transport.js +122 -111
  257. package/dist/prompts/index.js +1 -1
  258. package/dist/prompts/logic/focus.js +15 -14
  259. package/dist/prompts/logic/keys.js +93 -59
  260. package/dist/prompts/logic/prompts.js +27 -14
  261. package/dist/prompts/logic/subjects.js +60 -46
  262. package/dist/prompts/logic/useFocusAfterAnswer.js +60 -20
  263. package/dist/prompts/logic/usePromptSession.js +88 -77
  264. package/dist/prompts/ui/ApprovalBody.js +246 -25
  265. package/dist/prompts/ui/PromptActions.js +215 -9
  266. package/dist/prompts/ui/PromptCard.js +215 -36
  267. package/dist/prompts/ui/PromptView.js +372 -34
  268. package/dist/prompts/ui/QuestionBody.js +269 -73
  269. package/dist/providers/AccountColors.js +36 -5
  270. package/dist/providers/AccountDetail.js +683 -50
  271. package/dist/providers/AccountVariables.js +139 -32
  272. package/dist/providers/AddAccountForm.js +125 -38
  273. package/dist/providers/CliDetail.js +343 -36
  274. package/dist/providers/InstallPage.js +644 -59
  275. package/dist/providers/ProviderList.d.ts +2 -1
  276. package/dist/providers/ProviderList.js +215 -23
  277. package/dist/providers/ProvidersPane.d.ts +4 -2
  278. package/dist/providers/ProvidersPane.js +244 -64
  279. package/dist/providers/account-actions.js +54 -30
  280. package/dist/providers/index.js +1 -1
  281. package/dist/providers/install-steps.js +12 -9
  282. package/dist/providers/pane-target.d.ts +3 -0
  283. package/dist/providers/pane-target.js +34 -13
  284. package/dist/providers/parts.js +62 -12
  285. package/dist/providers/provider-abilities.js +5 -5
  286. package/dist/providers/provider-groups.js +75 -40
  287. package/dist/providers/variables.js +73 -39
  288. package/dist/scope.js +6 -6
  289. package/dist/settings/sections.js +18 -18
  290. package/dist/state/chats.d.ts +1 -0
  291. package/dist/state/chats.js +408 -192
  292. package/dist/state/index.js +1 -1
  293. package/dist/state/provider-accounts.js +70 -47
  294. package/dist/state/providers.js +45 -16
  295. package/dist/state/usage.js +154 -77
  296. package/dist/storage.js +69 -68
  297. package/dist/testing/index.js +1 -1
  298. package/dist/testing/prompts.js +105 -67
  299. package/dist/transport.js +10 -10
  300. package/dist/ui/PlainTextarea.js +27 -3
  301. package/dist/usage/LimitsList.js +646 -40
  302. package/dist/usage/UsageBreakdown.js +879 -38
  303. package/dist/usage/UsageChart.js +311 -32
  304. package/dist/usage/UsageDialog.js +46 -4
  305. package/dist/usage/UsageLimits.js +467 -34
  306. package/dist/usage/UsageLimitsCard.js +95 -11
  307. package/dist/usage/UsagePage.js +817 -96
  308. package/dist/usage/UsagePane.js +164 -10
  309. package/dist/usage/UsageSummary.js +151 -6
  310. package/dist/usage/UsageTiles.js +164 -14
  311. package/dist/usage/format.js +32 -32
  312. package/dist/usage/index.d.ts +1 -1
  313. package/dist/usage/index.js +2 -1
  314. package/dist/usage/limit-groups.d.ts +2 -0
  315. package/dist/usage/limit-groups.js +77 -59
  316. package/dist/usage/limits.js +78 -43
  317. package/dist/usage/money.js +20 -4
  318. package/dist/usage/summary.js +85 -64
  319. package/package.json +8 -8
  320. package/src/agents/ModelOptionControl.tsx +3 -1
  321. package/src/agents/option-words.ts +27 -0
  322. package/src/chat/account-choice.ts +41 -1
  323. package/src/chat/composer-effort.ts +32 -0
  324. package/src/chat/forks.ts +4 -5
  325. package/src/chat/index.ts +3 -1
  326. package/src/chat/logic/effort.ts +32 -0
  327. package/src/chat/logic/picker-entries.ts +45 -10
  328. package/src/chat/logic/resume-compaction.ts +95 -17
  329. package/src/chat/logic/timeline.ts +11 -3
  330. package/src/chat/preferences.ts +35 -0
  331. package/src/chat/subagent-view.ts +2 -3
  332. package/src/chat/ui/AnsiOutput.tsx +1 -2
  333. package/src/chat/ui/BookmarkSubmenu.tsx +3 -3
  334. package/src/chat/ui/ChatActivity.tsx +14 -22
  335. package/src/chat/ui/ChatReferenceChip.tsx +2 -3
  336. package/src/chat/ui/Composer.tsx +15 -7
  337. package/src/chat/ui/EditDiff.tsx +2 -3
  338. package/src/chat/ui/LimitState.tsx +2 -2
  339. package/src/chat/ui/Markdown.tsx +10 -8
  340. package/src/chat/ui/MermaidBlock.tsx +2 -3
  341. package/src/chat/ui/Pickers.tsx +49 -29
  342. package/src/chat/ui/PromptComposer.tsx +7 -9
  343. package/src/chat/ui/ResumeCompactionDock.tsx +16 -4
  344. package/src/chat/ui/RunSettings.tsx +67 -28
  345. package/src/chat/ui/Scrubber.tsx +3 -3
  346. package/src/chat/ui/ShellCommand.tsx +2 -0
  347. package/src/chat/ui/SubagentInfo.tsx +2 -3
  348. package/src/chat/ui/SubagentTimeline.tsx +12 -16
  349. package/src/chat/ui/Timeline.tsx +6 -6
  350. package/src/chat/ui/UnifiedDiff.tsx +3 -4
  351. package/src/chat/ui/VisualFrame.tsx +5 -8
  352. package/src/chat/ui/code-theme.ts +4 -4
  353. package/src/chat/ui/composer/placeholder.ts +2 -2
  354. package/src/chat/ui/composer/use-compaction-offer.ts +36 -16
  355. package/src/chat/ui/composer/use-composer-menus.ts +4 -9
  356. package/src/chat/ui/composer/use-composer-submit.ts +2 -1
  357. package/src/chat/ui/composer/use-effort-stepper.ts +56 -0
  358. package/src/chat/ui/composer/use-notice.ts +2 -2
  359. package/src/chat/ui/diff/EditorEditDiff.tsx +9 -13
  360. package/src/chat/ui/diff/LegacyEditDiff.tsx +12 -17
  361. package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +13 -21
  362. package/src/chat/ui/diff/use-review-stack.ts +4 -4
  363. package/src/chat/ui/diff-theme.ts +3 -3
  364. package/src/chat/ui/file-links.ts +2 -2
  365. package/src/chat/ui/intelligent-ui/UiReply.tsx +2 -0
  366. package/src/chat/ui/intelligent-ui/renderers/chart.tsx +3 -3
  367. package/src/chat/ui/intelligent-ui/renderers/content.tsx +5 -6
  368. package/src/chat/ui/intelligent-ui/renderers/map-view.tsx +2 -1
  369. package/src/chat/ui/intelligent-ui/renderers/map.tsx +2 -1
  370. package/src/chat/ui/intelligent-ui/use-truncated.ts +16 -19
  371. package/src/chat/ui/intelligent-ui/use-ui-links.ts +3 -3
  372. package/src/chat/ui/rows/ForksRow.tsx +3 -5
  373. package/src/chat/ui/rows/GeneratedImageRow.tsx +2 -1
  374. package/src/chat/ui/rows/MessageRows.tsx +12 -21
  375. package/src/chat/ui/rows/SubagentRow.tsx +3 -3
  376. package/src/chat/ui/rows/TaskRow.tsx +1 -1
  377. package/src/chat/ui/rows/WorkRows.tsx +20 -7
  378. package/src/chat/ui/useToggleSet.ts +15 -18
  379. package/src/chat/ui/visual-theme.ts +2 -3
  380. package/src/host-hooks.ts +113 -0
  381. package/src/lazy.tsx +2 -0
  382. package/src/locales/en/agent-chat.ts +135 -108
  383. package/src/locales/en/agent-prompts.ts +7 -7
  384. package/src/locales/en/agent-providers.ts +35 -34
  385. package/src/locales/en/agent-usage.ts +26 -20
  386. package/src/locales/nl/agent-chat.ts +127 -100
  387. package/src/locales/nl/agent-prompts.ts +5 -5
  388. package/src/locales/nl/agent-providers.ts +33 -32
  389. package/src/locales/nl/agent-usage.ts +25 -20
  390. package/src/prompts/ui/ApprovalBody.tsx +3 -1
  391. package/src/providers/CliDetail.tsx +2 -1
  392. package/src/providers/InstallPage.tsx +2 -4
  393. package/src/providers/ProviderList.tsx +12 -2
  394. package/src/providers/ProvidersPane.tsx +45 -15
  395. package/src/providers/pane-target.ts +20 -4
  396. package/src/state/chats.ts +7 -2
  397. package/src/usage/LimitsList.tsx +12 -13
  398. package/src/usage/UsageBreakdown.tsx +17 -6
  399. package/src/usage/UsageLimits.tsx +2 -1
  400. package/src/usage/UsagePage.tsx +3 -3
  401. package/src/usage/index.ts +1 -1
  402. package/src/usage/limit-groups.ts +12 -0
  403. package/src/usage/limits.ts +2 -2
  404. package/src/usage/money.ts +1 -2
@@ -13,13 +13,7 @@ const THEMATIC_BREAK = /^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/;
13
13
  const ENDS_ITEM = /^ {0,3}(?:#{1,6}(?:[ \t]|$)|>)/;
14
14
  const HTML_START = /^ {0,3}<[A-Za-z/!?]/;
15
15
  // The HTML that runs on until a marker rather than a blank line, with that marker.
16
- const HTML_UNTIL = [
17
- [/^ {0,3}<(?:pre|script|style|textarea)(?:[ \t>]|$)/i, /<\/(?:pre|script|style|textarea)>/i],
18
- [/^ {0,3}<!--/, /-->/],
19
- [/^ {0,3}<\?/, /\?>/],
20
- [/^ {0,3}<![A-Za-z]/, />/],
21
- [/^ {0,3}<!\[CDATA\[/, /\]\]>/]
22
- ];
16
+ const HTML_UNTIL = [[/^ {0,3}<(?:pre|script|style|textarea)(?:[ \t>]|$)/i, /<\/(?:pre|script|style|textarea)>/i], [/^ {0,3}<!--/, /-->/], [/^ {0,3}<\?/, /\?>/], [/^ {0,3}<![A-Za-z]/, />/], [/^ {0,3}<!\[CDATA\[/, /\]\]>/]];
23
17
  // A reference or footnote definition may be used anywhere in the text, so a block cannot stand alone.
24
18
  const DEFINITION = /^ {0,3}\[[^\]]+\]:/m;
25
19
  // Markdown ends a line at a lone carriage return too, which a split at line feeds would not see.
@@ -39,139 +33,154 @@ const BOLD_LINE = /^ {0,3}\*\*(?:[^*]|\*(?!\*))+\*\*:?[ \t]*$/;
39
33
  * Joined back together the blocks are the text.
40
34
  */
41
35
  export function splitMarkdownBlocks(text) {
42
- if (DEFINITION.test(text) || LONE_RETURN.test(text)) {
43
- return [{ text, openFence: isFenceOpenAtEnd(text) }];
44
- }
45
- const lines = text.split('\n');
46
- const blocks = [];
47
- let start = 0;
48
- let offset = 0;
49
- // The fence as a reading line by line sees it, blind to lists and indented code. A blank line is
50
- // only cut at where this reading agrees, so every such cut is one this split made before it
51
- // followed fences any further.
52
- let lineFence = null;
53
- let afterBlank = false;
54
- // A fence inside a list item.
55
- let fence = null;
56
- let top = null;
57
- // A top-level fence that has closed; its block takes the blank lines under it.
58
- let closed = null;
59
- let item = null;
60
- // The marker that ends the raw HTML the line stands in.
61
- let html = null;
62
- // Whether the top level is still known here. Past HTML, or a line that may or may not end a list
63
- // item, a fence is left inside the block it stands in, which markdown parses as a whole.
64
- let known = true;
65
- // Where the line above starts when it is blank.
66
- let blankAbove = null;
67
- const cutAt = (end) => {
68
- if (end > start) {
69
- blocks.push({ text: text.slice(start, end), openFence: false });
70
- }
71
- start = end;
72
- };
73
- for (const [index, line] of lines.entries()) {
74
- const at = offset;
75
- offset += line.length + 1;
76
- const content = withoutReturn(line);
77
- const blank = BLANK.test(line);
78
- // Blank to markdown, which a line ending in a carriage return is too.
79
- const empty = BLANK.test(content);
80
- const blankCut = lineFence === null && afterBlank && !blank && !CONTINUES.test(line);
81
- lineFence = nextFence(lineFence, line);
82
- afterBlank = lineFence === null && blank && index > 0;
83
- if (top !== null) {
84
- if (closesFence(top.marker, content)) {
85
- closed = { fence: top, source: text.slice(top.from, at + content.length) };
86
- top = null;
87
- }
88
- else if (index < lines.length - 1 || line !== '') {
89
- // The empty line after a line ending at the end of the text is no line of the fence.
90
- top.body += (top.ending ?? '') + outdent(content, top.indent);
91
- top.ending = line.length > content.length ? '\r\n' : '\n';
92
- }
93
- continue;
94
- }
95
- if (closed !== null) {
96
- if (empty) {
97
- continue;
98
- }
99
- blocks.push(fenceBlock(text.slice(start, at), closed.fence, closed.source, true));
100
- start = at;
101
- closed = null;
102
- }
103
- if (html !== null) {
104
- // Raw HTML holds no fence and no blank line to cut at until its marker.
105
- if (html.test(content)) {
106
- html = null;
107
- }
108
- continue;
109
- }
110
- if (known && fence !== null && item !== null && !empty && columns(content) < item.column) {
111
- // Code is no paragraph a line may continue lazily, so a line left of the item's content ends
112
- // the item and its code. A next item of the same list keeps the list going.
113
- fence = null;
114
- if (!LIST_MARKER.test(content)) {
115
- item = null;
116
- }
117
- }
118
- if (blankCut && fence === null) {
119
- cutAt(at);
120
- }
121
- const above = index > 0 ? withoutReturn(lines[index - 1]) : '';
122
- const opening = known && fence === null ? openingFence(content) : null;
123
- if (opening !== null && EMPTY_ITEM.test(above)) {
124
- // Markdown reads an empty item right above a fence as a list or as text depending on what
125
- // stands before it, so the two stay in one block.
126
- known = false;
127
- }
128
- else if (opening !== null && opening.indent < CODE_INDENT && (item === null || opening.indent < item.column)) {
129
- // The blank line right above goes with the fence. Code in a list item this fence ends takes
130
- // every blank line under it but the last, and at the end of a block it would take them all.
131
- cutAt(blankAbove !== null && blankAbove > start ? blankAbove : at);
132
- // Three columns at most, so the indentation is spaces.
133
- top = { ...opening, from: at + opening.indent, body: '', ending: null };
134
- item = null;
135
- blankAbove = null;
136
- continue;
137
- }
138
- if (known && item?.empty === true && empty) {
139
- // An item with nothing on its first line ends at a blank line right under it.
140
- item = null;
141
- }
142
- if (known && fence === null && !empty) {
143
- // A fence in an item is followed only while the item is known to be open, and less than four
144
- // columns deeper than its content: deeper it is code of the item, or of an item inside it.
145
- if (opening !== null && item !== null && (!item.certain || opening.indent < item.column || opening.indent >= item.column + CODE_INDENT)) {
146
- known = false;
147
- }
148
- else if (opening === null) {
149
- item = nextItem(item, content, index > 0 && !BLANK.test(above));
150
- }
151
- }
152
- if (fence === null && HTML_START.test(content)) {
153
- known = false;
154
- const until = HTML_UNTIL.find(([begins]) => begins.test(content))?.[1];
155
- html = until !== undefined && !until.test(content) ? until : null;
156
- }
157
- if (known && (fence !== null || item !== null)) {
158
- fence = nextFence(fence, fence === null ? itemContent(content) : content);
159
- }
160
- if (item?.empty === true && !empty && columns(content) >= item.column) {
161
- item = { ...item, empty: false };
162
- }
163
- blankAbove = empty ? at : null;
36
+ if (DEFINITION.test(text) || LONE_RETURN.test(text)) {
37
+ return [{
38
+ text,
39
+ openFence: isFenceOpenAtEnd(text)
40
+ }];
41
+ }
42
+ const lines = text.split('\n');
43
+ const blocks = [];
44
+ let start = 0;
45
+ let offset = 0;
46
+ // The fence as a reading line by line sees it, blind to lists and indented code. A blank line is
47
+ // only cut at where this reading agrees, so every such cut is one this split made before it
48
+ // followed fences any further.
49
+ let lineFence = null;
50
+ let afterBlank = false;
51
+ // A fence inside a list item.
52
+ let fence = null;
53
+ let top = null;
54
+ // A top-level fence that has closed; its block takes the blank lines under it.
55
+ let closed = null;
56
+ let item = null;
57
+ // The marker that ends the raw HTML the line stands in.
58
+ let html = null;
59
+ // Whether the top level is still known here. Past HTML, or a line that may or may not end a list
60
+ // item, a fence is left inside the block it stands in, which markdown parses as a whole.
61
+ let known = true;
62
+ // Where the line above starts when it is blank.
63
+ let blankAbove = null;
64
+ const cutAt = end => {
65
+ if (end > start) {
66
+ blocks.push({
67
+ text: text.slice(start, end),
68
+ openFence: false
69
+ });
164
70
  }
71
+ start = end;
72
+ };
73
+ for (const [index, line] of lines.entries()) {
74
+ const at = offset;
75
+ offset += line.length + 1;
76
+ const content = withoutReturn(line);
77
+ const blank = BLANK.test(line);
78
+ // Blank to markdown, which a line ending in a carriage return is too.
79
+ const empty = BLANK.test(content);
80
+ const blankCut = lineFence === null && afterBlank && !blank && !CONTINUES.test(line);
81
+ lineFence = nextFence(lineFence, line);
82
+ afterBlank = lineFence === null && blank && index > 0;
165
83
  if (top !== null) {
166
- blocks.push(fenceBlock(text.slice(start), top, text.slice(top.from), false));
84
+ if (closesFence(top.marker, content)) {
85
+ closed = {
86
+ fence: top,
87
+ source: text.slice(top.from, at + content.length)
88
+ };
89
+ top = null;
90
+ } else if (index < lines.length - 1 || line !== '') {
91
+ // The empty line after a line ending at the end of the text is no line of the fence.
92
+ top.body += (top.ending ?? '') + outdent(content, top.indent);
93
+ top.ending = line.length > content.length ? '\r\n' : '\n';
94
+ }
95
+ continue;
96
+ }
97
+ if (closed !== null) {
98
+ if (empty) {
99
+ continue;
100
+ }
101
+ blocks.push(fenceBlock(text.slice(start, at), closed.fence, closed.source, true));
102
+ start = at;
103
+ closed = null;
104
+ }
105
+ if (html !== null) {
106
+ // Raw HTML holds no fence and no blank line to cut at until its marker.
107
+ if (html.test(content)) {
108
+ html = null;
109
+ }
110
+ continue;
111
+ }
112
+ if (known && fence !== null && item !== null && !empty && columns(content) < item.column) {
113
+ // Code is no paragraph a line may continue lazily, so a line left of the item's content ends
114
+ // the item and its code. A next item of the same list keeps the list going.
115
+ fence = null;
116
+ if (!LIST_MARKER.test(content)) {
117
+ item = null;
118
+ }
119
+ }
120
+ if (blankCut && fence === null) {
121
+ cutAt(at);
122
+ }
123
+ const above = index > 0 ? withoutReturn(lines[index - 1]) : '';
124
+ const opening = known && fence === null ? openingFence(content) : null;
125
+ if (opening !== null && EMPTY_ITEM.test(above)) {
126
+ // Markdown reads an empty item right above a fence as a list or as text depending on what
127
+ // stands before it, so the two stay in one block.
128
+ known = false;
129
+ } else if (opening !== null && opening.indent < CODE_INDENT && (item === null || opening.indent < item.column)) {
130
+ // The blank line right above goes with the fence. Code in a list item this fence ends takes
131
+ // every blank line under it but the last, and at the end of a block it would take them all.
132
+ cutAt(blankAbove !== null && blankAbove > start ? blankAbove : at);
133
+ // Three columns at most, so the indentation is spaces.
134
+ top = {
135
+ ...opening,
136
+ from: at + opening.indent,
137
+ body: '',
138
+ ending: null
139
+ };
140
+ item = null;
141
+ blankAbove = null;
142
+ continue;
167
143
  }
168
- else if (closed !== null) {
169
- blocks.push(fenceBlock(text.slice(start), closed.fence, closed.source, true));
144
+ if (known && item?.empty === true && empty) {
145
+ // An item with nothing on its first line ends at a blank line right under it.
146
+ item = null;
170
147
  }
171
- else {
172
- blocks.push({ text: text.slice(start), openFence: (known ? fence : lineFence) !== null });
148
+ if (known && fence === null && !empty) {
149
+ // A fence in an item is followed only while the item is known to be open, and less than four
150
+ // columns deeper than its content: deeper it is code of the item, or of an item inside it.
151
+ if (opening !== null && item !== null && (!item.certain || opening.indent < item.column || opening.indent >= item.column + CODE_INDENT)) {
152
+ known = false;
153
+ } else if (opening === null) {
154
+ item = nextItem(item, content, index > 0 && !BLANK.test(above));
155
+ }
173
156
  }
174
- return blocks;
157
+ if (fence === null && HTML_START.test(content)) {
158
+ known = false;
159
+ const until = HTML_UNTIL.find(([begins]) => begins.test(content))?.[1];
160
+ html = until !== undefined && !until.test(content) ? until : null;
161
+ }
162
+ if (known && (fence !== null || item !== null)) {
163
+ fence = nextFence(fence, fence === null ? itemContent(content) : content);
164
+ }
165
+ if (item?.empty === true && !empty && columns(content) >= item.column) {
166
+ item = {
167
+ ...item,
168
+ empty: false
169
+ };
170
+ }
171
+ blankAbove = empty ? at : null;
172
+ }
173
+ if (top !== null) {
174
+ blocks.push(fenceBlock(text.slice(start), top, text.slice(top.from), false));
175
+ } else if (closed !== null) {
176
+ blocks.push(fenceBlock(text.slice(start), closed.fence, closed.source, true));
177
+ } else {
178
+ blocks.push({
179
+ text: text.slice(start),
180
+ openFence: (known ? fence : lineFence) !== null
181
+ });
182
+ }
183
+ return blocks;
175
184
  }
176
185
  /*
177
186
  * The blocks of a reply still being written that will not change any more: every block but the last.
@@ -180,172 +189,197 @@ export function splitMarkdownBlocks(text) {
180
189
  * block under it, so it never sits alone above a block that is still streaming.
181
190
  */
182
191
  export function settledBlocksText(text) {
183
- return withoutTrailingTitles(splitMarkdownBlocks(text)
184
- .slice(0, -1)
185
- .map((block) => block.text)
186
- .join(''));
192
+ return withoutTrailingTitles(splitMarkdownBlocks(text).slice(0, -1).map(block => block.text).join(''));
187
193
  }
188
194
  function withoutTrailingTitles(text) {
189
- const lines = text.split('\n');
190
- let end = lines.length;
191
- for (let index = lines.length - 1; index >= 0; index--) {
192
- const line = lines[index];
193
- if (BLANK.test(line)) {
194
- continue;
195
- }
196
- // A bold line right under a line of text continues that paragraph.
197
- const title = HEADING.test(line) || (BOLD_LINE.test(line) && (index === 0 || BLANK.test(lines[index - 1])));
198
- if (!title) {
199
- break;
200
- }
201
- end = index;
195
+ const lines = text.split('\n');
196
+ let end = lines.length;
197
+ for (let index = lines.length - 1; index >= 0; index--) {
198
+ const line = lines[index];
199
+ if (BLANK.test(line)) {
200
+ continue;
202
201
  }
203
- if (end === lines.length) {
204
- return text;
202
+ // A bold line right under a line of text continues that paragraph.
203
+ const title = HEADING.test(line) || BOLD_LINE.test(line) && (index === 0 || BLANK.test(lines[index - 1]));
204
+ if (!title) {
205
+ break;
205
206
  }
206
- return lines
207
- .slice(0, end)
208
- .map((line) => `${line}\n`)
209
- .join('');
207
+ end = index;
208
+ }
209
+ if (end === lines.length) {
210
+ return text;
211
+ }
212
+ return lines.slice(0, end).map(line => `${line}\n`).join('');
210
213
  }
211
214
  /* The fence a line leaves open: it opens one, closes the one that is open, or changes nothing. */
212
215
  function nextFence(fence, line) {
213
- const match = FENCE.exec(line);
214
- if (!match) {
215
- return fence;
216
- }
217
- const indent = match[1].length;
218
- const run = match[2];
219
- const rest = match[3];
220
- if (fence === null) {
221
- // A backtick fence's info string may not hold a backtick, or the line is inline code.
222
- if (run[0] === '`' && rest.includes('`')) {
223
- return null;
224
- }
225
- return { marker: run[0], length: run.length, indent };
226
- }
227
- // A closing fence carries no info string, and a line far deeper than the opening is code.
228
- if (run[0] === fence.marker && run.length >= fence.length && BLANK.test(rest) && indent <= fence.indent + CLOSING_INDENT) {
229
- return null;
230
- }
216
+ const match = FENCE.exec(line);
217
+ if (!match) {
231
218
  return fence;
219
+ }
220
+ const indent = match[1].length;
221
+ const run = match[2];
222
+ const rest = match[3];
223
+ if (fence === null) {
224
+ // A backtick fence's info string may not hold a backtick, or the line is inline code.
225
+ if (run[0] === '`' && rest.includes('`')) {
226
+ return null;
227
+ }
228
+ return {
229
+ marker: run[0],
230
+ length: run.length,
231
+ indent
232
+ };
233
+ }
234
+ // A closing fence carries no info string, and a line far deeper than the opening is code.
235
+ if (run[0] === fence.marker && run.length >= fence.length && BLANK.test(rest) && indent <= fence.indent + CLOSING_INDENT) {
236
+ return null;
237
+ }
238
+ return fence;
232
239
  }
233
240
  function isFenceOpenAtEnd(text) {
234
- let fence = null;
235
- for (const line of text.split('\n')) {
236
- fence = nextFence(fence, withoutReturn(line));
237
- }
238
- return fence !== null;
241
+ let fence = null;
242
+ for (const line of text.split('\n')) {
243
+ fence = nextFence(fence, withoutReturn(line));
244
+ }
245
+ return fence !== null;
239
246
  }
240
247
  /* The fence a line opens wherever it stands, with its indentation in columns. */
241
248
  function openingFence(content) {
242
- const match = FENCE.exec(content);
243
- if (!match) {
244
- return null;
245
- }
246
- const marker = match[2];
247
- const info = match[3].replace(/^[ \t]+|[ \t]+$/g, '');
248
- // A backtick fence's info string may not hold a backtick, or the line is inline code.
249
- if (marker[0] === '`' && info.includes('`')) {
250
- return null;
251
- }
252
- return { marker, info, indent: columns(content), direct: !/[\\&]/.test(info.split(/[ \t]/, 1)[0]) };
249
+ const match = FENCE.exec(content);
250
+ if (!match) {
251
+ return null;
252
+ }
253
+ const marker = match[2];
254
+ const info = match[3].replace(/^[ \t]+|[ \t]+$/g, '');
255
+ // A backtick fence's info string may not hold a backtick, or the line is inline code.
256
+ if (marker[0] === '`' && info.includes('`')) {
257
+ return null;
258
+ }
259
+ return {
260
+ marker,
261
+ info,
262
+ indent: columns(content),
263
+ direct: !/[\\&]/.test(info.split(/[ \t]/, 1)[0])
264
+ };
253
265
  }
254
266
  /* A line without the carriage return of a CRLF line ending. */
255
267
  function withoutReturn(line) {
256
- return line.endsWith('\r') ? line.slice(0, -1) : line;
268
+ return line.endsWith('\r') ? line.slice(0, -1) : line;
257
269
  }
258
270
  function closesFence(marker, content) {
259
- const run = CLOSING_FENCE.exec(content)?.[1];
260
- return run !== undefined && run[0] === marker[0] && run.length >= marker.length;
271
+ const run = CLOSING_FENCE.exec(content)?.[1];
272
+ return run !== undefined && run[0] === marker[0] && run.length >= marker.length;
261
273
  }
262
274
  function fenceBlock(text, fence, source, closed) {
263
- if (!fence.direct) {
264
- return { text, openFence: !closed };
275
+ if (!fence.direct) {
276
+ return {
277
+ text,
278
+ openFence: !closed
279
+ };
280
+ }
281
+ return {
282
+ text,
283
+ openFence: !closed,
284
+ fence: {
285
+ marker: fence.marker,
286
+ info: fence.info,
287
+ body: fence.body,
288
+ closed,
289
+ source
265
290
  }
266
- return { text, openFence: !closed, fence: { marker: fence.marker, info: fence.info, body: fence.body, closed, source } };
291
+ };
267
292
  }
268
293
  /* The list item a line that is neither blank nor a fence leaves open, as far as a fence needs to know. */
269
294
  function nextItem(item, content, underLine) {
270
- const indent = columns(content);
271
- if (item !== null && indent >= item.column) {
272
- return item;
273
- }
274
- if (THEMATIC_BREAK.test(content) || ENDS_ITEM.test(content)) {
275
- return null;
276
- }
277
- const marker = indent < CODE_INDENT ? itemMarker(content) : null;
278
- if (marker === null) {
279
- if (item === null || !underLine) {
280
- return null;
281
- }
282
- // A line right under an item may continue its paragraph, or follow an item that ends in something else.
283
- return { ...item, certain: false };
295
+ const indent = columns(content);
296
+ if (item !== null && indent >= item.column) {
297
+ return item;
298
+ }
299
+ if (THEMATIC_BREAK.test(content) || ENDS_ITEM.test(content)) {
300
+ return null;
301
+ }
302
+ const marker = indent < CODE_INDENT ? itemMarker(content) : null;
303
+ if (marker === null) {
304
+ if (item === null || !underLine) {
305
+ return null;
284
306
  }
285
- // Right under another line, only a bullet or a 1 with text after it surely starts a list; anything
286
- // else may be text of a paragraph above.
287
- const certain = !underLine || (item !== null && item.certain && item.kind === marker.kind) || (marker.first && marker.rest !== '');
288
- return { column: marker.column, kind: marker.kind, certain, empty: marker.rest === '' };
307
+ // A line right under an item may continue its paragraph, or follow an item that ends in something else.
308
+ return {
309
+ ...item,
310
+ certain: false
311
+ };
312
+ }
313
+ // Right under another line, only a bullet or a 1 with text after it surely starts a list; anything
314
+ // else may be text of a paragraph above.
315
+ const certain = !underLine || item !== null && item.certain && item.kind === marker.kind || marker.first && marker.rest !== '';
316
+ return {
317
+ column: marker.column,
318
+ kind: marker.kind,
319
+ certain,
320
+ empty: marker.rest === ''
321
+ };
289
322
  }
290
323
  /* The marker a list item starts with: its kind, whether it may start a list under text, and the column its content starts at. */
291
324
  function itemMarker(content) {
292
- const match = LIST_MARKER.exec(content);
293
- if (match === null) {
294
- return null;
295
- }
296
- const [, bullet, number, delimiter, spacing = '', rest = ''] = match;
297
- const indent = columns(content);
298
- const width = bullet !== undefined ? 1 : number.length + 1;
299
- // The content starts after the spaces behind the marker, unless there are five or more: then the
300
- // item starts with indented code one column after the marker.
301
- const gap = rest === '' ? 1 : columns(spacing, indent + width);
302
- const column = indent + width + (gap > CODE_INDENT ? 1 : gap);
303
- return { kind: bullet ?? delimiter, first: bullet !== undefined || Number(number) === 1, column, rest };
325
+ const match = LIST_MARKER.exec(content);
326
+ if (match === null) {
327
+ return null;
328
+ }
329
+ const [, bullet, number, delimiter, spacing = '', rest = ''] = match;
330
+ const indent = columns(content);
331
+ const width = bullet !== undefined ? 1 : number.length + 1;
332
+ // The content starts after the spaces behind the marker, unless there are five or more: then the
333
+ // item starts with indented code one column after the marker.
334
+ const gap = rest === '' ? 1 : columns(spacing, indent + width);
335
+ const column = indent + width + (gap > CODE_INDENT ? 1 : gap);
336
+ return {
337
+ kind: bullet ?? delimiter,
338
+ first: bullet !== undefined || Number(number) === 1,
339
+ column,
340
+ rest
341
+ };
304
342
  }
305
343
  /* A list item's line with its marker as spaces, so a fence on that line is seen where the item's content starts. */
306
344
  function itemContent(content) {
307
- const marker = itemMarker(content);
308
- return marker === null ? content : ' '.repeat(marker.column) + marker.rest;
345
+ const marker = itemMarker(content);
346
+ return marker === null ? content : ' '.repeat(marker.column) + marker.rest;
309
347
  }
310
348
  /* The columns of the indentation of a line, which starts at column `from`; a tab reaches to the next stop of four. */
311
349
  function columns(line, from = 0) {
312
- let column = from;
313
- for (const character of line) {
314
- if (character === '\t') {
315
- column += TAB_STOP - (column % TAB_STOP);
316
- }
317
- else if (character === ' ') {
318
- column += 1;
319
- }
320
- else {
321
- break;
322
- }
350
+ let column = from;
351
+ for (const character of line) {
352
+ if (character === '\t') {
353
+ column += TAB_STOP - column % TAB_STOP;
354
+ } else if (character === ' ') {
355
+ column += 1;
356
+ } else {
357
+ break;
323
358
  }
324
- return column - from;
359
+ }
360
+ return column - from;
325
361
  }
326
362
  /*
327
363
  * A line of a fence less up to `indent` columns of indentation. A tab reaches to the next stop of
328
364
  * four, and what of it lies past `indent` stays as spaces, as markdown reads it.
329
365
  */
330
366
  function outdent(line, indent) {
331
- let column = 0;
332
- let index = 0;
333
- while (column < indent && index < line.length) {
334
- const character = line[index];
335
- if (character === '\t') {
336
- const stop = column + TAB_STOP - (column % TAB_STOP);
337
- if (stop > indent) {
338
- return ' '.repeat(stop - indent) + line.slice(index + 1);
339
- }
340
- column = stop;
341
- }
342
- else if (character === ' ') {
343
- column += 1;
344
- }
345
- else {
346
- break;
347
- }
348
- index += 1;
367
+ let column = 0;
368
+ let index = 0;
369
+ while (column < indent && index < line.length) {
370
+ const character = line[index];
371
+ if (character === '\t') {
372
+ const stop = column + TAB_STOP - column % TAB_STOP;
373
+ if (stop > indent) {
374
+ return ' '.repeat(stop - indent) + line.slice(index + 1);
375
+ }
376
+ column = stop;
377
+ } else if (character === ' ') {
378
+ column += 1;
379
+ } else {
380
+ break;
349
381
  }
350
- return line.slice(index);
351
- }
382
+ index += 1;
383
+ }
384
+ return line.slice(index);
385
+ }