@cofy-x/dsh-console 0.1.0-alpha.4 → 0.1.0-alpha.5
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/cordis.patch.yml +1 -0
- package/dist/{chunk-ZO6HZW3P.js → chunk-6BGDBP2N.js} +1875 -654
- package/dist/chunk-WTD7XY24.js +32 -0
- package/dist/dsh/index.d.ts +1 -0
- package/dist/dsh/index.js +2 -1
- package/dist/dsh/startup.d.ts +1 -0
- package/dist/dsh/startup.js +22 -7
- package/dist/index.js +2 -1
- package/package.json +7 -2
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
POKEMON_NUMBER_ENV,
|
|
3
|
+
resolvePokemonNumber
|
|
4
|
+
} from "./chunk-WTD7XY24.js";
|
|
1
5
|
import {
|
|
2
6
|
CoreEvent,
|
|
3
7
|
DEFAULT_FILE_FILTERING_OPTIONS,
|
|
@@ -71,7 +75,7 @@ import {
|
|
|
71
75
|
} from "@deepseek-ai/dsh-agent";
|
|
72
76
|
import { createUserMessage as createUserMessage2 } from "@deepseek-ai/dsh-llm";
|
|
73
77
|
import {
|
|
74
|
-
SessionId as
|
|
78
|
+
SessionId as SessionId4
|
|
75
79
|
} from "@deepseek-ai/dsh-session";
|
|
76
80
|
|
|
77
81
|
// src/utils/exit-codes.ts
|
|
@@ -208,6 +212,7 @@ function isLoadableSettingScope(scope) {
|
|
|
208
212
|
}
|
|
209
213
|
|
|
210
214
|
// src/config/settings-schema.ts
|
|
215
|
+
var EMPTY_CUSTOM_THEMES = {};
|
|
211
216
|
var SETTINGS_SCHEMA = {
|
|
212
217
|
general: {
|
|
213
218
|
type: "object",
|
|
@@ -279,7 +284,7 @@ var SETTINGS_SCHEMA = {
|
|
|
279
284
|
label: "Custom Themes",
|
|
280
285
|
category: "UI",
|
|
281
286
|
requiresRestart: false,
|
|
282
|
-
default:
|
|
287
|
+
default: EMPTY_CUSTOM_THEMES,
|
|
283
288
|
description: "Custom theme definitions.",
|
|
284
289
|
showInDialog: false,
|
|
285
290
|
additionalProperties: {
|
|
@@ -1464,10 +1469,6 @@ function loadEnvironment(settings) {
|
|
|
1464
1469
|
}
|
|
1465
1470
|
}
|
|
1466
1471
|
function loadSettings(workspaceDir = process.cwd()) {
|
|
1467
|
-
let systemSettings = {};
|
|
1468
|
-
let systemDefaultSettings = {};
|
|
1469
|
-
let userSettings = {};
|
|
1470
|
-
let workspaceSettings = {};
|
|
1471
1472
|
const settingsErrors = [];
|
|
1472
1473
|
const systemSettingsPath = getSystemSettingsPath();
|
|
1473
1474
|
const systemDefaultsPath = getSystemDefaultsPath();
|
|
@@ -1535,10 +1536,10 @@ function loadSettings(workspaceDir = process.cwd()) {
|
|
|
1535
1536
|
);
|
|
1536
1537
|
const userOriginalSettings = structuredClone(userResult.settings);
|
|
1537
1538
|
const workspaceOriginalSettings = structuredClone(workspaceResult.settings);
|
|
1538
|
-
systemSettings = resolveEnvVarsInObject(systemResult.settings);
|
|
1539
|
-
systemDefaultSettings = resolveEnvVarsInObject(systemDefaultsResult.settings);
|
|
1540
|
-
userSettings = resolveEnvVarsInObject(userResult.settings);
|
|
1541
|
-
workspaceSettings = resolveEnvVarsInObject(workspaceResult.settings);
|
|
1539
|
+
const systemSettings = resolveEnvVarsInObject(systemResult.settings);
|
|
1540
|
+
const systemDefaultSettings = resolveEnvVarsInObject(systemDefaultsResult.settings);
|
|
1541
|
+
const userSettings = resolveEnvVarsInObject(userResult.settings);
|
|
1542
|
+
const workspaceSettings = resolveEnvVarsInObject(workspaceResult.settings);
|
|
1542
1543
|
const isTrusted = true;
|
|
1543
1544
|
const tempMergedSettings = mergeSettings(
|
|
1544
1545
|
systemSettings,
|
|
@@ -1610,6 +1611,100 @@ function saveSettings(settingsFile) {
|
|
|
1610
1611
|
// src/config/cli-args.ts
|
|
1611
1612
|
import yargs from "yargs/yargs";
|
|
1612
1613
|
import { hideBin } from "yargs/helpers";
|
|
1614
|
+
|
|
1615
|
+
// src/utils/header-loader.ts
|
|
1616
|
+
import fs3 from "node:fs";
|
|
1617
|
+
import path2 from "node:path";
|
|
1618
|
+
var packageRoot = findPackageRoot(import.meta.url);
|
|
1619
|
+
var builtResources = path2.join(
|
|
1620
|
+
packageRoot,
|
|
1621
|
+
"dist/ui/components/layout/resources"
|
|
1622
|
+
);
|
|
1623
|
+
var sourceResources = path2.join(
|
|
1624
|
+
packageRoot,
|
|
1625
|
+
"src/ui/components/layout/resources"
|
|
1626
|
+
);
|
|
1627
|
+
var PokemonHeaderArtNotFoundError = class extends Error {
|
|
1628
|
+
constructor(pokemonNumber) {
|
|
1629
|
+
super(`Bundled Pokemon #${pokemonNumber} is not available.`);
|
|
1630
|
+
this.name = "PokemonHeaderArtNotFoundError";
|
|
1631
|
+
}
|
|
1632
|
+
};
|
|
1633
|
+
function resolveResourcesDir(resourceType, customPath) {
|
|
1634
|
+
if (resourceType === "custom") {
|
|
1635
|
+
if (!customPath) {
|
|
1636
|
+
return null;
|
|
1637
|
+
}
|
|
1638
|
+
return path2.resolve(process.cwd(), customPath);
|
|
1639
|
+
}
|
|
1640
|
+
if (resourceType === "pokemon" && customPath) {
|
|
1641
|
+
return path2.resolve(process.cwd(), customPath);
|
|
1642
|
+
}
|
|
1643
|
+
const builtResourceDir = path2.join(builtResources, resourceType);
|
|
1644
|
+
return fs3.existsSync(builtResourceDir) ? builtResourceDir : path2.join(sourceResources, resourceType);
|
|
1645
|
+
}
|
|
1646
|
+
function loadHeaderArt(resourceType = "pokemon", customPath, pokemonNumber) {
|
|
1647
|
+
try {
|
|
1648
|
+
const resourcesDir = resolveResourcesDir(resourceType, customPath);
|
|
1649
|
+
if (!resourcesDir) {
|
|
1650
|
+
if (pokemonNumber !== void 0) {
|
|
1651
|
+
throw new PokemonHeaderArtNotFoundError(pokemonNumber);
|
|
1652
|
+
}
|
|
1653
|
+
debugLogger.warn("Custom header art requires an art resources path.");
|
|
1654
|
+
return null;
|
|
1655
|
+
}
|
|
1656
|
+
if (!fs3.existsSync(resourcesDir)) {
|
|
1657
|
+
if (pokemonNumber !== void 0) {
|
|
1658
|
+
throw new PokemonHeaderArtNotFoundError(pokemonNumber);
|
|
1659
|
+
}
|
|
1660
|
+
debugLogger.warn(`Header art resources path not found: ${resourcesDir}`);
|
|
1661
|
+
return null;
|
|
1662
|
+
}
|
|
1663
|
+
const files = fs3.readdirSync(resourcesDir).filter((file) => file.endsWith(".txt")).sort();
|
|
1664
|
+
if (files.length === 0) {
|
|
1665
|
+
if (pokemonNumber !== void 0) {
|
|
1666
|
+
throw new PokemonHeaderArtNotFoundError(pokemonNumber);
|
|
1667
|
+
}
|
|
1668
|
+
return null;
|
|
1669
|
+
}
|
|
1670
|
+
const selectedFile = pokemonNumber === void 0 ? files[Math.floor(Math.random() * files.length)] : files.find((file) => {
|
|
1671
|
+
const match = /^(\d+)(?:-|\.txt$)/.exec(file);
|
|
1672
|
+
return match?.[1] !== void 0 && Number(match[1]) === pokemonNumber;
|
|
1673
|
+
});
|
|
1674
|
+
if (!selectedFile) {
|
|
1675
|
+
if (pokemonNumber !== void 0) {
|
|
1676
|
+
throw new PokemonHeaderArtNotFoundError(pokemonNumber);
|
|
1677
|
+
}
|
|
1678
|
+
return null;
|
|
1679
|
+
}
|
|
1680
|
+
const filePath = path2.join(resourcesDir, selectedFile);
|
|
1681
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
1682
|
+
const id = selectedFile.replace(".txt", "");
|
|
1683
|
+
return {
|
|
1684
|
+
id,
|
|
1685
|
+
art: content
|
|
1686
|
+
};
|
|
1687
|
+
} catch (error) {
|
|
1688
|
+
if (error instanceof PokemonHeaderArtNotFoundError) throw error;
|
|
1689
|
+
debugLogger.warn("Error loading header art:", error);
|
|
1690
|
+
return null;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
function loadCustomAsciiArt(filePath) {
|
|
1694
|
+
try {
|
|
1695
|
+
const resolvedPath = path2.resolve(process.cwd(), filePath);
|
|
1696
|
+
if (!fs3.existsSync(resolvedPath)) {
|
|
1697
|
+
debugLogger.warn(`Custom ASCII art file not found: ${resolvedPath}`);
|
|
1698
|
+
return void 0;
|
|
1699
|
+
}
|
|
1700
|
+
return fs3.readFileSync(resolvedPath, "utf-8");
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
debugLogger.warn("Error loading custom ASCII art:", error);
|
|
1703
|
+
return void 0;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// src/config/cli-args.ts
|
|
1613
1708
|
async function parseArguments(settings, args = hideBin(process.argv)) {
|
|
1614
1709
|
const startupMessages = [];
|
|
1615
1710
|
const yargsInstance = yargs(args).locale("en").scriptName("dsh-console").usage(
|
|
@@ -1619,6 +1714,10 @@ async function parseArguments(settings, args = hideBin(process.argv)) {
|
|
|
1619
1714
|
type: "boolean",
|
|
1620
1715
|
description: "Enable DSH Console diagnostics",
|
|
1621
1716
|
default: false
|
|
1717
|
+
}).option("pokemon", {
|
|
1718
|
+
type: "string",
|
|
1719
|
+
nargs: 1,
|
|
1720
|
+
description: "Use a bundled Pokemon number for this launch"
|
|
1622
1721
|
}).command(
|
|
1623
1722
|
"$0 [query..]",
|
|
1624
1723
|
"Launch DSH Console",
|
|
@@ -1657,6 +1756,14 @@ async function parseArguments(settings, args = hideBin(process.argv)) {
|
|
|
1657
1756
|
let result;
|
|
1658
1757
|
try {
|
|
1659
1758
|
result = await yargsInstance.parse();
|
|
1759
|
+
const pokemonNumber = resolvePokemonNumber(
|
|
1760
|
+
result["pokemon"],
|
|
1761
|
+
process.env[POKEMON_NUMBER_ENV]
|
|
1762
|
+
);
|
|
1763
|
+
if (pokemonNumber !== void 0) {
|
|
1764
|
+
loadHeaderArt("pokemon", void 0, pokemonNumber);
|
|
1765
|
+
result["pokemon"] = pokemonNumber;
|
|
1766
|
+
}
|
|
1660
1767
|
} catch (e) {
|
|
1661
1768
|
const msg = e instanceof Error ? e.message : String(e);
|
|
1662
1769
|
debugLogger.error(msg);
|
|
@@ -1727,7 +1834,7 @@ var ConsolePatcher = class {
|
|
|
1727
1834
|
};
|
|
1728
1835
|
|
|
1729
1836
|
// src/config/config.ts
|
|
1730
|
-
import
|
|
1837
|
+
import path3 from "node:path";
|
|
1731
1838
|
var DEFAULT_SHELL_TERMINAL_WIDTH = 80;
|
|
1732
1839
|
var DEFAULT_SHELL_TERMINAL_HEIGHT = 24;
|
|
1733
1840
|
var Config = class {
|
|
@@ -1736,6 +1843,7 @@ var Config = class {
|
|
|
1736
1843
|
targetDir;
|
|
1737
1844
|
debugMode;
|
|
1738
1845
|
question;
|
|
1846
|
+
pokemonNumber;
|
|
1739
1847
|
// Environment sanitization
|
|
1740
1848
|
allowedEnvironmentVariables;
|
|
1741
1849
|
blockedEnvironmentVariables;
|
|
@@ -1756,9 +1864,10 @@ var Config = class {
|
|
|
1756
1864
|
// Storage
|
|
1757
1865
|
storage;
|
|
1758
1866
|
constructor(params) {
|
|
1759
|
-
this.targetDir =
|
|
1867
|
+
this.targetDir = path3.resolve(params.targetDir);
|
|
1760
1868
|
this.debugMode = params.debugMode;
|
|
1761
1869
|
this.question = params.question;
|
|
1870
|
+
this.pokemonNumber = params.pokemonNumber;
|
|
1762
1871
|
this.allowedEnvironmentVariables = params.allowedEnvironmentVariables ?? [];
|
|
1763
1872
|
this.blockedEnvironmentVariables = params.blockedEnvironmentVariables ?? [];
|
|
1764
1873
|
this.enableEnvironmentVariableRedaction = params.enableEnvironmentVariableRedaction ?? true;
|
|
@@ -1815,6 +1924,9 @@ var Config = class {
|
|
|
1815
1924
|
getQuestion() {
|
|
1816
1925
|
return this.question;
|
|
1817
1926
|
}
|
|
1927
|
+
getPokemonNumber() {
|
|
1928
|
+
return this.pokemonNumber;
|
|
1929
|
+
}
|
|
1818
1930
|
get sanitizationConfig() {
|
|
1819
1931
|
return {
|
|
1820
1932
|
allowedEnvironmentVariables: this.allowedEnvironmentVariables,
|
|
@@ -1887,6 +1999,7 @@ async function loadCliConfig(settings, argv, options = {}) {
|
|
|
1887
1999
|
targetDir: cwd,
|
|
1888
2000
|
debugMode,
|
|
1889
2001
|
question,
|
|
2002
|
+
pokemonNumber: argv.pokemon,
|
|
1890
2003
|
blockedEnvironmentVariables: settings.security?.environmentVariableRedaction?.blocked,
|
|
1891
2004
|
enableEnvironmentVariableRedaction: settings.security?.environmentVariableRedaction?.enabled,
|
|
1892
2005
|
accessibility: {
|
|
@@ -1924,7 +2037,7 @@ var useAlternateBuffer = () => {
|
|
|
1924
2037
|
};
|
|
1925
2038
|
|
|
1926
2039
|
// src/terminal/capabilities.ts
|
|
1927
|
-
import * as
|
|
2040
|
+
import * as fs4 from "node:fs";
|
|
1928
2041
|
var TerminalCapabilityManager = class _TerminalCapabilityManager {
|
|
1929
2042
|
static instance;
|
|
1930
2043
|
static KITTY_QUERY = "\x1B[?u";
|
|
@@ -2078,7 +2191,7 @@ var TerminalCapabilityManager = class _TerminalCapabilityManager {
|
|
|
2078
2191
|
};
|
|
2079
2192
|
process.stdin.on("data", onData);
|
|
2080
2193
|
try {
|
|
2081
|
-
|
|
2194
|
+
fs4.writeSync(
|
|
2082
2195
|
process.stdout.fd,
|
|
2083
2196
|
_TerminalCapabilityManager.KITTY_QUERY + _TerminalCapabilityManager.OSC_11_QUERY + _TerminalCapabilityManager.TERMINAL_NAME_QUERY + _TerminalCapabilityManager.MODIFY_OTHER_KEYS_QUERY + _TerminalCapabilityManager.DEVICE_ATTRIBUTES_QUERY
|
|
2084
2197
|
);
|
|
@@ -2168,21 +2281,21 @@ async function setupTerminalAndTheme(config, settings) {
|
|
|
2168
2281
|
}
|
|
2169
2282
|
|
|
2170
2283
|
// src/bootstrap/startup-warnings.ts
|
|
2171
|
-
import * as
|
|
2284
|
+
import * as fs5 from "node:fs/promises";
|
|
2172
2285
|
import os from "node:os";
|
|
2173
2286
|
import process2 from "node:process";
|
|
2174
|
-
import
|
|
2287
|
+
import path4, { join as pathJoin } from "node:path";
|
|
2175
2288
|
var WARNINGS_FILE_PATH = pathJoin(
|
|
2176
2289
|
os.tmpdir(),
|
|
2177
2290
|
"dsh-console-warnings.txt"
|
|
2178
2291
|
);
|
|
2179
2292
|
async function getStoredStartupWarnings() {
|
|
2180
2293
|
try {
|
|
2181
|
-
await
|
|
2182
|
-
const warningsContent = await
|
|
2294
|
+
await fs5.access(WARNINGS_FILE_PATH);
|
|
2295
|
+
const warningsContent = await fs5.readFile(WARNINGS_FILE_PATH, "utf-8");
|
|
2183
2296
|
const warnings = warningsContent.split("\n").filter((line) => line.trim() !== "");
|
|
2184
2297
|
try {
|
|
2185
|
-
await
|
|
2298
|
+
await fs5.unlink(WARNINGS_FILE_PATH);
|
|
2186
2299
|
} catch {
|
|
2187
2300
|
warnings.push("Warning: Could not delete temporary warnings file.");
|
|
2188
2301
|
}
|
|
@@ -2202,8 +2315,8 @@ var homeDirectoryCheck = {
|
|
|
2202
2315
|
}
|
|
2203
2316
|
try {
|
|
2204
2317
|
const [workspaceRealPath, homeRealPath] = await Promise.all([
|
|
2205
|
-
|
|
2206
|
-
|
|
2318
|
+
fs5.realpath(workspaceRoot),
|
|
2319
|
+
fs5.realpath(homedir())
|
|
2207
2320
|
]);
|
|
2208
2321
|
if (workspaceRealPath === homeRealPath) {
|
|
2209
2322
|
return "Warning you are running DSH Console in your home directory.\nThis warning can be disabled in /settings";
|
|
@@ -2218,9 +2331,9 @@ var rootDirectoryCheck = {
|
|
|
2218
2331
|
id: "root-directory",
|
|
2219
2332
|
check: async (workspaceRoot, _settings) => {
|
|
2220
2333
|
try {
|
|
2221
|
-
const workspaceRealPath = await
|
|
2334
|
+
const workspaceRealPath = await fs5.realpath(workspaceRoot);
|
|
2222
2335
|
const errorMessage = "Warning: You are running DSH Console in the root directory. Your entire folder structure will be used for context. It is strongly recommended to run in a project-specific directory.";
|
|
2223
|
-
if (
|
|
2336
|
+
if (path4.dirname(workspaceRealPath) === workspaceRealPath) {
|
|
2224
2337
|
return errorMessage;
|
|
2225
2338
|
}
|
|
2226
2339
|
return null;
|
|
@@ -2248,7 +2361,7 @@ async function getStartupWarnings(settings, workspaceRoot = process2.cwd()) {
|
|
|
2248
2361
|
}
|
|
2249
2362
|
|
|
2250
2363
|
// src/ui/root.tsx
|
|
2251
|
-
import { basename as
|
|
2364
|
+
import { basename as basename4 } from "node:path";
|
|
2252
2365
|
|
|
2253
2366
|
// src/ui/types.ts
|
|
2254
2367
|
import "react";
|
|
@@ -2319,13 +2432,13 @@ function computeTerminalTitle({
|
|
|
2319
2432
|
|
|
2320
2433
|
// src/ui/app-container.tsx
|
|
2321
2434
|
import {
|
|
2322
|
-
useMemo as
|
|
2323
|
-
useState as
|
|
2324
|
-
useCallback as
|
|
2325
|
-
useEffect as
|
|
2326
|
-
useRef as
|
|
2435
|
+
useMemo as useMemo36,
|
|
2436
|
+
useState as useState54,
|
|
2437
|
+
useCallback as useCallback46,
|
|
2438
|
+
useEffect as useEffect55,
|
|
2439
|
+
useRef as useRef31,
|
|
2327
2440
|
useLayoutEffect as useLayoutEffect3,
|
|
2328
|
-
useSyncExternalStore as
|
|
2441
|
+
useSyncExternalStore as useSyncExternalStore6
|
|
2329
2442
|
} from "react";
|
|
2330
2443
|
import { measureElement as measureElement3, useApp } from "ink";
|
|
2331
2444
|
|
|
@@ -3214,7 +3327,7 @@ var MarkdownDisplayInternal = ({
|
|
|
3214
3327
|
} else if (headerMatch) {
|
|
3215
3328
|
const level = headerMatch[1].length;
|
|
3216
3329
|
const headerText = headerMatch[2];
|
|
3217
|
-
let headerNode
|
|
3330
|
+
let headerNode;
|
|
3218
3331
|
switch (level) {
|
|
3219
3332
|
case 1:
|
|
3220
3333
|
headerNode = /* @__PURE__ */ jsx9(Text8, { bold: true, color: theme.text.link, children: /* @__PURE__ */ jsx9(RenderInline, { text: headerText, defaultColor: theme.text.link }) });
|
|
@@ -4210,8 +4323,8 @@ var renderDiffContent = (parsedLines, filename, tabWidth = DEFAULT_TAB_WIDTH, av
|
|
|
4210
4323
|
);
|
|
4211
4324
|
}
|
|
4212
4325
|
const lineKey = `diff-line-${index}`;
|
|
4213
|
-
let gutterNumStr
|
|
4214
|
-
let prefixSymbol
|
|
4326
|
+
let gutterNumStr;
|
|
4327
|
+
let prefixSymbol;
|
|
4215
4328
|
switch (line.type) {
|
|
4216
4329
|
case "add":
|
|
4217
4330
|
gutterNumStr = (line.newLine ?? "").toString();
|
|
@@ -5190,7 +5303,7 @@ function* emitKeys(keypressHandler) {
|
|
|
5190
5303
|
let alt = false;
|
|
5191
5304
|
let ctrl = false;
|
|
5192
5305
|
let cmd = false;
|
|
5193
|
-
let code
|
|
5306
|
+
let code;
|
|
5194
5307
|
let insertable = false;
|
|
5195
5308
|
if (ch === ESC) {
|
|
5196
5309
|
escaped = true;
|
|
@@ -5323,8 +5436,8 @@ function* emitKeys(keypressHandler) {
|
|
|
5323
5436
|
name2 = "undefined";
|
|
5324
5437
|
if ((ctrl || cmd || alt) && (code.endsWith("u") || code.endsWith("~"))) {
|
|
5325
5438
|
const codeNumber = parseInt(code.slice(1, -1), 10);
|
|
5326
|
-
if (codeNumber >=
|
|
5327
|
-
name2 = String.fromCharCode(codeNumber);
|
|
5439
|
+
if (codeNumber >= 32 && codeNumber <= 126) {
|
|
5440
|
+
name2 = String.fromCharCode(codeNumber).toLowerCase();
|
|
5328
5441
|
}
|
|
5329
5442
|
}
|
|
5330
5443
|
}
|
|
@@ -5486,6 +5599,9 @@ function useKeypress(onKeypress, { isActive }) {
|
|
|
5486
5599
|
}
|
|
5487
5600
|
|
|
5488
5601
|
// src/terminal/keys.ts
|
|
5602
|
+
function isConversationSwitchKey(key) {
|
|
5603
|
+
return key.sequence === "" || key.ctrl && (key.name === "/" || key.name === "_");
|
|
5604
|
+
}
|
|
5489
5605
|
function keyToAnsi(key) {
|
|
5490
5606
|
if (key.ctrl) {
|
|
5491
5607
|
if (key.name >= "a" && key.name <= "z") {
|
|
@@ -6039,7 +6155,7 @@ import { Box as Box25 } from "ink";
|
|
|
6039
6155
|
import { Box as Box21, Text as Text20 } from "ink";
|
|
6040
6156
|
|
|
6041
6157
|
// src/generated/git-commit.ts
|
|
6042
|
-
var GIT_COMMIT_INFO = "
|
|
6158
|
+
var GIT_COMMIT_INFO = "7fa332d";
|
|
6043
6159
|
|
|
6044
6160
|
// src/ui/components/dialogs/about-box.tsx
|
|
6045
6161
|
import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
@@ -6680,18 +6796,18 @@ var useAppContext = () => {
|
|
|
6680
6796
|
};
|
|
6681
6797
|
|
|
6682
6798
|
// src/ui/components/indicators/notifications.tsx
|
|
6683
|
-
import
|
|
6799
|
+
import path6 from "node:path";
|
|
6684
6800
|
|
|
6685
6801
|
// src/ui/state/persistent.ts
|
|
6686
|
-
import * as
|
|
6687
|
-
import * as
|
|
6802
|
+
import * as fs6 from "node:fs";
|
|
6803
|
+
import * as path5 from "node:path";
|
|
6688
6804
|
var STATE_FILENAME = "state.json";
|
|
6689
6805
|
var PersistentState = class {
|
|
6690
6806
|
cache = null;
|
|
6691
6807
|
filePath = null;
|
|
6692
6808
|
getPath() {
|
|
6693
6809
|
if (!this.filePath) {
|
|
6694
|
-
this.filePath =
|
|
6810
|
+
this.filePath = path5.join(
|
|
6695
6811
|
Storage.getGlobalDshConsoleDir(),
|
|
6696
6812
|
STATE_FILENAME
|
|
6697
6813
|
);
|
|
@@ -6704,8 +6820,8 @@ var PersistentState = class {
|
|
|
6704
6820
|
}
|
|
6705
6821
|
try {
|
|
6706
6822
|
const filePath = this.getPath();
|
|
6707
|
-
if (
|
|
6708
|
-
const content =
|
|
6823
|
+
if (fs6.existsSync(filePath)) {
|
|
6824
|
+
const content = fs6.readFileSync(filePath, "utf-8");
|
|
6709
6825
|
this.cache = JSON.parse(content);
|
|
6710
6826
|
} else {
|
|
6711
6827
|
this.cache = {};
|
|
@@ -6720,11 +6836,11 @@ var PersistentState = class {
|
|
|
6720
6836
|
if (!this.cache) return;
|
|
6721
6837
|
try {
|
|
6722
6838
|
const filePath = this.getPath();
|
|
6723
|
-
const dir =
|
|
6724
|
-
if (!
|
|
6725
|
-
|
|
6839
|
+
const dir = path5.dirname(filePath);
|
|
6840
|
+
if (!fs6.existsSync(dir)) {
|
|
6841
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
6726
6842
|
}
|
|
6727
|
-
|
|
6843
|
+
fs6.writeFileSync(filePath, JSON.stringify(this.cache, null, 2));
|
|
6728
6844
|
} catch (error) {
|
|
6729
6845
|
debugLogger.warn("Failed to save persistent state:", error);
|
|
6730
6846
|
}
|
|
@@ -6742,7 +6858,7 @@ var persistentState = new PersistentState();
|
|
|
6742
6858
|
|
|
6743
6859
|
// src/ui/components/indicators/notifications.tsx
|
|
6744
6860
|
import { Fragment as Fragment8, jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
6745
|
-
var settingsPath =
|
|
6861
|
+
var settingsPath = path6.join(homedir(), DSH_CONSOLE_DIR, "settings.json");
|
|
6746
6862
|
var Notifications = () => {
|
|
6747
6863
|
const { startupWarnings } = useAppContext();
|
|
6748
6864
|
const { initError, streamingState } = useUIState();
|
|
@@ -7273,76 +7389,6 @@ var Header = ({
|
|
|
7273
7389
|
return /* @__PURE__ */ jsx41(HorizontalHeader, { version, art: headerArt.art });
|
|
7274
7390
|
};
|
|
7275
7391
|
|
|
7276
|
-
// src/utils/header-loader.ts
|
|
7277
|
-
import fs6 from "node:fs";
|
|
7278
|
-
import path6 from "node:path";
|
|
7279
|
-
var packageRoot = findPackageRoot(import.meta.url);
|
|
7280
|
-
var builtResources = path6.join(
|
|
7281
|
-
packageRoot,
|
|
7282
|
-
"dist/ui/components/layout/resources"
|
|
7283
|
-
);
|
|
7284
|
-
var sourceResources = path6.join(
|
|
7285
|
-
packageRoot,
|
|
7286
|
-
"src/ui/components/layout/resources"
|
|
7287
|
-
);
|
|
7288
|
-
function resolveResourcesDir(resourceType, customPath) {
|
|
7289
|
-
if (resourceType === "custom") {
|
|
7290
|
-
if (!customPath) {
|
|
7291
|
-
return null;
|
|
7292
|
-
}
|
|
7293
|
-
return path6.resolve(process.cwd(), customPath);
|
|
7294
|
-
}
|
|
7295
|
-
if (resourceType === "pokemon" && customPath) {
|
|
7296
|
-
return path6.resolve(process.cwd(), customPath);
|
|
7297
|
-
}
|
|
7298
|
-
const builtResourceDir = path6.join(builtResources, resourceType);
|
|
7299
|
-
return fs6.existsSync(builtResourceDir) ? builtResourceDir : path6.join(sourceResources, resourceType);
|
|
7300
|
-
}
|
|
7301
|
-
function loadHeaderArt(resourceType = "pokemon", customPath) {
|
|
7302
|
-
try {
|
|
7303
|
-
const resourcesDir = resolveResourcesDir(resourceType, customPath);
|
|
7304
|
-
if (!resourcesDir) {
|
|
7305
|
-
debugLogger.warn("Custom header art requires an art resources path.");
|
|
7306
|
-
return null;
|
|
7307
|
-
}
|
|
7308
|
-
if (!fs6.existsSync(resourcesDir)) {
|
|
7309
|
-
debugLogger.warn(`Header art resources path not found: ${resourcesDir}`);
|
|
7310
|
-
return null;
|
|
7311
|
-
}
|
|
7312
|
-
const files = fs6.readdirSync(resourcesDir).filter((file) => file.endsWith(".txt")).sort();
|
|
7313
|
-
if (files.length === 0) {
|
|
7314
|
-
return null;
|
|
7315
|
-
}
|
|
7316
|
-
const selectedFile = files[Math.floor(Math.random() * files.length)];
|
|
7317
|
-
if (!selectedFile) {
|
|
7318
|
-
return null;
|
|
7319
|
-
}
|
|
7320
|
-
const filePath = path6.join(resourcesDir, selectedFile);
|
|
7321
|
-
const content = fs6.readFileSync(filePath, "utf-8");
|
|
7322
|
-
const id = selectedFile.replace(".txt", "");
|
|
7323
|
-
return {
|
|
7324
|
-
id,
|
|
7325
|
-
art: content
|
|
7326
|
-
};
|
|
7327
|
-
} catch (error) {
|
|
7328
|
-
debugLogger.warn("Error loading header art:", error);
|
|
7329
|
-
return null;
|
|
7330
|
-
}
|
|
7331
|
-
}
|
|
7332
|
-
function loadCustomAsciiArt(filePath) {
|
|
7333
|
-
try {
|
|
7334
|
-
const resolvedPath = path6.resolve(process.cwd(), filePath);
|
|
7335
|
-
if (!fs6.existsSync(resolvedPath)) {
|
|
7336
|
-
debugLogger.warn(`Custom ASCII art file not found: ${resolvedPath}`);
|
|
7337
|
-
return void 0;
|
|
7338
|
-
}
|
|
7339
|
-
return fs6.readFileSync(resolvedPath, "utf-8");
|
|
7340
|
-
} catch (error) {
|
|
7341
|
-
debugLogger.warn("Error loading custom ASCII art:", error);
|
|
7342
|
-
return void 0;
|
|
7343
|
-
}
|
|
7344
|
-
}
|
|
7345
|
-
|
|
7346
7392
|
// src/ui/components/layout/app-header.tsx
|
|
7347
7393
|
import { useMemo as useMemo9 } from "react";
|
|
7348
7394
|
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
@@ -7354,18 +7400,22 @@ var AppHeader = ({ version }) => {
|
|
|
7354
7400
|
const artResourceType = settings.merged.ui.header.artResourceType ?? "pokemon";
|
|
7355
7401
|
const artResourcesPath = settings.merged.ui.header.artResourcesPath;
|
|
7356
7402
|
const customAsciiArtPath = settings.merged.ui.header.customAsciiArtPath;
|
|
7403
|
+
const pokemonNumber = config.getPokemonNumber();
|
|
7357
7404
|
const customAsciiArt = useMemo9(() => {
|
|
7358
|
-
if (customAsciiArtPath) {
|
|
7405
|
+
if (pokemonNumber === void 0 && customAsciiArtPath) {
|
|
7359
7406
|
return loadCustomAsciiArt(customAsciiArtPath);
|
|
7360
7407
|
}
|
|
7361
7408
|
return void 0;
|
|
7362
|
-
}, [customAsciiArtPath]);
|
|
7409
|
+
}, [customAsciiArtPath, pokemonNumber]);
|
|
7363
7410
|
const headerArt = useMemo9(() => {
|
|
7364
7411
|
if (customAsciiArt) {
|
|
7365
7412
|
return null;
|
|
7366
7413
|
}
|
|
7414
|
+
if (pokemonNumber !== void 0) {
|
|
7415
|
+
return loadHeaderArt("pokemon", void 0, pokemonNumber);
|
|
7416
|
+
}
|
|
7367
7417
|
return loadHeaderArt(artResourceType, artResourcesPath);
|
|
7368
|
-
}, [artResourceType, artResourcesPath, customAsciiArt]);
|
|
7418
|
+
}, [artResourceType, artResourcesPath, customAsciiArt, pokemonNumber]);
|
|
7369
7419
|
if (config.getScreenReader()) {
|
|
7370
7420
|
return null;
|
|
7371
7421
|
}
|
|
@@ -7915,7 +7965,7 @@ var ScrollProvider = ({
|
|
|
7915
7965
|
const hitTop = isTop ? absoluteThumbTop : absoluteThumbTop - 1;
|
|
7916
7966
|
const hitBottom = isBottom ? absoluteThumbBottom : absoluteThumbBottom + 1;
|
|
7917
7967
|
const isThumbClick = mouseEvent.row >= hitTop && mouseEvent.row < hitBottom;
|
|
7918
|
-
let offset
|
|
7968
|
+
let offset;
|
|
7919
7969
|
const relativeMouseY = mouseEvent.row - y;
|
|
7920
7970
|
if (isThumbClick) {
|
|
7921
7971
|
offset = relativeMouseY - currentThumbY;
|
|
@@ -9780,11 +9830,9 @@ function getUserLinuxClipboardTool() {
|
|
|
9780
9830
|
if (linuxClipboardTool !== null) {
|
|
9781
9831
|
return linuxClipboardTool;
|
|
9782
9832
|
}
|
|
9783
|
-
let toolName = null;
|
|
9784
9833
|
const displayServer = process.env["XDG_SESSION_TYPE"];
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
else return null;
|
|
9834
|
+
const toolName = displayServer === "wayland" ? "wl-paste" : displayServer === "x11" ? "xclip" : null;
|
|
9835
|
+
if (toolName === null) return null;
|
|
9788
9836
|
try {
|
|
9789
9837
|
execSync(`command -v ${toolName}`, { stdio: "ignore" });
|
|
9790
9838
|
linuxClipboardTool = toolName;
|
|
@@ -10340,8 +10388,8 @@ function calculateInitialCursorPosition(initialLines, offset) {
|
|
|
10340
10388
|
return [0, 0];
|
|
10341
10389
|
}
|
|
10342
10390
|
function offsetToLogicalPos(text, offset) {
|
|
10343
|
-
let row
|
|
10344
|
-
let col
|
|
10391
|
+
let row;
|
|
10392
|
+
let col;
|
|
10345
10393
|
let currentOffset = 0;
|
|
10346
10394
|
if (offset === 0) return [0, 0];
|
|
10347
10395
|
const lines = text.split("\n");
|
|
@@ -11752,7 +11800,7 @@ function textBufferReducerLogic(state, action, options = {}) {
|
|
|
11752
11800
|
case "wordLeft": {
|
|
11753
11801
|
if (cursorCol === 0 && cursorRow === 0) return state;
|
|
11754
11802
|
let newCursorRow = cursorRow;
|
|
11755
|
-
let newCursorCol
|
|
11803
|
+
let newCursorCol;
|
|
11756
11804
|
if (cursorCol === 0) {
|
|
11757
11805
|
newCursorRow--;
|
|
11758
11806
|
newCursorCol = cpLen(lines[newCursorRow] ?? "");
|
|
@@ -11773,7 +11821,7 @@ function textBufferReducerLogic(state, action, options = {}) {
|
|
|
11773
11821
|
return state;
|
|
11774
11822
|
}
|
|
11775
11823
|
let newCursorRow = cursorRow;
|
|
11776
|
-
let newCursorCol
|
|
11824
|
+
let newCursorCol;
|
|
11777
11825
|
const lineLen = cpLen(lineContent);
|
|
11778
11826
|
if (cursorCol >= lineLen) {
|
|
11779
11827
|
newCursorRow++;
|
|
@@ -13176,7 +13224,7 @@ function BaseSettingsDialog({
|
|
|
13176
13224
|
return;
|
|
13177
13225
|
}
|
|
13178
13226
|
let ch = key.sequence;
|
|
13179
|
-
let isValidChar
|
|
13227
|
+
let isValidChar;
|
|
13180
13228
|
if (type === "number") {
|
|
13181
13229
|
isValidChar = /[0-9\-+.]/.test(ch);
|
|
13182
13230
|
} else {
|
|
@@ -14393,7 +14441,7 @@ var _ExpandableText = ({
|
|
|
14393
14441
|
}
|
|
14394
14442
|
const matchLength = userInput.length;
|
|
14395
14443
|
let before = "";
|
|
14396
|
-
let match
|
|
14444
|
+
let match;
|
|
14397
14445
|
let after = "";
|
|
14398
14446
|
if (isExpanded || label.length <= maxWidth) {
|
|
14399
14447
|
before = label.slice(0, matchedIndex);
|
|
@@ -14595,7 +14643,7 @@ function useInputHistory({
|
|
|
14595
14643
|
const navigateUp = useCallback23(() => {
|
|
14596
14644
|
if (!isActive) return false;
|
|
14597
14645
|
if (userMessages.length === 0) return false;
|
|
14598
|
-
let nextIndex
|
|
14646
|
+
let nextIndex;
|
|
14599
14647
|
if (historyIndex === -1) {
|
|
14600
14648
|
setOriginalQueryBeforeNav(currentQuery);
|
|
14601
14649
|
nextIndex = 0;
|
|
@@ -15257,7 +15305,7 @@ function useCommandSuggestions(query, parserResult, commandContext, getFzfForCom
|
|
|
15257
15305
|
if (commandsToSearch.length > 0) {
|
|
15258
15306
|
const performFuzzySearch = async () => {
|
|
15259
15307
|
if (signal.aborted) return;
|
|
15260
|
-
let potentialSuggestions
|
|
15308
|
+
let potentialSuggestions;
|
|
15261
15309
|
if (partial === "") {
|
|
15262
15310
|
potentialSuggestions = commandsToSearch.filter(
|
|
15263
15311
|
(cmd) => cmd.description && !cmd.hidden
|
|
@@ -15983,6 +16031,39 @@ import { createContext as createContext11, useContext as useContext12 } from "re
|
|
|
15983
16031
|
var ShellFocusContext = createContext11(true);
|
|
15984
16032
|
var useShellFocusState = () => useContext12(ShellFocusContext);
|
|
15985
16033
|
|
|
16034
|
+
// src/ui/commands/parser.ts
|
|
16035
|
+
var parseSlashCommand = (query, commands) => {
|
|
16036
|
+
const trimmed = query.trim();
|
|
16037
|
+
const parts = trimmed.substring(1).trim().split(/\s+/);
|
|
16038
|
+
const commandPath = parts.filter((p) => p);
|
|
16039
|
+
let currentCommands = commands;
|
|
16040
|
+
let commandToExecute;
|
|
16041
|
+
let pathIndex = 0;
|
|
16042
|
+
const canonicalPath = [];
|
|
16043
|
+
for (const part of commandPath) {
|
|
16044
|
+
let foundCommand = currentCommands.find((cmd) => cmd.name === part);
|
|
16045
|
+
if (!foundCommand) {
|
|
16046
|
+
foundCommand = currentCommands.find(
|
|
16047
|
+
(cmd) => cmd.altNames?.includes(part)
|
|
16048
|
+
);
|
|
16049
|
+
}
|
|
16050
|
+
if (foundCommand) {
|
|
16051
|
+
commandToExecute = foundCommand;
|
|
16052
|
+
canonicalPath.push(foundCommand.name);
|
|
16053
|
+
pathIndex++;
|
|
16054
|
+
if (foundCommand.subCommands) {
|
|
16055
|
+
currentCommands = foundCommand.subCommands;
|
|
16056
|
+
} else {
|
|
16057
|
+
break;
|
|
16058
|
+
}
|
|
16059
|
+
} else {
|
|
16060
|
+
break;
|
|
16061
|
+
}
|
|
16062
|
+
}
|
|
16063
|
+
const args = parts.slice(pathIndex).join(" ");
|
|
16064
|
+
return { commandToExecute, args, canonicalPath };
|
|
16065
|
+
};
|
|
16066
|
+
|
|
15986
16067
|
// src/ui/components/input/input-prompt.tsx
|
|
15987
16068
|
import { Fragment as Fragment12, jsx as jsx64, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
15988
16069
|
function isTerminalPasteTrusted(kittyProtocolSupported) {
|
|
@@ -16125,8 +16206,10 @@ var InputPrompt = ({
|
|
|
16125
16206
|
(submittedValue) => {
|
|
16126
16207
|
const trimmedMessage = submittedValue.trim();
|
|
16127
16208
|
const isSlash = isSlashCommand(trimmedMessage);
|
|
16209
|
+
const command = isSlash ? parseSlashCommand(trimmedMessage, slashCommands).commandToExecute : void 0;
|
|
16210
|
+
const canRunWhileBusy = command?.allowWhileBusy === true;
|
|
16128
16211
|
const isShell = shellModeActive;
|
|
16129
|
-
if ((
|
|
16212
|
+
if ((isShell || isSlash && !canRunWhileBusy) && streamingState === "responding" /* Responding */) {
|
|
16130
16213
|
setQueueErrorMessage(
|
|
16131
16214
|
`${isShell ? "Shell" : "Slash"} commands cannot be queued`
|
|
16132
16215
|
);
|
|
@@ -16136,6 +16219,7 @@ var InputPrompt = ({
|
|
|
16136
16219
|
},
|
|
16137
16220
|
[
|
|
16138
16221
|
handleSubmitAndClear,
|
|
16222
|
+
slashCommands,
|
|
16139
16223
|
shellModeActive,
|
|
16140
16224
|
streamingState,
|
|
16141
16225
|
setQueueErrorMessage
|
|
@@ -16587,6 +16671,9 @@ var InputPrompt = ({
|
|
|
16587
16671
|
}
|
|
16588
16672
|
return;
|
|
16589
16673
|
}
|
|
16674
|
+
if (isConversationSwitchKey(key)) {
|
|
16675
|
+
return;
|
|
16676
|
+
}
|
|
16590
16677
|
buffer.handleInput(key);
|
|
16591
16678
|
if (completion.promptCompletion.text && key.sequence && key.sequence.length === 1 && !key.alt && !key.ctrl && !key.cmd) {
|
|
16592
16679
|
completion.promptCompletion.clear();
|
|
@@ -16643,7 +16730,7 @@ var InputPrompt = ({
|
|
|
16643
16730
|
const remainingWidth = Math.max(0, inputWidth - usedWidth);
|
|
16644
16731
|
const ghostTextLinesRaw = ghostSuffix.split("\n");
|
|
16645
16732
|
const firstLineRaw = ghostTextLinesRaw.shift() || "";
|
|
16646
|
-
let inlineGhost2
|
|
16733
|
+
let inlineGhost2;
|
|
16647
16734
|
let remainingFirstLine = "";
|
|
16648
16735
|
if (stringWidth3(firstLineRaw) <= remainingWidth) {
|
|
16649
16736
|
inlineGhost2 = firstLineRaw;
|
|
@@ -16940,6 +17027,7 @@ var InputPrompt = ({
|
|
|
16940
17027
|
};
|
|
16941
17028
|
|
|
16942
17029
|
// src/ui/components/layout/footer.tsx
|
|
17030
|
+
import { basename as basename2 } from "node:path";
|
|
16943
17031
|
import { Box as Box54, Text as Text49 } from "ink";
|
|
16944
17032
|
|
|
16945
17033
|
// src/ui/components/layout/console-summary-display.tsx
|
|
@@ -16995,7 +17083,7 @@ var MemoryUsageDisplay = () => {
|
|
|
16995
17083
|
import { Text as Text47 } from "ink";
|
|
16996
17084
|
import { useEffect as useEffect35, useState as useState32 } from "react";
|
|
16997
17085
|
import { FixedDeque } from "mnemonist";
|
|
16998
|
-
import { jsx as jsx67, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
17086
|
+
import { Fragment as Fragment13, jsx as jsx67, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
16999
17087
|
var MIN_TIME_FROM_ACTION_TO_BE_IDLE = 500;
|
|
17000
17088
|
var ACTION_TIMESTAMP_CAPACITY = 2048;
|
|
17001
17089
|
var FRAME_TIMESTAMP_CAPACITY = 2048;
|
|
@@ -17147,12 +17235,14 @@ var DebugProfiler = ({ compact = false }) => {
|
|
|
17147
17235
|
}
|
|
17148
17236
|
if (compact) {
|
|
17149
17237
|
return /* @__PURE__ */ jsxs51(Text47, { color: theme.status.warning, wrap: "truncate-end", children: [
|
|
17150
|
-
"R
|
|
17238
|
+
"R",
|
|
17151
17239
|
profiler.numFrames,
|
|
17152
|
-
" I
|
|
17240
|
+
" I",
|
|
17153
17241
|
/* @__PURE__ */ jsx67(Text47, { color: theme.status.error, children: profiler.totalIdleFrames }),
|
|
17154
|
-
|
|
17155
|
-
|
|
17242
|
+
profiler.totalFlickerFrames > 0 && /* @__PURE__ */ jsxs51(Fragment13, { children: [
|
|
17243
|
+
" F",
|
|
17244
|
+
/* @__PURE__ */ jsx67(Text47, { color: theme.status.error, children: profiler.totalFlickerFrames })
|
|
17245
|
+
] })
|
|
17156
17246
|
] }, forceRefresh);
|
|
17157
17247
|
}
|
|
17158
17248
|
return /* @__PURE__ */ jsxs51(Text47, { color: theme.status.warning, wrap: "truncate-end", children: [
|
|
@@ -17227,14 +17317,26 @@ var Footer = () => {
|
|
|
17227
17317
|
nightly: uiState.nightly,
|
|
17228
17318
|
terminalWidth: uiState.terminalWidth
|
|
17229
17319
|
};
|
|
17230
|
-
const
|
|
17320
|
+
const isNarrow = terminalWidth < 120;
|
|
17321
|
+
const isCompact = terminalWidth < 160;
|
|
17322
|
+
const showMemoryUsage = !isCompact && (config.getDebugMode() || settings.merged.ui.showMemoryUsage);
|
|
17231
17323
|
const hideCWD = settings.merged.ui.footer.hideCWD;
|
|
17232
17324
|
const hideModelInfo = settings.merged.ui.footer.hideModelInfo;
|
|
17233
17325
|
const pathLength = Math.max(20, Math.floor(terminalWidth * 0.25));
|
|
17234
|
-
const displayPath = shortenPath(tildeifyPath(targetDir), pathLength);
|
|
17235
|
-
const justifyContent = hideCWD && hideModelInfo ? "center" : "space-between";
|
|
17326
|
+
const displayPath = isCompact ? basename2(targetDir) || targetDir : shortenPath(tildeifyPath(targetDir), pathLength);
|
|
17236
17327
|
const displayVimMode = vimEnabled ? vimMode : void 0;
|
|
17237
|
-
const
|
|
17328
|
+
const sideConversation = uiState.sideConversation ?? {
|
|
17329
|
+
activeSurface: "main",
|
|
17330
|
+
mainBusy: false,
|
|
17331
|
+
sideBusy: false
|
|
17332
|
+
};
|
|
17333
|
+
const showRenderDiagnostics = (debugMode || isDevelopment) && (!isNarrow || sideConversation.activeSurface !== "side");
|
|
17334
|
+
const showCwd = !hideCWD;
|
|
17335
|
+
const showLeft = Boolean(
|
|
17336
|
+
displayVimMode || showCwd || debugMode && isNarrow
|
|
17337
|
+
);
|
|
17338
|
+
const justifyContent = hideModelInfo ? showLeft ? "flex-start" : "center" : showLeft ? "space-between" : "flex-end";
|
|
17339
|
+
const displayModel = isCompact ? model.split("/").at(-1) ?? model : model;
|
|
17238
17340
|
return /* @__PURE__ */ jsxs53(
|
|
17239
17341
|
Box54,
|
|
17240
17342
|
{
|
|
@@ -17244,28 +17346,29 @@ var Footer = () => {
|
|
|
17244
17346
|
alignItems: "center",
|
|
17245
17347
|
paddingX: 1,
|
|
17246
17348
|
children: [
|
|
17247
|
-
(displayVimMode ||
|
|
17349
|
+
(displayVimMode || showCwd || debugMode && isNarrow) && /* @__PURE__ */ jsxs53(Box54, { flexShrink: 1, children: [
|
|
17248
17350
|
displayVimMode && /* @__PURE__ */ jsxs53(Text49, { color: theme.text.secondary, children: [
|
|
17249
17351
|
"[",
|
|
17250
17352
|
displayVimMode,
|
|
17251
17353
|
"] "
|
|
17252
17354
|
] }),
|
|
17253
|
-
|
|
17355
|
+
showCwd && (nightly ? /* @__PURE__ */ jsxs53(ThemedGradient, { children: [
|
|
17254
17356
|
displayPath,
|
|
17255
|
-
branchName && /* @__PURE__ */ jsxs53(Text49, { children: [
|
|
17357
|
+
branchName && !isNarrow && /* @__PURE__ */ jsxs53(Text49, { children: [
|
|
17256
17358
|
" (",
|
|
17257
17359
|
branchName,
|
|
17258
17360
|
"*)"
|
|
17259
17361
|
] })
|
|
17260
17362
|
] }) : /* @__PURE__ */ jsxs53(Text49, { color: theme.text.link, children: [
|
|
17261
17363
|
displayPath,
|
|
17262
|
-
branchName && /* @__PURE__ */ jsxs53(Text49, { color: theme.text.secondary, children: [
|
|
17364
|
+
branchName && !isNarrow && /* @__PURE__ */ jsxs53(Text49, { color: theme.text.secondary, children: [
|
|
17263
17365
|
" (",
|
|
17264
17366
|
branchName,
|
|
17265
17367
|
"*)"
|
|
17266
17368
|
] })
|
|
17267
17369
|
] })),
|
|
17268
|
-
debugMode && /* @__PURE__ */ jsx69(Text49, { color: theme.status.error, children: " " + (debugMessage || "--debug") })
|
|
17370
|
+
debugMode && !isNarrow && /* @__PURE__ */ jsx69(Text49, { color: theme.status.error, children: " " + (debugMessage || "--debug") }),
|
|
17371
|
+
debugMode && isNarrow && /* @__PURE__ */ jsx69(Text49, { color: theme.status.error, children: showCwd ? " --debug" : "--debug" })
|
|
17269
17372
|
] }),
|
|
17270
17373
|
showRenderDiagnostics && /* @__PURE__ */ jsx69(
|
|
17271
17374
|
Box54,
|
|
@@ -17274,12 +17377,30 @@ var Footer = () => {
|
|
|
17274
17377
|
flexShrink: 1,
|
|
17275
17378
|
justifyContent: "center",
|
|
17276
17379
|
marginX: terminalWidth >= 120 ? 1 : 0,
|
|
17277
|
-
children: /* @__PURE__ */ jsx69(DebugProfiler, { compact:
|
|
17380
|
+
children: /* @__PURE__ */ jsx69(DebugProfiler, { compact: isCompact })
|
|
17278
17381
|
}
|
|
17279
17382
|
),
|
|
17280
|
-
!hideModelInfo && /* @__PURE__ */ jsxs53(Box54, { alignItems: "center", justifyContent: "flex-end", children: [
|
|
17281
|
-
/* @__PURE__ */ jsxs53(Box54, {
|
|
17282
|
-
/* @__PURE__ */ jsx69(Text49, { color: theme.
|
|
17383
|
+
!hideModelInfo && /* @__PURE__ */ jsxs53(Box54, { alignItems: "center", justifyContent: "flex-end", flexShrink: 1, children: [
|
|
17384
|
+
(uiState.subagentCatalog?.runningCount ?? 0) > 0 && /* @__PURE__ */ jsxs53(Box54, { flexShrink: 0, children: [
|
|
17385
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.status.success, children: isCompact ? `A${uiState.subagentCatalog?.runningCount}` : `${uiState.subagentCatalog?.runningCount} agent${uiState.subagentCatalog?.runningCount === 1 ? "" : "s"} working` }),
|
|
17386
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.secondary, children: " | " })
|
|
17387
|
+
] }),
|
|
17388
|
+
sideConversation.activeSurface === "side" && /* @__PURE__ */ jsxs53(Box54, { flexShrink: 1, children: [
|
|
17389
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.accent, children: "Side" }),
|
|
17390
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.secondary, children: " \xB7 Main " }),
|
|
17391
|
+
/* @__PURE__ */ jsx69(
|
|
17392
|
+
Text49,
|
|
17393
|
+
{
|
|
17394
|
+
color: sideConversation.mainBusy ? theme.status.warning : theme.status.success,
|
|
17395
|
+
children: sideConversation.mainBusy ? "working" : "idle"
|
|
17396
|
+
}
|
|
17397
|
+
),
|
|
17398
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.secondary, children: " \xB7 " }),
|
|
17399
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.accent, wrap: "truncate-end", children: isCompact ? "Ctrl+/" : "Ctrl+/ switch" }),
|
|
17400
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.secondary, children: " | " })
|
|
17401
|
+
] }),
|
|
17402
|
+
/* @__PURE__ */ jsxs53(Box54, { alignItems: "center", justifyContent: "flex-end", flexShrink: 1, children: [
|
|
17403
|
+
/* @__PURE__ */ jsx69(Text49, { color: theme.text.accent, wrap: "truncate-end", children: displayModel }),
|
|
17283
17404
|
uiState.currentReasoningEffort && /* @__PURE__ */ jsxs53(Text49, { color: theme.text.link, children: [
|
|
17284
17405
|
" ",
|
|
17285
17406
|
uiState.currentReasoningEffort
|
|
@@ -17289,7 +17410,7 @@ var Footer = () => {
|
|
|
17289
17410
|
{
|
|
17290
17411
|
promptTokens: uiState.sessionStats.lastPromptTokenCount,
|
|
17291
17412
|
contextWindow: uiState.sessionStats.contextWindow,
|
|
17292
|
-
compact:
|
|
17413
|
+
compact: isCompact
|
|
17293
17414
|
}
|
|
17294
17415
|
),
|
|
17295
17416
|
showMemoryUsage && /* @__PURE__ */ jsx69(MemoryUsageDisplay, {})
|
|
@@ -17343,33 +17464,42 @@ var CommandInitDisplay = ({
|
|
|
17343
17464
|
import { Box as Box57, Text as Text52 } from "ink";
|
|
17344
17465
|
import { useMemo as useMemo21 } from "react";
|
|
17345
17466
|
import { jsx as jsx72, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
17346
|
-
var TodoTitleDisplay = ({ todos }) => {
|
|
17467
|
+
var TodoTitleDisplay = ({ todos, isWorking, compact = false }) => {
|
|
17347
17468
|
const score = useMemo21(() => {
|
|
17348
17469
|
let total = 0;
|
|
17349
17470
|
let completed = 0;
|
|
17471
|
+
let unfinished = 0;
|
|
17350
17472
|
for (const todo of todos.todos) {
|
|
17351
17473
|
if (todo.status !== "cancelled") {
|
|
17352
17474
|
total += 1;
|
|
17353
17475
|
if (todo.status === "completed") {
|
|
17354
17476
|
completed += 1;
|
|
17477
|
+
} else {
|
|
17478
|
+
unfinished += 1;
|
|
17355
17479
|
}
|
|
17356
17480
|
}
|
|
17357
17481
|
}
|
|
17358
|
-
|
|
17359
|
-
|
|
17482
|
+
const idleRemainder = !isWorking && unfinished > 0 ? ` \xB7 ${unfinished} unfinished` : "";
|
|
17483
|
+
const completion = compact ? `${completed}/${total}` : `${completed}/${total} completed`;
|
|
17484
|
+
return `${completion}${idleRemainder}`;
|
|
17485
|
+
}, [compact, isWorking, todos]);
|
|
17360
17486
|
return /* @__PURE__ */ jsxs56(Box57, { flexDirection: "row", columnGap: 2, height: 1, children: [
|
|
17361
17487
|
/* @__PURE__ */ jsx72(Text52, { color: theme.text.primary, bold: true, "aria-label": "Todo list", children: "Todo" }),
|
|
17362
|
-
/* @__PURE__ */ jsxs56(Text52, { color: theme.text.secondary, children: [
|
|
17488
|
+
/* @__PURE__ */ jsxs56(Text52, { color: theme.text.secondary, wrap: "truncate", children: [
|
|
17363
17489
|
score,
|
|
17364
|
-
"
|
|
17490
|
+
" ",
|
|
17491
|
+
compact ? "(ctrl+t)" : "(ctrl+t to toggle)"
|
|
17365
17492
|
] })
|
|
17366
17493
|
] });
|
|
17367
17494
|
};
|
|
17368
|
-
var TodoStatusDisplay = ({ status }) => {
|
|
17495
|
+
var TodoStatusDisplay = ({ status, isWorking }) => {
|
|
17369
17496
|
switch (status) {
|
|
17370
17497
|
case "completed":
|
|
17371
17498
|
return /* @__PURE__ */ jsx72(Text52, { color: theme.status.success, "aria-label": "Completed", children: "\u2713" });
|
|
17372
17499
|
case "in_progress":
|
|
17500
|
+
if (!isWorking) {
|
|
17501
|
+
return /* @__PURE__ */ jsx72(Text52, { color: theme.text.secondary, "aria-label": "Unfinished", children: "\u25CB" });
|
|
17502
|
+
}
|
|
17373
17503
|
return /* @__PURE__ */ jsx72(Text52, { color: theme.text.accent, "aria-label": "In Progress", children: "\xBB" });
|
|
17374
17504
|
case "pending":
|
|
17375
17505
|
return /* @__PURE__ */ jsx72(Text52, { color: theme.text.secondary, "aria-label": "Pending", children: "\u2610" });
|
|
@@ -17378,11 +17508,11 @@ var TodoStatusDisplay = ({ status }) => {
|
|
|
17378
17508
|
return /* @__PURE__ */ jsx72(Text52, { color: theme.status.error, "aria-label": "Cancelled", children: "\u2717" });
|
|
17379
17509
|
}
|
|
17380
17510
|
};
|
|
17381
|
-
var TodoItemDisplay = ({ todo, wrap, role: ariaRole }) => {
|
|
17511
|
+
var TodoItemDisplay = ({ todo, wrap, role: ariaRole, isWorking }) => {
|
|
17382
17512
|
const textColor = (() => {
|
|
17383
17513
|
switch (todo.status) {
|
|
17384
17514
|
case "in_progress":
|
|
17385
|
-
return theme.text.accent;
|
|
17515
|
+
return isWorking ? theme.text.accent : theme.text.primary;
|
|
17386
17516
|
case "completed":
|
|
17387
17517
|
case "cancelled":
|
|
17388
17518
|
return theme.text.secondary;
|
|
@@ -17392,13 +17522,14 @@ var TodoItemDisplay = ({ todo, wrap, role: ariaRole }) => {
|
|
|
17392
17522
|
})();
|
|
17393
17523
|
const strikethrough = todo.status === "cancelled";
|
|
17394
17524
|
return /* @__PURE__ */ jsxs56(Box57, { flexDirection: "row", columnGap: 1, "aria-role": ariaRole, children: [
|
|
17395
|
-
/* @__PURE__ */ jsx72(TodoStatusDisplay, { status: todo.status }),
|
|
17525
|
+
/* @__PURE__ */ jsx72(TodoStatusDisplay, { status: todo.status, isWorking }),
|
|
17396
17526
|
/* @__PURE__ */ jsx72(Box57, { flexShrink: 1, children: /* @__PURE__ */ jsx72(Text52, { color: textColor, wrap, strikethrough, children: todo.description }) })
|
|
17397
17527
|
] });
|
|
17398
17528
|
};
|
|
17399
17529
|
var TodoTray = () => {
|
|
17400
17530
|
const uiState = useUIState();
|
|
17401
17531
|
const todos = uiState.todos ?? null;
|
|
17532
|
+
const isWorking = uiState.streamingState === "responding" /* Responding */;
|
|
17402
17533
|
const inProgress = useMemo21(() => {
|
|
17403
17534
|
if (todos === null) {
|
|
17404
17535
|
return null;
|
|
@@ -17425,16 +17556,31 @@ var TodoTray = () => {
|
|
|
17425
17556
|
paddingLeft: 1,
|
|
17426
17557
|
paddingRight: 1,
|
|
17427
17558
|
children: uiState.showFullTodos ? /* @__PURE__ */ jsxs56(Box57, { flexDirection: "column", rowGap: 1, children: [
|
|
17428
|
-
/* @__PURE__ */ jsx72(TodoTitleDisplay, { todos }),
|
|
17429
|
-
/* @__PURE__ */ jsx72(TodoListDisplay, { todos })
|
|
17559
|
+
/* @__PURE__ */ jsx72(TodoTitleDisplay, { todos, isWorking }),
|
|
17560
|
+
/* @__PURE__ */ jsx72(TodoListDisplay, { todos, isWorking })
|
|
17430
17561
|
] }) : /* @__PURE__ */ jsxs56(Box57, { flexDirection: "row", columnGap: 1, height: 1, children: [
|
|
17431
|
-
/* @__PURE__ */ jsx72(Box57, { flexShrink:
|
|
17432
|
-
inProgress && /* @__PURE__ */ jsx72(Box57, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx72(
|
|
17562
|
+
/* @__PURE__ */ jsx72(Box57, { flexShrink: 1, flexGrow: 0, children: /* @__PURE__ */ jsx72(TodoTitleDisplay, { todos, isWorking, compact: true }) }),
|
|
17563
|
+
inProgress && /* @__PURE__ */ jsx72(Box57, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx72(
|
|
17564
|
+
TodoItemDisplay,
|
|
17565
|
+
{
|
|
17566
|
+
todo: inProgress,
|
|
17567
|
+
wrap: "truncate",
|
|
17568
|
+
isWorking
|
|
17569
|
+
}
|
|
17570
|
+
) })
|
|
17433
17571
|
] })
|
|
17434
17572
|
}
|
|
17435
17573
|
);
|
|
17436
17574
|
};
|
|
17437
|
-
var TodoListDisplay = ({ todos }) => /* @__PURE__ */ jsx72(Box57, { flexDirection: "column", "aria-role": "list", children: todos.todos.map((todo, index) => /* @__PURE__ */ jsx72(
|
|
17575
|
+
var TodoListDisplay = ({ todos, isWorking }) => /* @__PURE__ */ jsx72(Box57, { flexDirection: "column", "aria-role": "list", children: todos.todos.map((todo, index) => /* @__PURE__ */ jsx72(
|
|
17576
|
+
TodoItemDisplay,
|
|
17577
|
+
{
|
|
17578
|
+
todo,
|
|
17579
|
+
role: "listitem",
|
|
17580
|
+
isWorking
|
|
17581
|
+
},
|
|
17582
|
+
index
|
|
17583
|
+
)) });
|
|
17438
17584
|
|
|
17439
17585
|
// src/ui/components/layout/status-display.tsx
|
|
17440
17586
|
import { Text as Text53 } from "ink";
|
|
@@ -17560,10 +17706,10 @@ var Composer = ({ isFocused = true }) => {
|
|
|
17560
17706
|
|
|
17561
17707
|
// src/ui/components/dialogs/exit-warning.tsx
|
|
17562
17708
|
import { Box as Box59, Text as Text54 } from "ink";
|
|
17563
|
-
import { Fragment as
|
|
17709
|
+
import { Fragment as Fragment14, jsx as jsx75, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
17564
17710
|
var ExitWarning = () => {
|
|
17565
17711
|
const uiState = useUIState();
|
|
17566
|
-
return /* @__PURE__ */ jsxs58(
|
|
17712
|
+
return /* @__PURE__ */ jsxs58(Fragment14, { children: [
|
|
17567
17713
|
uiState.dialogsVisible && uiState.ctrlCPressedOnce && /* @__PURE__ */ jsx75(Box59, { marginTop: 1, children: /* @__PURE__ */ jsx75(Text54, { color: theme.status.warning, children: "Press Ctrl+C again to exit." }) }),
|
|
17568
17714
|
uiState.dialogsVisible && uiState.ctrlDPressedOnce && /* @__PURE__ */ jsx75(Box59, { marginTop: 1, children: /* @__PURE__ */ jsx75(Text54, { color: theme.status.warning, children: "Press Ctrl+D again to exit." }) })
|
|
17569
17715
|
] });
|
|
@@ -18706,7 +18852,7 @@ var CopyModeWarning = () => {
|
|
|
18706
18852
|
};
|
|
18707
18853
|
|
|
18708
18854
|
// src/ui/components/layout/default-app-layout.tsx
|
|
18709
|
-
import { Fragment as
|
|
18855
|
+
import { Fragment as Fragment15, jsx as jsx85, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
18710
18856
|
var DefaultAppLayout = () => {
|
|
18711
18857
|
const uiState = useUIState();
|
|
18712
18858
|
const isAlternateBuffer = useAlternateBuffer();
|
|
@@ -18740,7 +18886,7 @@ var DefaultAppLayout = () => {
|
|
|
18740
18886
|
children: [
|
|
18741
18887
|
/* @__PURE__ */ jsx85(Notifications, {}),
|
|
18742
18888
|
/* @__PURE__ */ jsx85(CopyModeWarning, {}),
|
|
18743
|
-
pendingApproval !== void 0 ? /* @__PURE__ */ jsxs64(
|
|
18889
|
+
pendingApproval !== void 0 ? /* @__PURE__ */ jsxs64(Fragment15, { children: [
|
|
18744
18890
|
/* @__PURE__ */ jsx85(
|
|
18745
18891
|
ToolConfirmationQueue,
|
|
18746
18892
|
{
|
|
@@ -18899,7 +19045,7 @@ function useHistory() {
|
|
|
18899
19045
|
}
|
|
18900
19046
|
|
|
18901
19047
|
// src/ui/hooks/commands/use-slash-command-processor.ts
|
|
18902
|
-
import { useCallback as
|
|
19048
|
+
import { useCallback as useCallback36, useMemo as useMemo34, useEffect as useEffect44, useRef as useRef22, useState as useState42 } from "react";
|
|
18903
19049
|
|
|
18904
19050
|
// src/services/command-service.ts
|
|
18905
19051
|
var CommandService = class _CommandService {
|
|
@@ -19276,7 +19422,7 @@ function ProviderSetupDialog({
|
|
|
19276
19422
|
}
|
|
19277
19423
|
|
|
19278
19424
|
// src/ui/components/dialogs/model-dialog.tsx
|
|
19279
|
-
import { Fragment as
|
|
19425
|
+
import { Fragment as Fragment16, jsx as jsx89, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
19280
19426
|
function capabilityLabel(model) {
|
|
19281
19427
|
return model.inputModalities.includes("image") ? "Text + Vision" : "Text";
|
|
19282
19428
|
}
|
|
@@ -19572,7 +19718,7 @@ function ModelDialog({
|
|
|
19572
19718
|
},
|
|
19573
19719
|
items.map((item) => item.key).join("|")
|
|
19574
19720
|
) }),
|
|
19575
|
-
/* @__PURE__ */ jsx89(Box69, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs67(
|
|
19721
|
+
/* @__PURE__ */ jsx89(Box69, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs67(Fragment16, { children: [
|
|
19576
19722
|
/* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.status.warning, children: "Start a new Session?" }),
|
|
19577
19723
|
/* @__PURE__ */ jsxs67(Box69, { marginTop: 1, flexDirection: "column", children: [
|
|
19578
19724
|
/* @__PURE__ */ jsxs67(Text62, { children: [
|
|
@@ -19597,7 +19743,7 @@ function ModelDialog({
|
|
|
19597
19743
|
showNumbers: false
|
|
19598
19744
|
}
|
|
19599
19745
|
) })
|
|
19600
|
-
] }) : /* @__PURE__ */ jsxs67(
|
|
19746
|
+
] }) : /* @__PURE__ */ jsxs67(Fragment16, { children: [
|
|
19601
19747
|
/* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.text.primary, children: highlighted.name }),
|
|
19602
19748
|
/* @__PURE__ */ jsxs67(Box69, { marginTop: 1, flexDirection: "column", children: [
|
|
19603
19749
|
/* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Provider" }),
|
|
@@ -19633,6 +19779,13 @@ var modelCommand = {
|
|
|
19633
19779
|
content: "Usage: /model"
|
|
19634
19780
|
};
|
|
19635
19781
|
}
|
|
19782
|
+
if (context.services.sideConversation?.getWorkspaceSnapshot().sideSessionId !== void 0) {
|
|
19783
|
+
return {
|
|
19784
|
+
type: "message",
|
|
19785
|
+
messageType: "error",
|
|
19786
|
+
content: "Close the Side conversation before changing the Main model. Use /side, then Ctrl+C."
|
|
19787
|
+
};
|
|
19788
|
+
}
|
|
19636
19789
|
const runtime = context.services.modelSelection;
|
|
19637
19790
|
if (!runtime) {
|
|
19638
19791
|
return { type: "message", messageType: "error", content: "DSH model selection is unavailable." };
|
|
@@ -19661,7 +19814,7 @@ import React17 from "react";
|
|
|
19661
19814
|
// src/ui/components/dialogs/provider-dialog.tsx
|
|
19662
19815
|
import { useEffect as useEffect40, useMemo as useMemo29, useState as useState37 } from "react";
|
|
19663
19816
|
import { Box as Box70, Text as Text63 } from "ink";
|
|
19664
|
-
import { Fragment as
|
|
19817
|
+
import { Fragment as Fragment17, jsx as jsx90, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
19665
19818
|
function statusLabel(status) {
|
|
19666
19819
|
switch (status) {
|
|
19667
19820
|
case "configured":
|
|
@@ -19819,11 +19972,11 @@ function ProviderDialog({
|
|
|
19819
19972
|
/* @__PURE__ */ jsx90(Text63, { children: highlighted.provider }),
|
|
19820
19973
|
/* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Status" }),
|
|
19821
19974
|
/* @__PURE__ */ jsx90(Text63, { color: statusColor(highlighted.status), children: statusLabel(highlighted.status) }),
|
|
19822
|
-
highlighted.credentialLabel && /* @__PURE__ */ jsxs68(
|
|
19975
|
+
highlighted.credentialLabel && /* @__PURE__ */ jsxs68(Fragment17, { children: [
|
|
19823
19976
|
/* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Credential" }),
|
|
19824
19977
|
/* @__PURE__ */ jsx90(Text63, { children: highlighted.credentialLabel })
|
|
19825
19978
|
] }),
|
|
19826
|
-
highlighted.source && /* @__PURE__ */ jsxs68(
|
|
19979
|
+
highlighted.source && /* @__PURE__ */ jsxs68(Fragment17, { children: [
|
|
19827
19980
|
/* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Source" }),
|
|
19828
19981
|
/* @__PURE__ */ jsx90(Text63, { children: highlighted.source })
|
|
19829
19982
|
] }),
|
|
@@ -19832,7 +19985,7 @@ function ProviderDialog({
|
|
|
19832
19985
|
] })
|
|
19833
19986
|
] })
|
|
19834
19987
|
] }),
|
|
19835
|
-
providers.length > 0 && highlighted && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: highlighted.writable && highlighted.status !== "unsupported" ? /* @__PURE__ */ jsxs68(
|
|
19988
|
+
providers.length > 0 && highlighted && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: highlighted.writable && highlighted.status !== "unsupported" ? /* @__PURE__ */ jsxs68(Fragment17, { children: [
|
|
19836
19989
|
/* @__PURE__ */ jsx90(Text63, { bold: true, color: theme.text.accent, children: "Enter" }),
|
|
19837
19990
|
/* @__PURE__ */ jsxs68(Text63, { color: theme.text.primary, children: [
|
|
19838
19991
|
" ",
|
|
@@ -19896,7 +20049,7 @@ import React18 from "react";
|
|
|
19896
20049
|
// src/ui/components/dialogs/session-dialog.tsx
|
|
19897
20050
|
import { useCallback as useCallback33, useEffect as useEffect41, useMemo as useMemo30, useRef as useRef20, useState as useState38 } from "react";
|
|
19898
20051
|
import { Box as Box71, Text as Text64 } from "ink";
|
|
19899
|
-
import { Fragment as
|
|
20052
|
+
import { Fragment as Fragment18, jsx as jsx91, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
19900
20053
|
function shortId(id) {
|
|
19901
20054
|
const start2 = id.startsWith("dsh-console-") ? "dsh-console-".length : 0;
|
|
19902
20055
|
return id.slice(start2, start2 + 12);
|
|
@@ -19912,24 +20065,64 @@ function SessionDialog({ runtime, onClose }) {
|
|
|
19912
20065
|
const [switching, setSwitching] = useState38(false);
|
|
19913
20066
|
const [error, setError] = useState38();
|
|
19914
20067
|
const switchingRef = useRef20(false);
|
|
20068
|
+
const titleRequestsRef = useRef20(/* @__PURE__ */ new Map());
|
|
20069
|
+
const resolveTitles = useCallback33((candidates) => {
|
|
20070
|
+
const sessionsToResolve = candidates.filter((session) => !session.title && !titleRequestsRef.current.has(session.id));
|
|
20071
|
+
if (sessionsToResolve.length === 0) return;
|
|
20072
|
+
const controller = new AbortController();
|
|
20073
|
+
for (const session of sessionsToResolve) {
|
|
20074
|
+
titleRequestsRef.current.set(session.id, controller);
|
|
20075
|
+
}
|
|
20076
|
+
void runtime.resolveSessionTitles(
|
|
20077
|
+
sessionsToResolve.map((session) => session.id),
|
|
20078
|
+
controller.signal
|
|
20079
|
+
).then((titles) => {
|
|
20080
|
+
if (controller.signal.aborted || titles.length === 0) return;
|
|
20081
|
+
const titleById = new Map(titles.map(({ id, title }) => [id, title]));
|
|
20082
|
+
const withResolvedTitle = (item) => {
|
|
20083
|
+
const title = titleById.get(item.id);
|
|
20084
|
+
return title === void 0 ? item : { ...item, title };
|
|
20085
|
+
};
|
|
20086
|
+
setSessions((current) => current.map(withResolvedTitle));
|
|
20087
|
+
setHighlighted((current) => current ? withResolvedTitle(current) : current);
|
|
20088
|
+
setPending((current) => current ? withResolvedTitle(current) : current);
|
|
20089
|
+
}).catch(() => {
|
|
20090
|
+
}).finally(() => {
|
|
20091
|
+
for (const session of sessionsToResolve) {
|
|
20092
|
+
if (titleRequestsRef.current.get(session.id) === controller) {
|
|
20093
|
+
titleRequestsRef.current.delete(session.id);
|
|
20094
|
+
}
|
|
20095
|
+
}
|
|
20096
|
+
});
|
|
20097
|
+
}, [runtime]);
|
|
19915
20098
|
useEffect41(() => {
|
|
19916
20099
|
const controller = new AbortController();
|
|
20100
|
+
const titleRequests = titleRequestsRef.current;
|
|
19917
20101
|
void runtime.listSessions(controller.signal).then((listed) => {
|
|
19918
20102
|
setSessions(listed);
|
|
19919
20103
|
setHighlighted(listed.find((session) => session.current) ?? listed[0]);
|
|
20104
|
+
resolveTitles(listed.slice(0, 12));
|
|
19920
20105
|
}).catch((cause) => {
|
|
19921
20106
|
if (!controller.signal.aborted) setError(cause instanceof Error ? cause.message : String(cause));
|
|
19922
20107
|
}).finally(() => {
|
|
19923
20108
|
if (!controller.signal.aborted) setLoading(false);
|
|
19924
20109
|
});
|
|
19925
|
-
return () =>
|
|
19926
|
-
|
|
20110
|
+
return () => {
|
|
20111
|
+
controller.abort();
|
|
20112
|
+
for (const titleController of titleRequests.values()) titleController.abort();
|
|
20113
|
+
titleRequests.clear();
|
|
20114
|
+
};
|
|
20115
|
+
}, [resolveTitles, runtime]);
|
|
19927
20116
|
const items = useMemo30(() => sessions.map((session) => ({
|
|
19928
20117
|
key: session.id,
|
|
19929
20118
|
value: session,
|
|
19930
20119
|
label: sessionLabel(session)
|
|
19931
20120
|
})), [sessions]);
|
|
19932
20121
|
const initialIndex = Math.max(0, sessions.findIndex((session) => session.current));
|
|
20122
|
+
const highlight = useCallback33((session) => {
|
|
20123
|
+
setHighlighted(session);
|
|
20124
|
+
resolveTitles([session]);
|
|
20125
|
+
}, [resolveTitles]);
|
|
19933
20126
|
const resume = useCallback33(async (session) => {
|
|
19934
20127
|
if (switchingRef.current) return;
|
|
19935
20128
|
switchingRef.current = true;
|
|
@@ -19975,7 +20168,7 @@ function SessionDialog({ runtime, onClose }) {
|
|
|
19975
20168
|
{
|
|
19976
20169
|
items,
|
|
19977
20170
|
initialIndex,
|
|
19978
|
-
onHighlight:
|
|
20171
|
+
onHighlight: highlight,
|
|
19979
20172
|
onSelect: select,
|
|
19980
20173
|
isFocused: !pending && !switching,
|
|
19981
20174
|
showScrollArrows: true,
|
|
@@ -19987,7 +20180,7 @@ function SessionDialog({ runtime, onClose }) {
|
|
|
19987
20180
|
] })
|
|
19988
20181
|
}
|
|
19989
20182
|
) }),
|
|
19990
|
-
/* @__PURE__ */ jsx91(Box71, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs69(
|
|
20183
|
+
/* @__PURE__ */ jsx91(Box71, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs69(Fragment18, { children: [
|
|
19991
20184
|
/* @__PURE__ */ jsx91(Text64, { bold: true, color: theme.status.warning, children: "Resume this Session?" }),
|
|
19992
20185
|
/* @__PURE__ */ jsxs69(Box71, { marginTop: 1, flexDirection: "column", children: [
|
|
19993
20186
|
/* @__PURE__ */ jsx91(Text64, { children: sessionLabel(pending) }),
|
|
@@ -20005,12 +20198,12 @@ function SessionDialog({ runtime, onClose }) {
|
|
|
20005
20198
|
showNumbers: false
|
|
20006
20199
|
}
|
|
20007
20200
|
) })
|
|
20008
|
-
] }) : highlighted ? /* @__PURE__ */ jsxs69(
|
|
20201
|
+
] }) : highlighted ? /* @__PURE__ */ jsxs69(Fragment18, { children: [
|
|
20009
20202
|
/* @__PURE__ */ jsx91(Text64, { bold: true, children: sessionLabel(highlighted) }),
|
|
20010
20203
|
/* @__PURE__ */ jsxs69(Box71, { marginTop: 1, flexDirection: "column", children: [
|
|
20011
20204
|
/* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Created" }),
|
|
20012
20205
|
/* @__PURE__ */ jsx91(Text64, { children: new Date(highlighted.createdAt).toLocaleString() }),
|
|
20013
|
-
!highlighted.resumable && highlighted.resumeUnavailableReason && /* @__PURE__ */ jsxs69(
|
|
20206
|
+
!highlighted.resumable && highlighted.resumeUnavailableReason && /* @__PURE__ */ jsxs69(Fragment18, { children: [
|
|
20014
20207
|
/* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Resume status" }),
|
|
20015
20208
|
/* @__PURE__ */ jsx91(Text64, { color: theme.status.warning, children: highlighted.resumeUnavailableReason })
|
|
20016
20209
|
] }),
|
|
@@ -20027,6 +20220,13 @@ function SessionDialog({ runtime, onClose }) {
|
|
|
20027
20220
|
function unavailable() {
|
|
20028
20221
|
return { type: "message", messageType: "error", content: "DSH Session management is unavailable." };
|
|
20029
20222
|
}
|
|
20223
|
+
function requireStableMain(context) {
|
|
20224
|
+
return context.services.sideConversation?.getWorkspaceSnapshot().sideSessionId !== void 0 ? {
|
|
20225
|
+
type: "message",
|
|
20226
|
+
messageType: "error",
|
|
20227
|
+
content: "Close the Side conversation before managing Main Sessions. Use /side, then Ctrl+C."
|
|
20228
|
+
} : void 0;
|
|
20229
|
+
}
|
|
20030
20230
|
function openDialog(context) {
|
|
20031
20231
|
const runtime = context.services.sessionManagement;
|
|
20032
20232
|
if (!runtime) return unavailable();
|
|
@@ -20044,6 +20244,8 @@ var newCommand = {
|
|
|
20044
20244
|
kind: "built-in" /* BUILT_IN */,
|
|
20045
20245
|
autoExecute: true,
|
|
20046
20246
|
action: async (context, args) => {
|
|
20247
|
+
const mainRequired = requireStableMain(context);
|
|
20248
|
+
if (mainRequired) return mainRequired;
|
|
20047
20249
|
if (args.trim() !== "") return { type: "message", messageType: "error", content: "Usage: /new" };
|
|
20048
20250
|
const runtime = context.services.sessionManagement;
|
|
20049
20251
|
if (!runtime) return unavailable();
|
|
@@ -20065,7 +20267,11 @@ var sessionsCommand = {
|
|
|
20065
20267
|
description: "Browse dsh-console Sessions in this workspace",
|
|
20066
20268
|
kind: "built-in" /* BUILT_IN */,
|
|
20067
20269
|
autoExecute: true,
|
|
20068
|
-
action: async (context, args) =>
|
|
20270
|
+
action: async (context, args) => {
|
|
20271
|
+
const mainRequired = requireStableMain(context);
|
|
20272
|
+
if (mainRequired) return mainRequired;
|
|
20273
|
+
return args.trim() === "" ? openDialog(context) : { type: "message", messageType: "error", content: "Usage: /sessions" };
|
|
20274
|
+
}
|
|
20069
20275
|
};
|
|
20070
20276
|
var resumeCommand = {
|
|
20071
20277
|
name: "resume",
|
|
@@ -20073,6 +20279,8 @@ var resumeCommand = {
|
|
|
20073
20279
|
kind: "built-in" /* BUILT_IN */,
|
|
20074
20280
|
autoExecute: true,
|
|
20075
20281
|
action: async (context, args) => {
|
|
20282
|
+
const mainRequired = requireStableMain(context);
|
|
20283
|
+
if (mainRequired) return mainRequired;
|
|
20076
20284
|
const runtime = context.services.sessionManagement;
|
|
20077
20285
|
if (!runtime) return unavailable();
|
|
20078
20286
|
const sessionId = args.trim();
|
|
@@ -20146,7 +20354,7 @@ function DescriptiveRadioButtonSelect({
|
|
|
20146
20354
|
}
|
|
20147
20355
|
|
|
20148
20356
|
// src/ui/components/dialogs/tools-dialog.tsx
|
|
20149
|
-
import { Fragment as
|
|
20357
|
+
import { Fragment as Fragment19, jsx as jsx93, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
20150
20358
|
function summary(description) {
|
|
20151
20359
|
const line = description.replace(/\s+/g, " ").trim();
|
|
20152
20360
|
return line.length > 90 ? `${line.slice(0, 89)}...` : line;
|
|
@@ -20207,7 +20415,7 @@ function ToolsDialog({ runtime, onClose }) {
|
|
|
20207
20415
|
maxItemsToShow: 10
|
|
20208
20416
|
}
|
|
20209
20417
|
) }),
|
|
20210
|
-
/* @__PURE__ */ jsx93(Box73, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected && /* @__PURE__ */ jsxs71(
|
|
20418
|
+
/* @__PURE__ */ jsx93(Box73, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected && /* @__PURE__ */ jsxs71(Fragment19, { children: [
|
|
20211
20419
|
/* @__PURE__ */ jsx93(Text66, { bold: true, color: theme.text.accent, children: selected.name }),
|
|
20212
20420
|
/* @__PURE__ */ jsx93(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx93(Text66, { wrap: "wrap", children: selected.description }) }),
|
|
20213
20421
|
/* @__PURE__ */ jsxs71(Box73, { marginTop: 1, flexDirection: "column", children: [
|
|
@@ -20270,7 +20478,7 @@ import React20 from "react";
|
|
|
20270
20478
|
// src/ui/components/dialogs/permission-dialog.tsx
|
|
20271
20479
|
import { useCallback as useCallback34, useMemo as useMemo32, useState as useState40, useSyncExternalStore as useSyncExternalStore4 } from "react";
|
|
20272
20480
|
import { Box as Box74, Text as Text67 } from "ink";
|
|
20273
|
-
import { Fragment as
|
|
20481
|
+
import { Fragment as Fragment20, jsx as jsx94, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
20274
20482
|
function PermissionDialog({
|
|
20275
20483
|
runtime,
|
|
20276
20484
|
onClose,
|
|
@@ -20364,7 +20572,7 @@ function PermissionDialog({
|
|
|
20364
20572
|
},
|
|
20365
20573
|
items.map((item) => item.key).join("|")
|
|
20366
20574
|
) }),
|
|
20367
|
-
/* @__PURE__ */ jsx94(Box74, { width: "50%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs72(
|
|
20575
|
+
/* @__PURE__ */ jsx94(Box74, { width: "50%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs72(Fragment20, { children: [
|
|
20368
20576
|
/* @__PURE__ */ jsx94(Text67, { bold: true, color: theme.status.warning, children: "Enable Full access?" }),
|
|
20369
20577
|
/* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { children: "This allows commands to run without workspace sandbox restrictions or approval prompts." }) }),
|
|
20370
20578
|
/* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(
|
|
@@ -20382,7 +20590,7 @@ function PermissionDialog({
|
|
|
20382
20590
|
showNumbers: false
|
|
20383
20591
|
}
|
|
20384
20592
|
) })
|
|
20385
|
-
] }) : selected ? /* @__PURE__ */ jsxs72(
|
|
20593
|
+
] }) : selected ? /* @__PURE__ */ jsxs72(Fragment20, { children: [
|
|
20386
20594
|
/* @__PURE__ */ jsx94(Text67, { bold: true, color: theme.text.primary, children: selected.name }),
|
|
20387
20595
|
/* @__PURE__ */ jsx94(Text67, { color: theme.text.secondary, children: selected.value }),
|
|
20388
20596
|
/* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { children: selected.description ?? "No description is available for this preset." }) }),
|
|
@@ -20478,82 +20686,525 @@ var profilerCommand = {
|
|
|
20478
20686
|
action: (context) => context.ui.toggleDebugProfiler()
|
|
20479
20687
|
};
|
|
20480
20688
|
|
|
20481
|
-
// src/
|
|
20482
|
-
var
|
|
20483
|
-
|
|
20484
|
-
|
|
20485
|
-
|
|
20486
|
-
|
|
20487
|
-
|
|
20488
|
-
|
|
20489
|
-
|
|
20490
|
-
|
|
20491
|
-
|
|
20492
|
-
|
|
20493
|
-
|
|
20494
|
-
|
|
20495
|
-
|
|
20496
|
-
|
|
20497
|
-
|
|
20498
|
-
|
|
20499
|
-
helpCommand,
|
|
20500
|
-
aboutCommand,
|
|
20501
|
-
statsCommand,
|
|
20502
|
-
toolsCommand,
|
|
20503
|
-
...this.enableProfiler ? [profilerCommand] : [],
|
|
20504
|
-
quitCommand,
|
|
20505
|
-
themeCommand,
|
|
20506
|
-
settingsCommand,
|
|
20507
|
-
vimCommand,
|
|
20508
|
-
modelCommand,
|
|
20509
|
-
providerCommand,
|
|
20510
|
-
permissionCommand,
|
|
20511
|
-
newCommand,
|
|
20512
|
-
sessionsCommand,
|
|
20513
|
-
resumeCommand
|
|
20514
|
-
];
|
|
20515
|
-
const duration = (performance.now() - startTime).toFixed(2);
|
|
20516
|
-
const logMessage = `[BuiltinCommandLoader] ${isInitialLoad ? "Loaded" : "Reloaded"} ${commands.length} commands in ${duration}ms`;
|
|
20517
|
-
if (isInitialLoad) {
|
|
20518
|
-
debugLogger.log(logMessage);
|
|
20519
|
-
} else {
|
|
20520
|
-
debugLogger.debug(logMessage);
|
|
20689
|
+
// src/ui/commands/btw-command.ts
|
|
20690
|
+
var btwCommand = {
|
|
20691
|
+
name: "btw",
|
|
20692
|
+
description: "Ask an ephemeral side question without interrupting the main Agent",
|
|
20693
|
+
inputHint: "<question>",
|
|
20694
|
+
kind: "built-in" /* BUILT_IN */,
|
|
20695
|
+
autoExecute: false,
|
|
20696
|
+
recordInvocation: false,
|
|
20697
|
+
allowWhileBusy: true,
|
|
20698
|
+
action: async (context, args) => {
|
|
20699
|
+
const question = args.trim();
|
|
20700
|
+
const runtime = context.services.sideConversation;
|
|
20701
|
+
if (!runtime) {
|
|
20702
|
+
return {
|
|
20703
|
+
type: "message",
|
|
20704
|
+
messageType: "error",
|
|
20705
|
+
content: "DSH Side conversations are unavailable."
|
|
20706
|
+
};
|
|
20521
20707
|
}
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20528
|
-
const trimmed = query.trim();
|
|
20529
|
-
const parts = trimmed.substring(1).trim().split(/\s+/);
|
|
20530
|
-
const commandPath = parts.filter((p) => p);
|
|
20531
|
-
let currentCommands = commands;
|
|
20532
|
-
let commandToExecute;
|
|
20533
|
-
let pathIndex = 0;
|
|
20534
|
-
const canonicalPath = [];
|
|
20535
|
-
for (const part of commandPath) {
|
|
20536
|
-
let foundCommand = currentCommands.find((cmd) => cmd.name === part);
|
|
20537
|
-
if (!foundCommand) {
|
|
20538
|
-
foundCommand = currentCommands.find(
|
|
20539
|
-
(cmd) => cmd.altNames?.includes(part)
|
|
20540
|
-
);
|
|
20708
|
+
if (!question && runtime.getWorkspaceSnapshot().sideSessionId === void 0) {
|
|
20709
|
+
return {
|
|
20710
|
+
type: "message",
|
|
20711
|
+
messageType: "error",
|
|
20712
|
+
content: "Usage: /btw <question>"
|
|
20713
|
+
};
|
|
20541
20714
|
}
|
|
20542
|
-
|
|
20543
|
-
|
|
20544
|
-
|
|
20545
|
-
|
|
20546
|
-
|
|
20547
|
-
|
|
20548
|
-
|
|
20549
|
-
|
|
20715
|
+
await runtime.open(question || void 0, context.invocation.signal);
|
|
20716
|
+
return void 0;
|
|
20717
|
+
}
|
|
20718
|
+
};
|
|
20719
|
+
var mainCommand = {
|
|
20720
|
+
name: "main",
|
|
20721
|
+
description: "Switch to the main conversation",
|
|
20722
|
+
kind: "built-in" /* BUILT_IN */,
|
|
20723
|
+
autoExecute: true,
|
|
20724
|
+
recordInvocation: false,
|
|
20725
|
+
allowWhileBusy: true,
|
|
20726
|
+
action: (context, args) => {
|
|
20727
|
+
if (args.trim()) return { type: "message", messageType: "error", content: "Usage: /main" };
|
|
20728
|
+
const runtime = context.services.sideConversation;
|
|
20729
|
+
if (!runtime) return { type: "message", messageType: "error", content: "DSH Side conversations are unavailable." };
|
|
20730
|
+
runtime.switchToMain();
|
|
20731
|
+
return void 0;
|
|
20732
|
+
}
|
|
20733
|
+
};
|
|
20734
|
+
var sideCommand = {
|
|
20735
|
+
name: "side",
|
|
20736
|
+
description: "Switch to the active Side conversation",
|
|
20737
|
+
kind: "built-in" /* BUILT_IN */,
|
|
20738
|
+
autoExecute: true,
|
|
20739
|
+
recordInvocation: false,
|
|
20740
|
+
allowWhileBusy: true,
|
|
20741
|
+
action: (context, args) => {
|
|
20742
|
+
if (args.trim()) return { type: "message", messageType: "error", content: "Usage: /side" };
|
|
20743
|
+
const runtime = context.services.sideConversation;
|
|
20744
|
+
if (!runtime) return { type: "message", messageType: "error", content: "DSH Side conversations are unavailable." };
|
|
20745
|
+
runtime.switchToSide();
|
|
20746
|
+
return void 0;
|
|
20747
|
+
}
|
|
20748
|
+
};
|
|
20749
|
+
|
|
20750
|
+
// src/ui/commands/agents-command.ts
|
|
20751
|
+
import React21 from "react";
|
|
20752
|
+
|
|
20753
|
+
// src/ui/components/dialogs/agents-dialog.tsx
|
|
20754
|
+
import {
|
|
20755
|
+
useCallback as useCallback35,
|
|
20756
|
+
useEffect as useEffect43,
|
|
20757
|
+
useMemo as useMemo33,
|
|
20758
|
+
useRef as useRef21,
|
|
20759
|
+
useState as useState41,
|
|
20760
|
+
useSyncExternalStore as useSyncExternalStore5
|
|
20761
|
+
} from "react";
|
|
20762
|
+
import { Box as Box75, Text as Text68 } from "ink";
|
|
20763
|
+
|
|
20764
|
+
// src/ui/conversation-history-projector.ts
|
|
20765
|
+
function projectedToolCallIds(messages) {
|
|
20766
|
+
return new Set(
|
|
20767
|
+
messages.flatMap(
|
|
20768
|
+
(message) => message.role === "tool" ? [message.callId] : []
|
|
20769
|
+
)
|
|
20770
|
+
);
|
|
20771
|
+
}
|
|
20772
|
+
function conversationMessageToHistoryItem(message, visibleToolCallIds) {
|
|
20773
|
+
const assistantContent = message.role === "assistant" ? message.content.filter(
|
|
20774
|
+
(block) => block.type !== "tool-call" || !visibleToolCallIds.has(block.id)
|
|
20775
|
+
) : void 0;
|
|
20776
|
+
if (message.role === "assistant" && assistantContent?.length === 0 && message.interrupted !== true) {
|
|
20777
|
+
return void 0;
|
|
20778
|
+
}
|
|
20779
|
+
if (message.role === "tool") {
|
|
20780
|
+
return {
|
|
20781
|
+
type: "tool_group",
|
|
20782
|
+
tools: [
|
|
20783
|
+
{
|
|
20784
|
+
callId: message.callId,
|
|
20785
|
+
name: message.presentation?.kind === "card" ? message.presentation.title ?? message.name : message.name,
|
|
20786
|
+
description: message.presentation?.kind === "compact" ? "" : message.presentation?.description ?? message.arguments,
|
|
20787
|
+
resultDisplay: message.presentation?.kind === "compact" ? void 0 : message.presentation?.resultDisplay ?? (message.result === void 0 ? void 0 : {
|
|
20788
|
+
type: "dsh-content",
|
|
20789
|
+
content: message.result.content,
|
|
20790
|
+
...message.result.error === void 0 ? {} : { error: message.result.error }
|
|
20791
|
+
}),
|
|
20792
|
+
...message.presentation?.kind === "compact" ? {
|
|
20793
|
+
presentation: {
|
|
20794
|
+
kind: "compact",
|
|
20795
|
+
label: message.presentation.label
|
|
20796
|
+
}
|
|
20797
|
+
} : {},
|
|
20798
|
+
status: message.status === "executing" ? "Executing" /* Executing */ : message.status === "success" ? "Success" /* Success */ : "Error" /* Error */
|
|
20799
|
+
}
|
|
20800
|
+
]
|
|
20801
|
+
};
|
|
20802
|
+
}
|
|
20803
|
+
if (message.role === "assistant") {
|
|
20804
|
+
return {
|
|
20805
|
+
type: "dsh_assistant",
|
|
20806
|
+
content: assistantContent ?? message.content,
|
|
20807
|
+
interrupted: message.interrupted === true
|
|
20808
|
+
};
|
|
20809
|
+
}
|
|
20810
|
+
if (message.role === "user") {
|
|
20811
|
+
return {
|
|
20812
|
+
type: "dsh_user",
|
|
20813
|
+
content: message.displayContent ?? message.content
|
|
20814
|
+
};
|
|
20815
|
+
}
|
|
20816
|
+
return {
|
|
20817
|
+
type: message.status === "cancelled" ? "warning" /* WARNING */ : "error" /* ERROR */,
|
|
20818
|
+
text: conversationMessageText(message)
|
|
20819
|
+
};
|
|
20820
|
+
}
|
|
20821
|
+
function conversationMessageFingerprint(message, item) {
|
|
20822
|
+
if (message.role === "tool") {
|
|
20823
|
+
return JSON.stringify([
|
|
20824
|
+
message.status,
|
|
20825
|
+
message.result,
|
|
20826
|
+
message.presentation
|
|
20827
|
+
]);
|
|
20828
|
+
}
|
|
20829
|
+
if (message.role === "assistant" && item.type === "dsh_assistant") {
|
|
20830
|
+
return JSON.stringify([item.content, item.interrupted]);
|
|
20831
|
+
}
|
|
20832
|
+
if (message.role === "user") {
|
|
20833
|
+
return JSON.stringify(message.displayContent ?? message.content);
|
|
20834
|
+
}
|
|
20835
|
+
return conversationMessageText(message);
|
|
20836
|
+
}
|
|
20837
|
+
|
|
20838
|
+
// src/ui/components/dialogs/agents-dialog.tsx
|
|
20839
|
+
import { Fragment as Fragment21, jsx as jsx95, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
20840
|
+
function shortId2(id) {
|
|
20841
|
+
return id.slice(-8);
|
|
20842
|
+
}
|
|
20843
|
+
function itemTitle(item) {
|
|
20844
|
+
const branch = item.depth > 1 ? `${" ".repeat(item.depth - 1)}- ` : "";
|
|
20845
|
+
return `${branch}${item.kind === "agent" ? item.label : `Unavailable ${shortId2(item.id)}`}`;
|
|
20846
|
+
}
|
|
20847
|
+
function itemDescription(item) {
|
|
20848
|
+
if (item.kind === "diagnostic") return `diagnostic \xB7 ${item.reason}`;
|
|
20849
|
+
return `${item.activity} \xB7 ${item.mode}`;
|
|
20850
|
+
}
|
|
20851
|
+
function AgentsDialog({ runtime, onClose }) {
|
|
20852
|
+
const snapshot = useSyncExternalStore5(
|
|
20853
|
+
runtime.subscribe,
|
|
20854
|
+
runtime.getSnapshot,
|
|
20855
|
+
runtime.getSnapshot
|
|
20856
|
+
);
|
|
20857
|
+
const [selectedId, setSelectedId] = useState41(snapshot.items[0]?.id);
|
|
20858
|
+
const [transcript, setTranscript] = useState41();
|
|
20859
|
+
const [transcriptSessionId, setTranscriptSessionId] = useState41();
|
|
20860
|
+
const [opening, setOpening] = useState41(false);
|
|
20861
|
+
const [openError, setOpenError] = useState41();
|
|
20862
|
+
const openController = useRef21(void 0);
|
|
20863
|
+
const openingRef = useRef21(false);
|
|
20864
|
+
const transcriptRef = useRef21(void 0);
|
|
20865
|
+
const selected = snapshot.items.find((item) => item.id === selectedId) ?? snapshot.items[0];
|
|
20866
|
+
useEffect43(() => {
|
|
20867
|
+
const controller = new AbortController();
|
|
20868
|
+
void runtime.refresh(controller.signal);
|
|
20869
|
+
return () => controller.abort();
|
|
20870
|
+
}, [runtime]);
|
|
20871
|
+
useEffect43(
|
|
20872
|
+
() => () => {
|
|
20873
|
+
openController.current?.abort();
|
|
20874
|
+
transcriptRef.current?.dispose();
|
|
20875
|
+
transcriptRef.current = void 0;
|
|
20876
|
+
},
|
|
20877
|
+
[]
|
|
20878
|
+
);
|
|
20879
|
+
useEffect43(() => {
|
|
20880
|
+
if (selected?.id !== selectedId) setSelectedId(selected?.id);
|
|
20881
|
+
}, [selected?.id, selectedId]);
|
|
20882
|
+
useKeypress(
|
|
20883
|
+
(key) => {
|
|
20884
|
+
if (transcript !== void 0) return;
|
|
20885
|
+
if (key.name === "escape") onClose();
|
|
20886
|
+
if (key.name === "r") void runtime.refresh();
|
|
20887
|
+
},
|
|
20888
|
+
{ isActive: true }
|
|
20889
|
+
);
|
|
20890
|
+
const openTranscript = useCallback35(
|
|
20891
|
+
async (sessionId) => {
|
|
20892
|
+
const item = snapshot.items.find(
|
|
20893
|
+
(candidate) => candidate.id === sessionId && candidate.kind === "agent"
|
|
20894
|
+
);
|
|
20895
|
+
if (item === void 0 || openingRef.current) return;
|
|
20896
|
+
openingRef.current = true;
|
|
20897
|
+
openController.current?.abort();
|
|
20898
|
+
const controller = new AbortController();
|
|
20899
|
+
openController.current = controller;
|
|
20900
|
+
setOpening(true);
|
|
20901
|
+
setOpenError(void 0);
|
|
20902
|
+
try {
|
|
20903
|
+
const next = await runtime.openTranscript(sessionId, controller.signal);
|
|
20904
|
+
if (controller.signal.aborted) {
|
|
20905
|
+
next.dispose();
|
|
20906
|
+
return;
|
|
20907
|
+
}
|
|
20908
|
+
transcriptRef.current?.dispose();
|
|
20909
|
+
transcriptRef.current = next;
|
|
20910
|
+
setTranscriptSessionId(sessionId);
|
|
20911
|
+
setTranscript(next);
|
|
20912
|
+
} catch (error) {
|
|
20913
|
+
if (!controller.signal.aborted) {
|
|
20914
|
+
setOpenError(
|
|
20915
|
+
error instanceof Error ? error.message : "Unable to open the subagent transcript."
|
|
20916
|
+
);
|
|
20917
|
+
}
|
|
20918
|
+
} finally {
|
|
20919
|
+
if (openController.current === controller) {
|
|
20920
|
+
openController.current = void 0;
|
|
20921
|
+
openingRef.current = false;
|
|
20922
|
+
if (!controller.signal.aborted) setOpening(false);
|
|
20923
|
+
}
|
|
20924
|
+
}
|
|
20925
|
+
},
|
|
20926
|
+
[runtime, snapshot.items]
|
|
20927
|
+
);
|
|
20928
|
+
const closeTranscript = useCallback35(() => {
|
|
20929
|
+
openController.current?.abort();
|
|
20930
|
+
openController.current = void 0;
|
|
20931
|
+
openingRef.current = false;
|
|
20932
|
+
transcriptRef.current?.dispose();
|
|
20933
|
+
transcriptRef.current = void 0;
|
|
20934
|
+
setTranscript(void 0);
|
|
20935
|
+
setTranscriptSessionId(void 0);
|
|
20936
|
+
setOpenError(void 0);
|
|
20937
|
+
}, []);
|
|
20938
|
+
const items = useMemo33(
|
|
20939
|
+
() => snapshot.items.map((item) => ({
|
|
20940
|
+
key: item.id,
|
|
20941
|
+
value: item.id,
|
|
20942
|
+
title: itemTitle(item),
|
|
20943
|
+
description: itemDescription(item)
|
|
20944
|
+
})),
|
|
20945
|
+
[snapshot.items]
|
|
20946
|
+
);
|
|
20947
|
+
if (transcript !== void 0 && transcriptSessionId !== void 0) {
|
|
20948
|
+
const item = snapshot.items.find(
|
|
20949
|
+
(candidate) => candidate.id === transcriptSessionId
|
|
20950
|
+
);
|
|
20951
|
+
return /* @__PURE__ */ jsx95(
|
|
20952
|
+
AgentTranscriptView,
|
|
20953
|
+
{
|
|
20954
|
+
runtime: transcript,
|
|
20955
|
+
item,
|
|
20956
|
+
onBack: closeTranscript
|
|
20550
20957
|
}
|
|
20958
|
+
);
|
|
20959
|
+
}
|
|
20960
|
+
return /* @__PURE__ */ jsxs73(
|
|
20961
|
+
Box75,
|
|
20962
|
+
{
|
|
20963
|
+
borderStyle: "round",
|
|
20964
|
+
borderColor: theme.border.default,
|
|
20965
|
+
flexDirection: "column",
|
|
20966
|
+
paddingX: 1,
|
|
20967
|
+
paddingY: 1,
|
|
20968
|
+
width: "100%",
|
|
20969
|
+
children: [
|
|
20970
|
+
/* @__PURE__ */ jsxs73(Box75, { justifyContent: "space-between", children: [
|
|
20971
|
+
/* @__PURE__ */ jsxs73(Text68, { bold: true, color: theme.text.primary, children: [
|
|
20972
|
+
"DSH Agents (",
|
|
20973
|
+
snapshot.items.length,
|
|
20974
|
+
")"
|
|
20975
|
+
] }),
|
|
20976
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "R refresh \xB7 Esc close" })
|
|
20977
|
+
] }),
|
|
20978
|
+
snapshot.status === "loading" && snapshot.items.length === 0 ? /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "Loading delegated Agents..." }) }) : snapshot.status === "error" && snapshot.items.length === 0 ? /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.status.error, children: snapshot.error }) }) : snapshot.items.length === 0 ? /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "The Main Agent has not delegated any subagents in this Session." }) }) : /* @__PURE__ */ jsxs73(Box75, { flexDirection: "row", marginTop: 1, children: [
|
|
20979
|
+
/* @__PURE__ */ jsx95(Box75, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx95(
|
|
20980
|
+
DescriptiveRadioButtonSelect,
|
|
20981
|
+
{
|
|
20982
|
+
items,
|
|
20983
|
+
onHighlight: setSelectedId,
|
|
20984
|
+
onSelect: (sessionId) => void openTranscript(sessionId),
|
|
20985
|
+
showNumbers: false,
|
|
20986
|
+
showScrollArrows: true,
|
|
20987
|
+
maxItemsToShow: 10
|
|
20988
|
+
}
|
|
20989
|
+
) }),
|
|
20990
|
+
/* @__PURE__ */ jsx95(Box75, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected?.kind === "agent" ? /* @__PURE__ */ jsxs73(Fragment21, { children: [
|
|
20991
|
+
/* @__PURE__ */ jsx95(Text68, { bold: true, color: theme.text.accent, children: selected.label }),
|
|
20992
|
+
/* @__PURE__ */ jsxs73(Box75, { marginTop: 1, flexDirection: "column", children: [
|
|
20993
|
+
/* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
20994
|
+
"Status",
|
|
20995
|
+
" ",
|
|
20996
|
+
/* @__PURE__ */ jsx95(
|
|
20997
|
+
Text68,
|
|
20998
|
+
{
|
|
20999
|
+
color: selected.activity === "running" ? theme.status.success : theme.text.primary,
|
|
21000
|
+
children: selected.activity
|
|
21001
|
+
}
|
|
21002
|
+
)
|
|
21003
|
+
] }),
|
|
21004
|
+
/* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21005
|
+
"Mode ",
|
|
21006
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: selected.mode })
|
|
21007
|
+
] }),
|
|
21008
|
+
/* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21009
|
+
"Depth ",
|
|
21010
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: selected.depth })
|
|
21011
|
+
] }),
|
|
21012
|
+
/* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21013
|
+
"Session ",
|
|
21014
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: shortId2(selected.id) })
|
|
21015
|
+
] })
|
|
21016
|
+
] })
|
|
21017
|
+
] }) : selected ? /* @__PURE__ */ jsxs73(Fragment21, { children: [
|
|
21018
|
+
/* @__PURE__ */ jsx95(Text68, { bold: true, color: theme.status.warning, children: "Unavailable Agent" }),
|
|
21019
|
+
/* @__PURE__ */ jsxs73(Box75, { marginTop: 1, flexDirection: "column", children: [
|
|
21020
|
+
/* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21021
|
+
"Reason ",
|
|
21022
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: selected.reason })
|
|
21023
|
+
] }),
|
|
21024
|
+
/* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21025
|
+
"Session ",
|
|
21026
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: shortId2(selected.id) })
|
|
21027
|
+
] })
|
|
21028
|
+
] })
|
|
21029
|
+
] }) : null })
|
|
21030
|
+
] }),
|
|
21031
|
+
(opening || openError !== void 0) && /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: openError === void 0 ? theme.text.secondary : theme.status.error, children: openError ?? "Opening canonical Agent history..." }) }),
|
|
21032
|
+
snapshot.items.length > 0 && /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "Enter opens read-only history. Agent conversations remain DSH-owned." }) })
|
|
21033
|
+
]
|
|
21034
|
+
}
|
|
21035
|
+
);
|
|
21036
|
+
}
|
|
21037
|
+
function AgentTranscriptView({
|
|
21038
|
+
runtime,
|
|
21039
|
+
item,
|
|
21040
|
+
onBack
|
|
21041
|
+
}) {
|
|
21042
|
+
const uiState = useUIState();
|
|
21043
|
+
const snapshot = useSyncExternalStore5(
|
|
21044
|
+
runtime.subscribe,
|
|
21045
|
+
runtime.getSnapshot,
|
|
21046
|
+
runtime.getSnapshot
|
|
21047
|
+
);
|
|
21048
|
+
const listRef = useRef21(null);
|
|
21049
|
+
const history = useMemo33(() => transcriptItems(snapshot.messages), [snapshot.messages]);
|
|
21050
|
+
const completed = snapshot.todos.filter((todo) => todo.status === "completed").length;
|
|
21051
|
+
useEffect43(() => {
|
|
21052
|
+
listRef.current?.scrollToEnd();
|
|
21053
|
+
}, [history.length]);
|
|
21054
|
+
useKeypress(
|
|
21055
|
+
(key) => {
|
|
21056
|
+
if (key.name === "escape") onBack();
|
|
21057
|
+
},
|
|
21058
|
+
{ isActive: true }
|
|
21059
|
+
);
|
|
21060
|
+
const width = Math.max(40, uiState.terminalWidth - 4);
|
|
21061
|
+
const height = Math.max(8, uiState.terminalHeight - 6);
|
|
21062
|
+
const label = item?.kind === "agent" ? item.label : shortId2(item?.id ?? "agent");
|
|
21063
|
+
return /* @__PURE__ */ jsxs73(
|
|
21064
|
+
Box75,
|
|
21065
|
+
{
|
|
21066
|
+
borderStyle: "round",
|
|
21067
|
+
borderColor: theme.border.default,
|
|
21068
|
+
flexDirection: "column",
|
|
21069
|
+
paddingX: 1,
|
|
21070
|
+
height,
|
|
21071
|
+
width: "100%",
|
|
21072
|
+
children: [
|
|
21073
|
+
/* @__PURE__ */ jsxs73(Box75, { justifyContent: "space-between", children: [
|
|
21074
|
+
/* @__PURE__ */ jsxs73(Box75, { children: [
|
|
21075
|
+
/* @__PURE__ */ jsx95(Text68, { bold: true, color: theme.text.primary, children: label }),
|
|
21076
|
+
item?.kind === "agent" && /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21077
|
+
" ",
|
|
21078
|
+
"\xB7 ",
|
|
21079
|
+
item.mode,
|
|
21080
|
+
" \xB7",
|
|
21081
|
+
" ",
|
|
21082
|
+
/* @__PURE__ */ jsx95(Text68, { color: item.activity === "running" ? theme.status.success : theme.text.secondary, children: item.activity })
|
|
21083
|
+
] })
|
|
21084
|
+
] }),
|
|
21085
|
+
/* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "Read only \xB7 Esc back" })
|
|
21086
|
+
] }),
|
|
21087
|
+
snapshot.todos.length > 0 && /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
|
|
21088
|
+
"Todo ",
|
|
21089
|
+
completed,
|
|
21090
|
+
"/",
|
|
21091
|
+
snapshot.todos.length,
|
|
21092
|
+
" completed"
|
|
21093
|
+
] }) }),
|
|
21094
|
+
/* @__PURE__ */ jsx95(Box75, { flexGrow: 1, marginTop: 1, overflow: "hidden", children: history.length === 0 ? /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "This Agent has no conversation events yet." }) : /* @__PURE__ */ jsx95(
|
|
21095
|
+
ScrollableListWithForwardRef,
|
|
21096
|
+
{
|
|
21097
|
+
ref: listRef,
|
|
21098
|
+
data: history,
|
|
21099
|
+
hasFocus: true,
|
|
21100
|
+
width: "100%",
|
|
21101
|
+
keyExtractor: (entry) => entry.key,
|
|
21102
|
+
estimatedItemHeight: () => 3,
|
|
21103
|
+
initialScrollIndex: history.length - 1,
|
|
21104
|
+
renderItem: ({ item: entry, index }) => /* @__PURE__ */ jsx95(
|
|
21105
|
+
HistoryItemDisplay,
|
|
21106
|
+
{
|
|
21107
|
+
item: { ...entry.item, id: index },
|
|
21108
|
+
terminalWidth: width,
|
|
21109
|
+
isPending: snapshot.busy && index === history.length - 1,
|
|
21110
|
+
isFocused: false
|
|
21111
|
+
}
|
|
21112
|
+
)
|
|
21113
|
+
}
|
|
21114
|
+
) })
|
|
21115
|
+
]
|
|
21116
|
+
}
|
|
21117
|
+
);
|
|
21118
|
+
}
|
|
21119
|
+
function transcriptItems(messages) {
|
|
21120
|
+
const toolCallIds = projectedToolCallIds(messages);
|
|
21121
|
+
return messages.flatMap((message) => {
|
|
21122
|
+
const item = conversationMessageToHistoryItem(message, toolCallIds);
|
|
21123
|
+
return item === void 0 ? [] : [{ key: message.id, item }];
|
|
21124
|
+
});
|
|
21125
|
+
}
|
|
21126
|
+
|
|
21127
|
+
// src/ui/commands/agents-command.ts
|
|
21128
|
+
var agentsCommand = {
|
|
21129
|
+
name: "agents",
|
|
21130
|
+
description: "Inspect subagents delegated by the Main Agent",
|
|
21131
|
+
kind: "built-in" /* BUILT_IN */,
|
|
21132
|
+
autoExecute: true,
|
|
21133
|
+
recordInvocation: false,
|
|
21134
|
+
allowWhileBusy: true,
|
|
21135
|
+
action: (context, args) => {
|
|
21136
|
+
if (args.trim().length > 0) {
|
|
21137
|
+
return {
|
|
21138
|
+
type: "message",
|
|
21139
|
+
messageType: "error",
|
|
21140
|
+
content: "Usage: /agents"
|
|
21141
|
+
};
|
|
21142
|
+
}
|
|
21143
|
+
const runtime = context.services.subagentCatalog;
|
|
21144
|
+
if (!runtime) {
|
|
21145
|
+
return {
|
|
21146
|
+
type: "message",
|
|
21147
|
+
messageType: "error",
|
|
21148
|
+
content: "DSH Agent catalog is unavailable."
|
|
21149
|
+
};
|
|
21150
|
+
}
|
|
21151
|
+
return {
|
|
21152
|
+
type: "custom_dialog",
|
|
21153
|
+
component: React21.createElement(AgentsDialog, {
|
|
21154
|
+
runtime,
|
|
21155
|
+
onClose: context.ui.removeComponent
|
|
21156
|
+
})
|
|
21157
|
+
};
|
|
21158
|
+
}
|
|
21159
|
+
};
|
|
21160
|
+
|
|
21161
|
+
// src/services/builtin-command-loader.ts
|
|
21162
|
+
var BuiltinCommandLoader = class {
|
|
21163
|
+
constructor(enableProfiler = false) {
|
|
21164
|
+
this.enableProfiler = enableProfiler;
|
|
21165
|
+
}
|
|
21166
|
+
isFirstLoad = true;
|
|
21167
|
+
/**
|
|
21168
|
+
* Gathers all raw built-in command definitions, injects dependencies where
|
|
21169
|
+
* needed (e.g., config) and filters out any that are not available.
|
|
21170
|
+
*
|
|
21171
|
+
* @param _signal An AbortSignal (unused for this synchronous loader).
|
|
21172
|
+
* @returns A promise that resolves to an array of `SlashCommand` objects.
|
|
21173
|
+
*/
|
|
21174
|
+
async loadCommands(_signal) {
|
|
21175
|
+
const startTime = performance.now();
|
|
21176
|
+
const isInitialLoad = this.isFirstLoad;
|
|
21177
|
+
this.isFirstLoad = false;
|
|
21178
|
+
const commands = [
|
|
21179
|
+
helpCommand,
|
|
21180
|
+
aboutCommand,
|
|
21181
|
+
statsCommand,
|
|
21182
|
+
toolsCommand,
|
|
21183
|
+
agentsCommand,
|
|
21184
|
+
btwCommand,
|
|
21185
|
+
mainCommand,
|
|
21186
|
+
sideCommand,
|
|
21187
|
+
...this.enableProfiler ? [profilerCommand] : [],
|
|
21188
|
+
quitCommand,
|
|
21189
|
+
themeCommand,
|
|
21190
|
+
settingsCommand,
|
|
21191
|
+
vimCommand,
|
|
21192
|
+
modelCommand,
|
|
21193
|
+
providerCommand,
|
|
21194
|
+
permissionCommand,
|
|
21195
|
+
newCommand,
|
|
21196
|
+
sessionsCommand,
|
|
21197
|
+
resumeCommand
|
|
21198
|
+
];
|
|
21199
|
+
const duration = (performance.now() - startTime).toFixed(2);
|
|
21200
|
+
const logMessage = `[BuiltinCommandLoader] ${isInitialLoad ? "Loaded" : "Reloaded"} ${commands.length} commands in ${duration}ms`;
|
|
21201
|
+
if (isInitialLoad) {
|
|
21202
|
+
debugLogger.log(logMessage);
|
|
20551
21203
|
} else {
|
|
20552
|
-
|
|
21204
|
+
debugLogger.debug(logMessage);
|
|
20553
21205
|
}
|
|
21206
|
+
return commands;
|
|
20554
21207
|
}
|
|
20555
|
-
const args = parts.slice(pathIndex).join(" ");
|
|
20556
|
-
return { commandToExecute, args, canonicalPath };
|
|
20557
21208
|
};
|
|
20558
21209
|
|
|
20559
21210
|
// src/services/dsh-command-loader.ts
|
|
@@ -20589,25 +21240,27 @@ var DshCommandLoader = class {
|
|
|
20589
21240
|
};
|
|
20590
21241
|
|
|
20591
21242
|
// src/ui/hooks/commands/use-slash-command-processor.ts
|
|
20592
|
-
var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic, toggleVimEnabled, setIsProcessing, actions, setCustomDialog, modelSelection, permissionSelection, sessionManagement, toolCatalog, dshCommands, enableProfiler = false, providerSetup) => {
|
|
21243
|
+
var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic, toggleVimEnabled, setIsProcessing, actions, setCustomDialog, modelSelection, permissionSelection, sessionManagement, toolCatalog, dshCommands, enableProfiler = false, providerSetup, sideConversation, subagentCatalog) => {
|
|
20593
21244
|
const session = useSessionStats();
|
|
20594
|
-
const [commands, setCommands] =
|
|
21245
|
+
const [commands, setCommands] = useState42(
|
|
20595
21246
|
void 0
|
|
20596
21247
|
);
|
|
20597
|
-
const [reloadTrigger, setReloadTrigger] =
|
|
20598
|
-
const commandAbortRef =
|
|
20599
|
-
const reloadCommands =
|
|
21248
|
+
const [reloadTrigger, setReloadTrigger] = useState42(0);
|
|
21249
|
+
const commandAbortRef = useRef22(void 0);
|
|
21250
|
+
const reloadCommands = useCallback36(() => {
|
|
20600
21251
|
setReloadTrigger((v) => v + 1);
|
|
20601
21252
|
}, []);
|
|
20602
|
-
const [confirmationRequest, setConfirmationRequest] =
|
|
20603
|
-
const commandContext =
|
|
21253
|
+
const [confirmationRequest, setConfirmationRequest] = useState42(null);
|
|
21254
|
+
const commandContext = useMemo34(
|
|
20604
21255
|
() => ({
|
|
20605
21256
|
services: {
|
|
20606
21257
|
modelSelection,
|
|
20607
21258
|
providerSetup,
|
|
20608
21259
|
permissionSelection,
|
|
20609
21260
|
sessionManagement,
|
|
20610
|
-
toolCatalog
|
|
21261
|
+
toolCatalog,
|
|
21262
|
+
sideConversation,
|
|
21263
|
+
subagentCatalog
|
|
20611
21264
|
},
|
|
20612
21265
|
ui: {
|
|
20613
21266
|
addItem,
|
|
@@ -20636,6 +21289,8 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
|
|
|
20636
21289
|
permissionSelection,
|
|
20637
21290
|
sessionManagement,
|
|
20638
21291
|
toolCatalog,
|
|
21292
|
+
sideConversation,
|
|
21293
|
+
subagentCatalog,
|
|
20639
21294
|
loadHistory,
|
|
20640
21295
|
addItem,
|
|
20641
21296
|
clearItems,
|
|
@@ -20646,7 +21301,7 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
|
|
|
20646
21301
|
setCustomDialog
|
|
20647
21302
|
]
|
|
20648
21303
|
);
|
|
20649
|
-
|
|
21304
|
+
useEffect44(() => {
|
|
20650
21305
|
const controller = new AbortController();
|
|
20651
21306
|
(async () => {
|
|
20652
21307
|
const loaders = [
|
|
@@ -20660,15 +21315,15 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
|
|
|
20660
21315
|
controller.abort();
|
|
20661
21316
|
};
|
|
20662
21317
|
}, [dshCommands, enableProfiler, reloadTrigger]);
|
|
20663
|
-
|
|
21318
|
+
useEffect44(
|
|
20664
21319
|
() => dshCommands?.subscribe(reloadCommands),
|
|
20665
21320
|
[dshCommands, reloadCommands]
|
|
20666
21321
|
);
|
|
20667
|
-
|
|
21322
|
+
useEffect44(
|
|
20668
21323
|
() => () => commandAbortRef.current?.abort(),
|
|
20669
21324
|
[]
|
|
20670
21325
|
);
|
|
20671
|
-
const handleSlashCommand =
|
|
21326
|
+
const handleSlashCommand = useCallback36(
|
|
20672
21327
|
async (rawQuery, overwriteConfirmed, addToHistory = true) => {
|
|
20673
21328
|
if (!commands) {
|
|
20674
21329
|
return false;
|
|
@@ -20681,14 +21336,14 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
|
|
|
20681
21336
|
const commandController = new AbortController();
|
|
20682
21337
|
commandAbortRef.current?.abort();
|
|
20683
21338
|
commandAbortRef.current = commandController;
|
|
20684
|
-
|
|
21339
|
+
const { commandToExecute, args } = parseSlashCommand(trimmed, commands);
|
|
21340
|
+
if (addToHistory && commandToExecute?.recordInvocation !== false) {
|
|
20685
21341
|
const userMessageTimestamp = Date.now();
|
|
20686
21342
|
addItem(
|
|
20687
21343
|
{ type: "user" /* USER */, text: trimmed },
|
|
20688
21344
|
userMessageTimestamp
|
|
20689
21345
|
);
|
|
20690
21346
|
}
|
|
20691
|
-
const { commandToExecute, args } = parseSlashCommand(trimmed, commands);
|
|
20692
21347
|
try {
|
|
20693
21348
|
if (commandToExecute) {
|
|
20694
21349
|
if (commandToExecute.action) {
|
|
@@ -20830,16 +21485,16 @@ ${commandToExecute.subCommands.map((sc) => ` - ${sc.name}: ${sc.description ||
|
|
|
20830
21485
|
import { useStdout as useStdout4, useStdin as useStdin4 } from "ink";
|
|
20831
21486
|
import ansiEscapes from "ansi-escapes";
|
|
20832
21487
|
import * as fs12 from "node:fs";
|
|
20833
|
-
import { basename as
|
|
21488
|
+
import { basename as basename3, join as join5 } from "node:path";
|
|
20834
21489
|
|
|
20835
21490
|
// src/ui/hooks/commands/use-settings-command.ts
|
|
20836
|
-
import { useState as
|
|
21491
|
+
import { useState as useState43, useCallback as useCallback37 } from "react";
|
|
20837
21492
|
function useSettingsCommand() {
|
|
20838
|
-
const [isSettingsDialogOpen, setIsSettingsDialogOpen] =
|
|
20839
|
-
const openSettingsDialog =
|
|
21493
|
+
const [isSettingsDialogOpen, setIsSettingsDialogOpen] = useState43(false);
|
|
21494
|
+
const openSettingsDialog = useCallback37(() => {
|
|
20840
21495
|
setIsSettingsDialogOpen(true);
|
|
20841
21496
|
}, []);
|
|
20842
|
-
const closeSettingsDialog =
|
|
21497
|
+
const closeSettingsDialog = useCallback37(() => {
|
|
20843
21498
|
setIsSettingsDialogOpen(false);
|
|
20844
21499
|
}, []);
|
|
20845
21500
|
return {
|
|
@@ -20850,11 +21505,11 @@ function useSettingsCommand() {
|
|
|
20850
21505
|
}
|
|
20851
21506
|
|
|
20852
21507
|
// src/ui/hooks/commands/use-theme-command.ts
|
|
20853
|
-
import { useState as
|
|
21508
|
+
import { useState as useState44, useCallback as useCallback38 } from "react";
|
|
20854
21509
|
import process6 from "node:process";
|
|
20855
21510
|
var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError) => {
|
|
20856
|
-
const [isThemeDialogOpen, setIsThemeDialogOpen] =
|
|
20857
|
-
const openThemeDialog =
|
|
21511
|
+
const [isThemeDialogOpen, setIsThemeDialogOpen] = useState44(!!initialThemeError);
|
|
21512
|
+
const openThemeDialog = useCallback38(() => {
|
|
20858
21513
|
if (process6.env["NO_COLOR"]) {
|
|
20859
21514
|
addItem(
|
|
20860
21515
|
{
|
|
@@ -20867,7 +21522,7 @@ var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError
|
|
|
20867
21522
|
}
|
|
20868
21523
|
setIsThemeDialogOpen(true);
|
|
20869
21524
|
}, [addItem]);
|
|
20870
|
-
const applyTheme =
|
|
21525
|
+
const applyTheme = useCallback38(
|
|
20871
21526
|
(themeName) => {
|
|
20872
21527
|
if (!themeManager.setActiveTheme(themeName)) {
|
|
20873
21528
|
setIsThemeDialogOpen(true);
|
|
@@ -20878,17 +21533,17 @@ var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError
|
|
|
20878
21533
|
},
|
|
20879
21534
|
[setThemeError]
|
|
20880
21535
|
);
|
|
20881
|
-
const handleThemeHighlight =
|
|
21536
|
+
const handleThemeHighlight = useCallback38(
|
|
20882
21537
|
(themeName) => {
|
|
20883
21538
|
applyTheme(themeName);
|
|
20884
21539
|
},
|
|
20885
21540
|
[applyTheme]
|
|
20886
21541
|
);
|
|
20887
|
-
const closeThemeDialog =
|
|
21542
|
+
const closeThemeDialog = useCallback38(() => {
|
|
20888
21543
|
applyTheme(loadedSettings.merged.ui.theme);
|
|
20889
21544
|
setIsThemeDialogOpen(false);
|
|
20890
21545
|
}, [applyTheme, loadedSettings]);
|
|
20891
|
-
const handleThemeSelect =
|
|
21546
|
+
const handleThemeSelect = useCallback38(
|
|
20892
21547
|
(themeName, scope) => {
|
|
20893
21548
|
try {
|
|
20894
21549
|
const mergedCustomThemes = {
|
|
@@ -20924,7 +21579,7 @@ var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError
|
|
|
20924
21579
|
};
|
|
20925
21580
|
|
|
20926
21581
|
// src/ui/hooks/input/use-vim.ts
|
|
20927
|
-
import { useCallback as
|
|
21582
|
+
import { useCallback as useCallback39, useReducer as useReducer5, useEffect as useEffect45, useRef as useRef23 } from "react";
|
|
20928
21583
|
var DIGIT_MULTIPLIER = 10;
|
|
20929
21584
|
var DEFAULT_COUNT = 1;
|
|
20930
21585
|
var DIGIT_1_TO_9 = /^[1-9]$/;
|
|
@@ -20989,22 +21644,22 @@ var vimReducer = (state, action) => {
|
|
|
20989
21644
|
function useVim(buffer, onSubmit) {
|
|
20990
21645
|
const { vimEnabled, vimMode, setVimMode } = useVimMode();
|
|
20991
21646
|
const [state, dispatch] = useReducer5(vimReducer, initialVimState);
|
|
20992
|
-
const lastEscapeTimestampRef =
|
|
20993
|
-
|
|
21647
|
+
const lastEscapeTimestampRef = useRef23(0);
|
|
21648
|
+
useEffect45(() => {
|
|
20994
21649
|
dispatch({ type: "SET_MODE", mode: vimMode });
|
|
20995
21650
|
}, [vimMode]);
|
|
20996
|
-
const updateMode =
|
|
21651
|
+
const updateMode = useCallback39(
|
|
20997
21652
|
(mode) => {
|
|
20998
21653
|
setVimMode(mode);
|
|
20999
21654
|
dispatch({ type: "SET_MODE", mode });
|
|
21000
21655
|
},
|
|
21001
21656
|
[setVimMode]
|
|
21002
21657
|
);
|
|
21003
|
-
const getCurrentCount =
|
|
21658
|
+
const getCurrentCount = useCallback39(
|
|
21004
21659
|
() => state.count || DEFAULT_COUNT,
|
|
21005
21660
|
[state.count]
|
|
21006
21661
|
);
|
|
21007
|
-
const checkDoubleEscape =
|
|
21662
|
+
const checkDoubleEscape = useCallback39(() => {
|
|
21008
21663
|
const now = Date.now();
|
|
21009
21664
|
const lastEscape = lastEscapeTimestampRef.current;
|
|
21010
21665
|
lastEscapeTimestampRef.current = now;
|
|
@@ -21014,7 +21669,7 @@ function useVim(buffer, onSubmit) {
|
|
|
21014
21669
|
}
|
|
21015
21670
|
return false;
|
|
21016
21671
|
}, []);
|
|
21017
|
-
const executeCommand =
|
|
21672
|
+
const executeCommand = useCallback39(
|
|
21018
21673
|
(cmdType, count) => {
|
|
21019
21674
|
switch (cmdType) {
|
|
21020
21675
|
case CMD_TYPES.DELETE_WORD_FORWARD: {
|
|
@@ -21090,7 +21745,7 @@ function useVim(buffer, onSubmit) {
|
|
|
21090
21745
|
},
|
|
21091
21746
|
[buffer, updateMode]
|
|
21092
21747
|
);
|
|
21093
|
-
const handleInsertModeInput =
|
|
21748
|
+
const handleInsertModeInput = useCallback39(
|
|
21094
21749
|
(normalizedKey) => {
|
|
21095
21750
|
if (keyMatchers["basic.cancel" /* ESCAPE */](normalizedKey)) {
|
|
21096
21751
|
checkDoubleEscape();
|
|
@@ -21122,7 +21777,7 @@ function useVim(buffer, onSubmit) {
|
|
|
21122
21777
|
},
|
|
21123
21778
|
[buffer, dispatch, updateMode, onSubmit, checkDoubleEscape]
|
|
21124
21779
|
);
|
|
21125
|
-
const normalizeKey =
|
|
21780
|
+
const normalizeKey = useCallback39(
|
|
21126
21781
|
(key) => ({
|
|
21127
21782
|
name: key.name || "",
|
|
21128
21783
|
sequence: key.sequence || "",
|
|
@@ -21134,7 +21789,7 @@ function useVim(buffer, onSubmit) {
|
|
|
21134
21789
|
}),
|
|
21135
21790
|
[]
|
|
21136
21791
|
);
|
|
21137
|
-
const handleChangeMovement =
|
|
21792
|
+
const handleChangeMovement = useCallback39(
|
|
21138
21793
|
(movement) => {
|
|
21139
21794
|
const count = getCurrentCount();
|
|
21140
21795
|
dispatch({ type: "CLEAR_COUNT" });
|
|
@@ -21155,7 +21810,7 @@ function useVim(buffer, onSubmit) {
|
|
|
21155
21810
|
},
|
|
21156
21811
|
[getCurrentCount, dispatch, buffer, updateMode]
|
|
21157
21812
|
);
|
|
21158
|
-
const handleOperatorMotion =
|
|
21813
|
+
const handleOperatorMotion = useCallback39(
|
|
21159
21814
|
(operator, motion) => {
|
|
21160
21815
|
const count = getCurrentCount();
|
|
21161
21816
|
const commandMap = {
|
|
@@ -21182,7 +21837,7 @@ function useVim(buffer, onSubmit) {
|
|
|
21182
21837
|
},
|
|
21183
21838
|
[getCurrentCount, executeCommand, dispatch]
|
|
21184
21839
|
);
|
|
21185
|
-
const handleInput =
|
|
21840
|
+
const handleInput = useCallback39(
|
|
21186
21841
|
(key) => {
|
|
21187
21842
|
if (!vimEnabled) {
|
|
21188
21843
|
return false;
|
|
@@ -21489,13 +22144,13 @@ function useVim(buffer, onSubmit) {
|
|
|
21489
22144
|
}
|
|
21490
22145
|
|
|
21491
22146
|
// src/ui/hooks/session/use-git-branch-name.ts
|
|
21492
|
-
import { useState as
|
|
22147
|
+
import { useState as useState45, useEffect as useEffect46, useCallback as useCallback40 } from "react";
|
|
21493
22148
|
import fs9 from "node:fs";
|
|
21494
22149
|
import fsPromises2 from "node:fs/promises";
|
|
21495
22150
|
import path11 from "node:path";
|
|
21496
22151
|
function useGitBranchName(cwd) {
|
|
21497
|
-
const [branchName, setBranchName] =
|
|
21498
|
-
const fetchBranchName =
|
|
22152
|
+
const [branchName, setBranchName] = useState45(void 0);
|
|
22153
|
+
const fetchBranchName = useCallback40(async () => {
|
|
21499
22154
|
try {
|
|
21500
22155
|
const { stdout } = await spawnAsync(
|
|
21501
22156
|
"git",
|
|
@@ -21517,15 +22172,15 @@ function useGitBranchName(cwd) {
|
|
|
21517
22172
|
setBranchName(void 0);
|
|
21518
22173
|
}
|
|
21519
22174
|
}, [cwd, setBranchName]);
|
|
21520
|
-
|
|
22175
|
+
useEffect46(() => {
|
|
21521
22176
|
fetchBranchName();
|
|
21522
22177
|
const gitLogsHeadPath = path11.join(cwd, ".git", "logs", "HEAD");
|
|
21523
22178
|
let watcher;
|
|
21524
|
-
let
|
|
22179
|
+
let cancelled2 = false;
|
|
21525
22180
|
const setupWatcher = async () => {
|
|
21526
22181
|
try {
|
|
21527
22182
|
await fsPromises2.access(gitLogsHeadPath, fs9.constants.F_OK);
|
|
21528
|
-
if (
|
|
22183
|
+
if (cancelled2) return;
|
|
21529
22184
|
watcher = fs9.watch(gitLogsHeadPath, (eventType) => {
|
|
21530
22185
|
if (eventType === "change" || eventType === "rename") {
|
|
21531
22186
|
fetchBranchName();
|
|
@@ -21536,7 +22191,7 @@ function useGitBranchName(cwd) {
|
|
|
21536
22191
|
};
|
|
21537
22192
|
setupWatcher();
|
|
21538
22193
|
return () => {
|
|
21539
|
-
|
|
22194
|
+
cancelled2 = true;
|
|
21540
22195
|
watcher?.close();
|
|
21541
22196
|
};
|
|
21542
22197
|
}, [cwd, fetchBranchName]);
|
|
@@ -21544,7 +22199,7 @@ function useGitBranchName(cwd) {
|
|
|
21544
22199
|
}
|
|
21545
22200
|
|
|
21546
22201
|
// src/ui/hooks/settings/use-editor-settings.ts
|
|
21547
|
-
import { useState as
|
|
22202
|
+
import { useState as useState46, useCallback as useCallback41 } from "react";
|
|
21548
22203
|
|
|
21549
22204
|
// src/config/setting-paths.ts
|
|
21550
22205
|
var SettingPaths = {
|
|
@@ -21555,11 +22210,11 @@ var SettingPaths = {
|
|
|
21555
22210
|
|
|
21556
22211
|
// src/ui/hooks/settings/use-editor-settings.ts
|
|
21557
22212
|
var useEditorSettings = (loadedSettings, setEditorError, addItem) => {
|
|
21558
|
-
const [isEditorDialogOpen, setIsEditorDialogOpen] =
|
|
21559
|
-
const openEditorDialog =
|
|
22213
|
+
const [isEditorDialogOpen, setIsEditorDialogOpen] = useState46(false);
|
|
22214
|
+
const openEditorDialog = useCallback41(() => {
|
|
21560
22215
|
setIsEditorDialogOpen(true);
|
|
21561
22216
|
}, []);
|
|
21562
|
-
const handleEditorSelect =
|
|
22217
|
+
const handleEditorSelect = useCallback41(
|
|
21563
22218
|
(editorType, scope) => {
|
|
21564
22219
|
if (editorType && !checkHasEditorType(editorType)) {
|
|
21565
22220
|
return;
|
|
@@ -21585,7 +22240,7 @@ var useEditorSettings = (loadedSettings, setEditorError, addItem) => {
|
|
|
21585
22240
|
},
|
|
21586
22241
|
[loadedSettings, setEditorError, addItem]
|
|
21587
22242
|
);
|
|
21588
|
-
const exitEditorDialog =
|
|
22243
|
+
const exitEditorDialog = useCallback41(() => {
|
|
21589
22244
|
setIsEditorDialogOpen(false);
|
|
21590
22245
|
}, []);
|
|
21591
22246
|
return {
|
|
@@ -21597,12 +22252,12 @@ var useEditorSettings = (loadedSettings, setEditorError, addItem) => {
|
|
|
21597
22252
|
};
|
|
21598
22253
|
|
|
21599
22254
|
// src/ui/hooks/terminal/use-memory-monitor.ts
|
|
21600
|
-
import { useEffect as
|
|
22255
|
+
import { useEffect as useEffect47 } from "react";
|
|
21601
22256
|
import process7 from "node:process";
|
|
21602
22257
|
var MEMORY_WARNING_THRESHOLD = 7 * 1024 * 1024 * 1024;
|
|
21603
22258
|
var MEMORY_CHECK_INTERVAL = 60 * 1e3;
|
|
21604
22259
|
var useMemoryMonitor = ({ addItem }) => {
|
|
21605
|
-
|
|
22260
|
+
useEffect47(() => {
|
|
21606
22261
|
const intervalId = setInterval(() => {
|
|
21607
22262
|
const usage = process7.memoryUsage().rss;
|
|
21608
22263
|
if (usage > MEMORY_WARNING_THRESHOLD) {
|
|
@@ -21622,10 +22277,10 @@ var useMemoryMonitor = ({ addItem }) => {
|
|
|
21622
22277
|
|
|
21623
22278
|
// src/ui/hooks/visual/use-console-messages.ts
|
|
21624
22279
|
import {
|
|
21625
|
-
useCallback as
|
|
21626
|
-
useEffect as
|
|
22280
|
+
useCallback as useCallback42,
|
|
22281
|
+
useEffect as useEffect48,
|
|
21627
22282
|
useReducer as useReducer6,
|
|
21628
|
-
useRef as
|
|
22283
|
+
useRef as useRef24,
|
|
21629
22284
|
useTransition
|
|
21630
22285
|
} from "react";
|
|
21631
22286
|
function consoleMessagesReducer(state, action) {
|
|
@@ -21653,10 +22308,10 @@ function consoleMessagesReducer(state, action) {
|
|
|
21653
22308
|
}
|
|
21654
22309
|
function useConsoleMessages() {
|
|
21655
22310
|
const [consoleMessages, dispatch] = useReducer6(consoleMessagesReducer, []);
|
|
21656
|
-
const messageQueueRef =
|
|
21657
|
-
const timeoutRef =
|
|
22311
|
+
const messageQueueRef = useRef24([]);
|
|
22312
|
+
const timeoutRef = useRef24(null);
|
|
21658
22313
|
const [, startTransition] = useTransition();
|
|
21659
|
-
const processQueue =
|
|
22314
|
+
const processQueue = useCallback42(() => {
|
|
21660
22315
|
if (messageQueueRef.current.length > 0) {
|
|
21661
22316
|
const messagesToProcess = messageQueueRef.current;
|
|
21662
22317
|
messageQueueRef.current = [];
|
|
@@ -21666,7 +22321,7 @@ function useConsoleMessages() {
|
|
|
21666
22321
|
}
|
|
21667
22322
|
timeoutRef.current = null;
|
|
21668
22323
|
}, []);
|
|
21669
|
-
const handleNewMessage =
|
|
22324
|
+
const handleNewMessage = useCallback42(
|
|
21670
22325
|
(message) => {
|
|
21671
22326
|
messageQueueRef.current.push(message);
|
|
21672
22327
|
if (!timeoutRef.current) {
|
|
@@ -21675,7 +22330,7 @@ function useConsoleMessages() {
|
|
|
21675
22330
|
},
|
|
21676
22331
|
[processQueue]
|
|
21677
22332
|
);
|
|
21678
|
-
|
|
22333
|
+
useEffect48(() => {
|
|
21679
22334
|
const handleConsoleLog = (payload) => {
|
|
21680
22335
|
handleNewMessage({
|
|
21681
22336
|
type: payload.type,
|
|
@@ -21694,7 +22349,7 @@ function useConsoleMessages() {
|
|
|
21694
22349
|
coreEvents.off(CoreEvent.Output, handleOutput);
|
|
21695
22350
|
};
|
|
21696
22351
|
}, [handleNewMessage]);
|
|
21697
|
-
const clearConsoleMessages =
|
|
22352
|
+
const clearConsoleMessages = useCallback42(() => {
|
|
21698
22353
|
if (timeoutRef.current) {
|
|
21699
22354
|
clearTimeout(timeoutRef.current);
|
|
21700
22355
|
timeoutRef.current = null;
|
|
@@ -21704,7 +22359,7 @@ function useConsoleMessages() {
|
|
|
21704
22359
|
dispatch({ type: "CLEAR" });
|
|
21705
22360
|
});
|
|
21706
22361
|
}, []);
|
|
21707
|
-
|
|
22362
|
+
useEffect48(
|
|
21708
22363
|
() => () => {
|
|
21709
22364
|
if (timeoutRef.current) {
|
|
21710
22365
|
clearTimeout(timeoutRef.current);
|
|
@@ -21716,13 +22371,13 @@ function useConsoleMessages() {
|
|
|
21716
22371
|
}
|
|
21717
22372
|
|
|
21718
22373
|
// src/ui/hooks/visual/use-timer.ts
|
|
21719
|
-
import { useState as
|
|
22374
|
+
import { useState as useState47, useEffect as useEffect49, useRef as useRef25 } from "react";
|
|
21720
22375
|
var useTimer = (isActive, resetKey) => {
|
|
21721
|
-
const [elapsedTime, setElapsedTime] =
|
|
21722
|
-
const timerRef =
|
|
21723
|
-
const prevResetKeyRef =
|
|
21724
|
-
const prevIsActiveRef =
|
|
21725
|
-
|
|
22376
|
+
const [elapsedTime, setElapsedTime] = useState47(0);
|
|
22377
|
+
const timerRef = useRef25(null);
|
|
22378
|
+
const prevResetKeyRef = useRef25(resetKey);
|
|
22379
|
+
const prevIsActiveRef = useRef25(isActive);
|
|
22380
|
+
useEffect49(() => {
|
|
21726
22381
|
let shouldResetTime = false;
|
|
21727
22382
|
if (prevResetKeyRef.current !== resetKey) {
|
|
21728
22383
|
shouldResetTime = true;
|
|
@@ -21759,7 +22414,7 @@ var useTimer = (isActive, resetKey) => {
|
|
|
21759
22414
|
};
|
|
21760
22415
|
|
|
21761
22416
|
// src/ui/hooks/visual/use-phrase-cycler.ts
|
|
21762
|
-
import { useState as
|
|
22417
|
+
import { useState as useState48, useEffect as useEffect50, useRef as useRef26 } from "react";
|
|
21763
22418
|
|
|
21764
22419
|
// src/ui/components/indicators/loading-phrases.ts
|
|
21765
22420
|
var WITTY_LOADING_PHRASES = [
|
|
@@ -21902,12 +22557,12 @@ var PHRASE_CHANGE_INTERVAL_MS = 15e3;
|
|
|
21902
22557
|
var INTERACTIVE_SHELL_WAITING_PHRASE = "Interactive shell awaiting input... press tab to focus shell";
|
|
21903
22558
|
var usePhraseCycler = (isActive, shouldShowFocusHint, customPhrases) => {
|
|
21904
22559
|
const loadingPhrases = customPhrases && customPhrases.length > 0 ? customPhrases : WITTY_LOADING_PHRASES;
|
|
21905
|
-
const [currentLoadingPhrase, setCurrentLoadingPhrase] =
|
|
22560
|
+
const [currentLoadingPhrase, setCurrentLoadingPhrase] = useState48(
|
|
21906
22561
|
loadingPhrases[0]
|
|
21907
22562
|
);
|
|
21908
|
-
const phraseIntervalRef =
|
|
21909
|
-
const hasShownFirstRequestTipRef =
|
|
21910
|
-
|
|
22563
|
+
const phraseIntervalRef = useRef26(null);
|
|
22564
|
+
const hasShownFirstRequestTipRef = useRef26(false);
|
|
22565
|
+
useEffect50(() => {
|
|
21911
22566
|
if (phraseIntervalRef.current) {
|
|
21912
22567
|
clearInterval(phraseIntervalRef.current);
|
|
21913
22568
|
phraseIntervalRef.current = null;
|
|
@@ -21952,13 +22607,13 @@ var usePhraseCycler = (isActive, shouldShowFocusHint, customPhrases) => {
|
|
|
21952
22607
|
};
|
|
21953
22608
|
|
|
21954
22609
|
// src/ui/hooks/visual/use-loading-indicator.ts
|
|
21955
|
-
import { useState as
|
|
22610
|
+
import { useState as useState49, useEffect as useEffect51, useRef as useRef27 } from "react";
|
|
21956
22611
|
var useLoadingIndicator = ({
|
|
21957
22612
|
streamingState,
|
|
21958
22613
|
shouldShowFocusHint,
|
|
21959
22614
|
customWittyPhrases
|
|
21960
22615
|
}) => {
|
|
21961
|
-
const [timerResetKey, setTimerResetKey] =
|
|
22616
|
+
const [timerResetKey, setTimerResetKey] = useState49(0);
|
|
21962
22617
|
const isTimerActive = streamingState === "responding" /* Responding */;
|
|
21963
22618
|
const elapsedTimeFromTimer = useTimer(isTimerActive, timerResetKey);
|
|
21964
22619
|
const isPhraseCyclingActive = streamingState === "responding" /* Responding */;
|
|
@@ -21967,8 +22622,8 @@ var useLoadingIndicator = ({
|
|
|
21967
22622
|
shouldShowFocusHint,
|
|
21968
22623
|
customWittyPhrases
|
|
21969
22624
|
);
|
|
21970
|
-
const prevStreamingStateRef =
|
|
21971
|
-
|
|
22625
|
+
const prevStreamingStateRef = useRef27(null);
|
|
22626
|
+
useEffect51(() => {
|
|
21972
22627
|
if (streamingState === "idle" /* Idle */ && prevStreamingStateRef.current === "responding" /* Responding */) {
|
|
21973
22628
|
setTimerResetKey((prevKey) => prevKey + 1);
|
|
21974
22629
|
}
|
|
@@ -21981,40 +22636,54 @@ var useLoadingIndicator = ({
|
|
|
21981
22636
|
};
|
|
21982
22637
|
|
|
21983
22638
|
// src/ui/hooks/session/use-message-queue.ts
|
|
21984
|
-
import { useCallback as
|
|
22639
|
+
import { useCallback as useCallback43, useEffect as useEffect52, useMemo as useMemo35, useState as useState50 } from "react";
|
|
21985
22640
|
function useMessageQueue({
|
|
22641
|
+
queueKey,
|
|
21986
22642
|
streamingState,
|
|
21987
22643
|
submitQuery
|
|
21988
22644
|
}) {
|
|
21989
|
-
const [
|
|
21990
|
-
const
|
|
22645
|
+
const [queuedMessages, setQueuedMessages] = useState50([]);
|
|
22646
|
+
const messageQueue = useMemo35(
|
|
22647
|
+
() => queuedMessages.filter((entry) => entry.key === queueKey).map((entry) => entry.message),
|
|
22648
|
+
[queueKey, queuedMessages]
|
|
22649
|
+
);
|
|
22650
|
+
const addMessage = useCallback43((message) => {
|
|
21991
22651
|
const trimmedMessage = message.trim();
|
|
21992
22652
|
if (trimmedMessage.length > 0) {
|
|
21993
|
-
|
|
22653
|
+
setQueuedMessages((previous) => [
|
|
22654
|
+
...previous,
|
|
22655
|
+
{ key: queueKey, message: trimmedMessage }
|
|
22656
|
+
]);
|
|
21994
22657
|
}
|
|
21995
|
-
}, []);
|
|
21996
|
-
const clearQueue =
|
|
21997
|
-
|
|
21998
|
-
|
|
21999
|
-
|
|
22658
|
+
}, [queueKey]);
|
|
22659
|
+
const clearQueue = useCallback43(() => {
|
|
22660
|
+
setQueuedMessages(
|
|
22661
|
+
(previous) => previous.filter((entry) => entry.key !== queueKey)
|
|
22662
|
+
);
|
|
22663
|
+
}, [queueKey]);
|
|
22664
|
+
const getQueuedMessagesText = useCallback43(() => {
|
|
22000
22665
|
if (messageQueue.length === 0) return "";
|
|
22001
22666
|
return messageQueue.join("\n\n");
|
|
22002
22667
|
}, [messageQueue]);
|
|
22003
|
-
const popAllMessages =
|
|
22668
|
+
const popAllMessages = useCallback43(() => {
|
|
22004
22669
|
if (messageQueue.length === 0) {
|
|
22005
22670
|
return void 0;
|
|
22006
22671
|
}
|
|
22007
22672
|
const allMessages = messageQueue.join("\n\n");
|
|
22008
|
-
|
|
22673
|
+
setQueuedMessages(
|
|
22674
|
+
(previous) => previous.filter((entry) => entry.key !== queueKey)
|
|
22675
|
+
);
|
|
22009
22676
|
return allMessages;
|
|
22010
|
-
}, [messageQueue]);
|
|
22011
|
-
|
|
22677
|
+
}, [messageQueue, queueKey]);
|
|
22678
|
+
useEffect52(() => {
|
|
22012
22679
|
if (streamingState === "idle" /* Idle */ && messageQueue.length > 0) {
|
|
22013
22680
|
const combinedMessage = messageQueue.join("\n\n");
|
|
22014
|
-
|
|
22681
|
+
setQueuedMessages(
|
|
22682
|
+
(previous) => previous.filter((entry) => entry.key !== queueKey)
|
|
22683
|
+
);
|
|
22015
22684
|
submitQuery(combinedMessage);
|
|
22016
22685
|
}
|
|
22017
|
-
}, [streamingState, messageQueue, submitQuery]);
|
|
22686
|
+
}, [streamingState, messageQueue, queueKey, submitQuery]);
|
|
22018
22687
|
return {
|
|
22019
22688
|
messageQueue,
|
|
22020
22689
|
addMessage,
|
|
@@ -22025,16 +22694,16 @@ function useMessageQueue({
|
|
|
22025
22694
|
}
|
|
22026
22695
|
|
|
22027
22696
|
// src/ui/hooks/input/use-input-history-store.ts
|
|
22028
|
-
import { useCallback as
|
|
22697
|
+
import { useCallback as useCallback44, useRef as useRef28, useState as useState51 } from "react";
|
|
22029
22698
|
function deduplicateConsecutive(messages) {
|
|
22030
22699
|
return messages.filter(
|
|
22031
22700
|
(message, index) => index === 0 || message !== messages[index - 1]
|
|
22032
22701
|
);
|
|
22033
22702
|
}
|
|
22034
22703
|
function useInputHistoryStore() {
|
|
22035
|
-
const [inputHistory, setInputHistory] =
|
|
22036
|
-
const initializationStarted =
|
|
22037
|
-
const initializeFromHistory =
|
|
22704
|
+
const [inputHistory, setInputHistory] = useState51([]);
|
|
22705
|
+
const initializationStarted = useRef28(false);
|
|
22706
|
+
const initializeFromHistory = useCallback44(
|
|
22038
22707
|
async (history) => {
|
|
22039
22708
|
if (initializationStarted.current) return;
|
|
22040
22709
|
initializationStarted.current = true;
|
|
@@ -22055,7 +22724,7 @@ function useInputHistoryStore() {
|
|
|
22055
22724
|
},
|
|
22056
22725
|
[]
|
|
22057
22726
|
);
|
|
22058
|
-
const addInput =
|
|
22727
|
+
const addInput = useCallback44(
|
|
22059
22728
|
(input) => {
|
|
22060
22729
|
const trimmedInput = input.trim();
|
|
22061
22730
|
if (!trimmedInput) return;
|
|
@@ -22155,12 +22824,12 @@ var PromptHistoryStore = class {
|
|
|
22155
22824
|
};
|
|
22156
22825
|
|
|
22157
22826
|
// src/ui/hooks/ai/use-turn-activity-monitor.ts
|
|
22158
|
-
import { useState as
|
|
22827
|
+
import { useState as useState52, useEffect as useEffect53, useRef as useRef29 } from "react";
|
|
22159
22828
|
var useTurnActivityMonitor = (streamingState, activePtyId) => {
|
|
22160
|
-
const [operationStartTime, setOperationStartTime] =
|
|
22161
|
-
const prevPtyIdRef =
|
|
22162
|
-
const prevStreamingStateRef =
|
|
22163
|
-
|
|
22829
|
+
const [operationStartTime, setOperationStartTime] = useState52(0);
|
|
22830
|
+
const prevPtyIdRef = useRef29(void 0);
|
|
22831
|
+
const prevStreamingStateRef = useRef29(void 0);
|
|
22832
|
+
useEffect53(() => {
|
|
22164
22833
|
const isNowResponding = streamingState === "responding" /* Responding */;
|
|
22165
22834
|
const wasResponding = prevStreamingStateRef.current === "responding" /* Responding */;
|
|
22166
22835
|
const ptyChanged = activePtyId !== prevPtyIdRef.current;
|
|
@@ -22219,7 +22888,7 @@ var useShellInactivityStatus = ({
|
|
|
22219
22888
|
};
|
|
22220
22889
|
|
|
22221
22890
|
// src/ui/hooks/input/use-local-shell-command.ts
|
|
22222
|
-
import { useCallback as
|
|
22891
|
+
import { useCallback as useCallback45, useEffect as useEffect54, useRef as useRef30, useState as useState53 } from "react";
|
|
22223
22892
|
import crypto2 from "node:crypto";
|
|
22224
22893
|
import fs11 from "node:fs";
|
|
22225
22894
|
import os3 from "node:os";
|
|
@@ -22236,20 +22905,20 @@ function useLocalShellCommand({
|
|
|
22236
22905
|
terminalWidth,
|
|
22237
22906
|
terminalHeight
|
|
22238
22907
|
}) {
|
|
22239
|
-
const controllerRef =
|
|
22240
|
-
const mountedRef =
|
|
22241
|
-
const [isExecuting, setIsExecuting] =
|
|
22242
|
-
const [activePtyId, setActivePtyId] =
|
|
22243
|
-
const [lastOutputTime, setLastOutputTime] =
|
|
22244
|
-
const cancel =
|
|
22245
|
-
|
|
22908
|
+
const controllerRef = useRef30(void 0);
|
|
22909
|
+
const mountedRef = useRef30(true);
|
|
22910
|
+
const [isExecuting, setIsExecuting] = useState53(false);
|
|
22911
|
+
const [activePtyId, setActivePtyId] = useState53(void 0);
|
|
22912
|
+
const [lastOutputTime, setLastOutputTime] = useState53(0);
|
|
22913
|
+
const cancel = useCallback45(() => controllerRef.current?.abort(), []);
|
|
22914
|
+
useEffect54(() => {
|
|
22246
22915
|
mountedRef.current = true;
|
|
22247
22916
|
return () => {
|
|
22248
22917
|
mountedRef.current = false;
|
|
22249
22918
|
controllerRef.current?.abort();
|
|
22250
22919
|
};
|
|
22251
22920
|
}, []);
|
|
22252
|
-
const execute =
|
|
22921
|
+
const execute = useCallback45(
|
|
22253
22922
|
(rawCommand) => {
|
|
22254
22923
|
const command = rawCommand.trim();
|
|
22255
22924
|
if (command.length === 0 || controllerRef.current !== void 0) {
|
|
@@ -22446,12 +23115,25 @@ ${output}`;
|
|
|
22446
23115
|
}
|
|
22447
23116
|
|
|
22448
23117
|
// src/ui/app-container.tsx
|
|
22449
|
-
import { jsx as
|
|
23118
|
+
import { jsx as jsx96 } from "react/jsx-runtime";
|
|
22450
23119
|
var SHELL_WIDTH_FRACTION = 0.89;
|
|
22451
23120
|
var SHELL_HEIGHT_PADDING = 10;
|
|
22452
23121
|
var noopExternalStoreSubscribe = () => () => {
|
|
22453
23122
|
};
|
|
22454
23123
|
var emptyProviderSetupSnapshot = () => void 0;
|
|
23124
|
+
var EMPTY_SIDE_CONVERSATION_SNAPSHOT = {
|
|
23125
|
+
activeSurface: "main",
|
|
23126
|
+
mainBusy: false,
|
|
23127
|
+
sideBusy: false
|
|
23128
|
+
};
|
|
23129
|
+
var emptySideConversationSnapshot = () => EMPTY_SIDE_CONVERSATION_SNAPSHOT;
|
|
23130
|
+
var EMPTY_SUBAGENT_CATALOG_SNAPSHOT = {
|
|
23131
|
+
rootSessionId: "",
|
|
23132
|
+
status: "idle",
|
|
23133
|
+
items: [],
|
|
23134
|
+
runningCount: 0
|
|
23135
|
+
};
|
|
23136
|
+
var emptySubagentCatalogSnapshot = () => EMPTY_SUBAGENT_CATALOG_SNAPSHOT;
|
|
22455
23137
|
var AppContainer = (props) => {
|
|
22456
23138
|
const {
|
|
22457
23139
|
config,
|
|
@@ -22466,38 +23148,50 @@ var AppContainer = (props) => {
|
|
|
22466
23148
|
userQuestionRuntime,
|
|
22467
23149
|
commandRuntime,
|
|
22468
23150
|
permissionSelectionRuntime,
|
|
22469
|
-
toolCatalogRuntime
|
|
23151
|
+
toolCatalogRuntime,
|
|
23152
|
+
sideConversationRuntime,
|
|
23153
|
+
subagentCatalogRuntime
|
|
22470
23154
|
} = props;
|
|
22471
23155
|
const historyManager = useHistory();
|
|
22472
|
-
const conversationSnapshot =
|
|
23156
|
+
const conversationSnapshot = useSyncExternalStore6(
|
|
22473
23157
|
conversationRuntime.subscribe,
|
|
22474
23158
|
conversationRuntime.getSnapshot,
|
|
22475
23159
|
conversationRuntime.getSnapshot
|
|
22476
23160
|
);
|
|
22477
|
-
const
|
|
23161
|
+
const sideConversationSnapshot = useSyncExternalStore6(
|
|
23162
|
+
sideConversationRuntime?.subscribeWorkspace ?? noopExternalStoreSubscribe,
|
|
23163
|
+
sideConversationRuntime?.getWorkspaceSnapshot ?? emptySideConversationSnapshot,
|
|
23164
|
+
sideConversationRuntime?.getWorkspaceSnapshot ?? emptySideConversationSnapshot
|
|
23165
|
+
);
|
|
23166
|
+
const subagentCatalogSnapshot = useSyncExternalStore6(
|
|
23167
|
+
subagentCatalogRuntime?.subscribe ?? noopExternalStoreSubscribe,
|
|
23168
|
+
subagentCatalogRuntime?.getSnapshot ?? emptySubagentCatalogSnapshot,
|
|
23169
|
+
subagentCatalogRuntime?.getSnapshot ?? emptySubagentCatalogSnapshot
|
|
23170
|
+
);
|
|
23171
|
+
const approvalSnapshot = useSyncExternalStore6(
|
|
22478
23172
|
approvalRuntime.subscribe,
|
|
22479
23173
|
approvalRuntime.getSnapshot,
|
|
22480
23174
|
approvalRuntime.getSnapshot
|
|
22481
23175
|
);
|
|
22482
23176
|
const pendingApproval = approvalSnapshot.pending[0];
|
|
22483
|
-
const userQuestionSnapshot =
|
|
23177
|
+
const userQuestionSnapshot = useSyncExternalStore6(
|
|
22484
23178
|
userQuestionRuntime.subscribe,
|
|
22485
23179
|
userQuestionRuntime.getSnapshot,
|
|
22486
23180
|
userQuestionRuntime.getSnapshot
|
|
22487
23181
|
);
|
|
22488
23182
|
const pendingUserQuestion = userQuestionSnapshot.pending[0];
|
|
22489
|
-
const conversationHistoryIds =
|
|
22490
|
-
const conversationHistoryTexts =
|
|
23183
|
+
const conversationHistoryIds = useRef31(/* @__PURE__ */ new Map());
|
|
23184
|
+
const conversationHistoryTexts = useRef31(/* @__PURE__ */ new Map());
|
|
22491
23185
|
const conversationSessionId = conversationRuntime.getSessionStats().sessionId;
|
|
22492
|
-
const [projectedSessionId, setProjectedSessionId] =
|
|
23186
|
+
const [projectedSessionId, setProjectedSessionId] = useState54(
|
|
22493
23187
|
conversationSessionId
|
|
22494
23188
|
);
|
|
22495
|
-
const promptInputAbortRef =
|
|
22496
|
-
const [promptInputPreparing, setPromptInputPreparing] =
|
|
23189
|
+
const promptInputAbortRef = useRef31(void 0);
|
|
23190
|
+
const [promptInputPreparing, setPromptInputPreparing] = useState54(false);
|
|
22497
23191
|
const addConversationHistoryItem = historyManager.addItem;
|
|
22498
23192
|
const updateConversationHistoryItem = historyManager.updateItem;
|
|
22499
23193
|
const clearConversationHistory = historyManager.clearItems;
|
|
22500
|
-
|
|
23194
|
+
useEffect55(() => {
|
|
22501
23195
|
if (projectedSessionId !== conversationSessionId) {
|
|
22502
23196
|
conversationHistoryIds.current.clear();
|
|
22503
23197
|
conversationHistoryTexts.current.clear();
|
|
@@ -22508,57 +23202,17 @@ var AppContainer = (props) => {
|
|
|
22508
23202
|
const visibleHistoryIds = new Set(
|
|
22509
23203
|
historyManager.history.map((item) => item.id)
|
|
22510
23204
|
);
|
|
22511
|
-
const
|
|
22512
|
-
conversationSnapshot.messages
|
|
22513
|
-
(message) => message.role === "tool" ? [message.callId] : []
|
|
22514
|
-
)
|
|
23205
|
+
const visibleToolCallIds = projectedToolCallIds(
|
|
23206
|
+
conversationSnapshot.messages
|
|
22515
23207
|
);
|
|
22516
23208
|
for (const message of conversationSnapshot.messages) {
|
|
22517
23209
|
const historyId = conversationHistoryIds.current.get(message.id);
|
|
22518
|
-
const
|
|
22519
|
-
|
|
22520
|
-
|
|
22521
|
-
|
|
22522
|
-
|
|
22523
|
-
|
|
22524
|
-
const messageText = message.role === "tool" ? void 0 : conversationMessageText(message);
|
|
22525
|
-
const item = message.role === "tool" ? {
|
|
22526
|
-
type: "tool_group",
|
|
22527
|
-
tools: [
|
|
22528
|
-
{
|
|
22529
|
-
callId: message.callId,
|
|
22530
|
-
name: message.presentation?.kind === "card" ? message.presentation.title ?? message.name : message.name,
|
|
22531
|
-
description: message.presentation?.kind === "compact" ? "" : message.presentation?.description ?? message.arguments,
|
|
22532
|
-
resultDisplay: message.presentation?.kind === "compact" ? void 0 : message.presentation?.resultDisplay ?? (message.result === void 0 ? void 0 : {
|
|
22533
|
-
type: "dsh-content",
|
|
22534
|
-
content: message.result.content,
|
|
22535
|
-
...message.result.error === void 0 ? {} : { error: message.result.error }
|
|
22536
|
-
}),
|
|
22537
|
-
...message.presentation?.kind === "compact" ? {
|
|
22538
|
-
presentation: {
|
|
22539
|
-
kind: "compact",
|
|
22540
|
-
label: message.presentation.label
|
|
22541
|
-
}
|
|
22542
|
-
} : {},
|
|
22543
|
-
status: message.status === "executing" ? "Executing" /* Executing */ : message.status === "success" ? "Success" /* Success */ : "Error" /* Error */
|
|
22544
|
-
}
|
|
22545
|
-
]
|
|
22546
|
-
} : message.role === "assistant" ? {
|
|
22547
|
-
type: "dsh_assistant",
|
|
22548
|
-
content: assistantContent ?? message.content,
|
|
22549
|
-
interrupted: message.interrupted === true
|
|
22550
|
-
} : message.role === "user" ? {
|
|
22551
|
-
type: "dsh_user",
|
|
22552
|
-
content: message.displayContent ?? message.content
|
|
22553
|
-
} : {
|
|
22554
|
-
type: message.status === "cancelled" ? "warning" /* WARNING */ : "error" /* ERROR */,
|
|
22555
|
-
text: messageText ?? ""
|
|
22556
|
-
};
|
|
22557
|
-
const fingerprint = message.role === "tool" ? JSON.stringify([
|
|
22558
|
-
message.status,
|
|
22559
|
-
message.result,
|
|
22560
|
-
message.presentation
|
|
22561
|
-
]) : message.role === "assistant" ? JSON.stringify([assistantContent, message.interrupted]) : message.role === "user" ? JSON.stringify(message.displayContent ?? message.content) : messageText ?? "";
|
|
23210
|
+
const item = conversationMessageToHistoryItem(
|
|
23211
|
+
message,
|
|
23212
|
+
visibleToolCallIds
|
|
23213
|
+
);
|
|
23214
|
+
if (item === void 0) continue;
|
|
23215
|
+
const fingerprint = conversationMessageFingerprint(message, item);
|
|
22562
23216
|
if (historyId === void 0 || !visibleHistoryIds.has(historyId)) {
|
|
22563
23217
|
const nextHistoryId = addConversationHistoryItem(item);
|
|
22564
23218
|
conversationHistoryIds.current.set(message.id, nextHistoryId);
|
|
@@ -22582,49 +23236,49 @@ var AppContainer = (props) => {
|
|
|
22582
23236
|
useMemoryMonitor(historyManager);
|
|
22583
23237
|
const settings = useSettings();
|
|
22584
23238
|
const isAlternateBuffer = useAlternateBuffer();
|
|
22585
|
-
const [debugMessage, setDebugMessage] =
|
|
22586
|
-
const [quittingMessages, setQuittingMessages] =
|
|
22587
|
-
const [themeError, setThemeError] =
|
|
23239
|
+
const [debugMessage, setDebugMessage] = useState54("");
|
|
23240
|
+
const [quittingMessages, setQuittingMessages] = useState54(null);
|
|
23241
|
+
const [themeError, setThemeError] = useState54(
|
|
22588
23242
|
initializationResult.themeError
|
|
22589
23243
|
);
|
|
22590
|
-
const [isProcessing, setIsProcessing] =
|
|
22591
|
-
const [embeddedShellFocused, setEmbeddedShellFocused] =
|
|
23244
|
+
const [isProcessing, setIsProcessing] = useState54(false);
|
|
23245
|
+
const [embeddedShellFocused, setEmbeddedShellFocused] = useState54(false);
|
|
22592
23246
|
const enableProfiler = config.getDebugMode() || process8.env["NODE_ENV"] === "development";
|
|
22593
|
-
const [showDebugProfiler, setShowDebugProfiler] =
|
|
22594
|
-
const [customDialog, setCustomDialog] =
|
|
23247
|
+
const [showDebugProfiler, setShowDebugProfiler] = useState54(enableProfiler);
|
|
23248
|
+
const [customDialog, setCustomDialog] = useState54(
|
|
22595
23249
|
null
|
|
22596
23250
|
);
|
|
22597
|
-
const [copyModeEnabled, setCopyModeEnabled] =
|
|
22598
|
-
const [pendingRestorePrompt, setPendingRestorePrompt] =
|
|
22599
|
-
const [shellModeActive, setShellModeActive] =
|
|
22600
|
-
const [pendingShellHistoryItem, setPendingShellHistoryItem] =
|
|
22601
|
-
const [historyRemountKey, setHistoryRemountKey] =
|
|
22602
|
-
const [settingsNonce, setSettingsNonce] =
|
|
22603
|
-
const [queueErrorMessage, setQueueErrorMessage] =
|
|
23251
|
+
const [copyModeEnabled, setCopyModeEnabled] = useState54(false);
|
|
23252
|
+
const [pendingRestorePrompt, setPendingRestorePrompt] = useState54(false);
|
|
23253
|
+
const [shellModeActive, setShellModeActive] = useState54(false);
|
|
23254
|
+
const [pendingShellHistoryItem, setPendingShellHistoryItem] = useState54(null);
|
|
23255
|
+
const [historyRemountKey, setHistoryRemountKey] = useState54(0);
|
|
23256
|
+
const [settingsNonce, setSettingsNonce] = useState54(0);
|
|
23257
|
+
const [queueErrorMessage, setQueueErrorMessage] = useState54(
|
|
22604
23258
|
null
|
|
22605
23259
|
);
|
|
22606
|
-
const toggleDebugProfiler =
|
|
23260
|
+
const toggleDebugProfiler = useCallback46(
|
|
22607
23261
|
() => setShowDebugProfiler((visible) => !visible),
|
|
22608
23262
|
[]
|
|
22609
23263
|
);
|
|
22610
|
-
const [modelSelectionSnapshot, setModelSelectionSnapshot] =
|
|
23264
|
+
const [modelSelectionSnapshot, setModelSelectionSnapshot] = useState54(
|
|
22611
23265
|
() => modelSelectionRuntime?.getSnapshot()
|
|
22612
23266
|
);
|
|
22613
|
-
|
|
23267
|
+
useEffect55(
|
|
22614
23268
|
() => modelSelectionRuntime?.subscribe(
|
|
22615
23269
|
() => setModelSelectionSnapshot(modelSelectionRuntime.getSnapshot())
|
|
22616
23270
|
),
|
|
22617
23271
|
[modelSelectionRuntime]
|
|
22618
23272
|
);
|
|
22619
|
-
const currentModel = modelSelectionSnapshot ? modelSelectionLabel(modelSelectionSnapshot.current) : "DSH default";
|
|
22620
|
-
const currentReasoningEffort = modelSelectionSnapshot ? modelReasoningEffortLabel(modelSelectionSnapshot.current) : void 0;
|
|
22621
|
-
const providerSetupSnapshot =
|
|
23273
|
+
const currentModel = sideConversationSnapshot.activeSurface === "side" && sideConversationSnapshot.sideModelLabel ? sideConversationSnapshot.sideModelLabel : modelSelectionSnapshot ? modelSelectionLabel(modelSelectionSnapshot.current) : "DSH default";
|
|
23274
|
+
const currentReasoningEffort = sideConversationSnapshot.activeSurface === "side" ? sideConversationSnapshot.sideReasoningEffortLabel : modelSelectionSnapshot ? modelReasoningEffortLabel(modelSelectionSnapshot.current) : void 0;
|
|
23275
|
+
const providerSetupSnapshot = useSyncExternalStore6(
|
|
22622
23276
|
providerSetupRuntime?.subscribe ?? noopExternalStoreSubscribe,
|
|
22623
23277
|
providerSetupRuntime?.getSnapshot ?? emptyProviderSetupSnapshot,
|
|
22624
23278
|
providerSetupRuntime?.getSnapshot ?? emptyProviderSetupSnapshot
|
|
22625
23279
|
);
|
|
22626
|
-
const [providerSetupDismissed, setProviderSetupDismissed] =
|
|
22627
|
-
const promptHistory =
|
|
23280
|
+
const [providerSetupDismissed, setProviderSetupDismissed] = useState54(false);
|
|
23281
|
+
const promptHistory = useMemo36(
|
|
22628
23282
|
() => new PromptHistoryStore(
|
|
22629
23283
|
join5(config.storage.getProjectTempDir(), "prompt_history.json")
|
|
22630
23284
|
),
|
|
@@ -22637,11 +23291,11 @@ var AppContainer = (props) => {
|
|
|
22637
23291
|
const app = useApp();
|
|
22638
23292
|
const { stats: sessionStats } = useSessionStats();
|
|
22639
23293
|
const branchName = useGitBranchName(config.getTargetDir());
|
|
22640
|
-
const mainControlsRef =
|
|
22641
|
-
const rootUiRef =
|
|
22642
|
-
const lastTitleRef =
|
|
23294
|
+
const mainControlsRef = useRef31(null);
|
|
23295
|
+
const rootUiRef = useRef31(null);
|
|
23296
|
+
const lastTitleRef = useRef31(null);
|
|
22643
23297
|
const staticExtraHeight = 3;
|
|
22644
|
-
|
|
23298
|
+
useEffect55(() => {
|
|
22645
23299
|
void (async () => {
|
|
22646
23300
|
startupProfiler.flush();
|
|
22647
23301
|
})();
|
|
@@ -22649,7 +23303,7 @@ var AppContainer = (props) => {
|
|
|
22649
23303
|
disableMouseEvents();
|
|
22650
23304
|
});
|
|
22651
23305
|
}, [config]);
|
|
22652
|
-
|
|
23306
|
+
useEffect55(() => {
|
|
22653
23307
|
const handleSettingsChanged = () => {
|
|
22654
23308
|
setSettingsNonce((prev) => prev + 1);
|
|
22655
23309
|
};
|
|
@@ -22660,19 +23314,19 @@ var AppContainer = (props) => {
|
|
|
22660
23314
|
}, []);
|
|
22661
23315
|
const { consoleMessages, clearConsoleMessages: clearConsoleMessagesState } = useConsoleMessages();
|
|
22662
23316
|
const mainAreaWidth = calculateMainAreaWidth(terminalWidth, settings);
|
|
22663
|
-
const { inputWidth, suggestionsWidth } =
|
|
23317
|
+
const { inputWidth, suggestionsWidth } = useMemo36(() => {
|
|
22664
23318
|
const { inputWidth: inputWidth2, suggestionsWidth: suggestionsWidth2 } = calculatePromptWidths(mainAreaWidth);
|
|
22665
23319
|
return { inputWidth: inputWidth2, suggestionsWidth: suggestionsWidth2 };
|
|
22666
23320
|
}, [mainAreaWidth]);
|
|
22667
23321
|
const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100);
|
|
22668
|
-
const isValidPath =
|
|
23322
|
+
const isValidPath = useCallback46((filePath) => {
|
|
22669
23323
|
try {
|
|
22670
23324
|
return fs12.existsSync(filePath) && fs12.statSync(filePath).isFile();
|
|
22671
23325
|
} catch (_e) {
|
|
22672
23326
|
return false;
|
|
22673
23327
|
}
|
|
22674
23328
|
}, []);
|
|
22675
|
-
const getPreferredEditor =
|
|
23329
|
+
const getPreferredEditor = useCallback46(
|
|
22676
23330
|
() => settings.merged.general.preferredEditor,
|
|
22677
23331
|
[settings.merged.general.preferredEditor]
|
|
22678
23332
|
);
|
|
@@ -22685,16 +23339,16 @@ var AppContainer = (props) => {
|
|
|
22685
23339
|
shellModeActive,
|
|
22686
23340
|
getPreferredEditor
|
|
22687
23341
|
});
|
|
22688
|
-
|
|
23342
|
+
useEffect55(() => {
|
|
22689
23343
|
initializeFromHistory(promptHistory);
|
|
22690
23344
|
}, [initializeFromHistory, promptHistory]);
|
|
22691
|
-
const refreshStatic =
|
|
23345
|
+
const refreshStatic = useCallback46(() => {
|
|
22692
23346
|
if (!isAlternateBuffer) {
|
|
22693
23347
|
stdout.write(ansiEscapes.clearTerminal);
|
|
22694
23348
|
}
|
|
22695
23349
|
setHistoryRemountKey((prev) => prev + 1);
|
|
22696
23350
|
}, [setHistoryRemountKey, isAlternateBuffer, stdout]);
|
|
22697
|
-
const handleEditorClose =
|
|
23351
|
+
const handleEditorClose = useCallback46(() => {
|
|
22698
23352
|
if (shouldEnterAlternateScreen(isAlternateBuffer, config.getScreenReader())) {
|
|
22699
23353
|
enterAlternateScreen();
|
|
22700
23354
|
enableMouseEvents();
|
|
@@ -22704,7 +23358,7 @@ var AppContainer = (props) => {
|
|
|
22704
23358
|
terminalCapabilityManager.enableSupportedModes();
|
|
22705
23359
|
refreshStatic();
|
|
22706
23360
|
}, [refreshStatic, isAlternateBuffer, app, config]);
|
|
22707
|
-
|
|
23361
|
+
useEffect55(() => {
|
|
22708
23362
|
coreEvents.on(CoreEvent.ExternalEditorClosed, handleEditorClose);
|
|
22709
23363
|
return () => {
|
|
22710
23364
|
coreEvents.off(CoreEvent.ExternalEditorClosed, handleEditorClose);
|
|
@@ -22722,7 +23376,7 @@ var AppContainer = (props) => {
|
|
|
22722
23376
|
historyManager.addItem,
|
|
22723
23377
|
initializationResult.themeError
|
|
22724
23378
|
);
|
|
22725
|
-
const [editorError, setEditorError] =
|
|
23379
|
+
const [editorError, setEditorError] = useState54(null);
|
|
22726
23380
|
const {
|
|
22727
23381
|
isEditorDialogOpen,
|
|
22728
23382
|
openEditorDialog,
|
|
@@ -22731,7 +23385,7 @@ var AppContainer = (props) => {
|
|
|
22731
23385
|
} = useEditorSettings(settings, setEditorError, historyManager.addItem);
|
|
22732
23386
|
const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } = useSettingsCommand();
|
|
22733
23387
|
const { toggleVimEnabled } = useVimMode();
|
|
22734
|
-
const slashCommandActions =
|
|
23388
|
+
const slashCommandActions = useMemo36(
|
|
22735
23389
|
() => ({
|
|
22736
23390
|
openThemeDialog,
|
|
22737
23391
|
openEditorDialog,
|
|
@@ -22776,13 +23430,15 @@ var AppContainer = (props) => {
|
|
|
22776
23430
|
toolCatalogRuntime,
|
|
22777
23431
|
commandRuntime,
|
|
22778
23432
|
enableProfiler,
|
|
22779
|
-
providerSetupRuntime
|
|
23433
|
+
providerSetupRuntime,
|
|
23434
|
+
sideConversationRuntime,
|
|
23435
|
+
subagentCatalogRuntime
|
|
22780
23436
|
);
|
|
22781
|
-
const cancelHandlerRef =
|
|
23437
|
+
const cancelHandlerRef = useRef31(
|
|
22782
23438
|
() => {
|
|
22783
23439
|
}
|
|
22784
23440
|
);
|
|
22785
|
-
|
|
23441
|
+
useEffect55(() => {
|
|
22786
23442
|
if (pendingRestorePrompt) {
|
|
22787
23443
|
const lastHistoryUserMsg = historyManager.history.findLast(
|
|
22788
23444
|
(h) => h.type === "user"
|
|
@@ -22795,7 +23451,7 @@ var AppContainer = (props) => {
|
|
|
22795
23451
|
}
|
|
22796
23452
|
}, [pendingRestorePrompt, inputHistory, historyManager.history]);
|
|
22797
23453
|
const initError = initializationResult.initError;
|
|
22798
|
-
const todos =
|
|
23454
|
+
const todos = useMemo36(
|
|
22799
23455
|
() => ({
|
|
22800
23456
|
todos: conversationSnapshot.todos.map((todo) => ({
|
|
22801
23457
|
description: todo.content,
|
|
@@ -22820,7 +23476,7 @@ var AppContainer = (props) => {
|
|
|
22820
23476
|
terminalHeight
|
|
22821
23477
|
});
|
|
22822
23478
|
const streamingState = conversationSnapshot.busy || promptInputPreparing || localShellExecuting || isProcessing ? "responding" /* Responding */ : "idle" /* Idle */;
|
|
22823
|
-
const submitQuery =
|
|
23479
|
+
const submitQuery = useCallback46(
|
|
22824
23480
|
(query) => {
|
|
22825
23481
|
if (isSlashCommand(query.trim())) {
|
|
22826
23482
|
void handleSlashCommand(query);
|
|
@@ -22873,20 +23529,20 @@ var AppContainer = (props) => {
|
|
|
22873
23529
|
buffer
|
|
22874
23530
|
]
|
|
22875
23531
|
);
|
|
22876
|
-
const cancelOngoingRequest =
|
|
23532
|
+
const cancelOngoingRequest = useCallback46(() => {
|
|
22877
23533
|
cancelCommand();
|
|
22878
23534
|
cancelLocalShell();
|
|
22879
23535
|
promptInputAbortRef.current?.abort();
|
|
22880
23536
|
conversationRuntime.cancel();
|
|
22881
23537
|
}, [cancelCommand, cancelLocalShell, conversationRuntime]);
|
|
22882
|
-
|
|
23538
|
+
useEffect55(
|
|
22883
23539
|
() => () => {
|
|
22884
23540
|
promptInputAbortRef.current?.abort();
|
|
22885
23541
|
},
|
|
22886
23542
|
[]
|
|
22887
23543
|
);
|
|
22888
|
-
const lastOutputTimeRef =
|
|
22889
|
-
|
|
23544
|
+
const lastOutputTimeRef = useRef31(0);
|
|
23545
|
+
useEffect55(() => {
|
|
22890
23546
|
lastOutputTimeRef.current = lastOutputTime;
|
|
22891
23547
|
}, [lastOutputTime]);
|
|
22892
23548
|
const { shouldShowFocusHint, inactivityStatus } = useShellInactivityStatus({
|
|
@@ -22905,10 +23561,11 @@ var AppContainer = (props) => {
|
|
|
22905
23561
|
getQueuedMessagesText,
|
|
22906
23562
|
popAllMessages
|
|
22907
23563
|
} = useMessageQueue({
|
|
23564
|
+
queueKey: conversationSessionId,
|
|
22908
23565
|
streamingState,
|
|
22909
23566
|
submitQuery
|
|
22910
23567
|
});
|
|
22911
|
-
cancelHandlerRef.current =
|
|
23568
|
+
cancelHandlerRef.current = useCallback46(
|
|
22912
23569
|
(shouldRestorePrompt = true) => {
|
|
22913
23570
|
const lastUserMessage = inputHistory.at(-1);
|
|
22914
23571
|
let textToSet = shouldRestorePrompt ? lastUserMessage || "" : "";
|
|
@@ -22923,14 +23580,9 @@ ${queuedText}` : queuedText;
|
|
|
22923
23580
|
buffer.setText(textToSet);
|
|
22924
23581
|
}
|
|
22925
23582
|
},
|
|
22926
|
-
[
|
|
22927
|
-
buffer,
|
|
22928
|
-
inputHistory,
|
|
22929
|
-
getQueuedMessagesText,
|
|
22930
|
-
clearQueue
|
|
22931
|
-
]
|
|
23583
|
+
[buffer, inputHistory, getQueuedMessagesText, clearQueue]
|
|
22932
23584
|
);
|
|
22933
|
-
const handleFinalSubmit =
|
|
23585
|
+
const handleFinalSubmit = useCallback46(
|
|
22934
23586
|
(submittedValue) => {
|
|
22935
23587
|
if (shellModeActive) {
|
|
22936
23588
|
executeLocalShell(submittedValue);
|
|
@@ -22965,14 +23617,14 @@ ${queuedText}` : queuedText;
|
|
|
22965
23617
|
streamingState
|
|
22966
23618
|
]
|
|
22967
23619
|
);
|
|
22968
|
-
const handleClearScreen =
|
|
23620
|
+
const handleClearScreen = useCallback46(() => {
|
|
22969
23621
|
historyManager.clearItems();
|
|
22970
23622
|
clearConsoleMessagesState();
|
|
22971
23623
|
refreshStatic();
|
|
22972
23624
|
}, [historyManager, clearConsoleMessagesState, refreshStatic]);
|
|
22973
23625
|
const { handleInput: vimHandleInput } = useVim(buffer, handleFinalSubmit);
|
|
22974
23626
|
const isInputActive = !initError && !isProcessing && pendingApproval === void 0 && pendingUserQuestion === void 0 && !!slashCommands && (streamingState === "idle" /* Idle */ || streamingState === "responding" /* Responding */);
|
|
22975
|
-
const [controlsHeight, setControlsHeight] =
|
|
23627
|
+
const [controlsHeight, setControlsHeight] = useState54(0);
|
|
22976
23628
|
useLayoutEffect3(() => {
|
|
22977
23629
|
if (mainControlsRef.current) {
|
|
22978
23630
|
const fullFooterMeasurement = measureElement3(mainControlsRef.current);
|
|
@@ -22996,18 +23648,18 @@ ${queuedText}` : queuedText;
|
|
|
22996
23648
|
sanitizationConfig: config.sanitizationConfig
|
|
22997
23649
|
});
|
|
22998
23650
|
const isFocused = useFocus();
|
|
22999
|
-
const initialPrompt =
|
|
23651
|
+
const initialPrompt = useMemo36(
|
|
23000
23652
|
() => props.initialPrompt ?? config.getQuestion(),
|
|
23001
23653
|
[config, props.initialPrompt]
|
|
23002
23654
|
);
|
|
23003
|
-
const initialPromptSubmitted =
|
|
23655
|
+
const initialPromptSubmitted = useRef31(false);
|
|
23004
23656
|
const providerSetupRequired = providerSetupSnapshot?.current.status === "missing";
|
|
23005
|
-
|
|
23657
|
+
useEffect55(() => {
|
|
23006
23658
|
if (!providerSetupRuntime || !providerSetupRequired || providerSetupDismissed || customDialog) {
|
|
23007
23659
|
return;
|
|
23008
23660
|
}
|
|
23009
23661
|
setCustomDialog(
|
|
23010
|
-
/* @__PURE__ */
|
|
23662
|
+
/* @__PURE__ */ jsx96(
|
|
23011
23663
|
ProviderSetupDialog,
|
|
23012
23664
|
{
|
|
23013
23665
|
runtime: providerSetupRuntime,
|
|
@@ -23034,7 +23686,7 @@ ${queuedText}` : queuedText;
|
|
|
23034
23686
|
providerSetupRuntime,
|
|
23035
23687
|
providerSetupSnapshot
|
|
23036
23688
|
]);
|
|
23037
|
-
|
|
23689
|
+
useEffect55(() => {
|
|
23038
23690
|
if (activePtyId) {
|
|
23039
23691
|
try {
|
|
23040
23692
|
ShellExecutionService.resizePty(
|
|
@@ -23052,7 +23704,7 @@ ${queuedText}` : queuedText;
|
|
|
23052
23704
|
}
|
|
23053
23705
|
}
|
|
23054
23706
|
}, [terminalWidth, availableTerminalHeight, activePtyId]);
|
|
23055
|
-
|
|
23707
|
+
useEffect55(() => {
|
|
23056
23708
|
if (initialPrompt && !initialPromptSubmitted.current && !isThemeDialogOpen && !isEditorDialogOpen && !providerSetupRequired && !customDialog && conversationRuntime) {
|
|
23057
23709
|
handleFinalSubmit(initialPrompt);
|
|
23058
23710
|
initialPromptSubmitted.current = true;
|
|
@@ -23066,20 +23718,20 @@ ${queuedText}` : queuedText;
|
|
|
23066
23718
|
customDialog,
|
|
23067
23719
|
conversationRuntime
|
|
23068
23720
|
]);
|
|
23069
|
-
const [showErrorDetails, setShowErrorDetails] =
|
|
23070
|
-
const [showFullTodos, setShowFullTodos] =
|
|
23071
|
-
const [renderMarkdown, setRenderMarkdown] =
|
|
23072
|
-
const [ctrlCPressCount, setCtrlCPressCount] =
|
|
23073
|
-
const ctrlCTimerRef =
|
|
23074
|
-
const [ctrlDPressCount, setCtrlDPressCount] =
|
|
23075
|
-
const ctrlDTimerRef =
|
|
23076
|
-
const [constrainHeight, setConstrainHeight] =
|
|
23077
|
-
const [showEscapePrompt, setShowEscapePrompt] =
|
|
23078
|
-
const [warningMessage, setWarningMessage] =
|
|
23079
|
-
const isInitialMount =
|
|
23080
|
-
const warningTimeoutRef =
|
|
23081
|
-
const tabFocusTimeoutRef =
|
|
23082
|
-
const handleWarning =
|
|
23721
|
+
const [showErrorDetails, setShowErrorDetails] = useState54(false);
|
|
23722
|
+
const [showFullTodos, setShowFullTodos] = useState54(false);
|
|
23723
|
+
const [renderMarkdown, setRenderMarkdown] = useState54(true);
|
|
23724
|
+
const [ctrlCPressCount, setCtrlCPressCount] = useState54(0);
|
|
23725
|
+
const ctrlCTimerRef = useRef31(null);
|
|
23726
|
+
const [ctrlDPressCount, setCtrlDPressCount] = useState54(0);
|
|
23727
|
+
const ctrlDTimerRef = useRef31(null);
|
|
23728
|
+
const [constrainHeight, setConstrainHeight] = useState54(true);
|
|
23729
|
+
const [showEscapePrompt, setShowEscapePrompt] = useState54(false);
|
|
23730
|
+
const [warningMessage, setWarningMessage] = useState54(null);
|
|
23731
|
+
const isInitialMount = useRef31(true);
|
|
23732
|
+
const warningTimeoutRef = useRef31(null);
|
|
23733
|
+
const tabFocusTimeoutRef = useRef31(null);
|
|
23734
|
+
const handleWarning = useCallback46((message) => {
|
|
23083
23735
|
setWarningMessage(message);
|
|
23084
23736
|
if (warningTimeoutRef.current) {
|
|
23085
23737
|
clearTimeout(warningTimeoutRef.current);
|
|
@@ -23088,7 +23740,7 @@ ${queuedText}` : queuedText;
|
|
|
23088
23740
|
setWarningMessage(null);
|
|
23089
23741
|
}, WARNING_PROMPT_DURATION_MS);
|
|
23090
23742
|
}, []);
|
|
23091
|
-
|
|
23743
|
+
useEffect55(() => {
|
|
23092
23744
|
const handleSelectionWarning = () => {
|
|
23093
23745
|
handleWarning("Press Ctrl-S to enter selection mode to copy text.");
|
|
23094
23746
|
};
|
|
@@ -23108,7 +23760,7 @@ ${queuedText}` : queuedText;
|
|
|
23108
23760
|
}
|
|
23109
23761
|
};
|
|
23110
23762
|
}, [handleWarning]);
|
|
23111
|
-
|
|
23763
|
+
useEffect55(() => {
|
|
23112
23764
|
if (queueErrorMessage) {
|
|
23113
23765
|
const timer = setTimeout(() => {
|
|
23114
23766
|
setQueueErrorMessage(null);
|
|
@@ -23117,7 +23769,7 @@ ${queuedText}` : queuedText;
|
|
|
23117
23769
|
}
|
|
23118
23770
|
return void 0;
|
|
23119
23771
|
}, [queueErrorMessage, setQueueErrorMessage]);
|
|
23120
|
-
|
|
23772
|
+
useEffect55(() => {
|
|
23121
23773
|
if (isInitialMount.current) {
|
|
23122
23774
|
isInitialMount.current = false;
|
|
23123
23775
|
return;
|
|
@@ -23129,7 +23781,7 @@ ${queuedText}` : queuedText;
|
|
|
23129
23781
|
clearTimeout(handler);
|
|
23130
23782
|
};
|
|
23131
23783
|
}, [terminalWidth, refreshStatic]);
|
|
23132
|
-
|
|
23784
|
+
useEffect55(() => {
|
|
23133
23785
|
const openDebugConsole = () => {
|
|
23134
23786
|
setShowErrorDetails(true);
|
|
23135
23787
|
setConstrainHeight(false);
|
|
@@ -23139,7 +23791,7 @@ ${queuedText}` : queuedText;
|
|
|
23139
23791
|
appEvents.off("open-debug-console" /* OpenDebugConsole */, openDebugConsole);
|
|
23140
23792
|
};
|
|
23141
23793
|
}, [config]);
|
|
23142
|
-
|
|
23794
|
+
useEffect55(() => {
|
|
23143
23795
|
if (ctrlCTimerRef.current) {
|
|
23144
23796
|
clearTimeout(ctrlCTimerRef.current);
|
|
23145
23797
|
ctrlCTimerRef.current = null;
|
|
@@ -23153,7 +23805,7 @@ ${queuedText}` : queuedText;
|
|
|
23153
23805
|
}, WARNING_PROMPT_DURATION_MS);
|
|
23154
23806
|
}
|
|
23155
23807
|
}, [ctrlCPressCount, config, setCtrlCPressCount, handleSlashCommand]);
|
|
23156
|
-
|
|
23808
|
+
useEffect55(() => {
|
|
23157
23809
|
if (ctrlDTimerRef.current) {
|
|
23158
23810
|
clearTimeout(ctrlDTimerRef.current);
|
|
23159
23811
|
ctrlCTimerRef.current = null;
|
|
@@ -23167,7 +23819,7 @@ ${queuedText}` : queuedText;
|
|
|
23167
23819
|
}, WARNING_PROMPT_DURATION_MS);
|
|
23168
23820
|
}
|
|
23169
23821
|
}, [ctrlDPressCount, config, setCtrlDPressCount, handleSlashCommand]);
|
|
23170
|
-
const handleEscapePromptChange =
|
|
23822
|
+
const handleEscapePromptChange = useCallback46((showPrompt) => {
|
|
23171
23823
|
setShowEscapePrompt(showPrompt);
|
|
23172
23824
|
}, []);
|
|
23173
23825
|
const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator({
|
|
@@ -23175,13 +23827,21 @@ ${queuedText}` : queuedText;
|
|
|
23175
23827
|
shouldShowFocusHint,
|
|
23176
23828
|
customWittyPhrases: settings.merged.ui.customWittyPhrases
|
|
23177
23829
|
});
|
|
23178
|
-
const handleGlobalKeypress =
|
|
23830
|
+
const handleGlobalKeypress = useCallback46(
|
|
23179
23831
|
(key) => {
|
|
23180
23832
|
if (copyModeEnabled) {
|
|
23181
23833
|
setCopyModeEnabled(false);
|
|
23182
23834
|
enableMouseEvents();
|
|
23183
23835
|
return;
|
|
23184
23836
|
}
|
|
23837
|
+
if (sideConversationRuntime && !customDialog && pendingApproval === void 0 && pendingUserQuestion === void 0 && isConversationSwitchKey(key)) {
|
|
23838
|
+
if (sideConversationSnapshot.activeSurface === "side") {
|
|
23839
|
+
sideConversationRuntime.switchToMain();
|
|
23840
|
+
} else if (sideConversationSnapshot.sideSessionId !== void 0) {
|
|
23841
|
+
sideConversationRuntime.switchToSide();
|
|
23842
|
+
}
|
|
23843
|
+
return;
|
|
23844
|
+
}
|
|
23185
23845
|
if (isAlternateBuffer && keyMatchers["app.toggleCopyMode" /* TOGGLE_COPY_MODE */](key)) {
|
|
23186
23846
|
setCopyModeEnabled(true);
|
|
23187
23847
|
disableMouseEvents();
|
|
@@ -23200,6 +23860,12 @@ ${queuedText}` : queuedText;
|
|
|
23200
23860
|
return;
|
|
23201
23861
|
}
|
|
23202
23862
|
if (conversationRuntime) {
|
|
23863
|
+
if (sideConversationRuntime && sideConversationSnapshot.activeSurface === "side" && !conversationSnapshot.busy && !promptInputPreparing && !localShellExecuting && !isProcessing) {
|
|
23864
|
+
if (buffer.text.length > 0) return;
|
|
23865
|
+
clearQueue();
|
|
23866
|
+
void sideConversationRuntime.closeSide();
|
|
23867
|
+
return;
|
|
23868
|
+
}
|
|
23203
23869
|
if (promptInputPreparing || localShellExecuting || isProcessing || conversationSnapshot.busy) {
|
|
23204
23870
|
cancelOngoingRequest();
|
|
23205
23871
|
} else {
|
|
@@ -23283,17 +23949,20 @@ ${queuedText}` : queuedText;
|
|
|
23283
23949
|
setCopyModeEnabled,
|
|
23284
23950
|
copyModeEnabled,
|
|
23285
23951
|
isAlternateBuffer,
|
|
23286
|
-
handleWarning
|
|
23952
|
+
handleWarning,
|
|
23953
|
+
clearQueue,
|
|
23954
|
+
sideConversationRuntime,
|
|
23955
|
+
sideConversationSnapshot
|
|
23287
23956
|
]
|
|
23288
23957
|
);
|
|
23289
23958
|
useKeypress(handleGlobalKeypress, { isActive: true });
|
|
23290
|
-
|
|
23959
|
+
useEffect55(() => {
|
|
23291
23960
|
if (settings.merged.ui.hideWindowTitle) return;
|
|
23292
23961
|
const paddedTitle = computeTerminalTitle({
|
|
23293
23962
|
streamingState,
|
|
23294
23963
|
isConfirming: pendingApproval !== void 0 || !!confirmationRequest || shouldShowActionRequiredTitle,
|
|
23295
23964
|
isSilentWorking: shouldShowSilentWorkingTitle,
|
|
23296
|
-
folderName:
|
|
23965
|
+
folderName: basename3(config.getTargetDir()),
|
|
23297
23966
|
useDynamicTitle: settings.merged.ui.dynamicWindowTitle
|
|
23298
23967
|
});
|
|
23299
23968
|
if (lastTitleRef.current !== paddedTitle) {
|
|
@@ -23311,7 +23980,7 @@ ${queuedText}` : queuedText;
|
|
|
23311
23980
|
config,
|
|
23312
23981
|
stdout
|
|
23313
23982
|
]);
|
|
23314
|
-
|
|
23983
|
+
useEffect55(() => {
|
|
23315
23984
|
const handleUserFeedback = (payload) => {
|
|
23316
23985
|
let type;
|
|
23317
23986
|
switch (payload.severity) {
|
|
@@ -23349,23 +24018,23 @@ ${queuedText}` : queuedText;
|
|
|
23349
24018
|
coreEvents.off(CoreEvent.UserFeedback, handleUserFeedback);
|
|
23350
24019
|
};
|
|
23351
24020
|
}, [historyManager]);
|
|
23352
|
-
const filteredConsoleMessages =
|
|
24021
|
+
const filteredConsoleMessages = useMemo36(() => {
|
|
23353
24022
|
if (config.getDebugMode()) {
|
|
23354
24023
|
return consoleMessages;
|
|
23355
24024
|
}
|
|
23356
24025
|
return consoleMessages.filter((msg) => msg.type !== "debug");
|
|
23357
24026
|
}, [consoleMessages, config]);
|
|
23358
|
-
const errorCount =
|
|
24027
|
+
const errorCount = useMemo36(
|
|
23359
24028
|
() => filteredConsoleMessages.filter((msg) => msg.type === "error").reduce((total, msg) => total + msg.count, 0),
|
|
23360
24029
|
[filteredConsoleMessages]
|
|
23361
24030
|
);
|
|
23362
24031
|
const nightly = props.version.includes("nightly");
|
|
23363
24032
|
const dialogsVisible = pendingUserQuestion !== void 0 || !!confirmationRequest || !!customDialog || isThemeDialogOpen || isSettingsDialogOpen || isEditorDialogOpen;
|
|
23364
|
-
const pendingHistoryItems =
|
|
24033
|
+
const pendingHistoryItems = useMemo36(
|
|
23365
24034
|
() => pendingShellHistoryItem ? [pendingShellHistoryItem] : [],
|
|
23366
24035
|
[pendingShellHistoryItem]
|
|
23367
24036
|
);
|
|
23368
|
-
const uiState =
|
|
24037
|
+
const uiState = useMemo36(
|
|
23369
24038
|
() => ({
|
|
23370
24039
|
history: historyManager.history,
|
|
23371
24040
|
isThemeDialogOpen,
|
|
@@ -23425,7 +24094,9 @@ ${queuedText}` : queuedText;
|
|
|
23425
24094
|
copyModeEnabled,
|
|
23426
24095
|
warningMessage,
|
|
23427
24096
|
terminalBackgroundColor: config.getTerminalBackground(),
|
|
23428
|
-
settingsNonce
|
|
24097
|
+
settingsNonce,
|
|
24098
|
+
sideConversation: sideConversationSnapshot,
|
|
24099
|
+
subagentCatalog: subagentCatalogSnapshot
|
|
23429
24100
|
}),
|
|
23430
24101
|
[
|
|
23431
24102
|
isThemeDialogOpen,
|
|
@@ -23486,10 +24157,12 @@ ${queuedText}` : queuedText;
|
|
|
23486
24157
|
copyModeEnabled,
|
|
23487
24158
|
warningMessage,
|
|
23488
24159
|
config,
|
|
23489
|
-
settingsNonce
|
|
24160
|
+
settingsNonce,
|
|
24161
|
+
sideConversationSnapshot,
|
|
24162
|
+
subagentCatalogSnapshot
|
|
23490
24163
|
]
|
|
23491
24164
|
);
|
|
23492
|
-
const uiActions =
|
|
24165
|
+
const uiActions = useMemo36(
|
|
23493
24166
|
() => ({
|
|
23494
24167
|
handleThemeSelect,
|
|
23495
24168
|
closeThemeDialog,
|
|
@@ -23531,22 +24204,22 @@ ${queuedText}` : queuedText;
|
|
|
23531
24204
|
setEmbeddedShellFocused
|
|
23532
24205
|
]
|
|
23533
24206
|
);
|
|
23534
|
-
return /* @__PURE__ */
|
|
24207
|
+
return /* @__PURE__ */ jsx96(UIStateContext.Provider, { value: uiState, children: /* @__PURE__ */ jsx96(UIActionsContext.Provider, { value: uiActions, children: /* @__PURE__ */ jsx96(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx96(
|
|
23535
24208
|
AppContext.Provider,
|
|
23536
24209
|
{
|
|
23537
24210
|
value: {
|
|
23538
24211
|
version: props.version,
|
|
23539
24212
|
startupWarnings: props.startupWarnings || []
|
|
23540
24213
|
},
|
|
23541
|
-
children: /* @__PURE__ */
|
|
24214
|
+
children: /* @__PURE__ */ jsx96(ApprovalRuntimeProvider, { runtime: approvalRuntime, children: /* @__PURE__ */ jsx96(UserQuestionRuntimeProvider, { runtime: userQuestionRuntime, children: /* @__PURE__ */ jsx96(ShellFocusContext.Provider, { value: isFocused, children: /* @__PURE__ */ jsx96(App, {}) }) }) })
|
|
23542
24215
|
}
|
|
23543
24216
|
) }) }) });
|
|
23544
24217
|
};
|
|
23545
24218
|
|
|
23546
24219
|
// src/ui/root.tsx
|
|
23547
|
-
import
|
|
24220
|
+
import React22 from "react";
|
|
23548
24221
|
import { render } from "ink";
|
|
23549
|
-
import { jsx as
|
|
24222
|
+
import { jsx as jsx97 } from "react/jsx-runtime";
|
|
23550
24223
|
var SLOW_RENDER_MS = 200;
|
|
23551
24224
|
function validateDnsResolutionOrder(order) {
|
|
23552
24225
|
const defaultValue = "ipv4first";
|
|
@@ -23578,7 +24251,7 @@ ${reason.stack}` : ""}`;
|
|
|
23578
24251
|
}
|
|
23579
24252
|
});
|
|
23580
24253
|
}
|
|
23581
|
-
async function startInteractiveUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), initializationResult, conversationRuntime, approvalRuntime, userQuestionRuntime, commandRuntime, permissionSelectionRuntime, toolCatalogRuntime, promptCompletionRuntime, promptInputRuntime, modelSelectionRuntime, sessionManagementRuntime, initialPrompt, providerSetupRuntime) {
|
|
24254
|
+
async function startInteractiveUI(config, settings, startupWarnings, workspaceRoot = process.cwd(), initializationResult, conversationRuntime, approvalRuntime, userQuestionRuntime, commandRuntime, permissionSelectionRuntime, toolCatalogRuntime, promptCompletionRuntime, promptInputRuntime, modelSelectionRuntime, sessionManagementRuntime, initialPrompt, providerSetupRuntime, sideConversationRuntime, subagentCatalogRuntime) {
|
|
23582
24255
|
const useAlternateBuffer2 = shouldEnterAlternateScreen(
|
|
23583
24256
|
isAlternateBufferEnabled(settings),
|
|
23584
24257
|
config.getScreenReader()
|
|
@@ -23590,21 +24263,21 @@ async function startInteractiveUI(config, settings, startupWarnings, workspaceRo
|
|
|
23590
24263
|
disableMouseEvents();
|
|
23591
24264
|
});
|
|
23592
24265
|
}
|
|
23593
|
-
setWindowTitle(
|
|
24266
|
+
setWindowTitle(basename4(workspaceRoot), settings);
|
|
23594
24267
|
const version = await getVersion();
|
|
23595
24268
|
const AppWrapper = () => {
|
|
23596
24269
|
useKittyKeyboardProtocol();
|
|
23597
|
-
return /* @__PURE__ */
|
|
24270
|
+
return /* @__PURE__ */ jsx97(SettingsContext.Provider, { value: settings, children: /* @__PURE__ */ jsx97(
|
|
23598
24271
|
KeypressProvider,
|
|
23599
24272
|
{
|
|
23600
24273
|
config,
|
|
23601
24274
|
debugKeystrokeLogging: settings.merged.general.debugKeystrokeLogging,
|
|
23602
|
-
children: /* @__PURE__ */
|
|
24275
|
+
children: /* @__PURE__ */ jsx97(
|
|
23603
24276
|
MouseProvider,
|
|
23604
24277
|
{
|
|
23605
24278
|
mouseEventsEnabled,
|
|
23606
24279
|
debugKeystrokeLogging: settings.merged.general.debugKeystrokeLogging,
|
|
23607
|
-
children: /* @__PURE__ */
|
|
24280
|
+
children: /* @__PURE__ */ jsx97(ScrollProvider, { children: /* @__PURE__ */ jsx97(SessionStatsProvider, { conversationRuntime, children: /* @__PURE__ */ jsx97(VimModeProvider, { settings, children: /* @__PURE__ */ jsx97(
|
|
23608
24281
|
AppContainer,
|
|
23609
24282
|
{
|
|
23610
24283
|
config,
|
|
@@ -23622,6 +24295,8 @@ async function startInteractiveUI(config, settings, startupWarnings, workspaceRo
|
|
|
23622
24295
|
commandRuntime,
|
|
23623
24296
|
permissionSelectionRuntime,
|
|
23624
24297
|
toolCatalogRuntime,
|
|
24298
|
+
sideConversationRuntime,
|
|
24299
|
+
subagentCatalogRuntime,
|
|
23625
24300
|
initialPrompt
|
|
23626
24301
|
}
|
|
23627
24302
|
) }) }) })
|
|
@@ -23632,7 +24307,7 @@ async function startInteractiveUI(config, settings, startupWarnings, workspaceRo
|
|
|
23632
24307
|
};
|
|
23633
24308
|
const { stdout: inkStdout, stderr: inkStderr } = createWorkingStdio();
|
|
23634
24309
|
const instance = render(
|
|
23635
|
-
process.env["DEBUG"] ? /* @__PURE__ */
|
|
24310
|
+
process.env["DEBUG"] ? /* @__PURE__ */ jsx97(React22.StrictMode, { children: /* @__PURE__ */ jsx97(AppWrapper, {}) }) : /* @__PURE__ */ jsx97(AppWrapper, {}),
|
|
23636
24311
|
{
|
|
23637
24312
|
stdout: inkStdout,
|
|
23638
24313
|
stderr: inkStderr,
|
|
@@ -23738,7 +24413,9 @@ async function main(options) {
|
|
|
23738
24413
|
options.modelSelectionRuntime,
|
|
23739
24414
|
options.sessionManagementRuntime,
|
|
23740
24415
|
options.initialPrompt,
|
|
23741
|
-
options.providerSetupRuntime
|
|
24416
|
+
options.providerSetupRuntime,
|
|
24417
|
+
options.sideConversationRuntime,
|
|
24418
|
+
options.subagentCatalogRuntime
|
|
23742
24419
|
);
|
|
23743
24420
|
}
|
|
23744
24421
|
}
|
|
@@ -24266,6 +24943,167 @@ var DshPromptCompletionRuntime = class {
|
|
|
24266
24943
|
}
|
|
24267
24944
|
};
|
|
24268
24945
|
|
|
24946
|
+
// src/dsh/side-conversation.ts
|
|
24947
|
+
var SIDE_SESSION_PREFIX = "dsh-console-side-";
|
|
24948
|
+
function completedTurnSeed(events) {
|
|
24949
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
24950
|
+
if (events[index].type === "turn/end") return events.slice(0, index + 1);
|
|
24951
|
+
}
|
|
24952
|
+
return [];
|
|
24953
|
+
}
|
|
24954
|
+
function pendingUserText(events, seedLength) {
|
|
24955
|
+
for (let index = events.length - 1; index >= seedLength; index -= 1) {
|
|
24956
|
+
const event = events[index];
|
|
24957
|
+
if (event.type !== "user/message") continue;
|
|
24958
|
+
return event.data.content.flatMap((block) => block.type === "text" ? [block.text] : []).join("").trim();
|
|
24959
|
+
}
|
|
24960
|
+
return "";
|
|
24961
|
+
}
|
|
24962
|
+
function firstSidePrompt(question, pendingRequest) {
|
|
24963
|
+
return [
|
|
24964
|
+
"You are a Side conversation branching from the main conversation context above.",
|
|
24965
|
+
"Help with the side discussion without continuing or modifying the main task.",
|
|
24966
|
+
"No tools are available in this Side conversation.",
|
|
24967
|
+
...pendingRequest ? ["The main Agent is currently working on this request:", pendingRequest] : [],
|
|
24968
|
+
"Side question:",
|
|
24969
|
+
question
|
|
24970
|
+
].join("\n\n");
|
|
24971
|
+
}
|
|
24972
|
+
|
|
24973
|
+
// src/ui/conversation-workspace-runtime.ts
|
|
24974
|
+
var ConversationWorkspaceRuntime = class {
|
|
24975
|
+
constructor(main2, createSide) {
|
|
24976
|
+
this.main = main2;
|
|
24977
|
+
this.createSide = createSide;
|
|
24978
|
+
this.offMain = main2.subscribe(this.notify);
|
|
24979
|
+
this.workspaceSnapshot = this.createWorkspaceSnapshot();
|
|
24980
|
+
}
|
|
24981
|
+
listeners = /* @__PURE__ */ new Set();
|
|
24982
|
+
surfaceListeners = /* @__PURE__ */ new Set();
|
|
24983
|
+
offMain;
|
|
24984
|
+
side;
|
|
24985
|
+
offSide;
|
|
24986
|
+
activeSurface = "main";
|
|
24987
|
+
opening;
|
|
24988
|
+
closing;
|
|
24989
|
+
workspaceSnapshot;
|
|
24990
|
+
getSnapshot = () => this.current().getSnapshot();
|
|
24991
|
+
getSessionStats = () => this.current().getSessionStats();
|
|
24992
|
+
subscribe = (listener) => {
|
|
24993
|
+
this.listeners.add(listener);
|
|
24994
|
+
return () => this.listeners.delete(listener);
|
|
24995
|
+
};
|
|
24996
|
+
submit = (submission) => this.current().submit(submission);
|
|
24997
|
+
cancel = () => this.current().cancel();
|
|
24998
|
+
exit = () => this.main.exit();
|
|
24999
|
+
getWorkspaceSnapshot = () => this.workspaceSnapshot;
|
|
25000
|
+
subscribeWorkspace = this.subscribe;
|
|
25001
|
+
subscribeSurface = (listener) => {
|
|
25002
|
+
this.surfaceListeners.add(listener);
|
|
25003
|
+
return () => this.surfaceListeners.delete(listener);
|
|
25004
|
+
};
|
|
25005
|
+
open = async (question, signal) => {
|
|
25006
|
+
const normalized = question?.trim();
|
|
25007
|
+
let createdSide = false;
|
|
25008
|
+
if (this.closing) await this.closing;
|
|
25009
|
+
if (this.opening) throw new Error("A Side conversation is already opening.");
|
|
25010
|
+
if (this.side?.getSnapshot().busy && normalized) {
|
|
25011
|
+
this.switchToSide();
|
|
25012
|
+
throw new Error("The Side Agent is already working.");
|
|
25013
|
+
}
|
|
25014
|
+
if (!this.side) {
|
|
25015
|
+
const operation = this.createSide(signal).then(async (side) => {
|
|
25016
|
+
if (signal.aborted) {
|
|
25017
|
+
await side.dispose();
|
|
25018
|
+
signal.throwIfAborted();
|
|
25019
|
+
}
|
|
25020
|
+
this.side = side;
|
|
25021
|
+
createdSide = true;
|
|
25022
|
+
this.offSide = side.subscribe(this.notify);
|
|
25023
|
+
this.activeSurface = "side";
|
|
25024
|
+
this.notifySurface();
|
|
25025
|
+
});
|
|
25026
|
+
this.opening = operation;
|
|
25027
|
+
try {
|
|
25028
|
+
await operation;
|
|
25029
|
+
} finally {
|
|
25030
|
+
if (this.opening === operation) this.opening = void 0;
|
|
25031
|
+
}
|
|
25032
|
+
} else {
|
|
25033
|
+
this.switchToSide();
|
|
25034
|
+
}
|
|
25035
|
+
if (normalized) {
|
|
25036
|
+
try {
|
|
25037
|
+
await this.side?.submit({
|
|
25038
|
+
content: [{ type: "text", text: normalized }],
|
|
25039
|
+
displayContent: [{ type: "text", text: normalized }],
|
|
25040
|
+
signal
|
|
25041
|
+
});
|
|
25042
|
+
} catch (error) {
|
|
25043
|
+
if (createdSide) await this.closeSide();
|
|
25044
|
+
throw error;
|
|
25045
|
+
}
|
|
25046
|
+
}
|
|
25047
|
+
};
|
|
25048
|
+
switchToMain = () => {
|
|
25049
|
+
if (this.activeSurface === "main") return;
|
|
25050
|
+
this.activeSurface = "main";
|
|
25051
|
+
this.notifySurface();
|
|
25052
|
+
};
|
|
25053
|
+
switchToSide = () => {
|
|
25054
|
+
if (!this.side) throw new Error("No Side conversation is open. Use /btw <question> first.");
|
|
25055
|
+
if (this.activeSurface === "side") return;
|
|
25056
|
+
this.activeSurface = "side";
|
|
25057
|
+
this.notifySurface();
|
|
25058
|
+
};
|
|
25059
|
+
closeSide = async () => {
|
|
25060
|
+
if (this.closing) return this.closing;
|
|
25061
|
+
const side = this.side;
|
|
25062
|
+
if (!side) return;
|
|
25063
|
+
this.activeSurface = "main";
|
|
25064
|
+
this.side = void 0;
|
|
25065
|
+
this.offSide?.();
|
|
25066
|
+
this.offSide = void 0;
|
|
25067
|
+
this.notifySurface();
|
|
25068
|
+
const operation = side.dispose().finally(() => {
|
|
25069
|
+
if (this.closing === operation) this.closing = void 0;
|
|
25070
|
+
});
|
|
25071
|
+
this.closing = operation;
|
|
25072
|
+
await operation;
|
|
25073
|
+
};
|
|
25074
|
+
dispose = async () => {
|
|
25075
|
+
await this.closeSide();
|
|
25076
|
+
this.offMain();
|
|
25077
|
+
this.listeners.clear();
|
|
25078
|
+
this.surfaceListeners.clear();
|
|
25079
|
+
};
|
|
25080
|
+
current() {
|
|
25081
|
+
return this.activeSurface === "side" && this.side ? this.side : this.main;
|
|
25082
|
+
}
|
|
25083
|
+
createWorkspaceSnapshot() {
|
|
25084
|
+
return {
|
|
25085
|
+
activeSurface: this.activeSurface,
|
|
25086
|
+
mainBusy: this.main.getSnapshot().busy,
|
|
25087
|
+
sideBusy: this.side?.getSnapshot().busy ?? false,
|
|
25088
|
+
...this.side === void 0 ? {} : {
|
|
25089
|
+
sideSessionId: this.side.getSessionStats().sessionId,
|
|
25090
|
+
sideModelLabel: this.side.modelLabel,
|
|
25091
|
+
...this.side.reasoningEffortLabel === void 0 ? {} : {
|
|
25092
|
+
sideReasoningEffortLabel: this.side.reasoningEffortLabel
|
|
25093
|
+
}
|
|
25094
|
+
}
|
|
25095
|
+
};
|
|
25096
|
+
}
|
|
25097
|
+
notify = () => {
|
|
25098
|
+
this.workspaceSnapshot = this.createWorkspaceSnapshot();
|
|
25099
|
+
for (const listener of this.listeners) listener();
|
|
25100
|
+
};
|
|
25101
|
+
notifySurface = () => {
|
|
25102
|
+
this.notify();
|
|
25103
|
+
for (const listener of this.surfaceListeners) listener();
|
|
25104
|
+
};
|
|
25105
|
+
};
|
|
25106
|
+
|
|
24269
25107
|
// src/dsh/prompt-input-runtime.ts
|
|
24270
25108
|
import { promises as fs13 } from "node:fs";
|
|
24271
25109
|
import path14 from "node:path";
|
|
@@ -24878,9 +25716,9 @@ var DshModelSelectionRuntime = class _DshModelSelectionRuntime {
|
|
|
24878
25716
|
import { foldRequestHeader, SessionId as SessionId2 } from "@deepseek-ai/dsh-session";
|
|
24879
25717
|
var SESSION_PREFIX = "dsh-console-";
|
|
24880
25718
|
var COMPLETION_PREFIX = "dsh-console-completion-";
|
|
24881
|
-
var
|
|
25719
|
+
var SIDE_PREFIX = "dsh-console-side-";
|
|
24882
25720
|
function isConsoleSession(id) {
|
|
24883
|
-
return id.startsWith(SESSION_PREFIX) && !id.startsWith(COMPLETION_PREFIX);
|
|
25721
|
+
return id.startsWith(SESSION_PREFIX) && !id.startsWith(COMPLETION_PREFIX) && !id.startsWith(SIDE_PREFIX);
|
|
24884
25722
|
}
|
|
24885
25723
|
function hasConversationEvents(events) {
|
|
24886
25724
|
return events.some(
|
|
@@ -24911,62 +25749,23 @@ var DshSessionManagementRuntime = class {
|
|
|
24911
25749
|
{ kind: "parent", values: [null] }
|
|
24912
25750
|
], signal);
|
|
24913
25751
|
signal?.throwIfAborted();
|
|
24914
|
-
|
|
25752
|
+
return records.filter((record) => {
|
|
24915
25753
|
const id = String(record.header.id);
|
|
24916
25754
|
return isConsoleSession(id) && (record.persisted || id === this.snapshot.currentSessionId);
|
|
24917
|
-
})
|
|
24918
|
-
const observations = [];
|
|
24919
|
-
for (let offset = 0; offset < candidates.length; offset += SESSION_OBSERVATION_BATCH_SIZE) {
|
|
24920
|
-
signal?.throwIfAborted();
|
|
24921
|
-
const batch = candidates.slice(offset, offset + SESSION_OBSERVATION_BATCH_SIZE);
|
|
24922
|
-
observations.push(...await Promise.all(batch.map(async (record) => {
|
|
24923
|
-
if (!record.persisted) {
|
|
24924
|
-
return { record, hasConversation: false, resumable: false };
|
|
24925
|
-
}
|
|
24926
|
-
try {
|
|
24927
|
-
const events = await this.query.listEvents(record.header.id);
|
|
24928
|
-
return {
|
|
24929
|
-
record,
|
|
24930
|
-
hasConversation: hasConversationEvents(events),
|
|
24931
|
-
resumable: events.some((event) => event.type === "request/header")
|
|
24932
|
-
};
|
|
24933
|
-
} catch {
|
|
24934
|
-
return {
|
|
24935
|
-
record,
|
|
24936
|
-
hasConversation: true,
|
|
24937
|
-
resumable: false,
|
|
24938
|
-
resumeUnavailableReason: "Session log could not be read."
|
|
24939
|
-
};
|
|
24940
|
-
}
|
|
24941
|
-
})));
|
|
24942
|
-
}
|
|
24943
|
-
signal?.throwIfAborted();
|
|
24944
|
-
const visible = observations.filter(
|
|
24945
|
-
({ record, hasConversation, resumable }) => String(record.header.id) === this.snapshot.currentSessionId || hasConversation || resumable
|
|
24946
|
-
);
|
|
24947
|
-
const titles = await this.query.readTitleSnapshots(
|
|
24948
|
-
visible.map(({ record }) => record.header.id),
|
|
24949
|
-
signal
|
|
24950
|
-
);
|
|
24951
|
-
signal?.throwIfAborted();
|
|
24952
|
-
const titleById = /* @__PURE__ */ new Map();
|
|
24953
|
-
for (const result of titles) {
|
|
24954
|
-
if (result.status === "fulfilled" && result.value.title !== void 0) {
|
|
24955
|
-
titleById.set(String(result.sessionId), result.value.title.title);
|
|
24956
|
-
}
|
|
24957
|
-
}
|
|
24958
|
-
return visible.map(({ record, resumable, ...observation }) => ({
|
|
25755
|
+
}).map((record) => ({
|
|
24959
25756
|
id: String(record.header.id),
|
|
24960
|
-
...titleById.has(String(record.header.id)) ? { title: titleById.get(String(record.header.id)) } : {},
|
|
24961
25757
|
createdAt: record.header.createdAt,
|
|
24962
25758
|
current: String(record.header.id) === this.snapshot.currentSessionId,
|
|
24963
25759
|
persisted: record.persisted,
|
|
24964
|
-
resumable
|
|
24965
|
-
...!resumable && record.persisted ? {
|
|
24966
|
-
resumeUnavailableReason: "resumeUnavailableReason" in observation ? observation.resumeUnavailableReason : "Missing model route."
|
|
24967
|
-
} : {}
|
|
25760
|
+
resumable: record.persisted
|
|
24968
25761
|
}));
|
|
24969
25762
|
}
|
|
25763
|
+
async resolveSessionTitles(sessionIds, signal) {
|
|
25764
|
+
if (sessionIds.length === 0) return [];
|
|
25765
|
+
const results = await this.query.readTitleSnapshots(sessionIds.map(SessionId2), signal);
|
|
25766
|
+
signal?.throwIfAborted();
|
|
25767
|
+
return results.flatMap((result) => result.status === "fulfilled" && result.value.title ? [{ id: String(result.sessionId), title: result.value.title.title }] : []);
|
|
25768
|
+
}
|
|
24970
25769
|
async createNew(signal) {
|
|
24971
25770
|
this.beginSwitch();
|
|
24972
25771
|
try {
|
|
@@ -25277,8 +26076,15 @@ var DshCommandRuntimeAdapter = class {
|
|
|
25277
26076
|
return () => this.listeners.delete(listener);
|
|
25278
26077
|
};
|
|
25279
26078
|
async execute(line, signal) {
|
|
26079
|
+
const agent = this.activeAgent();
|
|
26080
|
+
if (agent === void 0) {
|
|
26081
|
+
return {
|
|
26082
|
+
kind: "error",
|
|
26083
|
+
text: "Start a conversation before using DSH commands."
|
|
26084
|
+
};
|
|
26085
|
+
}
|
|
25280
26086
|
const execution = await this.commands.execute(
|
|
25281
|
-
|
|
26087
|
+
agent,
|
|
25282
26088
|
line,
|
|
25283
26089
|
[],
|
|
25284
26090
|
signal
|
|
@@ -25299,9 +26105,11 @@ var DshCommandRuntimeAdapter = class {
|
|
|
25299
26105
|
this.listeners.clear();
|
|
25300
26106
|
}
|
|
25301
26107
|
readSnapshot() {
|
|
26108
|
+
const agent = this.activeAgent();
|
|
26109
|
+
if (agent === void 0) return Object.freeze({ commands: Object.freeze([]) });
|
|
25302
26110
|
return Object.freeze({
|
|
25303
26111
|
commands: Object.freeze(
|
|
25304
|
-
this.commands.list(
|
|
26112
|
+
this.commands.list(agent).map(
|
|
25305
26113
|
(command) => Object.freeze({
|
|
25306
26114
|
name: command.name,
|
|
25307
26115
|
description: command.description,
|
|
@@ -25373,7 +26181,9 @@ var DshToolCatalogRuntime = class {
|
|
|
25373
26181
|
this.listeners.clear();
|
|
25374
26182
|
}
|
|
25375
26183
|
readSnapshot() {
|
|
25376
|
-
const
|
|
26184
|
+
const agent = this.activeAgent();
|
|
26185
|
+
if (agent === void 0) return Object.freeze({ tools: Object.freeze([]) });
|
|
26186
|
+
const schemas = this.tools.schemas(agent);
|
|
25377
26187
|
const catalog = schemas.map(projectTool).sort((left, right) => left.name.localeCompare(right.name));
|
|
25378
26188
|
return Object.freeze({ tools: Object.freeze(catalog) });
|
|
25379
26189
|
}
|
|
@@ -25393,7 +26203,8 @@ var DshPermissionSelectionRuntime = class {
|
|
|
25393
26203
|
this.activeAgent = activeAgent;
|
|
25394
26204
|
this.snapshot = this.readSnapshot(false);
|
|
25395
26205
|
this.offProjection = projections.onChanged((session, key) => {
|
|
25396
|
-
|
|
26206
|
+
const agent = this.activeAgent();
|
|
26207
|
+
if (agent === void 0 || session !== agent.session || key !== "permissions") return;
|
|
25397
26208
|
this.refresh();
|
|
25398
26209
|
});
|
|
25399
26210
|
}
|
|
@@ -25444,9 +26255,11 @@ var DshPermissionSelectionRuntime = class {
|
|
|
25444
26255
|
this.listeners.clear();
|
|
25445
26256
|
}
|
|
25446
26257
|
readSnapshot(busy) {
|
|
25447
|
-
const
|
|
25448
|
-
|
|
25449
|
-
|
|
26258
|
+
const agent = this.activeAgent();
|
|
26259
|
+
if (agent === void 0) {
|
|
26260
|
+
return Object.freeze({ available: false, options: Object.freeze([]), busy });
|
|
26261
|
+
}
|
|
26262
|
+
const selection = this.projections.snapshot(agent.session).values.permissions;
|
|
25450
26263
|
if (!selection) {
|
|
25451
26264
|
return Object.freeze({ available: false, options: Object.freeze([]), busy });
|
|
25452
26265
|
}
|
|
@@ -25644,6 +26457,211 @@ var DshProviderSetupRuntime = class _DshProviderSetupRuntime {
|
|
|
25644
26457
|
}
|
|
25645
26458
|
};
|
|
25646
26459
|
|
|
26460
|
+
// src/dsh/subagent-catalog-runtime.ts
|
|
26461
|
+
import { SessionId as SessionId3 } from "@deepseek-ai/dsh-session";
|
|
26462
|
+
|
|
26463
|
+
// src/dsh/subagent-transcript-runtime.ts
|
|
26464
|
+
function cancelled() {
|
|
26465
|
+
return new DOMException("Subagent transcript loading was cancelled.", "AbortError");
|
|
26466
|
+
}
|
|
26467
|
+
var DshSubagentTranscriptRuntime = class _DshSubagentTranscriptRuntime {
|
|
26468
|
+
constructor(projector, off) {
|
|
26469
|
+
this.projector = projector;
|
|
26470
|
+
this.off = off;
|
|
26471
|
+
}
|
|
26472
|
+
static async create(query, sessionId, presenter, subscribeToSession, signal) {
|
|
26473
|
+
signal?.throwIfAborted();
|
|
26474
|
+
const projector = new DshSessionProjector(
|
|
26475
|
+
String(sessionId),
|
|
26476
|
+
"subagent",
|
|
26477
|
+
presenter
|
|
26478
|
+
);
|
|
26479
|
+
const buffered = [];
|
|
26480
|
+
let replaying = true;
|
|
26481
|
+
const off = subscribeToSession(sessionId, (event) => {
|
|
26482
|
+
if (replaying) buffered.push(event);
|
|
26483
|
+
else projector.project(event);
|
|
26484
|
+
});
|
|
26485
|
+
try {
|
|
26486
|
+
const log = await query.readSession(sessionId);
|
|
26487
|
+
if (signal?.aborted) throw cancelled();
|
|
26488
|
+
projector.replay(log.events);
|
|
26489
|
+
const replayedSeq = log.events.at(-1)?.seq ?? -1;
|
|
26490
|
+
for (const event of buffered) {
|
|
26491
|
+
if (event.seq > replayedSeq) projector.project(event);
|
|
26492
|
+
}
|
|
26493
|
+
replaying = false;
|
|
26494
|
+
return new _DshSubagentTranscriptRuntime(projector, off);
|
|
26495
|
+
} catch (error) {
|
|
26496
|
+
off();
|
|
26497
|
+
throw error;
|
|
26498
|
+
}
|
|
26499
|
+
}
|
|
26500
|
+
disposed = false;
|
|
26501
|
+
getSnapshot = () => this.projector.getSnapshot();
|
|
26502
|
+
subscribe = (listener) => this.projector.subscribe(listener);
|
|
26503
|
+
dispose() {
|
|
26504
|
+
if (this.disposed) return;
|
|
26505
|
+
this.disposed = true;
|
|
26506
|
+
this.off();
|
|
26507
|
+
}
|
|
26508
|
+
};
|
|
26509
|
+
|
|
26510
|
+
// src/dsh/subagent-catalog-runtime.ts
|
|
26511
|
+
function fallbackLabel(id) {
|
|
26512
|
+
return `Agent ${String(id).slice(-8)}`;
|
|
26513
|
+
}
|
|
26514
|
+
function projectEntry(entry) {
|
|
26515
|
+
if (entry.kind === "diagnostic") {
|
|
26516
|
+
return Object.freeze({
|
|
26517
|
+
kind: "diagnostic",
|
|
26518
|
+
id: String(entry.id),
|
|
26519
|
+
parentId: String(entry.parentId),
|
|
26520
|
+
depth: entry.depth,
|
|
26521
|
+
reason: entry.reason
|
|
26522
|
+
});
|
|
26523
|
+
}
|
|
26524
|
+
return Object.freeze({
|
|
26525
|
+
kind: "agent",
|
|
26526
|
+
id: String(entry.id),
|
|
26527
|
+
parentId: String(entry.parentId),
|
|
26528
|
+
depth: entry.depth,
|
|
26529
|
+
label: entry.label?.trim() || fallbackLabel(entry.id),
|
|
26530
|
+
mode: entry.mode,
|
|
26531
|
+
activity: entry.activity,
|
|
26532
|
+
hasChildren: entry.hasChildren
|
|
26533
|
+
});
|
|
26534
|
+
}
|
|
26535
|
+
function isAbort(error, signal) {
|
|
26536
|
+
return signal?.aborted === true || error instanceof Error && error.name === "AbortError";
|
|
26537
|
+
}
|
|
26538
|
+
var DshSubagentCatalogRuntime = class {
|
|
26539
|
+
constructor(subagents, rootSessionId, subscribeToChanges, query, presenter, subscribeToSession) {
|
|
26540
|
+
this.subagents = subagents;
|
|
26541
|
+
this.rootSessionId = rootSessionId;
|
|
26542
|
+
this.query = query;
|
|
26543
|
+
this.presenter = presenter;
|
|
26544
|
+
this.subscribeToSession = subscribeToSession;
|
|
26545
|
+
this.snapshot = Object.freeze({
|
|
26546
|
+
rootSessionId: String(rootSessionId() ?? ""),
|
|
26547
|
+
status: "idle",
|
|
26548
|
+
items: Object.freeze([]),
|
|
26549
|
+
runningCount: 0
|
|
26550
|
+
});
|
|
26551
|
+
this.off = subscribeToChanges(() => this.queueRefresh());
|
|
26552
|
+
this.queueRefresh();
|
|
26553
|
+
}
|
|
26554
|
+
listeners = /* @__PURE__ */ new Set();
|
|
26555
|
+
snapshot;
|
|
26556
|
+
off;
|
|
26557
|
+
generation = 0;
|
|
26558
|
+
refreshQueued = false;
|
|
26559
|
+
disposed = false;
|
|
26560
|
+
refreshController;
|
|
26561
|
+
getSnapshot = () => this.snapshot;
|
|
26562
|
+
subscribe = (listener) => {
|
|
26563
|
+
this.listeners.add(listener);
|
|
26564
|
+
return () => this.listeners.delete(listener);
|
|
26565
|
+
};
|
|
26566
|
+
async openTranscript(sessionId, signal) {
|
|
26567
|
+
const item = this.snapshot.items.find(
|
|
26568
|
+
(candidate) => candidate.id === sessionId && candidate.kind === "agent"
|
|
26569
|
+
);
|
|
26570
|
+
if (item === void 0) {
|
|
26571
|
+
throw new Error("The selected subagent is no longer available.");
|
|
26572
|
+
}
|
|
26573
|
+
return DshSubagentTranscriptRuntime.create(
|
|
26574
|
+
this.query,
|
|
26575
|
+
SessionId3(sessionId),
|
|
26576
|
+
this.presenter,
|
|
26577
|
+
this.subscribeToSession,
|
|
26578
|
+
signal
|
|
26579
|
+
);
|
|
26580
|
+
}
|
|
26581
|
+
async refresh(signal) {
|
|
26582
|
+
if (this.disposed || signal?.aborted) return;
|
|
26583
|
+
this.refreshController?.abort();
|
|
26584
|
+
const controller = new AbortController();
|
|
26585
|
+
this.refreshController = controller;
|
|
26586
|
+
const refreshSignal = signal === void 0 ? controller.signal : AbortSignal.any([signal, controller.signal]);
|
|
26587
|
+
const generation = ++this.generation;
|
|
26588
|
+
const rootSessionId = this.rootSessionId();
|
|
26589
|
+
if (rootSessionId === void 0) {
|
|
26590
|
+
this.publish({
|
|
26591
|
+
rootSessionId: "",
|
|
26592
|
+
status: "idle",
|
|
26593
|
+
items: Object.freeze([]),
|
|
26594
|
+
runningCount: 0
|
|
26595
|
+
});
|
|
26596
|
+
return;
|
|
26597
|
+
}
|
|
26598
|
+
this.publish({
|
|
26599
|
+
...this.snapshot,
|
|
26600
|
+
rootSessionId: String(rootSessionId),
|
|
26601
|
+
status: "loading",
|
|
26602
|
+
error: void 0
|
|
26603
|
+
});
|
|
26604
|
+
try {
|
|
26605
|
+
const entries = await this.subagents.listDescendants(rootSessionId, refreshSignal);
|
|
26606
|
+
if (this.disposed || refreshSignal.aborted || generation !== this.generation) return;
|
|
26607
|
+
const items = Object.freeze(entries.map(projectEntry));
|
|
26608
|
+
this.publish({
|
|
26609
|
+
rootSessionId: String(rootSessionId),
|
|
26610
|
+
status: "ready",
|
|
26611
|
+
items,
|
|
26612
|
+
runningCount: items.filter(
|
|
26613
|
+
(item) => item.kind === "agent" && item.activity === "running"
|
|
26614
|
+
).length
|
|
26615
|
+
});
|
|
26616
|
+
} catch (error) {
|
|
26617
|
+
if (this.disposed || generation !== this.generation || isAbort(error, refreshSignal)) return;
|
|
26618
|
+
debugLogger.debug(`Unable to list DSH subagents: ${String(error)}`);
|
|
26619
|
+
this.publish({
|
|
26620
|
+
...this.snapshot,
|
|
26621
|
+
rootSessionId: String(rootSessionId),
|
|
26622
|
+
status: "error",
|
|
26623
|
+
error: "Unable to load the Agent catalog."
|
|
26624
|
+
});
|
|
26625
|
+
} finally {
|
|
26626
|
+
if (this.refreshController === controller) this.refreshController = void 0;
|
|
26627
|
+
}
|
|
26628
|
+
}
|
|
26629
|
+
activeAgentChanged() {
|
|
26630
|
+
this.refreshController?.abort();
|
|
26631
|
+
this.refreshController = void 0;
|
|
26632
|
+
this.generation += 1;
|
|
26633
|
+
this.publish({
|
|
26634
|
+
rootSessionId: String(this.rootSessionId() ?? ""),
|
|
26635
|
+
status: "idle",
|
|
26636
|
+
items: Object.freeze([]),
|
|
26637
|
+
runningCount: 0
|
|
26638
|
+
});
|
|
26639
|
+
this.queueRefresh();
|
|
26640
|
+
}
|
|
26641
|
+
dispose() {
|
|
26642
|
+
if (this.disposed) return;
|
|
26643
|
+
this.disposed = true;
|
|
26644
|
+
this.refreshController?.abort();
|
|
26645
|
+
this.refreshController = void 0;
|
|
26646
|
+
this.generation += 1;
|
|
26647
|
+
this.off();
|
|
26648
|
+
this.listeners.clear();
|
|
26649
|
+
}
|
|
26650
|
+
queueRefresh() {
|
|
26651
|
+
if (this.disposed || this.refreshQueued) return;
|
|
26652
|
+
this.refreshQueued = true;
|
|
26653
|
+
queueMicrotask(() => {
|
|
26654
|
+
this.refreshQueued = false;
|
|
26655
|
+
if (this.disposed) return;
|
|
26656
|
+
void this.refresh();
|
|
26657
|
+
});
|
|
26658
|
+
}
|
|
26659
|
+
publish(snapshot) {
|
|
26660
|
+
this.snapshot = Object.freeze(snapshot);
|
|
26661
|
+
for (const listener of this.listeners) listener();
|
|
26662
|
+
}
|
|
26663
|
+
};
|
|
26664
|
+
|
|
25647
26665
|
// src/dsh/index.ts
|
|
25648
26666
|
var name = "dsh-console-runner";
|
|
25649
26667
|
var inject = [
|
|
@@ -25659,11 +26677,13 @@ var inject = [
|
|
|
25659
26677
|
"commands",
|
|
25660
26678
|
"sessionProjections",
|
|
25661
26679
|
"credentials",
|
|
25662
|
-
"settings"
|
|
26680
|
+
"settings",
|
|
26681
|
+
"subagents"
|
|
25663
26682
|
];
|
|
25664
26683
|
var Config2 = z2.object({
|
|
25665
26684
|
prompt: z2.string(),
|
|
25666
|
-
debug: z2.boolean().default(false)
|
|
26685
|
+
debug: z2.boolean().default(false),
|
|
26686
|
+
pokemon: z2.number()
|
|
25667
26687
|
});
|
|
25668
26688
|
var CLEANUP_TIMEOUT_MS = 1500;
|
|
25669
26689
|
var FORCE_EXIT_TIMEOUT_MS = 2500;
|
|
@@ -25686,6 +26706,7 @@ async function start(ctx, config) {
|
|
|
25686
26706
|
const appExit = ctx.get("appExit");
|
|
25687
26707
|
const credentials = ctx.get("credentials");
|
|
25688
26708
|
const settings = ctx.get("settings");
|
|
26709
|
+
const subagents = ctx.get("subagents");
|
|
25689
26710
|
if (!attachments)
|
|
25690
26711
|
throw new Error("dsh-console requires the DSH attachment service");
|
|
25691
26712
|
if (!sessionQuery)
|
|
@@ -25702,10 +26723,14 @@ async function start(ctx, config) {
|
|
|
25702
26723
|
throw new Error("dsh-console requires the DSH credentials service");
|
|
25703
26724
|
if (!settings)
|
|
25704
26725
|
throw new Error("dsh-console requires the DSH settings service");
|
|
26726
|
+
if (!subagents)
|
|
26727
|
+
throw new Error("dsh-console requires the DSH subagent service");
|
|
25705
26728
|
if (!agents || !defaultModel || !sessions || !tools || !llm || !appExit)
|
|
25706
26729
|
return;
|
|
25707
26730
|
const selection = defaultModel.currentSelection();
|
|
25708
26731
|
let activeSelection = selection;
|
|
26732
|
+
let sideSelection;
|
|
26733
|
+
const workspaceRef = {};
|
|
25709
26734
|
const runtimeListeners = /* @__PURE__ */ new Set();
|
|
25710
26735
|
const notifyRuntime = () => {
|
|
25711
26736
|
for (const listener of runtimeListeners) listener();
|
|
@@ -25715,7 +26740,7 @@ async function start(ctx, config) {
|
|
|
25715
26740
|
createAgent: (options) => agents.create(options),
|
|
25716
26741
|
onSessionEvent: (listener) => ctx.on("session/event", listener)
|
|
25717
26742
|
},
|
|
25718
|
-
() => activeSelection
|
|
26743
|
+
() => workspaceRef.current?.getWorkspaceSnapshot().activeSurface === "side" ? sideSelection ?? activeSelection : activeSelection
|
|
25719
26744
|
);
|
|
25720
26745
|
const promptInputRuntime = new WorkspacePromptInputRuntime();
|
|
25721
26746
|
const attachmentInput = new DshAttachmentInputAdapter(attachments);
|
|
@@ -25737,10 +26762,16 @@ async function start(ctx, config) {
|
|
|
25737
26762
|
assembled: void 0
|
|
25738
26763
|
};
|
|
25739
26764
|
installModelSelection2(agentCtx, ref);
|
|
26765
|
+
if (options.restrictTools) agentCtx.tools.restrict({ allow: [] });
|
|
25740
26766
|
};
|
|
25741
26767
|
const handle = options.resumeSessionId === void 0 ? await agents.create({
|
|
25742
|
-
sessionId:
|
|
25743
|
-
meta: {
|
|
26768
|
+
sessionId: options.sessionId ?? SessionId4(`dsh-console-${randomUUID3()}`),
|
|
26769
|
+
meta: {
|
|
26770
|
+
cwd: process.cwd(),
|
|
26771
|
+
...options.parentSession === void 0 ? {} : { parentSession: options.parentSession },
|
|
26772
|
+
...options.seed === void 0 ? {} : { seedLength: options.seed.length }
|
|
26773
|
+
},
|
|
26774
|
+
...options.seed === void 0 ? {} : { seed: options.seed },
|
|
25744
26775
|
agentOptions,
|
|
25745
26776
|
setup,
|
|
25746
26777
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
@@ -25774,8 +26805,15 @@ async function start(ctx, config) {
|
|
|
25774
26805
|
}
|
|
25775
26806
|
}
|
|
25776
26807
|
);
|
|
25777
|
-
const offProjector =
|
|
25778
|
-
|
|
26808
|
+
const offProjector = options.publishRuntimeEvents === false ? () => {
|
|
26809
|
+
} : projector.subscribe(notifyRuntime);
|
|
26810
|
+
return {
|
|
26811
|
+
kind: "materialized",
|
|
26812
|
+
handle,
|
|
26813
|
+
projector,
|
|
26814
|
+
offSession,
|
|
26815
|
+
offProjector
|
|
26816
|
+
};
|
|
25779
26817
|
} catch (error) {
|
|
25780
26818
|
offSession?.();
|
|
25781
26819
|
try {
|
|
@@ -25788,7 +26826,29 @@ async function start(ctx, config) {
|
|
|
25788
26826
|
throw error;
|
|
25789
26827
|
}
|
|
25790
26828
|
};
|
|
25791
|
-
|
|
26829
|
+
const createPendingConversation = async (selected, signal) => {
|
|
26830
|
+
const modelInfo = await llm.resolveModelInfo(
|
|
26831
|
+
selected.provider,
|
|
26832
|
+
selected.model,
|
|
26833
|
+
signal
|
|
26834
|
+
);
|
|
26835
|
+
signal?.throwIfAborted();
|
|
26836
|
+
const projector = new DshSessionProjector(
|
|
26837
|
+
`dsh-console-pending-${randomUUID3()}`,
|
|
26838
|
+
String(selected.model),
|
|
26839
|
+
new DshToolPresentationAdapter(tools),
|
|
26840
|
+
modelInfo.context?.contextWindow
|
|
26841
|
+
);
|
|
26842
|
+
return {
|
|
26843
|
+
kind: "pending",
|
|
26844
|
+
projector,
|
|
26845
|
+
offProjector: projector.subscribe(notifyRuntime)
|
|
26846
|
+
};
|
|
26847
|
+
};
|
|
26848
|
+
let active = await createPendingConversation(selection);
|
|
26849
|
+
let visibleSideAgent;
|
|
26850
|
+
const mainAgent = () => active.kind === "materialized" ? active.handle.agent : void 0;
|
|
26851
|
+
const currentInteractiveAgent = () => workspaceRef.current?.getWorkspaceSnapshot().activeSurface === "side" && visibleSideAgent ? visibleSideAgent : mainAgent();
|
|
25792
26852
|
const providerSetupRuntime = await DshProviderSetupRuntime.create(
|
|
25793
26853
|
credentials,
|
|
25794
26854
|
settings,
|
|
@@ -25797,27 +26857,48 @@ async function start(ctx, config) {
|
|
|
25797
26857
|
);
|
|
25798
26858
|
const approvalRuntime = new DshApprovalRuntime(
|
|
25799
26859
|
(listener) => ctx.on("approval/request", listener),
|
|
25800
|
-
(agent) => agent ===
|
|
26860
|
+
(agent) => agent === mainAgent()
|
|
25801
26861
|
);
|
|
25802
26862
|
const userQuestionRuntime = new DshUserQuestionRuntime(
|
|
25803
26863
|
userQuestions,
|
|
25804
|
-
(agent) => agent ===
|
|
26864
|
+
(agent) => agent === mainAgent()
|
|
25805
26865
|
);
|
|
25806
26866
|
const commandRuntime = new DshCommandRuntimeAdapter(
|
|
25807
26867
|
commands,
|
|
25808
|
-
|
|
26868
|
+
currentInteractiveAgent,
|
|
25809
26869
|
(listener) => ctx.on("commands/change", listener)
|
|
25810
26870
|
);
|
|
25811
26871
|
const permissionSelectionRuntime = new DshPermissionSelectionRuntime(
|
|
25812
26872
|
sessionProjections,
|
|
25813
26873
|
commandRuntime,
|
|
25814
|
-
|
|
26874
|
+
currentInteractiveAgent
|
|
25815
26875
|
);
|
|
25816
26876
|
const toolCatalogRuntime = new DshToolCatalogRuntime(
|
|
25817
26877
|
tools,
|
|
25818
|
-
|
|
26878
|
+
currentInteractiveAgent,
|
|
25819
26879
|
(listener) => ctx.on("tools/change", listener)
|
|
25820
26880
|
);
|
|
26881
|
+
const subagentCatalogRuntime = new DshSubagentCatalogRuntime(
|
|
26882
|
+
subagents,
|
|
26883
|
+
() => mainAgent()?.session.id,
|
|
26884
|
+
(listener) => {
|
|
26885
|
+
const offStart = ctx.on("subagent/start", () => listener());
|
|
26886
|
+
const offEnd = ctx.on("subagent/end", () => listener());
|
|
26887
|
+
const offDescriptor = ctx.on("session/event", (_session, event) => {
|
|
26888
|
+
if (event.type === "subagent/descriptor") listener();
|
|
26889
|
+
});
|
|
26890
|
+
return () => {
|
|
26891
|
+
offStart();
|
|
26892
|
+
offEnd();
|
|
26893
|
+
offDescriptor();
|
|
26894
|
+
};
|
|
26895
|
+
},
|
|
26896
|
+
sessionQuery,
|
|
26897
|
+
new DshToolPresentationAdapter(tools),
|
|
26898
|
+
(sessionId, listener) => ctx.on("session/event", (session, event) => {
|
|
26899
|
+
if (session.id === sessionId) listener(event);
|
|
26900
|
+
})
|
|
26901
|
+
);
|
|
25821
26902
|
let switchingConversation = false;
|
|
25822
26903
|
const isConversationBusy = () => switchingConversation || active.projector.getSnapshot().busy || approvalRuntime.getSnapshot().pending.length > 0 || userQuestionRuntime.getSnapshot().pending.length > 0 || permissionSelectionRuntime.getSnapshot().busy;
|
|
25823
26904
|
const switchActiveConversation = async (selected, options = {}) => {
|
|
@@ -25831,39 +26912,46 @@ async function start(ctx, config) {
|
|
|
25831
26912
|
}
|
|
25832
26913
|
switchingConversation = true;
|
|
25833
26914
|
try {
|
|
25834
|
-
const next = await createActiveConversation(selected, options);
|
|
26915
|
+
const next = options.resumeSessionId === void 0 ? await createPendingConversation(selected, options.signal) : await createActiveConversation(selected, options);
|
|
25835
26916
|
const previous = active;
|
|
25836
|
-
|
|
25837
|
-
const flushed = await sessions.flush(previous.handle.agent.session);
|
|
25838
|
-
if (!flushed)
|
|
25839
|
-
throw new Error("DSH Session persistence is unavailable.");
|
|
25840
|
-
} catch (error) {
|
|
25841
|
-
next.offSession();
|
|
25842
|
-
next.offProjector();
|
|
26917
|
+
if (previous.kind === "materialized") {
|
|
25843
26918
|
try {
|
|
25844
|
-
await
|
|
25845
|
-
|
|
25846
|
-
|
|
25847
|
-
|
|
25848
|
-
);
|
|
26919
|
+
const flushed = await sessions.flush(previous.handle.agent.session);
|
|
26920
|
+
if (!flushed)
|
|
26921
|
+
throw new Error("DSH Session persistence is unavailable.");
|
|
26922
|
+
} catch (error) {
|
|
26923
|
+
next.offProjector();
|
|
26924
|
+
if (next.kind === "materialized") {
|
|
26925
|
+
next.offSession();
|
|
26926
|
+
try {
|
|
26927
|
+
await next.handle.dispose();
|
|
26928
|
+
} catch (disposeError) {
|
|
26929
|
+
debugLogger.debug(
|
|
26930
|
+
`Unable to dispose an uncommitted DSH Agent candidate: ${String(disposeError)}`
|
|
26931
|
+
);
|
|
26932
|
+
}
|
|
26933
|
+
}
|
|
26934
|
+
throw error;
|
|
25849
26935
|
}
|
|
25850
|
-
throw error;
|
|
25851
26936
|
}
|
|
25852
|
-
previous.offSession();
|
|
25853
26937
|
previous.offProjector();
|
|
26938
|
+
if (previous.kind === "materialized") previous.offSession();
|
|
25854
26939
|
active = next;
|
|
25855
26940
|
activeSelection = selected;
|
|
25856
26941
|
await providerSetupRuntime.refreshCurrent();
|
|
25857
26942
|
commandRuntime.activeAgentChanged();
|
|
25858
26943
|
permissionSelectionRuntime.activeAgentChanged();
|
|
25859
26944
|
toolCatalogRuntime.activeAgentChanged();
|
|
26945
|
+
subagentCatalogRuntime.activeAgentChanged();
|
|
25860
26946
|
notifyRuntime();
|
|
25861
|
-
|
|
25862
|
-
|
|
25863
|
-
|
|
25864
|
-
|
|
25865
|
-
|
|
25866
|
-
|
|
26947
|
+
if (previous.kind === "materialized") {
|
|
26948
|
+
try {
|
|
26949
|
+
await previous.handle.dispose();
|
|
26950
|
+
} catch (error) {
|
|
26951
|
+
debugLogger.debug(
|
|
26952
|
+
`Unable to dispose the previous DSH Agent: ${String(error)}`
|
|
26953
|
+
);
|
|
26954
|
+
}
|
|
25867
26955
|
}
|
|
25868
26956
|
} finally {
|
|
25869
26957
|
switchingConversation = false;
|
|
@@ -25879,19 +26967,19 @@ async function start(ctx, config) {
|
|
|
25879
26967
|
sessionQuery,
|
|
25880
26968
|
llm,
|
|
25881
26969
|
process.cwd(),
|
|
25882
|
-
|
|
26970
|
+
active.projector.getSessionStats().sessionId,
|
|
25883
26971
|
{
|
|
25884
26972
|
currentSelection: () => modelSelectionRuntime.getSnapshot().current,
|
|
25885
26973
|
createFresh: async (selected, signal) => {
|
|
25886
26974
|
await switchActiveConversation(selected, { signal });
|
|
25887
|
-
return
|
|
26975
|
+
return active.projector.getSessionStats().sessionId;
|
|
25888
26976
|
},
|
|
25889
26977
|
resume: async (sessionId, selected, signal) => {
|
|
25890
26978
|
await switchActiveConversation(selected, {
|
|
25891
26979
|
resumeSessionId: sessionId,
|
|
25892
26980
|
signal
|
|
25893
26981
|
});
|
|
25894
|
-
return
|
|
26982
|
+
return active.projector.getSessionStats().sessionId;
|
|
25895
26983
|
},
|
|
25896
26984
|
adoptCurrentModel: (selected) => modelSelectionRuntime.adoptCurrent(selected),
|
|
25897
26985
|
hasConversation: () => active.projector.getSnapshot().messages.length > 0,
|
|
@@ -25900,37 +26988,74 @@ async function start(ctx, config) {
|
|
|
25900
26988
|
);
|
|
25901
26989
|
let disposed = false;
|
|
25902
26990
|
let exiting = false;
|
|
26991
|
+
let offWorkspaceSurface = () => {
|
|
26992
|
+
};
|
|
25903
26993
|
const cleanup = async () => {
|
|
25904
26994
|
if (disposed) return;
|
|
25905
26995
|
disposed = true;
|
|
25906
|
-
|
|
26996
|
+
offWorkspaceSurface();
|
|
25907
26997
|
active.offProjector();
|
|
26998
|
+
if (active.kind === "materialized") active.offSession();
|
|
25908
26999
|
await Promise.all([
|
|
25909
|
-
active.handle.dispose(),
|
|
27000
|
+
active.kind === "materialized" ? active.handle.dispose() : Promise.resolve(),
|
|
25910
27001
|
promptCompletionRuntime.dispose(),
|
|
27002
|
+
workspaceRef.current?.dispose(),
|
|
25911
27003
|
promptInputRuntime.dispose(),
|
|
25912
27004
|
Promise.resolve(approvalRuntime.dispose()),
|
|
25913
27005
|
Promise.resolve(userQuestionRuntime.dispose()),
|
|
25914
27006
|
Promise.resolve(commandRuntime.dispose()),
|
|
25915
27007
|
Promise.resolve(permissionSelectionRuntime.dispose()),
|
|
25916
|
-
Promise.resolve(toolCatalogRuntime.dispose())
|
|
27008
|
+
Promise.resolve(toolCatalogRuntime.dispose()),
|
|
27009
|
+
Promise.resolve(subagentCatalogRuntime.dispose())
|
|
25917
27010
|
]);
|
|
25918
27011
|
};
|
|
25919
|
-
const
|
|
25920
|
-
|
|
25921
|
-
|
|
25922
|
-
|
|
25923
|
-
|
|
25924
|
-
|
|
25925
|
-
|
|
27012
|
+
const materializeActiveConversation = async (signal) => {
|
|
27013
|
+
if (active.kind === "materialized") return active;
|
|
27014
|
+
if (switchingConversation) {
|
|
27015
|
+
throw new Error("Another Agent change is already in progress.");
|
|
27016
|
+
}
|
|
27017
|
+
switchingConversation = true;
|
|
27018
|
+
const previous = active;
|
|
27019
|
+
let next;
|
|
27020
|
+
try {
|
|
27021
|
+
next = await createActiveConversation(activeSelection, { signal });
|
|
27022
|
+
signal.throwIfAborted();
|
|
27023
|
+
previous.offProjector();
|
|
27024
|
+
active = next;
|
|
27025
|
+
commandRuntime.activeAgentChanged();
|
|
27026
|
+
permissionSelectionRuntime.activeAgentChanged();
|
|
27027
|
+
toolCatalogRuntime.activeAgentChanged();
|
|
27028
|
+
subagentCatalogRuntime.activeAgentChanged();
|
|
27029
|
+
notifyRuntime();
|
|
27030
|
+
return next;
|
|
27031
|
+
} catch (error) {
|
|
27032
|
+
if (next !== void 0 && active !== next) {
|
|
27033
|
+
next.offSession();
|
|
27034
|
+
next.offProjector();
|
|
27035
|
+
await next.handle.dispose().catch((disposeError) => {
|
|
27036
|
+
debugLogger.debug(
|
|
27037
|
+
`Unable to dispose an aborted DSH Agent candidate: ${String(disposeError)}`
|
|
27038
|
+
);
|
|
27039
|
+
});
|
|
27040
|
+
}
|
|
27041
|
+
throw error;
|
|
27042
|
+
} finally {
|
|
27043
|
+
switchingConversation = false;
|
|
27044
|
+
}
|
|
27045
|
+
};
|
|
27046
|
+
const prepareSubmission = async ({ content, displayContent, signal }, allowImages) => {
|
|
25926
27047
|
if (content.some((part) => part.type === "image-source")) {
|
|
27048
|
+
if (!allowImages) {
|
|
27049
|
+
throw new Error(
|
|
27050
|
+
"Side conversations currently support text input only."
|
|
27051
|
+
);
|
|
27052
|
+
}
|
|
25927
27053
|
await modelSelectionRuntime.assertCurrentSupportsImages(signal);
|
|
25928
27054
|
}
|
|
25929
|
-
|
|
25930
|
-
|
|
25931
|
-
|
|
25932
|
-
|
|
25933
|
-
);
|
|
27055
|
+
return attachmentInput.ingest(content, displayContent, signal);
|
|
27056
|
+
};
|
|
27057
|
+
const submitToConversation = async (conversation, ingested, signal) => {
|
|
27058
|
+
if (conversation.projector.getSnapshot().busy) return;
|
|
25934
27059
|
signal.throwIfAborted();
|
|
25935
27060
|
conversation.projector.addUser(
|
|
25936
27061
|
projectDshContent(ingested.content),
|
|
@@ -25970,23 +27095,114 @@ async function start(ctx, config) {
|
|
|
25970
27095
|
});
|
|
25971
27096
|
void Promise.race([runExitCleanup(), cleanupTimeout]).then(cleanup).finally(() => appExit(0));
|
|
25972
27097
|
};
|
|
25973
|
-
const
|
|
27098
|
+
const mainConversationRuntime = {
|
|
25974
27099
|
getSnapshot: () => active.projector.getSnapshot(),
|
|
25975
27100
|
getSessionStats: () => active.projector.getSessionStats(),
|
|
25976
27101
|
subscribe: (listener) => {
|
|
25977
27102
|
runtimeListeners.add(listener);
|
|
25978
27103
|
return () => runtimeListeners.delete(listener);
|
|
25979
27104
|
},
|
|
25980
|
-
submit
|
|
27105
|
+
submit: async (submission) => {
|
|
27106
|
+
const ingested = await prepareSubmission(submission, true);
|
|
27107
|
+
const conversation = await materializeActiveConversation(submission.signal);
|
|
27108
|
+
await submitToConversation(conversation, ingested, submission.signal);
|
|
27109
|
+
},
|
|
25981
27110
|
cancel: () => {
|
|
25982
|
-
active.
|
|
25983
|
-
|
|
27111
|
+
if (active.kind === "materialized") {
|
|
27112
|
+
active.handle.agent.cancel({ kind: "user" });
|
|
27113
|
+
active.projector.cancel();
|
|
27114
|
+
}
|
|
25984
27115
|
},
|
|
25985
27116
|
exit
|
|
25986
27117
|
};
|
|
27118
|
+
const conversationWorkspace = new ConversationWorkspaceRuntime(
|
|
27119
|
+
mainConversationRuntime,
|
|
27120
|
+
async (signal) => {
|
|
27121
|
+
if (active.kind !== "materialized") {
|
|
27122
|
+
throw new Error("Start the main conversation before opening a Side conversation.");
|
|
27123
|
+
}
|
|
27124
|
+
const parent = active.handle.agent;
|
|
27125
|
+
const parentEvents = parent.session.events;
|
|
27126
|
+
const seed = completedTurnSeed(parentEvents);
|
|
27127
|
+
const pendingRequest = pendingUserText(parentEvents, seed.length);
|
|
27128
|
+
const selected = activeSelection;
|
|
27129
|
+
const selectedView = modelSelectionRuntime.getSnapshot().current;
|
|
27130
|
+
const side = await createActiveConversation(selected, {
|
|
27131
|
+
signal,
|
|
27132
|
+
sessionId: SessionId4(`${SIDE_SESSION_PREFIX}${randomUUID3()}`),
|
|
27133
|
+
parentSession: parent.session.id,
|
|
27134
|
+
seed,
|
|
27135
|
+
restrictTools: true,
|
|
27136
|
+
publishRuntimeEvents: false
|
|
27137
|
+
});
|
|
27138
|
+
sideSelection = selected;
|
|
27139
|
+
visibleSideAgent = side.handle.agent;
|
|
27140
|
+
let firstSubmission = true;
|
|
27141
|
+
let sideDisposed = false;
|
|
27142
|
+
const handle = {
|
|
27143
|
+
parentSessionId: String(parent.session.id),
|
|
27144
|
+
modelLabel: modelSelectionLabel(selectedView),
|
|
27145
|
+
...modelReasoningEffortLabel(selectedView) === void 0 ? {} : {
|
|
27146
|
+
reasoningEffortLabel: modelReasoningEffortLabel(selectedView)
|
|
27147
|
+
},
|
|
27148
|
+
getSnapshot: side.projector.getSnapshot,
|
|
27149
|
+
getSessionStats: side.projector.getSessionStats,
|
|
27150
|
+
subscribe: side.projector.subscribe,
|
|
27151
|
+
submit: async (submission) => {
|
|
27152
|
+
let prefixedFirstText = false;
|
|
27153
|
+
const prepared = firstSubmission ? {
|
|
27154
|
+
...submission,
|
|
27155
|
+
content: submission.content.map((part) => {
|
|
27156
|
+
if (prefixedFirstText || part.type !== "text") return part;
|
|
27157
|
+
prefixedFirstText = true;
|
|
27158
|
+
return {
|
|
27159
|
+
...part,
|
|
27160
|
+
text: firstSidePrompt(part.text, pendingRequest)
|
|
27161
|
+
};
|
|
27162
|
+
})
|
|
27163
|
+
} : submission;
|
|
27164
|
+
const ingested = await prepareSubmission(prepared, false);
|
|
27165
|
+
await submitToConversation(side, ingested, prepared.signal);
|
|
27166
|
+
firstSubmission = false;
|
|
27167
|
+
},
|
|
27168
|
+
cancel: () => {
|
|
27169
|
+
side.handle.agent.cancel({ kind: "user" });
|
|
27170
|
+
side.projector.cancel();
|
|
27171
|
+
},
|
|
27172
|
+
exit: () => {
|
|
27173
|
+
},
|
|
27174
|
+
dispose: async () => {
|
|
27175
|
+
if (sideDisposed) return;
|
|
27176
|
+
sideDisposed = true;
|
|
27177
|
+
if (side.projector.getSnapshot().busy) {
|
|
27178
|
+
side.handle.agent.cancel({ kind: "user" });
|
|
27179
|
+
await side.handle.agent.whenIdle();
|
|
27180
|
+
}
|
|
27181
|
+
await sessions.flush(side.handle.agent.session).catch((error) => {
|
|
27182
|
+
debugLogger.debug(
|
|
27183
|
+
`Unable to flush Side Session: ${String(error)}`
|
|
27184
|
+
);
|
|
27185
|
+
});
|
|
27186
|
+
side.offSession();
|
|
27187
|
+
side.offProjector();
|
|
27188
|
+
await side.handle.dispose();
|
|
27189
|
+
if (visibleSideAgent === side.handle.agent)
|
|
27190
|
+
visibleSideAgent = void 0;
|
|
27191
|
+
if (sideSelection === selected) sideSelection = void 0;
|
|
27192
|
+
}
|
|
27193
|
+
};
|
|
27194
|
+
return handle;
|
|
27195
|
+
}
|
|
27196
|
+
);
|
|
27197
|
+
workspaceRef.current = conversationWorkspace;
|
|
27198
|
+
offWorkspaceSurface = conversationWorkspace.subscribeSurface(() => {
|
|
27199
|
+
commandRuntime.activeAgentChanged();
|
|
27200
|
+
permissionSelectionRuntime.activeAgentChanged();
|
|
27201
|
+
toolCatalogRuntime.activeAgentChanged();
|
|
27202
|
+
});
|
|
25987
27203
|
ctx.effect(() => cleanup, "dsh-console: terminal");
|
|
25988
27204
|
await main({
|
|
25989
|
-
conversationRuntime,
|
|
27205
|
+
conversationRuntime: conversationWorkspace,
|
|
25990
27206
|
promptCompletionRuntime,
|
|
25991
27207
|
promptInputRuntime,
|
|
25992
27208
|
modelSelectionRuntime,
|
|
@@ -25997,8 +27213,13 @@ async function start(ctx, config) {
|
|
|
25997
27213
|
commandRuntime,
|
|
25998
27214
|
permissionSelectionRuntime,
|
|
25999
27215
|
toolCatalogRuntime,
|
|
27216
|
+
subagentCatalogRuntime,
|
|
27217
|
+
sideConversationRuntime: conversationWorkspace,
|
|
26000
27218
|
initialPrompt: config.prompt?.trim(),
|
|
26001
|
-
argv:
|
|
27219
|
+
argv: [
|
|
27220
|
+
...config.debug ? ["--debug"] : [],
|
|
27221
|
+
...config.pokemon === void 0 ? [] : ["--pokemon", String(config.pokemon)]
|
|
27222
|
+
]
|
|
26002
27223
|
});
|
|
26003
27224
|
}
|
|
26004
27225
|
function apply(ctx, config) {
|