dsh-bash-terminal-ts 0.5.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.core.js +3 -3
- package/dist/client.js +3 -3
- package/dsh.plugin.json +2 -2
- package/lib/client.js +3 -3
- package/lib/dsh-types.d.ts +0 -1
- package/lib/dsh.d.ts +2 -0
- package/lib/index.d.ts +0 -2
- package/lib/index.js +17 -11
- package/package.json +15 -17
- package/src/client.tsx +10 -9
- package/src/dsh-types.ts +0 -1
- package/src/dsh.ts +2 -0
- package/src/index.ts +21 -15
package/dist/client.core.js
CHANGED
|
@@ -28,7 +28,7 @@ var import_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
|
28
28
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
29
29
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
30
30
|
var SETTINGS_NS = "settings.bash-terminal";
|
|
31
|
-
var
|
|
31
|
+
var ENTRY_ID = "tool-bash-terminal";
|
|
32
32
|
var SHELLS = ["powershell", "gitbash", "msys2", "wsl"];
|
|
33
33
|
var ROW_CSS = ".btRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.btRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.btTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.btDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.btSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.btSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.btChevron{flex:none}";
|
|
34
34
|
if (typeof document !== "undefined" && document.querySelector('style[data-plugin-css="bash-terminal-row"]') === null) {
|
|
@@ -54,7 +54,7 @@ var en = {
|
|
|
54
54
|
"shell.msys2": "MSYS2",
|
|
55
55
|
"shell.wsl": "WSL"
|
|
56
56
|
};
|
|
57
|
-
var inject = ["slots", "locale", "
|
|
57
|
+
var inject = ["slots", "locale", "configForms"];
|
|
58
58
|
function ShellPreferenceRow({ t, useStore, setShell }) {
|
|
59
59
|
const shell = useStore((s) => s.shell);
|
|
60
60
|
const writable = useStore((s) => s.writable);
|
|
@@ -100,7 +100,7 @@ function ShellPreferenceRow({ t, useStore, setShell }) {
|
|
|
100
100
|
}
|
|
101
101
|
function apply(ctx) {
|
|
102
102
|
ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en }), "bash-terminal: settings dictionaries");
|
|
103
|
-
const scope = ctx.
|
|
103
|
+
const scope = ctx.configForms.get(ENTRY_ID);
|
|
104
104
|
const store = (0, import_dsh_client_store.defineStore)({
|
|
105
105
|
init: () => ({ shell: "powershell", revision: -1, writable: false }),
|
|
106
106
|
actions: {
|
package/dist/client.js
CHANGED
|
@@ -33,7 +33,7 @@ var import_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
|
33
33
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
34
34
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
35
35
|
var SETTINGS_NS = "settings.bash-terminal";
|
|
36
|
-
var
|
|
36
|
+
var ENTRY_ID = "tool-bash-terminal";
|
|
37
37
|
var SHELLS = ["powershell", "gitbash", "msys2", "wsl"];
|
|
38
38
|
var ROW_CSS = ".btRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.btRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.btTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.btDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.btSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.btSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.btChevron{flex:none}";
|
|
39
39
|
if (typeof document !== "undefined" && document.querySelector('style[data-plugin-css="bash-terminal-row"]') === null) {
|
|
@@ -59,7 +59,7 @@ var en = {
|
|
|
59
59
|
"shell.msys2": "MSYS2",
|
|
60
60
|
"shell.wsl": "WSL"
|
|
61
61
|
};
|
|
62
|
-
var inject = ["slots", "locale", "
|
|
62
|
+
var inject = ["slots", "locale", "configForms"];
|
|
63
63
|
function ShellPreferenceRow({ t, useStore, setShell }) {
|
|
64
64
|
const shell = useStore((s) => s.shell);
|
|
65
65
|
const writable = useStore((s) => s.writable);
|
|
@@ -105,7 +105,7 @@ function ShellPreferenceRow({ t, useStore, setShell }) {
|
|
|
105
105
|
}
|
|
106
106
|
function apply(ctx) {
|
|
107
107
|
ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en }), "bash-terminal: settings dictionaries");
|
|
108
|
-
const scope = ctx.
|
|
108
|
+
const scope = ctx.configForms.get(ENTRY_ID);
|
|
109
109
|
const store = (0, import_dsh_client_store.defineStore)({
|
|
110
110
|
init: () => ({ shell: "powershell", revision: -1, writable: false }),
|
|
111
111
|
actions: {
|
package/dsh.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-bash-terminal",
|
|
3
3
|
"name": "dsh-bash-terminal",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"description": {
|
|
6
6
|
"en": "One shell tool that runs commands through PowerShell, Git Bash, MSYS2 or WSL on Windows, with a user-chosen default terminal in the Web UI settings.",
|
|
7
7
|
"zh": "一个 shell 工具,可在 Windows 上通过 PowerShell / Git Bash / MSYS2 / WSL 执行命令,默认终端在 Web UI 设置中选择。"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"engines": {
|
|
16
|
-
"dsh": ">=0.1.
|
|
16
|
+
"dsh": ">=0.1.7-rc.1 <0.1.8-0"
|
|
17
17
|
},
|
|
18
18
|
"components": {
|
|
19
19
|
"host": "lib/index.js",
|
package/lib/client.js
CHANGED
|
@@ -33,7 +33,7 @@ var import_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
|
33
33
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
34
34
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
35
35
|
var SETTINGS_NS = "settings.bash-terminal";
|
|
36
|
-
var
|
|
36
|
+
var ENTRY_ID = "tool-bash-terminal";
|
|
37
37
|
var SHELLS = ["powershell", "gitbash", "msys2", "wsl"];
|
|
38
38
|
var ROW_CSS = ".btRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:16px 0;display:flex}.btRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.btTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.btDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:400;line-height:18px}.btSelector{background:var(--dsw-alias-bg-module-platform);height:36px;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;border-radius:18px;align-items:center;gap:12px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.btSelector:hover{background:var(--dsw-alias-interactive-bg-hover)}.btChevron{flex:none}";
|
|
39
39
|
if (typeof document !== "undefined" && document.querySelector('style[data-plugin-css="bash-terminal-row"]') === null) {
|
|
@@ -59,7 +59,7 @@ var en = {
|
|
|
59
59
|
"shell.msys2": "MSYS2",
|
|
60
60
|
"shell.wsl": "WSL"
|
|
61
61
|
};
|
|
62
|
-
var inject = ["slots", "locale", "
|
|
62
|
+
var inject = ["slots", "locale", "configForms"];
|
|
63
63
|
function ShellPreferenceRow({ t, useStore, setShell }) {
|
|
64
64
|
const shell = useStore((s) => s.shell);
|
|
65
65
|
const writable = useStore((s) => s.writable);
|
|
@@ -105,7 +105,7 @@ function ShellPreferenceRow({ t, useStore, setShell }) {
|
|
|
105
105
|
}
|
|
106
106
|
function apply(ctx) {
|
|
107
107
|
ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en }), "bash-terminal: settings dictionaries");
|
|
108
|
-
const scope = ctx.
|
|
108
|
+
const scope = ctx.configForms.get(ENTRY_ID);
|
|
109
109
|
const store = (0, import_dsh_client_store.defineStore)({
|
|
110
110
|
init: () => ({ shell: "powershell", revision: -1, writable: false }),
|
|
111
111
|
actions: {
|
package/lib/dsh-types.d.ts
CHANGED
|
@@ -250,7 +250,6 @@ export interface BashTerminalContext {
|
|
|
250
250
|
tools: ToolsSeam;
|
|
251
251
|
on(event: "system-prompt/assemble", handler: AssembleHandler): void;
|
|
252
252
|
shellEnv: ShellEnvSeam;
|
|
253
|
-
settings: SettingsSeam;
|
|
254
253
|
sandboxPolicy: SandboxPolicySeam;
|
|
255
254
|
sandbox: SandboxSeam;
|
|
256
255
|
get(key: string): unknown;
|
package/lib/dsh.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export declare const escalationHintMarker: (subject: string) => string;
|
|
|
20
20
|
/** Runtime config schema factory (schemastery fork). */
|
|
21
21
|
export interface SchemasterySchema {
|
|
22
22
|
default(value: unknown): SchemasterySchema;
|
|
23
|
+
/** 0.1.7+: expose the field on the auto-generated settings form. */
|
|
24
|
+
volatile(): SchemasterySchema;
|
|
23
25
|
}
|
|
24
26
|
export interface Schemastery {
|
|
25
27
|
object(fields: Record<string, SchemasterySchema>): SchemasterySchema;
|
package/lib/index.d.ts
CHANGED
|
@@ -7,8 +7,6 @@ export declare const inject: string[];
|
|
|
7
7
|
export declare const SHELLS: readonly ["powershell", "gitbash", "msys2", "wsl"];
|
|
8
8
|
/** The backend used when the caller does not name one. */
|
|
9
9
|
export declare const DEFAULT_SHELL: ShellId;
|
|
10
|
-
/** Settings namespace backing the user-chosen default terminal. */
|
|
11
|
-
export declare const SETTINGS_NAMESPACE = "bash-terminal";
|
|
12
10
|
/** Static shape of the runtime configuration schema. */
|
|
13
11
|
export interface ConfigValues {
|
|
14
12
|
defaultShell: string;
|
package/lib/index.js
CHANGED
|
@@ -33,8 +33,6 @@ export const inject = ["tools", "systemPrompt", "shellEnv", "subprocess", "setti
|
|
|
33
33
|
export const SHELLS = ["powershell", "gitbash", "msys2", "wsl"];
|
|
34
34
|
/** The backend used when the caller does not name one. */
|
|
35
35
|
export const DEFAULT_SHELL = "powershell";
|
|
36
|
-
/** Settings namespace backing the user-chosen default terminal. */
|
|
37
|
-
export const SETTINGS_NAMESPACE = "bash-terminal";
|
|
38
36
|
/** Default per-command timeout (ms). */
|
|
39
37
|
const DEFAULT_TIMEOUT_MS = 120000;
|
|
40
38
|
/** Upper bound a caller's timeoutMs is capped to. */
|
|
@@ -56,7 +54,7 @@ const ENV_OVERRIDES = {
|
|
|
56
54
|
};
|
|
57
55
|
/** Runtime configuration schema. */
|
|
58
56
|
export const Config = z.object({
|
|
59
|
-
defaultShell: z.string().default(DEFAULT_SHELL),
|
|
57
|
+
defaultShell: z.string().default(DEFAULT_SHELL).volatile(),
|
|
60
58
|
timeoutMs: z.number().default(DEFAULT_TIMEOUT_MS),
|
|
61
59
|
maxTimeoutMs: z.number().default(MAX_TIMEOUT_MS),
|
|
62
60
|
pwshPath: z.string().default(""),
|
|
@@ -500,11 +498,19 @@ export function apply(ctx, config = {}) {
|
|
|
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;
|
|
@@ -529,7 +535,7 @@ export function apply(ctx, config = {}) {
|
|
|
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,7 +650,7 @@ 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
656
|
throw new Error(`dsh-bash-terminal: ${shell} backend unavailable - executable not found. Install it or set the corresponding *Path config.`);
|
package/package.json
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-bash-terminal-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"publishConfig": {
|
|
5
|
-
"
|
|
6
|
-
"access": "public",
|
|
7
|
-
"tag": "dsh-0.1.5"
|
|
5
|
+
"tag": "dsh-0.1.7"
|
|
8
6
|
},
|
|
9
7
|
"description": "DSH plugin: one shell tool that runs commands through PowerShell, Git Bash, MSYS2, or WSL on Windows, with a user-chosen default terminal in the Web UI settings. TypeScript rewrite of MAXeaglet/dsh-bash-terminal with working MSYS2/MINGW64 support.",
|
|
10
8
|
"author": "drscrewdriver",
|
|
@@ -31,7 +29,7 @@
|
|
|
31
29
|
],
|
|
32
30
|
"engines": {
|
|
33
31
|
"node": ">=22",
|
|
34
|
-
"dsh": ">=0.1.
|
|
32
|
+
"dsh": ">=0.1.7-rc.1 <0.1.8-0"
|
|
35
33
|
},
|
|
36
34
|
"type": "module",
|
|
37
35
|
"main": "lib/index.js",
|
|
@@ -76,21 +74,21 @@
|
|
|
76
74
|
},
|
|
77
75
|
"peerDependencies": {
|
|
78
76
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
79
|
-
"@deepseek-ai/dsh-tools": ">=0.1.
|
|
80
|
-
"@deepseek-ai/dsh-settings": ">=0.1.
|
|
81
|
-
"@deepseek-ai/dsh-llm": ">=0.1.
|
|
82
|
-
"@deepseek-ai/dsh-shell": ">=0.1.
|
|
83
|
-
"@deepseek-ai/dsh-sandbox": ">=0.1.
|
|
84
|
-
"@deepseek-ai/dsh-timeout": ">=0.1.
|
|
85
|
-
"@deepseek-ai/dsh-client-store": ">=0.1.
|
|
86
|
-
"@deepseek-ai/dsh-client-locale": ">=0.1.
|
|
87
|
-
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.
|
|
88
|
-
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.
|
|
89
|
-
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.
|
|
77
|
+
"@deepseek-ai/dsh-tools": ">=0.1.7-rc.1 <0.1.8-0",
|
|
78
|
+
"@deepseek-ai/dsh-settings": ">=0.1.7-rc.1 <0.1.8-0",
|
|
79
|
+
"@deepseek-ai/dsh-llm": ">=0.1.7-rc.1 <0.1.8-0",
|
|
80
|
+
"@deepseek-ai/dsh-shell": ">=0.1.7-rc.1 <0.1.8-0",
|
|
81
|
+
"@deepseek-ai/dsh-sandbox": ">=0.1.7-rc.1 <0.1.8-0",
|
|
82
|
+
"@deepseek-ai/dsh-timeout": ">=0.1.7-rc.1 <0.1.8-0",
|
|
83
|
+
"@deepseek-ai/dsh-client-store": ">=0.1.7-rc.1 <0.1.8-0",
|
|
84
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.7-rc.1 <0.1.8-0",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.7-rc.1 <0.1.8-0",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.7-rc.1 <0.1.8-0",
|
|
87
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.7-rc.1 <0.1.8-0",
|
|
90
88
|
"react": "^18.2.0"
|
|
91
89
|
},
|
|
92
90
|
"dependencies": {
|
|
93
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
91
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
94
92
|
"node-pty": "^1.1.0"
|
|
95
93
|
},
|
|
96
94
|
"devDependencies": {
|
package/src/client.tsx
CHANGED
|
@@ -16,7 +16,8 @@ import { defineStore } from "@deepseek-ai/dsh-client-store";
|
|
|
16
16
|
import { IconChevronDownOutline14, Menu } from "@deepseek-ai/dsh-client-ui-primitives";
|
|
17
17
|
|
|
18
18
|
const SETTINGS_NS = "settings.bash-terminal";
|
|
19
|
-
|
|
19
|
+
/** Entry id of this plugin in the active profile (cordis.patch.yml). */
|
|
20
|
+
const ENTRY_ID = "tool-bash-terminal";
|
|
20
21
|
const SHELLS = ["powershell", "gitbash", "msys2", "wsl"] as const;
|
|
21
22
|
|
|
22
23
|
type ShellOption = (typeof SHELLS)[number];
|
|
@@ -55,7 +56,7 @@ const en: Record<string, string> = {
|
|
|
55
56
|
"shell.wsl": "WSL"
|
|
56
57
|
};
|
|
57
58
|
|
|
58
|
-
export const inject = ["slots", "locale", "
|
|
59
|
+
export const inject = ["slots", "locale", "configForms"];
|
|
59
60
|
|
|
60
61
|
/** Row state snapshot served through the settings store. */
|
|
61
62
|
interface RowState {
|
|
@@ -112,23 +113,23 @@ function ShellPreferenceRow({ t, useStore, setShell }: ShellPreferenceRowProps)
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
interface SettingsSnapshot {
|
|
115
|
-
status:
|
|
116
|
+
status: "loading" | "ready" | "unavailable";
|
|
116
117
|
value?: { defaultShell?: string };
|
|
117
|
-
revision: number;
|
|
118
|
+
revision: number | undefined;
|
|
118
119
|
writable: boolean;
|
|
119
120
|
}
|
|
120
121
|
|
|
121
|
-
interface
|
|
122
|
+
interface ConfigFormBinding {
|
|
122
123
|
getSnapshot(): SettingsSnapshot;
|
|
123
124
|
subscribe(fn: () => void): () => void;
|
|
124
|
-
set(field: string, value: string):
|
|
125
|
-
unset():
|
|
125
|
+
set(field: string, value: string): Promise<boolean>;
|
|
126
|
+
unset(field: string): Promise<boolean>;
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
interface ClientContext {
|
|
129
130
|
effect(fn: () => unknown, name?: string): unknown;
|
|
130
131
|
locale: { register(ns: string, dicts: Record<string, Record<string, string>>): unknown };
|
|
131
|
-
|
|
132
|
+
configForms: { get(entryId: string): ConfigFormBinding };
|
|
132
133
|
slots: {
|
|
133
134
|
inject(slot: string, fn: () => unknown, name?: string): void;
|
|
134
135
|
register(options: Record<string, unknown>, Component: unknown): Record<string, unknown>;
|
|
@@ -145,7 +146,7 @@ interface RowStore {
|
|
|
145
146
|
|
|
146
147
|
export function apply(ctx: ClientContext): void {
|
|
147
148
|
ctx.effect(() => ctx.locale.register(SETTINGS_NS, { zh, en }), "bash-terminal: settings dictionaries");
|
|
148
|
-
const scope = ctx.
|
|
149
|
+
const scope = ctx.configForms.get(ENTRY_ID);
|
|
149
150
|
const store = defineStore<RowState, { sync: (draft: RowState, shell?: string, revision?: number, writable?: boolean) => void }>({
|
|
150
151
|
init: (): RowState => ({ shell: "powershell", revision: -1, writable: false }),
|
|
151
152
|
actions: {
|
package/src/dsh-types.ts
CHANGED
|
@@ -303,7 +303,6 @@ export interface BashTerminalContext {
|
|
|
303
303
|
tools: ToolsSeam;
|
|
304
304
|
on(event: "system-prompt/assemble", handler: AssembleHandler): void;
|
|
305
305
|
shellEnv: ShellEnvSeam;
|
|
306
|
-
settings: SettingsSeam;
|
|
307
306
|
sandboxPolicy: SandboxPolicySeam;
|
|
308
307
|
sandbox: SandboxSeam;
|
|
309
308
|
get(key: string): unknown;
|
package/src/dsh.ts
CHANGED
|
@@ -52,6 +52,8 @@ export const escalationHintMarker = sandboxNs.escalationHintMarker as unknown as
|
|
|
52
52
|
/** Runtime config schema factory (schemastery fork). */
|
|
53
53
|
export interface SchemasterySchema {
|
|
54
54
|
default(value: unknown): SchemasterySchema;
|
|
55
|
+
/** 0.1.7+: expose the field on the auto-generated settings form. */
|
|
56
|
+
volatile(): SchemasterySchema;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export interface Schemastery {
|
package/src/index.ts
CHANGED
|
@@ -61,8 +61,6 @@ export const inject = ["tools", "systemPrompt", "shellEnv", "subprocess", "setti
|
|
|
61
61
|
export const SHELLS = ["powershell", "gitbash", "msys2", "wsl"] as const;
|
|
62
62
|
/** The backend used when the caller does not name one. */
|
|
63
63
|
export const DEFAULT_SHELL: ShellId = "powershell";
|
|
64
|
-
/** Settings namespace backing the user-chosen default terminal. */
|
|
65
|
-
export const SETTINGS_NAMESPACE = "bash-terminal";
|
|
66
64
|
/** Default per-command timeout (ms). */
|
|
67
65
|
const DEFAULT_TIMEOUT_MS = 120000;
|
|
68
66
|
/** Upper bound a caller's timeoutMs is capped to. */
|
|
@@ -84,6 +82,11 @@ const ENV_OVERRIDES: Record<string, string> = {
|
|
|
84
82
|
GIT_PAGER: "cat"
|
|
85
83
|
};
|
|
86
84
|
|
|
85
|
+
/** Live reference the 0.1.7 loader hands `apply` for `.volatile()` config fields. */
|
|
86
|
+
interface VolatileRef<T> {
|
|
87
|
+
get(): T;
|
|
88
|
+
}
|
|
89
|
+
|
|
87
90
|
/** Static shape of the runtime configuration schema. */
|
|
88
91
|
export interface ConfigValues {
|
|
89
92
|
defaultShell: string;
|
|
@@ -97,7 +100,7 @@ export interface ConfigValues {
|
|
|
97
100
|
|
|
98
101
|
/** Runtime configuration schema. */
|
|
99
102
|
export const Config = z.object({
|
|
100
|
-
defaultShell: z.string().default(DEFAULT_SHELL),
|
|
103
|
+
defaultShell: z.string().default(DEFAULT_SHELL).volatile(),
|
|
101
104
|
timeoutMs: z.number().default(DEFAULT_TIMEOUT_MS),
|
|
102
105
|
maxTimeoutMs: z.number().default(MAX_TIMEOUT_MS),
|
|
103
106
|
pwshPath: z.string().default(""),
|
|
@@ -671,15 +674,18 @@ export function apply(ctx: BashTerminalContext, config: Partial<ConfigValues> =
|
|
|
671
674
|
}
|
|
672
675
|
const backgroundEnabled = true;
|
|
673
676
|
const paths = resolveAllPaths(config);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
+
// 0.1.7: `defaultShell` is a `.volatile()` config field — the loader hands
|
|
678
|
+
// `apply` a live ref and the latest value is resolved on every read; there
|
|
679
|
+
// is no settings registration call anymore (removed with the 0.1.7 host).
|
|
680
|
+
const currentShell = (): string => {
|
|
681
|
+
const v = config.defaultShell as string | VolatileRef<string> | undefined;
|
|
682
|
+
if (typeof v === "string") return v;
|
|
683
|
+
const got = typeof v?.get === "function" ? v.get() : undefined;
|
|
684
|
+
return typeof got === "string" ? got : DEFAULT_SHELL;
|
|
685
|
+
};
|
|
686
|
+
if (!(SHELLS as readonly string[]).includes(currentShell())) {
|
|
687
|
+
throw new Error(`dsh-bash-terminal: invalid defaultShell ${JSON.stringify(currentShell())}`);
|
|
677
688
|
}
|
|
678
|
-
const settingsScope = ctx.settings.register(
|
|
679
|
-
SETTINGS_NAMESPACE,
|
|
680
|
-
z.object({ defaultShell: z.union(SHELLS.map((s) => z.const(s))).default(defaultShell) }),
|
|
681
|
-
{ base: { defaultShell } }
|
|
682
|
-
);
|
|
683
689
|
/** Official sandbox-escalation surface (mirrors tool-bash): advertise the
|
|
684
690
|
* escalation modes whenever the deployment confines. */
|
|
685
691
|
const escalationModes = ESCALATION_TARGETS;
|
|
@@ -711,7 +717,7 @@ export function apply(ctx: BashTerminalContext, config: Partial<ConfigValues> =
|
|
|
711
717
|
|
|
712
718
|
const toolName = "shell";
|
|
713
719
|
const terminalRegistry = createTerminalRegistry(ctx);
|
|
714
|
-
ctx.tools.register(terminalTool(ctx, terminalRegistry, paths, () =>
|
|
720
|
+
ctx.tools.register(terminalTool(ctx, terminalRegistry, paths, () => currentShell()));
|
|
715
721
|
|
|
716
722
|
// The model-facing description must track the user's chosen default
|
|
717
723
|
// terminal: a static description listing every backend leaves the model
|
|
@@ -720,7 +726,7 @@ export function apply(ctx: BashTerminalContext, config: Partial<ConfigValues> =
|
|
|
720
726
|
// without a restart.
|
|
721
727
|
ctx.on("system-prompt/assemble", async (_assembly, _context, next) => {
|
|
722
728
|
const assembled = await next();
|
|
723
|
-
const description = toolDescription(backgroundEnabled,
|
|
729
|
+
const description = toolDescription(backgroundEnabled, currentShell());
|
|
724
730
|
const tools = Array.isArray(assembled.tools)
|
|
725
731
|
? assembled.tools.map((tool) => (tool.name === toolName ? { ...tool, description } : tool))
|
|
726
732
|
: assembled.tools;
|
|
@@ -729,7 +735,7 @@ export function apply(ctx: BashTerminalContext, config: Partial<ConfigValues> =
|
|
|
729
735
|
|
|
730
736
|
ctx.tools.register(defineTool<ShellToolResult>({
|
|
731
737
|
name: toolName,
|
|
732
|
-
description: toolDescription(backgroundEnabled,
|
|
738
|
+
description: toolDescription(backgroundEnabled, currentShell()),
|
|
733
739
|
parameters: {
|
|
734
740
|
command: {
|
|
735
741
|
type: "string",
|
|
@@ -826,7 +832,7 @@ export function apply(ctx: BashTerminalContext, config: Partial<ConfigValues> =
|
|
|
826
832
|
},
|
|
827
833
|
async execute(args, exec) {
|
|
828
834
|
const v = validateArgs(args);
|
|
829
|
-
const shell =
|
|
835
|
+
const shell = currentShell();
|
|
830
836
|
const argv0 = buildArgv(shell, v.command, paths, v.distro);
|
|
831
837
|
if (argv0[0] === undefined) {
|
|
832
838
|
throw new Error(`dsh-bash-terminal: ${shell} backend unavailable - executable not found. Install it or set the corresponding *Path config.`);
|