@adecore/agents-react 0.23.1 → 0.24.1
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.
- package/README.md +14 -11
- package/dist/agents/AccountDot.js +3 -1
- package/dist/agents/accounts.d.ts +3 -2
- package/dist/agents/accounts.js +5 -6
- package/dist/chat/actions.d.ts +2 -2
- package/dist/chat/actions.js +8 -5
- package/dist/chat/bookmarks.d.ts +5 -3
- package/dist/chat/bookmarks.js +13 -14
- package/dist/chat/chat-client.d.ts +1 -0
- package/dist/chat/chat-client.js +7 -0
- package/dist/chat/composer-send.d.ts +3 -0
- package/dist/chat/composer-send.js +22 -0
- package/dist/chat/forks.js +22 -5
- package/dist/chat/index.d.ts +31 -0
- package/dist/chat/index.js +28 -0
- package/dist/chat/logic/embedded-code.d.ts +8 -0
- package/dist/chat/logic/embedded-code.js +371 -0
- package/dist/chat/logic/fork.js +1 -0
- package/dist/chat/logic/goal.d.ts +6 -0
- package/dist/chat/logic/goal.js +26 -0
- package/dist/chat/logic/scrubber.d.ts +1 -1
- package/dist/chat/logic/scrubber.js +6 -5
- package/dist/chat/logic/thought.d.ts +3 -0
- package/dist/chat/logic/thought.js +35 -0
- package/dist/chat/logic/thread-cards.js +2 -0
- package/dist/chat/logic/timeline.d.ts +5 -0
- package/dist/chat/logic/timeline.js +22 -1
- package/dist/chat/logic/tool-catalog.d.ts +1 -0
- package/dist/chat/logic/tool-catalog.js +3 -1
- package/dist/chat/logic/tools.d.ts +14 -0
- package/dist/chat/logic/tools.js +57 -0
- package/dist/chat/preferences.d.ts +6 -0
- package/dist/chat/preferences.js +19 -3
- package/dist/chat/reading-width.d.ts +9 -0
- package/dist/chat/reading-width.js +27 -0
- package/dist/chat/send-key.d.ts +10 -0
- package/dist/chat/send-key.js +24 -0
- package/dist/chat/ui/BookmarkMarker.js +4 -2
- package/dist/chat/ui/BookmarkSubmenu.js +4 -3
- package/dist/chat/ui/ChatActivity.js +14 -10
- package/dist/chat/ui/ChatReferenceChip.js +3 -4
- package/dist/chat/ui/CodeBlock.d.ts +2 -1
- package/dist/chat/ui/CodeBlock.js +14 -96
- package/dist/chat/ui/Composer.d.ts +1 -1
- package/dist/chat/ui/Composer.js +130 -907
- package/dist/chat/ui/ComposerInput.js +5 -4
- package/dist/chat/ui/EditDiff.js +3 -2
- package/dist/chat/ui/GoalDock.d.ts +9 -0
- package/dist/chat/ui/GoalDock.js +63 -0
- package/dist/chat/ui/LimitState.js +5 -3
- package/dist/chat/ui/Markdown.d.ts +2 -1
- package/dist/chat/ui/Markdown.js +70 -31
- package/dist/chat/ui/MermaidBlock.d.ts +3 -0
- package/dist/chat/ui/MermaidBlock.js +73 -0
- package/dist/chat/ui/MessageActions.js +12 -7
- package/dist/chat/ui/Pickers.js +6 -5
- package/dist/chat/ui/PromptComposer.js +4 -3
- package/dist/chat/ui/RowTime.d.ts +3 -0
- package/dist/chat/ui/RowTime.js +12 -0
- package/dist/chat/ui/RunSettings.js +5 -4
- package/dist/chat/ui/ShellCommand.d.ts +3 -0
- package/dist/chat/ui/ShellCommand.js +110 -0
- package/dist/chat/ui/SubagentInfo.js +4 -3
- package/dist/chat/ui/SubagentStopButton.js +4 -3
- package/dist/chat/ui/SubagentTimeline.js +4 -1
- package/dist/chat/ui/Timeline.js +70 -40
- package/dist/chat/ui/TimelineMenu.d.ts +2 -1
- package/dist/chat/ui/TimelineMenu.js +18 -8
- package/dist/chat/ui/UnifiedDiff.js +3 -2
- package/dist/chat/ui/VisualFrame.js +6 -7
- package/dist/chat/ui/code-theme.d.ts +2 -1
- package/dist/chat/ui/code-theme.js +4 -4
- package/dist/chat/ui/composer/ComposerControls.d.ts +27 -0
- package/dist/chat/ui/composer/ComposerControls.js +34 -0
- package/dist/chat/ui/composer/ComposerMenu.d.ts +4 -0
- package/dist/chat/ui/composer/ComposerMenu.js +46 -0
- package/dist/chat/ui/composer/DraftParts.d.ts +18 -0
- package/dist/chat/ui/composer/DraftParts.js +25 -0
- package/dist/chat/ui/composer/QueuedMessages.d.ts +10 -0
- package/dist/chat/ui/composer/QueuedMessages.js +20 -0
- package/dist/chat/ui/composer/key-handler.d.ts +20 -0
- package/dist/chat/ui/composer/key-handler.js +150 -0
- package/dist/chat/ui/composer/keys.d.ts +7 -2
- package/dist/chat/ui/composer/keys.js +19 -9
- package/dist/chat/ui/composer/placeholder.d.ts +9 -0
- package/dist/chat/ui/composer/placeholder.js +38 -0
- package/dist/chat/ui/composer/surface.d.ts +1 -0
- package/dist/chat/ui/composer/surface.js +44 -0
- package/dist/chat/ui/composer/use-chat-controls.d.ts +28 -0
- package/dist/chat/ui/composer/use-chat-controls.js +112 -0
- package/dist/chat/ui/composer/use-compaction-offer.d.ts +2 -0
- package/dist/chat/ui/composer/use-compaction-offer.js +23 -0
- package/dist/chat/ui/composer/use-composer-draft.d.ts +14 -0
- package/dist/chat/ui/composer/use-composer-draft.js +39 -0
- package/dist/chat/ui/composer/use-composer-menus.d.ts +52 -0
- package/dist/chat/ui/composer/use-composer-menus.js +232 -0
- package/dist/chat/ui/composer/use-composer-submit.d.ts +32 -0
- package/dist/chat/ui/composer/use-composer-submit.js +113 -0
- package/dist/chat/ui/composer/use-draft-files.d.ts +27 -0
- package/dist/chat/ui/composer/use-draft-files.js +111 -0
- package/dist/chat/ui/composer/use-notice.d.ts +6 -0
- package/dist/chat/ui/composer/use-notice.js +18 -0
- package/dist/chat/ui/composer/use-pending-requests.d.ts +2 -0
- package/dist/chat/ui/composer/use-pending-requests.js +22 -0
- package/dist/chat/ui/composer/use-prompt-history.d.ts +8 -0
- package/dist/chat/ui/composer/use-prompt-history.js +57 -0
- package/dist/chat/ui/composer/use-prompt-hold.d.ts +6 -0
- package/dist/chat/ui/composer/use-prompt-hold.js +48 -0
- package/dist/chat/ui/composer/use-take-back.d.ts +13 -0
- package/dist/chat/ui/composer/use-take-back.js +82 -0
- package/dist/chat/ui/diff/EditorEditDiff.js +4 -3
- package/dist/chat/ui/diff/LegacyDiffPool.js +3 -2
- package/dist/chat/ui/diff/LegacyEditDiff.js +3 -2
- package/dist/chat/ui/diff/LegacyUnifiedDiff.js +3 -2
- package/dist/chat/ui/diff/syntax-runtime.d.ts +2 -1
- package/dist/chat/ui/diff/syntax-runtime.js +9 -5
- package/dist/chat/ui/diff-syntax.d.ts +2 -2
- package/dist/chat/ui/diff-syntax.js +1 -2
- package/dist/chat/ui/diff-theme.js +10 -9
- package/dist/chat/ui/file-links.d.ts +1 -1
- package/dist/chat/ui/file-links.js +7 -5
- package/dist/chat/ui/highlighter.d.ts +27 -0
- package/dist/chat/ui/highlighter.js +151 -0
- package/dist/chat/ui/index.d.ts +67 -0
- package/dist/chat/ui/index.js +64 -0
- package/dist/chat/ui/intelligent-ui/UiReply.js +3 -2
- package/dist/chat/ui/intelligent-ui/renderers/content.js +3 -2
- package/dist/chat/ui/intelligent-ui/use-ui-links.js +2 -2
- package/dist/chat/ui/intelligent-ui/use-ui-queries.js +4 -3
- package/dist/chat/ui/markdown-blocks.d.ts +8 -0
- package/dist/chat/ui/markdown-blocks.js +260 -12
- package/dist/chat/ui/mermaid.d.ts +23 -0
- package/dist/chat/ui/mermaid.js +93 -0
- package/dist/chat/ui/rows/ForksRow.js +5 -3
- package/dist/chat/ui/rows/GeneratedImageRow.js +6 -4
- package/dist/chat/ui/rows/MessageRows.d.ts +4 -0
- package/dist/chat/ui/rows/MessageRows.js +36 -13
- package/dist/chat/ui/rows/Rows.js +3 -1
- package/dist/chat/ui/rows/SubagentRow.js +3 -2
- package/dist/chat/ui/rows/VisualRow.js +3 -2
- package/dist/chat/ui/rows/WorkRows.d.ts +6 -3
- package/dist/chat/ui/rows/WorkRows.js +57 -20
- package/dist/chat/ui/rows/WorkflowRow.js +3 -2
- package/dist/chat/ui/timestamp-format.d.ts +1 -0
- package/dist/chat/ui/timestamp-format.js +2 -0
- package/dist/chat/ui/use-diff-source-tokens.js +6 -3
- package/dist/chat/ui/visual-theme.js +3 -2
- package/dist/host.d.ts +9 -6
- package/dist/host.js +19 -8
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/locales/en/agent-chat.d.ts +658 -0
- package/dist/locales/en/agent-chat.js +657 -0
- package/dist/locales/en/agent-prompts.d.ts +44 -0
- package/dist/locales/en/agent-prompts.js +43 -0
- package/dist/locales/en/agent-providers.d.ts +132 -0
- package/dist/locales/en/agent-providers.js +131 -0
- package/dist/locales/en/agent-usage.d.ts +132 -0
- package/dist/locales/en/agent-usage.js +131 -0
- package/dist/locales/nl/agent-chat.d.ts +658 -0
- package/dist/locales/nl/agent-chat.js +657 -0
- package/dist/locales/nl/agent-prompts.d.ts +44 -0
- package/dist/locales/nl/agent-prompts.js +43 -0
- package/dist/locales/nl/agent-providers.d.ts +132 -0
- package/dist/locales/nl/agent-providers.js +131 -0
- package/dist/locales/nl/agent-usage.d.ts +132 -0
- package/dist/locales/nl/agent-usage.js +131 -0
- package/dist/locales.js +9 -8
- package/dist/prompts/index.d.ts +11 -0
- package/dist/prompts/index.js +12 -0
- package/dist/prompts/logic/subjects.d.ts +2 -1
- package/dist/prompts/logic/subjects.js +6 -4
- package/dist/prompts/ui/ApprovalBody.js +6 -4
- package/dist/prompts/ui/PromptCard.js +5 -4
- package/dist/prompts/ui/PromptView.js +3 -2
- package/dist/prompts/ui/QuestionBody.js +3 -2
- package/dist/providers/AccountColors.js +2 -2
- package/dist/providers/AccountDetail.js +7 -6
- package/dist/providers/AccountVariables.js +3 -1
- package/dist/providers/AddAccountForm.js +3 -2
- package/dist/providers/ProvidersPane.js +4 -3
- package/dist/providers/account-actions.d.ts +4 -3
- package/dist/providers/account-actions.js +6 -7
- package/dist/providers/index.d.ts +16 -0
- package/dist/providers/index.js +17 -0
- package/dist/providers/provider-abilities.d.ts +2 -1
- package/dist/providers/provider-abilities.js +4 -0
- package/dist/state/chats.js +4 -2
- package/dist/state/index.d.ts +4 -0
- package/dist/state/index.js +5 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +2 -0
- package/dist/{prompts/logic/prompts.fixtures.d.ts → testing/prompts.d.ts} +1 -1
- package/dist/theme.css +13 -3
- package/dist/usage/UsageBreakdown.js +3 -2
- package/dist/usage/UsageLimits.js +4 -3
- package/dist/usage/UsagePage.js +3 -2
- package/dist/usage/index.d.ts +15 -0
- package/dist/usage/index.js +15 -0
- package/package.json +53 -1031
- package/src/agents/AccountDot.tsx +3 -1
- package/src/agents/accounts.ts +6 -6
- package/src/chat/actions.ts +8 -5
- package/src/chat/bookmarks.ts +23 -14
- package/src/chat/chat-client.ts +8 -0
- package/src/chat/composer-send.ts +27 -0
- package/src/chat/forks.ts +27 -6
- package/src/chat/index.ts +98 -0
- package/src/chat/logic/embedded-code.ts +409 -0
- package/src/chat/logic/fork.ts +1 -0
- package/src/chat/logic/goal.ts +33 -0
- package/src/chat/logic/scrubber.ts +6 -5
- package/src/chat/logic/thought.ts +40 -0
- package/src/chat/logic/thread-cards.ts +2 -0
- package/src/chat/logic/timeline.ts +25 -1
- package/src/chat/logic/tool-catalog.ts +5 -1
- package/src/chat/logic/tools.ts +76 -0
- package/src/chat/preferences.ts +26 -3
- package/src/chat/reading-width.ts +39 -0
- package/src/chat/send-key.ts +38 -0
- package/src/chat/ui/BookmarkMarker.tsx +4 -2
- package/src/chat/ui/BookmarkSubmenu.tsx +4 -3
- package/src/chat/ui/ChatActivity.tsx +14 -10
- package/src/chat/ui/ChatReferenceChip.tsx +3 -4
- package/src/chat/ui/CodeBlock.tsx +33 -124
- package/src/chat/ui/Composer.tsx +212 -1358
- package/src/chat/ui/ComposerInput.tsx +5 -4
- package/src/chat/ui/EditDiff.tsx +3 -2
- package/src/chat/ui/GoalDock.tsx +104 -0
- package/src/chat/ui/LimitState.tsx +5 -3
- package/src/chat/ui/Markdown.tsx +113 -39
- package/src/chat/ui/MermaidBlock.tsx +119 -0
- package/src/chat/ui/MessageActions.tsx +13 -8
- package/src/chat/ui/Pickers.tsx +8 -7
- package/src/chat/ui/PromptComposer.tsx +4 -3
- package/src/chat/ui/RowTime.tsx +21 -0
- package/src/chat/ui/RunSettings.tsx +9 -4
- package/src/chat/ui/ShellCommand.tsx +134 -0
- package/src/chat/ui/SubagentInfo.tsx +4 -3
- package/src/chat/ui/SubagentStopButton.tsx +4 -3
- package/src/chat/ui/SubagentTimeline.tsx +5 -1
- package/src/chat/ui/Timeline.tsx +167 -105
- package/src/chat/ui/TimelineMenu.tsx +42 -7
- package/src/chat/ui/UnifiedDiff.tsx +3 -2
- package/src/chat/ui/VisualFrame.tsx +6 -7
- package/src/chat/ui/code-theme.ts +4 -4
- package/src/chat/ui/composer/ComposerControls.tsx +147 -0
- package/src/chat/ui/composer/ComposerMenu.tsx +138 -0
- package/src/chat/ui/composer/DraftParts.tsx +86 -0
- package/src/chat/ui/composer/QueuedMessages.tsx +64 -0
- package/src/chat/ui/composer/key-handler.ts +174 -0
- package/src/chat/ui/composer/keys.ts +32 -10
- package/src/chat/ui/composer/placeholder.ts +48 -0
- package/src/chat/ui/composer/surface.ts +45 -0
- package/src/chat/ui/composer/use-chat-controls.ts +134 -0
- package/src/chat/ui/composer/use-compaction-offer.ts +25 -0
- package/src/chat/ui/composer/use-composer-draft.ts +71 -0
- package/src/chat/ui/composer/use-composer-menus.ts +289 -0
- package/src/chat/ui/composer/use-composer-submit.ts +163 -0
- package/src/chat/ui/composer/use-draft-files.ts +135 -0
- package/src/chat/ui/composer/use-notice.ts +28 -0
- package/src/chat/ui/composer/use-pending-requests.ts +23 -0
- package/src/chat/ui/composer/use-prompt-history.ts +76 -0
- package/src/chat/ui/composer/use-prompt-hold.ts +58 -0
- package/src/chat/ui/composer/use-take-back.ts +91 -0
- package/src/chat/ui/diff/DiffFallbackBoundary.tsx +2 -2
- package/src/chat/ui/diff/EditorEditDiff.tsx +4 -3
- package/src/chat/ui/diff/LegacyDiffPool.tsx +3 -2
- package/src/chat/ui/diff/LegacyEditDiff.tsx +3 -2
- package/src/chat/ui/diff/LegacyUnifiedDiff.tsx +3 -2
- package/src/chat/ui/diff/syntax-runtime.ts +10 -5
- package/src/chat/ui/diff-syntax.ts +2 -2
- package/src/chat/ui/diff-theme.ts +10 -9
- package/src/chat/ui/file-links.ts +7 -5
- package/src/chat/ui/highlighter.ts +185 -0
- package/src/chat/ui/index.ts +109 -0
- package/src/chat/ui/intelligent-ui/UiReply.tsx +5 -4
- package/src/chat/ui/intelligent-ui/renderers/content.tsx +3 -2
- package/src/chat/ui/intelligent-ui/use-ui-links.ts +2 -2
- package/src/chat/ui/intelligent-ui/use-ui-queries.ts +4 -3
- package/src/chat/ui/markdown-blocks.ts +300 -12
- package/src/chat/ui/mermaid.ts +118 -0
- package/src/chat/ui/rows/ForksRow.tsx +5 -3
- package/src/chat/ui/rows/GeneratedImageRow.tsx +6 -4
- package/src/chat/ui/rows/MessageRows.tsx +73 -18
- package/src/chat/ui/rows/Rows.tsx +14 -1
- package/src/chat/ui/rows/SubagentRow.tsx +3 -2
- package/src/chat/ui/rows/VisualRow.tsx +3 -2
- package/src/chat/ui/rows/WorkRows.tsx +148 -47
- package/src/chat/ui/rows/WorkflowRow.tsx +3 -2
- package/src/chat/ui/timestamp-format.ts +2 -0
- package/src/chat/ui/use-diff-source-tokens.ts +10 -4
- package/src/chat/ui/visual-theme.ts +3 -2
- package/src/host.ts +31 -15
- package/src/index.ts +49 -0
- package/src/locales/en/agent-chat.ts +657 -0
- package/src/locales/en/agent-prompts.ts +43 -0
- package/src/locales/en/agent-providers.ts +131 -0
- package/src/locales/en/agent-usage.ts +131 -0
- package/src/locales/nl/agent-chat.ts +657 -0
- package/src/locales/nl/agent-prompts.ts +43 -0
- package/src/locales/nl/agent-providers.ts +131 -0
- package/src/locales/nl/agent-usage.ts +132 -0
- package/src/locales.ts +9 -8
- package/src/prompts/index.ts +35 -0
- package/src/prompts/logic/subjects.ts +12 -4
- package/src/prompts/ui/ApprovalBody.tsx +6 -4
- package/src/prompts/ui/PromptCard.tsx +11 -4
- package/src/prompts/ui/PromptView.tsx +3 -2
- package/src/prompts/ui/QuestionBody.tsx +3 -2
- package/src/providers/AccountColors.tsx +2 -2
- package/src/providers/AccountDetail.tsx +13 -7
- package/src/providers/AccountVariables.tsx +3 -1
- package/src/providers/AddAccountForm.tsx +3 -2
- package/src/providers/ProvidersPane.tsx +4 -3
- package/src/providers/account-actions.ts +7 -7
- package/src/providers/index.ts +17 -0
- package/src/providers/provider-abilities.ts +6 -1
- package/src/state/chats.ts +4 -2
- package/src/state/index.ts +39 -0
- package/src/testing/index.ts +2 -0
- package/src/{prompts/logic/prompts.fixtures.ts → testing/prompts.ts} +1 -1
- package/src/theme.css +13 -3
- package/src/usage/UsageBreakdown.tsx +3 -2
- package/src/usage/UsageLimits.tsx +4 -3
- package/src/usage/UsagePage.tsx +3 -2
- package/src/usage/index.ts +16 -0
- package/dist/locales/en/agent-chat.json +0 -597
- package/dist/locales/en/agent-prompts.json +0 -43
- package/dist/locales/en/agent-providers.json +0 -131
- package/dist/locales/en/agent-usage.json +0 -131
- package/dist/locales/nl/agent-chat.json +0 -597
- package/dist/locales/nl/agent-prompts.json +0 -43
- package/dist/locales/nl/agent-providers.json +0 -131
- package/dist/locales/nl/agent-usage.json +0 -131
- package/src/locales/en/agent-chat.json +0 -597
- package/src/locales/en/agent-prompts.json +0 -43
- package/src/locales/en/agent-providers.json +0 -131
- package/src/locales/en/agent-usage.json +0 -131
- package/src/locales/nl/agent-chat.json +0 -597
- package/src/locales/nl/agent-prompts.json +0 -43
- package/src/locales/nl/agent-providers.json +0 -131
- package/src/locales/nl/agent-usage.json +0 -131
- /package/dist/{prompts/logic/prompts.fixtures.js → testing/prompts.js} +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Public API: exports.test.ts snapshots this list, so a name added or dropped here is an API change.
|
|
2
|
+
export { AccountPill } from './AccountPill';
|
|
3
|
+
export { AnsiOutput } from './AnsiOutput';
|
|
4
|
+
export { BookmarkMarker } from './BookmarkMarker';
|
|
5
|
+
export { BookmarkSubmenu } from './BookmarkSubmenu';
|
|
6
|
+
export { ChatActivity, StatusIcon } from './ChatActivity';
|
|
7
|
+
export { ChatReferenceChip } from './ChatReferenceChip';
|
|
8
|
+
export { CodeBlock } from './CodeBlock';
|
|
9
|
+
export { Composer } from './Composer';
|
|
10
|
+
export { type ComposerInputHandle, ComposerInput, type InputSelection } from './ComposerInput';
|
|
11
|
+
export { default as DiffPool } from './DiffPool';
|
|
12
|
+
export { default as EditDiff } from './EditDiff';
|
|
13
|
+
export { FadingWords } from './FadingWords';
|
|
14
|
+
export { GoalDock, GoalPill } from './GoalDock';
|
|
15
|
+
export { ImageThumb, type ImageThumbProps } from './ImageView';
|
|
16
|
+
export { LimitDock, LimitPill } from './LimitState';
|
|
17
|
+
export { ReplyMarkdown, MessageMarkdown, Markdown } from './Markdown';
|
|
18
|
+
export { MermaidBlock } from './MermaidBlock';
|
|
19
|
+
export { MessageActions } from './MessageActions';
|
|
20
|
+
export { ModelPicker, StashPicker } from './Pickers';
|
|
21
|
+
export { type PromptHold, PromptComposer } from './PromptComposer';
|
|
22
|
+
export { QuoteButton } from './QuoteButton';
|
|
23
|
+
export { ResumeCompactionDock } from './ResumeCompactionDock';
|
|
24
|
+
export { RowTime } from './RowTime';
|
|
25
|
+
export { RunSettings } from './RunSettings';
|
|
26
|
+
export { Scrubber, type CardChat } from './Scrubber';
|
|
27
|
+
export { SubagentTitleCrumb, SubagentBreadcrumb, SubagentActions } from './SubagentControls';
|
|
28
|
+
export { SubagentInfo } from './SubagentInfo';
|
|
29
|
+
export { SubagentStopButton } from './SubagentStopButton';
|
|
30
|
+
export { SubagentTimeline } from './SubagentTimeline';
|
|
31
|
+
export { Timeline } from './Timeline';
|
|
32
|
+
export { TimelineMenuPopup, BookmarkMenuItems } from './TimelineMenu';
|
|
33
|
+
export { default as UnifiedDiff } from './UnifiedDiff';
|
|
34
|
+
export { UploadThumb } from './UploadThumb';
|
|
35
|
+
export { VisualDialogs } from './VisualDialogs';
|
|
36
|
+
export { type VisualFrameProps, VisualFrame } from './VisualFrame';
|
|
37
|
+
export { WelcomeGreeting } from './Welcome';
|
|
38
|
+
export { chipDecorations, type ChipChoices } from './composer/chips';
|
|
39
|
+
export { externalChange, markdownLanguage, composerEditorExtensions } from './composer/editor';
|
|
40
|
+
export { insertAtSelection } from './composer/insert';
|
|
41
|
+
export {
|
|
42
|
+
listItemAt,
|
|
43
|
+
enterAction,
|
|
44
|
+
inOpenFence,
|
|
45
|
+
recallDirection,
|
|
46
|
+
type EnterAction,
|
|
47
|
+
type EnterKeys,
|
|
48
|
+
type ListItem,
|
|
49
|
+
type EnterContext,
|
|
50
|
+
type RecallContext
|
|
51
|
+
} from './composer/keys';
|
|
52
|
+
export {
|
|
53
|
+
createDiffSyntaxRuntime,
|
|
54
|
+
diffSyntaxRuntime,
|
|
55
|
+
type DiffSyntaxRuntime,
|
|
56
|
+
type DiffSyntaxRuntimeOptions,
|
|
57
|
+
type DiffSyntaxSession,
|
|
58
|
+
type DiffSyntaxMapping,
|
|
59
|
+
type DiffSourceTokenSession,
|
|
60
|
+
diffSourceTokens
|
|
61
|
+
} from './diff-syntax';
|
|
62
|
+
export { useDiffTheme } from './diff-theme';
|
|
63
|
+
export type { UnifiedDiffProps } from './diff/diff-props';
|
|
64
|
+
export { FileLinkContext, useFileLinkCwd, useFileLinkScopeId, useOpenFileLink } from './file-links';
|
|
65
|
+
export { type ChatFindField, type FindReveal, useOpenForFind } from './find-reveal';
|
|
66
|
+
export type { DiffContents } from './full-diff';
|
|
67
|
+
export { type UiBlockFrameProps, UiBlockFrame, type UiBlockFix, type UiBlockFooterProps } from './intelligent-ui/UiBlockFrame';
|
|
68
|
+
export { UiFallbackPart, type UiFallbackProblem } from './intelligent-ui/UiFallbackPart';
|
|
69
|
+
export { UiReply } from './intelligent-ui/UiReply';
|
|
70
|
+
export { uiChartData, type UiChartSeries, type UiChartValues, type UiChartData } from './intelligent-ui/chart-data';
|
|
71
|
+
export { uiNodeLabel } from './intelligent-ui/node-text';
|
|
72
|
+
export { UI_RENDERERS } from './intelligent-ui/registry';
|
|
73
|
+
export type {
|
|
74
|
+
UiRenderContext,
|
|
75
|
+
UiRendererProps,
|
|
76
|
+
UiLinkTarget,
|
|
77
|
+
UiLink,
|
|
78
|
+
UiAnswer,
|
|
79
|
+
UiLiveStatus,
|
|
80
|
+
UiLiveValue,
|
|
81
|
+
UiRenderer,
|
|
82
|
+
UiRenderers
|
|
83
|
+
} from './intelligent-ui/render-context';
|
|
84
|
+
export { uiTableColumns, type UiColumnKind, type UiTableColumn } from './intelligent-ui/table-data';
|
|
85
|
+
export type { QuoteTaker } from './quote-selection';
|
|
86
|
+
export { ReplyContext } from './reply-context';
|
|
87
|
+
export { ForksRow } from './rows/ForksRow';
|
|
88
|
+
export { GeneratedImageRow } from './rows/GeneratedImageRow';
|
|
89
|
+
export {
|
|
90
|
+
UserRow,
|
|
91
|
+
ReportRow,
|
|
92
|
+
ReplyHeader,
|
|
93
|
+
AssistantRow,
|
|
94
|
+
ThinkingRow,
|
|
95
|
+
LiveThoughtRow,
|
|
96
|
+
NoteRow,
|
|
97
|
+
AgentTurnRow,
|
|
98
|
+
CompactionRow,
|
|
99
|
+
ApprovalHistoryRow,
|
|
100
|
+
QuestionHistoryRow
|
|
101
|
+
} from './rows/MessageRows';
|
|
102
|
+
export { type RowContainerProps, RowContainer } from './rows/RowContainer';
|
|
103
|
+
export { Row, type RowProps } from './rows/Rows';
|
|
104
|
+
export { SubagentRow, SubagentBranchRow } from './rows/SubagentRow';
|
|
105
|
+
export { TaskRow } from './rows/TaskRow';
|
|
106
|
+
export { VisualRow } from './rows/VisualRow';
|
|
107
|
+
export { ToggleLine, WorkRow, RunningFor, WorkLiveRow, WorkGroupRow, TurnFoldRow, ChangedFilesRow, WorkingRow } from './rows/WorkRows';
|
|
108
|
+
export { WorkflowRow } from './rows/WorkflowRow';
|
|
109
|
+
export { useDiffSourceTokens } from './use-diff-source-tokens';
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from '@adecore/intelligent-ui';
|
|
27
27
|
import { ErrorBoundary, Tooltip } from '@adecore/ui';
|
|
28
28
|
import type { ChatUiAnswer, ChatUiQueryState } from '@adecore/agent-contracts';
|
|
29
|
-
import {
|
|
29
|
+
import { useChatHost } from '../../../host';
|
|
30
30
|
import { UiReplyNavigationContext } from '../reply-context';
|
|
31
31
|
import { ReplyMarkdown } from '../Markdown';
|
|
32
32
|
import { rehypeFadeWords } from '../rehype-fade';
|
|
@@ -314,7 +314,7 @@ interface UiNodeBoundaryState {
|
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
class UiNodeBoundary extends Component<UiNodeBoundaryProps, UiNodeBoundaryState> {
|
|
317
|
-
state = { failed: false, node: this.props.node };
|
|
317
|
+
override state = { failed: false, node: this.props.node };
|
|
318
318
|
|
|
319
319
|
static getDerivedStateFromError(): { failed: boolean } {
|
|
320
320
|
return { failed: true };
|
|
@@ -324,7 +324,7 @@ class UiNodeBoundary extends Component<UiNodeBoundaryProps, UiNodeBoundaryState>
|
|
|
324
324
|
return props.node === state.node ? null : { failed: false, node: props.node };
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
-
render(): ReactNode {
|
|
327
|
+
override render(): ReactNode {
|
|
328
328
|
return this.state.failed ? <UiFallbackPart fallback={this.props.node.fallback} problem={{ kind: 'failed' }} /> : this.props.children;
|
|
329
329
|
}
|
|
330
330
|
}
|
|
@@ -379,6 +379,7 @@ function UiBlockBody({
|
|
|
379
379
|
answered?: ChatUiAnswer;
|
|
380
380
|
frozen?: ChatUiQueryState['blocks'][string];
|
|
381
381
|
}): ReactNode {
|
|
382
|
+
const host = useChatHost();
|
|
382
383
|
const { t } = useTranslation('agent-chat');
|
|
383
384
|
const key = JSON.stringify([context.scopeId, context.chatId, context.itemId, block.id]);
|
|
384
385
|
const [state] = useState(() => localState(key, block, answered));
|
|
@@ -428,7 +429,7 @@ function UiBlockBody({
|
|
|
428
429
|
[sources, element]
|
|
429
430
|
);
|
|
430
431
|
const liveValue = useUiLiveValues(block, evaluation.nodes, queries.currentReadings);
|
|
431
|
-
const sendChoice =
|
|
432
|
+
const sendChoice = host.intelligentUi?.sendChoice;
|
|
432
433
|
const rendering: UiRenderContext = {
|
|
433
434
|
...context,
|
|
434
435
|
...links,
|
|
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import type { UiProps } from '@adecore/intelligent-ui';
|
|
5
5
|
import { PreviewCard, Tooltip } from '@adecore/ui';
|
|
6
6
|
import { formatNumber } from '@adecore/ui/format';
|
|
7
|
-
import {
|
|
7
|
+
import { useChatHost } from '../../../../host';
|
|
8
8
|
import { CodeBlock } from '../../CodeBlock';
|
|
9
9
|
import { CodeStreamingContext } from '../../code-streaming';
|
|
10
10
|
import { ImageThumb } from '../../ImageView';
|
|
@@ -26,7 +26,8 @@ export function CodeBlockRenderer({ node }: UiRendererProps<UiProps<'CodeBlock'>
|
|
|
26
26
|
|
|
27
27
|
/* Its own component, so the host's hook is only called for an image that names an attachment. */
|
|
28
28
|
function AttachedImage({ scopeId, chatId, attachmentId, alt }: { scopeId: string; chatId: string; attachmentId: string; alt: string }) {
|
|
29
|
-
const
|
|
29
|
+
const host = useChatHost();
|
|
30
|
+
const source = host.attachments.useUrl(scopeId, chatId, attachmentId);
|
|
30
31
|
return <ImageThumb source={source} alt={alt} className="max-h-70 max-w-full object-contain" />;
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
2
2
|
import type { ChatUiLinkReading, ChatUiQueryState } from '@adecore/agent-contracts';
|
|
3
3
|
import { uiLinkTargets, type UiLinkTarget } from '@adecore/intelligent-ui/links';
|
|
4
4
|
import { uiInputValues, UI_HOST_LIMITS, type UiBlock, UiState } from '@adecore/intelligent-ui';
|
|
5
|
-
import {
|
|
5
|
+
import { useChatHost } from '../../../host';
|
|
6
6
|
import type { UiRenderContext } from './render-context';
|
|
7
7
|
|
|
8
8
|
interface LinkState {
|
|
@@ -23,7 +23,7 @@ export function useUiLinks(
|
|
|
23
23
|
const [checked, setChecked] = useState<Record<string, LinkState>>({});
|
|
24
24
|
// What each node was last checked as, so a change of input checks only the targets it moved.
|
|
25
25
|
const asked = useRef(new Map<string, string>());
|
|
26
|
-
const host =
|
|
26
|
+
const host = useChatHost().intelligentUi;
|
|
27
27
|
const values = uiInputValues(block, state);
|
|
28
28
|
const scope = state.scope();
|
|
29
29
|
const queryValues = Object.fromEntries(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import type { ChatUiQueryReading, ChatUiQueryState } from '@adecore/agent-contracts';
|
|
3
3
|
import { uiInputValues, UI_CATALOG_VERSION, UI_HOST_LIMITS, UiState, type UiBlock, type UiViewNode, type UiNode } from '@adecore/intelligent-ui';
|
|
4
|
-
import {
|
|
4
|
+
import { useChatHost } from '../../../host';
|
|
5
5
|
import type { UiLiveValue, UiLiveStatus, UiRenderContext } from './render-context';
|
|
6
6
|
|
|
7
7
|
interface LocalReading {
|
|
@@ -43,6 +43,7 @@ export function useUiQueries(
|
|
|
43
43
|
element: HTMLDivElement | null,
|
|
44
44
|
frozen?: ChatUiQueryState['blocks'][string]
|
|
45
45
|
) {
|
|
46
|
+
const host = useChatHost();
|
|
46
47
|
const [readings, setReadings] = useState<Record<string, LocalReading>>({});
|
|
47
48
|
const [busyInput, setBusyInput] = useState<string | null>(null);
|
|
48
49
|
const lastRead = useRef({ inputKey: '', at: 0 });
|
|
@@ -70,8 +71,8 @@ export function useUiQueries(
|
|
|
70
71
|
};
|
|
71
72
|
const reads = readsFor(JSON.parse(inputs));
|
|
72
73
|
const ready = reads !== null;
|
|
73
|
-
const query =
|
|
74
|
-
const subscribe =
|
|
74
|
+
const query = host.intelligentUi?.query;
|
|
75
|
+
const subscribe = host.intelligentUi?.subscribe;
|
|
75
76
|
useEffect(() => {
|
|
76
77
|
const scope = state.scope();
|
|
77
78
|
for (const name of Object.keys(block.queries)) {
|
|
@@ -2,6 +2,20 @@ export interface MarkdownBlock {
|
|
|
2
2
|
text: string;
|
|
3
3
|
/* The block ends inside a code fence that has not closed yet. */
|
|
4
4
|
openFence: boolean;
|
|
5
|
+
/* Set when the block is one code fence at the top level of the text, read as markdown reads it. */
|
|
6
|
+
fence?: MarkdownFence;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface MarkdownFence {
|
|
10
|
+
/* The run of backticks or tildes that opens it. */
|
|
11
|
+
marker: string;
|
|
12
|
+
/* What follows the marker on its line, trimmed. Its first word is the language. */
|
|
13
|
+
info: string;
|
|
14
|
+
/* The lines between the fences, less the indentation of the opening fence. */
|
|
15
|
+
body: string;
|
|
16
|
+
closed: boolean;
|
|
17
|
+
/* The fence as written, from its opening marker to the end of its closing one or of the text. */
|
|
18
|
+
source: string;
|
|
5
19
|
}
|
|
6
20
|
|
|
7
21
|
interface OpenFence {
|
|
@@ -10,45 +24,202 @@ interface OpenFence {
|
|
|
10
24
|
indent: number;
|
|
11
25
|
}
|
|
12
26
|
|
|
27
|
+
interface TopFence {
|
|
28
|
+
// Where the opening marker stands in the text.
|
|
29
|
+
from: number;
|
|
30
|
+
marker: string;
|
|
31
|
+
info: string;
|
|
32
|
+
indent: number;
|
|
33
|
+
body: string;
|
|
34
|
+
// The line ending of the last line in `body`, which goes in front of the next one; null before the first.
|
|
35
|
+
ending: string | null;
|
|
36
|
+
// Markdown decodes an escape or a character reference in the language, so such a fence is left to it.
|
|
37
|
+
direct: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* The outermost list item a line may still belong to. */
|
|
41
|
+
interface ListItem {
|
|
42
|
+
// The column its content starts at; a line less indented than that is not part of it.
|
|
43
|
+
column: number;
|
|
44
|
+
// The bullet, or the delimiter of a number, which a next item of the same list repeats.
|
|
45
|
+
kind: string;
|
|
46
|
+
// False once a line may or may not have ended it, which only markdown itself can tell.
|
|
47
|
+
certain: boolean;
|
|
48
|
+
// Nothing stands in it yet.
|
|
49
|
+
empty: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
13
52
|
const FENCE = /^([ \t]*)(`{3,}|~{3,})(.*)$/;
|
|
53
|
+
const CLOSING_FENCE = /^ {0,3}(`{3,}|~{3,})[ \t]*$/;
|
|
14
54
|
// Spaces and tabs only: a line that holds a no-break space is text to markdown, not a blank line.
|
|
15
55
|
const BLANK = /^[ \t]*$/;
|
|
16
56
|
// A line that continues what stood before the blank line: an indented paragraph of a list item, or
|
|
17
57
|
// the next item of a loose list. Splitting there would change what the markdown means.
|
|
18
58
|
const CONTINUES = /^([ \t]|[-*+][ \t]|\d+[.)][ \t])/;
|
|
59
|
+
const LIST_MARKER = /^[ \t]*(?:([-*+])|(\d{1,9})([.)]))(?:([ \t]+)(.*))?$/;
|
|
60
|
+
// A list item with nothing after its marker.
|
|
61
|
+
const EMPTY_ITEM = /^ {0,3}(?:[-*+]|\d{1,9}[.)])[ \t]*$/;
|
|
62
|
+
const THEMATIC_BREAK = /^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/;
|
|
63
|
+
// A heading or a quote, which ends a list item instead of continuing its paragraph.
|
|
64
|
+
const ENDS_ITEM = /^ {0,3}(?:#{1,6}(?:[ \t]|$)|>)/;
|
|
65
|
+
const HTML_START = /^ {0,3}<[A-Za-z/!?]/;
|
|
66
|
+
// The HTML that runs on until a marker rather than a blank line, with that marker.
|
|
67
|
+
const HTML_UNTIL: [RegExp, RegExp][] = [
|
|
68
|
+
[/^ {0,3}<(?:pre|script|style|textarea)(?:[ \t>]|$)/i, /<\/(?:pre|script|style|textarea)>/i],
|
|
69
|
+
[/^ {0,3}<!--/, /-->/],
|
|
70
|
+
[/^ {0,3}<\?/, /\?>/],
|
|
71
|
+
[/^ {0,3}<![A-Za-z]/, />/],
|
|
72
|
+
[/^ {0,3}<!\[CDATA\[/, /\]\]>/]
|
|
73
|
+
];
|
|
19
74
|
// A reference or footnote definition may be used anywhere in the text, so a block cannot stand alone.
|
|
20
75
|
const DEFINITION = /^ {0,3}\[[^\]]+\]:/m;
|
|
76
|
+
// Markdown ends a line at a lone carriage return too, which a split at line feeds would not see.
|
|
77
|
+
const LONE_RETURN = /\r(?!\n|$)/;
|
|
21
78
|
// How much deeper than its opening a closing fence may sit; deeper than that it is a line of code.
|
|
22
79
|
const CLOSING_INDENT = 3;
|
|
80
|
+
// From four columns in, a line is indented code rather than the start of a block.
|
|
81
|
+
const CODE_INDENT = 4;
|
|
82
|
+
const TAB_STOP = 4;
|
|
23
83
|
// A section title: an ATX heading, or a line of only bold text, which models write as a heading too.
|
|
24
84
|
const HEADING = /^ {0,3}#{1,6}(?:[ \t]|$)/;
|
|
25
85
|
const BOLD_LINE = /^ {0,3}\*\*(?:[^*]|\*(?!\*))+\*\*:?[ \t]*$/;
|
|
26
86
|
|
|
27
87
|
/*
|
|
28
88
|
* A reply cut into blocks at blank lines outside a code fence, so each block parses on its own and
|
|
29
|
-
* only the one still growing is parsed again.
|
|
89
|
+
* only the one still growing is parsed again. A code fence at the top level is a block of its own,
|
|
90
|
+
* through its closing line and the blank lines under it, so it can be drawn without parsing at all.
|
|
91
|
+
* Joined back together the blocks are the text.
|
|
30
92
|
*/
|
|
31
93
|
export function splitMarkdownBlocks(text: string): MarkdownBlock[] {
|
|
32
|
-
if (DEFINITION.test(text)) {
|
|
94
|
+
if (DEFINITION.test(text) || LONE_RETURN.test(text)) {
|
|
33
95
|
return [{ text, openFence: isFenceOpenAtEnd(text) }];
|
|
34
96
|
}
|
|
35
97
|
const lines = text.split('\n');
|
|
36
98
|
const blocks: MarkdownBlock[] = [];
|
|
37
99
|
let start = 0;
|
|
38
100
|
let offset = 0;
|
|
39
|
-
|
|
101
|
+
// The fence as a reading line by line sees it, blind to lists and indented code. A blank line is
|
|
102
|
+
// only cut at where this reading agrees, so every such cut is one this split made before it
|
|
103
|
+
// followed fences any further.
|
|
104
|
+
let lineFence: OpenFence | null = null;
|
|
40
105
|
let afterBlank = false;
|
|
106
|
+
// A fence inside a list item.
|
|
107
|
+
let fence: OpenFence | null = null;
|
|
108
|
+
let top: TopFence | null = null;
|
|
109
|
+
// A top-level fence that has closed; its block takes the blank lines under it.
|
|
110
|
+
let closed: { fence: TopFence; source: string } | null = null;
|
|
111
|
+
let item: ListItem | null = null;
|
|
112
|
+
// The marker that ends the raw HTML the line stands in.
|
|
113
|
+
let html: RegExp | null = null;
|
|
114
|
+
// Whether the top level is still known here. Past HTML, or a line that may or may not end a list
|
|
115
|
+
// item, a fence is left inside the block it stands in, which markdown parses as a whole.
|
|
116
|
+
let known = true;
|
|
117
|
+
// Where the line above starts when it is blank.
|
|
118
|
+
let blankAbove: number | null = null;
|
|
41
119
|
|
|
42
|
-
|
|
43
|
-
if (
|
|
44
|
-
blocks.push({ text: text.slice(start,
|
|
45
|
-
start = offset;
|
|
120
|
+
const cutAt = (end: number): void => {
|
|
121
|
+
if (end > start) {
|
|
122
|
+
blocks.push({ text: text.slice(start, end), openFence: false });
|
|
46
123
|
}
|
|
47
|
-
|
|
48
|
-
|
|
124
|
+
start = end;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
for (const [index, line] of lines.entries()) {
|
|
128
|
+
const at = offset;
|
|
49
129
|
offset += line.length + 1;
|
|
50
|
-
|
|
51
|
-
|
|
130
|
+
const content = withoutReturn(line);
|
|
131
|
+
const blank = BLANK.test(line);
|
|
132
|
+
// Blank to markdown, which a line ending in a carriage return is too.
|
|
133
|
+
const empty = BLANK.test(content);
|
|
134
|
+
const blankCut = lineFence === null && afterBlank && !blank && !CONTINUES.test(line);
|
|
135
|
+
lineFence = nextFence(lineFence, line);
|
|
136
|
+
afterBlank = lineFence === null && blank && index > 0;
|
|
137
|
+
if (top !== null) {
|
|
138
|
+
if (closesFence(top.marker, content)) {
|
|
139
|
+
closed = { fence: top, source: text.slice(top.from, at + content.length) };
|
|
140
|
+
top = null;
|
|
141
|
+
} else if (index < lines.length - 1 || line !== '') {
|
|
142
|
+
// The empty line after a line ending at the end of the text is no line of the fence.
|
|
143
|
+
top.body += (top.ending ?? '') + outdent(content, top.indent);
|
|
144
|
+
top.ending = line.length > content.length ? '\r\n' : '\n';
|
|
145
|
+
}
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (closed !== null) {
|
|
149
|
+
if (empty) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
blocks.push(fenceBlock(text.slice(start, at), closed.fence, closed.source, true));
|
|
153
|
+
start = at;
|
|
154
|
+
closed = null;
|
|
155
|
+
}
|
|
156
|
+
if (html !== null) {
|
|
157
|
+
// Raw HTML holds no fence and no blank line to cut at until its marker.
|
|
158
|
+
if (html.test(content)) {
|
|
159
|
+
html = null;
|
|
160
|
+
}
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (known && fence !== null && item !== null && !empty && columns(content) < item.column) {
|
|
164
|
+
// Code is no paragraph a line may continue lazily, so a line left of the item's content ends
|
|
165
|
+
// the item and its code. A next item of the same list keeps the list going.
|
|
166
|
+
fence = null;
|
|
167
|
+
if (!LIST_MARKER.test(content)) {
|
|
168
|
+
item = null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (blankCut && fence === null) {
|
|
172
|
+
cutAt(at);
|
|
173
|
+
}
|
|
174
|
+
const above = index > 0 ? withoutReturn(lines[index - 1]!) : '';
|
|
175
|
+
const opening = known && fence === null ? openingFence(content) : null;
|
|
176
|
+
if (opening !== null && EMPTY_ITEM.test(above)) {
|
|
177
|
+
// Markdown reads an empty item right above a fence as a list or as text depending on what
|
|
178
|
+
// stands before it, so the two stay in one block.
|
|
179
|
+
known = false;
|
|
180
|
+
} else if (opening !== null && opening.indent < CODE_INDENT && (item === null || opening.indent < item.column)) {
|
|
181
|
+
// The blank line right above goes with the fence. Code in a list item this fence ends takes
|
|
182
|
+
// every blank line under it but the last, and at the end of a block it would take them all.
|
|
183
|
+
cutAt(blankAbove !== null && blankAbove > start ? blankAbove : at);
|
|
184
|
+
// Three columns at most, so the indentation is spaces.
|
|
185
|
+
top = { ...opening, from: at + opening.indent, body: '', ending: null };
|
|
186
|
+
item = null;
|
|
187
|
+
blankAbove = null;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (known && item?.empty === true && empty) {
|
|
191
|
+
// An item with nothing on its first line ends at a blank line right under it.
|
|
192
|
+
item = null;
|
|
193
|
+
}
|
|
194
|
+
if (known && fence === null && !empty) {
|
|
195
|
+
// A fence in an item is followed only while the item is known to be open, and less than four
|
|
196
|
+
// columns deeper than its content: deeper it is code of the item, or of an item inside it.
|
|
197
|
+
if (opening !== null && item !== null && (!item.certain || opening.indent < item.column || opening.indent >= item.column + CODE_INDENT)) {
|
|
198
|
+
known = false;
|
|
199
|
+
} else if (opening === null) {
|
|
200
|
+
item = nextItem(item, content, index > 0 && !BLANK.test(above));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (fence === null && HTML_START.test(content)) {
|
|
204
|
+
known = false;
|
|
205
|
+
const until = HTML_UNTIL.find(([begins]) => begins.test(content))?.[1];
|
|
206
|
+
html = until !== undefined && !until.test(content) ? until : null;
|
|
207
|
+
}
|
|
208
|
+
if (known && (fence !== null || item !== null)) {
|
|
209
|
+
fence = nextFence(fence, fence === null ? itemContent(content) : content);
|
|
210
|
+
}
|
|
211
|
+
if (item?.empty === true && !empty && columns(content) >= item.column) {
|
|
212
|
+
item = { ...item, empty: false };
|
|
213
|
+
}
|
|
214
|
+
blankAbove = empty ? at : null;
|
|
215
|
+
}
|
|
216
|
+
if (top !== null) {
|
|
217
|
+
blocks.push(fenceBlock(text.slice(start), top, text.slice(top.from), false));
|
|
218
|
+
} else if (closed !== null) {
|
|
219
|
+
blocks.push(fenceBlock(text.slice(start), closed.fence, closed.source, true));
|
|
220
|
+
} else {
|
|
221
|
+
blocks.push({ text: text.slice(start), openFence: (known ? fence : lineFence) !== null });
|
|
222
|
+
}
|
|
52
223
|
return blocks;
|
|
53
224
|
}
|
|
54
225
|
|
|
@@ -117,7 +288,124 @@ function nextFence(fence: OpenFence | null, line: string): OpenFence | null {
|
|
|
117
288
|
function isFenceOpenAtEnd(text: string): boolean {
|
|
118
289
|
let fence: OpenFence | null = null;
|
|
119
290
|
for (const line of text.split('\n')) {
|
|
120
|
-
fence = nextFence(fence, line);
|
|
291
|
+
fence = nextFence(fence, withoutReturn(line));
|
|
121
292
|
}
|
|
122
293
|
return fence !== null;
|
|
123
294
|
}
|
|
295
|
+
|
|
296
|
+
/* The fence a line opens wherever it stands, with its indentation in columns. */
|
|
297
|
+
function openingFence(content: string): Pick<TopFence, 'marker' | 'info' | 'indent' | 'direct'> | null {
|
|
298
|
+
const match = FENCE.exec(content);
|
|
299
|
+
if (!match) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
const marker = match[2]!;
|
|
303
|
+
const info = match[3]!.replace(/^[ \t]+|[ \t]+$/g, '');
|
|
304
|
+
// A backtick fence's info string may not hold a backtick, or the line is inline code.
|
|
305
|
+
if (marker[0] === '`' && info.includes('`')) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
return { marker, info, indent: columns(content), direct: !/[\\&]/.test(info.split(/[ \t]/, 1)[0]!) };
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* A line without the carriage return of a CRLF line ending. */
|
|
312
|
+
function withoutReturn(line: string): string {
|
|
313
|
+
return line.endsWith('\r') ? line.slice(0, -1) : line;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function closesFence(marker: string, content: string): boolean {
|
|
317
|
+
const run = CLOSING_FENCE.exec(content)?.[1];
|
|
318
|
+
return run !== undefined && run[0] === marker[0] && run.length >= marker.length;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function fenceBlock(text: string, fence: TopFence, source: string, closed: boolean): MarkdownBlock {
|
|
322
|
+
if (!fence.direct) {
|
|
323
|
+
return { text, openFence: !closed };
|
|
324
|
+
}
|
|
325
|
+
return { text, openFence: !closed, fence: { marker: fence.marker, info: fence.info, body: fence.body, closed, source } };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* The list item a line that is neither blank nor a fence leaves open, as far as a fence needs to know. */
|
|
329
|
+
function nextItem(item: ListItem | null, content: string, underLine: boolean): ListItem | null {
|
|
330
|
+
const indent = columns(content);
|
|
331
|
+
if (item !== null && indent >= item.column) {
|
|
332
|
+
return item;
|
|
333
|
+
}
|
|
334
|
+
if (THEMATIC_BREAK.test(content) || ENDS_ITEM.test(content)) {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
const marker = indent < CODE_INDENT ? itemMarker(content) : null;
|
|
338
|
+
if (marker === null) {
|
|
339
|
+
if (item === null || !underLine) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
// A line right under an item may continue its paragraph, or follow an item that ends in something else.
|
|
343
|
+
return { ...item, certain: false };
|
|
344
|
+
}
|
|
345
|
+
// Right under another line, only a bullet or a 1 with text after it surely starts a list; anything
|
|
346
|
+
// else may be text of a paragraph above.
|
|
347
|
+
const certain = !underLine || (item !== null && item.certain && item.kind === marker.kind) || (marker.first && marker.rest !== '');
|
|
348
|
+
return { column: marker.column, kind: marker.kind, certain, empty: marker.rest === '' };
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* The marker a list item starts with: its kind, whether it may start a list under text, and the column its content starts at. */
|
|
352
|
+
function itemMarker(content: string): { kind: string; first: boolean; column: number; rest: string } | null {
|
|
353
|
+
const match = LIST_MARKER.exec(content);
|
|
354
|
+
if (match === null) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
const [, bullet, number, delimiter, spacing = '', rest = ''] = match;
|
|
358
|
+
const indent = columns(content);
|
|
359
|
+
const width = bullet !== undefined ? 1 : number!.length + 1;
|
|
360
|
+
// The content starts after the spaces behind the marker, unless there are five or more: then the
|
|
361
|
+
// item starts with indented code one column after the marker.
|
|
362
|
+
const gap = rest === '' ? 1 : columns(spacing, indent + width);
|
|
363
|
+
const column = indent + width + (gap > CODE_INDENT ? 1 : gap);
|
|
364
|
+
return { kind: bullet ?? delimiter!, first: bullet !== undefined || Number(number) === 1, column, rest };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* A list item's line with its marker as spaces, so a fence on that line is seen where the item's content starts. */
|
|
368
|
+
function itemContent(content: string): string {
|
|
369
|
+
const marker = itemMarker(content);
|
|
370
|
+
return marker === null ? content : ' '.repeat(marker.column) + marker.rest;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* The columns of the indentation of a line, which starts at column `from`; a tab reaches to the next stop of four. */
|
|
374
|
+
function columns(line: string, from = 0): number {
|
|
375
|
+
let column = from;
|
|
376
|
+
for (const character of line) {
|
|
377
|
+
if (character === '\t') {
|
|
378
|
+
column += TAB_STOP - (column % TAB_STOP);
|
|
379
|
+
} else if (character === ' ') {
|
|
380
|
+
column += 1;
|
|
381
|
+
} else {
|
|
382
|
+
break;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return column - from;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/*
|
|
389
|
+
* A line of a fence less up to `indent` columns of indentation. A tab reaches to the next stop of
|
|
390
|
+
* four, and what of it lies past `indent` stays as spaces, as markdown reads it.
|
|
391
|
+
*/
|
|
392
|
+
function outdent(line: string, indent: number): string {
|
|
393
|
+
let column = 0;
|
|
394
|
+
let index = 0;
|
|
395
|
+
while (column < indent && index < line.length) {
|
|
396
|
+
const character = line[index];
|
|
397
|
+
if (character === '\t') {
|
|
398
|
+
const stop = column + TAB_STOP - (column % TAB_STOP);
|
|
399
|
+
if (stop > indent) {
|
|
400
|
+
return ' '.repeat(stop - indent) + line.slice(index + 1);
|
|
401
|
+
}
|
|
402
|
+
column = stop;
|
|
403
|
+
} else if (character === ' ') {
|
|
404
|
+
column += 1;
|
|
405
|
+
} else {
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
index += 1;
|
|
409
|
+
}
|
|
410
|
+
return line.slice(index);
|
|
411
|
+
}
|