@ykurilov/agent-chat-skin-tandem 0.63.2 → 0.65.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @ykurilov/agent-chat-skin-tandem
2
2
 
3
+ ## 0.65.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 814ee7f: Пометка «Агент написал первым — человек молчал 1 ч 7 мин» перед ответом, который агент написал сам. Ядро: право чата `appNotices` (по умолчанию выключено) — служебные пометки приложения (`kind: "app"`) уходят в историю без текста для модели и только через белый список `appNoticeViews` (имя → безопасные данные для экрана; без функции пометка не уходит); `modelDetails: false` выключает и `appNotices`. React: `noticeLines` у `AgentChat` (имя пометки → строка), договор скина 27 — необязательный `ServiceLine`. Сценарии: в данных пометки `silentMs` (от последнего сообщения человека) и `exit`, проекция для экрана регистрируется в `withChat`, готовые строки `flowNoticeLines()` с подписями `russianFlowNoticeLabels`/`englishFlowNoticeLabels` (`FlowLabels.notices`); `FlowTestChat` передаёт их в `renderChat(chatId, { noticeLines })`. Тандем рисует `ServiceLine`. Как подключить — CHANGES.md, раздел 0.65.0.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [814ee7f]
12
+ - @ykurilov/agent-chat-react@0.65.0
13
+ - @ykurilov/agent-chat-flows@0.65.0
14
+ - @ykurilov/agent-chat-mcp@0.65.0
15
+ - @ykurilov/agent-chat-messengers@0.65.0
16
+ - @ykurilov/agent-chat-sandbox@0.65.0
17
+ - @ykurilov/agent-chat-skills@0.65.0
18
+
19
+ ## 0.64.0
20
+
21
+ ### Minor Changes
22
+
23
+ - 1ea05c0: Тестовый чат: кнопка «К следующему напоминанию» проматывает часы ровно к моменту, когда сценарий сам напишет первым (касание, утреннее, выход по сроку, «срок вышел», «не завершил»; ночь и потолки учтены), и поле «своё время» («15 мин», «1 ч 30 мин», «2 дня»). Сервер: `flow.advanceTestClock({ ownerId, chatId, to: "next_first_message" })` → `{ timeOffset, reason }`, впереди ничего — `FlowTestClockError` с `code: "nothing_scheduled"`. Браузер: `FlowTestChatConnection.advanceToNextFirstMessage`. Разбор длительности — `parseDuration` из `/format`. Скин: необязательные `onNextFirstMessage`, `nothingScheduled`, `onAdvanceText` и пять надписей. Как подключить — CHANGES.md, раздел 0.64.0.
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [1ea05c0]
28
+ - Updated dependencies [99cded9]
29
+ - @ykurilov/agent-chat-flows@0.64.0
30
+ - @ykurilov/agent-chat-react@0.64.0
31
+ - @ykurilov/agent-chat-mcp@0.64.0
32
+ - @ykurilov/agent-chat-messengers@0.64.0
33
+ - @ykurilov/agent-chat-sandbox@0.64.0
34
+ - @ykurilov/agent-chat-skills@0.64.0
35
+
3
36
  ## 0.63.2
4
37
 
5
38
  ### Patch Changes
@@ -289,13 +289,44 @@ function TandemFlowBoardToggle({ kind, label, expanded, showText, onClick }) {
289
289
  import { Button as Button2, Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@tandem/ui";
290
290
  import { useFlowLabels as useFlowLabels4 } from "@ykurilov/agent-chat-flows/react";
291
291
  import { Check, Copy, Download, Upload } from "lucide-react";
292
- import { useRef, useState } from "react";
292
+ import { useRef, useState as useState2 } from "react";
293
293
 
294
294
  // src/flows/test-chat.tsx
295
- import { Button } from "@tandem/ui";
295
+ import { Button, Input } from "@tandem/ui";
296
296
  import { useFlowLabels as useFlowLabels3 } from "@ykurilov/agent-chat-flows/react";
297
- import { Clock as Clock3, RotateCcw, Sunrise, X } from "lucide-react";
297
+ import { BellRing, Clock as Clock3, RotateCcw, Sunrise, X } from "lucide-react";
298
+ import { useState } from "react";
298
299
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
300
+ function CustomTimeField({ onAdvanceText, busy }) {
301
+ const labels = useFlowLabels3().testChat;
302
+ const [text, setText] = useState("");
303
+ const [invalid, setInvalid] = useState(false);
304
+ return /* @__PURE__ */ jsxs3("div", { className: "w-full", children: [
305
+ /* @__PURE__ */ jsx3(
306
+ Input,
307
+ {
308
+ "aria-label": labels.customTime,
309
+ "aria-invalid": invalid,
310
+ placeholder: labels.customTimePlaceholder,
311
+ className: "h-8 w-full text-sm",
312
+ disabled: busy,
313
+ value: text,
314
+ onChange: (event) => {
315
+ setText(event.target.value);
316
+ setInvalid(false);
317
+ },
318
+ onKeyDown: (event) => {
319
+ if (event.key !== "Enter" || !text.trim()) return;
320
+ event.preventDefault();
321
+ const understood = onAdvanceText(text);
322
+ setInvalid(!understood);
323
+ if (understood) setText("");
324
+ }
325
+ }
326
+ ),
327
+ invalid && /* @__PURE__ */ jsx3("p", { className: "mt-1 text-xs text-[var(--destructive-text)]", children: labels.customTimeInvalid })
328
+ ] });
329
+ }
299
330
  function TandemFlowTestChatFrame(props) {
300
331
  const labels = useFlowLabels3().testChat;
301
332
  return /* @__PURE__ */ jsxs3("section", { "aria-label": labels.title, "data-flow-test-chat": "", className: "flex min-h-0 flex-1 flex-col", children: [
@@ -322,8 +353,14 @@ function TandemFlowTestChatFrame(props) {
322
353
  props.onNextDay && /* @__PURE__ */ jsxs3(Button, { variant: "secondary", size: "sm", disabled: props.busy, onClick: props.onNextDay, children: [
323
354
  /* @__PURE__ */ jsx3(Sunrise, { "aria-hidden": "true", className: "size-3.5" }),
324
355
  labels.nextDay
325
- ] })
356
+ ] }),
357
+ props.onNextFirstMessage && /* @__PURE__ */ jsxs3(Button, { variant: "secondary", size: "sm", disabled: props.busy, onClick: props.onNextFirstMessage, children: [
358
+ /* @__PURE__ */ jsx3(BellRing, { "aria-hidden": "true", className: "size-3.5" }),
359
+ labels.nextFirstMessage
360
+ ] }),
361
+ props.onAdvanceText && /* @__PURE__ */ jsx3(CustomTimeField, { onAdvanceText: props.onAdvanceText, busy: props.busy })
326
362
  ] }),
363
+ props.nothingScheduled && /* @__PURE__ */ jsx3("p", { role: "status", className: "mx-5 mt-2 rounded-[var(--radius-small)] bg-[var(--surface-muted)] px-3 py-2 text-xs text-[var(--foreground-muted)]", children: labels.nothingScheduled }),
327
364
  props.failed && /* @__PURE__ */ jsx3("p", { role: "alert", className: "mx-5 mt-2 rounded-[var(--radius-small)] bg-[color-mix(in_oklab,var(--destructive)_10%,transparent)] px-3 py-2 text-xs text-[var(--destructive-text)]", children: labels.failed }),
328
365
  /* @__PURE__ */ jsx3("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden", children: props.children })
329
366
  ] });
@@ -333,8 +370,8 @@ function TandemFlowTestChatFrame(props) {
333
370
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
334
371
  function TandemFlowJsonDialog(props) {
335
372
  const labels = useFlowLabels4().editor.jsonDialog;
336
- const [text, setText] = useState(props.json);
337
- const [copied, setCopied] = useState(false);
373
+ const [text, setText] = useState2(props.json);
374
+ const [copied, setCopied] = useState2(false);
338
375
  const file = useRef(null);
339
376
  const edited = text !== props.json;
340
377
  return /* @__PURE__ */ jsx4(Dialog, { open: true, onOpenChange: (open) => !open && props.onClose(), children: /* @__PURE__ */ jsxs4(DialogContent, { className: "flex max-h-[90vh] w-[min(760px,calc(100vw-24px))] max-w-none flex-col gap-3", children: [
@@ -397,7 +434,7 @@ function TandemFlowJsonDialog(props) {
397
434
  }
398
435
 
399
436
  // src/flows/flow-exit-card.tsx
400
- import { Input, Textarea, cn as cn3 } from "@tandem/ui";
437
+ import { Input as Input2, Textarea, cn as cn3 } from "@tandem/ui";
401
438
  import { useFlowLabels as useFlowLabels5 } from "@ykurilov/agent-chat-flows/react";
402
439
  import { ChevronDown, ChevronUp, Trash2 } from "lucide-react";
403
440
  import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
@@ -468,8 +505,8 @@ function TandemFlowExitCard(props) {
468
505
  /* @__PURE__ */ jsx5("option", { value: "state_days", children: `${labels.statePanel.duration}, ${labels.statePanel.durationUnits.d}` }),
469
506
  /* @__PURE__ */ jsx5("option", { value: "program_day", children: `${labels.statePanel.duration}, ${labels.statePanel.durationUnits.program_day}` })
470
507
  ] }) }),
471
- when.from === "time_of_day" ? /* @__PURE__ */ jsx5(Labeled, { label: labels.exitCard.at, children: /* @__PURE__ */ jsx5(Input, { type: "time", value: when.at, onChange: (event) => event.target.value && change({ ...when, at: event.target.value }) }) }) : when.from === "state_days" || when.from === "program_day" ? /* @__PURE__ */ jsx5(Labeled, { label: labels.exitCard.amount, children: /* @__PURE__ */ jsx5(
472
- Input,
508
+ when.from === "time_of_day" ? /* @__PURE__ */ jsx5(Labeled, { label: labels.exitCard.at, children: /* @__PURE__ */ jsx5(Input2, { type: "time", value: when.at, onChange: (event) => event.target.value && change({ ...when, at: event.target.value }) }) }) : when.from === "state_days" || when.from === "program_day" ? /* @__PURE__ */ jsx5(Labeled, { label: labels.exitCard.amount, children: /* @__PURE__ */ jsx5(
509
+ Input2,
473
510
  {
474
511
  type: "number",
475
512
  min: 1,
@@ -482,7 +519,7 @@ function TandemFlowExitCard(props) {
482
519
  }
483
520
  ) }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
484
521
  /* @__PURE__ */ jsx5(Labeled, { label: labels.exitCard.amount, children: /* @__PURE__ */ jsx5(
485
- Input,
522
+ Input2,
486
523
  {
487
524
  type: "number",
488
525
  min: 1,
@@ -531,7 +568,7 @@ function DataSettings(props) {
531
568
  /* @__PURE__ */ jsx5("option", { value: "" }),
532
569
  field.options.map((option) => /* @__PURE__ */ jsx5("option", { value: option, children: option }, option))
533
570
  ] }) }) : /* @__PURE__ */ jsx5(Labeled, { label: labels.exitCard.value, children: /* @__PURE__ */ jsx5(
534
- Input,
571
+ Input2,
535
572
  {
536
573
  value: String(when.value ?? ""),
537
574
  inputMode: field?.type === "number" ? "decimal" : void 0,
@@ -545,15 +582,15 @@ function DataSettings(props) {
545
582
  import { Badge, Button as Button4, TandemMark, cn as cn4 } from "@tandem/ui";
546
583
  import { useFlowLabels as useFlowLabels6 } from "@ykurilov/agent-chat-flows/react";
547
584
  import { Braces, Eye, IdCard, Maximize2, MessagesSquare, Minimize2, Play, Plus as Plus2, Save, ShieldCheck, Shuffle as Shuffle2 } from "lucide-react";
548
- import { useEffect as useEffect2, useState as useState3 } from "react";
585
+ import { useEffect as useEffect2, useState as useState4 } from "react";
549
586
 
550
587
  // src/flows/flow-header-menu.tsx
551
588
  import { Button as Button3 } from "@tandem/ui";
552
589
  import { Ellipsis } from "lucide-react";
553
- import { useEffect, useRef as useRef2, useState as useState2 } from "react";
590
+ import { useEffect, useRef as useRef2, useState as useState3 } from "react";
554
591
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
555
592
  function FlowHeaderMenu({ label, items, className }) {
556
- const [open, setOpen] = useState2(false);
593
+ const [open, setOpen] = useState3(false);
557
594
  const root = useRef2(null);
558
595
  const entries = () => [...root.current?.querySelectorAll('[role="menuitem"]:not([disabled])') ?? []];
559
596
  const close = (refocus) => {
@@ -675,7 +712,7 @@ function TandemFlowEditorFrame({ header, board, panel, dialog, className, style,
675
712
  );
676
713
  }
677
714
  function FlowName({ name, onRename, readOnly }) {
678
- const [draft, setDraft] = useState3(name);
715
+ const [draft, setDraft] = useState4(name);
679
716
  useEffect2(() => setDraft(name), [name]);
680
717
  const commit = () => {
681
718
  const next = draft.trim();
@@ -803,7 +840,7 @@ function TandemFlowHeader(props) {
803
840
  }
804
841
 
805
842
  // src/flows/flow-panels.tsx
806
- import { Badge as Badge2, Button as Button5, Input as Input2, Switch, Textarea as Textarea2, cn as cn5 } from "@tandem/ui";
843
+ import { Badge as Badge2, Button as Button5, Input as Input3, Switch, Textarea as Textarea2, cn as cn5 } from "@tandem/ui";
807
844
  import { useFlowLabels as useFlowLabels7 } from "@ykurilov/agent-chat-flows/react";
808
845
  import { ChevronDown as ChevronDown2, ChevronUp as ChevronUp2, CircleAlert, Flag as Flag2, Plus as Plus3, Trash2 as Trash22, TriangleAlert } from "lucide-react";
809
846
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
@@ -903,7 +940,7 @@ function TandemFlowStatePanel(props) {
903
940
  actions: /* @__PURE__ */ jsx8(IconButton, { label: labels.statePanel.deleteState, onClick: props.onDelete, tone: "danger", children: /* @__PURE__ */ jsx8(Trash22, { "aria-hidden": "true", className: "size-4" }) }),
904
941
  children: [
905
942
  /* @__PURE__ */ jsx8(IssueList, { issues: props.issues }),
906
- /* @__PURE__ */ jsx8(Labeled, { label: labels.statePanel.name, children: /* @__PURE__ */ jsx8(Input2, { value: props.title, onChange: (event) => onChange({ title: event.target.value }) }) }),
943
+ /* @__PURE__ */ jsx8(Labeled, { label: labels.statePanel.name, children: /* @__PURE__ */ jsx8(Input3, { value: props.title, onChange: (event) => onChange({ title: event.target.value }) }) }),
907
944
  /* @__PURE__ */ jsx8(Labeled, { label: labels.statePanel.instructions, hint: labels.statePanel.instructionsHint, children: /* @__PURE__ */ jsx8(Textarea2, { rows: 6, value: props.instructions, onChange: (event) => onChange({ instructions: event.target.value }) }) }),
908
945
  props.fields.length > 0 && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1.5", children: [
909
946
  /* @__PURE__ */ jsx8("span", { className: "text-sm font-medium text-[var(--foreground)]", children: labels.statePanel.learn }),
@@ -955,7 +992,7 @@ function TandemFlowStatePanel(props) {
955
992
  }
956
993
  )
957
994
  ] }),
958
- /* @__PURE__ */ jsx8(Labeled, { label: labels.statePanel.tags, children: /* @__PURE__ */ jsx8(Input2, { defaultValue: props.tags.join(", "), onBlur: (event) => onChange({ tags: splitList(event.target.value) }) }, props.tags.join(",")) }),
995
+ /* @__PURE__ */ jsx8(Labeled, { label: labels.statePanel.tags, children: /* @__PURE__ */ jsx8(Input3, { defaultValue: props.tags.join(", "), onBlur: (event) => onChange({ tags: splitList(event.target.value) }) }, props.tags.join(",")) }),
959
996
  /* @__PURE__ */ jsxs8("label", { className: "flex items-center justify-between gap-3 text-sm text-[var(--foreground)]", children: [
960
997
  labels.statePanel.noSideQuestions,
961
998
  /* @__PURE__ */ jsx8(Switch, { checked: props.noSideQuestions, onCheckedChange: (noSideQuestions) => onChange({ noSideQuestions }) })
@@ -998,7 +1035,7 @@ function TandemFlowFieldRow(props) {
998
1035
  ),
999
1036
  children: [
1000
1037
  /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1", children: [
1001
- /* @__PURE__ */ jsx8(Input2, { "aria-label": labels.name, value: field.name, onChange: (event) => onChange({ name: event.target.value }), className: "flex-1" }),
1038
+ /* @__PURE__ */ jsx8(Input3, { "aria-label": labels.name, value: field.name, onChange: (event) => onChange({ name: event.target.value }), className: "flex-1" }),
1002
1039
  /* @__PURE__ */ jsx8(IconButton, { label: exitLabels.moveUp, onClick: props.onMoveUp, disabled: !props.canMoveUp, children: /* @__PURE__ */ jsx8(ChevronUp2, { "aria-hidden": "true", className: "size-4" }) }),
1003
1040
  /* @__PURE__ */ jsx8(IconButton, { label: exitLabels.moveDown, onClick: props.onMoveDown, disabled: !props.canMoveDown, children: /* @__PURE__ */ jsx8(ChevronDown2, { "aria-hidden": "true", className: "size-4" }) }),
1004
1041
  /* @__PURE__ */ jsx8(IconButton, { label: exitLabels.delete, onClick: props.onDelete, tone: "danger", children: /* @__PURE__ */ jsx8(Trash22, { "aria-hidden": "true", className: "size-4" }) })
@@ -1019,7 +1056,7 @@ function TandemFlowFieldRow(props) {
1019
1056
  ) })
1020
1057
  ] }),
1021
1058
  field.type === "choice" && /* @__PURE__ */ jsx8(Labeled, { label: labels.options, hint: labels.optionsHint, children: /* @__PURE__ */ jsx8(
1022
- Input2,
1059
+ Input3,
1023
1060
  {
1024
1061
  defaultValue: field.options.join(", "),
1025
1062
  onBlur: (event) => onChange({ options: splitList(event.target.value) })
@@ -1085,7 +1122,7 @@ function TandemFlowCardPanel(props) {
1085
1122
  /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-2 text-sm text-[var(--foreground)]", children: [
1086
1123
  labels.pace,
1087
1124
  /* @__PURE__ */ jsx8(
1088
- Input2,
1125
+ Input3,
1089
1126
  {
1090
1127
  type: "number",
1091
1128
  min: 1,
@@ -1132,7 +1169,7 @@ function TandemFlowCheckPanel({ issues }) {
1132
1169
  }
1133
1170
 
1134
1171
  // src/flows/flow-days.tsx
1135
- import { Button as Button6, Input as Input3, Switch as Switch2, Textarea as Textarea3, cn as cn6 } from "@tandem/ui";
1172
+ import { Button as Button6, Input as Input4, Switch as Switch2, Textarea as Textarea3, cn as cn6 } from "@tandem/ui";
1136
1173
  import { DEFAULT_NUDGES, useFlowLabels as useFlowLabels8 } from "@ykurilov/agent-chat-flows/react";
1137
1174
  import { ChevronDown as ChevronDown3, Clock as Clock4, Plus as Plus4, Trash2 as Trash23, X as X2 } from "lucide-react";
1138
1175
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -1159,7 +1196,7 @@ function DurationInput({ label, value, onChange, onRemove }) {
1159
1196
  const remove = useFlowLabels8().editor.nudges.remove;
1160
1197
  return /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
1161
1198
  /* @__PURE__ */ jsx9(
1162
- Input3,
1199
+ Input4,
1163
1200
  {
1164
1201
  "aria-label": label,
1165
1202
  type: "number",
@@ -1205,7 +1242,7 @@ function TandemFlowNudgesEditor({ nudges, optional, onChange }) {
1205
1242
  /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-[var(--foreground)]", children: labels.dailyAt }),
1206
1243
  daily.map((at, index) => /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
1207
1244
  /* @__PURE__ */ jsx9(
1208
- Input3,
1245
+ Input4,
1209
1246
  {
1210
1247
  "aria-label": `${labels.dailyAt} ${index + 1}`,
1211
1248
  type: "time",
@@ -1242,9 +1279,9 @@ function TandemFlowScheduleSection(props) {
1242
1279
  /* @__PURE__ */ jsx9(IssueList, { issues: props.issues }),
1243
1280
  schedule && /* @__PURE__ */ jsxs9(Fragment2, { children: [
1244
1281
  /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-2 gap-2", children: [
1245
- /* @__PURE__ */ jsx9(Labeled, { label: text.dayStart, hint: text.dayStartHint, children: /* @__PURE__ */ jsx9(Input3, { type: "time", value: schedule.dayStart, onChange: (event) => event.target.value && onChange({ dayStart: event.target.value }) }) }),
1282
+ /* @__PURE__ */ jsx9(Labeled, { label: text.dayStart, hint: text.dayStartHint, children: /* @__PURE__ */ jsx9(Input4, { type: "time", value: schedule.dayStart, onChange: (event) => event.target.value && onChange({ dayStart: event.target.value }) }) }),
1246
1283
  /* @__PURE__ */ jsx9(Labeled, { label: text.lengthDays, children: /* @__PURE__ */ jsx9(
1247
- Input3,
1284
+ Input4,
1248
1285
  {
1249
1286
  type: "number",
1250
1287
  min: 1,
@@ -1273,9 +1310,9 @@ function TandemFlowScheduleSection(props) {
1273
1310
  /* @__PURE__ */ jsxs9(More, { title: text.more, children: [
1274
1311
  schedule && /* @__PURE__ */ jsxs9(Fragment2, { children: [
1275
1312
  /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-2 gap-2", children: [
1276
- /* @__PURE__ */ jsx9(Labeled, { label: text.nightFrom, children: /* @__PURE__ */ jsx9(Input3, { type: "time", value: schedule.nightFrom ?? "", onChange: (event) => onChange({ nightFrom: event.target.value || void 0 }) }) }),
1313
+ /* @__PURE__ */ jsx9(Labeled, { label: text.nightFrom, children: /* @__PURE__ */ jsx9(Input4, { type: "time", value: schedule.nightFrom ?? "", onChange: (event) => onChange({ nightFrom: event.target.value || void 0 }) }) }),
1277
1314
  /* @__PURE__ */ jsx9(Labeled, { label: text.lateStart, children: /* @__PURE__ */ jsx9(
1278
- Input3,
1315
+ Input4,
1279
1316
  {
1280
1317
  type: "number",
1281
1318
  min: 0,
@@ -1293,7 +1330,7 @@ function TandemFlowScheduleSection(props) {
1293
1330
  /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-2", children: [
1294
1331
  /* @__PURE__ */ jsx9(SectionTitle, { children: text.firstMessages }),
1295
1332
  /* @__PURE__ */ jsx9(Labeled, { label: text.maxPerDay, hint: text.maxPerDayHint, children: /* @__PURE__ */ jsx9(
1296
- Input3,
1333
+ Input4,
1297
1334
  {
1298
1335
  type: "number",
1299
1336
  min: 0,
@@ -1311,7 +1348,7 @@ function TandemFlowScheduleSection(props) {
1311
1348
  }
1312
1349
  ),
1313
1350
  /* @__PURE__ */ jsx9(Labeled, { label: text.skipMorning, children: /* @__PURE__ */ jsx9(
1314
- Input3,
1351
+ Input4,
1315
1352
  {
1316
1353
  type: "number",
1317
1354
  min: 0,
@@ -1327,7 +1364,7 @@ function TandemFlowScheduleSection(props) {
1327
1364
  /* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--foreground-muted)]", children: text.dayFrameHint }),
1328
1365
  /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-2 gap-2", children: [
1329
1366
  /* @__PURE__ */ jsx9(Labeled, { label: text.softFrom, children: /* @__PURE__ */ jsx9(
1330
- Input3,
1367
+ Input4,
1331
1368
  {
1332
1369
  type: "number",
1333
1370
  min: 1,
@@ -1337,7 +1374,7 @@ function TandemFlowScheduleSection(props) {
1337
1374
  }
1338
1375
  ) }),
1339
1376
  /* @__PURE__ */ jsx9(Labeled, { label: text.hardAt, children: /* @__PURE__ */ jsx9(
1340
- Input3,
1377
+ Input4,
1341
1378
  {
1342
1379
  type: "number",
1343
1380
  min: 1,
@@ -1394,11 +1431,11 @@ function TandemFlowSideTasksSection(props) {
1394
1431
  fromApp.length > 0 && /* @__PURE__ */ jsx9("optgroup", { label: labels.fromApp, children: fromApp.map((field) => /* @__PURE__ */ jsx9("option", { value: field.id, children: field.title }, field.id)) })
1395
1432
  ] }) }),
1396
1433
  /* @__PURE__ */ jsxs9(More, { title: editorLabels.schedule.more, children: [
1397
- /* @__PURE__ */ jsx9(Labeled, { label: labels.when, children: /* @__PURE__ */ jsx9(Input3, { value: task.when ?? "", onChange: (event) => props.onChange(task.id, { when: event.target.value }) }) }),
1434
+ /* @__PURE__ */ jsx9(Labeled, { label: labels.when, children: /* @__PURE__ */ jsx9(Input4, { value: task.when ?? "", onChange: (event) => props.onChange(task.id, { when: event.target.value }) }) }),
1398
1435
  /* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-2 text-sm text-[var(--foreground)]", children: [
1399
1436
  labels.maxAttempts,
1400
1437
  /* @__PURE__ */ jsx9(
1401
- Input3,
1438
+ Input4,
1402
1439
  {
1403
1440
  type: "number",
1404
1441
  min: 1,
@@ -1427,7 +1464,7 @@ function TandemFlowStateTiming(props) {
1427
1464
  const { duration } = props;
1428
1465
  const units = props.daysAvailable ? ["h", "d", "program_day"] : ["h"];
1429
1466
  const amount = duration && /* @__PURE__ */ jsx9(
1430
- Input3,
1467
+ Input4,
1431
1468
  {
1432
1469
  "aria-label": `${labels.duration}: ${labels.durationUnits[duration.unit]}`,
1433
1470
  type: "number",
@@ -1497,7 +1534,7 @@ function NudgesDays({ days, onChange }) {
1497
1534
  /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-[var(--foreground)]", children: labels.nudgesDays }),
1498
1535
  /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1.5", children: [
1499
1536
  days !== null && /* @__PURE__ */ jsx9(
1500
- Input3,
1537
+ Input4,
1501
1538
  {
1502
1539
  "aria-label": `${labels.nudgesDays}: ${labels.nudgesDaysModes.days}`,
1503
1540
  type: "number",
@@ -1518,16 +1555,16 @@ function NudgesDays({ days, onChange }) {
1518
1555
  }
1519
1556
 
1520
1557
  // src/flows/flow-run-panel.tsx
1521
- import { Button as Button7, Input as Input4, cn as cn7 } from "@tandem/ui";
1558
+ import { Button as Button7, Input as Input5, cn as cn7 } from "@tandem/ui";
1522
1559
  import { useFlowLabels as useFlowLabels9 } from "@ykurilov/agent-chat-flows/react";
1523
1560
  import { ArrowRight, MessageCircleQuestion, RotateCcw as RotateCcw2, Undo2 as Undo22 } from "lucide-react";
1524
- import { useEffect as useEffect3, useState as useState4 } from "react";
1561
+ import { useEffect as useEffect3, useState as useState5 } from "react";
1525
1562
  import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1526
1563
  function KnownInput({ value, label, placeholder, onChange }) {
1527
- const [draft, setDraft] = useState4(value ?? "");
1564
+ const [draft, setDraft] = useState5(value ?? "");
1528
1565
  useEffect3(() => setDraft(value ?? ""), [value]);
1529
1566
  return /* @__PURE__ */ jsx10(
1530
- Input4,
1567
+ Input5,
1531
1568
  {
1532
1569
  "aria-label": label,
1533
1570
  value: draft,