skydive-cli 0.2.0-beta.600 → 0.2.0-beta.604
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/js/bin.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import semver from "semver";
|
|
|
20
20
|
|
|
21
21
|
//#region package.json
|
|
22
22
|
var name = "skydive-cli";
|
|
23
|
-
var version = "0.2.0-beta.
|
|
23
|
+
var version = "0.2.0-beta.604";
|
|
24
24
|
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/types.ts
|
|
@@ -1200,7 +1200,7 @@ const importCommand = {
|
|
|
1200
1200
|
process.exit(1);
|
|
1201
1201
|
}
|
|
1202
1202
|
}
|
|
1203
|
-
const { runChat } = await import("./boot-
|
|
1203
|
+
const { runChat } = await import("./boot-Cmte0eob.mjs");
|
|
1204
1204
|
await runChat({
|
|
1205
1205
|
appUrl,
|
|
1206
1206
|
sessionToken: session.value.sessionToken,
|
|
@@ -1209,6 +1209,7 @@ const importCommand = {
|
|
|
1209
1209
|
notifications: true,
|
|
1210
1210
|
agentSelector: argv.agent ?? null,
|
|
1211
1211
|
conversationId: null,
|
|
1212
|
+
newConversation: false,
|
|
1212
1213
|
seedPrompt: buildImportSeedPrompt(process.cwd())
|
|
1213
1214
|
});
|
|
1214
1215
|
}
|
|
@@ -1465,6 +1466,10 @@ const chatCommand = {
|
|
|
1465
1466
|
alias: "resume",
|
|
1466
1467
|
type: "string",
|
|
1467
1468
|
describe: "Continue an existing conversation by id. With -p, the one-shot lands in that conversation; without -p, the TUI opens directly into it (the agent is resolved from the conversation, no --agent needed)."
|
|
1469
|
+
}).option("new", {
|
|
1470
|
+
type: "boolean",
|
|
1471
|
+
default: false,
|
|
1472
|
+
describe: "Start a fresh conversation instead of opening the conversation list. With --agent, opens a new conversation with that agent directly. Without --agent, opens a new conversation once you pick an agent (auto-picked if the account has only one). Ignored with --resume, which always continues the named conversation."
|
|
1468
1473
|
}).option("share-machine", {
|
|
1469
1474
|
type: "boolean",
|
|
1470
1475
|
describe: "Share this machine with the agent over the portal so it can run commands here (default-deny; in the TUI you approve per agent, with -p the flag grants the target agent for the run). Defaults to `shareMachineDefault` in the CLI config file; --no-share-machine disables for this invocation."
|
|
@@ -1475,7 +1480,7 @@ const chatCommand = {
|
|
|
1475
1480
|
type: "boolean",
|
|
1476
1481
|
default: true,
|
|
1477
1482
|
describe: "Show a desktop notification when a run finishes or needs your input while this terminal is unfocused (use --no-notify to disable)"
|
|
1478
|
-
}).example("skydive chat -p \"summarize my open PRs\" --agent grace", "One-shot, non-interactive").example("echo \"what changed today?\" | skydive chat -p --agent grace", "Read the prompt from stdin").example("skydive chat --agent grace", "Open Grace's conversation list in the TUI (skips the agent picker)").example("skydive chat --resume 0197e0f3-…", "Reopen a previous conversation in the TUI (the id is printed when you quit a chat)"),
|
|
1483
|
+
}).example("skydive chat -p \"summarize my open PRs\" --agent grace", "One-shot, non-interactive").example("echo \"what changed today?\" | skydive chat -p --agent grace", "Read the prompt from stdin").example("skydive chat --agent grace", "Open Grace's conversation list in the TUI (skips the agent picker)").example("skydive chat --agent grace --new", "Start a fresh conversation with Grace directly (skips the conversation list)").example("skydive chat --resume 0197e0f3-…", "Reopen a previous conversation in the TUI (the id is printed when you quit a chat)"),
|
|
1479
1484
|
handler: async (argv) => {
|
|
1480
1485
|
const appUrl = resolveAppUrl({ appUrl: argv["api-url"] });
|
|
1481
1486
|
if (argv.print !== void 0) {
|
|
@@ -1511,7 +1516,7 @@ const chatCommand = {
|
|
|
1511
1516
|
printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
|
|
1512
1517
|
process.exit(1);
|
|
1513
1518
|
}
|
|
1514
|
-
const { runChat } = await import("./boot-
|
|
1519
|
+
const { runChat } = await import("./boot-Cmte0eob.mjs");
|
|
1515
1520
|
await runChat({
|
|
1516
1521
|
appUrl,
|
|
1517
1522
|
sessionToken: session.value.sessionToken,
|
|
@@ -1521,6 +1526,7 @@ const chatCommand = {
|
|
|
1521
1526
|
notifications: argv.notify,
|
|
1522
1527
|
agentSelector: argv.agent ?? null,
|
|
1523
1528
|
conversationId: argv.conversation ?? null,
|
|
1529
|
+
newConversation: resolveNewConversation(argv),
|
|
1524
1530
|
seedPrompt: null
|
|
1525
1531
|
});
|
|
1526
1532
|
}
|
|
@@ -1533,6 +1539,14 @@ const chatCommand = {
|
|
|
1533
1539
|
function resolveShareMachine(argv) {
|
|
1534
1540
|
return argv["share-machine"] ?? getShareMachineDefault();
|
|
1535
1541
|
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Whether this invocation should boot straight into a fresh conversation:
|
|
1544
|
+
* `--new` requests it, but `--resume <id>` always wins (it pins an existing
|
|
1545
|
+
* conversation, so "new" is meaningless alongside it).
|
|
1546
|
+
*/
|
|
1547
|
+
function resolveNewConversation(argv) {
|
|
1548
|
+
return argv.new === true && !argv.conversation;
|
|
1549
|
+
}
|
|
1536
1550
|
async function runPrintMode({ argv, appUrl }) {
|
|
1537
1551
|
const session = resolveSession({ appUrl });
|
|
1538
1552
|
if (session.isErr()) {
|
|
@@ -1810,7 +1824,7 @@ const switchCommand = {
|
|
|
1810
1824
|
printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
|
|
1811
1825
|
process.exit(1);
|
|
1812
1826
|
}
|
|
1813
|
-
const { runWorkspacePicker } = await import("./boot-
|
|
1827
|
+
const { runWorkspacePicker } = await import("./boot-Cmte0eob.mjs");
|
|
1814
1828
|
await runWorkspacePicker(session);
|
|
1815
1829
|
return;
|
|
1816
1830
|
}
|
|
@@ -78,6 +78,7 @@ const useStore = create((set, get) => ({
|
|
|
78
78
|
toast: null,
|
|
79
79
|
seedPrompt: null,
|
|
80
80
|
autoGrantMachine: false,
|
|
81
|
+
newConversationIntent: false,
|
|
81
82
|
goTo: (screen) => set({
|
|
82
83
|
screen,
|
|
83
84
|
chatTitle: initialChatTitle(screen)
|
|
@@ -1324,7 +1325,8 @@ function FilterableAgentList({ agents, scope, onPick }) {
|
|
|
1324
1325
|
else if (key.name === "return") {
|
|
1325
1326
|
const agent = filtered[clamped];
|
|
1326
1327
|
if (!agent) return;
|
|
1327
|
-
|
|
1328
|
+
const store = useStore.getState();
|
|
1329
|
+
onPick(store.seedPrompt !== null || store.newConversationIntent ? {
|
|
1328
1330
|
kind: "chat",
|
|
1329
1331
|
agent,
|
|
1330
1332
|
conversation: {
|
|
@@ -3687,6 +3689,149 @@ function formatElapsed(totalSeconds) {
|
|
|
3687
3689
|
return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
|
|
3688
3690
|
}
|
|
3689
3691
|
|
|
3692
|
+
//#endregion
|
|
3693
|
+
//#region src/chat/tui/chat/clamp.ts
|
|
3694
|
+
/** Max bytes we keep for a single clamped string field (head + tail combined). */
|
|
3695
|
+
const MAX_FIELD_CHARS = 24e3;
|
|
3696
|
+
/** Below this a string is never worth clamping (avoids churn on small fields). */
|
|
3697
|
+
const MIN_CLAMP_CHARS = MAX_FIELD_CHARS + 2e3;
|
|
3698
|
+
/** Fraction of the budget kept from the head; the rest is kept from the tail. */
|
|
3699
|
+
const HEAD_FRACTION = .7;
|
|
3700
|
+
/**
|
|
3701
|
+
* Clamp one string to a head + tail with an elision marker in the middle.
|
|
3702
|
+
* Idempotent: a string already carrying our marker is returned unchanged, so
|
|
3703
|
+
* re-clamping a loaded-from-history item (or a re-render) never re-slices.
|
|
3704
|
+
*/
|
|
3705
|
+
function clampString(text) {
|
|
3706
|
+
if (text.length <= MIN_CLAMP_CHARS) return text;
|
|
3707
|
+
if (text.includes(ELISION_MARKER_TAG)) return text;
|
|
3708
|
+
const headLen = Math.floor(MAX_FIELD_CHARS * HEAD_FRACTION);
|
|
3709
|
+
const tailLen = MAX_FIELD_CHARS - headLen;
|
|
3710
|
+
const elided = text.length - MAX_FIELD_CHARS;
|
|
3711
|
+
const head = text.slice(0, headLen);
|
|
3712
|
+
const tail = text.slice(text.length - tailLen);
|
|
3713
|
+
return `${head}\n${elisionMarker(elided)}\n${tail}`;
|
|
3714
|
+
}
|
|
3715
|
+
/**
|
|
3716
|
+
* Append to a growing output buffer while keeping it bounded, preferring the
|
|
3717
|
+
* TAIL — for live streaming shell output the newest bytes are what you want on
|
|
3718
|
+
* screen. Used by the `!` and `/sandbox` streams, whose output would otherwise
|
|
3719
|
+
* grow without limit for a long-running command.
|
|
3720
|
+
*/
|
|
3721
|
+
function clampedAppend(current, chunk) {
|
|
3722
|
+
const next = current + chunk;
|
|
3723
|
+
if (next.length <= MIN_CLAMP_CHARS) return next;
|
|
3724
|
+
const priorMarkerLen = leadingMarkerLength(current);
|
|
3725
|
+
const bodyLen = next.length - priorMarkerLen;
|
|
3726
|
+
const kept = stripLeadingMarker(next.slice(next.length - MAX_FIELD_CHARS));
|
|
3727
|
+
return `${elisionMarker(Math.max(0, bodyLen - kept.length))}\n${kept}`;
|
|
3728
|
+
}
|
|
3729
|
+
/** Length (incl. trailing newline) of a marker line at the very start of `s`. */
|
|
3730
|
+
function leadingMarkerLength(s) {
|
|
3731
|
+
if (!s.startsWith(ELISION_MARKER_TAG)) return 0;
|
|
3732
|
+
const nl = s.indexOf("\n");
|
|
3733
|
+
return nl === -1 ? s.length : nl + 1;
|
|
3734
|
+
}
|
|
3735
|
+
function stripLeadingMarker(s) {
|
|
3736
|
+
return s.slice(leadingMarkerLength(s));
|
|
3737
|
+
}
|
|
3738
|
+
const ELISION_MARKER_TAG = "⋯ elided";
|
|
3739
|
+
function elisionMarker(bytes) {
|
|
3740
|
+
return `${ELISION_MARKER_TAG} ${formatBytes$2(bytes)} to save memory ⋯`;
|
|
3741
|
+
}
|
|
3742
|
+
function formatBytes$2(n) {
|
|
3743
|
+
if (n < 1024) return `${n} chars`;
|
|
3744
|
+
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
|
|
3745
|
+
return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
|
3746
|
+
}
|
|
3747
|
+
/**
|
|
3748
|
+
* Recursively clamp the large string fields of an arbitrary tool payload
|
|
3749
|
+
* (input or output `value`). Structure is preserved so the tool renderers,
|
|
3750
|
+
* which reach for known keys like `.stdout` / `.output` / `.content`, still
|
|
3751
|
+
* find them — only the *size* of long strings is bounded. Depth and breadth
|
|
3752
|
+
* are capped so a pathological payload can't make clamping itself expensive.
|
|
3753
|
+
*/
|
|
3754
|
+
function clampPayload(value, depth = 0) {
|
|
3755
|
+
if (typeof value === "string") return clampString(value);
|
|
3756
|
+
if (depth >= 6) return value;
|
|
3757
|
+
if (Array.isArray(value)) {
|
|
3758
|
+
const overLong = value.length > 5e3;
|
|
3759
|
+
const source = overLong ? value.slice(0, 5e3) : value;
|
|
3760
|
+
let changed = overLong;
|
|
3761
|
+
const mapped = source.map((v) => {
|
|
3762
|
+
const c = clampPayload(v, depth + 1);
|
|
3763
|
+
if (c !== v) changed = true;
|
|
3764
|
+
return c;
|
|
3765
|
+
});
|
|
3766
|
+
return changed ? mapped : value;
|
|
3767
|
+
}
|
|
3768
|
+
if (isRecord(value)) {
|
|
3769
|
+
let changed = false;
|
|
3770
|
+
const out = {};
|
|
3771
|
+
for (const [k, v] of Object.entries(value)) {
|
|
3772
|
+
const c = clampPayload(v, depth + 1);
|
|
3773
|
+
if (c !== v) changed = true;
|
|
3774
|
+
out[k] = c;
|
|
3775
|
+
}
|
|
3776
|
+
return changed ? out : value;
|
|
3777
|
+
}
|
|
3778
|
+
return value;
|
|
3779
|
+
}
|
|
3780
|
+
/**
|
|
3781
|
+
* Clamp a single MessageItem in place-safe (returns a new object only when it
|
|
3782
|
+
* actually changed). Applied by the reducer when a tool settles and by the
|
|
3783
|
+
* history loader for every loaded item. Streaming text bubbles are left alone
|
|
3784
|
+
* — they're bounded by the model's output and clamping mid-stream would fight
|
|
3785
|
+
* the append path; only large tool/shell payloads and finished long texts are
|
|
3786
|
+
* worth clamping.
|
|
3787
|
+
*/
|
|
3788
|
+
function clampItem(item) {
|
|
3789
|
+
switch (item.kind) {
|
|
3790
|
+
case "tool": {
|
|
3791
|
+
const input = item.input == null ? item.input : clampPayload(item.input);
|
|
3792
|
+
const inputText = item.inputText.length > MIN_CLAMP_CHARS ? clampString(item.inputText) : item.inputText;
|
|
3793
|
+
let output = item.output;
|
|
3794
|
+
if (output?.kind === "ok") {
|
|
3795
|
+
const value = clampPayload(output.value);
|
|
3796
|
+
if (value !== output.value) output = {
|
|
3797
|
+
kind: "ok",
|
|
3798
|
+
value
|
|
3799
|
+
};
|
|
3800
|
+
} else if (output?.kind === "error") {
|
|
3801
|
+
const errorText = clampString(output.errorText);
|
|
3802
|
+
if (errorText !== output.errorText) output = {
|
|
3803
|
+
kind: "error",
|
|
3804
|
+
errorText
|
|
3805
|
+
};
|
|
3806
|
+
}
|
|
3807
|
+
if (input === item.input && inputText === item.inputText && output === item.output) return item;
|
|
3808
|
+
return {
|
|
3809
|
+
...item,
|
|
3810
|
+
input,
|
|
3811
|
+
inputText,
|
|
3812
|
+
output
|
|
3813
|
+
};
|
|
3814
|
+
}
|
|
3815
|
+
case "shell": {
|
|
3816
|
+
const clamped = clampString(item.output);
|
|
3817
|
+
return clamped === item.output ? item : {
|
|
3818
|
+
...item,
|
|
3819
|
+
output: clamped
|
|
3820
|
+
};
|
|
3821
|
+
}
|
|
3822
|
+
case "assistant-text":
|
|
3823
|
+
case "reasoning": {
|
|
3824
|
+
if (!item.done) return item;
|
|
3825
|
+
const clamped = clampString(item.text);
|
|
3826
|
+
return clamped === item.text ? item : {
|
|
3827
|
+
...item,
|
|
3828
|
+
text: clamped
|
|
3829
|
+
};
|
|
3830
|
+
}
|
|
3831
|
+
default: return item;
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3834
|
+
|
|
3690
3835
|
//#endregion
|
|
3691
3836
|
//#region src/chat/tui/chat/reducer.ts
|
|
3692
3837
|
function str(chunk, key) {
|
|
@@ -3769,7 +3914,7 @@ function applyChunk(items, chunk, agentName = null) {
|
|
|
3769
3914
|
case "tool-input-available": {
|
|
3770
3915
|
const toolCallId = str(chunk, "toolCallId");
|
|
3771
3916
|
const toolName = str(chunk, "toolName");
|
|
3772
|
-
const input = chunk.input
|
|
3917
|
+
const input = chunk.input == null ? null : clampPayload(chunk.input);
|
|
3773
3918
|
if (!toolCallId) return [...items];
|
|
3774
3919
|
if (items.find((m) => m.kind === "tool" && m.id === toolCallId)) return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
|
|
3775
3920
|
...m,
|
|
@@ -3790,7 +3935,7 @@ function applyChunk(items, chunk, agentName = null) {
|
|
|
3790
3935
|
case "tool-output-available": {
|
|
3791
3936
|
const toolCallId = str(chunk, "toolCallId");
|
|
3792
3937
|
if (!toolCallId) return [...items];
|
|
3793
|
-
const output = chunk.output
|
|
3938
|
+
const output = chunk.output == null ? null : clampPayload(chunk.output);
|
|
3794
3939
|
return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
|
|
3795
3940
|
...m,
|
|
3796
3941
|
output: {
|
|
@@ -3803,7 +3948,7 @@ function applyChunk(items, chunk, agentName = null) {
|
|
|
3803
3948
|
case "tool-output-error": {
|
|
3804
3949
|
const toolCallId = str(chunk, "toolCallId");
|
|
3805
3950
|
if (!toolCallId) return [...items];
|
|
3806
|
-
const errorText = str(chunk, "errorText") ?? "tool error";
|
|
3951
|
+
const errorText = clampString(str(chunk, "errorText") ?? "tool error");
|
|
3807
3952
|
return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
|
|
3808
3953
|
...m,
|
|
3809
3954
|
output: {
|
|
@@ -3957,6 +4102,32 @@ function nextCardId(items, toolCallId) {
|
|
|
3957
4102
|
return `${toolCallId}#c${items.filter((m) => m.kind === "card" && m.toolCallId === toolCallId).length}`;
|
|
3958
4103
|
}
|
|
3959
4104
|
|
|
4105
|
+
//#endregion
|
|
4106
|
+
//#region src/chat/tui/chat/window.ts
|
|
4107
|
+
/** Max transcript rows mounted at once. */
|
|
4108
|
+
const MAX_MOUNTED_ROWS = 400;
|
|
4109
|
+
/**
|
|
4110
|
+
* Keep the most recent `max` rows mounted; report how many older ones were
|
|
4111
|
+
* dropped from the mount so the UI can show a "N earlier messages" marker.
|
|
4112
|
+
*/
|
|
4113
|
+
function windowItems(items, max = MAX_MOUNTED_ROWS) {
|
|
4114
|
+
if (items.length <= max) return {
|
|
4115
|
+
visible: items.map((item, index) => ({
|
|
4116
|
+
item,
|
|
4117
|
+
index
|
|
4118
|
+
})),
|
|
4119
|
+
hiddenCount: 0
|
|
4120
|
+
};
|
|
4121
|
+
const start = items.length - max;
|
|
4122
|
+
return {
|
|
4123
|
+
visible: items.slice(start).map((item, offset) => ({
|
|
4124
|
+
item,
|
|
4125
|
+
index: start + offset
|
|
4126
|
+
})),
|
|
4127
|
+
hiddenCount: start
|
|
4128
|
+
};
|
|
4129
|
+
}
|
|
4130
|
+
|
|
3960
4131
|
//#endregion
|
|
3961
4132
|
//#region src/chat/tui/chat/attribution.ts
|
|
3962
4133
|
/**
|
|
@@ -4116,7 +4287,7 @@ function uiMessagesToItems(messages) {
|
|
|
4116
4287
|
});
|
|
4117
4288
|
}
|
|
4118
4289
|
}
|
|
4119
|
-
return out;
|
|
4290
|
+
return out.map(clampItem);
|
|
4120
4291
|
}
|
|
4121
4292
|
function mapToolState(raw) {
|
|
4122
4293
|
switch (raw) {
|
|
@@ -8797,6 +8968,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8797
8968
|
agentHost
|
|
8798
8969
|
]);
|
|
8799
8970
|
const multiAgent = useMemo(() => conversationAgentNames(items, agent.name), [items, agent.name]).size > 1;
|
|
8971
|
+
const transcriptWindow = useMemo(() => windowItems(items), [items]);
|
|
8800
8972
|
const themeGeneration = themeVersion();
|
|
8801
8973
|
useEffect(() => {
|
|
8802
8974
|
if (!rest || !conversationId) return;
|
|
@@ -9153,10 +9325,10 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9153
9325
|
}]);
|
|
9154
9326
|
let captured = "";
|
|
9155
9327
|
const appendOutput = (chunk) => {
|
|
9156
|
-
captured
|
|
9328
|
+
captured = clampedAppend(captured, chunk);
|
|
9157
9329
|
setItems((prev) => prev.map((m) => m.id === id && m.kind === "shell" ? {
|
|
9158
9330
|
...m,
|
|
9159
|
-
output: m.output
|
|
9331
|
+
output: clampedAppend(m.output, chunk)
|
|
9160
9332
|
} : m));
|
|
9161
9333
|
};
|
|
9162
9334
|
let exitCode;
|
|
@@ -9193,7 +9365,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9193
9365
|
const dec = new TextDecoder();
|
|
9194
9366
|
const append = (chunk) => setItems((prev) => prev.map((m) => m.id === id && m.kind === "shell" ? {
|
|
9195
9367
|
...m,
|
|
9196
|
-
output: m.output
|
|
9368
|
+
output: clampedAppend(m.output, chunk)
|
|
9197
9369
|
} : m));
|
|
9198
9370
|
const stamp = (exit) => setItems((prev) => prev.map((m) => m.id === id && m.kind === "shell" ? {
|
|
9199
9371
|
...m,
|
|
@@ -10103,11 +10275,26 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10103
10275
|
agent.name,
|
|
10104
10276
|
" below."
|
|
10105
10277
|
]
|
|
10106
|
-
}) :
|
|
10278
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [transcriptWindow.hiddenCount > 0 ? /* @__PURE__ */ jsx("box", {
|
|
10279
|
+
style: {
|
|
10280
|
+
paddingLeft: 1,
|
|
10281
|
+
paddingRight: 1
|
|
10282
|
+
},
|
|
10283
|
+
children: /* @__PURE__ */ jsxs("text", {
|
|
10284
|
+
fg: theme.dim,
|
|
10285
|
+
children: [
|
|
10286
|
+
"↑ ",
|
|
10287
|
+
transcriptWindow.hiddenCount,
|
|
10288
|
+
" earlier message",
|
|
10289
|
+
transcriptWindow.hiddenCount === 1 ? "" : "s",
|
|
10290
|
+
" · kept in this session, not shown"
|
|
10291
|
+
]
|
|
10292
|
+
})
|
|
10293
|
+
}) : null, transcriptWindow.visible.map(({ item, index }) => /* @__PURE__ */ jsx(TranscriptRow, {
|
|
10107
10294
|
item,
|
|
10108
|
-
label: multiAgent ? agentLabelFor(items,
|
|
10295
|
+
label: multiAgent ? agentLabelFor(items, index) : null,
|
|
10109
10296
|
themeVersion: themeGeneration
|
|
10110
|
-
}, item.id)), run.kind !== "idle" ? /* @__PURE__ */ jsx(ActivityRow, {
|
|
10297
|
+
}, item.id))] }), run.kind !== "idle" ? /* @__PURE__ */ jsx(ActivityRow, {
|
|
10111
10298
|
label: run.kind === "sending" ? "sending" : "working",
|
|
10112
10299
|
startedAtMs: run.startedAtMs
|
|
10113
10300
|
}) : null]
|
|
@@ -10526,7 +10713,7 @@ function ToastView() {
|
|
|
10526
10713
|
|
|
10527
10714
|
//#endregion
|
|
10528
10715
|
//#region src/chat/tui/app.tsx
|
|
10529
|
-
function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notifications, agentSelector, conversationId }) {
|
|
10716
|
+
function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notifications, agentSelector, conversationId, newConversation }) {
|
|
10530
10717
|
const renderer = useRenderer();
|
|
10531
10718
|
const screen = useStore((s) => s.screen);
|
|
10532
10719
|
const chatTitle = useStore((s) => s.chatTitle);
|
|
@@ -10608,7 +10795,7 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
10608
10795
|
rest,
|
|
10609
10796
|
agentSelector,
|
|
10610
10797
|
conversationId,
|
|
10611
|
-
newConversation: useStore.getState().seedPrompt !== null
|
|
10798
|
+
newConversation: newConversation || useStore.getState().seedPrompt !== null
|
|
10612
10799
|
});
|
|
10613
10800
|
if (cancelled) return;
|
|
10614
10801
|
goTo(screen);
|
|
@@ -10630,6 +10817,7 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
10630
10817
|
promptHistoryPath,
|
|
10631
10818
|
agentSelector,
|
|
10632
10819
|
conversationId,
|
|
10820
|
+
newConversation,
|
|
10633
10821
|
goTo,
|
|
10634
10822
|
setClients,
|
|
10635
10823
|
fail
|
|
@@ -10933,12 +11121,13 @@ var LinkifiedMarkdownRenderable = class extends MarkdownRenderable {
|
|
|
10933
11121
|
* module — and the heavy OpenTUI dependency graph it pulls in — is
|
|
10934
11122
|
* dynamically imported and never loaded on the Node management path.
|
|
10935
11123
|
*/
|
|
10936
|
-
async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath, theme: themeOverride, notifications, agentSelector, conversationId, seedPrompt }) {
|
|
11124
|
+
async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath, theme: themeOverride, notifications, agentSelector, conversationId, newConversation, seedPrompt }) {
|
|
10937
11125
|
const renderer = await createCliRenderer({ exitOnCtrlC: false });
|
|
10938
11126
|
extend({ markdown: LinkifiedMarkdownRenderable });
|
|
10939
11127
|
useStore.setState({
|
|
10940
11128
|
seedPrompt: seedPrompt ?? null,
|
|
10941
|
-
autoGrantMachine: Boolean(seedPrompt && shareMachine)
|
|
11129
|
+
autoGrantMachine: Boolean(seedPrompt && shareMachine),
|
|
11130
|
+
newConversationIntent: newConversation
|
|
10942
11131
|
});
|
|
10943
11132
|
const store = useStore.getState();
|
|
10944
11133
|
if (noColorRequested()) {
|
|
@@ -10962,7 +11151,8 @@ async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath,
|
|
|
10962
11151
|
promptHistoryPath,
|
|
10963
11152
|
notifications,
|
|
10964
11153
|
agentSelector: agentSelector ?? null,
|
|
10965
|
-
conversationId: conversationId ?? null
|
|
11154
|
+
conversationId: conversationId ?? null,
|
|
11155
|
+
newConversation
|
|
10966
11156
|
}));
|
|
10967
11157
|
}
|
|
10968
11158
|
/** Open the same workspace picker used by the initial agent screen. */
|