dsh-bash-terminal-ts 0.4.0 → 0.6.0
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/README.en.md +53 -162
- package/README.md +103 -94
- package/cordis.patch.yml +2 -2
- package/dist/client.core.js +49 -42
- package/dist/client.js +50 -43
- package/dsh.plugin.json +4 -4
- package/lib/client.js +148 -0
- package/lib/dsh-types.d.ts +1 -2
- package/lib/dsh.d.ts +2 -0
- package/lib/index.d.ts +17 -18
- package/lib/index.js +63 -57
- package/lib/terminal.d.ts +24 -1
- package/lib/terminal.js +214 -49
- package/package.json +115 -137
- package/screenshots.json +5 -0
- package/scripts/build-client.mjs +14 -13
- package/src/client.tsx +80 -55
- package/src/dsh-types.ts +1 -2
- package/src/dsh.ts +2 -0
- package/src/index.ts +67 -61
- package/src/terminal.ts +254 -54
- package/template/README.md +82 -0
- package/template/terminal-adapter.ts +343 -0
- package/README.ja.md +0 -196
- package/README.ko.md +0 -194
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// dsh-bash-terminal
|
|
1
|
+
// dsh-bash-terminal - one shell tool, four Windows terminals.
|
|
2
2
|
//
|
|
3
3
|
// Registers a model-facing shell tool. The terminal backend (powershell /
|
|
4
4
|
// gitbash / msys2 / wsl) is chosen by the USER in the Web UI settings (default
|
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
// choice:
|
|
7
7
|
// - powershell: pwsh -NoLogo -NoProfile -NonInteractive -Command <cmd>
|
|
8
8
|
// - gitbash: Git for Windows bash -lc <cmd> (POSIX; /d/... paths)
|
|
9
|
-
// - msys2:
|
|
10
|
-
// toolchain). NOT msys2.exe: that Cygwin launcher allocates a
|
|
11
|
-
// console and returns exit 0 with zero bytes under piped stdio.
|
|
12
|
-
// MSYSTEM=MINGW64 is injected via buildEnv so /etc/profile picks
|
|
13
|
-
// the MINGW64 environment and /mingw64/bin lands on PATH.
|
|
9
|
+
// - msys2: MSYS2 bash -lc <cmd> (POSIX; /c/... paths, full GCC/mingw64 toolchain)
|
|
14
10
|
// - wsl: wsl [-d <distro>] -e bash -lc <cmd> (Linux; /mnt/d/... paths)
|
|
15
11
|
//
|
|
16
12
|
// The tool spawns through the shared ctx.subprocess seam (process-tree
|
|
@@ -18,8 +14,13 @@
|
|
|
18
14
|
// handles with the generic ctx.jobs registry, mirroring the shipped
|
|
19
15
|
// dsh-tool-bash / dsh-tool-pwsh story call-for-call. It deliberately
|
|
20
16
|
// does NOT consume the ctx.shell capability seam: the platform's own
|
|
21
|
-
// sandboxed PowerShell executor keeps serving the pwsh tool
|
|
22
|
-
//
|
|
17
|
+
// sandboxed PowerShell executor keeps serving the pwsh tool. This tool is
|
|
18
|
+
// an additional, user-selected terminal that still honors the DSH sandbox:
|
|
19
|
+
// confined modes wrap PowerShell's spawn argv through ctx.sandbox
|
|
20
|
+
// (fail-closed), while danger-full-access, Git Bash, MSYS2, and WSL run
|
|
21
|
+
// unconfined. Git Bash and MSYS2 are unconfined because the DSH Windows ACL
|
|
22
|
+
// restricted-token runner cannot host Cygwin/MSYS2: bash aborts with
|
|
23
|
+
// "CreateFileMapping ... Win32 error 5" during startup.
|
|
23
24
|
import { lstatSync } from "node:fs";
|
|
24
25
|
import { isAbsolute, join, resolve } from "node:path";
|
|
25
26
|
import { ESCALATION_TARGETS, TOOL_ABORTED, approveEscalation, defineTool, escalationHintMarker, clampTimeout, deadline, parseExitStatus, timeoutOf, sandboxDenialMarker, validateEscalationArgs, z, HarnessError } from "./dsh.js";
|
|
@@ -32,8 +33,6 @@ export const inject = ["tools", "systemPrompt", "shellEnv", "subprocess", "setti
|
|
|
32
33
|
export const SHELLS = ["powershell", "gitbash", "msys2", "wsl"];
|
|
33
34
|
/** The backend used when the caller does not name one. */
|
|
34
35
|
export const DEFAULT_SHELL = "powershell";
|
|
35
|
-
/** Settings namespace backing the user-chosen default terminal. */
|
|
36
|
-
export const SETTINGS_NAMESPACE = "bash-terminal";
|
|
37
36
|
/** Default per-command timeout (ms). */
|
|
38
37
|
const DEFAULT_TIMEOUT_MS = 120000;
|
|
39
38
|
/** Upper bound a caller's timeoutMs is capped to. */
|
|
@@ -55,7 +54,7 @@ const ENV_OVERRIDES = {
|
|
|
55
54
|
};
|
|
56
55
|
/** Runtime configuration schema. */
|
|
57
56
|
export const Config = z.object({
|
|
58
|
-
defaultShell: z.string().default(DEFAULT_SHELL),
|
|
57
|
+
defaultShell: z.string().default(DEFAULT_SHELL).volatile(),
|
|
59
58
|
timeoutMs: z.number().default(DEFAULT_TIMEOUT_MS),
|
|
60
59
|
maxTimeoutMs: z.number().default(MAX_TIMEOUT_MS),
|
|
61
60
|
pwshPath: z.string().default(""),
|
|
@@ -120,34 +119,30 @@ export function candidateGitBashPaths(env = process.env) {
|
|
|
120
119
|
return candidates;
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
123
|
-
* MSYS2 locations, in preference order: the real `bash.exe` under usr\bin
|
|
124
|
-
* then bin\bash.exe, and `msys2.exe` dead last.
|
|
122
|
+
* MSYS2 locations, in preference order: the real `bash.exe` under usr\bin
|
|
123
|
+
* first, then bin\bash.exe, and `msys2.exe` dead last.
|
|
125
124
|
*
|
|
126
125
|
* msys2.exe is NOT a usable backend for piped execution: it is the console-
|
|
127
126
|
* allocating Cygwin launcher, so a spawn with piped stdio returns exit 0 with
|
|
128
|
-
* zero bytes on both stdout and stderr (measured on
|
|
129
|
-
* Keeping it in the list only as a last-resort
|
|
130
|
-
* config docs reference, but a working
|
|
127
|
+
* zero bytes on both stdout and stderr (measured on this machine against
|
|
128
|
+
* MSYS2 with bash 5.3.15). Keeping it in the list only as a last-resort
|
|
129
|
+
* fallback preserves the path the config docs reference, but a working
|
|
130
|
+
* bash.exe always wins.
|
|
131
131
|
*
|
|
132
|
-
* MSYS2 uses the same Cygwin/MSYS2 runtime as Git Bash, so it cannot run
|
|
133
|
-
* the DSH Windows ACL restricted-token sandbox.
|
|
132
|
+
* MSYS2 uses the same Cygwin/MSYS2 runtime as Git Bash, so it cannot run
|
|
133
|
+
* under the DSH Windows ACL restricted-token sandbox.
|
|
134
134
|
*/
|
|
135
135
|
export function candidateMsys2Paths(env = process.env) {
|
|
136
|
-
const programFiles = env.ProgramFiles ?? "C:\\Program Files";
|
|
137
136
|
const candidates = [
|
|
138
137
|
"C:\\msys64\\usr\\bin\\bash.exe",
|
|
139
138
|
"C:\\msys64\\bin\\bash.exe"
|
|
140
139
|
];
|
|
141
|
-
// Also check 32-bit variant
|
|
142
|
-
const programFilesX86 = env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
143
|
-
if (programFilesX86 !== programFiles) {
|
|
144
|
-
candidates.push("C:\\msys64\\usr\\bin\\bash.exe"); // same path regardless of arch
|
|
145
|
-
}
|
|
146
140
|
for (const entry of (env.PATH ?? "").split(";")) {
|
|
147
141
|
const trimmed = entry.trim().replace(/^"|"$/g, "");
|
|
148
142
|
if (trimmed.length === 0)
|
|
149
143
|
continue;
|
|
150
|
-
|
|
144
|
+
const lower = trimmed.toLowerCase();
|
|
145
|
+
if (lower.includes("msys64") || lower.includes("mingw64")) {
|
|
151
146
|
candidates.push(join(trimmed, "bash.exe"));
|
|
152
147
|
}
|
|
153
148
|
}
|
|
@@ -195,40 +190,42 @@ export function buildArgv(shell, command, paths, distro) {
|
|
|
195
190
|
}
|
|
196
191
|
/**
|
|
197
192
|
* Merge the DSH_* environment over the process environment. For WSL, only
|
|
198
|
-
* variables explicitly listed in WSLENV cross the boundary, so every DSH_*
|
|
199
|
-
* appended
|
|
193
|
+
* variables explicitly listed in WSLENV cross the boundary, so every DSH_*
|
|
194
|
+
* key is appended there — and the list is *layered onto* whatever WSLENV the
|
|
195
|
+
* host already had (Windows Terminal exports e.g. `WT_SESSION:WT_PROFILE_ID:`),
|
|
196
|
+
* never rebuilt from scratch: WSLENV is an allow-list, so dropping the
|
|
197
|
+
* inherited entries would silently stop them crossing into WSL.
|
|
200
198
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* wholesale (the PTY path) must pass the inherited value explicitly.
|
|
206
|
-
*
|
|
207
|
-
* @param inheritedWslenv - the WSLENV the child would otherwise inherit.
|
|
199
|
+
* @param inheritedWslenv - the ambient WSLENV to layer onto. Callers that
|
|
200
|
+
* replace the child environment wholesale (the PTY path) must pass
|
|
201
|
+
* `process.env.WSLENV` explicitly, because the ambient value is not visible
|
|
202
|
+
* through `dshEnv`.
|
|
208
203
|
*/
|
|
209
204
|
export function buildEnv(shell, dshEnv, inheritedWslenv = process.env.WSLENV) {
|
|
210
205
|
const env = { ...ENV_OVERRIDES, ...dshEnv };
|
|
211
206
|
if (shell === "msys2") {
|
|
212
|
-
// Picks the MINGW64 environment, so /mingw64/bin (gcc, make, ...) joins
|
|
213
|
-
// via /etc/profile. Without it MSYS2 defaults to the bare MSYS
|
|
207
|
+
// Picks the MINGW64 environment, so /mingw64/bin (gcc, make, ...) joins
|
|
208
|
+
// PATH via /etc/profile. Without it MSYS2 defaults to the bare MSYS
|
|
209
|
+
// environment. An explicit caller-supplied value wins.
|
|
214
210
|
if (env.MSYSTEM === undefined)
|
|
215
211
|
env.MSYSTEM = "MINGW64";
|
|
216
212
|
}
|
|
217
213
|
if (shell === "wsl") {
|
|
218
214
|
const keys = Object.keys(dshEnv ?? {});
|
|
219
215
|
if (keys.length > 0) {
|
|
220
|
-
// An explicit WSLENV
|
|
216
|
+
// An explicit WSLENV in dshEnv wins over the inherited one; otherwise the
|
|
217
|
+
// inherited value is the base. Either way the base is SPLIT into entries
|
|
218
|
+
// (the host value ends with a trailing ":", so string concatenation would
|
|
219
|
+
// produce a malformed empty entry) and the WSLENV key itself is excluded
|
|
220
|
+
// (it is a key of dshEnv too, and appending it would add a bogus entry).
|
|
221
221
|
const declared = Object.prototype.hasOwnProperty.call(dshEnv ?? {}, "WSLENV");
|
|
222
222
|
const base = declared
|
|
223
223
|
? env.WSLENV
|
|
224
224
|
: (typeof inheritedWslenv === "string" && inheritedWslenv.length > 0 ? inheritedWslenv : env.WSLENV);
|
|
225
|
-
// Windows Terminal's own value ends with a trailing ':' and the caller's
|
|
226
|
-
// may too, so split/normalise instead of string-concatenating -- a naive
|
|
227
|
-
// join yields an empty entry ("A:B::DSH_X"), which WSL flags as malformed.
|
|
228
225
|
const parts = typeof base === "string" ? base.split(":") : [];
|
|
229
226
|
env.WSLENV = [...parts, ...keys.filter((k) => k !== "WSLENV").flatMap((k) => k.split(":"))]
|
|
230
|
-
.map((
|
|
231
|
-
.filter((
|
|
227
|
+
.map((p) => p.trim())
|
|
228
|
+
.filter((p) => p.length > 0)
|
|
232
229
|
.join(":");
|
|
233
230
|
}
|
|
234
231
|
}
|
|
@@ -252,7 +249,7 @@ function spawnSpec(resolved, argv, env, signal) {
|
|
|
252
249
|
function collectedOutput(handle) {
|
|
253
250
|
const { stdout, stderr } = handle.collected;
|
|
254
251
|
if (!isCollectedStream(stdout) || !isCollectedStream(stderr)) {
|
|
255
|
-
throw new Error("dsh-bash-terminal
|
|
252
|
+
throw new Error("dsh-bash-terminal: subprocess implementation dropped a requested collect stream");
|
|
256
253
|
}
|
|
257
254
|
return { stdout, stderr };
|
|
258
255
|
}
|
|
@@ -293,7 +290,7 @@ async function runForeground(ctx, argv, resolved, env, signal, timeoutMs) {
|
|
|
293
290
|
function requireSubprocess(ctx) {
|
|
294
291
|
const subprocess = ctx.subprocess;
|
|
295
292
|
if (subprocess === null) {
|
|
296
|
-
throw new Error("dsh-bash-terminal
|
|
293
|
+
throw new Error("dsh-bash-terminal: ctx.subprocess seam unavailable (missing inject service)");
|
|
297
294
|
}
|
|
298
295
|
return subprocess;
|
|
299
296
|
}
|
|
@@ -442,8 +439,9 @@ export function validateArgs(args) {
|
|
|
442
439
|
* Git Bash and MSYS2 are also not confined: DSH's Windows ACL restricted-token
|
|
443
440
|
* runner cannot start Cygwin/MSYS2 (CreateFileMapping Win32 error 5), so
|
|
444
441
|
* attempting to wrap them would abort every Git Bash / MSYS2 command. A
|
|
445
|
-
* requested confined mode
|
|
446
|
-
*
|
|
442
|
+
* requested confined mode
|
|
443
|
+
* with no usable backend throws the fail-closed SandboxUnavailableError,
|
|
444
|
+
* exactly like the shipped executors.
|
|
447
445
|
*/
|
|
448
446
|
function confineSpawn(ctx, argv, policy, shell) {
|
|
449
447
|
if (policy.mode === "danger-full-access" || shell === "wsl" || shell === "gitbash" || shell === "msys2") {
|
|
@@ -495,16 +493,24 @@ const BACKGROUND_OUTPUT_PROPERTIES = {
|
|
|
495
493
|
// ---- plugin -------------------------------------------------------------------
|
|
496
494
|
export function apply(ctx, config = {}) {
|
|
497
495
|
if (process.platform !== "win32") {
|
|
498
|
-
ctx.logger?.info?.("dsh-bash-terminal
|
|
496
|
+
ctx.logger?.info?.("dsh-bash-terminal: only meaningful on win32; skipping tool registration");
|
|
499
497
|
return;
|
|
500
498
|
}
|
|
501
499
|
const backgroundEnabled = true;
|
|
502
500
|
const paths = resolveAllPaths(config);
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
501
|
+
// 0.1.7: `defaultShell` is a `.volatile()` config field — the loader hands
|
|
502
|
+
// `apply` a live ref and the latest value is resolved on every read; there
|
|
503
|
+
// is no settings registration call anymore (removed with the 0.1.7 host).
|
|
504
|
+
const currentShell = () => {
|
|
505
|
+
const v = config.defaultShell;
|
|
506
|
+
if (typeof v === "string")
|
|
507
|
+
return v;
|
|
508
|
+
const got = typeof v?.get === "function" ? v.get() : undefined;
|
|
509
|
+
return typeof got === "string" ? got : DEFAULT_SHELL;
|
|
510
|
+
};
|
|
511
|
+
if (!SHELLS.includes(currentShell())) {
|
|
512
|
+
throw new Error(`dsh-bash-terminal: invalid defaultShell ${JSON.stringify(currentShell())}`);
|
|
506
513
|
}
|
|
507
|
-
const settingsScope = ctx.settings.register(SETTINGS_NAMESPACE, z.object({ defaultShell: z.union(SHELLS.map((s) => z.const(s))).default(defaultShell) }), { base: { defaultShell } });
|
|
508
514
|
/** Official sandbox-escalation surface (mirrors tool-bash): advertise the
|
|
509
515
|
* escalation modes whenever the deployment confines. */
|
|
510
516
|
const escalationModes = ESCALATION_TARGETS;
|
|
@@ -525,11 +531,11 @@ export function apply(ctx, config = {}) {
|
|
|
525
531
|
ctx.systemPrompt.section({
|
|
526
532
|
name: "tool:bash-terminal",
|
|
527
533
|
order: 105,
|
|
528
|
-
text: "Use the shell tool for terminal commands: it runs in the terminal the user chose in Settings -> General -> Default terminal (PowerShell, Git Bash, or WSL) and honors the DSH sandbox. Prefer it over the pwsh tool for everyday commands; keep the pwsh tool for cases that specifically need the sandboxed PowerShell surface."
|
|
534
|
+
text: "Use the shell tool for terminal commands: it runs in the terminal the user chose in Settings -> General -> Default terminal (PowerShell, Git Bash, MSYS2, or WSL) and honors the DSH sandbox. Prefer it over the pwsh tool for everyday commands; keep the pwsh tool for cases that specifically need the sandboxed PowerShell surface."
|
|
529
535
|
});
|
|
530
536
|
const toolName = "shell";
|
|
531
537
|
const terminalRegistry = createTerminalRegistry(ctx);
|
|
532
|
-
ctx.tools.register(terminalTool(ctx, terminalRegistry, paths, () =>
|
|
538
|
+
ctx.tools.register(terminalTool(ctx, terminalRegistry, paths, () => currentShell()));
|
|
533
539
|
// The model-facing description must track the user's chosen default
|
|
534
540
|
// terminal: a static description listing every backend leaves the model
|
|
535
541
|
// guessing which syntax applies. Re-render it on every prompt assembly —
|
|
@@ -537,7 +543,7 @@ export function apply(ctx, config = {}) {
|
|
|
537
543
|
// without a restart.
|
|
538
544
|
ctx.on("system-prompt/assemble", async (_assembly, _context, next) => {
|
|
539
545
|
const assembled = await next();
|
|
540
|
-
const description = toolDescription(backgroundEnabled,
|
|
546
|
+
const description = toolDescription(backgroundEnabled, currentShell());
|
|
541
547
|
const tools = Array.isArray(assembled.tools)
|
|
542
548
|
? assembled.tools.map((tool) => (tool.name === toolName ? { ...tool, description } : tool))
|
|
543
549
|
: assembled.tools;
|
|
@@ -545,7 +551,7 @@ export function apply(ctx, config = {}) {
|
|
|
545
551
|
});
|
|
546
552
|
ctx.tools.register(defineTool({
|
|
547
553
|
name: toolName,
|
|
548
|
-
description: toolDescription(backgroundEnabled,
|
|
554
|
+
description: toolDescription(backgroundEnabled, currentShell()),
|
|
549
555
|
parameters: {
|
|
550
556
|
command: {
|
|
551
557
|
type: "string",
|
|
@@ -644,10 +650,10 @@ export function apply(ctx, config = {}) {
|
|
|
644
650
|
},
|
|
645
651
|
async execute(args, exec) {
|
|
646
652
|
const v = validateArgs(args);
|
|
647
|
-
const shell =
|
|
653
|
+
const shell = currentShell();
|
|
648
654
|
const argv0 = buildArgv(shell, v.command, paths, v.distro);
|
|
649
655
|
if (argv0[0] === undefined) {
|
|
650
|
-
throw new Error(`dsh-bash-terminal
|
|
656
|
+
throw new Error(`dsh-bash-terminal: ${shell} backend unavailable - executable not found. Install it or set the corresponding *Path config.`);
|
|
651
657
|
}
|
|
652
658
|
// Only element 0 (the resolved executable) can be undefined; guarded above.
|
|
653
659
|
const argv = argv0;
|
package/lib/terminal.d.ts
CHANGED
|
@@ -4,14 +4,23 @@ export type TerminalSignal = (typeof TERMINAL_SIGNALS)[number];
|
|
|
4
4
|
interface TerminalBufferRead {
|
|
5
5
|
delta: string;
|
|
6
6
|
nextOffset: number;
|
|
7
|
+
truncated: boolean;
|
|
7
8
|
}
|
|
8
9
|
interface TerminalBuffer {
|
|
9
10
|
append(chunk: string): void;
|
|
10
11
|
readFrom(offset: number): TerminalBufferRead;
|
|
11
12
|
snapshot(): string;
|
|
13
|
+
wasTruncated(): boolean;
|
|
14
|
+
lastAppendAt(): number;
|
|
12
15
|
}
|
|
13
16
|
/** Interactive-shell argv (no -c: the terminal itself is the session). */
|
|
14
17
|
export declare function terminalArgv(shell: string, paths: ResolvedPaths, distro?: string): Array<string | undefined>;
|
|
18
|
+
export interface TerminalSessionInfo {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
shell: string;
|
|
21
|
+
pid: number;
|
|
22
|
+
closed: boolean;
|
|
23
|
+
}
|
|
15
24
|
interface TerminalSession {
|
|
16
25
|
id: string;
|
|
17
26
|
handle: TerminalHandle;
|
|
@@ -19,6 +28,9 @@ interface TerminalSession {
|
|
|
19
28
|
shell: string;
|
|
20
29
|
distro?: string;
|
|
21
30
|
closed: boolean;
|
|
31
|
+
idleMs: number;
|
|
32
|
+
idleTimer?: NodeJS.Timeout;
|
|
33
|
+
touch: () => void;
|
|
22
34
|
}
|
|
23
35
|
export interface TerminalOpenOptions {
|
|
24
36
|
argv: string[];
|
|
@@ -29,6 +41,7 @@ export interface TerminalOpenOptions {
|
|
|
29
41
|
cols: number;
|
|
30
42
|
distro?: string;
|
|
31
43
|
initial?: string;
|
|
44
|
+
idleMs?: number;
|
|
32
45
|
}
|
|
33
46
|
export interface TerminalRegistry {
|
|
34
47
|
open(options: TerminalOpenOptions): Promise<TerminalSession>;
|
|
@@ -37,6 +50,7 @@ export interface TerminalRegistry {
|
|
|
37
50
|
read(id: string): TerminalBufferRead;
|
|
38
51
|
signal(id: string, sig: string): Promise<TerminalBufferRead>;
|
|
39
52
|
close(id: string): Promise<boolean>;
|
|
53
|
+
list(): TerminalSessionInfo[];
|
|
40
54
|
}
|
|
41
55
|
/**
|
|
42
56
|
* Terminal-session registry owned by the plugin fiber: opens PTYs through
|
|
@@ -51,6 +65,7 @@ export type ValidatedTerminalArgs = {
|
|
|
51
65
|
command?: string;
|
|
52
66
|
distro?: string;
|
|
53
67
|
workdir?: string;
|
|
68
|
+
idleMs?: number;
|
|
54
69
|
} | {
|
|
55
70
|
action: "send";
|
|
56
71
|
sessionId: string;
|
|
@@ -65,11 +80,14 @@ export type ValidatedTerminalArgs = {
|
|
|
65
80
|
} | {
|
|
66
81
|
action: "close";
|
|
67
82
|
sessionId: string;
|
|
83
|
+
} | {
|
|
84
|
+
action: "list";
|
|
68
85
|
};
|
|
69
86
|
export declare function validateArgs(args: Record<string, unknown>): asserts args is ValidatedTerminalArgs;
|
|
70
87
|
export interface TerminalOpenResult {
|
|
71
88
|
kind: "open";
|
|
72
89
|
sessionId: string;
|
|
90
|
+
jobId?: string;
|
|
73
91
|
pid: number;
|
|
74
92
|
shell: string;
|
|
75
93
|
output: string;
|
|
@@ -77,11 +95,16 @@ export interface TerminalOpenResult {
|
|
|
77
95
|
export interface TerminalSessionResult {
|
|
78
96
|
kind: "session";
|
|
79
97
|
output: string;
|
|
98
|
+
truncated?: boolean;
|
|
80
99
|
}
|
|
81
100
|
export interface TerminalClosedResult {
|
|
82
101
|
kind: "closed";
|
|
83
102
|
sessionId: string;
|
|
84
103
|
}
|
|
85
|
-
export
|
|
104
|
+
export interface TerminalListResult {
|
|
105
|
+
kind: "list";
|
|
106
|
+
sessions: TerminalSessionInfo[];
|
|
107
|
+
}
|
|
108
|
+
export type TerminalToolResult = TerminalOpenResult | TerminalSessionResult | TerminalClosedResult | TerminalListResult;
|
|
86
109
|
export declare function terminalTool(ctx: BashTerminalContext, registry: TerminalRegistry, paths: ResolvedPaths, defaultShell: () => string): import("./dsh-types.js").ToolDefinition;
|
|
87
110
|
export {};
|