dsh-gitbash-shell 0.32.0 → 0.32.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/CHANGELOG.md +9 -0
- package/dsh.plugin.json +1 -1
- package/package.json +1 -1
- package/src/client.js +12 -44
- package/src/index.js +22 -186
- package/src/shell.js +4 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
> 倒序排列,新版本条目在最上面。条目格式:`## vX.Y.Z — YYYY-MM-DD` + 类型(feat / fix / docs / chore)+ 要点 + 相关链接。
|
|
4
4
|
> 纪律见 AGENTS.md「变更记录纪律」:发版前先更新本文件并随版本提交;事故复盘、复现与真机验证记录也记在这里。
|
|
5
5
|
|
|
6
|
+
## v0.32.1 — 2026-09-28
|
|
7
|
+
|
|
8
|
+
**类型**:chore(清掉 v0.32.0 遗留的 legacy settings 死代码)+ fix(冒烟里 mac 平台误判的 toolchain 路径用例)
|
|
9
|
+
|
|
10
|
+
- **legacy settings 面整体删除**(v0.32.0 识别的死代码,当时保守留了一手):宿主 settings 服务自 0.1.7 起只有 describe()/update()(packages/settings/settings/src/index.ts 方法面核对),没有 register(SettingsScope)也没有 get(ns) ⇒ 全部探测分支不可达。删除:① host 半的 legacy settings namespace 注册块(legacySettings 探测 + ctx.inject(['settings']) 注册 schema + scope.watch 接线);② makeLiveReader 的 era 探测(legacy 恒 false,"legacy || !hasConfig" 收敛为 !hasConfig 的等价 fallback);③ 四个 settings.get(ns) 读取器(readPosixPaths / readDialectSettings / readAdoptSidebar / readSuppressPeerCordis,生产调用全在死分支里)与 SETTINGS_NAMESPACE 常量;④ sidebarScope(唯一赋值点在死代码里)及其 polling watch 挂钩;⑤ adoptSidebarShell.readShell 的 get(ns) 死分支(describe 分支保留,0.1.7 上在用);⑥ shell.js dialectSettings() 的同款 get(ns) 分支;⑦ client 半的 settingsScope 注入段与 settings.plugin.item 旧座位(设置卡只剩 plugins.bundle.config 详情页座位)。行数:src/index.js 2549 → 约 2470 行。
|
|
11
|
+
- **行为不变**:所有被删分支在 >=0.1.7-rc 宿主上均不可达;每个消费点的现役路径(describe() 读取 / 行 Config volatile 读取)逐字未动。冒烟 96 项全绿,新增防复活守卫(源码不得再出现 settings.register / SETTINGS_NAMESPACE)。
|
|
12
|
+
- **fix(tests):toolchain PATH 扫描用例在非 Windows 平台误判**——实现永远以 Windows 反斜杠拼接(该扫描只在 win32 跑,行为正确),期望却用 process.platform 的 sep 构造,mac/Linux 上必挂。期望改为字面量反斜杠;该用例从 v0.32.0 起的既有的平台失败就此消除。
|
|
13
|
+
- 同步:AGENTS.md 条目 0(死代码段改为「已整体删除」)、4b(SERVICE READ RULE 更新为 makeLiveReader)、§4e/§4g/§4i 的双时代措辞收敛;验证清单与发布 checklist 更新(含 minimumReleaseAge 冷却提示)。
|
|
14
|
+
|
|
6
15
|
## v0.32.0 — 2026-09-28
|
|
7
16
|
|
|
8
17
|
**类型**:chore(宿主下限提高到 >= 0.1.7-rc:删除 0.1.6 以前的全部兼容路径,插件瘦身六分之一)
|
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-gitbash-shell",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.1",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"description": "Windows 全模式 Git Bash:用 Git for Windows bash 替换 PowerShell 执行器,声明式注册 standard/minimal/code/cordis 的 Git Bash 变体 preset(preset id 永不变)。联动:dsh-ptc-cordis-preset(两者同装时 PTC 创造模式带 Git Bash 行且可去重)+ dsh-better-sidebar(终端 UI 标签与模型 terminal_* 工具自动切到 Git Bash)。",
|
|
6
6
|
"engines": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-gitbash-shell",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.1",
|
|
4
4
|
"description": "Windows 上让 agent 的每条 shell 命令改经 Git for Windows bash 执行;物化四个内置预设的 Git Bash 变体,统一 MSYS 盘根路径方言,侧栏终端接管可开关。· Run every agent shell command through Git for Windows bash on Windows; materialize Git Bash variants of the built-in presets, unify the MSYS drive-root path dialect, and adopt the sidebar terminal behind a switch.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
package/src/client.js
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
* dsh-gitbash-shell — browser half (hand-written ModuleLoader bundle).
|
|
3
3
|
*
|
|
4
4
|
* ONE job: the Settings → Plugins card that gates the unified POSIX path
|
|
5
|
-
* dialect. The
|
|
6
|
-
*
|
|
7
|
-
* half (src/index.js) has registered the 'gitbash-shell' settings namespace.
|
|
5
|
+
* dialect. The card lives on the plugin's detail page (the
|
|
6
|
+
* plugins.bundle.config seat, keyed by the package name).
|
|
8
7
|
*
|
|
9
|
-
* The card flips one boolean — posixPaths — through
|
|
8
|
+
* The card flips one boolean — posixPaths — through this plugin's row Config form:
|
|
10
9
|
* on → the host injects the order-126 directive (every tool takes MSYS
|
|
11
10
|
* drive roots /c/...) and the tools/execute wrapper translates
|
|
12
11
|
* path-argument fields (/x/ → X:/) for the Node-backed file tools;
|
|
@@ -21,7 +20,7 @@
|
|
|
21
20
|
* (react and @deepseek-ai/dsh-client-ui-primitives only, smoke-enforced);
|
|
22
21
|
* - plain React.createElement, no JSX/TS; components at module level;
|
|
23
22
|
* - dsh.client.inject in package.json lists the packages that must load
|
|
24
|
-
* first so locale /
|
|
23
|
+
* first so locale / configForms / slots exist when this applies;
|
|
25
24
|
* - copy ships in three layers: zh/en inline, one LOCALES entry per third
|
|
26
25
|
* language (each preceded by a locale marker line), every dictionary
|
|
27
26
|
* key-aligned with zh (smoke-enforced) and read through a live lookup —
|
|
@@ -1872,7 +1871,7 @@ window.__ModuleLoader__.load({
|
|
|
1872
1871
|
|
|
1873
1872
|
// dsh 0.1.6-alpha.2: the Plugins page renders this card through the
|
|
1874
1873
|
// `plugins.bundle.config` slot with view="page" — the page draws the
|
|
1875
|
-
// title itself
|
|
1874
|
+
// title itself; the collapsible shell only shows on the popup seat.
|
|
1876
1875
|
var pageView = props.view === "page";
|
|
1877
1876
|
|
|
1878
1877
|
var mounts = snap.value.virtualMounts !== false;
|
|
@@ -2637,32 +2636,16 @@ window.__ModuleLoader__.load({
|
|
|
2637
2636
|
|
|
2638
2637
|
/**
|
|
2639
2638
|
* Required client services: only era-guaranteed ones are hard-injected;
|
|
2640
|
-
* the settings face is acquired OPTIONALLY (
|
|
2641
|
-
*
|
|
2642
|
-
* forever, taking the card down with it).
|
|
2639
|
+
* the settings face is acquired OPTIONALLY (a missing configForms on a
|
|
2640
|
+
* stripped-down host must not take the card down with it).
|
|
2643
2641
|
*/
|
|
2644
2642
|
exports.inject = ["locale", "slots"];
|
|
2645
2643
|
|
|
2646
2644
|
exports.apply = function (ctx) {
|
|
2647
|
-
//
|
|
2645
|
+
// The settings face: one ConfigForm per live profile entry; the form
|
|
2646
|
+
// key is the row id "gitbash-shell" (contract: getSnapshot/set/unset).
|
|
2648
2647
|
var scope = null;
|
|
2649
2648
|
|
|
2650
|
-
// OLD era (dsh <= 0.1.6): bound settings scope.
|
|
2651
|
-
try {
|
|
2652
|
-
ctx.inject(["settingsScope"], function (sctx) {
|
|
2653
|
-
try {
|
|
2654
|
-
var svc = sctx && sctx.settingsScope;
|
|
2655
|
-
if (svc && typeof svc.bind === "function") scope = svc.bind({ namespace: SETTINGS_NAMESPACE });
|
|
2656
|
-
} catch (error) {
|
|
2657
|
-
console.warn(TAG + " settingsScope acquisition failed:", error && error.message ? error.message : error);
|
|
2658
|
-
}
|
|
2659
|
-
});
|
|
2660
|
-
} catch (error) {
|
|
2661
|
-
console.warn(TAG + " settingsScope wiring failed:", error && error.message ? error.message : error);
|
|
2662
|
-
}
|
|
2663
|
-
|
|
2664
|
-
// NEW era (dsh >= 0.1.7): one ConfigForm per live profile entry; the form
|
|
2665
|
-
// key is the row id "gitbash-shell" (same string as the old namespace).
|
|
2666
2649
|
try {
|
|
2667
2650
|
ctx.inject(["configForms"], function (fctx) {
|
|
2668
2651
|
try {
|
|
@@ -2714,23 +2697,8 @@ window.__ModuleLoader__.load({
|
|
|
2714
2697
|
// members (top-level options fields do NOT reach the component).
|
|
2715
2698
|
return { scope: scope, ctx: ctx };
|
|
2716
2699
|
};
|
|
2717
|
-
//
|
|
2718
|
-
|
|
2719
|
-
return slots.register({
|
|
2720
|
-
name: "settings.plugin.item",
|
|
2721
|
-
key: SETTINGS_NAMESPACE,
|
|
2722
|
-
locale: NS,
|
|
2723
|
-
inject: injected,
|
|
2724
|
-
}, function CardWithLocale(props) {
|
|
2725
|
-
/* The registration's locale field also hands out the framework's own
|
|
2726
|
-
t seat; the plugin's lookup wins (21 locale tags against the catalog's
|
|
2727
|
-
zh/en), passed last so no prop merge order can override it. */
|
|
2728
|
-
return E(LocaleLive, { ctx: ctx, t: t, cardProps: props });
|
|
2729
|
-
});
|
|
2730
|
-
});
|
|
2731
|
-
// dsh 0.1.6-alpha.2+: the Plugins page's bundle configuration seat,
|
|
2732
|
-
// keyed by the PACKAGE name. Each inject waits for its own slot
|
|
2733
|
-
// declaration, so exactly one seat is live on any host version.
|
|
2700
|
+
// The Plugins page's bundle configuration seat, keyed by the PACKAGE
|
|
2701
|
+
// name. Each inject waits for its own slot declaration.
|
|
2734
2702
|
/* Root-level popup seat: rendered regardless of which page is open,
|
|
2735
2703
|
which is the point — the user may never open settings. */
|
|
2736
2704
|
slots.inject("shell.overlay", function () {
|
|
@@ -2750,7 +2718,7 @@ window.__ModuleLoader__.load({
|
|
|
2750
2718
|
locale: NS,
|
|
2751
2719
|
inject: injected,
|
|
2752
2720
|
}, function BundleConfigWithBoundary(props) {
|
|
2753
|
-
/* Same LocaleLive wrap
|
|
2721
|
+
/* Same LocaleLive wrap: the plugin's 21-tag
|
|
2754
2722
|
dictionary wins over the catalog's zh/en t seat. */
|
|
2755
2723
|
return E(LocaleLive, { ctx: ctx, t: t, cardProps: props });
|
|
2756
2724
|
});
|
package/src/index.js
CHANGED
|
@@ -408,14 +408,12 @@ export function installRegisterShim(reg) {
|
|
|
408
408
|
// ── unified path dialect: settings namespace + gate (v0.9.0) ───────────────
|
|
409
409
|
//
|
|
410
410
|
// The dialect (directive + translation wrapper) is OFF by default and gated
|
|
411
|
-
// by the posixPaths boolean
|
|
412
|
-
// flipped from the
|
|
413
|
-
// text closure returns '' while off — empty context contributions
|
|
414
|
-
// dropped at assembly, so a disabled dialect adds zero prompt noise; the
|
|
411
|
+
// by the posixPaths boolean on this plugin's row Config (volatile, read live
|
|
412
|
+
// per dispatch), flipped from the plugin's settings card (src/client.js). The
|
|
413
|
+
// directive's text closure returns '' while off — empty context contributions
|
|
414
|
+
// are dropped at assembly, so a disabled dialect adds zero prompt noise; the
|
|
415
415
|
// wrapper reads the same value per dispatch and passes calls through.
|
|
416
416
|
|
|
417
|
-
const SETTINGS_NAMESPACE = 'gitbash-shell'
|
|
418
|
-
|
|
419
417
|
/**
|
|
420
418
|
* dsh >= 0.1.7 marks a Config field live-editable without remount; a
|
|
421
419
|
* 0.1.6-era schemastery predates the method and the guard keeps this module
|
|
@@ -493,14 +491,16 @@ export function valueOf(value) {
|
|
|
493
491
|
* @returns {{ dialect: () => object, posix: () => boolean, adoptSidebar: () => boolean, suppressPeerCordis: () => boolean }}
|
|
494
492
|
*/
|
|
495
493
|
function makeLiveReader(ctx, config) {
|
|
496
|
-
let legacy = false
|
|
497
|
-
try {
|
|
498
|
-
const settings = ctx.get('settings')
|
|
499
|
-
legacy = !!(settings && typeof settings.register === 'function')
|
|
500
|
-
} catch { legacy = false }
|
|
501
494
|
const hasConfig = !!(config && typeof config === 'object')
|
|
502
495
|
const dialect = () => {
|
|
503
|
-
if (
|
|
496
|
+
if (!hasConfig) {
|
|
497
|
+
// No row Config (schemastery unresolvable): everything off except the
|
|
498
|
+
// opt-out booleans, the exact shape the old fallback returned.
|
|
499
|
+
return {
|
|
500
|
+
posixPaths: false, virtualMounts: false, globSplit: false, errorDialect: false,
|
|
501
|
+
codePaths: false, gitAutocrlf: false, bashPath: '', subagentDialect: true, autoTerminalShell: true,
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
504
|
const bash = valueOf(config.bashPath)
|
|
505
505
|
return {
|
|
506
506
|
posixPaths: valueOf(config.posixPaths) === true,
|
|
@@ -522,8 +522,8 @@ function makeLiveReader(ctx, config) {
|
|
|
522
522
|
posix: () => dialect().posixPaths === true,
|
|
523
523
|
adoptSidebar: () => dialect().adoptSidebar !== false,
|
|
524
524
|
autoTerminalShell: () => dialect().autoTerminalShell !== false,
|
|
525
|
-
// Default OFF
|
|
526
|
-
suppressPeerCordis: () => (
|
|
525
|
+
// Default OFF: only an explicit true asks for deduplication.
|
|
526
|
+
suppressPeerCordis: () => (hasConfig ? valueOf(config.suppressPeerCordis) === true : false),
|
|
527
527
|
}
|
|
528
528
|
}
|
|
529
529
|
|
|
@@ -568,79 +568,6 @@ const PATH_DIALECT_DESCRIPTION = 'Path dialect for tool calls and tool results:
|
|
|
568
568
|
// They cannot ride the shell-env registry below: that registry accepts DSH_*
|
|
569
569
|
// facts only, and a non-DSH key throws the whole contribution away.
|
|
570
570
|
|
|
571
|
-
/** Read the posixPaths switch from the live settings service; never throws. */
|
|
572
|
-
export function readPosixPaths(ctxLike) {
|
|
573
|
-
try {
|
|
574
|
-
const settings = ctxLike && typeof ctxLike.get === 'function' ? ctxLike.get('settings') : undefined
|
|
575
|
-
const value = settings && typeof settings.get === 'function' ? settings.get(SETTINGS_NAMESPACE) : undefined
|
|
576
|
-
return !!(value && value.posixPaths === true)
|
|
577
|
-
} catch {
|
|
578
|
-
return false
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
/**
|
|
583
|
-
* Read every dialect switch at once (v0.19.0): posixPaths gates the whole
|
|
584
|
-
* dialect; virtualMounts gates the bash virtual mounts + ~ + $VAR expansion
|
|
585
|
-
* (off = strict drive-root-only translation); globSplit gates the absolute
|
|
586
|
-
* glob-pattern rewrite; errorDialect gates error-message translation and the
|
|
587
|
-
* NUL guidance block; bashPath (optional) joins the Git-root probe candidates
|
|
588
|
-
* first. All default ON (schema defaults); never throws.
|
|
589
|
-
*/
|
|
590
|
-
export function readDialectSettings(ctxLike) {
|
|
591
|
-
const fallback = { posixPaths: false, virtualMounts: false, globSplit: false, errorDialect: false, codePaths: false, gitAutocrlf: false, bashPath: '', subagentDialect: true, autoTerminalShell: true }
|
|
592
|
-
try {
|
|
593
|
-
const settings = ctxLike && typeof ctxLike.get === 'function' ? ctxLike.get('settings') : undefined
|
|
594
|
-
const value = settings && typeof settings.get === 'function' ? settings.get(SETTINGS_NAMESPACE) : undefined
|
|
595
|
-
const v = value && typeof value === 'object' ? value : {}
|
|
596
|
-
return {
|
|
597
|
-
posixPaths: v.posixPaths === true,
|
|
598
|
-
virtualMounts: v.virtualMounts === true,
|
|
599
|
-
globSplit: v.globSplit === true,
|
|
600
|
-
errorDialect: v.errorDialect === true,
|
|
601
|
-
codePaths: v.codePaths === true,
|
|
602
|
-
// An old host without the key keeps the default (delegated agents covered).
|
|
603
|
-
subagentDialect: v.subagentDialect !== false,
|
|
604
|
-
// Default ON: a host without the key still gets the terminal adoption.
|
|
605
|
-
autoTerminalShell: v.autoTerminalShell !== false,
|
|
606
|
-
gitAutocrlf: v.gitAutocrlf === true,
|
|
607
|
-
bashPath: typeof v.bashPath === 'string' ? v.bashPath : '',
|
|
608
|
-
}
|
|
609
|
-
} catch {
|
|
610
|
-
return fallback
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* Read the adoptSidebar switch (v0.15.0, default ON). Unlike posixPaths the
|
|
616
|
-
* default is on, so only an explicit false disables the takeover.
|
|
617
|
-
*/
|
|
618
|
-
export function readAdoptSidebar(ctxLike) {
|
|
619
|
-
try {
|
|
620
|
-
const settings = ctxLike && typeof ctxLike.get === 'function' ? ctxLike.get('settings') : undefined
|
|
621
|
-
const value = settings && typeof settings.get === 'function' ? settings.get(SETTINGS_NAMESPACE) : undefined
|
|
622
|
-
return !(value && value.adoptSidebar === false)
|
|
623
|
-
} catch {
|
|
624
|
-
return true
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
/**
|
|
629
|
-
* Read the peer-dedupe switch (v0.25.0, default OFF) from the OLD era's
|
|
630
|
-
* registered namespace — on dsh >= 0.1.7 the row Config is the surface and
|
|
631
|
-
* `makeLiveReader` reads it directly. Never throws.
|
|
632
|
-
*/
|
|
633
|
-
export function readSuppressPeerCordis(ctxLike) {
|
|
634
|
-
try {
|
|
635
|
-
const settings = ctxLike && typeof ctxLike.get === 'function' ? ctxLike.get('settings') : undefined
|
|
636
|
-
const value = settings && typeof settings.get === 'function' ? settings.get(SETTINGS_NAMESPACE) : undefined
|
|
637
|
-
return !!(value && value.suppressPeerCordis === true)
|
|
638
|
-
} catch {
|
|
639
|
-
return false
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
|
|
644
571
|
// Windows absolute path -> MSYS drive-root form, for rewriting PROSE in place
|
|
645
572
|
// (v0.10.0). Quoted spaced paths ("C:\Program Files\Git") are matched whole; a bare
|
|
646
573
|
// path stops at a closing punctuation and crosses a space ONLY into a token that
|
|
@@ -1470,10 +1397,6 @@ const SIDEBAR_NS = 'dsh-better-sidebar'
|
|
|
1470
1397
|
const SIDEBAR_TRIES = 12
|
|
1471
1398
|
const SIDEBAR_RETRY_MS = 1500
|
|
1472
1399
|
|
|
1473
|
-
// Owner scope of the gitbash-shell namespace once registered (shared with
|
|
1474
|
-
// the register callback so a late registration can reconcile + watch).
|
|
1475
|
-
let sidebarScope = undefined
|
|
1476
|
-
|
|
1477
1400
|
// Reconciler installed by adoptSidebarShell; a no-op until then.
|
|
1478
1401
|
let reconcileSidebar = () => {}
|
|
1479
1402
|
|
|
@@ -1502,14 +1425,9 @@ function adoptSidebarShell(ctx, bashPath, readAdopt) {
|
|
|
1502
1425
|
const settings = ctx.get('settings')
|
|
1503
1426
|
if (!settings || typeof settings.update !== 'function') return null
|
|
1504
1427
|
try {
|
|
1505
|
-
//
|
|
1506
|
-
//
|
|
1507
|
-
//
|
|
1508
|
-
// without this branch the adoption was silently skipped on the new host.
|
|
1509
|
-
if (typeof settings.get === 'function') {
|
|
1510
|
-
const value = settings.get(SIDEBAR_NS)
|
|
1511
|
-
return value && typeof value === 'object' && typeof value.terminalShell === 'string' ? value.terminalShell : ''
|
|
1512
|
-
}
|
|
1428
|
+
// The sidebar's value lives in ITS row Config, projected into the
|
|
1429
|
+
// settings describe() list; the service exposes describe/update only
|
|
1430
|
+
// (the old `get(ns)` reader died with dsh 0.1.6).
|
|
1513
1431
|
if (typeof settings.describe === 'function') {
|
|
1514
1432
|
const entry = settings.describe().find((row) => row !== null && typeof row === 'object' && row.ns === SIDEBAR_NS)
|
|
1515
1433
|
const value = entry === undefined ? undefined : entry.value
|
|
@@ -1560,18 +1478,7 @@ function adoptSidebarShell(ctx, bashPath, readAdopt) {
|
|
|
1560
1478
|
const run = () => {
|
|
1561
1479
|
tried += 1
|
|
1562
1480
|
const ok = reconcileSidebar(readAdopt())
|
|
1563
|
-
if (ok)
|
|
1564
|
-
// The namespace scope may register after the settings service; hook
|
|
1565
|
-
// the live watch once it exists (idempotent via the effect disposer).
|
|
1566
|
-
if (sidebarScope && typeof sidebarScope.watch === 'function' && !run.watched) {
|
|
1567
|
-
run.watched = true
|
|
1568
|
-
try {
|
|
1569
|
-
const off = sidebarScope.watch((next) => { reconcileSidebar(next && next.adoptSidebar !== false) })
|
|
1570
|
-
ctx.effect(() => off, 'dsh-gitbash-shell: adoptSidebar watch (polling path)')
|
|
1571
|
-
} catch { /* best effort */ }
|
|
1572
|
-
}
|
|
1573
|
-
return
|
|
1574
|
-
}
|
|
1481
|
+
if (ok) return
|
|
1575
1482
|
if (tried < SIDEBAR_TRIES) {
|
|
1576
1483
|
timer = setTimeout(run, SIDEBAR_RETRY_MS)
|
|
1577
1484
|
return
|
|
@@ -1922,82 +1829,11 @@ export async function apply(ctx, config = {}) {
|
|
|
1922
1829
|
const disposeGitBash = ctx.provide('gitBash', gitBashCapability)
|
|
1923
1830
|
ctx.effect(() => disposeGitBash, 'dsh-gitbash-shell: gitBash capability')
|
|
1924
1831
|
|
|
1925
|
-
// Era-aware live settings:
|
|
1926
|
-
// (volatile,
|
|
1927
|
-
//
|
|
1928
|
-
// flipped knob lands on the next dispatch with zero wiring.
|
|
1832
|
+
// Era-aware live settings: every consumer below re-reads the row Config
|
|
1833
|
+
// refs on every use (volatile), so a flipped knob lands on the next
|
|
1834
|
+
// dispatch with zero wiring.
|
|
1929
1835
|
const liveSettings = makeLiveReader(ctx, config)
|
|
1930
1836
|
|
|
1931
|
-
// ── settings namespace: the posixPaths switch (default ON, v0.1.0) — OLD
|
|
1932
|
-
// hosts only; on dsh >= 0.1.7 the row Config above IS the surface.
|
|
1933
|
-
|
|
1934
|
-
// Served on the host so the Plugins tab pairs it with the browser card
|
|
1935
|
-
// (the tab dispatches Host-served namespaces ∩ registered cards). Dynamic
|
|
1936
|
-
// imports keep the zero-dependency smoke path importable; the schema MUST
|
|
1937
|
-
// be a callable schemastery object (dsh-settings calls schema(merged)).
|
|
1938
|
-
const legacySettings = (() => {
|
|
1939
|
-
try {
|
|
1940
|
-
const settings = ctx.get('settings')
|
|
1941
|
-
return !!(settings && typeof settings.register === 'function')
|
|
1942
|
-
} catch {
|
|
1943
|
-
return false
|
|
1944
|
-
}
|
|
1945
|
-
})()
|
|
1946
|
-
if (legacySettings) try {
|
|
1947
|
-
ctx.inject(['settings'], (sctx) => {
|
|
1948
|
-
Promise.resolve(import('@deepseek-ai/dsh-settings'))
|
|
1949
|
-
.then((ds) => {
|
|
1950
|
-
const settings = sctx && sctx.settings
|
|
1951
|
-
if (!settings || typeof settings.register !== 'function') return
|
|
1952
|
-
// The SAME copy the executor and the row Config were built from
|
|
1953
|
-
// (issue #12): one resolution per process, so the two faces of this
|
|
1954
|
-
// plugin can never disagree about the schema vocabulary.
|
|
1955
|
-
if (!Schema) return
|
|
1956
|
-
// Era probe: newer dsh register() takes a plain string; the older
|
|
1957
|
-
// one accepted the branded helper — one call satisfies both.
|
|
1958
|
-
const ns = typeof ds.settingsNamespace === 'function'
|
|
1959
|
-
? ds.settingsNamespace(SETTINGS_NAMESPACE)
|
|
1960
|
-
: SETTINGS_NAMESPACE
|
|
1961
|
-
const scope = settings.register(ns, Schema.object({
|
|
1962
|
-
posixPaths: Schema.boolean().default(true),
|
|
1963
|
-
virtualMounts: Schema.boolean().default(true),
|
|
1964
|
-
globSplit: Schema.boolean().default(true),
|
|
1965
|
-
errorDialect: Schema.boolean().default(true),
|
|
1966
|
-
codePaths: Schema.boolean().default(true),
|
|
1967
|
-
subagentDialect: Schema.boolean().default(true),
|
|
1968
|
-
gitAutocrlf: Schema.boolean().default(true),
|
|
1969
|
-
bashPath: Schema.string().default(''),
|
|
1970
|
-
adoptSidebar: Schema.boolean().default(true),
|
|
1971
|
-
// v0.29.0: official sidebar terminal adoption (default ON).
|
|
1972
|
-
autoTerminalShell: Schema.boolean().default(true),
|
|
1973
|
-
// v0.25.0: same switch as the row Config carries on dsh >= 0.1.7
|
|
1974
|
-
// (the OLD era has no cross-namespace edits, so this namespace is
|
|
1975
|
-
// the only side that can change it here).
|
|
1976
|
-
suppressPeerCordis: Schema.boolean().default(false),
|
|
1977
|
-
}))
|
|
1978
|
-
sidebarScope = scope
|
|
1979
|
-
console.log(`${TAG} settings namespace registered: ${SETTINGS_NAMESPACE} (posixPaths default on, adoptSidebar default on)`)
|
|
1980
|
-
// A late register (settings service up after the adoption polling
|
|
1981
|
-
// finished) still reconciles once, and the live watch flips the
|
|
1982
|
-
// takeover when the user toggles the card switch.
|
|
1983
|
-
try {
|
|
1984
|
-
if (typeof scope?.watch === 'function') {
|
|
1985
|
-
const off = scope.watch((next) => { reconcileSidebar(next && next.adoptSidebar !== false) })
|
|
1986
|
-
ctx.effect(() => off, 'dsh-gitbash-shell: adoptSidebar watch')
|
|
1987
|
-
}
|
|
1988
|
-
reconcileSidebar(readAdoptSidebar(ctx))
|
|
1989
|
-
} catch (error) {
|
|
1990
|
-
console.log(`${TAG} adoptSidebar watch wiring failed: ${error?.message ?? error}`)
|
|
1991
|
-
}
|
|
1992
|
-
})
|
|
1993
|
-
.catch((error) => {
|
|
1994
|
-
console.log(`${TAG} settings namespace registration FAILED: ${error && error.stack || String(error)}`)
|
|
1995
|
-
})
|
|
1996
|
-
})
|
|
1997
|
-
} catch (error) {
|
|
1998
|
-
console.log(`${TAG} settings inject wiring failed: ${error?.message ?? error}`)
|
|
1999
|
-
}
|
|
2000
|
-
|
|
2001
1837
|
// ── official shell-env fact: DSH_PATH_DIALECT (Windows only, gated; v0.11.0) ──
|
|
2002
1838
|
// dsh-shell-env owns the model-visible $DSH_* facts (host-plane service;
|
|
2003
1839
|
// the web composition injects it and publishes DSH_WEB_URL beside the
|
|
@@ -2516,4 +2352,4 @@ export async function apply(ctx, config = {}) {
|
|
|
2516
2352
|
|
|
2517
2353
|
}
|
|
2518
2354
|
// Test surface: pure helpers, no Cordis context required.
|
|
2519
|
-
export const _internal = { PRESET_IDS, PEER_COVERED_PRESET_ID, PEER_CAPABILITY, isDelegatedAgent, dialectApplies, PEER_PYTHON_FIELD, PEER_PYTHON_BACKEND_FIELD, peerFact, peerBackend, pythonBackendActive, effectivePresetIds,
|
|
2355
|
+
export const _internal = { PRESET_IDS, PEER_COVERED_PRESET_ID, PEER_CAPABILITY, isDelegatedAgent, dialectApplies, PEER_PYTHON_FIELD, PEER_PYTHON_BACKEND_FIELD, peerFact, peerBackend, pythonBackendActive, effectivePresetIds, translateDispatch, translateMsysPath, translatePathArguments, rewriteCodePaths, scanCodeLiterals, programPrelude, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, rewriteErrorMessage, rewriteFailureMessage, msysEcho, driveToMsys, pathEcho, ERROR_CONTENT_TOOLS, windowsToMsys, rewriteResultPaths, adoptSidebarShell, MARKER_FILE, classify, hashTree, installRegisterShim }
|
package/src/shell.js
CHANGED
|
@@ -316,19 +316,16 @@ export class GitBashSandboxExecutor extends SandboxBashExecutor {
|
|
|
316
316
|
* @returns {object} the request with the parity facts merged in
|
|
317
317
|
*/
|
|
318
318
|
/**
|
|
319
|
-
* The plugin row's live dialect settings
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
* applied. The new era reads the row Config's projected values from the form
|
|
324
|
-
* descriptors (the same read dsh-agent-lang uses for the `locale` namespace).
|
|
319
|
+
* The plugin row's live dialect settings. The settings service exposes only
|
|
320
|
+
* `describe()` / `update()`, so the row Config's projected values come from
|
|
321
|
+
* the form descriptors (the same read dsh-agent-lang uses for the `locale`
|
|
322
|
+
* namespace).
|
|
325
323
|
* @returns the row's settings object, or undefined when unavailable.
|
|
326
324
|
*/
|
|
327
325
|
dialectSettings() {
|
|
328
326
|
try {
|
|
329
327
|
const settings = this.ctx && typeof this.ctx.get === 'function' ? this.ctx.get('settings') : undefined
|
|
330
328
|
if (settings === undefined || settings === null) return undefined
|
|
331
|
-
if (typeof settings.get === 'function') return settings.get(SETTINGS_NAMESPACE)
|
|
332
329
|
if (typeof settings.describe === 'function') {
|
|
333
330
|
const entry = settings.describe().find((row) => row !== null && typeof row === 'object' && row.ns === SETTINGS_NAMESPACE)
|
|
334
331
|
return entry === undefined ? undefined : entry.value
|