@cmodjs/core 4.0.3 → 4.1.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.
Files changed (143) hide show
  1. package/docs/commands.md +44 -9
  2. package/docs/index.md +3 -3
  3. package/docs/install-steps.md +8 -8
  4. package/docs/jobs.md +2 -1
  5. package/docs/mod.md +1 -1
  6. package/docs/options.md +1 -1
  7. package/docs/permissions.md +1 -1
  8. package/docs/session.md +46 -13
  9. package/docs/testing.md +15 -11
  10. package/docs/ui.md +43 -11
  11. package/installer.d.ts +3 -2
  12. package/installer.d.ts.map +1 -1
  13. package/jobs/program.d.ts +1 -0
  14. package/jobs/program.d.ts.map +1 -1
  15. package/jobs/program.js +39 -23
  16. package/mod.d.ts +3 -2
  17. package/mod.d.ts.map +1 -1
  18. package/mod.js +1 -0
  19. package/package.json +1 -1
  20. package/records.d.ts +15 -1
  21. package/records.d.ts.map +1 -1
  22. package/records.js +39 -1
  23. package/register.d.ts.map +1 -1
  24. package/register.js +8 -5
  25. package/runtime/before.d.ts +6 -2
  26. package/runtime/before.d.ts.map +1 -1
  27. package/runtime/before.js +56 -18
  28. package/runtime/buttons.d.ts +10 -0
  29. package/runtime/buttons.d.ts.map +1 -0
  30. package/runtime/buttons.js +12 -0
  31. package/runtime/conversations.d.ts +3 -0
  32. package/runtime/conversations.d.ts.map +1 -1
  33. package/runtime/conversations.js +164 -27
  34. package/runtime/engine.d.ts +2 -0
  35. package/runtime/engine.d.ts.map +1 -1
  36. package/runtime/grants.d.ts +1 -0
  37. package/runtime/grants.d.ts.map +1 -1
  38. package/runtime/grants.js +5 -2
  39. package/runtime/hotkeys.d.ts.map +1 -1
  40. package/runtime/hotkeys.js +7 -4
  41. package/runtime/installer.d.ts +10 -6
  42. package/runtime/installer.d.ts.map +1 -1
  43. package/runtime/installer.js +106 -48
  44. package/runtime/lifecycle.d.ts +2 -2
  45. package/runtime/lifecycle.d.ts.map +1 -1
  46. package/runtime/lifecycle.js +144 -42
  47. package/runtime/pages.d.ts +3 -1
  48. package/runtime/pages.d.ts.map +1 -1
  49. package/runtime/pages.js +48 -14
  50. package/runtime/parts.d.ts +1 -0
  51. package/runtime/parts.d.ts.map +1 -1
  52. package/runtime/parts.js +6 -3
  53. package/runtime/programs.d.ts +1 -0
  54. package/runtime/programs.d.ts.map +1 -1
  55. package/runtime/programs.js +4 -1
  56. package/runtime/sessions.d.ts +10 -3
  57. package/runtime/sessions.d.ts.map +1 -1
  58. package/runtime/sessions.js +104 -59
  59. package/runtime/toaster.d.ts.map +1 -1
  60. package/runtime/toaster.js +23 -9
  61. package/runtime/ui.d.ts +22 -4
  62. package/runtime/ui.d.ts.map +1 -1
  63. package/runtime/ui.js +161 -59
  64. package/runtime/watches.d.ts.map +1 -1
  65. package/runtime/watches.js +18 -4
  66. package/runtime/widgets.d.ts +7 -5
  67. package/runtime/widgets.d.ts.map +1 -1
  68. package/runtime/widgets.js +31 -21
  69. package/session/context/turn/message/attached-file.d.ts +13 -0
  70. package/session/context/turn/message/attached-file.d.ts.map +1 -0
  71. package/session/context/turn/message/attached-file.js +21 -0
  72. package/session/context/turn/message/message.d.ts +3 -2
  73. package/session/context/turn/message/message.d.ts.map +1 -1
  74. package/session/context/turn/message/message.js +20 -6
  75. package/session/conversation.d.ts +15 -3
  76. package/session/conversation.d.ts.map +1 -1
  77. package/session/conversation.js +23 -4
  78. package/session/goal/task.d.ts +5 -0
  79. package/session/goal/task.d.ts.map +1 -1
  80. package/session/session.d.ts +36 -7
  81. package/session/session.d.ts.map +1 -1
  82. package/session/session.js +2 -1
  83. package/src/installer.ts +3 -2
  84. package/src/jobs/program.ts +41 -21
  85. package/src/mod.ts +3 -2
  86. package/src/records.ts +49 -1
  87. package/src/register.ts +11 -8
  88. package/src/runtime/before.ts +61 -22
  89. package/src/runtime/buttons.ts +22 -0
  90. package/src/runtime/conversations.ts +170 -34
  91. package/src/runtime/engine.ts +2 -0
  92. package/src/runtime/grants.ts +6 -2
  93. package/src/runtime/hotkeys.ts +7 -4
  94. package/src/runtime/installer.ts +147 -83
  95. package/src/runtime/lifecycle.ts +149 -48
  96. package/src/runtime/pages.ts +56 -12
  97. package/src/runtime/parts.ts +8 -4
  98. package/src/runtime/programs.ts +5 -1
  99. package/src/runtime/sessions.ts +106 -59
  100. package/src/runtime/toaster.ts +27 -9
  101. package/src/runtime/ui.ts +166 -62
  102. package/src/runtime/watches.ts +20 -5
  103. package/src/runtime/widgets.ts +35 -23
  104. package/src/session/context/turn/message/attached-file.ts +36 -0
  105. package/src/session/context/turn/message/message.ts +20 -7
  106. package/src/session/conversation.ts +31 -6
  107. package/src/session/goal/task.ts +6 -0
  108. package/src/session/session.ts +18 -7
  109. package/src/testing/fake-claude.ts +21 -6
  110. package/src/testing/fake-elements.ts +57 -8
  111. package/src/testing/fake-sessions.ts +72 -24
  112. package/src/testing.ts +114 -33
  113. package/src/ui/areas.ts +1 -0
  114. package/src/ui/components.ts +14 -8
  115. package/src/ui/elements.ts +6 -2
  116. package/src/ui/markdown.ts +3 -3
  117. package/src/ui/panes.ts +2 -2
  118. package/src/ui/styles.ts +6 -2
  119. package/testing/fake-claude.d.ts +3 -0
  120. package/testing/fake-claude.d.ts.map +1 -1
  121. package/testing/fake-claude.js +18 -5
  122. package/testing/fake-elements.d.ts.map +1 -1
  123. package/testing/fake-elements.js +52 -7
  124. package/testing/fake-sessions.d.ts +24 -10
  125. package/testing/fake-sessions.d.ts.map +1 -1
  126. package/testing/fake-sessions.js +66 -20
  127. package/testing.d.ts +8 -12
  128. package/testing.d.ts.map +1 -1
  129. package/testing.js +113 -27
  130. package/ui/areas.d.ts +4 -0
  131. package/ui/areas.d.ts.map +1 -1
  132. package/ui/components.d.ts +1 -0
  133. package/ui/components.d.ts.map +1 -1
  134. package/ui/components.js +11 -7
  135. package/ui/elements.d.ts +3 -0
  136. package/ui/elements.d.ts.map +1 -1
  137. package/ui/elements.js +6 -1
  138. package/ui/markdown.d.ts +2 -2
  139. package/ui/markdown.d.ts.map +1 -1
  140. package/ui/panes.d.ts +2 -1
  141. package/ui/panes.d.ts.map +1 -1
  142. package/ui/styles.d.ts +11 -2
  143. package/ui/styles.d.ts.map +1 -1
package/testing.js CHANGED
@@ -7,7 +7,7 @@ import { createRouter } from './runtime/router.js';
7
7
  import { toolInputOf } from './runtime/tool-calls.js';
8
8
  import { createLifecycle } from './runtime/lifecycle.js';
9
9
  import { MissingOptions } from './runtime/options.js';
10
- import { conversationMethods } from './runtime/sessions.js';
10
+ import { conversationMethods, pickedColor } from './runtime/sessions.js';
11
11
  import { Message } from './session/context/turn/message/message.js';
12
12
  import { Note, untagged } from './session/context/turn/message/note.js';
13
13
  import { Prompt } from './session/context/turn/message/prompt.js';
@@ -27,7 +27,7 @@ import { drawWith, elementOf } from './ui/elements.js';
27
27
  import { drawnParts } from './runtime/parts.js';
28
28
  import { serveWidgets } from './runtime/widgets.js';
29
29
  import { engineOf } from './runtime/engine.js';
30
- import { pagesOf } from './runtime/pages.js';
30
+ import { pagesOf, servePages } from './runtime/pages.js';
31
31
  import { partMethods } from './runtime/ui.js';
32
32
  const defaultColumns = 80;
33
33
  const defaultRows = 24;
@@ -50,9 +50,11 @@ export function testMod(definition, options = {}) {
50
50
  fake.claude.session.cwd = async () => cwd;
51
51
  const conversations = fakeSessions({
52
52
  callTool: (args) => fake.claude.tool.call(args),
53
+ listAgents: () => fake.fakes.agent.list?.() ?? Promise.resolve([]),
53
54
  project: () => projectRoot,
54
55
  cwd: () => cwd,
55
56
  given: options.sessions ?? [],
57
+ decide: (event, change) => decide(event, change),
56
58
  push: (mod, session, change) => {
57
59
  if (mod !== name)
58
60
  return;
@@ -62,6 +64,15 @@ export function testMod(definition, options = {}) {
62
64
  });
63
65
  conversations.start(sessionId);
64
66
  const callMod = async (method, input, caller = cmodPluginName) => calledAnswer(caller, await lifecycle.route('cmod.call', { to: name, method, input, caller }, async () => ({ deny: notInstalled(name) })));
67
+ const tellColor = async (told) => {
68
+ if (name !== cmodPluginName)
69
+ await callMod(conversationMethods.sessionColor, told);
70
+ };
71
+ const tellHeldColor = async () => {
72
+ const held = conversations.color();
73
+ if (held.color !== undefined)
74
+ await tellColor(held);
75
+ };
65
76
  let declaredPages = [];
66
77
  let openPages = [];
67
78
  let shownPage;
@@ -87,38 +98,69 @@ export function testMod(definition, options = {}) {
87
98
  await tellShown();
88
99
  };
89
100
  let widgets;
101
+ let stylesMarkdown = false;
102
+ const ownMarkdown = new Map();
103
+ const missedMarkdown = new Map();
90
104
  const updated = async ({ parts, redraw, requests }) => {
91
- if (parts !== undefined)
105
+ if (parts !== undefined) {
92
106
  declaredPages = pagesOf(parts);
107
+ stylesMarkdown = parts.stylesMarkdown === true;
108
+ ownMarkdown.clear();
109
+ }
93
110
  if (parts !== undefined || redraw !== undefined)
94
111
  (await widgetsOf()).update(name, { ...(parts === undefined ? {} : { parts }), ...(redraw === undefined ? {} : { redraw }) });
95
112
  if (requests !== undefined && requests.length > 0)
96
113
  await applyRequests(requests);
97
114
  };
98
115
  const pressPart = (input) => callMod(partMethods.press, input).then((update) => updated((update ?? {})));
116
+ const markdownIn = (table, at) => (props) => {
117
+ const drawnAt = `${at.surface}\u0000${at.columns}\u0000${props.text}`;
118
+ const drawn = stylesMarkdown ? ownMarkdown.get(drawnAt) : null;
119
+ if (drawn === undefined)
120
+ missedMarkdown.set(drawnAt, { markdown: props.text, ...at });
121
+ if (drawn === undefined || drawn === null || drawn.tree === null)
122
+ return table.Markdown(props);
123
+ const { draw, tree } = drawn;
124
+ return drawWith(table, () => elementOf(tree, '', (handler, args) => void pressPart({ draw, handler, args })));
125
+ };
126
+ const withOwnMarkdown = async (draw) => {
127
+ const first = await draw();
128
+ if (missedMarkdown.size === 0)
129
+ return first;
130
+ for (const [drawnAt, input] of missedMarkdown)
131
+ ownMarkdown.set(drawnAt, (await callMod(partMethods.draw, input)));
132
+ missedMarkdown.clear();
133
+ return draw();
134
+ };
135
+ const cmodClaude = { ...fake.claude, cmod: { call: async (input) => (input.to === name ? callMod(input.method, input.input) : fake.claude.cmod.call(input)) } };
136
+ const reportPart = (_id, message, error) => fake.claude.ui.log(`cmod: ${message}: ${messageOf(error)}`, { to: 'debug' });
137
+ const parts = drawnParts({ claude: cmodClaude, report: reportPart, press: (_mod, input) => void pressPart(input).catch((error) => fake.claude.ui.log(`cmod: ${name} did not take the press: ${messageOf(error)}`, { to: 'debug' })) });
99
138
  const servedWidgets = async () => {
100
139
  const own = name === cmodPluginName && lifecycle.mod !== undefined ? engineOf(lifecycle.mod).widgets : undefined;
101
140
  if (own !== undefined)
102
141
  return own;
103
- const claude = { ...fake.claude, cmod: { call: async (input) => (input.to === name ? callMod(input.method, input.input) : fake.claude.cmod.call(input)) } };
104
- const report = (_id, message, error) => fake.claude.ui.log(`cmod: ${message}: ${messageOf(error)}`, { to: 'debug' });
105
- const press = (_mod, input) => void pressPart(input).catch((error) => fake.claude.ui.log(`cmod: ${name} did not take the press: ${messageOf(error)}`, { to: 'debug' }));
106
142
  return serveWidgets({
107
- claude,
143
+ claude: cmodClaude,
108
144
  router: cmodPlugin,
109
145
  store: storeFolder({ HOME: await fake.claude.env.home(), XDG_DATA_HOME: await fake.claude.env.dataHome() }),
110
- report,
146
+ report: reportPart,
111
147
  turnClosedBy: () => conversations.lastTurn(),
112
- parts: drawnParts({ claude, report, press }),
148
+ parts,
149
+ markdownIn,
113
150
  });
114
151
  };
115
152
  const widgetsOf = () => (widgets ??= servedWidgets());
153
+ const cmodBeneath = createRouter();
154
+ const pages = servePages({ claude: cmodClaude, router: cmodBeneath, report: reportPart, widgets: { update: (mod, update) => void widgetsOf().then((served) => served.update(mod, update)) }, parts, tellStylers: () => undefined });
155
+ pages.apply((_mod, requests) => applyRequests(requests));
116
156
  const dependencies = fakeDependencies(name, options.dependencies ?? {}, conversations);
117
157
  fake.fakes.cmod.call = async (call) => {
118
158
  if (call.to !== cmodPluginName || call.method !== partMethods.changed)
119
159
  return dependencies(call);
120
- await updated(call.input);
121
- return { isHeld: call.input.isAsked === true };
160
+ const { requests, isAsked, ...listing } = call.input;
161
+ const isHeld = isAsked === true && requests !== undefined && pages.update(name, { requests, isAsked });
162
+ await updated(isAsked === true ? listing : call.input);
163
+ return { isHeld };
122
164
  };
123
165
  const appendRow = fake.claude.session.append;
124
166
  fake.claude.session.append = async (args) => {
@@ -147,6 +189,7 @@ export function testMod(definition, options = {}) {
147
189
  const state = Object.fromEntries(declared.map(([lifetime, values]) => [lifetime, { ...values, ...starting?.[lifetime] }]));
148
190
  const lifecycle = createLifecycle({ ...definition, state }, () => permissionRoutes, (options.options ?? {}), false);
149
191
  let started;
192
+ let isColorTold = false;
150
193
  const start = async () => {
151
194
  started ??= lifecycle.start(fake.claude, async (claude) => {
152
195
  const steps = await modSteps();
@@ -170,44 +213,80 @@ export function testMod(definition, options = {}) {
170
213
  }
171
214
  if (lifecycle.phase !== 'active')
172
215
  throw failure ?? new Error(`${name} did not start: the lifecycle is ${lifecycle.phase}.`);
216
+ if (isColorTold)
217
+ return;
218
+ isColorTold = true;
219
+ await tellHeldColor();
173
220
  };
174
221
  const cmodPlugin = createRouter();
175
222
  const askMod = async (event, change) => {
176
223
  const asked = { to: name, method: conversationMethods.before, input: { session: sessionId, event, change }, caller: cmodPluginName };
177
224
  return calledAnswer(cmodPluginName, await lifecycle.route('cmod.call', asked, async () => ({ deny: notInstalled(name) })));
178
225
  };
226
+ const decide = (event, change) => foldBefore(event, change, [(latest) => askMod(event, latest)], (error) => fake.claude.ui.log(`cmod: passed the ${event} on without ${name}'s answer: ${messageOf(error)}`, { to: 'debug' }));
179
227
  installBefore({
180
228
  claude: fake.claude,
181
229
  router: cmodPlugin,
182
230
  hooks: {
183
231
  place: async () => conversations.place(),
184
232
  wants: async (event) => conversations.wants(name, event),
185
- fold: () => (event, change) => foldBefore(event, change, [(latest) => askMod(event, latest)], (error) => fake.claude.ui.log(`cmod: passed the ${event} on without ${name}'s answer: ${messageOf(error)}`, { to: 'debug' })),
233
+ fold: () => decide,
186
234
  },
187
235
  });
188
236
  const route = async (event, input, below) => {
189
237
  await start();
190
238
  if (event === 'ui.render') {
239
+ const { component, requestId } = input;
240
+ if (component === 'Pane')
241
+ fake.placePane(requestId);
191
242
  await widgetsOf();
192
243
  await fake.settle();
193
244
  }
194
- return cmodPlugin.dispatch(event, input, (passed) => lifecycle.route(event, passed, async (e) => (below ?? claudeCodeAnswer(event, e))));
245
+ return cmodPlugin.dispatch(event, input, (passed) => lifecycle.route(event, passed, async (e) => (await claudeCodeRuns(event, e, below))));
195
246
  };
196
- const runCommand = async (command, args) => {
247
+ const claudeCodeRuns = async (event, e, below) => {
248
+ if (event === 'session.compact' && e.trigger !== 'precompute') {
249
+ const started = await fire('SessionStart', { source: 'compact' });
250
+ fake.shown.notes.push(...(started.additionalContext ?? []).map(untagged));
251
+ }
252
+ if (below !== undefined)
253
+ return below;
254
+ const answer = claudeCodeAnswer(event, e);
255
+ if (event === 'ui.close') {
256
+ const { id, origin } = e;
257
+ if (origin.kind === 'person' && fake.shown.openPanes.has(id))
258
+ await drawPane(id);
259
+ fake.shown.openPanes.delete(id);
260
+ }
261
+ if (event === 'agent.spawn') {
262
+ const started = await route('classic.SubagentStart', { hook_event_name: 'SubagentStart', agent_id: answer.agentId, agent_type: e.subagentType }, undefined);
263
+ fake.shown.notes.push(...(started.additionalContext ?? []).map(untagged));
264
+ }
265
+ return answer;
266
+ };
267
+ const runCommand = async (command, args, builtIn = {}) => {
197
268
  await start();
198
269
  const reached = new Set();
199
- const ownRun = async () => (reached.add(command), {});
200
- const answer = await cmodPlugin.dispatch('command.run', { command, args, origin: { kind: 'composer' }, presentation }, (passed) => lifecycle.route('command.run', passed, ownRun));
270
+ const ownRun = async () => (reached.add(command), builtIn);
271
+ const answer = await cmodPlugin.dispatch('command.run', { command, args, origin: { kind: 'composer' }, presentation }, (passed) => lifecycle.route('command.run', passed, (e) => cmodBeneath.dispatch('command.run', e, ownRun)));
201
272
  if (reached.has(command) && answer.text === undefined)
202
273
  throw new Error(!fake.shown.commands.includes(command) ? `${name} has no slash command /${command}. Add it in setup with mod.use(slashCommand({ name: '${command}', … })).` : `${name}: /${command} reached Claude Code's own run of the command, so Claude Code shows "${name} registered /${command} but no command.run hook answered it". Answer it without calling next(e).`);
203
274
  return answer;
204
275
  };
205
- const drawPane = async (paneId) => {
276
+ const runColor = async (args) => {
277
+ if (args.trim() === '')
278
+ throw new Error(`Claude Code's /color with no color picks one at random, so a test names the color, such as tested.type('/color cyan').`);
279
+ const color = pickedColor(args);
280
+ const answer = await runCommand('color', args, { text: color === undefined ? 'Session color reset to default' : `Session color set to: ${color}` });
281
+ await tellColor(conversations.recolor(color));
282
+ return answer;
283
+ };
284
+ const drawPane = async (paneId, asked) => {
206
285
  await start();
207
286
  if (!fake.shown.openPanes.has(paneId))
208
287
  throw new Error(`The pane "${paneId}" of ${name} closed, and a user sees a pane only while it is open.`);
209
288
  const opened = fake.calls.findLast((call) => call.call === 'ui.open' && call.args[0].id === paneId)?.args[0];
210
- const columns = opened?.columns ?? defaultColumns;
289
+ const columns = asked ?? opened?.columns ?? defaultColumns;
211
290
  const isFocused = (await fake.claude.ui.panes()).some((open) => open.id === paneId && open.isFocused);
212
291
  const props = { title: opened?.title ?? paneId, isFocused, bodyColumns: columns, placement: 'dock', scroll: { offset: 0, bodyRows: defaultRows }, view: {} };
213
292
  const drawing = await route('ui.render', { surface: 'terminal', component: 'Pane', requestId: paneId, props }, elements.Box({}));
@@ -221,7 +300,7 @@ export function testMod(definition, options = {}) {
221
300
  const drawn = (await callMod(partMethods.draw, { page: pageId, params: page.params, columns, isFocused: page.isFocused }));
222
301
  await fake.settle();
223
302
  const tree = drawn?.tree ?? null;
224
- const drawing = tree === null || drawn === null ? elements.Box({}) : drawWith(elements, () => elementOf(tree, '', (handler, args) => void pressPart({ draw: drawn.draw, handler, args })));
303
+ const drawing = tree === null || drawn === null ? elements.Box({}) : await withOwnMarkdown(async () => drawWith(elements, () => elementOf(tree, '', (handler, args) => void pressPart({ draw: drawn.draw, handler, args })), markdownIn(elements, { surface: 'terminal', columns })));
225
304
  return { drawing, columns };
226
305
  };
227
306
  const shownNow = (isPane) => {
@@ -240,7 +319,7 @@ export function testMod(definition, options = {}) {
240
319
  const draw = async (columns) => {
241
320
  await start();
242
321
  const { id } = shownNow(isPane);
243
- return { id, ...(isPane ? await drawPane(id) : await drawPage(id, columns)) };
322
+ return { id, ...(isPane ? await drawPane(id, columns) : await drawPage(id, columns)) };
244
323
  };
245
324
  const drawnElement = async (type, key) => {
246
325
  const { id, drawing } = await draw();
@@ -274,7 +353,7 @@ export function testMod(definition, options = {}) {
274
353
  return { element: e.element };
275
354
  };
276
355
  if (isPane)
277
- await lifecycle.route('ui.press', pressed, run);
356
+ await lifecycle.route('ui.press', pressed, (e) => cmodBeneath.dispatch('ui.press', e, run));
278
357
  else
279
358
  await run(pressed);
280
359
  await fake.settle();
@@ -304,7 +383,7 @@ export function testMod(definition, options = {}) {
304
383
  const turn = area === TurnEndArea ? conversations.lastTurn() : undefined;
305
384
  if (area === TurnEndArea && turn?.closedAt === undefined)
306
385
  throw new Error(`${name} has no ended turn, so TurnEnd draws nothing. End one with tested.add({ type: Prompt, text: '…' }), then tested.endTurn().`);
307
- return { drawing: elements.Box({ flexDirection: 'column', children: [...(await served.draw(area, elements, columns, turn))] }), columns };
386
+ return { drawing: elements.Box({ flexDirection: 'column', children: [...(await withOwnMarkdown(() => served.draw(area, elements, { surface: 'terminal', columns }, turn)))] }), columns };
308
387
  };
309
388
  const drawSlot = async (component, props, requestId = `${component}_${(slotDraws += 1)}`) => {
310
389
  await start();
@@ -326,8 +405,11 @@ export function testMod(definition, options = {}) {
326
405
  const toolUse = toolUseEvents.includes(event) ? { tool_use_id: `toolu_${(toolUses += 1)}` } : {};
327
406
  const transcript = `/test/transcripts/${sessionId}.jsonl`;
328
407
  const filled = { session_id: sessionId, transcript_path: transcript, cwd, hook_event_name: event, ...toolUse, ...input };
329
- if (event === 'SessionStart' && !('transcript_path' in input))
330
- return files.write(transcript, '').then(() => route('classic.SessionStart', filled, below));
408
+ if (event === 'SessionStart') {
409
+ const source = input.source;
410
+ const started = 'transcript_path' in input ? route('classic.SessionStart', filled, below) : files.write(transcript, '').then(() => route('classic.SessionStart', filled, below));
411
+ return source === 'startup' || source === 'clear' ? started : started.then(async (answer) => (await tellHeldColor(), answer));
412
+ }
331
413
  if (event !== 'PreToolUse')
332
414
  return route(`classic.${event}`, filled, below);
333
415
  return firePreToolUse(filled, below);
@@ -406,9 +488,9 @@ export function testMod(definition, options = {}) {
406
488
  await start();
407
489
  return settled(conversations.add(message, added?.task));
408
490
  },
409
- endTurn: async (ending) => {
491
+ endTurn: async (ending, options) => {
410
492
  await start();
411
- await settled(conversations.endTurn(ending === undefined ? undefined : { ...ending, ...(ending.failure === undefined ? {} : { reason: 'error' }) }));
493
+ await settled(conversations.endTurn(ending === undefined ? undefined : { ...ending, ...(ending.failure === undefined ? {} : { reason: 'error' }) }, options?.task));
412
494
  },
413
495
  compact: async () => {
414
496
  await start();
@@ -439,7 +521,7 @@ export function testMod(definition, options = {}) {
439
521
  if (typed === null)
440
522
  throw new Error(`type takes a slash command the way the user types it, such as tested.type('/help'), and "${line}" does not start with /.`);
441
523
  const [, command = '', args = ''] = typed;
442
- return replyOf(await runCommand(command, args));
524
+ return replyOf(await (command === 'color' ? runColor(args) : runCommand(command, args)));
443
525
  },
444
526
  async callTool(toolName, input) {
445
527
  const tool = `mcp__${name}__${toolName}`;
@@ -530,6 +612,10 @@ function claudeCodeAnswer(event, e) {
530
612
  const { model, parentModel } = e;
531
613
  return { agentId: 'agent-1', model: model ?? parentModel };
532
614
  }
615
+ if (event === 'session.append') {
616
+ const { message, uuid } = e;
617
+ return { message, uuid };
618
+ }
533
619
  if (event !== 'prompt.submit')
534
620
  return {};
535
621
  const { text, context, origin } = e;
package/ui/areas.d.ts CHANGED
@@ -19,6 +19,10 @@ export type WidgetInit<State extends object = Record<never, never>> = {
19
19
  readonly id: string;
20
20
  readonly title: string;
21
21
  readonly areas: readonly [Area, ...Area[]];
22
+ readonly place?: {
23
+ readonly side?: 'left' | 'right';
24
+ readonly size?: 'fit' | 'fill';
25
+ };
22
26
  render(mod: Mod<State>, context: WidgetContext): RenderElement | undefined;
23
27
  };
24
28
  export type Widget = {
package/ui/areas.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"areas.d.ts","sourceRoot":"","sources":["../src/ui/areas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE1C,eAAO,MAAM,WAAW,gBAAgB,CAAA;AACxC,eAAO,MAAM,WAAW,gBAAgB,CAAA;AACxC,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,eAAO,MAAM,KAAK,4EAAmE,CAAA;AAErF,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzL,MAAM,MAAM,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IACpE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;IAC1C,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,aAAa,GAAG,SAAS,CAAA;CAC3E,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;IAC/B,MAAM,IAAI,IAAI,CAAA;CACf,CAAA"}
1
+ {"version":3,"file":"areas.d.ts","sourceRoot":"","sources":["../src/ui/areas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE1C,eAAO,MAAM,WAAW,gBAAgB,CAAA;AACxC,eAAO,MAAM,WAAW,gBAAgB,CAAA;AACxC,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,OAAO,YAAY,CAAA;AAChC,eAAO,MAAM,SAAS,cAAc,CAAA;AAEpC,eAAO,MAAM,KAAK,4EAAmE,CAAA;AAErF,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzL,MAAM,MAAM,UAAU,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IACpE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAA;IACrF,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,aAAa,GAAG,SAAS,CAAA;CAC3E,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;IAC/B,MAAM,IAAI,IAAI,CAAA;CACf,CAAA"}
@@ -2,6 +2,7 @@ import type { RenderChildren, RenderElement } from 'claude-code';
2
2
  export type Tab = {
3
3
  readonly key: string;
4
4
  readonly label: string;
5
+ readonly hotkey?: string;
5
6
  };
6
7
  export declare function Tabs({ tabs, selected, onSelect, children }: {
7
8
  readonly tabs: readonly Tab[];
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/ui/components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhE,MAAM,MAAM,GAAG,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAElE,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAQtN;AAED,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,GAAG,aAAa,CAGlG;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAExH;AAED,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAExK;AAED,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAExH;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAEzK;AAED,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAEpK;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAS7J;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAGlH"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/ui/components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhE,MAAM,MAAM,GAAG,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5F,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAOtN;AAED,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,GAAG,aAAa,CAGlG;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CASxH;AAED,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAExK;AAED,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAExH;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAEzK;AAED,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAAG,aAAa,CAEpK;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,aAAa,CAS7J;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAGlH"}
package/ui/components.js CHANGED
@@ -1,11 +1,8 @@
1
1
  import { Box, Button, Text } from './elements.js';
2
2
  export function Tabs({ tabs, selected, onSelect, children }) {
3
- const row = tabs.map((tab, index) => {
4
- const hotkey = index < 9 ? `${index + 1}` : undefined;
5
- return tab.key === selected
6
- ? Text({ children: [...(hotkey === undefined ? [] : [Text({ color: 'claude', children: hotkey }), ': ']), Text({ bold: true, underline: true, children: tab.label })] })
7
- : Button({ plain: true, dimColor: true, key: `tab:${tab.key}`, ...(hotkey === undefined ? {} : { hotkey }), label: tab.label, onPress: () => onSelect(tab.key) });
8
- });
3
+ const row = tabs.map(({ key, label, hotkey }) => key === selected
4
+ ? Text({ children: [...(hotkey === undefined ? [] : [Text({ color: 'claude', children: hotkey }), ': ']), Text({ bold: true, underline: true, children: label })] })
5
+ : Button({ plain: true, dimColor: true, key: `tab:${key}`, ...(hotkey === undefined ? {} : { hotkey }), label, onPress: () => onSelect(key) }));
9
6
  return Box({ flexDirection: 'column', gap: 1, children: [Box({ gap: 3, children: row }), children] });
10
7
  }
11
8
  export function Split({ children }) {
@@ -13,7 +10,14 @@ export function Split({ children }) {
13
10
  return Box({ gap: 1, children: children.map((child) => Box({ width, children: child })) });
14
11
  }
15
12
  export function Panel({ title, children }) {
16
- return Box({ flexDirection: 'column', flexGrow: 1, borderStyle: 'round', borderColor: 'subtle', paddingX: 1, children: [Text({ bold: true, children: title }), children] });
13
+ return Box({
14
+ flexDirection: 'column',
15
+ flexGrow: 1,
16
+ children: [
17
+ Box({ flexDirection: 'column', flexGrow: 1, minWidth: [...title].length + 6, borderStyle: 'round', borderColor: 'subtle', paddingX: 1, children }),
18
+ Box({ position: 'absolute', top: 0, left: 2, children: Text({ bold: true, wrap: 'truncate-end', children: ` ${title} ` }) }),
19
+ ],
20
+ });
17
21
  }
18
22
  export function Toggle({ label, checked, onChange }) {
19
23
  return Button({ plain: true, key: `toggle:${label}`, label: `${checked ? '[x]' : '[ ]'} ${label}`, onPress: () => onChange(!checked) });
package/ui/elements.d.ts CHANGED
@@ -12,4 +12,7 @@ export declare const Markdown: import("claude-code").ElementConstructor<Markdown
12
12
  export declare const Input: import("claude-code").ElementConstructor<import("claude-code").InputProps>;
13
13
  export declare const Select: import("claude-code").ElementConstructor<import("claude-code").SelectProps>;
14
14
  export declare const Image: import("claude-code").ElementConstructor<import("claude-code").ImageProps>;
15
+ export declare const Svg: import("claude-code").ElementConstructor<import("claude-code").SvgProps>;
16
+ export declare const Raster: import("claude-code").ElementConstructor<import("claude-code").RasterProps>;
17
+ export declare const Client: import("claude-code").ElementConstructor<import("claude-code").ClientProps>;
15
18
  //# sourceMappingURL=elements.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../src/ui/elements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,YAAY,EAAY,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAcpG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,aAAa,GAAG,KAAK,CASjI;AAwBD,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;AAErD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAUxE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAa/H;AAED,eAAO,MAAM,GAAG,0EAAiB,CAAA;AACjC,eAAO,MAAM,IAAI,2EAAkB,CAAA;AACnC,eAAO,MAAM,MAAM,6EAAoB,CAAA;AACvC,eAAO,MAAM,IAAI,2EAAkB,CAAA;AACnC,eAAO,MAAM,IAAI,2EAAkB,CAAA;AACnC,eAAO,MAAM,QAAQ,yDAAsB,CAAA;AAC3C,eAAO,MAAM,KAAK,4EAAmB,CAAA;AACrC,eAAO,MAAM,MAAM,6EAAoB,CAAA;AACvC,eAAO,MAAM,KAAK,4EAAmB,CAAA"}
1
+ {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../src/ui/elements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,YAAY,EAAY,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAcpG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,aAAa,GAAG,KAAK,CASjI;AAwBD,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAA;AAErD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAWxE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAa/H;AAED,eAAO,MAAM,GAAG,0EAAiB,CAAA;AACjC,eAAO,MAAM,IAAI,2EAAkB,CAAA;AACnC,eAAO,MAAM,MAAM,6EAAoB,CAAA;AACvC,eAAO,MAAM,IAAI,2EAAkB,CAAA;AACnC,eAAO,MAAM,IAAI,2EAAkB,CAAA;AACnC,eAAO,MAAM,QAAQ,yDAAsB,CAAA;AAC3C,eAAO,MAAM,KAAK,4EAAmB,CAAA;AACrC,eAAO,MAAM,MAAM,6EAAoB,CAAA;AACvC,eAAO,MAAM,KAAK,4EAAmB,CAAA;AACrC,eAAO,MAAM,GAAG,0EAAiB,CAAA;AACjC,eAAO,MAAM,MAAM,6EAAoB,CAAA;AACvC,eAAO,MAAM,MAAM,6EAAoB,CAAA"}
package/ui/elements.js CHANGED
@@ -40,6 +40,8 @@ export function elementData(value, handlers) {
40
40
  return value;
41
41
  if (unbuilt in value) {
42
42
  const { name, props } = value[unbuilt];
43
+ if (name === 'Client')
44
+ throw new Error('Client draws only in panes and styles.');
43
45
  return { [elementKey]: name, props: elementData(props, handlers) };
44
46
  }
45
47
  if (Object.getPrototypeOf(value) !== Object.prototype)
@@ -73,4 +75,7 @@ export const Markdown = element('Markdown');
73
75
  export const Input = element('Input');
74
76
  export const Select = element('Select');
75
77
  export const Image = element('Image');
76
- const constructors = { Box, Text, Button, Link, Code, Markdown, Input, Select, Image };
78
+ export const Svg = element('Svg');
79
+ export const Raster = element('Raster');
80
+ export const Client = element('Client');
81
+ const constructors = { Box, Text, Button, Link, Code, Markdown, Input, Select, Image, Svg, Raster };
package/ui/markdown.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { StyleProps } from './styles.js';
1
+ import type { KindProps } from './styles.js';
2
2
  type BlockText = {
3
3
  readonly text: string;
4
4
  readonly source: string;
@@ -46,6 +46,6 @@ export declare const Table: Block<"table">;
46
46
  export declare const ThematicBreak: Block<"thematicBreak">;
47
47
  export declare const HtmlBlock: Block<"html">;
48
48
  export declare function createReader(): MarkdownReader;
49
- export declare function markdownBlocks<K extends Block>(text: string, kind: K): Omit<StyleProps<K>, 'Default'>[];
49
+ export declare function markdownBlocks<K extends Block>(text: string, kind: K): KindProps<K>[];
50
50
  export {};
51
51
  //# sourceMappingURL=markdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/ui/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,KAAK,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnE,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;IAClD,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACtG,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAA;IACjG,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAA;KAAE,CAAA;IAC1E,IAAI,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,CAAA;AAExH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAA;AAEtH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,CAAA;AAEzJ,MAAM,MAAM,KAAK,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,YAAY,IAAI,cAAc,CAAA;CAC/B,CAAA;AAMD,eAAO,MAAM,OAAO,kBAAkC,CAAA;AACtD,eAAO,MAAM,SAAS,oBAAsC,CAAA;AAC5D,eAAO,MAAM,SAAS,eAAiC,CAAA;AACvD,eAAO,MAAM,UAAU,qBAAwC,CAAA;AAC/D,eAAO,MAAM,IAAI,eAA4B,CAAA;AAC7C,eAAO,MAAM,KAAK,gBAA8B,CAAA;AAChD,eAAO,MAAM,aAAa,wBAA8C,CAAA;AACxE,eAAO,MAAM,SAAS,eAAiC,CAAA;AA4BvD,wBAAgB,YAAY,IAAI,cAAc,CA0C7C;AA0DD,wBAAgB,cAAc,CAAC,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAGvG"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/ui/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,KAAK,SAAS,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnE,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;IAClD,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACtG,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAA;IACjG,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAA;KAAE,CAAA;IAC1E,IAAI,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;CACjC,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,IAAI,SAAS,MAAM,IAAI,IAAI,SAAS,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,CAAA;AAExH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAA;AAEtH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,SAAS,aAAa,CAAC,MAAM,CAAC,EAAE,CAAA;AAEzJ,MAAM,MAAM,KAAK,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,IAAI;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;IACvB,YAAY,IAAI,cAAc,CAAA;CAC/B,CAAA;AAMD,eAAO,MAAM,OAAO,kBAAkC,CAAA;AACtD,eAAO,MAAM,SAAS,oBAAsC,CAAA;AAC5D,eAAO,MAAM,SAAS,eAAiC,CAAA;AACvD,eAAO,MAAM,UAAU,qBAAwC,CAAA;AAC/D,eAAO,MAAM,IAAI,eAA4B,CAAA;AAC7C,eAAO,MAAM,KAAK,gBAA8B,CAAA;AAChD,eAAO,MAAM,aAAa,wBAA8C,CAAA;AACxE,eAAO,MAAM,SAAS,eAAiC,CAAA;AA4BvD,wBAAgB,YAAY,IAAI,cAAc,CA0C7C;AA0DD,wBAAgB,cAAc,CAAC,CAAC,SAAS,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAGrF"}
package/ui/panes.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Frozen, PaneCloseInput, RenderElement, RenderPropsOf, UiScrollInput } from 'claude-code';
2
- import type { Mod } from '../mod.js';
2
+ import type { Mod, Surface } from '../mod.js';
3
3
  export type ScrollTarget = 'start' | 'end' | {
4
4
  readonly key: string;
5
5
  };
@@ -14,6 +14,7 @@ export type OpenOptions<Params> = {
14
14
  readonly params: Params;
15
15
  });
16
16
  export type PaneProps<Params> = Frozen<RenderPropsOf['Pane']> & {
17
+ readonly surface: Surface;
17
18
  readonly params: Params;
18
19
  };
19
20
  export type PaneInit<State extends object = Record<never, never>, Params = undefined> = {
package/ui/panes.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"panes.d.ts","sourceRoot":"","sources":["../src/ui/panes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"panes.d.ts","sourceRoot":"","sources":["../src/ui/panes.ts"],"names":[],"mappings":"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"}
package/ui/styles.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Frozen, RenderComponent, RenderElement, RenderPropsOf } from 'claude-code';
2
- import type { Mod } from '../mod.js';
2
+ import type { Mod, Surface } from '../mod.js';
3
3
  import type { Block, BlockProps } from './markdown.js';
4
4
  export declare const ToolGroup = "toolGroup";
5
5
  export declare const ToolProgress = "toolProgress";
@@ -27,9 +27,18 @@ type PropsOf<K extends Kind> = K extends Row ? RowProps[K] : K extends Block<inf
27
27
  type DefaultOf<K extends Kind> = K extends Row ? Partial<Omit<RowProps[K], 'onScreen'>> : {
28
28
  readonly source?: string;
29
29
  };
30
- export type StyleProps<K extends Kind> = Frozen<PropsOf<K>> & {
30
+ export type StyleProps<K extends Kind> = Frozen<PropsOf<K>> & StyledAt & (K extends Row ? {
31
+ readonly id: string;
32
+ } : {
33
+ readonly id?: string;
34
+ }) & {
31
35
  readonly Default: (props: Frozen<DefaultOf<K>>) => RenderElement;
32
36
  };
37
+ export type KindProps<K extends Kind> = Omit<StyleProps<K>, 'Default' | 'surface' | 'columns' | 'id'>;
38
+ export type StyledAt = {
39
+ readonly surface: Surface;
40
+ readonly columns: number;
41
+ };
33
42
  export type StyleInit<K extends Kind, State extends object = Record<never, never>> = {
34
43
  readonly kind: K;
35
44
  render(mod: Mod<State>, props: StyleProps<K>): RenderElement;
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/ui/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEtD,eAAO,MAAM,SAAS,cAAc,CAAA;AACpC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAC5C,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAEhD,QAAA,MAAM,UAAU;qBACN,aAAa;oBACd,kBAAkB;uBACf,SAAS;yBACP,YAAY;qBAChB,YAAY;wBACP,WAAW;2BACR,cAAc;4BACb,eAAe;8BACb,iBAAiB;sBACzB,SAAS;sBACT,cAAc;CACoD,CAAA;AAE/E,MAAM,MAAM,GAAG,GAAG,MAAM,OAAO,UAAU,CAAA;AAEzC,MAAM,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAA;AAE9B,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,GAAG,GAAG,aAAa,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE9E,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;AAEnH,KAAK,SAAS,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAA;CAAE,CAAA;AAElI,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IACnF,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,aAAa,CAAA;CAC7D,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,MAAM,IAAI,IAAI,CAAA;CACf,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,SAAS,CAEpF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEzC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/ui/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE7C,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAEtD,eAAO,MAAM,SAAS,cAAc,CAAA;AACpC,eAAO,MAAM,YAAY,iBAAiB,CAAA;AAC1C,eAAO,MAAM,aAAa,kBAAkB,CAAA;AAC5C,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAEhD,QAAA,MAAM,UAAU;qBACN,aAAa;oBACd,kBAAkB;uBACf,SAAS;yBACP,YAAY;qBAChB,YAAY;wBACP,WAAW;2BACR,cAAc;4BACb,eAAe;8BACb,iBAAiB;sBACzB,SAAS;sBACT,cAAc;CACoD,CAAA;AAE/E,MAAM,MAAM,GAAG,GAAG,MAAM,OAAO,UAAU,CAAA;AAEzC,MAAM,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAA;AAE9B,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,GAAG,GAAG,aAAa,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAE9E,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;AAEnH,KAAK,SAAS,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,SAAS,GAAG,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAA;CAAE,CAAA;AAEpN,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;AAErG,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9E,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,IAAI,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI;IACnF,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,aAAa,CAAA;CAC7D,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,MAAM,IAAI,IAAI,CAAA;CACf,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,SAAS,CAEpF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEzC"}