@elizaos/plugin-task-coordinator 2.0.3-beta.2 → 2.0.3-beta.4

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 (176) hide show
  1. package/assets/hero.png +0 -0
  2. package/dist/AgentTabsSection.d.ts +16 -0
  3. package/dist/AgentTabsSection.d.ts.map +1 -0
  4. package/dist/AgentTabsSection.js +169 -0
  5. package/dist/AgentTabsSection.js.map +1 -0
  6. package/dist/CodingAgentControlChip.d.ts +2 -0
  7. package/dist/CodingAgentControlChip.d.ts.map +1 -0
  8. package/dist/CodingAgentControlChip.js +73 -0
  9. package/dist/CodingAgentControlChip.js.map +1 -0
  10. package/dist/CodingAgentSettingsSection.d.ts +2 -0
  11. package/dist/CodingAgentSettingsSection.d.ts.map +1 -0
  12. package/dist/CodingAgentSettingsSection.js +379 -0
  13. package/dist/CodingAgentSettingsSection.js.map +1 -0
  14. package/dist/CodingAgentTasksPanel.d.ts +4 -0
  15. package/dist/CodingAgentTasksPanel.d.ts.map +1 -0
  16. package/dist/CodingAgentTasksPanel.interact.d.ts +2 -0
  17. package/dist/CodingAgentTasksPanel.interact.d.ts.map +1 -0
  18. package/dist/CodingAgentTasksPanel.interact.js +46 -0
  19. package/dist/CodingAgentTasksPanel.interact.js.map +1 -0
  20. package/dist/CodingAgentTasksPanel.js +740 -0
  21. package/dist/CodingAgentTasksPanel.js.map +1 -0
  22. package/dist/GitHubConnectionCard.d.ts +2 -0
  23. package/dist/GitHubConnectionCard.d.ts.map +1 -0
  24. package/dist/GitHubConnectionCard.js +172 -0
  25. package/dist/GitHubConnectionCard.js.map +1 -0
  26. package/dist/GlobalPrefsSection.d.ts +10 -0
  27. package/dist/GlobalPrefsSection.d.ts.map +1 -0
  28. package/dist/GlobalPrefsSection.js +166 -0
  29. package/dist/GlobalPrefsSection.js.map +1 -0
  30. package/dist/LlmProviderSection.d.ts +10 -0
  31. package/dist/LlmProviderSection.d.ts.map +1 -0
  32. package/dist/LlmProviderSection.js +161 -0
  33. package/dist/LlmProviderSection.js.map +1 -0
  34. package/dist/ModelConfigSection.d.ts +15 -0
  35. package/dist/ModelConfigSection.d.ts.map +1 -0
  36. package/dist/ModelConfigSection.js +86 -0
  37. package/dist/ModelConfigSection.js.map +1 -0
  38. package/dist/OrchestratorView.d.ts +20 -0
  39. package/dist/OrchestratorView.d.ts.map +1 -0
  40. package/dist/OrchestratorView.js +231 -0
  41. package/dist/OrchestratorView.js.map +1 -0
  42. package/dist/OrchestratorWorkbench.d.ts +32 -0
  43. package/dist/OrchestratorWorkbench.d.ts.map +1 -0
  44. package/dist/OrchestratorWorkbench.js +3200 -0
  45. package/dist/OrchestratorWorkbench.js.map +1 -0
  46. package/dist/PtyConsoleBase.d.ts +9 -0
  47. package/dist/PtyConsoleBase.d.ts.map +1 -0
  48. package/dist/PtyConsoleBase.js +174 -0
  49. package/dist/PtyConsoleBase.js.map +1 -0
  50. package/dist/PtyConsoleDrawer.d.ts +10 -0
  51. package/dist/PtyConsoleDrawer.d.ts.map +1 -0
  52. package/dist/PtyConsoleDrawer.js +77 -0
  53. package/dist/PtyConsoleDrawer.js.map +1 -0
  54. package/dist/PtyConsoleSidePanel.d.ts +8 -0
  55. package/dist/PtyConsoleSidePanel.d.ts.map +1 -0
  56. package/dist/PtyConsoleSidePanel.js +9 -0
  57. package/dist/PtyConsoleSidePanel.js.map +1 -0
  58. package/dist/PtyTerminalPane.d.ts +10 -0
  59. package/dist/PtyTerminalPane.d.ts.map +1 -0
  60. package/dist/PtyTerminalPane.js +147 -0
  61. package/dist/PtyTerminalPane.js.map +1 -0
  62. package/dist/TaskCardList.d.ts +76 -0
  63. package/dist/TaskCardList.d.ts.map +1 -0
  64. package/dist/TaskCardList.js +327 -0
  65. package/dist/TaskCardList.js.map +1 -0
  66. package/dist/TaskCoordinatorView.d.ts +20 -0
  67. package/dist/TaskCoordinatorView.d.ts.map +1 -0
  68. package/dist/TaskCoordinatorView.js +146 -0
  69. package/dist/TaskCoordinatorView.js.map +1 -0
  70. package/dist/__e2e__/dashboard-fixture.d.ts +9 -0
  71. package/dist/__e2e__/dashboard-fixture.d.ts.map +1 -0
  72. package/dist/__e2e__/dashboard-fixture.js +123 -0
  73. package/dist/__e2e__/dashboard-fixture.js.map +1 -0
  74. package/dist/api/coding-agents-auth-sanitize.d.ts +23 -0
  75. package/dist/api/coding-agents-auth-sanitize.d.ts.map +1 -0
  76. package/dist/api/coding-agents-auth-sanitize.js +22 -0
  77. package/dist/api/coding-agents-auth-sanitize.js.map +1 -0
  78. package/dist/api/coding-agents-preflight-normalize.d.ts +29 -0
  79. package/dist/api/coding-agents-preflight-normalize.d.ts.map +1 -0
  80. package/dist/api/coding-agents-preflight-normalize.js +20 -0
  81. package/dist/api/coding-agents-preflight-normalize.js.map +1 -0
  82. package/dist/coding-agent-settings-shared.d.ts +42 -0
  83. package/dist/coding-agent-settings-shared.d.ts.map +1 -0
  84. package/dist/coding-agent-settings-shared.js +121 -0
  85. package/dist/coding-agent-settings-shared.js.map +1 -0
  86. package/dist/components/OrchestratorSpatialView.d.ts +56 -0
  87. package/dist/components/OrchestratorSpatialView.d.ts.map +1 -0
  88. package/dist/components/OrchestratorSpatialView.js +501 -0
  89. package/dist/components/OrchestratorSpatialView.js.map +1 -0
  90. package/dist/components/TaskCoordinatorSpatialView.d.ts +59 -0
  91. package/dist/components/TaskCoordinatorSpatialView.d.ts.map +1 -0
  92. package/dist/components/TaskCoordinatorSpatialView.js +294 -0
  93. package/dist/components/TaskCoordinatorSpatialView.js.map +1 -0
  94. package/dist/index.d.ts +5 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +286 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/orchestrator-capabilities.d.ts +3 -0
  99. package/dist/orchestrator-capabilities.d.ts.map +1 -0
  100. package/dist/orchestrator-capabilities.js +136 -0
  101. package/dist/orchestrator-capabilities.js.map +1 -0
  102. package/dist/orchestrator-command.d.ts +39 -0
  103. package/dist/orchestrator-command.d.ts.map +1 -0
  104. package/dist/orchestrator-command.js +52 -0
  105. package/dist/orchestrator-command.js.map +1 -0
  106. package/dist/orchestrator-diff.d.ts +19 -0
  107. package/dist/orchestrator-diff.d.ts.map +1 -0
  108. package/dist/orchestrator-diff.helpers.d.ts +18 -0
  109. package/dist/orchestrator-diff.helpers.d.ts.map +1 -0
  110. package/dist/orchestrator-diff.helpers.js +76 -0
  111. package/dist/orchestrator-diff.helpers.js.map +1 -0
  112. package/dist/orchestrator-diff.js +119 -0
  113. package/dist/orchestrator-diff.js.map +1 -0
  114. package/dist/orchestrator-markdown.d.ts +5 -0
  115. package/dist/orchestrator-markdown.d.ts.map +1 -0
  116. package/dist/orchestrator-markdown.helpers.d.ts +2 -0
  117. package/dist/orchestrator-markdown.helpers.d.ts.map +1 -0
  118. package/dist/orchestrator-markdown.helpers.js +21 -0
  119. package/dist/orchestrator-markdown.helpers.js.map +1 -0
  120. package/dist/orchestrator-markdown.js +199 -0
  121. package/dist/orchestrator-markdown.js.map +1 -0
  122. package/dist/orchestrator-params.d.ts +8 -0
  123. package/dist/orchestrator-params.d.ts.map +1 -0
  124. package/dist/orchestrator-params.js +27 -0
  125. package/dist/orchestrator-params.js.map +1 -0
  126. package/dist/orchestrator-plan.d.ts +5 -0
  127. package/dist/orchestrator-plan.d.ts.map +1 -0
  128. package/dist/orchestrator-plan.js +95 -0
  129. package/dist/orchestrator-plan.js.map +1 -0
  130. package/dist/orchestrator-reasoning.d.ts +21 -0
  131. package/dist/orchestrator-reasoning.d.ts.map +1 -0
  132. package/dist/orchestrator-reasoning.js +105 -0
  133. package/dist/orchestrator-reasoning.js.map +1 -0
  134. package/dist/orchestrator-stream.d.ts +15 -0
  135. package/dist/orchestrator-stream.d.ts.map +1 -0
  136. package/dist/orchestrator-stream.helpers.d.ts +89 -0
  137. package/dist/orchestrator-stream.helpers.d.ts.map +1 -0
  138. package/dist/orchestrator-stream.helpers.js +361 -0
  139. package/dist/orchestrator-stream.helpers.js.map +1 -0
  140. package/dist/orchestrator-stream.js +307 -0
  141. package/dist/orchestrator-stream.js.map +1 -0
  142. package/dist/pty-status-dots.d.ts +2 -0
  143. package/dist/pty-status-dots.d.ts.map +1 -0
  144. package/dist/pty-status-dots.js +6 -0
  145. package/dist/pty-status-dots.js.map +1 -0
  146. package/dist/register-slots.d.ts +20 -0
  147. package/dist/register-slots.d.ts.map +1 -0
  148. package/dist/register-slots.js +50 -0
  149. package/dist/register-slots.js.map +1 -0
  150. package/dist/register-terminal-view.d.ts +21 -0
  151. package/dist/register-terminal-view.d.ts.map +1 -0
  152. package/dist/register-terminal-view.js +46 -0
  153. package/dist/register-terminal-view.js.map +1 -0
  154. package/dist/register.d.ts +2 -0
  155. package/dist/register.d.ts.map +1 -0
  156. package/dist/register.js +23 -0
  157. package/dist/register.js.map +1 -0
  158. package/dist/session-hydration.d.ts +2 -0
  159. package/dist/session-hydration.d.ts.map +1 -0
  160. package/dist/session-hydration.js +9 -0
  161. package/dist/session-hydration.js.map +1 -0
  162. package/dist/task-coordinator-view-bundle.d.ts +4 -0
  163. package/dist/task-coordinator-view-bundle.d.ts.map +1 -0
  164. package/dist/task-coordinator-view-bundle.js +9 -0
  165. package/dist/task-coordinator-view-bundle.js.map +1 -0
  166. package/dist/ui.d.ts +2 -0
  167. package/dist/ui.d.ts.map +1 -0
  168. package/dist/ui.js +13 -0
  169. package/dist/ui.js.map +1 -0
  170. package/dist/view-format.d.ts +25 -0
  171. package/dist/view-format.d.ts.map +1 -0
  172. package/dist/view-format.js +64 -0
  173. package/dist/view-format.js.map +1 -0
  174. package/dist/views/bundle.js +1383 -0
  175. package/dist/views/bundle.js.map +1 -0
  176. package/package.json +7 -6
@@ -0,0 +1,199 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Check, Copy } from "lucide-react";
3
+ import { marked } from "marked";
4
+ import { useEffect, useRef, useState } from "react";
5
+ import { sanitizeMarkdownUrl } from "./orchestrator-markdown.helpers";
6
+ function alignStyle(align) {
7
+ return align ? { textAlign: align } : void 0;
8
+ }
9
+ function renderChildren(tokens, key) {
10
+ if (!tokens || tokens.length === 0) return null;
11
+ return tokens.map((token, index) => renderToken(token, `${key}.${index}`));
12
+ }
13
+ function renderToken(token, key) {
14
+ switch (token.type) {
15
+ case "space":
16
+ case "def":
17
+ return null;
18
+ case "paragraph":
19
+ return /* @__PURE__ */ jsx("p", { className: "my-1 leading-relaxed first:mt-0 last:mb-0", children: renderChildren(token.tokens, key) }, key);
20
+ case "heading": {
21
+ const depth = Math.min(Math.max(token.depth, 1), 4);
22
+ const Tag = `h${depth}`;
23
+ return /* @__PURE__ */ jsx(Tag, { className: "mt-2 mb-1 font-semibold text-txt first:mt-0", children: renderChildren(token.tokens, key) }, key);
24
+ }
25
+ case "code":
26
+ return /* @__PURE__ */ jsx(CodeBlock, { code: token.text, lang: token.lang }, key);
27
+ case "blockquote":
28
+ return /* @__PURE__ */ jsx(
29
+ "blockquote",
30
+ {
31
+ className: "my-1 border-l-2 border-border pl-3 text-muted-strong",
32
+ children: renderChildren(token.tokens, key)
33
+ },
34
+ key
35
+ );
36
+ case "list": {
37
+ const items = token.items.map((item, index) => {
38
+ const itemKey = `${key}.${index}`;
39
+ return /* @__PURE__ */ jsxs("li", { className: "my-0.5 marker:text-muted", children: [
40
+ item.task ? /* @__PURE__ */ jsx(
41
+ "input",
42
+ {
43
+ type: "checkbox",
44
+ checked: Boolean(item.checked),
45
+ readOnly: true,
46
+ "aria-hidden": true,
47
+ className: "mr-1.5 align-middle accent-accent"
48
+ }
49
+ ) : null,
50
+ renderChildren(item.tokens, itemKey)
51
+ ] }, itemKey);
52
+ });
53
+ return token.ordered ? /* @__PURE__ */ jsx(
54
+ "ol",
55
+ {
56
+ start: typeof token.start === "number" ? token.start : void 0,
57
+ className: "my-1 list-decimal space-y-0.5 pl-5",
58
+ children: items
59
+ },
60
+ key
61
+ ) : /* @__PURE__ */ jsx("ul", { className: "my-1 list-disc space-y-0.5 pl-5", children: items }, key);
62
+ }
63
+ case "table":
64
+ return /* @__PURE__ */ jsx("div", { className: "my-1.5 overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-2xs", children: [
65
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: token.header.map((cell, index) => {
66
+ const cellKey = `${key}.h${index}`;
67
+ return /* @__PURE__ */ jsx(
68
+ "th",
69
+ {
70
+ style: alignStyle(cell.align),
71
+ className: "border border-border/60 bg-bg/40 px-2 py-1 text-left font-semibold text-txt",
72
+ children: renderChildren(cell.tokens, cellKey)
73
+ },
74
+ cellKey
75
+ );
76
+ }) }) }),
77
+ /* @__PURE__ */ jsx("tbody", { children: token.rows.map((row, rowIndex) => {
78
+ const rowKey = `${key}.r${rowIndex}`;
79
+ return /* @__PURE__ */ jsx("tr", { children: row.map((cell, cellIndex) => {
80
+ const cellKey = `${rowKey}c${cellIndex}`;
81
+ return /* @__PURE__ */ jsx(
82
+ "td",
83
+ {
84
+ style: alignStyle(cell.align),
85
+ className: "border border-border/50 px-2 py-1 align-top",
86
+ children: renderChildren(cell.tokens, cellKey)
87
+ },
88
+ cellKey
89
+ );
90
+ }) }, rowKey);
91
+ }) })
92
+ ] }) }, key);
93
+ case "hr":
94
+ return /* @__PURE__ */ jsx("hr", { className: "my-2 border-border/50" }, key);
95
+ case "strong":
96
+ return /* @__PURE__ */ jsx("strong", { className: "font-semibold text-txt", children: renderChildren(token.tokens, key) }, key);
97
+ case "em":
98
+ return /* @__PURE__ */ jsx("em", { className: "italic", children: renderChildren(token.tokens, key) }, key);
99
+ case "del":
100
+ return /* @__PURE__ */ jsx("del", { className: "line-through opacity-80", children: renderChildren(token.tokens, key) }, key);
101
+ case "codespan":
102
+ return /* @__PURE__ */ jsx(
103
+ "code",
104
+ {
105
+ className: "break-words rounded-sm bg-bg/70 px-1 py-px font-mono text-[0.95em] text-txt-strong",
106
+ children: token.text
107
+ },
108
+ key
109
+ );
110
+ case "link": {
111
+ const href = sanitizeMarkdownUrl(token.href);
112
+ const isExternal = href !== null && /^https?:/i.test(href);
113
+ return /* @__PURE__ */ jsx(
114
+ "a",
115
+ {
116
+ href: href ?? void 0,
117
+ title: token.title ?? void 0,
118
+ target: isExternal ? "_blank" : void 0,
119
+ rel: isExternal ? "noreferrer" : void 0,
120
+ className: "text-txt-strong underline underline-offset-2 transition-colors hover:text-accent",
121
+ children: renderChildren(token.tokens, key)
122
+ },
123
+ key
124
+ );
125
+ }
126
+ case "image": {
127
+ const src = sanitizeMarkdownUrl(token.href);
128
+ if (!src) return token.text;
129
+ return /* @__PURE__ */ jsx(
130
+ "img",
131
+ {
132
+ src,
133
+ alt: token.text,
134
+ title: token.title ?? void 0,
135
+ className: "my-1 max-w-full rounded-sm border border-border/50"
136
+ },
137
+ key
138
+ );
139
+ }
140
+ case "br":
141
+ return /* @__PURE__ */ jsx("br", {}, key);
142
+ case "escape":
143
+ return token.text;
144
+ case "text":
145
+ return token.tokens && token.tokens.length > 0 ? renderChildren(token.tokens, key) : token.text;
146
+ default:
147
+ return "raw" in token ? token.raw : null;
148
+ }
149
+ }
150
+ function CodeBlock({ code, lang }) {
151
+ const [copied, setCopied] = useState(false);
152
+ const revertTimer = useRef(null);
153
+ useEffect(
154
+ () => () => {
155
+ if (revertTimer.current) clearTimeout(revertTimer.current);
156
+ },
157
+ []
158
+ );
159
+ const copy = () => {
160
+ if (typeof navigator === "undefined" || !navigator.clipboard?.writeText) {
161
+ return;
162
+ }
163
+ navigator.clipboard.writeText(code).then(
164
+ () => {
165
+ setCopied(true);
166
+ if (revertTimer.current) clearTimeout(revertTimer.current);
167
+ revertTimer.current = setTimeout(() => setCopied(false), 1200);
168
+ },
169
+ () => void 0
170
+ );
171
+ };
172
+ return /* @__PURE__ */ jsxs("div", { className: "group/code relative my-1 overflow-hidden rounded-sm border border-border/50 bg-bg/80", children: [
173
+ lang ? /* @__PURE__ */ jsx("div", { className: "border-b border-border/40 px-2.5 py-0.5 font-mono text-3xs uppercase tracking-wide text-muted", children: lang }) : null,
174
+ /* @__PURE__ */ jsx(
175
+ "button",
176
+ {
177
+ type: "button",
178
+ onClick: copy,
179
+ "aria-label": copied ? "Copied" : "Copy code",
180
+ className: `absolute right-1 top-1 z-10 rounded p-1 text-muted opacity-0 transition-[color,opacity] hover:bg-bg-hover/60 hover:text-txt focus-visible:opacity-100 group-hover/code:opacity-100 ${copied ? "text-ok opacity-100" : ""}`,
181
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5", "aria-hidden": true }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5", "aria-hidden": true })
182
+ }
183
+ ),
184
+ /* @__PURE__ */ jsx("pre", { className: "max-h-72 overflow-auto px-2.5 py-1.5 font-mono text-2xs leading-relaxed text-txt", children: /* @__PURE__ */ jsx("code", { className: "whitespace-pre-wrap break-words", children: code }) })
185
+ ] });
186
+ }
187
+ function MarkdownText({ text }) {
188
+ let tokens;
189
+ try {
190
+ tokens = marked.lexer(text);
191
+ } catch {
192
+ return /* @__PURE__ */ jsx("div", { className: "whitespace-pre-wrap break-words text-xs text-txt", children: text });
193
+ }
194
+ return /* @__PURE__ */ jsx("div", { className: "break-words text-xs text-txt", children: tokens.map((token, index) => renderToken(token, `t${index}`)) });
195
+ }
196
+ export {
197
+ MarkdownText
198
+ };
199
+ //# sourceMappingURL=orchestrator-markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/orchestrator-markdown.tsx"],"sourcesContent":["import { Check, Copy } from \"lucide-react\";\nimport { marked, type Token, type Tokens, type TokensList } from \"marked\";\nimport { type ReactNode, useEffect, useRef, useState } from \"react\";\nimport { sanitizeMarkdownUrl } from \"./orchestrator-markdown.helpers\";\n\n// The coding agent writes markdown prose. We parse it with `marked` — a real\n// lexer, not a hand-rolled regex — then render its token AST directly to React\n// elements. Rendering the AST (rather than marked's HTML string) means nothing\n// is ever injected via dangerouslySetInnerHTML: raw HTML that appears in the\n// stream is shown as escaped text, never executed, so there's no XSS surface\n// and no sanitizer dependency. marked is pure ESM with zero dependencies, so it\n// also sidesteps the rolldown dev-optimizer's CommonJS-interop hang that\n// react-markdown's `style-to-js` dep triggers in this app.\n\nfunction alignStyle(align: Tokens.TableCell[\"align\"]) {\n return align ? { textAlign: align } : undefined;\n}\n\nfunction renderChildren(tokens: Token[] | undefined, key: string): ReactNode {\n if (!tokens || tokens.length === 0) return null;\n return tokens.map((token, index) => renderToken(token, `${key}.${index}`));\n}\n\nfunction renderToken(token: Token, key: string): ReactNode {\n switch (token.type) {\n case \"space\":\n case \"def\":\n return null;\n case \"paragraph\":\n return (\n <p key={key} className=\"my-1 leading-relaxed first:mt-0 last:mb-0\">\n {renderChildren(token.tokens, key)}\n </p>\n );\n case \"heading\": {\n const depth = Math.min(Math.max(token.depth, 1), 4);\n const Tag = `h${depth}` as \"h1\" | \"h2\" | \"h3\" | \"h4\";\n return (\n <Tag key={key} className=\"mt-2 mb-1 font-semibold text-txt first:mt-0\">\n {renderChildren(token.tokens, key)}\n </Tag>\n );\n }\n case \"code\":\n return <CodeBlock key={key} code={token.text} lang={token.lang} />;\n case \"blockquote\":\n return (\n <blockquote\n key={key}\n className=\"my-1 border-l-2 border-border pl-3 text-muted-strong\"\n >\n {renderChildren(token.tokens, key)}\n </blockquote>\n );\n case \"list\": {\n const items = token.items.map((item, index) => {\n // Composite path key (parent path + position): stable across this\n // immutable, fully-recomputed AST render, and unique among siblings.\n const itemKey = `${key}.${index}`;\n return (\n <li key={itemKey} className=\"my-0.5 marker:text-muted\">\n {item.task ? (\n <input\n type=\"checkbox\"\n checked={Boolean(item.checked)}\n readOnly\n aria-hidden\n className=\"mr-1.5 align-middle accent-accent\"\n />\n ) : null}\n {renderChildren(item.tokens, itemKey)}\n </li>\n );\n });\n return token.ordered ? (\n <ol\n key={key}\n start={typeof token.start === \"number\" ? token.start : undefined}\n className=\"my-1 list-decimal space-y-0.5 pl-5\"\n >\n {items}\n </ol>\n ) : (\n <ul key={key} className=\"my-1 list-disc space-y-0.5 pl-5\">\n {items}\n </ul>\n );\n }\n case \"table\":\n return (\n <div key={key} className=\"my-1.5 overflow-x-auto\">\n <table className=\"w-full border-collapse text-2xs\">\n <thead>\n <tr>\n {token.header.map((cell, index) => {\n const cellKey = `${key}.h${index}`;\n return (\n <th\n key={cellKey}\n style={alignStyle(cell.align)}\n className=\"border border-border/60 bg-bg/40 px-2 py-1 text-left font-semibold text-txt\"\n >\n {renderChildren(cell.tokens, cellKey)}\n </th>\n );\n })}\n </tr>\n </thead>\n <tbody>\n {token.rows.map((row, rowIndex) => {\n const rowKey = `${key}.r${rowIndex}`;\n return (\n <tr key={rowKey}>\n {row.map((cell, cellIndex) => {\n const cellKey = `${rowKey}c${cellIndex}`;\n return (\n <td\n key={cellKey}\n style={alignStyle(cell.align)}\n className=\"border border-border/50 px-2 py-1 align-top\"\n >\n {renderChildren(cell.tokens, cellKey)}\n </td>\n );\n })}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n case \"hr\":\n return <hr key={key} className=\"my-2 border-border/50\" />;\n case \"strong\":\n return (\n <strong key={key} className=\"font-semibold text-txt\">\n {renderChildren(token.tokens, key)}\n </strong>\n );\n case \"em\":\n return (\n <em key={key} className=\"italic\">\n {renderChildren(token.tokens, key)}\n </em>\n );\n case \"del\":\n return (\n <del key={key} className=\"line-through opacity-80\">\n {renderChildren(token.tokens, key)}\n </del>\n );\n case \"codespan\":\n return (\n <code\n key={key}\n className=\"break-words rounded-sm bg-bg/70 px-1 py-px font-mono text-[0.95em] text-txt-strong\"\n >\n {token.text}\n </code>\n );\n case \"link\": {\n const href = sanitizeMarkdownUrl(token.href);\n // Only open external (http/https/mailto) links in a new tab.\n // Relative paths should navigate in the same context.\n const isExternal = href !== null && /^https?:/i.test(href);\n return (\n <a\n key={key}\n href={href ?? undefined}\n title={token.title ?? undefined}\n target={isExternal ? \"_blank\" : undefined}\n rel={isExternal ? \"noreferrer\" : undefined}\n className=\"text-txt-strong underline underline-offset-2 transition-colors hover:text-accent\"\n >\n {renderChildren(token.tokens, key)}\n </a>\n );\n }\n case \"image\": {\n const src = sanitizeMarkdownUrl(token.href);\n if (!src) return token.text;\n return (\n <img\n key={key}\n src={src}\n alt={token.text}\n title={token.title ?? undefined}\n className=\"my-1 max-w-full rounded-sm border border-border/50\"\n />\n );\n }\n case \"br\":\n return <br key={key} />;\n case \"escape\":\n return token.text;\n case \"text\":\n // A block-level text token (e.g. loose-list content) carries inline\n // tokens; an inline text leaf is just its string.\n return token.tokens && token.tokens.length > 0\n ? renderChildren(token.tokens, key)\n : token.text;\n default:\n // `html` and any other raw tokens are rendered as escaped text — never\n // injected as markup — so stray tags in the stream can't execute.\n return \"raw\" in token ? token.raw : null;\n }\n}\n\nfunction CodeBlock({ code, lang }: { code: string; lang?: string }): ReactNode {\n const [copied, setCopied] = useState(false);\n // Hold the revert timer so we can cancel it on unmount; firing setCopied\n // after unmount (within the 1200ms window) would be a stale-state update.\n const revertTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (revertTimer.current) clearTimeout(revertTimer.current);\n },\n [],\n );\n\n const copy = () => {\n // Guard for non-secure-context / older webviews where clipboard is absent.\n if (typeof navigator === \"undefined\" || !navigator.clipboard?.writeText) {\n return;\n }\n navigator.clipboard.writeText(code).then(\n () => {\n setCopied(true);\n // Brief confirmation, then revert to the resting copy icon.\n if (revertTimer.current) clearTimeout(revertTimer.current);\n revertTimer.current = setTimeout(() => setCopied(false), 1200);\n },\n () => undefined,\n );\n };\n\n return (\n <div className=\"group/code relative my-1 overflow-hidden rounded-sm border border-border/50 bg-bg/80\">\n {lang ? (\n <div className=\"border-b border-border/40 px-2.5 py-0.5 font-mono text-3xs uppercase tracking-wide text-muted\">\n {lang}\n </div>\n ) : null}\n <button\n type=\"button\"\n onClick={copy}\n aria-label={copied ? \"Copied\" : \"Copy code\"}\n // Unobtrusive: faded until the block is hovered/focused, fully shown\n // once copied. Green only as the success affordance.\n className={`absolute right-1 top-1 z-10 rounded p-1 text-muted opacity-0 transition-[color,opacity] hover:bg-bg-hover/60 hover:text-txt focus-visible:opacity-100 group-hover/code:opacity-100 ${\n copied ? \"text-ok opacity-100\" : \"\"\n }`}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5\" aria-hidden />\n ) : (\n <Copy className=\"h-3.5 w-3.5\" aria-hidden />\n )}\n </button>\n <pre className=\"max-h-72 overflow-auto px-2.5 py-1.5 font-mono text-2xs leading-relaxed text-txt\">\n <code className=\"whitespace-pre-wrap break-words\">{code}</code>\n </pre>\n </div>\n );\n}\n\nexport function MarkdownText({ text }: { text: string }): ReactNode {\n // marked.lexer runs synchronously here. It can throw — a stack overflow on\n // pathologically nested input, or a TypeError on a non-string. A throw in\n // this render would unmount the whole conversation, so degrade to plain text.\n let tokens: TokensList;\n try {\n tokens = marked.lexer(text);\n } catch {\n return (\n <div className=\"whitespace-pre-wrap break-words text-xs text-txt\">\n {text}\n </div>\n );\n }\n return (\n <div className=\"break-words text-xs text-txt\">\n {tokens.map((token, index) => renderToken(token, `t${index}`))}\n </div>\n );\n}\n"],"mappings":"AA8BQ,cA8BE,YA9BF;AA9BR,SAAS,OAAO,YAAY;AAC5B,SAAS,cAAwD;AACjE,SAAyB,WAAW,QAAQ,gBAAgB;AAC5D,SAAS,2BAA2B;AAWpC,SAAS,WAAW,OAAkC;AACpD,SAAO,QAAQ,EAAE,WAAW,MAAM,IAAI;AACxC;AAEA,SAAS,eAAe,QAA6B,KAAwB;AAC3E,MAAI,CAAC,UAAU,OAAO,WAAW,EAAG,QAAO;AAC3C,SAAO,OAAO,IAAI,CAAC,OAAO,UAAU,YAAY,OAAO,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;AAC3E;AAEA,SAAS,YAAY,OAAc,KAAwB;AACzD,UAAQ,MAAM,MAAM;AAAA,IAClB,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aACE,oBAAC,OAAY,WAAU,6CACpB,yBAAe,MAAM,QAAQ,GAAG,KAD3B,GAER;AAAA,IAEJ,KAAK,WAAW;AACd,YAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,MAAM,OAAO,CAAC,GAAG,CAAC;AAClD,YAAM,MAAM,IAAI,KAAK;AACrB,aACE,oBAAC,OAAc,WAAU,+CACtB,yBAAe,MAAM,QAAQ,GAAG,KADzB,GAEV;AAAA,IAEJ;AAAA,IACA,KAAK;AACH,aAAO,oBAAC,aAAoB,MAAM,MAAM,MAAM,MAAM,MAAM,QAAnC,GAAyC;AAAA,IAClE,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UAET,yBAAe,MAAM,QAAQ,GAAG;AAAA;AAAA,QAH5B;AAAA,MAIP;AAAA,IAEJ,KAAK,QAAQ;AACX,YAAM,QAAQ,MAAM,MAAM,IAAI,CAAC,MAAM,UAAU;AAG7C,cAAM,UAAU,GAAG,GAAG,IAAI,KAAK;AAC/B,eACE,qBAAC,QAAiB,WAAU,4BACzB;AAAA,eAAK,OACJ;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,QAAQ,KAAK,OAAO;AAAA,cAC7B,UAAQ;AAAA,cACR,eAAW;AAAA,cACX,WAAU;AAAA;AAAA,UACZ,IACE;AAAA,UACH,eAAe,KAAK,QAAQ,OAAO;AAAA,aAV7B,OAWT;AAAA,MAEJ,CAAC;AACD,aAAO,MAAM,UACX;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAAA,UACvD,WAAU;AAAA,UAET;AAAA;AAAA,QAJI;AAAA,MAKP,IAEA,oBAAC,QAAa,WAAU,mCACrB,mBADM,GAET;AAAA,IAEJ;AAAA,IACA,KAAK;AACH,aACE,oBAAC,SAAc,WAAU,0BACvB,+BAAC,WAAM,WAAU,mCACf;AAAA,4BAAC,WACC,8BAAC,QACE,gBAAM,OAAO,IAAI,CAAC,MAAM,UAAU;AACjC,gBAAM,UAAU,GAAG,GAAG,KAAK,KAAK;AAChC,iBACE;AAAA,YAAC;AAAA;AAAA,cAEC,OAAO,WAAW,KAAK,KAAK;AAAA,cAC5B,WAAU;AAAA,cAET,yBAAe,KAAK,QAAQ,OAAO;AAAA;AAAA,YAJ/B;AAAA,UAKP;AAAA,QAEJ,CAAC,GACH,GACF;AAAA,QACA,oBAAC,WACE,gBAAM,KAAK,IAAI,CAAC,KAAK,aAAa;AACjC,gBAAM,SAAS,GAAG,GAAG,KAAK,QAAQ;AAClC,iBACE,oBAAC,QACE,cAAI,IAAI,CAAC,MAAM,cAAc;AAC5B,kBAAM,UAAU,GAAG,MAAM,IAAI,SAAS;AACtC,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,OAAO,WAAW,KAAK,KAAK;AAAA,gBAC5B,WAAU;AAAA,gBAET,yBAAe,KAAK,QAAQ,OAAO;AAAA;AAAA,cAJ/B;AAAA,YAKP;AAAA,UAEJ,CAAC,KAZM,MAaT;AAAA,QAEJ,CAAC,GACH;AAAA,SACF,KAvCQ,GAwCV;AAAA,IAEJ,KAAK;AACH,aAAO,oBAAC,QAAa,WAAU,2BAAf,GAAuC;AAAA,IACzD,KAAK;AACH,aACE,oBAAC,YAAiB,WAAU,0BACzB,yBAAe,MAAM,QAAQ,GAAG,KADtB,GAEb;AAAA,IAEJ,KAAK;AACH,aACE,oBAAC,QAAa,WAAU,UACrB,yBAAe,MAAM,QAAQ,GAAG,KAD1B,GAET;AAAA,IAEJ,KAAK;AACH,aACE,oBAAC,SAAc,WAAU,2BACtB,yBAAe,MAAM,QAAQ,GAAG,KADzB,GAEV;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,WAAU;AAAA,UAET,gBAAM;AAAA;AAAA,QAHF;AAAA,MAIP;AAAA,IAEJ,KAAK,QAAQ;AACX,YAAM,OAAO,oBAAoB,MAAM,IAAI;AAG3C,YAAM,aAAa,SAAS,QAAQ,YAAY,KAAK,IAAI;AACzD,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,MAAM,QAAQ;AAAA,UACd,OAAO,MAAM,SAAS;AAAA,UACtB,QAAQ,aAAa,WAAW;AAAA,UAChC,KAAK,aAAa,eAAe;AAAA,UACjC,WAAU;AAAA,UAET,yBAAe,MAAM,QAAQ,GAAG;AAAA;AAAA,QAP5B;AAAA,MAQP;AAAA,IAEJ;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,MAAM,oBAAoB,MAAM,IAAI;AAC1C,UAAI,CAAC,IAAK,QAAO,MAAM;AACvB,aACE;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,KAAK,MAAM;AAAA,UACX,OAAO,MAAM,SAAS;AAAA,UACtB,WAAU;AAAA;AAAA,QAJL;AAAA,MAKP;AAAA,IAEJ;AAAA,IACA,KAAK;AACH,aAAO,oBAAC,UAAQ,GAAK;AAAA,IACvB,KAAK;AACH,aAAO,MAAM;AAAA,IACf,KAAK;AAGH,aAAO,MAAM,UAAU,MAAM,OAAO,SAAS,IACzC,eAAe,MAAM,QAAQ,GAAG,IAChC,MAAM;AAAA,IACZ;AAGE,aAAO,SAAS,QAAQ,MAAM,MAAM;AAAA,EACxC;AACF;AAEA,SAAS,UAAU,EAAE,MAAM,KAAK,GAA+C;AAC7E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAG1C,QAAM,cAAc,OAA6C,IAAI;AAErE;AAAA,IACE,MAAM,MAAM;AACV,UAAI,YAAY,QAAS,cAAa,YAAY,OAAO;AAAA,IAC3D;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,MAAM;AAEjB,QAAI,OAAO,cAAc,eAAe,CAAC,UAAU,WAAW,WAAW;AACvE;AAAA,IACF;AACA,cAAU,UAAU,UAAU,IAAI,EAAE;AAAA,MAClC,MAAM;AACJ,kBAAU,IAAI;AAEd,YAAI,YAAY,QAAS,cAAa,YAAY,OAAO;AACzD,oBAAY,UAAU,WAAW,MAAM,UAAU,KAAK,GAAG,IAAI;AAAA,MAC/D;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,WAAU,wFACZ;AAAA,WACC,oBAAC,SAAI,WAAU,iGACZ,gBACH,IACE;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS;AAAA,QACT,cAAY,SAAS,WAAW;AAAA,QAGhC,WAAW,sLACT,SAAS,wBAAwB,EACnC;AAAA,QAEC,mBACC,oBAAC,SAAM,WAAU,eAAc,eAAW,MAAC,IAE3C,oBAAC,QAAK,WAAU,eAAc,eAAW,MAAC;AAAA;AAAA,IAE9C;AAAA,IACA,oBAAC,SAAI,WAAU,oFACb,8BAAC,UAAK,WAAU,mCAAmC,gBAAK,GAC1D;AAAA,KACF;AAEJ;AAEO,SAAS,aAAa,EAAE,KAAK,GAAgC;AAIlE,MAAI;AACJ,MAAI;AACF,aAAS,OAAO,MAAM,IAAI;AAAA,EAC5B,QAAQ;AACN,WACE,oBAAC,SAAI,WAAU,oDACZ,gBACH;AAAA,EAEJ;AACA,SACE,oBAAC,SAAI,WAAU,gCACZ,iBAAO,IAAI,CAAC,OAAO,UAAU,YAAY,OAAO,IAAI,KAAK,EAAE,CAAC,GAC/D;AAEJ;","names":[]}
@@ -0,0 +1,8 @@
1
+ import type { CodingAgentTaskThread } from "@elizaos/ui";
2
+ export type TaskPriority = CodingAgentTaskThread["priority"];
3
+ export declare const TASK_LIST_LIMIT = 100;
4
+ export declare function paramString(value: unknown): string | undefined;
5
+ export declare function paramPriority(value: unknown): TaskPriority | undefined;
6
+ export declare function paramStringArray(value: unknown): string[] | undefined;
7
+ export declare function requireTaskId(params?: Record<string, unknown>): string;
8
+ //# sourceMappingURL=orchestrator-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-params.d.ts","sourceRoot":"","sources":["../src/orchestrator-params.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,MAAM,YAAY,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAE7D,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE9D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAOtE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAOrE;AAED,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAItE"}
@@ -0,0 +1,27 @@
1
+ const TASK_LIST_LIMIT = 100;
2
+ function paramString(value) {
3
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
4
+ }
5
+ function paramPriority(value) {
6
+ return value === "low" || value === "normal" || value === "high" || value === "urgent" ? value : void 0;
7
+ }
8
+ function paramStringArray(value) {
9
+ if (!Array.isArray(value)) return void 0;
10
+ const items = value.filter(
11
+ (entry) => typeof entry === "string" && entry.trim() !== ""
12
+ );
13
+ return items.length > 0 ? items.map((entry) => entry.trim()) : void 0;
14
+ }
15
+ function requireTaskId(params) {
16
+ const taskId = paramString(params?.taskId);
17
+ if (!taskId) throw new Error("taskId is required for this capability.");
18
+ return taskId;
19
+ }
20
+ export {
21
+ TASK_LIST_LIMIT,
22
+ paramPriority,
23
+ paramString,
24
+ paramStringArray,
25
+ requireTaskId
26
+ };
27
+ //# sourceMappingURL=orchestrator-params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/orchestrator-params.ts"],"sourcesContent":["// Shared orchestrator param coercion helpers + small constants used by both\n// OrchestratorWorkbench.tsx (the React workbench) and the capability dispatcher\n// in orchestrator-capabilities.ts. Kept out of the .tsx so that file exports\n// only React components and stays Fast-Refresh-compatible in dev.\nimport type { CodingAgentTaskThread } from \"@elizaos/ui\";\n\nexport type TaskPriority = CodingAgentTaskThread[\"priority\"];\n\nexport const TASK_LIST_LIMIT = 100;\n\nexport function paramString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nexport function paramPriority(value: unknown): TaskPriority | undefined {\n return value === \"low\" ||\n value === \"normal\" ||\n value === \"high\" ||\n value === \"urgent\"\n ? value\n : undefined;\n}\n\nexport function paramStringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const items = value.filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.trim() !== \"\",\n );\n return items.length > 0 ? items.map((entry) => entry.trim()) : undefined;\n}\n\nexport function requireTaskId(params?: Record<string, unknown>): string {\n const taskId = paramString(params?.taskId);\n if (!taskId) throw new Error(\"taskId is required for this capability.\");\n return taskId;\n}\n"],"mappings":"AAQO,MAAM,kBAAkB;AAExB,SAAS,YAAY,OAAoC;AAC9D,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI;AACpE;AAEO,SAAS,cAAc,OAA0C;AACtE,SAAO,UAAU,SACf,UAAU,YACV,UAAU,UACV,UAAU,WACR,QACA;AACN;AAEO,SAAS,iBAAiB,OAAsC;AACrE,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,QAAM,QAAQ,MAAM;AAAA,IAClB,CAAC,UACC,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM;AAAA,EAClD;AACA,SAAO,MAAM,SAAS,IAAI,MAAM,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,IAAI;AACjE;AAEO,SAAS,cAAc,QAA0C;AACtE,QAAM,SAAS,YAAY,QAAQ,MAAM;AACzC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,yCAAyC;AACtE,SAAO;AACT;","names":[]}
@@ -0,0 +1,5 @@
1
+ import { type ReactNode } from "react";
2
+ export declare function PlanDock({ plan, }: {
3
+ plan: Record<string, unknown>;
4
+ }): ReactNode;
5
+ //# sourceMappingURL=orchestrator-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-plan.d.ts","sourceRoot":"","sources":["../src/orchestrator-plan.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAC;AA+C5D,wBAAgB,QAAQ,CAAC,EACvB,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GAAG,SAAS,CAgEZ"}
@@ -0,0 +1,95 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Check, ChevronRight, Circle, Loader } from "lucide-react";
3
+ import { useEffect, useState } from "react";
4
+ function readEntries(plan) {
5
+ const raw = plan.entries;
6
+ if (!Array.isArray(raw)) return [];
7
+ const entries = [];
8
+ for (const item of raw) {
9
+ if (!item || typeof item !== "object") continue;
10
+ const record = item;
11
+ const content = typeof record.content === "string" ? record.content : "";
12
+ if (content === "") continue;
13
+ const status = record.status === "in_progress" || record.status === "completed" ? record.status : "pending";
14
+ entries.push({ content, status });
15
+ }
16
+ return entries;
17
+ }
18
+ function StatusIcon({ status }) {
19
+ if (status === "completed")
20
+ return /* @__PURE__ */ jsx(Check, { className: "h-3 w-3 shrink-0 text-ok", "aria-hidden": true });
21
+ if (status === "in_progress")
22
+ return /* @__PURE__ */ jsx(
23
+ Loader,
24
+ {
25
+ className: "h-3 w-3 shrink-0 animate-spin text-muted-strong",
26
+ "aria-hidden": true
27
+ }
28
+ );
29
+ return /* @__PURE__ */ jsx(Circle, { className: "h-3 w-3 shrink-0 text-muted/60", "aria-hidden": true });
30
+ }
31
+ function PlanDock({
32
+ plan
33
+ }) {
34
+ const entries = readEntries(plan);
35
+ const hasActive = entries.some((entry) => entry.status === "in_progress");
36
+ const [open, setOpen] = useState(hasActive);
37
+ useEffect(() => {
38
+ if (hasActive) setOpen(true);
39
+ }, [hasActive]);
40
+ if (entries.length === 0) return null;
41
+ const done = entries.filter((entry) => entry.status === "completed").length;
42
+ return /* @__PURE__ */ jsxs(
43
+ "div",
44
+ {
45
+ className: "rounded-md border border-border/50 bg-card/40",
46
+ "data-testid": "orchestrator-plan",
47
+ children: [
48
+ /* @__PURE__ */ jsxs(
49
+ "button",
50
+ {
51
+ type: "button",
52
+ onClick: () => setOpen((value) => !value),
53
+ className: "flex w-full items-center gap-2 px-2.5 py-1.5 text-left",
54
+ children: [
55
+ /* @__PURE__ */ jsx(
56
+ ChevronRight,
57
+ {
58
+ className: `h-3 w-3 shrink-0 text-muted transition-transform ${open ? "rotate-90" : ""}`
59
+ }
60
+ ),
61
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-txt", children: "Plan" }),
62
+ /* @__PURE__ */ jsx("span", { className: "flex-1" }),
63
+ /* @__PURE__ */ jsxs("span", { className: "font-mono text-2xs tabular-nums text-muted", children: [
64
+ done,
65
+ "/",
66
+ entries.length
67
+ ] })
68
+ ]
69
+ }
70
+ ),
71
+ open ? /* @__PURE__ */ jsx("ul", { className: "space-y-0.5 px-2.5 pb-2", children: entries.map((entry, index) => /* @__PURE__ */ jsxs(
72
+ "li",
73
+ {
74
+ className: "flex items-start gap-2 text-xs-tight",
75
+ children: [
76
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx(StatusIcon, { status: entry.status }) }),
77
+ /* @__PURE__ */ jsx(
78
+ "span",
79
+ {
80
+ className: entry.status === "completed" ? "text-muted line-through" : entry.status === "in_progress" ? "text-txt" : "text-muted-strong",
81
+ children: entry.content
82
+ }
83
+ )
84
+ ]
85
+ },
86
+ `${entry.content}-${index}`
87
+ )) }) : null
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ export {
93
+ PlanDock
94
+ };
95
+ //# sourceMappingURL=orchestrator-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/orchestrator-plan.tsx"],"sourcesContent":["import { Check, ChevronRight, Circle, Loader } from \"lucide-react\";\nimport { type ReactNode, useEffect, useState } from \"react\";\n\n// The orchestrator's current plan/todo list. The sub-agent (opencode) emits its\n// todo snapshot as an ACP `plan` update; the backend sanitizes it onto the\n// task's `currentPlan`, and this dock renders it the way Codex/Claude/opencode\n// surface a live checklist: a pinned, collapsible panel with per-item status\n// (pending / in-progress / done) and a progress count. Color is meaning-only —\n// green = done, neutral spinner = in-progress, muted = pending; no accent fill.\n\ninterface PlanEntry {\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\";\n}\n\n/** Narrow the loosely-typed `currentPlan` DTO (Record<string, unknown>) into the\n * typed entries this view renders, dropping anything malformed. */\nfunction readEntries(plan: Record<string, unknown>): PlanEntry[] {\n const raw = plan.entries;\n if (!Array.isArray(raw)) return [];\n const entries: PlanEntry[] = [];\n for (const item of raw) {\n if (!item || typeof item !== \"object\") continue;\n const record = item as Record<string, unknown>;\n const content = typeof record.content === \"string\" ? record.content : \"\";\n if (content === \"\") continue;\n const status =\n record.status === \"in_progress\" || record.status === \"completed\"\n ? record.status\n : \"pending\";\n entries.push({ content, status });\n }\n return entries;\n}\n\nfunction StatusIcon({ status }: { status: PlanEntry[\"status\"] }): ReactNode {\n if (status === \"completed\")\n return <Check className=\"h-3 w-3 shrink-0 text-ok\" aria-hidden />;\n if (status === \"in_progress\")\n return (\n <Loader\n className=\"h-3 w-3 shrink-0 animate-spin text-muted-strong\"\n aria-hidden\n />\n );\n return <Circle className=\"h-3 w-3 shrink-0 text-muted/60\" aria-hidden />;\n}\n\nexport function PlanDock({\n plan,\n}: {\n plan: Record<string, unknown>;\n}): ReactNode {\n const entries = readEntries(plan);\n // The agent has just begun in-progress items first by default, so opening the\n // dock once there's an active step keeps the live work visible.\n const hasActive = entries.some((entry) => entry.status === \"in_progress\");\n const [open, setOpen] = useState(hasActive);\n // A plan can start all-pending (collapsed) and only later gain an in-progress\n // step; the lazy init above runs once at mount, so reopen on the false→true\n // transition. Only forces open (never re-collapses), preserving manual toggle.\n useEffect(() => {\n if (hasActive) setOpen(true);\n }, [hasActive]);\n if (entries.length === 0) return null;\n const done = entries.filter((entry) => entry.status === \"completed\").length;\n\n return (\n <div\n className=\"rounded-md border border-border/50 bg-card/40\"\n data-testid=\"orchestrator-plan\"\n >\n <button\n type=\"button\"\n onClick={() => setOpen((value) => !value)}\n className=\"flex w-full items-center gap-2 px-2.5 py-1.5 text-left\"\n >\n <ChevronRight\n className={`h-3 w-3 shrink-0 text-muted transition-transform ${open ? \"rotate-90\" : \"\"}`}\n />\n <span className=\"text-xs font-semibold text-txt\">Plan</span>\n <span className=\"flex-1\" />\n <span className=\"font-mono text-2xs tabular-nums text-muted\">\n {done}/{entries.length}\n </span>\n </button>\n {open ? (\n <ul className=\"space-y-0.5 px-2.5 pb-2\">\n {entries.map((entry, index) => (\n <li\n // Plan entries have no stable id and may repeat content across a\n // single immutable snapshot; position is the only discriminator.\n // biome-ignore lint/suspicious/noArrayIndexKey: positional plan snapshot\n key={`${entry.content}-${index}`}\n className=\"flex items-start gap-2 text-xs-tight\"\n >\n <span className=\"mt-0.5\">\n <StatusIcon status={entry.status} />\n </span>\n <span\n className={\n entry.status === \"completed\"\n ? \"text-muted line-through\"\n : entry.status === \"in_progress\"\n ? \"text-txt\"\n : \"text-muted-strong\"\n }\n >\n {entry.content}\n </span>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n );\n}\n"],"mappings":"AAqCW,cA6CH,YA7CG;AArCX,SAAS,OAAO,cAAc,QAAQ,cAAc;AACpD,SAAyB,WAAW,gBAAgB;AAgBpD,SAAS,YAAY,MAA4C;AAC/D,QAAM,MAAM,KAAK;AACjB,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,QAAM,UAAuB,CAAC;AAC9B,aAAW,QAAQ,KAAK;AACtB,QAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,UAAM,SAAS;AACf,UAAM,UAAU,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AACtE,QAAI,YAAY,GAAI;AACpB,UAAM,SACJ,OAAO,WAAW,iBAAiB,OAAO,WAAW,cACjD,OAAO,SACP;AACN,YAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,EAClC;AACA,SAAO;AACT;AAEA,SAAS,WAAW,EAAE,OAAO,GAA+C;AAC1E,MAAI,WAAW;AACb,WAAO,oBAAC,SAAM,WAAU,4BAA2B,eAAW,MAAC;AACjE,MAAI,WAAW;AACb,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,eAAW;AAAA;AAAA,IACb;AAEJ,SAAO,oBAAC,UAAO,WAAU,kCAAiC,eAAW,MAAC;AACxE;AAEO,SAAS,SAAS;AAAA,EACvB;AACF,GAEc;AACZ,QAAM,UAAU,YAAY,IAAI;AAGhC,QAAM,YAAY,QAAQ,KAAK,CAAC,UAAU,MAAM,WAAW,aAAa;AACxE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,SAAS;AAI1C,YAAU,MAAM;AACd,QAAI,UAAW,SAAQ,IAAI;AAAA,EAC7B,GAAG,CAAC,SAAS,CAAC;AACd,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,OAAO,QAAQ,OAAO,CAAC,UAAU,MAAM,WAAW,WAAW,EAAE;AAErE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MAEZ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,QAAQ,CAAC,UAAU,CAAC,KAAK;AAAA,YACxC,WAAU;AAAA,YAEV;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,oDAAoD,OAAO,cAAc,EAAE;AAAA;AAAA,cACxF;AAAA,cACA,oBAAC,UAAK,WAAU,kCAAiC,kBAAI;AAAA,cACrD,oBAAC,UAAK,WAAU,UAAS;AAAA,cACzB,qBAAC,UAAK,WAAU,8CACb;AAAA;AAAA,gBAAK;AAAA,gBAAE,QAAQ;AAAA,iBAClB;AAAA;AAAA;AAAA,QACF;AAAA,QACC,OACC,oBAAC,QAAG,WAAU,2BACX,kBAAQ,IAAI,CAAC,OAAO,UACnB;AAAA,UAAC;AAAA;AAAA,YAKC,WAAU;AAAA,YAEV;AAAA,kCAAC,UAAK,WAAU,UACd,8BAAC,cAAW,QAAQ,MAAM,QAAQ,GACpC;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,WACE,MAAM,WAAW,cACb,4BACA,MAAM,WAAW,gBACf,aACA;AAAA,kBAGP,gBAAM;AAAA;AAAA,cACT;AAAA;AAAA;AAAA,UAhBK,GAAG,MAAM,OAAO,IAAI,KAAK;AAAA,QAiBhC,CACD,GACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,21 @@
1
+ import { type ReactNode } from "react";
2
+ /**
3
+ * A collapsed-by-default reasoning cell. While the model is still thinking the
4
+ * header reads "Thinking…" and the body text gets a luminance-sweep shimmer;
5
+ * once finished it reads "Thought for {duration}". The shimmer is a CSS
6
+ * mask-image sweep over the SAME `text-muted` glyphs — it introduces no new
7
+ * color, and it is disabled under `prefers-reduced-motion`.
8
+ *
9
+ * Pure presentational: it renders only from its props and owns no data.
10
+ *
11
+ * @param props.text - The reasoning / chain-of-thought markdown to render.
12
+ * @param props.durationMs - Total thinking time in ms; humanized in the header.
13
+ * @param props.streaming - Whether reasoning is still arriving (drives the
14
+ * "Thinking…" label and the shimmer).
15
+ */
16
+ export declare function ReasoningCell({ text, durationMs, streaming, }: {
17
+ text: string;
18
+ durationMs?: number;
19
+ streaming?: boolean;
20
+ }): ReactNode;
21
+ //# sourceMappingURL=orchestrator-reasoning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-reasoning.d.ts","sourceRoot":"","sources":["../src/orchestrator-reasoning.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAyEjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,UAAU,EACV,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,SAAS,CAuDZ"}
@@ -0,0 +1,105 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Brain, ChevronRight } from "lucide-react";
3
+ import { useState } from "react";
4
+ import { MarkdownText } from "./orchestrator-markdown.js";
5
+ const REASONING_SHIMMER_CSS = `
6
+ .orchestrator-reasoning-shimmer {
7
+ -webkit-mask-image: linear-gradient(
8
+ 100deg,
9
+ rgba(0, 0, 0, 0.45) 30%,
10
+ rgba(0, 0, 0, 1) 50%,
11
+ rgba(0, 0, 0, 0.45) 70%
12
+ );
13
+ mask-image: linear-gradient(
14
+ 100deg,
15
+ rgba(0, 0, 0, 0.45) 30%,
16
+ rgba(0, 0, 0, 1) 50%,
17
+ rgba(0, 0, 0, 0.45) 70%
18
+ );
19
+ -webkit-mask-size: 220% 100%;
20
+ mask-size: 220% 100%;
21
+ animation: orchestrator-reasoning-sweep 1.8s linear infinite;
22
+ }
23
+ @keyframes orchestrator-reasoning-sweep {
24
+ from {
25
+ -webkit-mask-position: 180% 0;
26
+ mask-position: 180% 0;
27
+ }
28
+ to {
29
+ -webkit-mask-position: -80% 0;
30
+ mask-position: -80% 0;
31
+ }
32
+ }
33
+ @media (prefers-reduced-motion: reduce) {
34
+ .orchestrator-reasoning-shimmer {
35
+ -webkit-mask-image: none;
36
+ mask-image: none;
37
+ animation: none;
38
+ }
39
+ }
40
+ `;
41
+ function humanizeDuration(ms) {
42
+ const totalSeconds = Math.max(0, Math.round(ms / 1e3));
43
+ if (totalSeconds < 60) {
44
+ return `${totalSeconds}s`;
45
+ }
46
+ const minutes = Math.floor(totalSeconds / 60);
47
+ const seconds = totalSeconds % 60;
48
+ return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;
49
+ }
50
+ function ReasoningCell({
51
+ text,
52
+ durationMs,
53
+ streaming
54
+ }) {
55
+ const [open, setOpen] = useState(false);
56
+ const header = streaming ? "Thinking\u2026" : durationMs !== void 0 ? `Thought for ${humanizeDuration(durationMs)}` : "Thought";
57
+ return /* @__PURE__ */ jsxs(
58
+ "div",
59
+ {
60
+ className: "rounded-md border border-border/50 bg-card/50",
61
+ "data-testid": "orchestrator-reasoning",
62
+ children: [
63
+ /* @__PURE__ */ jsxs(
64
+ "button",
65
+ {
66
+ type: "button",
67
+ onClick: () => setOpen((value) => !value),
68
+ "aria-expanded": open,
69
+ className: "flex w-full items-center gap-2 px-2.5 py-1.5 text-left",
70
+ children: [
71
+ /* @__PURE__ */ jsx(
72
+ ChevronRight,
73
+ {
74
+ className: `h-3 w-3 shrink-0 text-muted transition-transform ${open ? "rotate-90" : ""}`
75
+ }
76
+ ),
77
+ /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5 shrink-0 text-muted-strong" }),
78
+ /* @__PURE__ */ jsx(
79
+ "span",
80
+ {
81
+ className: `min-w-0 flex-1 truncate text-2xs italic text-muted ${// The header itself gets the shimmer while streaming so the cell
82
+ // reads as "alive" even when collapsed.
83
+ streaming ? "orchestrator-reasoning-shimmer" : ""}`,
84
+ children: header
85
+ }
86
+ )
87
+ ]
88
+ }
89
+ ),
90
+ open ? /* @__PURE__ */ jsx("div", { className: "px-2.5 pb-2", children: /* @__PURE__ */ jsx(
91
+ "div",
92
+ {
93
+ className: `text-2xs italic text-muted ${streaming ? "orchestrator-reasoning-shimmer" : ""}`,
94
+ children: /* @__PURE__ */ jsx(MarkdownText, { text })
95
+ }
96
+ ) }) : null,
97
+ /* @__PURE__ */ jsx("style", { href: "orchestrator-reasoning-shimmer", precedence: "default", children: REASONING_SHIMMER_CSS })
98
+ ]
99
+ }
100
+ );
101
+ }
102
+ export {
103
+ ReasoningCell
104
+ };
105
+ //# sourceMappingURL=orchestrator-reasoning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/orchestrator-reasoning.tsx"],"sourcesContent":["import { Brain, ChevronRight } from \"lucide-react\";\nimport { type ReactNode, useState } from \"react\";\nimport { MarkdownText } from \"./orchestrator-markdown.js\";\n\n// Luminance-sweep shimmer keyframes for the streaming reasoning cell. The cell\n// renders in the OrchestratorWorkbench timeline (/orchestrator), which injects\n// no shared stylesheet, so the cell carries the rule itself rather than\n// assuming an ambient stylesheet is present. It is emitted via a\n// React-hoistable <style href precedence> (below):\n// React lifts it to <head> and DEDUPLICATES every identical href to a single\n// DOM node, so N cells across any number of renders inject the rule exactly\n// once (the per-instance <style> this replaces injected one tag per cell). The\n// reduced-motion guard drops the animation and the mask entirely.\nconst REASONING_SHIMMER_CSS = `\n.orchestrator-reasoning-shimmer {\n -webkit-mask-image: linear-gradient(\n 100deg,\n rgba(0, 0, 0, 0.45) 30%,\n rgba(0, 0, 0, 1) 50%,\n rgba(0, 0, 0, 0.45) 70%\n );\n mask-image: linear-gradient(\n 100deg,\n rgba(0, 0, 0, 0.45) 30%,\n rgba(0, 0, 0, 1) 50%,\n rgba(0, 0, 0, 0.45) 70%\n );\n -webkit-mask-size: 220% 100%;\n mask-size: 220% 100%;\n animation: orchestrator-reasoning-sweep 1.8s linear infinite;\n}\n@keyframes orchestrator-reasoning-sweep {\n from {\n -webkit-mask-position: 180% 0;\n mask-position: 180% 0;\n }\n to {\n -webkit-mask-position: -80% 0;\n mask-position: -80% 0;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .orchestrator-reasoning-shimmer {\n -webkit-mask-image: none;\n mask-image: none;\n animation: none;\n }\n}\n`;\n\n// A collapsible \"reasoning / thinking\" cell, matching the Codex / opencode\n// shape: a dim one-line header you can expand into the model's raw chain of\n// thought. The cloud-ui ai-elements `Reasoning` primitive\n// (packages/ui/.../ai-elements/reasoning.tsx) carries a Radix\n// `useControllableState` + auto-open/auto-close timer machine and its own\n// `text-muted-foreground`/`text-sm` skin keyed to seconds. Our contract is a\n// flat presentational `{ text, durationMs, streaming }` with a humanized\n// duration, a `MarkdownText` body, and an in-token shimmer — none of which that\n// primitive exposes — so we build a self-contained collapsible on the same\n// useState open/setOpen pattern the sibling tool-call cell uses, re-skinned to\n// eliza tokens (text-2xs, text-muted, rounded-md, border-border/50).\n\n/** Humanize a stopwatch duration the way Codex's header reads: sub-minute as\n * whole seconds, then minutes (+ trailing seconds). Display-only rounding. */\nfunction humanizeDuration(ms: number): string {\n const totalSeconds = Math.max(0, Math.round(ms / 1000));\n if (totalSeconds < 60) {\n return `${totalSeconds}s`;\n }\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;\n}\n\n/**\n * A collapsed-by-default reasoning cell. While the model is still thinking the\n * header reads \"Thinking…\" and the body text gets a luminance-sweep shimmer;\n * once finished it reads \"Thought for {duration}\". The shimmer is a CSS\n * mask-image sweep over the SAME `text-muted` glyphs — it introduces no new\n * color, and it is disabled under `prefers-reduced-motion`.\n *\n * Pure presentational: it renders only from its props and owns no data.\n *\n * @param props.text - The reasoning / chain-of-thought markdown to render.\n * @param props.durationMs - Total thinking time in ms; humanized in the header.\n * @param props.streaming - Whether reasoning is still arriving (drives the\n * \"Thinking…\" label and the shimmer).\n */\nexport function ReasoningCell({\n text,\n durationMs,\n streaming,\n}: {\n text: string;\n durationMs?: number;\n streaming?: boolean;\n}): ReactNode {\n const [open, setOpen] = useState(false);\n\n const header = streaming\n ? \"Thinking…\"\n : durationMs !== undefined\n ? `Thought for ${humanizeDuration(durationMs)}`\n : \"Thought\";\n\n return (\n <div\n className=\"rounded-md border border-border/50 bg-card/50\"\n data-testid=\"orchestrator-reasoning\"\n >\n <button\n type=\"button\"\n onClick={() => setOpen((value) => !value)}\n aria-expanded={open}\n className=\"flex w-full items-center gap-2 px-2.5 py-1.5 text-left\"\n >\n <ChevronRight\n className={`h-3 w-3 shrink-0 text-muted transition-transform ${\n open ? \"rotate-90\" : \"\"\n }`}\n />\n <Brain className=\"h-3.5 w-3.5 shrink-0 text-muted-strong\" />\n <span\n className={`min-w-0 flex-1 truncate text-2xs italic text-muted ${\n // The header itself gets the shimmer while streaming so the cell\n // reads as \"alive\" even when collapsed.\n streaming ? \"orchestrator-reasoning-shimmer\" : \"\"\n }`}\n >\n {header}\n </span>\n </button>\n {open ? (\n <div className=\"px-2.5 pb-2\">\n <div\n className={`text-2xs italic text-muted ${\n streaming ? \"orchestrator-reasoning-shimmer\" : \"\"\n }`}\n >\n <MarkdownText text={text} />\n </div>\n </div>\n ) : null}\n {/* React-hoistable, deduplicated stylesheet: the shared `href` collapses\n every ReasoningCell's copy of this rule to a single <head> node, so it\n is emitted once regardless of how many cells mount or re-render. */}\n <style href=\"orchestrator-reasoning-shimmer\" precedence=\"default\">\n {REASONING_SHIMMER_CSS}\n </style>\n </div>\n );\n}\n"],"mappings":"AA8GM,SAME,KANF;AA9GN,SAAS,OAAO,oBAAoB;AACpC,SAAyB,gBAAgB;AACzC,SAAS,oBAAoB;AAW7B,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmD9B,SAAS,iBAAiB,IAAoB;AAC5C,QAAM,eAAe,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;AACtD,MAAI,eAAe,IAAI;AACrB,WAAO,GAAG,YAAY;AAAA,EACxB;AACA,QAAM,UAAU,KAAK,MAAM,eAAe,EAAE;AAC5C,QAAM,UAAU,eAAe;AAC/B,SAAO,YAAY,IAAI,GAAG,OAAO,MAAM,GAAG,OAAO,KAAK,OAAO;AAC/D;AAgBO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAIc;AACZ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AAEtC,QAAM,SAAS,YACX,mBACA,eAAe,SACb,eAAe,iBAAiB,UAAU,CAAC,KAC3C;AAEN,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MAEZ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,QAAQ,CAAC,UAAU,CAAC,KAAK;AAAA,YACxC,iBAAe;AAAA,YACf,WAAU;AAAA,YAEV;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,oDACT,OAAO,cAAc,EACvB;AAAA;AAAA,cACF;AAAA,cACA,oBAAC,SAAM,WAAU,0CAAyC;AAAA,cAC1D;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW;AAAA;AAAA,kBAGT,YAAY,mCAAmC,EACjD;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QACF;AAAA,QACC,OACC,oBAAC,SAAI,WAAU,eACb;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,8BACT,YAAY,mCAAmC,EACjD;AAAA,YAEA,8BAAC,gBAAa,MAAY;AAAA;AAAA,QAC5B,GACF,IACE;AAAA,QAIJ,oBAAC,WAAM,MAAK,kCAAiC,YAAW,WACrD,iCACH;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,15 @@
1
+ import { type ReactNode } from "react";
2
+ import type { ConversationBlock, ToolView } from "./orchestrator-stream.helpers";
3
+ export type { ConversationBlock, ToolView, } from "./orchestrator-stream.helpers";
4
+ /** The expandable body of a tool card: an interleaved diff for edits, the new
5
+ * content for writes, the command + output for shells, and the raw output
6
+ * otherwise. */
7
+ export declare function ToolBody({ tool }: {
8
+ tool: ToolView;
9
+ }): ReactNode;
10
+ export declare function ConversationBlockView({ block, locale, onInspect, }: {
11
+ block: ConversationBlock;
12
+ locale?: string;
13
+ onInspect?: () => void;
14
+ }): ReactNode;
15
+ //# sourceMappingURL=orchestrator-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-stream.d.ts","sourceRoot":"","sources":["../src/orchestrator-stream.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AAK1D,OAAO,KAAK,EACV,iBAAiB,EAEjB,QAAQ,EACT,MAAM,+BAA+B,CAAC;AAGvC,YAAY,EACV,iBAAiB,EACjB,QAAQ,GACT,MAAM,+BAA+B,CAAC;AA6IvC;;gBAEgB;AAChB,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,SAAS,CAiChE;AAqGD,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,MAAM,EACN,SAAS,GACV,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,GAAG,SAAS,CAmFZ"}