skydive-cli 0.2.0-beta.600 → 0.2.0-beta.605
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/{api-Bx5VyWaC.mjs → api-BGWcPuik.mjs} +1 -1
- package/dist/js/bin.mjs +30 -16
- package/dist/js/{boot-Dj_fZZA_.mjs → boot-B_I9v5NI.mjs} +316 -23
- package/dist/js/client-BRfmlbgI.mjs +6 -0
- package/dist/js/{client-BsLCAWf1.mjs → client-l3OrGKaC.mjs} +2 -2
- package/dist/js/{print-DLGCpIM9.mjs → print-6Bm51XhR.mjs} +1 -1
- package/dist/js/{print-QPPaRx38.mjs → print-qXJymvuF.mjs} +2 -2
- package/dist/js/{print-share-DPsQq2Cy.mjs → print-share-DE_dkZX7.mjs} +1 -1
- package/dist/js/{rest-nx0AmgJy.mjs → rest-C3RySrPa.mjs} +1 -1
- package/dist/js/{rest-vu2-Lrsa.mjs → rest-DMpigwmN.mjs} +3 -1
- package/package.json +1 -1
- package/dist/js/client-BYYp0E6M.mjs +0 -6
package/dist/js/bin.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { A as getPromptHistoryPath, B as resolveSession, C as API_KEY_PREFIX, D as deleteConfig, E as DEFAULT_WEB_URL, F as getStoredApiKeyWorkspaceName, G as setLastSeenVersion, H as saveConfig, I as getUpdateCheckDisabled, L as resolveAppUrl, N as getShareMachineDefault, O as getConfigPath, P as getStoredApiKeyId, R as resolveConfig, S as API_KEY_FAMILY_PREFIX, U as saveSession, _ as getActiveWorkspaceId, b as setActiveWorkspace, g as ensureActiveOrganization, k as getLastSeenVersion, m as themes, r as brandHelpArt, v as getSessionIdentity, w as DEFAULT_API_URL, x as API_KEYS_URL, y as listWorkspaces, z as resolveManagementAuth } from "./brand-BVALAEf1.mjs";
|
|
3
3
|
import { n as printError, r as printTable, t as output } from "./output-B4cW10Ph.mjs";
|
|
4
|
-
import { n as createRestClient } from "./rest-
|
|
5
|
-
import { i as resolveAgent } from "./print-
|
|
6
|
-
import { a as registerPortalDevice, c as machineIdentity, n as findThisDevice, o as revokePortalAccess, r as grantPortalAccess, t as fetchPortalDevices } from "./api-
|
|
4
|
+
import { n as createRestClient } from "./rest-DMpigwmN.mjs";
|
|
5
|
+
import { i as resolveAgent } from "./print-6Bm51XhR.mjs";
|
|
6
|
+
import { a as registerPortalDevice, c as machineIdentity, n as findThisDevice, o as revokePortalAccess, r as grantPortalAccess, t as fetchPortalDevices } from "./api-BGWcPuik.mjs";
|
|
7
7
|
import { t as SandboxStream } from "./client-BVOAwU8M.mjs";
|
|
8
8
|
import { hideBin } from "yargs/helpers";
|
|
9
9
|
import yargs from "yargs";
|
|
@@ -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.605";
|
|
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-B_I9v5NI.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
|
}
|
|
@@ -1226,7 +1227,7 @@ async function runImportPrintMode({ argv, appUrl }) {
|
|
|
1226
1227
|
printError(`${session.error.message} For non-interactive use, run \`skydive auth login --web\` first, or set SKYDIVE_SESSION_TOKEN.`);
|
|
1227
1228
|
process.exit(1);
|
|
1228
1229
|
}
|
|
1229
|
-
const { connectMachineShare } = await import("./print-share-
|
|
1230
|
+
const { connectMachineShare } = await import("./print-share-DE_dkZX7.mjs");
|
|
1230
1231
|
const machineShare = await connectMachineShare({
|
|
1231
1232
|
appUrl,
|
|
1232
1233
|
sessionToken: session.value.sessionToken,
|
|
@@ -1234,7 +1235,7 @@ async function runImportPrintMode({ argv, appUrl }) {
|
|
|
1234
1235
|
});
|
|
1235
1236
|
const extra = (argv.print ?? "").trim();
|
|
1236
1237
|
const prompt = buildImportSeedPrompt(process.cwd()) + (extra ? `\n\nAdditional instructions: ${extra}` : "");
|
|
1237
|
-
const { runPrint } = await import("./print-
|
|
1238
|
+
const { runPrint } = await import("./print-qXJymvuF.mjs");
|
|
1238
1239
|
try {
|
|
1239
1240
|
const result = await runPrint({
|
|
1240
1241
|
appUrl,
|
|
@@ -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-B_I9v5NI.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,13 +1539,21 @@ 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()) {
|
|
1539
1553
|
printError(`${session.error.message} For non-interactive use, run \`skydive auth login\` first, or set SKYDIVE_SESSION_TOKEN.`);
|
|
1540
1554
|
process.exit(1);
|
|
1541
1555
|
}
|
|
1542
|
-
const { runPrint, readStdin } = await import("./print-
|
|
1556
|
+
const { runPrint, readStdin } = await import("./print-qXJymvuF.mjs");
|
|
1543
1557
|
let prompt = (argv.print ?? "").trim();
|
|
1544
1558
|
if (!prompt) {
|
|
1545
1559
|
if (process.stdin.isTTY) {
|
|
@@ -1554,7 +1568,7 @@ async function runPrintMode({ argv, appUrl }) {
|
|
|
1554
1568
|
}
|
|
1555
1569
|
let machineShare = null;
|
|
1556
1570
|
if (resolveShareMachine(argv)) {
|
|
1557
|
-
const { connectMachineShare } = await import("./print-share-
|
|
1571
|
+
const { connectMachineShare } = await import("./print-share-DE_dkZX7.mjs");
|
|
1558
1572
|
machineShare = await connectMachineShare({
|
|
1559
1573
|
appUrl,
|
|
1560
1574
|
sessionToken: session.value.sessionToken,
|
|
@@ -1613,7 +1627,7 @@ const getCommand = {
|
|
|
1613
1627
|
printError(`${session.error.message} Run \`skydive auth login\` first, or set SKYDIVE_SESSION_TOKEN.`);
|
|
1614
1628
|
process.exit(1);
|
|
1615
1629
|
}
|
|
1616
|
-
const { messageGet } = await import("./print-
|
|
1630
|
+
const { messageGet } = await import("./print-qXJymvuF.mjs");
|
|
1617
1631
|
try {
|
|
1618
1632
|
const result = await messageGet({
|
|
1619
1633
|
appUrl,
|
|
@@ -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-B_I9v5NI.mjs");
|
|
1814
1828
|
await runWorkspacePicker(session);
|
|
1815
1829
|
return;
|
|
1816
1830
|
}
|
|
@@ -1888,7 +1902,7 @@ const openCommand = {
|
|
|
1888
1902
|
const agent = argv.agent ? resolveAgent((await fetchPortalDevices(session)).agents, argv.agent) : null;
|
|
1889
1903
|
const cwd = argv.cwd ? path.resolve(argv.cwd) : process.cwd();
|
|
1890
1904
|
const { machineName } = machineIdentity();
|
|
1891
|
-
const { PortalClient } = await import("./client-
|
|
1905
|
+
const { PortalClient } = await import("./client-BRfmlbgI.mjs");
|
|
1892
1906
|
let lastLine = "";
|
|
1893
1907
|
let signalConnected;
|
|
1894
1908
|
const connected = new Promise((resolve) => {
|
|
@@ -2060,8 +2074,8 @@ const sandboxCommand = {
|
|
|
2060
2074
|
}).example("skydive sandbox --agent grace", "Live terminal (Ctrl-] detaches)").example("skydive sandbox --agent grace -- tail -n 50 /tmp/harness.log", "One-shot command (use `--` so its flags reach the sandbox)").example("skydive sandbox --agent grace -- sh -c 'ls /tmp | wc -l'", "Shell features go through an explicit `sh -c`"),
|
|
2061
2075
|
handler: async (argv) => {
|
|
2062
2076
|
const session = requireSession(argv);
|
|
2063
|
-
const { createRestClient } = await import("./rest-
|
|
2064
|
-
const { resolveAgent } = await import("./print-
|
|
2077
|
+
const { createRestClient } = await import("./rest-C3RySrPa.mjs");
|
|
2078
|
+
const { resolveAgent } = await import("./print-qXJymvuF.mjs");
|
|
2065
2079
|
const client = createRestClient({
|
|
2066
2080
|
appUrl: session.appUrl,
|
|
2067
2081
|
sessionToken: session.sessionToken
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { M as getSavedTheme, O as getConfigPath, T as DEFAULT_APP_URL, V as resolveWebUrl, W as saveTheme, _ as getActiveWorkspaceId, a as applyTheme, b as setActiveWorkspace, c as noColorRequested, d as themeMode, f as themeModeFromColorFgBg, h as themesForMode, i as DEFAULT_THEME_ID, j as getReviewStateDir, l as theme, n as WORDMARK, o as findTheme, p as themeVersion, s as monoTheme, t as MARK_CELLS, u as themeForMode, w as DEFAULT_API_URL, y as listWorkspaces } from "./brand-BVALAEf1.mjs";
|
|
3
|
-
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-
|
|
4
|
-
import { c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams } from "./print-
|
|
5
|
-
import "./api-
|
|
3
|
+
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, r as errorDetail, t as HttpError } from "./rest-DMpigwmN.mjs";
|
|
4
|
+
import { c as cardActionErrorMessage, d as reconcileMaskedInput, f as resolveConnectUrl, i as resolveAgent, l as parseExternalOauthConnectParams, m as specKeyFor, p as parseConnectCard, s as MASK_CHAR, u as parseOauthConnectParams } from "./print-6Bm51XhR.mjs";
|
|
5
|
+
import "./api-BGWcPuik.mjs";
|
|
6
6
|
import { t as SandboxStream } from "./client-BVOAwU8M.mjs";
|
|
7
|
-
import { t as PortalClient } from "./client-
|
|
7
|
+
import { t as PortalClient } from "./client-l3OrGKaC.mjs";
|
|
8
8
|
import { t as runRawPtyPassthrough } from "./raw-pty-Dbi2kb9v.mjs";
|
|
9
9
|
import * as os$1 from "node:os";
|
|
10
10
|
import { homedir, platform, release, tmpdir } from "node:os";
|
|
@@ -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: {
|
|
@@ -1860,8 +1862,28 @@ function fitHintLine(segments, width) {
|
|
|
1860
1862
|
return truncate(kept.join(" · "), width);
|
|
1861
1863
|
}
|
|
1862
1864
|
|
|
1865
|
+
//#endregion
|
|
1866
|
+
//#region src/chat/tui/use-debounced-value.ts
|
|
1867
|
+
/**
|
|
1868
|
+
* Returns a copy of `value` that only updates after it has stopped changing
|
|
1869
|
+
* for `delayMs`. Use it to throttle work driven by fast-changing state — e.g.
|
|
1870
|
+
* a search input whose every keystroke would otherwise fire a new request.
|
|
1871
|
+
*
|
|
1872
|
+
* Mirrors the web app's `useDebouncedValue` so the CLI conversation search
|
|
1873
|
+
* debounces its server query the same way the web sidebar does.
|
|
1874
|
+
*/
|
|
1875
|
+
function useDebouncedValue(value, delayMs) {
|
|
1876
|
+
const [debounced, setDebounced] = useState(value);
|
|
1877
|
+
useEffect(() => {
|
|
1878
|
+
const timer = setTimeout(() => setDebounced(value), delayMs);
|
|
1879
|
+
return () => clearTimeout(timer);
|
|
1880
|
+
}, [value, delayMs]);
|
|
1881
|
+
return debounced;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1863
1884
|
//#endregion
|
|
1864
1885
|
//#region src/chat/tui/screens/conversation-picker.tsx
|
|
1886
|
+
const SEARCH_DEBOUNCE_MS = 250;
|
|
1865
1887
|
const humanChannels = [
|
|
1866
1888
|
"web",
|
|
1867
1889
|
"slack",
|
|
@@ -1969,16 +1991,83 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1969
1991
|
const rest = useStore((s) => s.rest);
|
|
1970
1992
|
const [query, setQuery] = useState("");
|
|
1971
1993
|
const [highlight, setHighlight] = useState(0);
|
|
1994
|
+
const debouncedQuery = useDebouncedValue(query.trim(), SEARCH_DEBOUNCE_MS);
|
|
1995
|
+
const isSearching = debouncedQuery.length > 0;
|
|
1996
|
+
const [search, setSearch] = useState(null);
|
|
1997
|
+
useEffect(() => {
|
|
1998
|
+
if (!rest || !isSearching) {
|
|
1999
|
+
setSearch(null);
|
|
2000
|
+
return;
|
|
2001
|
+
}
|
|
2002
|
+
let cancelled = false;
|
|
2003
|
+
setSearch({
|
|
2004
|
+
query: debouncedQuery,
|
|
2005
|
+
state: { kind: "loading" }
|
|
2006
|
+
});
|
|
2007
|
+
(async () => {
|
|
2008
|
+
try {
|
|
2009
|
+
const results = await rest.listConversations({
|
|
2010
|
+
agentId: agent.id,
|
|
2011
|
+
channels: showAutomated ? void 0 : humanChannels,
|
|
2012
|
+
archived: showArchived ? "include" : "exclude",
|
|
2013
|
+
query: debouncedQuery,
|
|
2014
|
+
onPage: (partial) => {
|
|
2015
|
+
if (!cancelled) setSearch({
|
|
2016
|
+
query: debouncedQuery,
|
|
2017
|
+
state: {
|
|
2018
|
+
kind: "ready",
|
|
2019
|
+
conversations: partial
|
|
2020
|
+
}
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
});
|
|
2024
|
+
if (cancelled) return;
|
|
2025
|
+
setSearch({
|
|
2026
|
+
query: debouncedQuery,
|
|
2027
|
+
state: {
|
|
2028
|
+
kind: "ready",
|
|
2029
|
+
conversations: results
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
2032
|
+
} catch (err) {
|
|
2033
|
+
if (cancelled) return;
|
|
2034
|
+
setSearch({
|
|
2035
|
+
query: debouncedQuery,
|
|
2036
|
+
state: {
|
|
2037
|
+
kind: "error",
|
|
2038
|
+
message: err instanceof Error ? err.message : String(err)
|
|
2039
|
+
}
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
2042
|
+
})();
|
|
2043
|
+
return () => {
|
|
2044
|
+
cancelled = true;
|
|
2045
|
+
};
|
|
2046
|
+
}, [
|
|
2047
|
+
rest,
|
|
2048
|
+
agent.id,
|
|
2049
|
+
debouncedQuery,
|
|
2050
|
+
isSearching,
|
|
2051
|
+
showAutomated,
|
|
2052
|
+
showArchived
|
|
2053
|
+
]);
|
|
1972
2054
|
const [removedIds, setRemovedIds] = useState(/* @__PURE__ */ new Set());
|
|
1973
2055
|
const [archiveOverrides, setArchiveOverrides] = useState(/* @__PURE__ */ new Map());
|
|
1974
2056
|
const [confirmId, setConfirmId] = useState(null);
|
|
1975
2057
|
const [error, setError] = useState(null);
|
|
1976
2058
|
const isArchived = (c) => archiveOverrides.get(c.id) ?? c.viewerArchivedAt != null;
|
|
1977
|
-
const list = conversations.filter((c) => !removedIds.has(c.id) && (showArchived || !isArchived(c)));
|
|
2059
|
+
const list = ((isSearching && search?.query === debouncedQuery && search.state.kind === "ready" ? search.state.conversations : null) ?? conversations).filter((c) => !removedIds.has(c.id) && (showArchived || !isArchived(c)));
|
|
1978
2060
|
useEffect(() => {
|
|
1979
2061
|
setHighlight(0);
|
|
1980
2062
|
}, [showAutomated, showArchived]);
|
|
1981
|
-
const hits =
|
|
2063
|
+
const hits = isSearching ? list.map((item) => ({
|
|
2064
|
+
item,
|
|
2065
|
+
highlights: [
|
|
2066
|
+
substringIndexes(singleLine(item.title ?? ""), debouncedQuery),
|
|
2067
|
+
null,
|
|
2068
|
+
null
|
|
2069
|
+
]
|
|
2070
|
+
})) : fuzzyFilter(query, list, conversationKeys);
|
|
1982
2071
|
const rows = [{ kind: "new" }, ...hits.map((hit) => ({
|
|
1983
2072
|
kind: "conv",
|
|
1984
2073
|
hit
|
|
@@ -1989,6 +2078,8 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1989
2078
|
const highlightRow = rows[clamped];
|
|
1990
2079
|
const highlightArchived = highlightRow?.kind === "conv" && isArchived(highlightRow.hit.item);
|
|
1991
2080
|
const confirmConv = confirmId !== null ? list.find((c) => c.id === confirmId) : void 0;
|
|
2081
|
+
const searchState = isSearching ? search?.state : void 0;
|
|
2082
|
+
const countSegment = isSearching && (searchState?.kind === "loading" || search === null) ? "searching…" : isSearching && searchState?.kind === "error" ? `search failed: ${searchState.message}` : `${hits.length}/${list.length}${complete || isSearching ? "" : " (loading…)"}`;
|
|
1992
2083
|
const status = confirmConv ? {
|
|
1993
2084
|
fg: theme.error,
|
|
1994
2085
|
text: truncate(`delete “${confirmConv.title ?? "(untitled)"}”? y/n`, innerWidth)
|
|
@@ -1998,7 +2089,7 @@ function ConversationList({ agent, conversations, complete, showAutomated, onTog
|
|
|
1998
2089
|
} : {
|
|
1999
2090
|
fg: theme.dim,
|
|
2000
2091
|
text: fitHintLine([
|
|
2001
|
-
|
|
2092
|
+
countSegment,
|
|
2002
2093
|
`ctrl+a ${highlightArchived ? "unarchive" : "archive"}`,
|
|
2003
2094
|
"ctrl+d delete",
|
|
2004
2095
|
`tab ${showAutomated ? "hide" : "show"} agent runs`,
|
|
@@ -2189,6 +2280,20 @@ const conversationKeys = [
|
|
|
2189
2280
|
(c) => c.preview ?? "",
|
|
2190
2281
|
(c) => conversationAgents(c).map((a) => a.name).join(" ")
|
|
2191
2282
|
];
|
|
2283
|
+
/**
|
|
2284
|
+
* Character indexes of the first case-insensitive occurrence of `needle` in
|
|
2285
|
+
* `haystack`, for highlighting a literal title match under server search (the
|
|
2286
|
+
* server's title branch is a substring ILIKE). Null when it doesn't occur — a
|
|
2287
|
+
* server row can match on message body or participant name without its title
|
|
2288
|
+
* containing the query, in which case nothing in the title is highlighted.
|
|
2289
|
+
*/
|
|
2290
|
+
function substringIndexes(haystack, needle) {
|
|
2291
|
+
const trimmed = needle.trim();
|
|
2292
|
+
if (!trimmed) return null;
|
|
2293
|
+
const at = haystack.toLowerCase().indexOf(trimmed.toLowerCase());
|
|
2294
|
+
if (at < 0) return null;
|
|
2295
|
+
return Array.from({ length: trimmed.length }, (_, i) => at + i);
|
|
2296
|
+
}
|
|
2192
2297
|
function previewLine(c) {
|
|
2193
2298
|
const when = relativeTime(c.updatedAt);
|
|
2194
2299
|
const prefix = c.preview ? c.preview.replace(/\s+/g, " ").trim() : "";
|
|
@@ -3687,6 +3792,149 @@ function formatElapsed(totalSeconds) {
|
|
|
3687
3792
|
return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
|
|
3688
3793
|
}
|
|
3689
3794
|
|
|
3795
|
+
//#endregion
|
|
3796
|
+
//#region src/chat/tui/chat/clamp.ts
|
|
3797
|
+
/** Max bytes we keep for a single clamped string field (head + tail combined). */
|
|
3798
|
+
const MAX_FIELD_CHARS = 24e3;
|
|
3799
|
+
/** Below this a string is never worth clamping (avoids churn on small fields). */
|
|
3800
|
+
const MIN_CLAMP_CHARS = MAX_FIELD_CHARS + 2e3;
|
|
3801
|
+
/** Fraction of the budget kept from the head; the rest is kept from the tail. */
|
|
3802
|
+
const HEAD_FRACTION = .7;
|
|
3803
|
+
/**
|
|
3804
|
+
* Clamp one string to a head + tail with an elision marker in the middle.
|
|
3805
|
+
* Idempotent: a string already carrying our marker is returned unchanged, so
|
|
3806
|
+
* re-clamping a loaded-from-history item (or a re-render) never re-slices.
|
|
3807
|
+
*/
|
|
3808
|
+
function clampString(text) {
|
|
3809
|
+
if (text.length <= MIN_CLAMP_CHARS) return text;
|
|
3810
|
+
if (text.includes(ELISION_MARKER_TAG)) return text;
|
|
3811
|
+
const headLen = Math.floor(MAX_FIELD_CHARS * HEAD_FRACTION);
|
|
3812
|
+
const tailLen = MAX_FIELD_CHARS - headLen;
|
|
3813
|
+
const elided = text.length - MAX_FIELD_CHARS;
|
|
3814
|
+
const head = text.slice(0, headLen);
|
|
3815
|
+
const tail = text.slice(text.length - tailLen);
|
|
3816
|
+
return `${head}\n${elisionMarker(elided)}\n${tail}`;
|
|
3817
|
+
}
|
|
3818
|
+
/**
|
|
3819
|
+
* Append to a growing output buffer while keeping it bounded, preferring the
|
|
3820
|
+
* TAIL — for live streaming shell output the newest bytes are what you want on
|
|
3821
|
+
* screen. Used by the `!` and `/sandbox` streams, whose output would otherwise
|
|
3822
|
+
* grow without limit for a long-running command.
|
|
3823
|
+
*/
|
|
3824
|
+
function clampedAppend(current, chunk) {
|
|
3825
|
+
const next = current + chunk;
|
|
3826
|
+
if (next.length <= MIN_CLAMP_CHARS) return next;
|
|
3827
|
+
const priorMarkerLen = leadingMarkerLength(current);
|
|
3828
|
+
const bodyLen = next.length - priorMarkerLen;
|
|
3829
|
+
const kept = stripLeadingMarker(next.slice(next.length - MAX_FIELD_CHARS));
|
|
3830
|
+
return `${elisionMarker(Math.max(0, bodyLen - kept.length))}\n${kept}`;
|
|
3831
|
+
}
|
|
3832
|
+
/** Length (incl. trailing newline) of a marker line at the very start of `s`. */
|
|
3833
|
+
function leadingMarkerLength(s) {
|
|
3834
|
+
if (!s.startsWith(ELISION_MARKER_TAG)) return 0;
|
|
3835
|
+
const nl = s.indexOf("\n");
|
|
3836
|
+
return nl === -1 ? s.length : nl + 1;
|
|
3837
|
+
}
|
|
3838
|
+
function stripLeadingMarker(s) {
|
|
3839
|
+
return s.slice(leadingMarkerLength(s));
|
|
3840
|
+
}
|
|
3841
|
+
const ELISION_MARKER_TAG = "⋯ elided";
|
|
3842
|
+
function elisionMarker(bytes) {
|
|
3843
|
+
return `${ELISION_MARKER_TAG} ${formatBytes$2(bytes)} to save memory ⋯`;
|
|
3844
|
+
}
|
|
3845
|
+
function formatBytes$2(n) {
|
|
3846
|
+
if (n < 1024) return `${n} chars`;
|
|
3847
|
+
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
|
|
3848
|
+
return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
|
3849
|
+
}
|
|
3850
|
+
/**
|
|
3851
|
+
* Recursively clamp the large string fields of an arbitrary tool payload
|
|
3852
|
+
* (input or output `value`). Structure is preserved so the tool renderers,
|
|
3853
|
+
* which reach for known keys like `.stdout` / `.output` / `.content`, still
|
|
3854
|
+
* find them — only the *size* of long strings is bounded. Depth and breadth
|
|
3855
|
+
* are capped so a pathological payload can't make clamping itself expensive.
|
|
3856
|
+
*/
|
|
3857
|
+
function clampPayload(value, depth = 0) {
|
|
3858
|
+
if (typeof value === "string") return clampString(value);
|
|
3859
|
+
if (depth >= 6) return value;
|
|
3860
|
+
if (Array.isArray(value)) {
|
|
3861
|
+
const overLong = value.length > 5e3;
|
|
3862
|
+
const source = overLong ? value.slice(0, 5e3) : value;
|
|
3863
|
+
let changed = overLong;
|
|
3864
|
+
const mapped = source.map((v) => {
|
|
3865
|
+
const c = clampPayload(v, depth + 1);
|
|
3866
|
+
if (c !== v) changed = true;
|
|
3867
|
+
return c;
|
|
3868
|
+
});
|
|
3869
|
+
return changed ? mapped : value;
|
|
3870
|
+
}
|
|
3871
|
+
if (isRecord(value)) {
|
|
3872
|
+
let changed = false;
|
|
3873
|
+
const out = {};
|
|
3874
|
+
for (const [k, v] of Object.entries(value)) {
|
|
3875
|
+
const c = clampPayload(v, depth + 1);
|
|
3876
|
+
if (c !== v) changed = true;
|
|
3877
|
+
out[k] = c;
|
|
3878
|
+
}
|
|
3879
|
+
return changed ? out : value;
|
|
3880
|
+
}
|
|
3881
|
+
return value;
|
|
3882
|
+
}
|
|
3883
|
+
/**
|
|
3884
|
+
* Clamp a single MessageItem in place-safe (returns a new object only when it
|
|
3885
|
+
* actually changed). Applied by the reducer when a tool settles and by the
|
|
3886
|
+
* history loader for every loaded item. Streaming text bubbles are left alone
|
|
3887
|
+
* — they're bounded by the model's output and clamping mid-stream would fight
|
|
3888
|
+
* the append path; only large tool/shell payloads and finished long texts are
|
|
3889
|
+
* worth clamping.
|
|
3890
|
+
*/
|
|
3891
|
+
function clampItem(item) {
|
|
3892
|
+
switch (item.kind) {
|
|
3893
|
+
case "tool": {
|
|
3894
|
+
const input = item.input == null ? item.input : clampPayload(item.input);
|
|
3895
|
+
const inputText = item.inputText.length > MIN_CLAMP_CHARS ? clampString(item.inputText) : item.inputText;
|
|
3896
|
+
let output = item.output;
|
|
3897
|
+
if (output?.kind === "ok") {
|
|
3898
|
+
const value = clampPayload(output.value);
|
|
3899
|
+
if (value !== output.value) output = {
|
|
3900
|
+
kind: "ok",
|
|
3901
|
+
value
|
|
3902
|
+
};
|
|
3903
|
+
} else if (output?.kind === "error") {
|
|
3904
|
+
const errorText = clampString(output.errorText);
|
|
3905
|
+
if (errorText !== output.errorText) output = {
|
|
3906
|
+
kind: "error",
|
|
3907
|
+
errorText
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
if (input === item.input && inputText === item.inputText && output === item.output) return item;
|
|
3911
|
+
return {
|
|
3912
|
+
...item,
|
|
3913
|
+
input,
|
|
3914
|
+
inputText,
|
|
3915
|
+
output
|
|
3916
|
+
};
|
|
3917
|
+
}
|
|
3918
|
+
case "shell": {
|
|
3919
|
+
const clamped = clampString(item.output);
|
|
3920
|
+
return clamped === item.output ? item : {
|
|
3921
|
+
...item,
|
|
3922
|
+
output: clamped
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3925
|
+
case "assistant-text":
|
|
3926
|
+
case "reasoning": {
|
|
3927
|
+
if (!item.done) return item;
|
|
3928
|
+
const clamped = clampString(item.text);
|
|
3929
|
+
return clamped === item.text ? item : {
|
|
3930
|
+
...item,
|
|
3931
|
+
text: clamped
|
|
3932
|
+
};
|
|
3933
|
+
}
|
|
3934
|
+
default: return item;
|
|
3935
|
+
}
|
|
3936
|
+
}
|
|
3937
|
+
|
|
3690
3938
|
//#endregion
|
|
3691
3939
|
//#region src/chat/tui/chat/reducer.ts
|
|
3692
3940
|
function str(chunk, key) {
|
|
@@ -3769,7 +4017,7 @@ function applyChunk(items, chunk, agentName = null) {
|
|
|
3769
4017
|
case "tool-input-available": {
|
|
3770
4018
|
const toolCallId = str(chunk, "toolCallId");
|
|
3771
4019
|
const toolName = str(chunk, "toolName");
|
|
3772
|
-
const input = chunk.input
|
|
4020
|
+
const input = chunk.input == null ? null : clampPayload(chunk.input);
|
|
3773
4021
|
if (!toolCallId) return [...items];
|
|
3774
4022
|
if (items.find((m) => m.kind === "tool" && m.id === toolCallId)) return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
|
|
3775
4023
|
...m,
|
|
@@ -3790,7 +4038,7 @@ function applyChunk(items, chunk, agentName = null) {
|
|
|
3790
4038
|
case "tool-output-available": {
|
|
3791
4039
|
const toolCallId = str(chunk, "toolCallId");
|
|
3792
4040
|
if (!toolCallId) return [...items];
|
|
3793
|
-
const output = chunk.output
|
|
4041
|
+
const output = chunk.output == null ? null : clampPayload(chunk.output);
|
|
3794
4042
|
return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
|
|
3795
4043
|
...m,
|
|
3796
4044
|
output: {
|
|
@@ -3803,7 +4051,7 @@ function applyChunk(items, chunk, agentName = null) {
|
|
|
3803
4051
|
case "tool-output-error": {
|
|
3804
4052
|
const toolCallId = str(chunk, "toolCallId");
|
|
3805
4053
|
if (!toolCallId) return [...items];
|
|
3806
|
-
const errorText = str(chunk, "errorText") ?? "tool error";
|
|
4054
|
+
const errorText = clampString(str(chunk, "errorText") ?? "tool error");
|
|
3807
4055
|
return items.map((m) => m.kind === "tool" && m.id === toolCallId ? {
|
|
3808
4056
|
...m,
|
|
3809
4057
|
output: {
|
|
@@ -3957,6 +4205,32 @@ function nextCardId(items, toolCallId) {
|
|
|
3957
4205
|
return `${toolCallId}#c${items.filter((m) => m.kind === "card" && m.toolCallId === toolCallId).length}`;
|
|
3958
4206
|
}
|
|
3959
4207
|
|
|
4208
|
+
//#endregion
|
|
4209
|
+
//#region src/chat/tui/chat/window.ts
|
|
4210
|
+
/** Max transcript rows mounted at once. */
|
|
4211
|
+
const MAX_MOUNTED_ROWS = 400;
|
|
4212
|
+
/**
|
|
4213
|
+
* Keep the most recent `max` rows mounted; report how many older ones were
|
|
4214
|
+
* dropped from the mount so the UI can show a "N earlier messages" marker.
|
|
4215
|
+
*/
|
|
4216
|
+
function windowItems(items, max = MAX_MOUNTED_ROWS) {
|
|
4217
|
+
if (items.length <= max) return {
|
|
4218
|
+
visible: items.map((item, index) => ({
|
|
4219
|
+
item,
|
|
4220
|
+
index
|
|
4221
|
+
})),
|
|
4222
|
+
hiddenCount: 0
|
|
4223
|
+
};
|
|
4224
|
+
const start = items.length - max;
|
|
4225
|
+
return {
|
|
4226
|
+
visible: items.slice(start).map((item, offset) => ({
|
|
4227
|
+
item,
|
|
4228
|
+
index: start + offset
|
|
4229
|
+
})),
|
|
4230
|
+
hiddenCount: start
|
|
4231
|
+
};
|
|
4232
|
+
}
|
|
4233
|
+
|
|
3960
4234
|
//#endregion
|
|
3961
4235
|
//#region src/chat/tui/chat/attribution.ts
|
|
3962
4236
|
/**
|
|
@@ -4116,7 +4390,7 @@ function uiMessagesToItems(messages) {
|
|
|
4116
4390
|
});
|
|
4117
4391
|
}
|
|
4118
4392
|
}
|
|
4119
|
-
return out;
|
|
4393
|
+
return out.map(clampItem);
|
|
4120
4394
|
}
|
|
4121
4395
|
function mapToolState(raw) {
|
|
4122
4396
|
switch (raw) {
|
|
@@ -8797,6 +9071,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
8797
9071
|
agentHost
|
|
8798
9072
|
]);
|
|
8799
9073
|
const multiAgent = useMemo(() => conversationAgentNames(items, agent.name), [items, agent.name]).size > 1;
|
|
9074
|
+
const transcriptWindow = useMemo(() => windowItems(items), [items]);
|
|
8800
9075
|
const themeGeneration = themeVersion();
|
|
8801
9076
|
useEffect(() => {
|
|
8802
9077
|
if (!rest || !conversationId) return;
|
|
@@ -9153,10 +9428,10 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9153
9428
|
}]);
|
|
9154
9429
|
let captured = "";
|
|
9155
9430
|
const appendOutput = (chunk) => {
|
|
9156
|
-
captured
|
|
9431
|
+
captured = clampedAppend(captured, chunk);
|
|
9157
9432
|
setItems((prev) => prev.map((m) => m.id === id && m.kind === "shell" ? {
|
|
9158
9433
|
...m,
|
|
9159
|
-
output: m.output
|
|
9434
|
+
output: clampedAppend(m.output, chunk)
|
|
9160
9435
|
} : m));
|
|
9161
9436
|
};
|
|
9162
9437
|
let exitCode;
|
|
@@ -9193,7 +9468,7 @@ function ChatScreen({ agent, conversation }) {
|
|
|
9193
9468
|
const dec = new TextDecoder();
|
|
9194
9469
|
const append = (chunk) => setItems((prev) => prev.map((m) => m.id === id && m.kind === "shell" ? {
|
|
9195
9470
|
...m,
|
|
9196
|
-
output: m.output
|
|
9471
|
+
output: clampedAppend(m.output, chunk)
|
|
9197
9472
|
} : m));
|
|
9198
9473
|
const stamp = (exit) => setItems((prev) => prev.map((m) => m.id === id && m.kind === "shell" ? {
|
|
9199
9474
|
...m,
|
|
@@ -10103,11 +10378,26 @@ function ChatScreen({ agent, conversation }) {
|
|
|
10103
10378
|
agent.name,
|
|
10104
10379
|
" below."
|
|
10105
10380
|
]
|
|
10106
|
-
}) :
|
|
10381
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [transcriptWindow.hiddenCount > 0 ? /* @__PURE__ */ jsx("box", {
|
|
10382
|
+
style: {
|
|
10383
|
+
paddingLeft: 1,
|
|
10384
|
+
paddingRight: 1
|
|
10385
|
+
},
|
|
10386
|
+
children: /* @__PURE__ */ jsxs("text", {
|
|
10387
|
+
fg: theme.dim,
|
|
10388
|
+
children: [
|
|
10389
|
+
"↑ ",
|
|
10390
|
+
transcriptWindow.hiddenCount,
|
|
10391
|
+
" earlier message",
|
|
10392
|
+
transcriptWindow.hiddenCount === 1 ? "" : "s",
|
|
10393
|
+
" · kept in this session, not shown"
|
|
10394
|
+
]
|
|
10395
|
+
})
|
|
10396
|
+
}) : null, transcriptWindow.visible.map(({ item, index }) => /* @__PURE__ */ jsx(TranscriptRow, {
|
|
10107
10397
|
item,
|
|
10108
|
-
label: multiAgent ? agentLabelFor(items,
|
|
10398
|
+
label: multiAgent ? agentLabelFor(items, index) : null,
|
|
10109
10399
|
themeVersion: themeGeneration
|
|
10110
|
-
}, item.id)), run.kind !== "idle" ? /* @__PURE__ */ jsx(ActivityRow, {
|
|
10400
|
+
}, item.id))] }), run.kind !== "idle" ? /* @__PURE__ */ jsx(ActivityRow, {
|
|
10111
10401
|
label: run.kind === "sending" ? "sending" : "working",
|
|
10112
10402
|
startedAtMs: run.startedAtMs
|
|
10113
10403
|
}) : null]
|
|
@@ -10526,7 +10816,7 @@ function ToastView() {
|
|
|
10526
10816
|
|
|
10527
10817
|
//#endregion
|
|
10528
10818
|
//#region src/chat/tui/app.tsx
|
|
10529
|
-
function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notifications, agentSelector, conversationId }) {
|
|
10819
|
+
function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notifications, agentSelector, conversationId, newConversation }) {
|
|
10530
10820
|
const renderer = useRenderer();
|
|
10531
10821
|
const screen = useStore((s) => s.screen);
|
|
10532
10822
|
const chatTitle = useStore((s) => s.chatTitle);
|
|
@@ -10608,7 +10898,7 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
10608
10898
|
rest,
|
|
10609
10899
|
agentSelector,
|
|
10610
10900
|
conversationId,
|
|
10611
|
-
newConversation: useStore.getState().seedPrompt !== null
|
|
10901
|
+
newConversation: newConversation || useStore.getState().seedPrompt !== null
|
|
10612
10902
|
});
|
|
10613
10903
|
if (cancelled) return;
|
|
10614
10904
|
goTo(screen);
|
|
@@ -10630,6 +10920,7 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
10630
10920
|
promptHistoryPath,
|
|
10631
10921
|
agentSelector,
|
|
10632
10922
|
conversationId,
|
|
10923
|
+
newConversation,
|
|
10633
10924
|
goTo,
|
|
10634
10925
|
setClients,
|
|
10635
10926
|
fail
|
|
@@ -10933,12 +11224,13 @@ var LinkifiedMarkdownRenderable = class extends MarkdownRenderable {
|
|
|
10933
11224
|
* module — and the heavy OpenTUI dependency graph it pulls in — is
|
|
10934
11225
|
* dynamically imported and never loaded on the Node management path.
|
|
10935
11226
|
*/
|
|
10936
|
-
async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath, theme: themeOverride, notifications, agentSelector, conversationId, seedPrompt }) {
|
|
11227
|
+
async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath, theme: themeOverride, notifications, agentSelector, conversationId, newConversation, seedPrompt }) {
|
|
10937
11228
|
const renderer = await createCliRenderer({ exitOnCtrlC: false });
|
|
10938
11229
|
extend({ markdown: LinkifiedMarkdownRenderable });
|
|
10939
11230
|
useStore.setState({
|
|
10940
11231
|
seedPrompt: seedPrompt ?? null,
|
|
10941
|
-
autoGrantMachine: Boolean(seedPrompt && shareMachine)
|
|
11232
|
+
autoGrantMachine: Boolean(seedPrompt && shareMachine),
|
|
11233
|
+
newConversationIntent: newConversation
|
|
10942
11234
|
});
|
|
10943
11235
|
const store = useStore.getState();
|
|
10944
11236
|
if (noColorRequested()) {
|
|
@@ -10962,7 +11254,8 @@ async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath,
|
|
|
10962
11254
|
promptHistoryPath,
|
|
10963
11255
|
notifications,
|
|
10964
11256
|
agentSelector: agentSelector ?? null,
|
|
10965
|
-
conversationId: conversationId ?? null
|
|
11257
|
+
conversationId: conversationId ?? null,
|
|
11258
|
+
newConversation
|
|
10966
11259
|
}));
|
|
10967
11260
|
}
|
|
10968
11261
|
/** Open the same workspace picker used by the initial agent screen. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as errorMessage } from "./rest-
|
|
3
|
-
import { c as machineIdentity, i as mintPortalDeviceToken, l as portalWsUrl, n as findThisDevice, r as grantPortalAccess, s as buildEnv, t as fetchPortalDevices } from "./api-
|
|
2
|
+
import { a as errorMessage } from "./rest-DMpigwmN.mjs";
|
|
3
|
+
import { c as machineIdentity, i as mintPortalDeviceToken, l as portalWsUrl, n as findThisDevice, r as grantPortalAccess, s as buildEnv, t as fetchPortalDevices } from "./api-BGWcPuik.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { WebSocket } from "ws";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, t as HttpError } from "./rest-
|
|
2
|
+
import { a as errorMessage, i as sendErrorMessage, n as createRestClient, o as isRecord, t as HttpError } from "./rest-DMpigwmN.mjs";
|
|
3
3
|
import stableStringify from "safe-stable-stringify";
|
|
4
4
|
|
|
5
5
|
//#region src/chat/tui/chat/card.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./rest-
|
|
3
|
-
import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-
|
|
2
|
+
import "./rest-DMpigwmN.mjs";
|
|
3
|
+
import { a as runPrint, i as resolveAgent, n as messageGet, o as toPrintError, r as readStdin, t as collectRunText } from "./print-6Bm51XhR.mjs";
|
|
4
4
|
|
|
5
5
|
export { messageGet, readStdin, resolveAgent, runPrint };
|
|
@@ -14,7 +14,7 @@ import { n as printError } from "./output-B4cW10Ph.mjs";
|
|
|
14
14
|
* the reply (and to --json).
|
|
15
15
|
*/
|
|
16
16
|
async function connectMachineShare({ appUrl, sessionToken, timeoutHint }) {
|
|
17
|
-
const { PortalClient } = await import("./client-
|
|
17
|
+
const { PortalClient } = await import("./client-BRfmlbgI.mjs");
|
|
18
18
|
let signalConnected;
|
|
19
19
|
const connected = new Promise((resolve) => {
|
|
20
20
|
signalConnected = resolve;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as sendErrorMessage, n as createRestClient, r as errorDetail, t as HttpError } from "./rest-
|
|
2
|
+
import { i as sendErrorMessage, n as createRestClient, r as errorDetail, t as HttpError } from "./rest-DMpigwmN.mjs";
|
|
3
3
|
|
|
4
4
|
export { createRestClient };
|
|
@@ -226,7 +226,8 @@ function createRestClient({ appUrl, sessionToken }) {
|
|
|
226
226
|
const { agent } = await post(`/api/v1/agents/${encodeURIComponent(agentId)}`, { model }, updateAgentResponseSchema, "PATCH");
|
|
227
227
|
return { model: agent.model ?? null };
|
|
228
228
|
},
|
|
229
|
-
listConversations: async ({ agentId, limit, channels, archived, onPage }) => {
|
|
229
|
+
listConversations: async ({ agentId, limit, channels, archived, query, onPage }) => {
|
|
230
|
+
const trimmedQuery = query?.trim();
|
|
230
231
|
const all = [];
|
|
231
232
|
const maxConversations = limit ?? 5e3;
|
|
232
233
|
let cursor;
|
|
@@ -239,6 +240,7 @@ function createRestClient({ appUrl, sessionToken }) {
|
|
|
239
240
|
params.set("limit", String(Math.min(remaining, 100)));
|
|
240
241
|
if (cursor) params.set("cursor", cursor);
|
|
241
242
|
if (archived) params.set("archived", archived);
|
|
243
|
+
if (trimmedQuery) params.set("query", trimmedQuery);
|
|
242
244
|
for (const channel of channels ?? []) params.append("channels", channel);
|
|
243
245
|
const page = await get(`/api/v1/conversations?${params.toString()}`, listConversationsResponseSchema);
|
|
244
246
|
all.push(...page.conversations);
|
package/package.json
CHANGED