@wrongstack/tui 0.291.1 → 0.291.2

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/dist/index.js CHANGED
@@ -43,6 +43,30 @@ import { toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
43
43
  import { routeImagesForModel } from "@wrongstack/runtime/vision";
44
44
  import { getIndexState, getProcessRegistry as getProcessRegistry4, onIndexStateChange } from "@wrongstack/tools";
45
45
  import { createAutoProceedLoopGuard } from "@wrongstack/tools/auto-proceed-loop-guard";
46
+
47
+ // src/prompt-refinement-start.ts
48
+ async function startPromptRefinement(options) {
49
+ options.originalSlot.current = options.original;
50
+ options.setStartedAt((options.now ?? Date.now)());
51
+ options.setBusy(true);
52
+ options.clearDraft();
53
+ options.abortSlot.current = options.controller;
54
+ if (options.controller.signal.aborted) return options.fallbackContext;
55
+ let onAbort;
56
+ const aborted = new Promise((resolve) => {
57
+ onAbort = () => resolve(options.fallbackContext);
58
+ options.controller.signal.addEventListener("abort", onAbort, { once: true });
59
+ });
60
+ try {
61
+ return await Promise.race([options.prepareContext(), aborted]);
62
+ } catch {
63
+ return options.fallbackContext;
64
+ } finally {
65
+ if (onAbort) options.controller.signal.removeEventListener("abort", onAbort);
66
+ }
67
+ }
68
+
69
+ // src/app.tsx
46
70
  import React8, {
47
71
  useCallback as useCallback12,
48
72
  useEffect as useEffect42,
@@ -1123,7 +1147,7 @@ function SendModePicker({
1123
1147
  /* @__PURE__ */ jsx3(Text, { dimColor: true, children: "Message: " }),
1124
1148
  /* @__PURE__ */ jsx3(Text, { color: "white", children: formatSendModeMessagePreview(messagePreview) })
1125
1149
  ] }) : null,
1126
- /* @__PURE__ */ jsx3(Text, { dimColor: true, children: "q/b/s pick \xB7 \u2191/\u2193 move \xB7 Enter select \xB7 Esc \u2192 queue" }),
1150
+ /* @__PURE__ */ jsx3(Text, { dimColor: true, children: "q/b/s pick \xB7 \u2191/\u2193 move \xB7 Enter select \xB7 Esc \u2192 back to input" }),
1127
1151
  SEND_MODE_OPTIONS.map((opt, i) => /* @__PURE__ */ jsxs2(Text, { inverse: i === selected, ...i === selected ? { color: opt.color } : {}, children: [
1128
1152
  i === selected ? "\u203A " : " ",
1129
1153
  /* @__PURE__ */ jsxs2(Text, { bold: true, color: opt.color, children: [
@@ -13595,7 +13619,7 @@ function FleetPanel({
13595
13619
  );
13596
13620
  const hasSwarm = grid.rows.length > 0;
13597
13621
  if (!hasSwarm && todoRows.length === 0 && !hasCollab) return null;
13598
- const runningCount = subagents.filter((entry) => entry.status === "running").length;
13622
+ const runningCount = list.filter((entry) => entry.status === "running").length;
13599
13623
  const totalIterations = subagents.reduce((sum, entry) => sum + entry.iterations, 0);
13600
13624
  const totalTools = subagents.reduce((sum, entry) => sum + entry.toolCalls, 0);
13601
13625
  const todoCounts = (todos ?? []).reduce(
@@ -16525,957 +16549,6 @@ var Input = memo2(function Input2({
16525
16549
  ] });
16526
16550
  });
16527
16551
 
16528
- // src/input-validation.ts
16529
- var MAX_INPUT_BUFFER_CHARS = 1e5;
16530
- var MAX_ENTRY_TEXT_CHARS = 5e5;
16531
- var MAX_HISTORY_ENTRIES = 400;
16532
- var MAX_BATCHED_ACTIONS = 500;
16533
- var MAX_ACTION_STRING_FIELD = 1e4;
16534
- var MAX_FLEET_ENTRIES = 200;
16535
- var MAX_ACTION_DEPTH = 8;
16536
- var MAX_HOST_STRING_FIELD = 500;
16537
- var MAX_PICKER_MATCHES = 500;
16538
- var ALLOWED_ACTION_TYPES = [
16539
- "addEntry",
16540
- "compactHistory",
16541
- "setBuffer",
16542
- "clearInput",
16543
- "clearHistory",
16544
- "replaceHistory",
16545
- "replaceEntry",
16546
- "historyRoll",
16547
- "setHistoryIndex",
16548
- "setHistoryDraft",
16549
- "scrollBy",
16550
- "scrollTo",
16551
- "scrollPage",
16552
- "scrollToBottom",
16553
- "scrollToTop",
16554
- "setMeasuredLines",
16555
- "setViewportRows",
16556
- "pickerOpen",
16557
- "pickerMove",
16558
- "pickerClose",
16559
- "pickerQuery",
16560
- "pickerSetMatches",
16561
- "slashPickerOpen",
16562
- "slashPickerMove",
16563
- "slashPickerClose",
16564
- "slashPickerQuery",
16565
- "slashPickerSetMatches",
16566
- "modelPickerOpen",
16567
- "modelPickerMove",
16568
- "modelPickerClose",
16569
- "modelPickerSelect",
16570
- "modelPickerSetProviders",
16571
- "autonomyPickerOpen",
16572
- "autonomyPickerMove",
16573
- "autonomyPickerClose",
16574
- "autonomyPickerSelect",
16575
- "cancelSend",
16576
- "submit",
16577
- "afterSubmit",
16578
- "streamStart",
16579
- "streamToken",
16580
- "streamToolUse",
16581
- "streamToolResult",
16582
- "streamEnd",
16583
- "setMode",
16584
- "toggleHelp",
16585
- "toggleMonitor",
16586
- "toggleAgentsMonitor",
16587
- "toggleTodosMonitor",
16588
- "toggleQueuePanel",
16589
- "toggleProcessList",
16590
- "toggleCronMonitor",
16591
- "toggleAuditPanel",
16592
- "togglePlanPanel",
16593
- "closeAllPanels",
16594
- "toggleKanbanPanel",
16595
- "toggleGoalPanel",
16596
- "toggleGoalKanbanPanel",
16597
- "toggleContextPanel",
16598
- "toggleSessionsPanel",
16599
- "sessionsPanelSet",
16600
- "sessionsPanelMove",
16601
- "sessionsPanelBusy",
16602
- "sessionResumeConfirmSet",
16603
- "sessionResumeConfirmClear",
16604
- "settingsPickerOpen",
16605
- "settingsPickerMove",
16606
- "settingsPickerClose",
16607
- "settingsPick",
16608
- "statuslinePickerOpen",
16609
- "statuslinePickerMove",
16610
- "statuslinePickerClose",
16611
- "pluginPickerOpen",
16612
- "pluginPickerMove",
16613
- "pluginPickerClose",
16614
- "mcpPickerOpen",
16615
- "mcpPickerMove",
16616
- "mcpPickerClose",
16617
- "toolsPickerOpen",
16618
- "toolsPickerMove",
16619
- "toolsPickerClose",
16620
- "projectPickerOpen",
16621
- "projectPickerMove",
16622
- "projectPickerClose",
16623
- "projectPickerSelect",
16624
- "projectPickerSetItems",
16625
- "fKeyPickerOpen",
16626
- "fKeyPickerMove",
16627
- "fKeyPickerClose",
16628
- "confirmPromptOpen",
16629
- "confirmPromptClose",
16630
- "clearConfirmOpen",
16631
- "clearConfirmClose",
16632
- "clearConfirmSetValue",
16633
- "exitConfirmOpen",
16634
- "exitConfirmClose",
16635
- "slashConfirmOpen",
16636
- "slashConfirmClose",
16637
- "escConfirmOpen",
16638
- "escConfirmClose",
16639
- "sendModePickerOpen",
16640
- "sendModePickerMove",
16641
- "sendModePickerClose",
16642
- "resetContextChip",
16643
- "fleetSeed",
16644
- "fleetSpawn",
16645
- "fleetToolStart",
16646
- "fleetToolEnd",
16647
- "fleetStart",
16648
- "fleetDelta",
16649
- "fleetMessage",
16650
- "fleetTool",
16651
- "fleetUsage",
16652
- "fleetDone",
16653
- "fleetRemove",
16654
- "fleetBudgetWarning",
16655
- "fleetBudgetExtended",
16656
- "fleetCtxPct",
16657
- "fleetCost",
16658
- "fleetConcurrency",
16659
- "fleetBatch",
16660
- "leaderIterStart",
16661
- "leaderIterEnd",
16662
- "leaderToolStart",
16663
- "leaderToolEnd",
16664
- "leaderCtxPct",
16665
- "setFleetChat",
16666
- "enhanceOpen",
16667
- "enhanceClose",
16668
- "enhanceBusy",
16669
- "enhanceBusyDone",
16670
- "enhanceResult",
16671
- "enhanceCancel",
16672
- "enhanceDismiss",
16673
- "refineFailureOpen",
16674
- "refineFailureClose",
16675
- "continueConfirmOpen",
16676
- "continueConfirmClose",
16677
- "checkpointReceived",
16678
- "rewindOverlayOpen",
16679
- "rewindOverlayClose",
16680
- "rewindOverlayMove",
16681
- "setDeadline",
16682
- "setLiveProvider",
16683
- "setLiveModel",
16684
- "setCapability",
16685
- "setDesignKit",
16686
- "setAnimationStyle",
16687
- "setEffectiveMaxContext",
16688
- "setStreamingText",
16689
- "setToolStream",
16690
- "toolStreamClear",
16691
- "setThinkingWord",
16692
- "setFleetVerbosity",
16693
- "setAutonomyMode",
16694
- "setSendMode",
16695
- "setSteering",
16696
- "setSteeringPending",
16697
- "clearSteering",
16698
- "setGoalText",
16699
- "setGoalPanelGoal",
16700
- "showGoal",
16701
- "goalSummary",
16702
- "goalRunInit",
16703
- "goalRunPhaseUpdate",
16704
- "goalRunRunningPhases",
16705
- "goalRunElapsed",
16706
- "goalRunTaskActive",
16707
- "goalRunMonitorToggle",
16708
- "goalRunReset",
16709
- "sddBoardSnapshot",
16710
- "toggleSddBoardMonitor",
16711
- "sddBoardFocusNext",
16712
- "sddBoardFocusPrev",
16713
- "worktreeUpsert",
16714
- "worktreeRemove",
16715
- "toggleWorktreeMonitor",
16716
- "collabBugFound",
16717
- "collabPlanEmitted",
16718
- "collabEvalComplete",
16719
- "collabSessionDone",
16720
- "collabSubagentSpawned",
16721
- "debugStreamStats",
16722
- "debugStreamStatsClear",
16723
- "countdownTick",
16724
- "countdownEnded",
16725
- "coordinatorEvent",
16726
- "toggleCoordinatorMonitor",
16727
- "setEnhancedPrompt",
16728
- "enhanceConfirmOpen",
16729
- "enhanceConfirmClose",
16730
- "setShowModelReasoning"
16731
- ];
16732
- var TEXT_BEARING_ENTRY_KINDS = /* @__PURE__ */ new Set([
16733
- "user",
16734
- "assistant",
16735
- "thinking",
16736
- "info",
16737
- "warn",
16738
- "error",
16739
- "turn-summary"
16740
- ]);
16741
- var ALLOWED_ENTRY_KINDS = /* @__PURE__ */ new Set([
16742
- ...TEXT_BEARING_ENTRY_KINDS,
16743
- "tool",
16744
- "banner",
16745
- "divider"
16746
- ]);
16747
- var ALLOWED_SCROLL_DIRS = /* @__PURE__ */ new Set(["up", "down"]);
16748
- var ALLOWED_AUTONOMY_MODES = /* @__PURE__ */ new Set([
16749
- "off",
16750
- "suggest",
16751
- "auto",
16752
- "eternal",
16753
- "eternal-parallel"
16754
- ]);
16755
- var ALLOWED_SEND_MODES = /* @__PURE__ */ new Set(["queue", "steer", "btw", "direct"]);
16756
- var ALLOWED_FLEET_CHAT_MODES = /* @__PURE__ */ new Set(["off", "concise", "full"]);
16757
- var ALLOWED_COLLAB_VERDICTS = /* @__PURE__ */ new Set(["approve", "needs_revision", "reject"]);
16758
- var ALLOWED_CAPABILITY_FIELDS = /* @__PURE__ */ new Set([
16759
- "colorDepth",
16760
- "mouseProtocol",
16761
- "supportsTitle"
16762
- ]);
16763
- function validateAction(action) {
16764
- const type = String(action.type);
16765
- const typeAllowed = ALLOWED_ACTION_TYPES.includes(type);
16766
- if (!typeAllowed) {
16767
- return {
16768
- valid: false,
16769
- error: `action.type: "${type}" is not on the allow-list.`
16770
- };
16771
- }
16772
- const normalized = normalizeActionType(type);
16773
- if (!normalized) {
16774
- return { valid: false, error: `action.type: "${type}" normalized to empty.` };
16775
- }
16776
- const payload = { ...action, type: normalized };
16777
- const depth = measureDepth(payload, 0);
16778
- if (depth > MAX_ACTION_DEPTH) {
16779
- return {
16780
- valid: false,
16781
- error: `action: payload nesting depth ${depth} exceeds max ${MAX_ACTION_DEPTH}.`
16782
- };
16783
- }
16784
- for (const [k, v] of Object.entries(payload)) {
16785
- if (k === "actions") continue;
16786
- if (typeof v === "string" && v.length > MAX_ACTION_STRING_FIELD) {
16787
- return {
16788
- valid: false,
16789
- error: `action.${k}: string exceeds ${MAX_ACTION_STRING_FIELD.toLocaleString()} chars (got ${v.length}).`
16790
- };
16791
- }
16792
- }
16793
- switch (normalized) {
16794
- // ── Buffer/input mutations ──────────────────────────────────────
16795
- case "setBuffer": {
16796
- const buf = String(action.buffer ?? "");
16797
- if (buf.length > MAX_INPUT_BUFFER_CHARS) {
16798
- return {
16799
- valid: false,
16800
- error: `setBuffer.buffer: exceeds ${MAX_INPUT_BUFFER_CHARS.toLocaleString()} chars (got ${buf.length}).`
16801
- };
16802
- }
16803
- const cursor = Number(action.cursor);
16804
- if (!Number.isInteger(cursor) || cursor < 0 || cursor > buf.length) {
16805
- return {
16806
- valid: false,
16807
- error: `setBuffer.cursor: ${action.cursor} out of range [0, ${buf.length}].`
16808
- };
16809
- }
16810
- return { valid: true, value: payload };
16811
- }
16812
- case "clearInput":
16813
- return { valid: true, value: payload };
16814
- // ── History mutations ───────────────────────────────────────────
16815
- case "addEntry": {
16816
- const entry = action.entry;
16817
- if (!entry || typeof entry !== "object") {
16818
- return { valid: false, error: "addEntry.entry: missing or non-object." };
16819
- }
16820
- const kind = String(entry.kind ?? "");
16821
- if (!ALLOWED_ENTRY_KINDS.has(kind)) {
16822
- return {
16823
- valid: false,
16824
- error: `addEntry.entry.kind: "${kind}" not on allow-list.`
16825
- };
16826
- }
16827
- if (TEXT_BEARING_ENTRY_KINDS.has(kind)) {
16828
- const text = entry.text;
16829
- if (typeof text === "string" && text.length > MAX_ENTRY_TEXT_CHARS) {
16830
- return {
16831
- valid: false,
16832
- error: `addEntry.entry.text: exceeds ${MAX_ENTRY_TEXT_CHARS.toLocaleString()} chars (got ${text.length}).`
16833
- };
16834
- }
16835
- }
16836
- return { valid: true, value: payload };
16837
- }
16838
- case "replaceEntry": {
16839
- const id = Number(action.id);
16840
- if (!Number.isInteger(id) || id < 0) {
16841
- return { valid: false, error: `replaceEntry.id: ${action.id} is not a non-negative integer.` };
16842
- }
16843
- return { valid: true, value: payload };
16844
- }
16845
- case "replaceHistory": {
16846
- const entries = action.entries;
16847
- if (!Array.isArray(entries)) {
16848
- return { valid: false, error: "replaceHistory.entries: not an array." };
16849
- }
16850
- if (entries.length > MAX_HISTORY_ENTRIES) {
16851
- return {
16852
- valid: false,
16853
- error: `replaceHistory.entries: ${entries.length} exceeds max ${MAX_HISTORY_ENTRIES}.`
16854
- };
16855
- }
16856
- return { valid: true, value: payload };
16857
- }
16858
- // ── Scroll ──────────────────────────────────────────────────────
16859
- case "scrollBy": {
16860
- const delta = Number(action.delta);
16861
- if (!Number.isInteger(delta)) {
16862
- return { valid: false, error: `scrollBy.delta: ${action.delta} is not an integer.` };
16863
- }
16864
- return { valid: true, value: payload };
16865
- }
16866
- case "scrollPage": {
16867
- const dir = String(action.dir ?? "");
16868
- if (!ALLOWED_SCROLL_DIRS.has(dir)) {
16869
- return { valid: false, error: `scrollPage.dir: "${dir}" not on allow-list (up|down).` };
16870
- }
16871
- return { valid: true, value: payload };
16872
- }
16873
- case "setMeasuredLines": {
16874
- const lines = Number(action.totalLines);
16875
- if (!Number.isInteger(lines) || lines < 0) {
16876
- return { valid: false, error: `setMeasuredLines.totalLines: ${action.totalLines} is not a non-negative integer.` };
16877
- }
16878
- return { valid: true, value: payload };
16879
- }
16880
- case "setViewportRows": {
16881
- const rows = Number(action.rows);
16882
- if (!Number.isInteger(rows) || rows < 0) {
16883
- return { valid: false, error: `setViewportRows.rows: ${action.rows} is not a non-negative integer.` };
16884
- }
16885
- return { valid: true, value: payload };
16886
- }
16887
- // ── Picker ──────────────────────────────────────────────────────
16888
- case "pickerMove":
16889
- case "slashPickerMove":
16890
- case "modelPickerMove":
16891
- case "autonomyPickerMove":
16892
- case "settingsPickerMove":
16893
- case "statuslinePickerMove":
16894
- case "pluginPickerMove":
16895
- case "mcpPickerMove":
16896
- case "toolsPickerMove":
16897
- case "projectPickerMove":
16898
- case "fKeyPickerMove":
16899
- case "sessionsPanelMove":
16900
- case "rewindOverlayMove":
16901
- case "sendModePickerMove": {
16902
- const delta = Number(action.delta);
16903
- if (!Number.isInteger(delta) || delta < -1 || delta > 1) {
16904
- return { valid: false, error: `${type}.delta: ${action.delta} is not -1, 0, or 1.` };
16905
- }
16906
- return { valid: true, value: payload };
16907
- }
16908
- case "pickerSetMatches":
16909
- case "slashPickerSetMatches": {
16910
- const matches = action.matches;
16911
- if (!Array.isArray(matches)) {
16912
- return { valid: false, error: `${type}.matches: not an array.` };
16913
- }
16914
- if (matches.length > MAX_PICKER_MATCHES) {
16915
- return {
16916
- valid: false,
16917
- error: `${type}.matches: ${matches.length} exceeds max ${MAX_PICKER_MATCHES}.`
16918
- };
16919
- }
16920
- return { valid: true, value: payload };
16921
- }
16922
- case "modelPickerSelect": {
16923
- const idx = Number(action.index);
16924
- if (!Number.isInteger(idx) || idx < 0) {
16925
- return { valid: false, error: `modelPickerSelect.index: ${action.index} is not a non-negative integer.` };
16926
- }
16927
- return { valid: true, value: payload };
16928
- }
16929
- case "projectPickerSelect": {
16930
- const idx = Number(action.selected);
16931
- if (!Number.isInteger(idx) || idx < 0) {
16932
- return { valid: false, error: `projectPickerSelect.selected: ${action.selected} is not a non-negative integer.` };
16933
- }
16934
- return { valid: true, value: payload };
16935
- }
16936
- case "projectPickerSetItems": {
16937
- const items = action.items;
16938
- if (!Array.isArray(items)) {
16939
- return { valid: false, error: "projectPickerSetItems.items: not an array." };
16940
- }
16941
- if (items.length > MAX_PICKER_MATCHES) {
16942
- return {
16943
- valid: false,
16944
- error: `projectPickerSetItems.items: ${items.length} exceeds max ${MAX_PICKER_MATCHES}.`
16945
- };
16946
- }
16947
- return { valid: true, value: payload };
16948
- }
16949
- case "modelPickerSetProviders": {
16950
- const providers = action.providers;
16951
- if (!Array.isArray(providers)) {
16952
- return { valid: false, error: "modelPickerSetProviders.providers: not an array." };
16953
- }
16954
- return { valid: true, value: payload };
16955
- }
16956
- // ── Settings ────────────────────────────────────────────────────
16957
- case "settingsPick": {
16958
- const field = String(action.field ?? "");
16959
- if (field.length > 100) {
16960
- return { valid: false, error: `settingsPick.field: length ${field.length} exceeds 100.` };
16961
- }
16962
- return { valid: true, value: payload };
16963
- }
16964
- // ── Fleet ───────────────────────────────────────────────────────
16965
- case "fleetSeed": {
16966
- const entries = action.entries;
16967
- if (!Array.isArray(entries)) {
16968
- return { valid: false, error: "fleetSeed.entries: not an array." };
16969
- }
16970
- if (entries.length > MAX_FLEET_ENTRIES) {
16971
- return {
16972
- valid: false,
16973
- error: `fleetSeed.entries: ${entries.length} exceeds max ${MAX_FLEET_ENTRIES}.`
16974
- };
16975
- }
16976
- return { valid: true, value: payload };
16977
- }
16978
- case "fleetBatch": {
16979
- const actions = action.actions;
16980
- if (!Array.isArray(actions)) {
16981
- return { valid: false, error: "fleetBatch.actions: not an array." };
16982
- }
16983
- if (actions.length > MAX_BATCHED_ACTIONS) {
16984
- return {
16985
- valid: false,
16986
- error: `fleetBatch.actions: ${actions.length} exceeds max ${MAX_BATCHED_ACTIONS}.`
16987
- };
16988
- }
16989
- return { valid: true, value: payload };
16990
- }
16991
- case "fleetToolStart":
16992
- case "fleetToolEnd":
16993
- case "fleetTool": {
16994
- const id = String(action.id ?? "");
16995
- if (id.length === 0) {
16996
- return { valid: false, error: `${type}.id: empty or missing.` };
16997
- }
16998
- return { valid: true, value: payload };
16999
- }
17000
- case "fleetSpawn":
17001
- case "fleetStart":
17002
- case "fleetDelta":
17003
- case "fleetMessage":
17004
- case "fleetUsage":
17005
- case "fleetDone":
17006
- case "fleetRemove":
17007
- case "fleetBudgetWarning":
17008
- case "fleetBudgetExtended":
17009
- case "fleetCtxPct":
17010
- case "fleetCost":
17011
- case "fleetConcurrency":
17012
- case "leaderIterStart":
17013
- case "leaderIterEnd":
17014
- case "leaderToolStart":
17015
- case "leaderToolEnd":
17016
- case "leaderCtxPct": {
17017
- const id = String(action.id ?? "");
17018
- if (id.length === 0) {
17019
- return { valid: false, error: `${type}.id: empty or missing.` };
17020
- }
17021
- return { valid: true, value: payload };
17022
- }
17023
- case "setFleetChat": {
17024
- const mode = String(action.mode ?? "");
17025
- if (!ALLOWED_FLEET_CHAT_MODES.has(mode)) {
17026
- return { valid: false, error: `setFleetChat.mode: "${mode}" not on allow-list.` };
17027
- }
17028
- return { valid: true, value: payload };
17029
- }
17030
- // ── State mutations ─────────────────────────────────────────────
17031
- case "setAutonomyMode": {
17032
- const mode = String(action.mode ?? "");
17033
- if (!ALLOWED_AUTONOMY_MODES.has(mode)) {
17034
- return { valid: false, error: `setAutonomyMode.mode: "${mode}" not on allow-list.` };
17035
- }
17036
- return { valid: true, value: payload };
17037
- }
17038
- case "setSendMode": {
17039
- const mode = String(action.mode ?? "");
17040
- if (!ALLOWED_SEND_MODES.has(mode)) {
17041
- return { valid: false, error: `setSendMode.mode: "${mode}" not on allow-list.` };
17042
- }
17043
- return { valid: true, value: payload };
17044
- }
17045
- case "setLiveProvider":
17046
- case "setLiveModel": {
17047
- const value = String(action.value ?? "");
17048
- if (value.length > MAX_HOST_STRING_FIELD) {
17049
- return { valid: false, error: `${type}.value: exceeds ${MAX_HOST_STRING_FIELD} chars.` };
17050
- }
17051
- return { valid: true, value: payload };
17052
- }
17053
- case "setEffectiveMaxContext": {
17054
- const ctx = Number(action.value);
17055
- if (!Number.isInteger(ctx) || ctx < 0 || ctx > 1e7) {
17056
- return { valid: false, error: `setEffectiveMaxContext.value: ${action.value} out of range [0, 10_000_000].` };
17057
- }
17058
- return { valid: true, value: payload };
17059
- }
17060
- case "setStreamingText": {
17061
- const text = String(action.text ?? "");
17062
- if (text.length > MAX_ENTRY_TEXT_CHARS) {
17063
- return {
17064
- valid: false,
17065
- error: `setStreamingText.text: exceeds ${MAX_ENTRY_TEXT_CHARS.toLocaleString()} chars.`
17066
- };
17067
- }
17068
- return { valid: true, value: payload };
17069
- }
17070
- case "setToolStream": {
17071
- const text = String(action.text ?? "");
17072
- if (text.length > MAX_TOOL_STREAM_RETAINED_CHARS) {
17073
- return {
17074
- valid: false,
17075
- error: `setToolStream.text: exceeds ${MAX_TOOL_STREAM_RETAINED_CHARS.toLocaleString()} chars.`
17076
- };
17077
- }
17078
- return { valid: true, value: payload };
17079
- }
17080
- case "setThinkingWord": {
17081
- const word = String(action.word ?? "");
17082
- if (word.length > 16) {
17083
- return { valid: false, error: `setThinkingWord.word: "${word}" exceeds 16 chars.` };
17084
- }
17085
- return { valid: true, value: payload };
17086
- }
17087
- case "setAnimationStyle": {
17088
- const style = String(action.style ?? "");
17089
- if (style.length > 50) {
17090
- return { valid: false, error: `setAnimationStyle.style: length ${style.length} exceeds 50.` };
17091
- }
17092
- return { valid: true, value: payload };
17093
- }
17094
- case "setCapability": {
17095
- const cap = action.capability;
17096
- if (!cap || typeof cap !== "object") {
17097
- return { valid: false, error: "setCapability.capability: missing or non-object." };
17098
- }
17099
- for (const k of Object.keys(cap)) {
17100
- if (!ALLOWED_CAPABILITY_FIELDS.has(k)) {
17101
- return { valid: false, error: `setCapability.capability.${k}: unknown field.` };
17102
- }
17103
- }
17104
- return { valid: true, value: payload };
17105
- }
17106
- // ── Confirm panels ──────────────────────────────────────────────
17107
- case "clearConfirmOpen":
17108
- case "exitConfirmOpen":
17109
- case "slashConfirmOpen":
17110
- case "escConfirmOpen":
17111
- case "enhanceConfirmOpen": {
17112
- const info = action.info;
17113
- if (!info || typeof info !== "object") {
17114
- return { valid: false, error: `${type}.info: missing or non-object.` };
17115
- }
17116
- return { valid: true, value: payload };
17117
- }
17118
- case "clearConfirmSetValue": {
17119
- const value = String(action.value ?? "");
17120
- if (value.length > 100) {
17121
- return { valid: false, error: `clearConfirmSetValue.value: exceeds 100 chars.` };
17122
- }
17123
- return { valid: true, value: payload };
17124
- }
17125
- // ── Checkpoints ─────────────────────────────────────────────────
17126
- case "checkpointReceived": {
17127
- const cp = action.cp;
17128
- if (!cp || typeof cp !== "object") {
17129
- return { valid: false, error: "checkpointReceived.cp: missing or non-object." };
17130
- }
17131
- const promptIndex = Number(cp.promptIndex);
17132
- if (!Number.isInteger(promptIndex) || promptIndex < 0) {
17133
- return {
17134
- valid: false,
17135
- error: `checkpointReceived.cp.promptIndex: ${promptIndex} is not a non-negative integer.`
17136
- };
17137
- }
17138
- return { valid: true, value: payload };
17139
- }
17140
- // ── Rewind ──────────────────────────────────────────────────────
17141
- case "rewindOverlayOpen": {
17142
- const checkpoints = action.checkpoints;
17143
- if (!Array.isArray(checkpoints)) {
17144
- return { valid: false, error: "rewindOverlayOpen.checkpoints: not an array." };
17145
- }
17146
- if (checkpoints.length > MAX_HISTORY_ENTRIES) {
17147
- return {
17148
- valid: false,
17149
- error: `rewindOverlayOpen.checkpoints: ${checkpoints.length} exceeds max ${MAX_HISTORY_ENTRIES}.`
17150
- };
17151
- }
17152
- return { valid: true, value: payload };
17153
- }
17154
- // ── Steering ────────────────────────────────────────────────────
17155
- case "setSteering": {
17156
- const text = String(action.text ?? "");
17157
- if (text.length > MAX_INPUT_BUFFER_CHARS) {
17158
- return {
17159
- valid: false,
17160
- error: `setSteering.text: exceeds ${MAX_INPUT_BUFFER_CHARS.toLocaleString()} chars.`
17161
- };
17162
- }
17163
- return { valid: true, value: payload };
17164
- }
17165
- // ── Goal ────────────────────────────────────────────────────────
17166
- case "goalRunInit": {
17167
- const title = String(action.title ?? "");
17168
- if (title.length > 500) {
17169
- return { valid: false, error: `goalRunInit.title: exceeds 500 chars.` };
17170
- }
17171
- return { valid: true, value: payload };
17172
- }
17173
- case "goalRunPhaseUpdate": {
17174
- const completed = Number(action.completedTasks);
17175
- if (!Number.isInteger(completed) || completed < 0) {
17176
- return { valid: false, error: `goalRunPhaseUpdate.completedTasks: ${completed} is not a non-negative integer.` };
17177
- }
17178
- const total = Number(action.totalTasks);
17179
- if (!Number.isInteger(total) || total < 0) {
17180
- return { valid: false, error: `goalRunPhaseUpdate.totalTasks: ${total} is not a non-negative integer.` };
17181
- }
17182
- return { valid: true, value: payload };
17183
- }
17184
- case "goalRunRunningPhases": {
17185
- const phaseIds = action.phaseIds;
17186
- if (!Array.isArray(phaseIds)) {
17187
- return { valid: false, error: "goalRunRunningPhases.phaseIds: not an array." };
17188
- }
17189
- return { valid: true, value: payload };
17190
- }
17191
- case "goalRunElapsed": {
17192
- const ms = Number(action.ms);
17193
- if (!Number.isFinite(ms) || ms < 0) {
17194
- return { valid: false, error: `goalRunElapsed.ms: ${ms} is not a non-negative number.` };
17195
- }
17196
- return { valid: true, value: payload };
17197
- }
17198
- case "goalRunTaskActive": {
17199
- if (typeof action.active !== "boolean") {
17200
- return { valid: false, error: "goalRunTaskActive.active: not a boolean." };
17201
- }
17202
- return { valid: true, value: payload };
17203
- }
17204
- // ── SDD board ───────────────────────────────────────────────────
17205
- case "sddBoardSnapshot": {
17206
- if (!action.snapshot || typeof action.snapshot !== "object") {
17207
- return { valid: false, error: "sddBoardSnapshot.snapshot: missing or non-object." };
17208
- }
17209
- return { valid: true, value: payload };
17210
- }
17211
- // ── Worktree ────────────────────────────────────────────────────
17212
- case "worktreeUpsert": {
17213
- const handleId = String(action.handleId ?? "");
17214
- if (handleId.length === 0) {
17215
- return { valid: false, error: "worktreeUpsert.handleId: empty." };
17216
- }
17217
- return { valid: true, value: payload };
17218
- }
17219
- case "worktreeRemove": {
17220
- const handleId = String(action.handleId ?? "");
17221
- if (handleId.length === 0) {
17222
- return { valid: false, error: "worktreeRemove.handleId: empty." };
17223
- }
17224
- return { valid: true, value: payload };
17225
- }
17226
- // ── Collaboration ───────────────────────────────────────────────
17227
- case "collabBugFound": {
17228
- const bugId = String(action.bugId ?? "");
17229
- if (bugId.length === 0) {
17230
- return { valid: false, error: "collabBugFound.bugId: empty." };
17231
- }
17232
- return { valid: true, value: payload };
17233
- }
17234
- case "collabSessionDone": {
17235
- const verdict = String(action.verdict ?? "");
17236
- if (!ALLOWED_COLLAB_VERDICTS.has(verdict)) {
17237
- return { valid: false, error: `collabSessionDone.verdict: "${verdict}" not on allow-list.` };
17238
- }
17239
- return { valid: true, value: payload };
17240
- }
17241
- case "collabSubagentSpawned": {
17242
- const role = String(action.role ?? "");
17243
- if (role.length === 0) {
17244
- return { valid: false, error: "collabSubagentSpawned.role: empty." };
17245
- }
17246
- return { valid: true, value: payload };
17247
- }
17248
- // ── Debug stream ────────────────────────────────────────────────
17249
- case "debugStreamStats": {
17250
- const chunkCount = Number(action.chunkCount);
17251
- if (!Number.isInteger(chunkCount) || chunkCount < 0) {
17252
- return { valid: false, error: `debugStreamStats.chunkCount: ${chunkCount} is not a non-negative integer.` };
17253
- }
17254
- const lastChunkSize = Number(action.lastChunkSize);
17255
- if (!Number.isInteger(lastChunkSize) || lastChunkSize < 0) {
17256
- return { valid: false, error: `debugStreamStats.lastChunkSize: ${lastChunkSize} is not a non-negative integer.` };
17257
- }
17258
- const totalBytes = Number(action.totalBytes);
17259
- if (!Number.isInteger(totalBytes) || totalBytes < 0) {
17260
- return { valid: false, error: `debugStreamStats.totalBytes: ${totalBytes} is not a non-negative integer.` };
17261
- }
17262
- return { valid: true, value: payload };
17263
- }
17264
- // ── Countdown ───────────────────────────────────────────────────
17265
- case "countdownTick": {
17266
- const remaining = Number(action.remainingSeconds);
17267
- if (!Number.isFinite(remaining) || remaining < 0) {
17268
- return { valid: false, error: `countdownTick.remainingSeconds: ${remaining} is not a non-negative number.` };
17269
- }
17270
- return { valid: true, value: payload };
17271
- }
17272
- // ── Coordinator ─────────────────────────────────────────────────
17273
- case "coordinatorEvent": {
17274
- if (!action.event || typeof action.event !== "object") {
17275
- return { valid: false, error: "coordinatorEvent.event: missing or non-object." };
17276
- }
17277
- return { valid: true, value: payload };
17278
- }
17279
- // ── Sessions panel ──────────────────────────────────────────────
17280
- case "sessionsPanelSet": {
17281
- const sessions = action.sessions;
17282
- if (!Array.isArray(sessions)) {
17283
- return { valid: false, error: "sessionsPanelSet.sessions: not an array." };
17284
- }
17285
- if (sessions.length > 200) {
17286
- return { valid: false, error: `sessionsPanelSet.sessions: ${sessions.length} exceeds max 200.` };
17287
- }
17288
- return { valid: true, value: payload };
17289
- }
17290
- case "sessionsPanelBusy": {
17291
- if (typeof action.on !== "boolean") {
17292
- return { valid: false, error: "sessionsPanelBusy.on: not a boolean." };
17293
- }
17294
- return { valid: true, value: payload };
17295
- }
17296
- case "sessionResumeConfirmSet": {
17297
- const sessionId = String(action.sessionId ?? "");
17298
- if (sessionId.length === 0) {
17299
- return { valid: false, error: "sessionResumeConfirmSet.sessionId: empty." };
17300
- }
17301
- return { valid: true, value: payload };
17302
- }
17303
- // ── Simple state toggles and setters ────────────────────────────
17304
- case "setShowModelReasoning": {
17305
- if (typeof action.value !== "boolean") {
17306
- return { valid: false, error: "setShowModelReasoning.value: not a boolean." };
17307
- }
17308
- return { valid: true, value: payload };
17309
- }
17310
- case "setEnhancedPrompt": {
17311
- const text = String(action.text ?? "");
17312
- if (text.length > MAX_ENTRY_TEXT_CHARS) {
17313
- return {
17314
- valid: false,
17315
- error: `setEnhancedPrompt.text: exceeds ${MAX_ENTRY_TEXT_CHARS.toLocaleString()} chars.`
17316
- };
17317
- }
17318
- return { valid: true, value: payload };
17319
- }
17320
- case "setDesignKit": {
17321
- const name = String(action.name ?? "");
17322
- if (name.length > 100) {
17323
- return { valid: false, error: `setDesignKit.name: exceeds 100 chars.` };
17324
- }
17325
- return { valid: true, value: payload };
17326
- }
17327
- case "setGoalText":
17328
- case "setGoalPanelGoal": {
17329
- const text = String(action.text ?? "");
17330
- if (text.length > 5e3) {
17331
- return { valid: false, error: `${type}.text: exceeds 5000 chars.` };
17332
- }
17333
- return { valid: true, value: payload };
17334
- }
17335
- // ── Enhance / refine ───────────────────────────────────────────
17336
- case "enhanceResult": {
17337
- const result = action.result;
17338
- if (!result || typeof result !== "object") {
17339
- return { valid: false, error: "enhanceResult.result: missing or non-object." };
17340
- }
17341
- return { valid: true, value: payload };
17342
- }
17343
- case "refineFailureOpen": {
17344
- const info = action.info;
17345
- if (!info || typeof info !== "object") {
17346
- return { valid: false, error: "refineFailureOpen.info: missing or non-object." };
17347
- }
17348
- return { valid: true, value: payload };
17349
- }
17350
- // ── Actions with no payload or trivial payload ──────────────────
17351
- case "toggleHelp":
17352
- case "toggleMonitor":
17353
- case "toggleAgentsMonitor":
17354
- case "toggleTodosMonitor":
17355
- case "toggleQueuePanel":
17356
- case "toggleProcessList":
17357
- case "toggleCronMonitor":
17358
- case "toggleAuditPanel":
17359
- case "togglePlanPanel":
17360
- case "closeAllPanels":
17361
- case "toggleKanbanPanel":
17362
- case "toggleGoalPanel":
17363
- case "toggleGoalKanbanPanel":
17364
- case "toggleContextPanel":
17365
- case "toggleSessionsPanel":
17366
- case "toggleSddBoardMonitor":
17367
- case "toggleWorktreeMonitor":
17368
- case "toggleCoordinatorMonitor":
17369
- case "resetContextChip":
17370
- case "clearConfirmClose":
17371
- case "exitConfirmClose":
17372
- case "slashConfirmClose":
17373
- case "escConfirmClose":
17374
- case "sendModePickerClose":
17375
- case "enhanceClose":
17376
- case "enhanceBusy":
17377
- case "enhanceBusyDone":
17378
- case "enhanceCancel":
17379
- case "enhanceDismiss":
17380
- case "enhanceConfirmClose":
17381
- case "refineFailureClose":
17382
- case "continueConfirmOpen":
17383
- case "continueConfirmClose":
17384
- case "rewindOverlayClose":
17385
- case "countdownEnded":
17386
- case "cancelSend":
17387
- case "submit":
17388
- case "afterSubmit":
17389
- case "streamStart":
17390
- case "streamToken":
17391
- case "streamToolUse":
17392
- case "streamToolResult":
17393
- case "streamEnd":
17394
- case "setMode":
17395
- case "clearInput":
17396
- case "clearHistory":
17397
- case "toolStreamClear":
17398
- case "debugStreamStatsClear":
17399
- case "setSteeringPending":
17400
- case "clearSteering":
17401
- case "showGoal":
17402
- case "goalSummary":
17403
- case "goalRunMonitorToggle":
17404
- case "goalRunReset":
17405
- case "sddBoardFocusNext":
17406
- case "sddBoardFocusPrev":
17407
- case "compactHistory":
17408
- case "scrollToBottom":
17409
- case "scrollToTop":
17410
- case "pickerOpen":
17411
- case "pickerClose":
17412
- case "slashPickerOpen":
17413
- case "slashPickerClose":
17414
- case "modelPickerOpen":
17415
- case "modelPickerClose":
17416
- case "autonomyPickerOpen":
17417
- case "autonomyPickerClose":
17418
- case "settingsPickerOpen":
17419
- case "settingsPickerClose":
17420
- case "statuslinePickerOpen":
17421
- case "statuslinePickerClose":
17422
- case "pluginPickerOpen":
17423
- case "pluginPickerClose":
17424
- case "mcpPickerOpen":
17425
- case "mcpPickerClose":
17426
- case "toolsPickerOpen":
17427
- case "toolsPickerClose":
17428
- case "projectPickerOpen":
17429
- case "projectPickerClose":
17430
- case "fKeyPickerOpen":
17431
- case "fKeyPickerClose":
17432
- case "confirmPromptOpen":
17433
- case "confirmPromptClose":
17434
- case "setDeadline":
17435
- case "enhanceOpen":
17436
- return { valid: true, value: payload };
17437
- default:
17438
- return {
17439
- valid: false,
17440
- error: `action.type: "${type}" has no type-specific validator \u2014 may be a missing case.`
17441
- };
17442
- }
17443
- }
17444
- function normalizeActionType(type) {
17445
- const trimmed = String(type ?? "").trim();
17446
- if (trimmed.length === 0) return null;
17447
- return trimmed;
17448
- }
17449
- function measureDepth(value, depth) {
17450
- if (depth > MAX_ACTION_DEPTH) return depth;
17451
- if (value === null || typeof value !== "object") return depth;
17452
- if (Array.isArray(value)) {
17453
- let max2 = depth;
17454
- for (const item of value.slice(0, 10)) {
17455
- const d = measureDepth(item, depth + 1);
17456
- if (d > max2) max2 = d;
17457
- if (max2 > MAX_ACTION_DEPTH) return max2;
17458
- }
17459
- return max2;
17460
- }
17461
- let max = depth;
17462
- for (const v of Object.values(value).slice(0, 10)) {
17463
- const d = measureDepth(v, depth + 1);
17464
- if (d > max) max = d;
17465
- if (max > MAX_ACTION_DEPTH) return max;
17466
- }
17467
- return max;
17468
- }
17469
- function safeDispatch(action, dispatch) {
17470
- const result = validateAction(action);
17471
- if (!result.valid) {
17472
- console.error(`[input-validation] REJECTED dispatch "${action.type}": ${result.error}`);
17473
- return false;
17474
- }
17475
- dispatch(result.value);
17476
- return true;
17477
- }
17478
-
17479
16552
  // src/components/kanban-panel.tsx
17480
16553
  import {
17481
16554
  addTask,
@@ -23200,7 +22273,7 @@ function usePickerKeys(host) {
23200
22273
  dispatch({ type: "modelPickerMove", delta: 1 });
23201
22274
  return true;
23202
22275
  }
23203
- if (state.modelPicker.step === "model" && input && !key.return && !key.backspace) {
22276
+ if (state.modelPicker.step === "model" && input && !isEnter && !key.backspace) {
23204
22277
  dispatch({ type: "modelPickerSearch", query: state.modelPicker.searchQuery + input });
23205
22278
  return true;
23206
22279
  }
@@ -27252,12 +26325,7 @@ function App({
27252
26325
  initialFleetChat: fleetStreamController?.mode
27253
26326
  })
27254
26327
  );
27255
- const dispatch = useCallback12(
27256
- (action) => {
27257
- safeDispatch(action, rawDispatch);
27258
- },
27259
- [rawDispatch]
27260
- );
26328
+ const dispatch = rawDispatch;
27261
26329
  const [focusedBoardId, setFocusedBoardId] = useState29(null);
27262
26330
  const boardFocusRef = useRef17(null);
27263
26331
  if (!boardFocusRef.current) {
@@ -31068,14 +30136,32 @@ ${content}
31068
30136
  setEnhanceDurationMs(null);
31069
30137
  const ac = new AbortController();
31070
30138
  const baseTimeoutMs = 9e4;
31071
- enhanceOriginalRef.current = trimmed;
31072
- clearDraft();
31073
- enhanceAbortRef.current = ac;
31074
- const contextSections = await buildRefinerContextSections({
31075
- text: cleanText,
31076
- memoryStore,
31077
- context: agent.ctx
30139
+ const contextSections = await startPromptRefinement({
30140
+ original: trimmed,
30141
+ controller: ac,
30142
+ originalSlot: enhanceOriginalRef,
30143
+ abortSlot: enhanceAbortRef,
30144
+ setStartedAt: setEnhanceStartedAt,
30145
+ setBusy: (on) => dispatch({ type: "enhanceBusy", on }),
30146
+ clearDraft,
30147
+ prepareContext: () => buildRefinerContextSections({
30148
+ text: cleanText,
30149
+ memoryStore,
30150
+ context: agent.ctx
30151
+ }),
30152
+ fallbackContext: []
31078
30153
  });
30154
+ const restoreCancelledPreflight = () => {
30155
+ if (!ac.signal.aborted) return false;
30156
+ enhanceCancelledRef.current = false;
30157
+ enhanceAbortRef.current = null;
30158
+ dispatch({ type: "enhanceBusy", on: false });
30159
+ setEnhanceStartedAt(null);
30160
+ setEnhanceDurationMs(null);
30161
+ setDraft(trimmed, trimmed.length);
30162
+ return true;
30163
+ };
30164
+ if (restoreCancelledPreflight()) return;
31079
30165
  const runAttempt = async (provider2, model2, timeoutMs, reasoning, hints = {}) => {
31080
30166
  let kind;
31081
30167
  let reason = null;
@@ -31122,7 +30208,12 @@ ${content}
31122
30208
  const ref = parseModelRef(configuredRef);
31123
30209
  const targetProvider = ref.provider ?? agent.ctx.provider.id;
31124
30210
  if (ref.model) {
31125
- const built = await buildEnhancerProvider(targetProvider, ref.model);
30211
+ let built;
30212
+ try {
30213
+ built = await buildEnhancerProvider(targetProvider, ref.model);
30214
+ } catch {
30215
+ built = void 0;
30216
+ }
31126
30217
  if (built) {
31127
30218
  initialProvider = built;
31128
30219
  initialModel = ref.model;
@@ -31130,6 +30221,7 @@ ${content}
31130
30221
  }
31131
30222
  }
31132
30223
  }
30224
+ if (restoreCancelledPreflight()) return;
31133
30225
  let outcome = await runAttempt(
31134
30226
  initialProvider,
31135
30227
  initialModel,
@@ -31395,6 +30487,10 @@ ${content}
31395
30487
  }
31396
30488
  return;
31397
30489
  }
30490
+ if (mode === "cancel") {
30491
+ setDraft(effectiveText, effectiveText.length);
30492
+ return;
30493
+ }
31398
30494
  dispatch({
31399
30495
  type: "addEntry",
31400
30496
  entry: { kind: "user", text: displayText, queued: true, pasteContent }