@adecore/agents-react 0.37.3 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/agents/AgentModelLabel.d.ts +10 -0
  2. package/dist/agents/AgentModelLabel.js +97 -0
  3. package/dist/chat/logic/visual-height.d.ts +1 -0
  4. package/dist/chat/logic/visual-height.js +1 -1
  5. package/dist/chat/ui/Composer.js +385 -360
  6. package/dist/chat/ui/HostMenuItems.d.ts +4 -0
  7. package/dist/chat/ui/HostMenuItems.js +15 -0
  8. package/dist/chat/ui/Pickers.d.ts +2 -1
  9. package/dist/chat/ui/Pickers.js +126 -123
  10. package/dist/chat/ui/PromptEditor.d.ts +19 -0
  11. package/dist/chat/ui/PromptEditor.js +115 -0
  12. package/dist/chat/ui/Timeline.d.ts +2 -1
  13. package/dist/chat/ui/Timeline.js +13 -1
  14. package/dist/chat/ui/VisualFrame.d.ts +8 -0
  15. package/dist/chat/ui/VisualFrame.js +217 -115
  16. package/dist/chat/ui/composer/ComposerControls.d.ts +3 -0
  17. package/dist/chat/ui/composer/ComposerControls.js +235 -38
  18. package/dist/chat/ui/composer/key-handler.d.ts +1 -1
  19. package/dist/chat/ui/composer/key-handler.js +3 -11
  20. package/dist/chat/ui/composer/prompt-picks.d.ts +4 -0
  21. package/dist/chat/ui/composer/prompt-picks.js +14 -0
  22. package/dist/chat/ui/composer/use-composer-menus.d.ts +4 -49
  23. package/dist/chat/ui/composer/use-composer-menus.js +65 -519
  24. package/dist/chat/ui/composer/use-prompt-menus.d.ts +73 -0
  25. package/dist/chat/ui/composer/use-prompt-menus.js +536 -0
  26. package/dist/chat/ui/index.d.ts +4 -0
  27. package/dist/chat/ui/index.js +3 -0
  28. package/dist/chat/ui/rows/GeneratedImageRow.js +8 -4
  29. package/dist/chat/ui/rows/VisualRow.js +184 -142
  30. package/dist/chat/ui/rows/row-rhythm.js +6 -4
  31. package/dist/host-hooks.d.ts +2 -1
  32. package/dist/host-hooks.js +6 -0
  33. package/dist/host.d.ts +27 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/locales/en/agent-chat.d.ts +1 -0
  36. package/dist/locales/en/agent-chat.js +1 -0
  37. package/dist/locales/nl/agent-chat.d.ts +1 -0
  38. package/dist/locales/nl/agent-chat.js +1 -0
  39. package/dist/providers/index.d.ts +1 -0
  40. package/dist/providers/index.js +1 -0
  41. package/dist/theme.css +3 -0
  42. package/package.json +8 -8
  43. package/src/agents/AgentModelLabel.tsx +40 -0
  44. package/src/chat/logic/visual-height.ts +1 -1
  45. package/src/chat/ui/Composer.tsx +12 -3
  46. package/src/chat/ui/HostMenuItems.tsx +11 -0
  47. package/src/chat/ui/Pickers.tsx +4 -1
  48. package/src/chat/ui/PromptEditor.tsx +130 -0
  49. package/src/chat/ui/Timeline.tsx +22 -1
  50. package/src/chat/ui/VisualFrame.tsx +68 -21
  51. package/src/chat/ui/composer/ComposerControls.tsx +65 -15
  52. package/src/chat/ui/composer/key-handler.ts +3 -9
  53. package/src/chat/ui/composer/prompt-picks.ts +17 -0
  54. package/src/chat/ui/composer/use-composer-menus.ts +18 -275
  55. package/src/chat/ui/composer/use-prompt-menus.ts +341 -0
  56. package/src/chat/ui/index.ts +4 -0
  57. package/src/chat/ui/rows/GeneratedImageRow.tsx +9 -4
  58. package/src/chat/ui/rows/VisualRow.tsx +5 -1
  59. package/src/chat/ui/rows/row-rhythm.ts +6 -4
  60. package/src/host-hooks.ts +9 -1
  61. package/src/host.ts +45 -1
  62. package/src/index.ts +3 -0
  63. package/src/locales/en/agent-chat.ts +1 -0
  64. package/src/locales/nl/agent-chat.ts +1 -0
  65. package/src/providers/index.ts +1 -0
  66. package/src/theme.css +3 -0
@@ -0,0 +1,536 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useEffect, useId, useMemo, useState } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { ensureSyntaxTree, syntaxTree } from '@codemirror/language';
5
+ import { useChatHost } from '../../../host.js';
6
+ import { useChatScope } from '../../../scope.js';
7
+ import { referenceSuggestions, referenceTokens } from '../../chat-references.js';
8
+ import { usableSlashCommands } from '../../guards.js';
9
+ import { chipRanges, findMentionQuery, findReferenceQuery, findSkillQuery, insertMention, insertReference, insertSkill, mentionPick, NO_MENTION_SEARCH, queryOutsideChips } from '../../mentions.js';
10
+ import { inCode } from './keys.js';
11
+ import { clampMenuIndex, composerMenuAria } from './menu-aria.js';
12
+ const SEARCH_DEBOUNCE_MS = 80;
13
+ // What fits above the box without turning the picker into a file tree.
14
+ const MENTION_RESULTS = 8;
15
+ const REFERENCE_RESULTS = 8;
16
+ const NO_COMMANDS = [];
17
+ function sameQuery(left, right) {
18
+ return left?.start === right?.start && left?.query === right?.query;
19
+ }
20
+ /*
21
+ * The pickers over a prompt: `/` for a command, `$` for a skill, `@` for a file and `#` for a view,
22
+ * a node or a chat. One is open at a time, and the arrow keys and the editor's ARIA attributes
23
+ * follow that one.
24
+ */
25
+ export function usePromptMenus(t0) {
26
+ const $ = _c(103);
27
+ const {
28
+ draft: t1,
29
+ inputRef,
30
+ cwd,
31
+ skills,
32
+ slashCommands,
33
+ localCommands: t2,
34
+ goals,
35
+ providerName,
36
+ referables,
37
+ ownId,
38
+ label
39
+ } = t0;
40
+ const {
41
+ draft,
42
+ setDraft,
43
+ setText
44
+ } = t1;
45
+ const localCommands = t2 === undefined ? NO_COMMANDS : t2;
46
+ const {
47
+ t
48
+ } = useTranslation("agent-chat");
49
+ const scope = useChatScope();
50
+ const {
51
+ searchFiles
52
+ } = useChatHost();
53
+ const [menuIndex, setMenuIndex] = useState(0);
54
+ const [mention, setMention] = useState(null);
55
+ const [referenceQuery, setReferenceQuery] = useState(null);
56
+ const [skillQuery, setSkillQuery] = useState(null);
57
+ const [searched, setSearched] = useState(NO_MENTION_SEARCH);
58
+ const text = draft.text;
59
+ let t3;
60
+ let t4;
61
+ if ($[0] !== cwd || $[1] !== mention || $[2] !== scope || $[3] !== searchFiles) {
62
+ t3 = () => {
63
+ if (mention === null || cwd === null) {
64
+ return;
65
+ }
66
+ let stale = false;
67
+ const search = () => {
68
+ if (searchFiles === null) {
69
+ return;
70
+ }
71
+ searchFiles(scope.id, cwd, mention.query, MENTION_RESULTS).then(files => {
72
+ if (!stale) {
73
+ setSearched({
74
+ query: mention.query,
75
+ files
76
+ });
77
+ setMenuIndex(0);
78
+ }
79
+ }).catch(_temp);
80
+ };
81
+ if (mention.query === "") {
82
+ search();
83
+ return () => {
84
+ stale = true;
85
+ };
86
+ }
87
+ const timer = setTimeout(search, SEARCH_DEBOUNCE_MS);
88
+ return () => {
89
+ stale = true;
90
+ clearTimeout(timer);
91
+ };
92
+ };
93
+ t4 = [scope, cwd, mention, searchFiles];
94
+ $[0] = cwd;
95
+ $[1] = mention;
96
+ $[2] = scope;
97
+ $[3] = searchFiles;
98
+ $[4] = t3;
99
+ $[5] = t4;
100
+ } else {
101
+ t3 = $[4];
102
+ t4 = $[5];
103
+ }
104
+ useEffect(t3, t4);
105
+ let t5;
106
+ if ($[6] !== text) {
107
+ t5 = text.startsWith("/") && !text.includes("\n") ? text.slice(1).trim().toLowerCase() : null;
108
+ $[6] = text;
109
+ $[7] = t5;
110
+ } else {
111
+ t5 = $[7];
112
+ }
113
+ const commandQuery = t5;
114
+ let t6;
115
+ bb0: {
116
+ if (commandQuery === null) {
117
+ let t7;
118
+ if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
119
+ t7 = [];
120
+ $[8] = t7;
121
+ } else {
122
+ t7 = $[8];
123
+ }
124
+ t6 = t7;
125
+ break bb0;
126
+ }
127
+ let t7;
128
+ if ($[9] !== skills) {
129
+ t7 = new Set(skills.map(_temp2));
130
+ $[9] = skills;
131
+ $[10] = t7;
132
+ } else {
133
+ t7 = $[10];
134
+ }
135
+ const known = t7;
136
+ let t8;
137
+ if ($[11] !== commandQuery || $[12] !== goals || $[13] !== known || $[14] !== localCommands || $[15] !== providerName || $[16] !== slashCommands || $[17] !== t) {
138
+ const own = localCommands.map(name => ({
139
+ name,
140
+ hint: t(`composer.commands.${name}`),
141
+ local: true,
142
+ skill: false
143
+ }));
144
+ const goal = goals ? [{
145
+ name: "goal",
146
+ hint: t("composer.commands.goal"),
147
+ local: false,
148
+ skill: false
149
+ }] : [];
150
+ const cli = usableSlashCommands([...slashCommands]).filter(name_0 => !localCommands.includes(name_0) && (!goals || name_0 !== "goal")).map(name_1 => ({
151
+ name: name_1,
152
+ hint: known.has(name_1) ? t("composer.commands.skill") : t("composer.commands.cli", {
153
+ cli: providerName ?? t("composer.commands.anyCli")
154
+ }),
155
+ local: false,
156
+ skill: known.has(name_1)
157
+ }));
158
+ t8 = [...own, ...goal, ...cli].filter(command => command.name.startsWith(commandQuery)).slice(0, 8);
159
+ $[11] = commandQuery;
160
+ $[12] = goals;
161
+ $[13] = known;
162
+ $[14] = localCommands;
163
+ $[15] = providerName;
164
+ $[16] = slashCommands;
165
+ $[17] = t;
166
+ $[18] = t8;
167
+ } else {
168
+ t8 = $[18];
169
+ }
170
+ t6 = t8;
171
+ }
172
+ const commands = t6;
173
+ let t7;
174
+ bb1: {
175
+ if (skillQuery === null) {
176
+ let t8;
177
+ if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
178
+ t8 = [];
179
+ $[19] = t8;
180
+ } else {
181
+ t8 = $[19];
182
+ }
183
+ t7 = t8;
184
+ break bb1;
185
+ }
186
+ let t8;
187
+ if ($[20] !== skillQuery.query || $[21] !== skills) {
188
+ const query = skillQuery.query.toLowerCase();
189
+ t8 = skills.filter(skill_0 => skill_0.name.toLowerCase().includes(query)).slice(0, 8);
190
+ $[20] = skillQuery.query;
191
+ $[21] = skills;
192
+ $[22] = t8;
193
+ } else {
194
+ t8 = $[22];
195
+ }
196
+ t7 = t8;
197
+ }
198
+ const skillMatches = t7;
199
+ const commandMenuOpen = commandQuery !== null && commands.length > 0;
200
+ const skillMenuOpen = !commandMenuOpen && skillQuery !== null && skillMatches.length > 0;
201
+ const mentionMenuOpen = !commandMenuOpen && !skillMenuOpen && mention !== null;
202
+ const files_0 = mention === null ? [] : searched.files;
203
+ const mentionCount = files_0.length;
204
+ let t8;
205
+ if ($[23] !== referables.chatsOnly) {
206
+ t8 = item => !referables.chatsOnly || item.kind === "chat";
207
+ $[23] = referables.chatsOnly;
208
+ $[24] = t8;
209
+ } else {
210
+ t8 = $[24];
211
+ }
212
+ const offersReferences = referables.items.some(t8);
213
+ const referenceMenuOpen = !commandMenuOpen && !skillMenuOpen && !mentionMenuOpen && referenceQuery !== null && offersReferences;
214
+ const excluded = ownId === undefined ? [...draft.chats, ...draft.references] : [ownId, ...draft.chats, ...draft.references];
215
+ const referenceMatches = referenceMenuOpen ? referenceSuggestions(referables, referenceQuery.query, excluded, REFERENCE_RESULTS) : [];
216
+ let t9;
217
+ if ($[25] !== draft.chats || $[26] !== draft.referenceNames || $[27] !== draft.references || $[28] !== referables.items) {
218
+ let t10;
219
+ if ($[30] !== referables.items) {
220
+ t10 = token => ({
221
+ ...token,
222
+ kind: referables.items.find(item_0 => item_0.id === token.id)?.kind ?? null
223
+ });
224
+ $[30] = referables.items;
225
+ $[31] = t10;
226
+ } else {
227
+ t10 = $[31];
228
+ }
229
+ t9 = referenceTokens([...draft.chats, ...draft.references], referables.items, draft.referenceNames).map(t10);
230
+ $[25] = draft.chats;
231
+ $[26] = draft.referenceNames;
232
+ $[27] = draft.references;
233
+ $[28] = referables.items;
234
+ $[29] = t9;
235
+ } else {
236
+ t9 = $[29];
237
+ }
238
+ const referenceChips = t9;
239
+ const listId = useId();
240
+ const menuOpen = commandMenuOpen || skillMenuOpen || mentionMenuOpen || referenceMenuOpen;
241
+ const menuCount = commandMenuOpen ? commands.length : skillMenuOpen ? skillMatches.length : mentionMenuOpen ? mentionCount : referenceMatches.length;
242
+ const activeIndex = clampMenuIndex(menuIndex, menuCount);
243
+ const inputAria = composerMenuAria({
244
+ label,
245
+ listId,
246
+ open: menuOpen,
247
+ activeIndex,
248
+ count: menuCount
249
+ });
250
+ let t10;
251
+ if ($[32] !== cwd || $[33] !== draft.mentions || $[34] !== draft.skills || $[35] !== referenceChips) {
252
+ t10 = (value, selection, state) => {
253
+ const empty = selection.from === selection.to;
254
+ const tree = empty ? ensureSyntaxTree(state, selection.from, 50) ?? syntaxTree(state) : null;
255
+ const caret = tree !== null && !inCode(tree, value, selection.from) ? selection.from : null;
256
+ const chips = caret === null ? [] : chipRanges(value, draft.mentions, draft.skills, [], referenceChips);
257
+ const skill_1 = caret === null ? null : queryOutsideChips(findSkillQuery(value, caret), chips);
258
+ setSkillQuery(current => sameQuery(current, skill_1) ? current : skill_1);
259
+ const next = caret === null || cwd === null ? null : queryOutsideChips(findMentionQuery(value, caret), chips);
260
+ setMention(current_0 => sameQuery(current_0, next) ? current_0 : next);
261
+ const reference = caret === null ? null : queryOutsideChips(findReferenceQuery(value, caret), chips);
262
+ setReferenceQuery(current_1 => sameQuery(current_1, reference) ? current_1 : reference);
263
+ };
264
+ $[32] = cwd;
265
+ $[33] = draft.mentions;
266
+ $[34] = draft.skills;
267
+ $[35] = referenceChips;
268
+ $[36] = t10;
269
+ } else {
270
+ t10 = $[36];
271
+ }
272
+ const trackTriggers = t10;
273
+ let t11;
274
+ if ($[37] !== inputRef) {
275
+ t11 = caret_0 => {
276
+ requestAnimationFrame(() => inputRef.current?.setCaret(caret_0));
277
+ };
278
+ $[37] = inputRef;
279
+ $[38] = t11;
280
+ } else {
281
+ t11 = $[38];
282
+ }
283
+ const moveCaret = t11;
284
+ let t12;
285
+ if ($[39] === Symbol.for("react.memo_cache_sentinel")) {
286
+ t12 = () => {
287
+ setMention(null);
288
+ setSkillQuery(null);
289
+ setReferenceQuery(null);
290
+ };
291
+ $[39] = t12;
292
+ } else {
293
+ t12 = $[39];
294
+ }
295
+ const close = t12;
296
+ let t13;
297
+ if ($[40] !== draft.mentions || $[41] !== mention || $[42] !== moveCaret || $[43] !== setText || $[44] !== text) {
298
+ t13 = path => {
299
+ if (!mention) {
300
+ return;
301
+ }
302
+ const result = insertMention(text, mention, path);
303
+ setText(result.text, draft.mentions.includes(path) ? draft.mentions : [...draft.mentions, path]);
304
+ setMention(null);
305
+ moveCaret(result.caret);
306
+ };
307
+ $[40] = draft.mentions;
308
+ $[41] = mention;
309
+ $[42] = moveCaret;
310
+ $[43] = setText;
311
+ $[44] = text;
312
+ $[45] = t13;
313
+ } else {
314
+ t13 = $[45];
315
+ }
316
+ const chooseMention = t13;
317
+ let t14;
318
+ if ($[46] !== chooseMention || $[47] !== mention || $[48] !== searched) {
319
+ t14 = index => {
320
+ const path_0 = mention === null ? null : mentionPick(index, searched, mention.query);
321
+ if (path_0 !== null) {
322
+ chooseMention(path_0);
323
+ }
324
+ };
325
+ $[46] = chooseMention;
326
+ $[47] = mention;
327
+ $[48] = searched;
328
+ $[49] = t14;
329
+ } else {
330
+ t14 = $[49];
331
+ }
332
+ const chooseMentionAt = t14;
333
+ let t15;
334
+ if ($[50] !== moveCaret || $[51] !== referenceQuery || $[52] !== setDraft || $[53] !== text) {
335
+ t15 = item_1 => {
336
+ if (!referenceQuery) {
337
+ return;
338
+ }
339
+ const result_0 = insertReference(text, referenceQuery, item_1.name);
340
+ const chat = item_1.kind === "chat";
341
+ const add = ids => ids.includes(item_1.id) ? ids : [...ids, item_1.id];
342
+ setDraft(current_2 => ({
343
+ ...current_2,
344
+ text: result_0.text,
345
+ chats: chat ? add(current_2.chats) : current_2.chats,
346
+ references: chat ? current_2.references : add(current_2.references),
347
+ referenceNames: {
348
+ ...current_2.referenceNames,
349
+ [item_1.id]: item_1.name
350
+ }
351
+ }));
352
+ setReferenceQuery(null);
353
+ moveCaret(result_0.caret);
354
+ };
355
+ $[50] = moveCaret;
356
+ $[51] = referenceQuery;
357
+ $[52] = setDraft;
358
+ $[53] = text;
359
+ $[54] = t15;
360
+ } else {
361
+ t15 = $[54];
362
+ }
363
+ const chooseReference = t15;
364
+ let t16;
365
+ if ($[55] !== chooseReference || $[56] !== referenceMatches) {
366
+ t16 = index_0 => {
367
+ const item_2 = referenceMatches[index_0] ?? referenceMatches[0];
368
+ if (item_2 !== undefined) {
369
+ chooseReference(item_2);
370
+ }
371
+ };
372
+ $[55] = chooseReference;
373
+ $[56] = referenceMatches;
374
+ $[57] = t16;
375
+ } else {
376
+ t16 = $[57];
377
+ }
378
+ const chooseReferenceAt = t16;
379
+ let t17;
380
+ if ($[58] !== draft.mentions || $[59] !== draft.skills || $[60] !== moveCaret || $[61] !== setText || $[62] !== skillQuery || $[63] !== text) {
381
+ t17 = name_2 => {
382
+ const result_1 = skillQuery ? insertSkill(text, skillQuery, name_2) : {
383
+ text: `$${name_2} `,
384
+ caret: name_2.length + 2
385
+ };
386
+ setText(result_1.text, draft.mentions, draft.skills.includes(name_2) ? draft.skills : [...draft.skills, name_2]);
387
+ setSkillQuery(null);
388
+ moveCaret(result_1.caret);
389
+ };
390
+ $[58] = draft.mentions;
391
+ $[59] = draft.skills;
392
+ $[60] = moveCaret;
393
+ $[61] = setText;
394
+ $[62] = skillQuery;
395
+ $[63] = text;
396
+ $[64] = t17;
397
+ } else {
398
+ t17 = $[64];
399
+ }
400
+ const chooseSkill = t17;
401
+ let t18;
402
+ if ($[65] !== chooseSkill || $[66] !== inputRef || $[67] !== setText) {
403
+ t18 = (command_0, index_1) => {
404
+ setMenuIndex(index_1);
405
+ if (command_0.skill) {
406
+ chooseSkill(command_0.name);
407
+ return;
408
+ }
409
+ setText(`/${command_0.name}`);
410
+ inputRef.current?.focus();
411
+ };
412
+ $[65] = chooseSkill;
413
+ $[66] = inputRef;
414
+ $[67] = setText;
415
+ $[68] = t18;
416
+ } else {
417
+ t18 = $[68];
418
+ }
419
+ const pickCommand = t18;
420
+ let t19;
421
+ if ($[69] !== chooseSkill || $[70] !== setText) {
422
+ t19 = command_1 => {
423
+ if (command_1.skill) {
424
+ chooseSkill(command_1.name);
425
+ return;
426
+ }
427
+ setText(`/${command_1.name} `);
428
+ };
429
+ $[69] = chooseSkill;
430
+ $[70] = setText;
431
+ $[71] = t19;
432
+ } else {
433
+ t19 = $[71];
434
+ }
435
+ const completeCommand = t19;
436
+ let t20;
437
+ if ($[72] === Symbol.for("react.memo_cache_sentinel")) {
438
+ t20 = (key, count) => {
439
+ if (key === "ArrowDown") {
440
+ setMenuIndex(i => (i + 1) % count);
441
+ return true;
442
+ }
443
+ if (key === "ArrowUp") {
444
+ setMenuIndex(i_0 => (i_0 - 1 + count) % count);
445
+ return true;
446
+ }
447
+ return false;
448
+ };
449
+ $[72] = t20;
450
+ } else {
451
+ t20 = $[72];
452
+ }
453
+ const moveInMenu = t20;
454
+ const t21 = skills.length > 0;
455
+ let t22;
456
+ if ($[73] !== skills) {
457
+ t22 = skills.map(_temp3);
458
+ $[73] = skills;
459
+ $[74] = t22;
460
+ } else {
461
+ t22 = $[74];
462
+ }
463
+ let t23;
464
+ if ($[75] !== activeIndex || $[76] !== chooseMention || $[77] !== chooseMentionAt || $[78] !== chooseReference || $[79] !== chooseReferenceAt || $[80] !== chooseSkill || $[81] !== commandMenuOpen || $[82] !== commandQuery || $[83] !== commands || $[84] !== completeCommand || $[85] !== files_0 || $[86] !== inputAria || $[87] !== listId || $[88] !== mention || $[89] !== mentionCount || $[90] !== mentionMenuOpen || $[91] !== menuOpen || $[92] !== pickCommand || $[93] !== referables || $[94] !== referenceChips || $[95] !== referenceMatches || $[96] !== referenceMenuOpen || $[97] !== skillMatches || $[98] !== skillMenuOpen || $[99] !== t21 || $[100] !== t22 || $[101] !== trackTriggers) {
465
+ t23 = {
466
+ listId,
467
+ activeIndex,
468
+ inputAria,
469
+ menuOpen,
470
+ hasSkills: t21,
471
+ skillNames: t22,
472
+ commandQuery,
473
+ commands,
474
+ commandMenuOpen,
475
+ skillMatches,
476
+ skillMenuOpen,
477
+ mention,
478
+ mentionMenuOpen,
479
+ mentionCount,
480
+ files: files_0,
481
+ referenceMenuOpen,
482
+ referenceMatches,
483
+ referables,
484
+ referenceChips,
485
+ setMenuIndex,
486
+ trackTriggers,
487
+ close,
488
+ chooseMention,
489
+ chooseMentionAt,
490
+ chooseReference,
491
+ chooseReferenceAt,
492
+ chooseSkill,
493
+ pickCommand,
494
+ completeCommand,
495
+ moveInMenu
496
+ };
497
+ $[75] = activeIndex;
498
+ $[76] = chooseMention;
499
+ $[77] = chooseMentionAt;
500
+ $[78] = chooseReference;
501
+ $[79] = chooseReferenceAt;
502
+ $[80] = chooseSkill;
503
+ $[81] = commandMenuOpen;
504
+ $[82] = commandQuery;
505
+ $[83] = commands;
506
+ $[84] = completeCommand;
507
+ $[85] = files_0;
508
+ $[86] = inputAria;
509
+ $[87] = listId;
510
+ $[88] = mention;
511
+ $[89] = mentionCount;
512
+ $[90] = mentionMenuOpen;
513
+ $[91] = menuOpen;
514
+ $[92] = pickCommand;
515
+ $[93] = referables;
516
+ $[94] = referenceChips;
517
+ $[95] = referenceMatches;
518
+ $[96] = referenceMenuOpen;
519
+ $[97] = skillMatches;
520
+ $[98] = skillMenuOpen;
521
+ $[99] = t21;
522
+ $[100] = t22;
523
+ $[101] = trackTriggers;
524
+ $[102] = t23;
525
+ } else {
526
+ t23 = $[102];
527
+ }
528
+ return t23;
529
+ }
530
+ function _temp3(skill_2) {
531
+ return skill_2.name;
532
+ }
533
+ function _temp2(skill) {
534
+ return skill.name;
535
+ }
536
+ function _temp() {}
@@ -13,6 +13,9 @@ export { ImageThumb, type ImageThumbProps } from './ImageView.js';
13
13
  export { LimitDock, LimitPill } from './LimitState.js';
14
14
  export { ReplyMarkdown, MessageMarkdown, Markdown } from './Markdown.js';
15
15
  export { ModelPicker } from './Pickers.js';
16
+ export { PromptEditor } from './PromptEditor.js';
17
+ export { promptPicks } from './composer/prompt-picks.js';
18
+ export type { PromptDraft } from './composer/use-prompt-menus.js';
16
19
  export { ResumeCompactionDock } from './ResumeCompactionDock.js';
17
20
  export { SubagentTitleCrumb, SubagentBreadcrumb } from './SubagentControls.js';
18
21
  export { SubagentInfo } from './SubagentInfo.js';
@@ -21,6 +24,7 @@ export { Timeline } from './Timeline.js';
21
24
  export { TimelineMenuPopup } from './TimelineMenu.js';
22
25
  export { default as UnifiedDiff } from './UnifiedDiff.js';
23
26
  export { UploadThumb } from './UploadThumb.js';
27
+ export { VisualPageFrame, type VisualPageFrameProps } from './VisualFrame.js';
24
28
  export { WelcomeGreeting } from './Welcome.js';
25
29
  export { externalChange, composerEditorExtensions } from './composer/editor.js';
26
30
  export { createDiffSyntaxRuntime, diffSyntaxRuntime, type DiffSyntaxRuntime, type DiffSyntaxRuntimeOptions, type DiffSyntaxSession, type DiffSyntaxMapping, type DiffSourceTokenSession, diffSourceTokens } from './diff-syntax.js';
@@ -14,6 +14,8 @@ export { ImageThumb } from './ImageView.js';
14
14
  export { LimitDock, LimitPill } from './LimitState.js';
15
15
  export { ReplyMarkdown, MessageMarkdown, Markdown } from './Markdown.js';
16
16
  export { ModelPicker } from './Pickers.js';
17
+ export { PromptEditor } from './PromptEditor.js';
18
+ export { promptPicks } from './composer/prompt-picks.js';
17
19
  export { ResumeCompactionDock } from './ResumeCompactionDock.js';
18
20
  export { SubagentTitleCrumb, SubagentBreadcrumb } from './SubagentControls.js';
19
21
  export { SubagentInfo } from './SubagentInfo.js';
@@ -22,6 +24,7 @@ export { Timeline } from './Timeline.js';
22
24
  export { TimelineMenuPopup } from './TimelineMenu.js';
23
25
  export { default as UnifiedDiff } from './UnifiedDiff.js';
24
26
  export { UploadThumb } from './UploadThumb.js';
27
+ export { VisualPageFrame } from './VisualFrame.js';
25
28
  export { WelcomeGreeting } from './Welcome.js';
26
29
  export { externalChange, composerEditorExtensions } from './composer/editor.js';
27
30
  export { createDiffSyntaxRuntime, diffSyntaxRuntime, diffSourceTokens } from './diff-syntax.js';
@@ -12,6 +12,7 @@ import { attachmentAspect, generatedImageView } from '../../logic/generated-imag
12
12
  import { toolStartedAt } from '../../logic/tools.js';
13
13
  import { CHIP_IN_MESSAGE, MENTION_TONE } from '../chips.js';
14
14
  import { useFileLinkCwd, useOpenFileLink } from '../file-links.js';
15
+ import { HostMenuItems } from '../HostMenuItems.js';
15
16
  import { ImageThumb } from '../ImageView.js';
16
17
  import { ROW_GUTTER } from '../icons.js';
17
18
  import { RunningFor, WorkRow } from './WorkRows.js';
@@ -299,6 +300,7 @@ function ReadyImage({
299
300
  open,
300
301
  saveToProject
301
302
  } = attachments;
303
+ const extra = attachments.actions?.(scopeId, chatId, attachment) ?? [];
302
304
  const detail = [attachment.width !== undefined && attachment.height !== undefined ? t('generatedImage.dimensions', {
303
305
  width: attachment.width,
304
306
  height: attachment.height
@@ -359,21 +361,23 @@ function ReadyImage({
359
361
  size: "sm",
360
362
  label: t('generatedImage.openLarge'),
361
363
  onClick: () => setLightbox(true)
362
- }), prompt !== null && /*#__PURE__*/_jsxs(Menu.Root, {
364
+ }), (prompt !== null || extra.length > 0) && /*#__PURE__*/_jsxs(Menu.Root, {
363
365
  children: [/*#__PURE__*/_jsx(IconButton, {
364
366
  icon: Ellipsis,
365
367
  size: "sm",
366
368
  label: t('generatedImage.more'),
367
369
  render: /*#__PURE__*/_jsx(Menu.Trigger, {})
368
- }), /*#__PURE__*/_jsx(Menu.Popup, {
370
+ }), /*#__PURE__*/_jsxs(Menu.Popup, {
369
371
  align: "end",
370
- children: /*#__PURE__*/_jsxs(Menu.Item, {
372
+ children: [prompt !== null && /*#__PURE__*/_jsxs(Menu.Item, {
371
373
  onClick: () => copyText(prompt),
372
374
  children: [/*#__PURE__*/_jsx(Icon, {
373
375
  icon: Copy,
374
376
  size: 14
375
377
  }), " ", t('generatedImage.copyPrompt')]
376
- })
378
+ }), /*#__PURE__*/_jsx(HostMenuItems, {
379
+ actions: extra
380
+ })]
377
381
  })]
378
382
  })]
379
383
  })