@wrongstack/tui 0.6.5 → 0.6.6
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.d.ts +30 -0
- package/dist/index.js +158 -4
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -50,6 +50,34 @@ interface RunTuiOptions {
|
|
|
50
50
|
* iteration as a live timeline entry as it lands.
|
|
51
51
|
*/
|
|
52
52
|
subscribeEternalIteration?: (fn: (entry: _wrongstack_core.JournalEntry) => void) => () => void;
|
|
53
|
+
/**
|
|
54
|
+
* Subscribe to per-iteration stage transitions from the eternal engine.
|
|
55
|
+
* TUI uses this to render live status (decide → execute → reflect →
|
|
56
|
+
* sleep/paused/stopped) in the status bar.
|
|
57
|
+
*/
|
|
58
|
+
subscribeEternalStage?: (fn: (stage: {
|
|
59
|
+
phase: 'idle';
|
|
60
|
+
} | {
|
|
61
|
+
phase: 'decide';
|
|
62
|
+
reason: string;
|
|
63
|
+
} | {
|
|
64
|
+
phase: 'execute';
|
|
65
|
+
task: string;
|
|
66
|
+
} | {
|
|
67
|
+
phase: 'reflect';
|
|
68
|
+
status: 'success' | 'failure' | 'aborted' | 'skipped';
|
|
69
|
+
note?: string;
|
|
70
|
+
} | {
|
|
71
|
+
phase: 'sleep';
|
|
72
|
+
ms: number;
|
|
73
|
+
} | {
|
|
74
|
+
phase: 'paused';
|
|
75
|
+
} | {
|
|
76
|
+
phase: 'stopped';
|
|
77
|
+
} | {
|
|
78
|
+
phase: 'error';
|
|
79
|
+
message: string;
|
|
80
|
+
}) => void) => () => void;
|
|
53
81
|
/** Renders in the startup banner. Read from the CLI's package.json. */
|
|
54
82
|
appVersion?: string;
|
|
55
83
|
/** Provider id for the startup banner ("openai", "anthropic", ...). */
|
|
@@ -62,6 +90,8 @@ interface RunTuiOptions {
|
|
|
62
90
|
getPickableProviders?: () => Promise<ProviderOption[]>;
|
|
63
91
|
/** Apply a (provider, model) pair after the picker confirms. Returns an error string on failure. */
|
|
64
92
|
switchProviderAndModel?: (providerId: string, modelId: string) => string | null;
|
|
93
|
+
/** Apply an autonomy mode after the picker confirms. Returns an error string on failure. */
|
|
94
|
+
switchAutonomy?: (mode: 'off' | 'suggest' | 'auto' | 'eternal' | 'eternal-parallel') => string | null;
|
|
65
95
|
/**
|
|
66
96
|
* Model-specific maxContext (tokens), resolved by the CLI via the
|
|
67
97
|
* ModelsRegistry. When omitted, the TUI falls back to the provider
|
package/dist/index.js
CHANGED
|
@@ -1550,6 +1550,25 @@ function LiveActivityStrip({
|
|
|
1550
1550
|
] }) }) : null
|
|
1551
1551
|
] });
|
|
1552
1552
|
}
|
|
1553
|
+
var AUTONOMY_OPTIONS = [
|
|
1554
|
+
{ mode: "off", label: "OFF", description: "Agent stops after each turn (normal interactive mode)", color: "green" },
|
|
1555
|
+
{ mode: "suggest", label: "SUGGEST", description: "Shows next-step suggestions after each turn", color: "cyan" },
|
|
1556
|
+
{ mode: "auto", label: "AUTO", description: "Self-driving \u2014 agent picks next step and continues", color: "yellow" },
|
|
1557
|
+
{ mode: "eternal", label: "ETERNAL", description: "Goal-driven loop \u2014 requires /goal set first", color: "red" },
|
|
1558
|
+
{ mode: "eternal-parallel", label: "PARALLEL", description: "Fan-out 4\u20138 subagents per tick \u2014 requires /goal", color: "magenta" }
|
|
1559
|
+
];
|
|
1560
|
+
function AutonomyPicker({ options, selected, hint }) {
|
|
1561
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
|
|
1562
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2501\u2501 Autonomy Mode \u2501\u2501" }),
|
|
1563
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 navigate \xB7 Enter select \xB7 Esc cancel \xB7 Ctrl+C exit" }),
|
|
1564
|
+
options.map((opt, i) => /* @__PURE__ */ jsxs(Text, { color: i === selected ? opt.color : void 0, inverse: i === selected, children: [
|
|
1565
|
+
i === selected ? "\u203A " : " ",
|
|
1566
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: opt.label.padEnd(12) }),
|
|
1567
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: opt.description })
|
|
1568
|
+
] }, opt.mode)),
|
|
1569
|
+
hint ? /* @__PURE__ */ jsx(Text, { color: "yellow", children: hint }) : null
|
|
1570
|
+
] });
|
|
1571
|
+
}
|
|
1553
1572
|
function ModelPicker({
|
|
1554
1573
|
step,
|
|
1555
1574
|
providerOptions,
|
|
@@ -1634,7 +1653,8 @@ function StatusBar({
|
|
|
1634
1653
|
context,
|
|
1635
1654
|
projectName,
|
|
1636
1655
|
processCount,
|
|
1637
|
-
hiddenItems
|
|
1656
|
+
hiddenItems,
|
|
1657
|
+
eternalStage
|
|
1638
1658
|
}) {
|
|
1639
1659
|
const hiddenSet = new Set(hiddenItems);
|
|
1640
1660
|
const usage = tokenCounter?.total();
|
|
@@ -1730,8 +1750,12 @@ function StatusBar({
|
|
|
1730
1750
|
}
|
|
1731
1751
|
)
|
|
1732
1752
|
] }) : null,
|
|
1753
|
+
eternalStage ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1754
|
+
yolo || autonomy && autonomy !== "off" ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
1755
|
+
/* @__PURE__ */ jsx(EternalStageChip, { stage: eternalStage })
|
|
1756
|
+
] }) : null,
|
|
1733
1757
|
elapsedMs !== void 0 && !hiddenSet.has("elapsed") ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1734
|
-
yolo ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
1758
|
+
yolo || autonomy && autonomy !== "off" || eternalStage ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }) : null,
|
|
1735
1759
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1736
1760
|
"\u23F1 ",
|
|
1737
1761
|
fmtElapsed2(elapsedMs)
|
|
@@ -1855,6 +1879,45 @@ function StatusBar({
|
|
|
1855
1879
|
}
|
|
1856
1880
|
);
|
|
1857
1881
|
}
|
|
1882
|
+
function EternalStageChip({
|
|
1883
|
+
stage
|
|
1884
|
+
}) {
|
|
1885
|
+
switch (stage.phase) {
|
|
1886
|
+
case "idle":
|
|
1887
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2B1C idle" });
|
|
1888
|
+
case "decide":
|
|
1889
|
+
return /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
1890
|
+
"\u2B07 decide: ",
|
|
1891
|
+
stage.reason
|
|
1892
|
+
] });
|
|
1893
|
+
case "execute":
|
|
1894
|
+
return /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
1895
|
+
"\u25B6 ",
|
|
1896
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "execute" }),
|
|
1897
|
+
stage.task ? `(${stage.task})` : ""
|
|
1898
|
+
] });
|
|
1899
|
+
case "reflect":
|
|
1900
|
+
return /* @__PURE__ */ jsxs(Text, { color: stage.status === "success" ? "green" : stage.status === "failure" ? "red" : "yellow", children: [
|
|
1901
|
+
"\u21A9 reflect: ",
|
|
1902
|
+
stage.status
|
|
1903
|
+
] });
|
|
1904
|
+
case "sleep":
|
|
1905
|
+
return /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1906
|
+
"\u{1F4A4} sleep ",
|
|
1907
|
+
Math.round(stage.ms / 1e3),
|
|
1908
|
+
"s"
|
|
1909
|
+
] });
|
|
1910
|
+
case "paused":
|
|
1911
|
+
return /* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u23F8 paused" });
|
|
1912
|
+
case "stopped":
|
|
1913
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u25A0 stopped" });
|
|
1914
|
+
case "error":
|
|
1915
|
+
return /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
1916
|
+
"\u26A0 error: ",
|
|
1917
|
+
stage.message
|
|
1918
|
+
] });
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1858
1921
|
function ContextChip({ ctx }) {
|
|
1859
1922
|
const ratio = Math.max(0, Math.min(1, ctx.used / ctx.max));
|
|
1860
1923
|
const pct = Math.round(ratio * 100);
|
|
@@ -2451,6 +2514,30 @@ function reducer(state, action) {
|
|
|
2451
2514
|
...state,
|
|
2452
2515
|
modelPicker: { ...state.modelPicker, hint: action.text }
|
|
2453
2516
|
};
|
|
2517
|
+
case "autonomyPickerOpen":
|
|
2518
|
+
return {
|
|
2519
|
+
...state,
|
|
2520
|
+
autonomyPicker: { open: true, options: action.options, selected: 0, hint: void 0 }
|
|
2521
|
+
};
|
|
2522
|
+
case "autonomyPickerClose":
|
|
2523
|
+
return {
|
|
2524
|
+
...state,
|
|
2525
|
+
autonomyPicker: { open: false, options: [], selected: 0 }
|
|
2526
|
+
};
|
|
2527
|
+
case "autonomyPickerMove": {
|
|
2528
|
+
const n = state.autonomyPicker.options.length;
|
|
2529
|
+
if (n === 0) return state;
|
|
2530
|
+
const next = (state.autonomyPicker.selected + action.delta + n) % n;
|
|
2531
|
+
return {
|
|
2532
|
+
...state,
|
|
2533
|
+
autonomyPicker: { ...state.autonomyPicker, selected: next }
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
case "autonomyPickerHint":
|
|
2537
|
+
return {
|
|
2538
|
+
...state,
|
|
2539
|
+
autonomyPicker: { ...state.autonomyPicker, hint: action.text }
|
|
2540
|
+
};
|
|
2454
2541
|
case "confirmOpen":
|
|
2455
2542
|
return { ...state, confirmQueue: [...state.confirmQueue, action.info] };
|
|
2456
2543
|
case "confirmClose":
|
|
@@ -2666,6 +2753,9 @@ function reducer(state, action) {
|
|
|
2666
2753
|
rewindOverlay: null
|
|
2667
2754
|
};
|
|
2668
2755
|
}
|
|
2756
|
+
case "eternalStage": {
|
|
2757
|
+
return { ...state, eternalStage: action.stage };
|
|
2758
|
+
}
|
|
2669
2759
|
}
|
|
2670
2760
|
}
|
|
2671
2761
|
var PASTE_THRESHOLD_CHARS = 200;
|
|
@@ -2720,6 +2810,7 @@ function App({
|
|
|
2720
2810
|
getEternalEngine,
|
|
2721
2811
|
getParallelEngine,
|
|
2722
2812
|
subscribeEternalIteration,
|
|
2813
|
+
subscribeEternalStage,
|
|
2723
2814
|
getSDDContext,
|
|
2724
2815
|
onSDDOutput,
|
|
2725
2816
|
appVersion,
|
|
@@ -2728,6 +2819,7 @@ function App({
|
|
|
2728
2819
|
keyTail,
|
|
2729
2820
|
getPickableProviders,
|
|
2730
2821
|
switchProviderAndModel,
|
|
2822
|
+
switchAutonomy,
|
|
2731
2823
|
effectiveMaxContext,
|
|
2732
2824
|
onExit,
|
|
2733
2825
|
director,
|
|
@@ -2790,13 +2882,15 @@ function App({
|
|
|
2790
2882
|
modelOptions: [],
|
|
2791
2883
|
selected: 0
|
|
2792
2884
|
},
|
|
2885
|
+
autonomyPicker: { open: false, options: [], selected: 0 },
|
|
2793
2886
|
confirmQueue: [],
|
|
2794
2887
|
contextChipVersion: 0,
|
|
2795
2888
|
fleet: {},
|
|
2796
2889
|
fleetCost: 0,
|
|
2797
2890
|
streamFleet: true,
|
|
2798
2891
|
checkpoints: [],
|
|
2799
|
-
rewindOverlay: null
|
|
2892
|
+
rewindOverlay: null,
|
|
2893
|
+
eternalStage: null
|
|
2800
2894
|
});
|
|
2801
2895
|
const builderRef = useRef(null);
|
|
2802
2896
|
if (builderRef.current === null) {
|
|
@@ -3283,6 +3377,22 @@ function App({
|
|
|
3283
3377
|
slashRegistry.unregister("model");
|
|
3284
3378
|
};
|
|
3285
3379
|
}, [slashRegistry, getPickableProviders, switchProviderAndModel]);
|
|
3380
|
+
useEffect(() => {
|
|
3381
|
+
if (!switchAutonomy) return;
|
|
3382
|
+
const cmd = {
|
|
3383
|
+
name: "autonomy",
|
|
3384
|
+
aliases: ["auto"],
|
|
3385
|
+
description: "Pick an autonomy mode interactively (picker).",
|
|
3386
|
+
async run() {
|
|
3387
|
+
dispatch({ type: "autonomyPickerOpen", options: AUTONOMY_OPTIONS });
|
|
3388
|
+
return { message: void 0 };
|
|
3389
|
+
}
|
|
3390
|
+
};
|
|
3391
|
+
slashRegistry.register(cmd);
|
|
3392
|
+
return () => {
|
|
3393
|
+
slashRegistry.unregister("autonomy");
|
|
3394
|
+
};
|
|
3395
|
+
}, [slashRegistry, switchAutonomy]);
|
|
3286
3396
|
useEffect(() => {
|
|
3287
3397
|
const FLUSH_MS = 100;
|
|
3288
3398
|
const flush = () => {
|
|
@@ -3930,6 +4040,32 @@ function App({
|
|
|
3930
4040
|
}
|
|
3931
4041
|
return;
|
|
3932
4042
|
}
|
|
4043
|
+
if (state.autonomyPicker.open) {
|
|
4044
|
+
if (key.escape) {
|
|
4045
|
+
dispatch({ type: "autonomyPickerClose" });
|
|
4046
|
+
return;
|
|
4047
|
+
}
|
|
4048
|
+
if (key.upArrow) {
|
|
4049
|
+
dispatch({ type: "autonomyPickerMove", delta: -1 });
|
|
4050
|
+
return;
|
|
4051
|
+
}
|
|
4052
|
+
if (key.downArrow) {
|
|
4053
|
+
dispatch({ type: "autonomyPickerMove", delta: 1 });
|
|
4054
|
+
return;
|
|
4055
|
+
}
|
|
4056
|
+
if (isEnter) {
|
|
4057
|
+
const opt = state.autonomyPicker.options[state.autonomyPicker.selected];
|
|
4058
|
+
if (!opt) return;
|
|
4059
|
+
const err = switchAutonomy?.(opt.mode);
|
|
4060
|
+
if (err) {
|
|
4061
|
+
dispatch({ type: "autonomyPickerHint", text: err });
|
|
4062
|
+
return;
|
|
4063
|
+
}
|
|
4064
|
+
dispatch({ type: "autonomyPickerClose" });
|
|
4065
|
+
return;
|
|
4066
|
+
}
|
|
4067
|
+
return;
|
|
4068
|
+
}
|
|
3933
4069
|
if (state.slashPicker.open) {
|
|
3934
4070
|
if (key.escape) {
|
|
3935
4071
|
dispatch({ type: "slashPickerClose" });
|
|
@@ -4343,6 +4479,13 @@ function App({
|
|
|
4343
4479
|
});
|
|
4344
4480
|
return unsub;
|
|
4345
4481
|
}, [subscribeEternalIteration]);
|
|
4482
|
+
useEffect(() => {
|
|
4483
|
+
if (!subscribeEternalStage) return;
|
|
4484
|
+
const unsub = subscribeEternalStage((stage) => {
|
|
4485
|
+
dispatch({ type: "eternalStage", stage });
|
|
4486
|
+
});
|
|
4487
|
+
return unsub;
|
|
4488
|
+
}, [subscribeEternalStage]);
|
|
4346
4489
|
const submit = async (overrideRaw) => {
|
|
4347
4490
|
const raw = overrideRaw ?? draftRef.current.buffer;
|
|
4348
4491
|
const trimmed = raw.trim();
|
|
@@ -4528,6 +4671,14 @@ User message:
|
|
|
4528
4671
|
hint: state.modelPicker.hint
|
|
4529
4672
|
}
|
|
4530
4673
|
) : null,
|
|
4674
|
+
state.autonomyPicker.open ? /* @__PURE__ */ jsx(
|
|
4675
|
+
AutonomyPicker,
|
|
4676
|
+
{
|
|
4677
|
+
options: state.autonomyPicker.options,
|
|
4678
|
+
selected: state.autonomyPicker.selected,
|
|
4679
|
+
hint: state.autonomyPicker.hint
|
|
4680
|
+
}
|
|
4681
|
+
) : null,
|
|
4531
4682
|
state.rewindOverlay ? /* @__PURE__ */ jsx(
|
|
4532
4683
|
CheckpointTimeline,
|
|
4533
4684
|
{
|
|
@@ -4576,7 +4727,8 @@ User message:
|
|
|
4576
4727
|
projectName,
|
|
4577
4728
|
subagentCount: Object.keys(state.fleet).length,
|
|
4578
4729
|
processCount: getProcessRegistry().activeCount,
|
|
4579
|
-
hiddenItems
|
|
4730
|
+
hiddenItems,
|
|
4731
|
+
eternalStage: state.eternalStage
|
|
4580
4732
|
}
|
|
4581
4733
|
),
|
|
4582
4734
|
director ? /* @__PURE__ */ jsx(FleetPanel, { entries: state.fleet, totalCost: state.fleetCost, roster: fleetRoster }) : null
|
|
@@ -4707,12 +4859,14 @@ async function runTui(opts) {
|
|
|
4707
4859
|
getEternalEngine: opts.getEternalEngine,
|
|
4708
4860
|
getParallelEngine: opts.getParallelEngine,
|
|
4709
4861
|
subscribeEternalIteration: opts.subscribeEternalIteration,
|
|
4862
|
+
subscribeEternalStage: opts.subscribeEternalStage,
|
|
4710
4863
|
appVersion: opts.appVersion,
|
|
4711
4864
|
provider: opts.provider,
|
|
4712
4865
|
family: opts.family,
|
|
4713
4866
|
keyTail: opts.keyTail,
|
|
4714
4867
|
getPickableProviders: opts.getPickableProviders,
|
|
4715
4868
|
switchProviderAndModel: opts.switchProviderAndModel,
|
|
4869
|
+
switchAutonomy: opts.switchAutonomy,
|
|
4716
4870
|
effectiveMaxContext: opts.effectiveMaxContext,
|
|
4717
4871
|
onExit,
|
|
4718
4872
|
director: opts.director ?? null,
|