@lemonriver/core 0.1.0 → 0.2.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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{build-f-fM2ZY4.js → build-Df_xwIpg.js} +1 -1
  3. package/dist/cli/bin.js +4 -4
  4. package/dist/{config-DO45GU3e.js → config-BjWCLoMQ.js} +2343 -363
  5. package/dist/{config-B6JaKJM4.d.ts → config-rMGCkz6i.d.ts} +6 -2
  6. package/dist/{dev-CqS2xpgE.js → dev-Ctsx9IeO.js} +2 -2
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +4 -3
  9. package/dist/locale/index.d.ts +5 -2
  10. package/dist/locale/index.js +2 -2
  11. package/dist/{preview-BihgMlEl.js → preview-CJgcqsPk.js} +1 -1
  12. package/dist/{types-BjW4glip.d.ts → types-8VUyA2bu.d.ts} +133 -5
  13. package/dist/{update-C_R0ycVC.js → update-BKOA3Z6o.js} +153 -21
  14. package/dist/vite/index.d.ts +1 -1
  15. package/dist/vite/index.js +1 -1
  16. package/dist/{zh-tw-Ci0jK8eg.js → zh-tw-CeLrYwRE.js} +1178 -25
  17. package/package.json +21 -15
  18. package/skills/apply-comments/SKILL.md +10 -6
  19. package/skills/create-slide/SKILL.md +2 -0
  20. package/skills/current-slide/SKILL.md +1 -0
  21. package/skills/slide-authoring/SKILL.md +31 -1
  22. package/src/agent/prompt.ts +141 -0
  23. package/src/agent/provider.ts +123 -0
  24. package/src/agent/types.ts +151 -0
  25. package/src/app/app.tsx +2 -0
  26. package/src/app/assets/open-slide.svg +39 -0
  27. package/src/app/components/agent/agent-dock.tsx +35 -0
  28. package/src/app/components/agent/agent-markdown.tsx +45 -0
  29. package/src/app/components/agent/agent-panel.tsx +692 -0
  30. package/src/app/components/agent/agent-presence.tsx +74 -0
  31. package/src/app/components/agent/composer.tsx +120 -0
  32. package/src/app/components/agent/connect-view.tsx +184 -0
  33. package/src/app/components/agent/history-view.tsx +135 -0
  34. package/src/app/components/agent/provider-logo.tsx +34 -0
  35. package/src/app/components/agent/transcript.tsx +609 -0
  36. package/src/app/components/board/board-canvas.tsx +143 -12
  37. package/src/app/components/board/board.css +51 -0
  38. package/src/app/components/board/layout.test.ts +53 -1
  39. package/src/app/components/board/layout.ts +50 -2
  40. package/src/app/components/board/page-node.tsx +287 -13
  41. package/src/app/components/board/use-board-cards.ts +210 -0
  42. package/src/app/components/board/use-page-order.ts +17 -9
  43. package/src/app/components/command/slide-command-menu.tsx +10 -0
  44. package/src/app/components/icon-switcher-indicator.tsx +1 -1
  45. package/src/app/components/inspector/comment-layer.tsx +1011 -0
  46. package/src/app/components/inspector/image-crop-dialog.tsx +1 -5
  47. package/src/app/components/inspector/inspect-overlay.tsx +2 -39
  48. package/src/app/components/inspector/inspector-panel.tsx +10 -93
  49. package/src/app/components/inspector/inspector-provider.tsx +121 -47
  50. package/src/app/components/panel/editor-sidebar.tsx +85 -16
  51. package/src/app/components/panel/panel-shell.tsx +2 -2
  52. package/src/app/components/panel/resize-handle.tsx +129 -0
  53. package/src/app/components/player.tsx +0 -1
  54. package/src/app/components/preview-step-host.tsx +16 -0
  55. package/src/app/components/sidebar/sidebar.tsx +2 -2
  56. package/src/app/components/style-panel/style-panel.tsx +3 -2
  57. package/src/app/components/thumbnail-rail.tsx +76 -1
  58. package/src/app/favicon.ico +0 -0
  59. package/src/app/favicon.svg +39 -0
  60. package/src/app/index.html +2 -1
  61. package/src/app/lib/agent/use-agent.ts +543 -0
  62. package/src/app/lib/inspector/freeze-motion.ts +61 -0
  63. package/src/app/lib/inspector/use-comments.ts +32 -3
  64. package/src/app/lib/locale-store.ts +6 -1
  65. package/src/app/lib/print-ready.ts +9 -6
  66. package/src/app/lib/use-auto-grow.ts +15 -0
  67. package/src/app/lib/utils.ts +4 -0
  68. package/src/app/routes/board.tsx +48 -11
  69. package/src/app/routes/home.tsx +43 -7
  70. package/src/app/routes/presenter.tsx +1 -16
  71. package/src/app/routes/preview.tsx +169 -0
  72. package/src/app/routes/slide.tsx +221 -173
  73. package/src/app/styles.css +234 -80
  74. package/src/editing/placeholder-id.ts +1 -0
  75. package/src/locale/en.ts +127 -5
  76. package/src/locale/es.ts +692 -0
  77. package/src/locale/index.ts +1 -0
  78. package/src/locale/ja.ts +120 -6
  79. package/src/locale/types.ts +132 -5
  80. package/src/locale/zh-cn.ts +117 -5
  81. package/src/locale/zh-tw.ts +117 -5
  82. package/src/app/assets/open-slide.png +0 -0
  83. package/src/app/components/inspector/comment-widget.tsx +0 -119
@@ -222,109 +222,93 @@
222
222
  }
223
223
 
224
224
  /*
225
- * Comment input cue — kept from the original design but retoned to match
226
- * the new palette (warm vermillion + amber instead of the AI-classic
227
- * blue/violet halo). Plays once on first open, then settles.
225
+ * Indeterminate "line loader" — a hairline track with a short bar that
226
+ * glides back and forth. Used for full-screen loading states in place of
227
+ * a spinner; quieter, more typographic, easier on the eye.
228
228
  */
229
- @property --comment-cue-angle {
230
- syntax: "<angle>";
231
- initial-value: 0deg;
232
- inherits: false;
229
+ /* Comment-mode hint pill: the shell materializes once, then every text
230
+ swap blurs the old copy out while the new one blurs in. */
231
+ @keyframes island-enter {
232
+ from {
233
+ opacity: 0;
234
+ filter: blur(6px);
235
+ transform: translateY(6px) scale(0.9);
236
+ }
233
237
  }
234
238
 
235
- .comment-cue {
236
- position: relative;
237
- isolation: isolate;
239
+ @keyframes island-arrive {
240
+ from {
241
+ opacity: 0;
242
+ filter: blur(6px);
243
+ transform: scale(0.94);
244
+ }
238
245
  }
239
246
 
240
- .comment-cue::before {
241
- content: "";
242
- position: absolute;
243
- inset: -1px;
244
- border-radius: calc(var(--radius-md) + 1px);
245
- padding: 1.25px;
246
- background: conic-gradient(
247
- from var(--comment-cue-angle),
248
- transparent 0deg,
249
- transparent 250deg,
250
- oklch(0.78 0.14 60 / 0.55) 295deg,
251
- oklch(0.62 0.2 28 / 0.85) 325deg,
252
- oklch(0.78 0.14 60 / 0.55) 350deg,
253
- transparent 360deg
254
- );
255
- -webkit-mask:
256
- linear-gradient(#000 0 0) content-box,
257
- linear-gradient(#000 0 0);
258
- -webkit-mask-composite: xor;
259
- mask:
260
- linear-gradient(#000 0 0) content-box,
261
- linear-gradient(#000 0 0);
262
- mask-composite: exclude;
263
- pointer-events: none;
264
- opacity: 0;
265
- z-index: 1;
266
- animation: comment-cue-trace 1500ms cubic-bezier(0.22, 0.61, 0.36, 1) 220ms 1 both;
247
+ @keyframes island-leave {
248
+ to {
249
+ opacity: 0;
250
+ filter: blur(6px);
251
+ transform: scale(0.94);
252
+ }
267
253
  }
268
254
 
269
- .comment-cue::after {
270
- content: "";
271
- position: absolute;
272
- inset: -10px;
273
- border-radius: calc(var(--radius-md) + 10px);
274
- background:
275
- radial-gradient(80% 60% at 30% 50%, oklch(0.62 0.2 28 / 0.18), transparent 70%),
276
- radial-gradient(70% 60% at 75% 60%, oklch(0.78 0.14 60 / 0.16), transparent 70%);
277
- filter: blur(14px);
278
- opacity: 0;
279
- z-index: -1;
255
+ .island-enter {
256
+ animation: island-enter 420ms cubic-bezier(0.32, 0.72, 0, 1) both;
257
+ }
258
+
259
+ .island-arrive {
260
+ animation: island-arrive 320ms cubic-bezier(0.32, 0.72, 0, 1) both;
261
+ }
262
+
263
+ .island-leave {
280
264
  pointer-events: none;
281
- animation: comment-cue-halo 1700ms ease-out 180ms 1 both;
265
+ animation: island-leave 320ms cubic-bezier(0.32, 0.72, 0, 1) both;
282
266
  }
283
267
 
284
- @keyframes comment-cue-trace {
285
- 0% {
286
- --comment-cue-angle: 0deg;
287
- opacity: 0;
288
- }
289
- 18% {
290
- opacity: 1;
291
- }
292
- 82% {
293
- opacity: 1;
294
- }
295
- 100% {
296
- --comment-cue-angle: 360deg;
268
+ /* Counter digits roll in the direction of the change (--roll: 1 up, -1 down). */
269
+ @keyframes roll-arrive {
270
+ from {
297
271
  opacity: 0;
272
+ transform: translateY(calc(var(--roll, 1) * 100%));
298
273
  }
299
274
  }
300
275
 
301
- @keyframes comment-cue-halo {
302
- 0% {
303
- opacity: 0;
304
- transform: scale(0.97);
305
- }
306
- 40% {
307
- opacity: 1;
308
- transform: scale(1);
309
- }
310
- 100% {
276
+ @keyframes roll-leave {
277
+ to {
311
278
  opacity: 0;
312
- transform: scale(1.015);
279
+ transform: translateY(calc(var(--roll, 1) * -100%));
313
280
  }
314
281
  }
315
282
 
283
+ .roll-arrive {
284
+ animation: roll-arrive 320ms cubic-bezier(0.32, 0.72, 0, 1) both;
285
+ }
286
+
287
+ .roll-leave {
288
+ pointer-events: none;
289
+ animation: roll-leave 320ms cubic-bezier(0.32, 0.72, 0, 1) both;
290
+ }
291
+
316
292
  @media (prefers-reduced-motion: reduce) {
317
- .comment-cue::before,
318
- .comment-cue::after {
293
+ .island-enter,
294
+ .island-arrive {
295
+ animation: island-arrive 160ms ease-out both;
296
+ filter: none;
297
+ transform: none;
298
+ }
299
+
300
+ .island-leave,
301
+ .roll-leave {
319
302
  animation: none;
303
+ opacity: 0;
304
+ }
305
+
306
+ .roll-arrive {
307
+ animation: island-arrive 160ms ease-out both;
308
+ transform: none;
320
309
  }
321
310
  }
322
311
 
323
- /*
324
- * Indeterminate "line loader" — a hairline track with a short bar that
325
- * glides back and forth. Used for full-screen loading states in place of
326
- * a spinner; quieter, more typographic, easier on the eye.
327
- */
328
312
  @keyframes osd-line-loader {
329
313
  0% {
330
314
  transform: translateX(0%);
@@ -399,3 +383,173 @@
399
383
  background-clip: content-box;
400
384
  }
401
385
  }
386
+
387
+ /* Agent presence: ring, write sweep and shimmer shown while an agent edits a deck. */
388
+ @property --agent-angle {
389
+ syntax: "<angle>";
390
+ inherits: false;
391
+ initial-value: 0deg;
392
+ }
393
+
394
+ [data-agent-provider] {
395
+ --agent-a: oklch(0.68 0.14 42);
396
+ --agent-b: oklch(0.82 0.12 75);
397
+ }
398
+
399
+ [data-agent-provider="codex"] {
400
+ --agent-a: oklch(0.64 0.13 170);
401
+ --agent-b: oklch(0.7 0.14 240);
402
+ }
403
+
404
+ @keyframes agent-spin {
405
+ to {
406
+ --agent-angle: 360deg;
407
+ }
408
+ }
409
+
410
+ @keyframes agent-fade-in {
411
+ from {
412
+ opacity: 0;
413
+ }
414
+ }
415
+
416
+ .agent-ring {
417
+ pointer-events: none;
418
+ position: absolute;
419
+ inset: 0;
420
+ border-radius: inherit;
421
+ padding: 1.5px;
422
+ background: conic-gradient(
423
+ from var(--agent-angle),
424
+ transparent 0deg,
425
+ var(--agent-a) 70deg,
426
+ var(--agent-b) 140deg,
427
+ transparent 210deg,
428
+ transparent 360deg
429
+ );
430
+ mask:
431
+ linear-gradient(#000 0 0) content-box exclude,
432
+ linear-gradient(#000 0 0);
433
+ animation:
434
+ agent-spin 3.6s linear infinite,
435
+ agent-fade-in 400ms var(--ease-swift) both;
436
+ }
437
+
438
+ .agent-glow {
439
+ pointer-events: none;
440
+ position: absolute;
441
+ inset: 0;
442
+ border-radius: inherit;
443
+ box-shadow:
444
+ inset 0 0 0 1px color-mix(in oklch, var(--agent-a) 35%, transparent),
445
+ inset 0 0 48px -12px color-mix(in oklch, var(--agent-a) 45%, transparent);
446
+ animation: agent-fade-in 400ms var(--ease-swift) both;
447
+ }
448
+
449
+ @keyframes agent-sweep {
450
+ from {
451
+ background-position: 120% 0;
452
+ opacity: 1;
453
+ }
454
+ to {
455
+ background-position: -20% 0;
456
+ opacity: 0;
457
+ }
458
+ }
459
+
460
+ .agent-sweep {
461
+ pointer-events: none;
462
+ position: absolute;
463
+ inset: 0;
464
+ border-radius: inherit;
465
+ background: linear-gradient(
466
+ 105deg,
467
+ transparent 35%,
468
+ color-mix(in oklch, var(--agent-b) 22%, transparent) 50%,
469
+ transparent 65%
470
+ );
471
+ background-size: 250% 100%;
472
+ animation: agent-sweep 900ms var(--ease-swift) both;
473
+ }
474
+
475
+ @keyframes agent-shimmer {
476
+ from {
477
+ background-position: 100% 0;
478
+ }
479
+ to {
480
+ background-position: 0% 0;
481
+ }
482
+ }
483
+
484
+ .agent-shimmer {
485
+ background: linear-gradient(
486
+ 90deg,
487
+ var(--muted-foreground) 35%,
488
+ var(--foreground) 50%,
489
+ var(--muted-foreground) 65%
490
+ );
491
+ background-size: 300% 100%;
492
+ background-clip: text;
493
+ color: transparent;
494
+ animation: agent-shimmer 1.8s linear infinite;
495
+ }
496
+
497
+ @keyframes agent-progress {
498
+ from {
499
+ transform: translateX(-100%);
500
+ }
501
+ to {
502
+ transform: translateX(250%);
503
+ }
504
+ }
505
+
506
+ .agent-progress {
507
+ pointer-events: none;
508
+ position: absolute;
509
+ inset-inline: 0;
510
+ top: 0;
511
+ height: 1.5px;
512
+ overflow: hidden;
513
+ }
514
+
515
+ .agent-progress::after {
516
+ content: "";
517
+ position: absolute;
518
+ inset-block: 0;
519
+ width: 40%;
520
+ background: linear-gradient(90deg, transparent, var(--agent-a), var(--agent-b), transparent);
521
+ animation: agent-progress 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;
522
+ }
523
+
524
+ @media (prefers-reduced-motion: reduce) {
525
+ .agent-ring {
526
+ animation: agent-fade-in 160ms ease-out both;
527
+ --agent-angle: 120deg;
528
+ }
529
+
530
+ .agent-sweep {
531
+ display: none;
532
+ }
533
+
534
+ .agent-shimmer {
535
+ animation: none;
536
+ color: var(--foreground);
537
+ background: none;
538
+ }
539
+
540
+ .agent-progress::after {
541
+ animation: none;
542
+ width: 100%;
543
+ opacity: 0.6;
544
+ }
545
+ }
546
+
547
+ .sidebar-swap {
548
+ animation: agent-fade-in 160ms var(--ease-swift, ease-out);
549
+ }
550
+
551
+ @media (prefers-reduced-motion: reduce) {
552
+ .sidebar-swap {
553
+ animation: none;
554
+ }
555
+ }
@@ -0,0 +1 @@
1
+ export const UNTITLED_SLIDE_ID_RE = /^untitled(-\d+)?$/;
package/src/locale/en.ts CHANGED
@@ -96,6 +96,7 @@ export const en: Locale = {
96
96
  },
97
97
 
98
98
  slide: {
99
+ resizeSidePanel: 'Resize side panel',
99
100
  home: 'Home',
100
101
  backToHome: 'Back to home',
101
102
  agentConnected: 'Agent connected',
@@ -287,10 +288,9 @@ export const en: Locale = {
287
288
  cropFitCover: 'Fill',
288
289
  cropFitContain: 'Fit',
289
290
  cropApply: 'Apply',
290
- leaveComment: 'Comment',
291
+ commentMode: 'Comment',
291
292
  commentPlaceholder: 'Describe a change for the agent…',
292
- commentShortcutHint: '⌘/ to focus · ⌘↵ to add',
293
- addComment: 'Add comment',
293
+ commentPost: 'Post',
294
294
  unsavedChanges: {
295
295
  one: '{count} unsaved change',
296
296
  other: '{count} unsaved changes',
@@ -300,10 +300,14 @@ export const en: Locale = {
300
300
  other: '{count} comments',
301
301
  },
302
302
  commentLineLabel: 'line {n}',
303
- commentsEmpty: 'No comments yet. Select an object and open Comment in the Format panel.',
303
+ commentRegionLabel: 'region',
304
+ commentEmptyHint: 'Click an element or drag across a region to leave a comment.',
304
305
  commentsApplyHintPrefix: 'Run ',
305
306
  commentsApplyHintSuffix: ' in your agent to apply these.',
306
307
  commentDeleteAria: 'Delete',
308
+ commentUpdateFailed: "Couldn't update comment:",
309
+ commentAddFailed: "Couldn't add comment:",
310
+ commentRegionNoTarget: "Couldn't find an element to attach this region to.",
307
311
  saveFailed: "Couldn't save:",
308
312
  decreaseFontSize: 'Decrease font size',
309
313
  increaseFontSize: 'Increase font size',
@@ -454,7 +458,7 @@ export const en: Locale = {
454
458
  title: 'Story board',
455
459
  openBoard: 'Story board (B)',
456
460
  backToDeck: 'Back to deck',
457
- hint: 'Drag a card to reorder · Double-click to edit the page',
461
+ hint: 'Drag a card to reorder · Double-click to edit the page · Drag the dot to link two cards',
458
462
  loading: 'Loading deck…',
459
463
  columnFallback: 'Part {n}',
460
464
  moveToEnd: 'Move to end',
@@ -470,6 +474,19 @@ export const en: Locale = {
470
474
  /** template: "Added a blank page at {n}" */
471
475
  toastInserted: 'Added a blank page at {n}',
472
476
  insertFailed: 'Could not add a page',
477
+ cardTitlePlaceholder: 'Name this card',
478
+ renameCard: 'Rename this card',
479
+ status: 'Status',
480
+ statusNone: 'No status',
481
+ statusTodo: 'To do',
482
+ statusDoing: 'In progress',
483
+ statusReview: 'In review',
484
+ statusDone: 'Done',
485
+ memoPlaceholder: 'Work memo — stays on the board…',
486
+ linkHandle: 'Drag onto another card to link them',
487
+ showLinks: 'Show links',
488
+ hideLinks: 'Hide links',
489
+ removeLink: 'Remove this link',
473
490
  },
474
491
 
475
492
  pdfToast: {
@@ -559,4 +576,109 @@ export const en: Locale = {
559
576
  expandPromptAria: 'Expand prompt',
560
577
  collapsePromptAria: 'Collapse prompt',
561
578
  },
579
+
580
+ agent: {
581
+ title: 'Agent',
582
+ beta: 'Beta',
583
+ betaTitle: 'Early preview',
584
+ betaHint: 'Replies, edits and tool calls can occasionally fail or do something unexpected.',
585
+ open: 'Agent',
586
+ openTitle: 'Open the agent panel',
587
+ close: 'Close agent panel',
588
+ newSession: 'New chat',
589
+ sessions: 'History',
590
+ noSessions: 'No conversations yet.',
591
+ deleteSession: 'Delete conversation',
592
+ historyThisDeck: 'This deck',
593
+ historyOtherDecks: 'Other decks',
594
+ historyEmptyHint: 'Chats you start in this panel show up here.',
595
+ sessionRunning: 'Working',
596
+ composerPlaceholder: 'Ask {provider} to create or edit slides…',
597
+ send: 'Send',
598
+ stop: 'Stop',
599
+ working: 'Working',
600
+ contextPage: 'Page {n}',
601
+ contextSelection: 'Selection',
602
+ pendingComments: { one: '{count} comment', other: '{count} comments' },
603
+ applyComments: 'Apply comments',
604
+ applyCommentsWith: 'Apply with {provider}',
605
+ createDeck: 'New deck',
606
+ createDeckWith: 'Create a deck with {provider}',
607
+ quickCreate: 'Draft a new deck',
608
+ quickCreateHint: 'Opens a blank deck; describe it and the agent drafts it page by page.',
609
+ quickApply: 'Apply pending comments',
610
+ quickApplyHint: 'Resolves every @slide-comment marker in this slide.',
611
+ quickTheme: 'Create a theme',
612
+ quickThemeHint: 'Extracts or designs a reusable theme under themes/.',
613
+ quickEdit: 'Edit this page',
614
+ quickEditHint: 'Describe a change to the page you are viewing.',
615
+ emptyTitle: 'What should we build?',
616
+ emptyHint: 'Describe a deck, or pick a starting point.',
617
+ questionSubmit: 'Continue',
618
+ questionOther: 'Other',
619
+ questionOtherPlaceholder: 'Type your own answer',
620
+ questionCancelled: 'Dismissed',
621
+ permissionTitle: 'Needs approval',
622
+ allow: 'Allow',
623
+ deny: 'Deny',
624
+ allowed: 'Allowed',
625
+ denied: 'Denied',
626
+ autoApprove: 'Auto-approve',
627
+ autoApproveHint: 'Run commands without asking. Edits inside the workspace are always allowed.',
628
+ resultDone: 'Done',
629
+ resultStopped: 'Stopped',
630
+ resultSeconds: '{seconds}s',
631
+ errorEyebrow: 'Error',
632
+ statusLoading: 'Checking agents',
633
+ disabled: 'The agent panel is disabled in lemonriver.config.ts.',
634
+ connectTitle: 'Connect an agent',
635
+ connectDescription:
636
+ 'Drive your coding agent from here instead of a terminal. Agents installed on this machine connect automatically and reuse their sign-in.',
637
+ connect: 'Connect',
638
+ connecting: 'Connecting',
639
+ connected: 'Connected',
640
+ connectInstallHint: 'Adds {pkg} to this workspace with {pm}.',
641
+ cliFound: 'CLI found · v{version}',
642
+ cliFoundNoVersion: 'CLI found',
643
+ cliMissing: 'CLI not found on PATH',
644
+ cliHint: 'Install the {name} CLI and sign in once; the panel reuses its login.',
645
+ needCliTitle: 'Install Claude Code or Codex first',
646
+ needCliDescription:
647
+ 'The panel drives the coding agent CLI on this machine, and none was found on your PATH. Install one, sign in once in a terminal, then check again.',
648
+ checkAgain: 'Check again',
649
+ retry: 'Retry',
650
+ toastConnected: '{name} connected',
651
+ toastConnectFailed: 'Could not install {pkg}',
652
+ manageConnections: 'Manage agents',
653
+ backToChat: 'Back',
654
+ toastSendFailed: 'Could not send message',
655
+ newDeckTitle: "What's this deck about?",
656
+ newDeckHint:
657
+ 'Describe the topic, audience and tone. {provider} drafts it page by page while you watch.',
658
+ newDeckPlaceholder: 'A 10-minute talk on…',
659
+ toastCreateDeckFailed: 'Could not create a deck',
660
+ steps: { one: '{count} step', other: '{count} steps' },
661
+ questionSkip: 'Skip',
662
+ copyMessage: 'Copy',
663
+ copied: 'Copied',
664
+ editMessage: 'Edit',
665
+ cancelEdit: 'Cancel',
666
+ sendEdit: 'Send',
667
+ editHint:
668
+ 'Sending replaces the conversation after this message. Edits already made to files stay.',
669
+ modelDefault: 'Default',
670
+ reasoning: 'Reasoning',
671
+ effortAuto: 'Auto',
672
+ efforts: {
673
+ minimal: 'Minimal',
674
+ low: 'Low',
675
+ medium: 'Medium',
676
+ high: 'High',
677
+ xhigh: 'Extra high',
678
+ max: 'Max',
679
+ },
680
+ presenceEditing: '{provider} is editing',
681
+ presenceThinking: 'Thinking',
682
+ presenceWaiting: 'Waiting for you',
683
+ },
562
684
  };