dsh-gitbash-shell 0.25.1 → 0.26.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 CHANGED
@@ -3,6 +3,69 @@
3
3
  > 倒序排列,新版本条目在最上面。条目格式:`## vX.Y.Z — YYYY-MM-DD` + 类型(feat / fix / docs / chore)+ 要点 + 相关链接。
4
4
  > 纪律见 AGENTS.md「变更记录纪律」:发版前先更新本文件并随版本提交;事故复盘、复现与真机验证记录也记在这里。
5
5
 
6
+ ## v0.26.1 — 2026-09-25
7
+
8
+ **类型**:fix(v0.26.0 的 workflow 互斥按「意图」而非「生效态」收敛:后端不可用时用户会白丢 workflow 能力)
9
+
10
+ > v0.26.0 把互斥条件写成「对方能力报 `pythonRuntime: true`」——那是**用户意图**。当对方的 preflight 失败(包被移除、解释器不合格、Windows),`!!js` 兜底与组合实际仍跑 Node,而本插件却已经把四个变体的 `workflow-ptc`/`tool-workflow` 关掉了:用户白丢一项能力,且卡片显示"已开启"与实际不符。dsh-ptc-cordis-preset **v0.15.1** 在能力服务上加了**加法字段** `pythonBackend: 'python' | 'node'`(用与 `!!js` 完全相同的合取计算),本版据此收敛。
11
+
12
+ - **① 互斥只在真正生效时发生**:新增纯函数 `pythonBackendActive(capability)` = 「意图 `pythonRuntime` 为真 **且** 生效态为 `'python'`」;`pluginsFor({ …, pythonActive })` 的形参由 `pythonRuntime` 改名 **`pythonActive`**,语义写明「run_code 实际会用的后端」——`workflowOn = kind !== 'ptc' && pythonActive !== true`。
13
+ - **② 旧 peer 回退(兼容硬要求)**:`peerBackend()` 对缺字段 / 类型不符 / getter 抛错一律返回 `undefined`(绝不把"没报"读成 `'node'`),`pythonBackendActive` 此时**用意图顶替** ⇒ 对方 < 0.15.1 的行为与 v0.26.0 **完全一致**,不会因缺字段崩溃或改变既有联动。
14
+ - **③ 日志把"真换了"与"想换但没生效"分开**:生效 → `peer reports the experimental CPython run_code backend: workflow rows go off in every variant`;意图 on 但未生效 → `peer has the CPython switch on but the effective backend is node|unreported (older peer: the intent stands in): workflow rows stay on (reason in the host log)`。
15
+ - **④ 卡片显示真实状态(防御性实现,当前不可达)**:从**同一份 peer 快照**读可选的 `pythonBackend`;意图 on + 生效 `node` ⇒ 状态值显示「Python(实验性) · **后端不可用,当前仍为 Node(原因见宿主启动日志)**」并另起一行红字;新增第 7 个词典键 `python.degraded`(**21 门语言**同齐)。字段缺省(旧 peer)⇒ 卡片与 v0.26.0 **逐字节一致**(不显示降级态)。
16
+ - **可达性拆分(Lead 裁决 A,2026-09-25)**:**「意图 on + 生效 node」这个状态本身是可达的** —— ptc 侧不拒绝把意图落成 true(Lead 明确不授权任何"单方面回写用户 settings 表单值"的行为,即不做"点开关被拒绝")。**不可达的是本插件这行降级显示**:浏览器侧只能读 `configForms.get('ptc-cordis').getSnapshot().value`(该行 **Config / settings 表单**),而 `pythonBackend` 只挂在**能力服务**上(宿主侧,浏览器读不到),ptc v0.15.1 的 Config schema 里没有该字段。因此现状是:ptc 卡显示 on + 红字原因,**本插件卡只显示 on**(hint 已指向宿主日志)。
17
+ - **后续项(本轮不做,避免再开一轮发布)**:由对方用**加法只读字段**把 `pythonBackend`/`pythonIssue` **投影进行 Config 快照**(不动用户意图字段 `pythonRuntime`);那一刻本插件**无需改动**即自动亮起(读的就是同一个键)。已记入最终报告的「已知限制/后续项」。
18
+ - **测试**:冒烟 **83/83 绿**(改写 2 条到 `pythonActive` 语义 + 新增 3 条:①生效态矩阵含旧 peer 回退与闭集校验 ②降级意图只上报不驱动 ③卡片降级态与 21 语言文案);`tests/align-official.mjs` 四个变体仍全绿(本版不动组合的官方行形态)。
19
+ - **真机 A/B/C(隔离 `DSH_HOME` + 新建 profile + `link:` 安装 + 探针能力,dsh 0.1.7-rc.2,本机 macOS,端口 3262-3264,收尾已清理)**:探针分别报三种能力形态,读数(`readDocument()` 的 `disabled`)与日志三例全部符合预期:
20
+
21
+ | 探针能力 | 日志 | 四变体的 `workflow-ptc`/`tool-workflow` |
22
+ | --- | --- | --- |
23
+ | `{pythonRuntime:true, pythonBackend:'python'}` | `peer reports the experimental CPython run_code backend: workflow rows go off in every variant` + 四条 `retired … (peer CPython backend changed; rows are rebuilt)` | **`disabled: true`**(互斥生效) |
24
+ | `{pythonRuntime:true, pythonBackend:'node'}` | `peer has the CPython switch on but the effective backend is node: workflow rows stay on (reason in the host log)`(**无**重建日志,行未变) | **保持启用**(`standard/cordis-gitbash` 不丢 workflow;`code-gitbash` 本就关) |
25
+ | `{pythonRuntime:true}`(旧 peer,缺生效字段) | 与第一行相同(意图顶替) | `disabled: true` —— 与 v0.26.0 行为**逐字节一致** |
26
+
27
+ - 协作边界:v0.15.1 的 `pythonBackend` 是**加法字段**,本插件零形状破坏;`pythonRuntime` 仍是两侧卡片读写的权威**意图**字段。发布后由 contract-rc2 在 task-10 复验两条通道一致性。
28
+
29
+ ## v0.26.0 — 2026-09-25
30
+
31
+ **类型**:feat(run_code 的实验性 Python 后端开关,与 dsh-ptc-cordis-preset 双向联动)+ fix(issue #10:JSON 转义的 Windows 路径多出前导斜杠)+ chore(dsh 0.1.7-rc.2 增量对齐复核)
32
+
33
+ ### 一、issue #10:JSON 转义的 Windows 路径多出前导斜杠(报障 @youyv)
34
+
35
+ > https://github.com/KannaKuron/dsh-gitbash-shell/issues/10 —— `windowsToMsys('"D:\\\\dsh\\\\工作"')` 得到 `"/d//dsh/工作"`,期望 `"/d/dsh/工作"`。
36
+
37
+ - **根因**(与报障者的定位一致,独立复核后确认):两个正则的**盘符后分隔符原子都只吃一个**(`(?:\\|\/)`),而生产输入是**JSON 转义**形态 —— 宿主 `packages/sandbox/sandbox-policy/src/index.ts:47` 用 `${JSON.stringify(policy.workspaceRoot)}` 渲染 `sandbox:policy` 上下文行,于是进入提示词的字面文本带**双反斜杠**。第一个反斜杠被原子吃掉,第二个留在 `rest` 头部,`rest.replace(/[\\/]+/g,'/')` 把它归一成**前导斜杠** ⇒ `/d/` + `/dsh/工作` = `/d//dsh/工作`。缺陷点:`src/index.js:960`(`BARE_WIN_PATH`)、`src/index.js:961`(`QUOTED_WIN_PATH`)、合成点 `src/index.js:967-970`;对照组整值字段走 `driveToMsys()`(带 `^\/*` 剥离)一直正确 —— **只有散文改写器在 JSON 转义输入下坏掉**。
38
+ - **修法(用户批准的方案 A)**:两处原子改为 `[\\/]+`(一次吃光盘符后的全部连续分隔符)。单分隔符输入逐字节不变;`D://dsh//工作` 也一并收敛。**没有**对整段文本 collapse `//`(本文件其它地方把 UNC 拼成 `//server/share`,全局收敛会破坏该形态)。
39
+ - **回归测试**:冒烟新增 `windowsToMsys keeps JSON-escaped Windows paths canonical (v0.26.0, issue #10)` —— 引号分支 + 裸分支、`JSON.stringify('D:\\dsh\\工作')`、`D://dsh//工作`、带空格目录,外加 UNC / URL / `file://` / 已 MSYS 形态的负例。
40
+ - **影响面**:仅"盘符后紧跟 ≥2 个连续分隔符"的文本;三面(`system-prompt/assemble` 的 sections/contexts/variables 与失败 content / error.message)共用该纯函数,同时受益、不会产生方言分歧。语义上是**规范性**修复(Windows 与 MSYS 本来都会收敛中间的 `//`),不是权限或功能故障。
41
+
42
+ ### 二、dsh 0.1.7-rc.1 → rc.2 增量对齐复核(AGENTS.md §9)
43
+
44
+ - **官方预设文本逐字节未变**:`packages/bundle/web-app/presets/{standard,cordis,ptc,minimal}.patch.yml` 在 rc.1→rc.2 的 sha256 **完全一致**(`git diff dsh-v0.1.7-rc.1 dsh-v0.1.7-rc.2 -- packages/bundle/web-app/presets/` 为空),所以 `src/compositions.js` 的行数据与 `PLAN_SECTION` 本版无需重新对齐。
45
+ - **新增可复跑的核对工具 `tests/align-official.mjs`**:按 §9① 抽官方 patch 的 `- id:` / `name:` / `disabled:` 行序列(含嵌套组层级),与本插件四个变体逐条对比,并**钉住 rc.2 的四个 sha256**;官方文本将来变化时会以 `DRIFT` 明确报警而不是静默漂移。当前结果:**四个变体 × unix/win32 两个分支全绿**,唯一的差异是文档化的 Git Bash 增量(bash 行常开、pwsh 行常关)。
46
+ - **执行器 / 路径方言 / 沙箱面**:rc.1→rc.2 的 `packages/shell/bash-local`、`bash-sandbox` **只有版本号 bump**,`ShellExecutor`/`Config`/`confine` 契约无变化 ⇒ 本插件执行器半无需改动。rc.2 的真实改动集中在 `@deepseek-ai/dsh-tool-bash`/`tool-pwsh` 的**描述文本搬迁**(description → 参数描述、新增 `sandboxPermissionsDescription`)、`tool-*-persistent` 的代理对截断修复、`sandbox` 的 escalation `displayReason`、boot/plugin-manager 的 profile 并发保护、client UI。本插件不消费这些描述文本,启动的翻译层/执行器面不受影响(rc.2 新增的 `PreToolDecision.ask.displayReason` 是可选字段,本插件不产 `ask` 决策)。
47
+ - **exports / manifest / peer 复核**:rc.2 新增 `packages/boot/app-boot/src/package-meta.ts`(插件图标与 locale 显示元数据走 exports map,**不执行插件代码**)。本插件已具备 `./package.json`、`./locale/*.json`、`./client`、`./shell`、`.` 五条导出 + `icon.svg` + `dsh.client.platform: 'web'` + `dsh.bundle.patch`,与 rc.2 的解析规则一致(`packages/client/modules/src/index.ts` 的 `locatePkgJson()` 在 rc.2 未变),无需改动。
48
+ - **工具面覆盖复核(§9⑥)**:rc.2 未新增/改动带路径参数的工具 schema(`read/write/edit/read_image/glob/grep/present/bash` 的字段名与嵌套形状不变),`TRANSLATABLE_PATH_FIELDS` + present 嵌套覆盖仍然完整。
49
+
50
+ ### 三、run_code 后端开关:实验性 Python(与 dsh-ptc-cordis-preset 双向联动,默认关)
51
+
52
+ - **需求**:有时想用 Python 跑 `run_code`(少踩转义/编码坑),但默认必须与官方逐字节一致;两插件同装时**只在一处改**、两侧即时同步。
53
+ - **归属(Lead 裁决 + ptc 定案)**:换掉的是 **profile 级** `ptc-runtime` 行(`packages/bundle/base/cordis.patch.yml:389`),不是 preset 内的行;isolate realm 方案实测无效(provider 落在私有 realm,root 的 `tools` 服务看不到)。所以**运行行只由 dsh-ptc-cordis-preset insert**(它的 `./src/runtime.js` + 条件 disable base 行),**本插件不 insert 任何运行行、不声明该依赖**(两插件各插一行会让 `ptcRuntime` 二次注册)。权威状态 = 对方行 Config 布尔 `pythonRuntime`(默认 false)。
54
+ - **本插件侧只做两件事**:
55
+ - ① **镜像设置卡**(`src/client.js`):`configForms.get('ptc-cordis')` 读写**同一个字段** + `subscribe`,任一侧改动两侧立即同步;对方未装或版本无该字段(对方 < 0.15.0)⇒ 整段不画;win32 显示禁用态 + POSIX-only 原因(实验性 CPython 后端在 win32 构造即抛错),按钮不出现。文案 21 语言(`sec.python` / `python.label/on/off/hint/blocked`),写明**重启 dsh 后生效**与**原因见宿主启动日志**(对方不提供 `pythonRuntimeIssue` 这类字段:客户端读不到宿主探测结果,加了就是第二份会漂移的状态)。
56
+ - ② **组合的工作流互斥**(`src/compositions.js` + `src/index.js`):`workflow-ptc` 构造器硬要求 `ctx.ptcRuntime.language === 'typescript'`(`packages/workflow/workflow-ptc/src/index.ts:117`),而 preset 行在**独立 PresetTree** 里挂载、**base 行 disable 管不到它** ⇒ python 后端期间选 standard/cordis 会让该行抛错,`agent-preset-registry` 的 `audit.failed` 直接**拒绝整棵 preset 挂载**。修法与官方 Python 参考组合一致(`snapshots/session/ptc-python-turn/cordis.yml:25-36` 同款禁用两行):对方能力报 `pythonRuntime: true` 时,**四个变体**的 `workflow-ptc`/`tool-workflow` 一律 `disabled: true`(用户 workflow 设置值保留,关掉后端后下次启动恢复);`code-gitbash` 本来就关。
57
+ - **信号来源**:对方能力服务 `ptcCordisPreset` 新增 `pythonRuntime`(boolean 或 getter,读不到一律 false);值变化必须**重注册已在 `live` 表里的变体**(行内容变了,只增删名录不够),日志 `peer reports the experimental CPython run_code backend: workflow rows go off in every variant` + 每条 `retired … (peer CPython switch changed; rows are rebuilt)`。
58
+ - **提示词自动跟随**:后端实例自己提供 `language`(`'typescript'` / `'python'`)与 `executionInstructions`,`packages/core/tools/src/ptc.ts:752` 与 `agent-tool-presentation`(`ctx.inject(['ptcRuntime'])`)据此渲染 run_code 的 SDK 提示词与工具呈现 ⇒ 组合文本两种状态都不变,无需本插件硬编码 Python 文案。
59
+ - **测试**:冒烟 +4(`peerFact` 保守读取矩阵、组合的 workflow 互斥矩阵、宿主重注册与"不 insert 运行行"断言、镜像卡的门控/写穿/win32 断言),共 **80/80 绿**。
60
+ - **真机验证(隔离 `DSH_HOME` + 新建 web profile + 插件 `link:` 安装 + 探针插件,真实 dsh 0.1.7-rc.2,本机 macOS,端口 3251-3256,未触碰 `~/.dsh` 下任何在用 profile)**:
61
+ - **A(默认关)**:四个变体注册成功,名录 8 项;`readDocument()` 读数 = 官方形态(`standard/cordis-gitbash`:`workflow-ptc`/`tool-workflow` 启用;`code-gitbash`:两者 `disabled: true`;`tool-bash` 启用 / `tool-pwsh` 禁用;`tool-ralph` 全禁用)。
62
+ - **B(探针报 `pythonRuntime: true`)**:出现上面两行日志,四个变体**全部重建**,读数变为两行 `disabled: true`。
63
+ - **两态都做真实挂载**:`agentPresets.acquireScope('<variant>')` 四个变体各返回 `MOUNT OK`(挂载审计无 failed 行),证明显式注册的组合在 rc.2 上确实可挂载,而不只是"注册成功"。
64
+ - **Windows 专属面**:win32 分支(卡片禁用态、宿主拒绝写入、python 后端构造抛错)在 macOS 上**无法真机验证**,按实现 + 单测/模拟记录;本插件的执行器与路径方言层按 `process.platform === 'win32'` 门控,而 python 后端仅 POSIX,两者在各自平台上互不重叠。
65
+ - **独立验证(发布后补记,2026-09-25,task-8,由另一位成员执行)**:用 **npm 已发布的 `dsh-gitbash-shell@0.26.0`** + `dsh-ptc-cordis-preset@0.15.0` 在隔离 `DSH_HOME` 上复验 —— **ptc → gitbash 方向联动通过**:把对方的行 Config `pythonRuntime` 置 `true` 后 boot,本插件打出 `peer reports the experimental CPython run_code backend: workflow rows go off in every variant` 以及四条 `retired … (peer CPython switch changed; rows are rebuilt)`;关态 boot **没有**这些行 ⇒ 能力感知 + 变体重建按设计工作(完整报告:`_rc2-contract/PYTHON-SWITCH-VERIFY.md`)。
66
+ - 仍未覆盖(留给集成阶段/真机):**反方向「在 gitbash 卡上改 → ptc 跟随」与两张卡的 UI 即时同步**(headless 无法操作设置卡,需真实 web 实例人工点选;两侧写的是同一个 `configForms` 字段,机制与 v0.25.0 已验证的 dedupe 镜像同构)以及 **win32 真机**(本机无 Windows;静态核对确认 ptc 侧平台表达式与 python 后端 `ptc-runtime-python/src/index.ts:837-839` 的「win32 构造即抛」一致,本插件侧按 `python.blocked` + 不画按钮实现平台限制)。
67
+ - 相关:issue #10 https://github.com/KannaKuron/dsh-gitbash-shell/issues/10 ;对方仓库 dsh-ptc-cordis-preset v0.15.0(能力字段与运行行)
68
+
6
69
  ## v0.25.1 — 2026-09-24
7
70
 
8
71
  **类型**:fix(issue #8 —— 路径方言在 dsh 0.1.7 上**整层静默失效**:工具分发面用错了设置读取器;同一次审计另修侧栏终端还原的同类漏网)
package/README.md CHANGED
@@ -187,6 +187,40 @@ preset 会被插件自动清理;宿主 shell 回退为 PowerShell。
187
187
  **依赖版本**:去重开关本体在**本插件 ≥ 0.25.0**;对方的协作能力在
188
188
  **dsh-ptc-cordis-preset ≥ 0.14.0**。
189
189
 
190
+ ### run_code 后端开关:`pythonRuntime`(默认关,v0.26.0)
191
+
192
+ dsh 有一个**实验性 CPython 后端**用于 PTC 的 `run_code`
193
+ (`@deepseek-ai/dsh-experimental-ptc-runtime-python`)。它换掉的是 **profile 级**的
194
+ `ptc-runtime` 行(不是 preset 里的行),所以**权威开关属于 dsh-ptc-cordis-preset**:它那一行
195
+ Config 的布尔字段 `pythonRuntime`(默认 `false`),由它在 profile 组合期决定挂哪个后端。
196
+
197
+ 本插件做的是**第二张设置卡**——同装 dsh-ptc-cordis-preset 时,本插件的设置页也会出现这一行,
198
+ 通过 `ctx.configForms.get('ptc-cordis')` 读写**同一个字段**,任一侧改动两侧立即同步
199
+ (与 `suppressPeerCordis` 同构,方向相反)。对方没装、或版本低于 0.15.0(没有该字段)时,
200
+ 这一行**不显示**。
201
+
202
+ - **开关关闭(默认)**:`run_code` 用官方 Node/TypeScript 后端,组合与官方逐字节一致。
203
+ - **开关开启**:`run_code` 的语言、生成的 SDK 提示词与工具呈现整体切到 Python(由后端实例的
204
+ `language`/`executionInstructions` 决定,组合文本不变)。
205
+ - **生效时机**:**重启 dsh 之后生效**(后端行的替换在 profile 组合期求值);设置卡上的状态
206
+ 两侧即时同步,只有后端切换需要重启。若开启后没有生效,原因见 dsh 启动日志。
207
+ - **"想开"与"真的开了"是两件事**:后端不可用(包被移除 / 解释器低于 3.10 / Windows)时,开关的
208
+ 意图仍可为"开",但组合**照旧跑 Node** —— 此时 **workflow 侧不再被连带禁用**(v0.26.1:互斥只看
209
+ 实际生效的后端;v0.26.0 只看意图,会让用户白丢 workflow 能力),**原因见 dsh 启动日志**。
210
+ > 关于卡片上的"后端不可用,当前仍为 Node"这行提示:本插件已实现该降级文案(21 语言),但它要等
211
+ > **对方把生效态投影进行 Config 快照**后才会亮起 —— 浏览器只读得到那份快照,而生效态目前只在
212
+ > 宿主侧的能力服务里(见 AGENTS.md §4f)。在此之前:对方卡片显示"已开启 + 原因",本插件卡片
213
+ > 显示"已开启"(hint 指向宿主日志)。
214
+ - **平台**:该后端**仅支持 POSIX**——它在 Windows 上构造即抛错,所以 Windows 上开关显示为
215
+ 禁用并注明原因,宿主侧也会拒绝写入。
216
+ - **与 workflow 互斥**:`workflow-ptc` 硬要求 TypeScript 后端(`ctx.ptcRuntime.language ===
217
+ 'typescript'`),官方 Python 组合同样把 `workflow-ptc` / `tool-workflow` 一起禁用。因此**开启
218
+ 期间本插件四个变体的这两行一律禁用**(用户自己的 workflow 设置值保留,关掉后端后下次启动
219
+ 恢复)——不这样做,选标准/创造模式会因一行构造失败而拒绝**整棵 preset 挂载**。
220
+ - **依赖**:python 运行时包由 dsh-ptc-cordis-preset 声明(`optionalDependencies`,
221
+ `0.1.7-rc.2`);本插件不声明该依赖、也不 insert 任何运行行(两个插件各插一行会造成
222
+ `ptcRuntime` 二次注册)。
223
+
190
224
  ## POSIX 路径方言(v0.7.0 引入,受 `posixPaths` 开关门控)
191
225
 
192
226
  Windows 上本插件把宿主 shell 换成 Git Bash 的同时,让**模型看到的路径**统一成 MSYS 盘根
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-gitbash-shell",
3
- "version": "0.25.1",
3
+ "version": "0.26.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。双 era 适配 dsh <= 0.1.1(内置 id 'code')与 >= 0.1.2(改名 'ptc'),启动探测自动选择,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.25.1",
3
+ "version": "0.26.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
@@ -51,6 +51,15 @@ window.__ModuleLoader__.load({
51
51
  plugin's row (the single authoritative copy the peer card binds too) —
52
52
  and the section is drawn only while that entry is actually served. */
53
53
  var PEER_NS = "ptc-cordis";
54
+ /** The peer's authoritative experimental-CPython field on that SAME row:
55
+ both cards read and write this one form field, so either side changes
56
+ both. Absent on a peer that predates the switch ⇒ no row is drawn. */
57
+ var PEER_PYTHON_FIELD = "pythonRuntime";
58
+ /** The peer's EFFECTIVE backend on the same snapshot ('python' | 'node'),
59
+ when its version reports one: 'node' while the intent is on means the
60
+ preflight failed (package missing / interpreter too old / Windows), so
61
+ the card shows the degraded state instead of claiming Python. */
62
+ var PEER_PYTHON_BACKEND_FIELD = "pythonBackend";
54
63
 
55
64
  // ── dictionaries ────────────────────────────────────────────────────────
56
65
  // zh/en stay inline; the third languages live in LOCALES below, one entry
@@ -89,6 +98,13 @@ window.__ModuleLoader__.load({
89
98
  "sec.dedupe": "与 PTC 创造模式去重",
90
99
  "dedupe.label": "「创造模式 · Git Bash」重复项",
91
100
  "dedupe.hint": "dsh-ptc-cordis-preset 同装时,它的「PTC 创造模式」在联动下已是 Git Bash 版,与本插件的「创造模式 · Git Bash」指向同一件事。开启去重后本插件不再注册那一条(名录少一项);默认关闭,保持四个变体不变。此开关就是对方设置卡上的同一个开关——两侧共享同一份状态,任一侧改动另一侧立即同步。仅在已安装 dsh-ptc-cordis-preset 时显示。",
101
+ "sec.python": "run_code 后端(实验性 Python)",
102
+ "python.label": "run_code 后端",
103
+ "python.on": "Python(实验性)",
104
+ "python.off": "Node / TypeScript(默认)",
105
+ "python.hint": "默认关闭时 run_code 用官方 Node/TypeScript 后端,与官方 ptc 组合逐字节一致;开启后改用 dsh 实验性 CPython 后端(@deepseek-ai/dsh-experimental-ptc-runtime-python),run_code 的语言、生成的 SDK 提示词与工具呈现随之切到 Python。要求 POSIX 平台与 CPython ≥ 3.10(Windows 不可用);与 workflow 工具互斥——官方 Python 组合同样禁用 workflow,因此开启期间本插件四个变体的 workflow 侧强制关闭(你的工作流设置值保留,关掉后恢复)。改动需重启 dsh 后生效;此开关就是 dsh-ptc-cordis-preset 设置卡上的同一个开关——两侧共享同一份状态,任一侧改动两侧同步。仅在已安装 dsh-ptc-cordis-preset 时显示。若置为开启后未生效,原因见宿主启动日志。",
106
+ "python.degraded": "后端不可用,当前仍为 Node(原因见宿主启动日志)",
107
+ "python.blocked": "本机是 Windows:实验性 Python 后端仅支持 POSIX,此开关不可用。",
92
108
  };
93
109
 
94
110
  var en = {
@@ -122,6 +138,13 @@ window.__ModuleLoader__.load({
122
138
  "sec.dedupe": "Dedupe with PTC creation mode",
123
139
  "dedupe.label": "\"Creation mode · Git Bash\" duplicate",
124
140
  "dedupe.hint": "With dsh-ptc-cordis-preset installed alongside, its \"PTC creation mode\" is already the Git Bash variant under the link-up, so it and this plugin's \"creation mode · Git Bash\" point at the same thing. With dedupe on, this plugin stops registering that entry (one fewer in the roster); off by default, which keeps the four variants unchanged. This switch is the very same switch on the peer's settings card — both sides share one state, so a change on either side syncs to the other immediately. Shown only while dsh-ptc-cordis-preset is installed.",
141
+ "sec.python": "run_code backend (experimental Python)",
142
+ "python.label": "run_code backend",
143
+ "python.on": "Python (experimental)",
144
+ "python.off": "Node / TypeScript (default)",
145
+ "python.hint": "While off (default) run_code uses the official Node/TypeScript backend, byte-identical to the shipped ptc composition; turning it on switches to dsh's experimental CPython backend (@deepseek-ai/dsh-experimental-ptc-runtime-python), which also switches run_code's language, generated SDK prompt and tool presentation to Python. Requires a POSIX platform and CPython ≥ 3.10 (unavailable on Windows) and is mutually exclusive with the workflow tool — the official Python composition disables workflow too, so the workflow side of all four variants is forced off while this is on (your workflow setting is kept and restored when you turn it back off). Takes effect after restarting dsh; this is the very same switch on dsh-ptc-cordis-preset's card — both sides share one state, so either side updates both. Shown only while dsh-ptc-cordis-preset is installed. If turning it on does not take effect, the dsh startup log states why.",
146
+ "python.degraded": "backend unavailable, still Node (reason in the dsh startup log)",
147
+ "python.blocked": "This host is Windows: the experimental Python backend supports POSIX only, so this switch is unavailable.",
125
148
  };
126
149
 
127
150
  /* Third-language dictionaries: one entry per language, each preceded
@@ -165,6 +188,13 @@ window.__ModuleLoader__.load({
165
188
  "sec.dedupe": "إزالة التكرار مع وضع PTC الإبداعي",
166
189
  "dedupe.label": "عنصر «وضع الإبداع · Git Bash» المكرر",
167
190
  "dedupe.hint": "عند تثبيت dsh-ptc-cordis-preset معًا، يكون «وضع PTC الإبداعي» لديه بالفعل نسخة Git Bash في إطار الربط، فيشير هو و«وضع الإبداع · Git Bash» في هذه الإضافة إلى الشيء نفسه. عند تفعيل إزالة التكرار تتوقف هذه الإضافة عن تسجيل ذلك العنصر (عنصر أقل في القائمة)؛ والمعطَّل افتراضيًا يُبقي المتغيّرات الأربعة كما هي. هذا المفتاح هو نفسه المفتاح الموجود على بطاقة إعدادات الطرف الآخر — الجانبان يتشاركان الحالة نفسها، وأي تغيير في أحد الجانبين يُزامَن فورًا مع الآخر. يظهر فقط عندما يكون dsh-ptc-cordis-preset مثبَّتًا.",
191
+ "sec.python": "خلفية run_code (Python تجريبي)",
192
+ "python.label": "خلفية run_code",
193
+ "python.on": "Python (تجريبي)",
194
+ "python.off": "Node / TypeScript (افتراضي)",
195
+ "python.hint": "عند الإيقاف (افتراضيًا) يستخدم run_code الخلفية الرسمية Node/TypeScript، مطابقة تمامًا لتركيبة ptc الرسمية؛ وعند التشغيل يتحول إلى خلفية CPython التجريبية في dsh (@deepseek-ai/dsh-experimental-ptc-runtime-python)، فتتحول لغة run_code ومطالبة SDK المولَّدة وعرض الأداة إلى Python. يتطلب نظام POSIX و CPython ≥ 3.10 (غير متاح على Windows)، وهو متعارض مع أداة workflow — فالتركيبة الرسمية لـ Python تعطّل workflow أيضًا، لذا يبقى جانب workflow مُعطَّلًا في المتغيّرات الأربعة أثناء التشغيل (قيمتك محفوظة وتعود عند الإيقاف). يسري التغيير بعد إعادة تشغيل dsh؛ هذا هو المفتاح نفسه على بطاقة dsh-ptc-cordis-preset — الجانبان يتشاركان حالة واحدة. يظهر فقط عند تثبيت dsh-ptc-cordis-preset. إذا لم يسري التشغيل، فسبب ذلك مذكور في سجل تشغيل dsh.",
196
+ "python.degraded": "الخلفية غير متاحة، لا يزال Node (السبب في سجل بدء التشغيل)",
197
+ "python.blocked": "هذا المضيف يعمل بـ Windows: الخلفية التجريبية Python تدعم POSIX فقط، لذا لا يتوفر هذا المفتاح.",
168
198
  },
169
199
  /* locale: de */
170
200
  "de": {
@@ -198,6 +228,13 @@ window.__ModuleLoader__.load({
198
228
  "sec.dedupe": "Deduplizierung mit dem PTC-Kreativmodus",
199
229
  "dedupe.label": "Doppelter Eintrag „Kreativmodus · Git Bash“",
200
230
  "dedupe.hint": "Ist dsh-ptc-cordis-preset mitinstalliert, ist dessen „PTC-Kreativmodus“ durch die Verknüpfung bereits die Git-Bash-Fassung und zeigt damit auf dasselbe wie der „Kreativmodus · Git Bash“ dieses Plugins. Mit aktiver Deduplizierung registriert dieses Plugin den eigenen Eintrag nicht mehr (ein Eintrag weniger im Verzeichnis); standardmäßig aus, die vier Varianten bleiben unverändert. Dieser Schalter ist derselbe Schalter auf der Einstellungskarte der Gegenseite — beide Seiten teilen einen Zustand, eine Änderung auf einer Seite erreicht die andere sofort. Nur sichtbar, solange dsh-ptc-cordis-preset installiert ist.",
231
+ "sec.python": "run_code-Backend (experimentelles Python)",
232
+ "python.label": "run_code-Backend",
233
+ "python.on": "Python (experimentell)",
234
+ "python.off": "Node / TypeScript (Standard)",
235
+ "python.hint": "Aus (Standard): run_code nutzt das offizielle Node/TypeScript-Backend, byte-identisch zur ausgelieferten ptc-Komposition; an: dsh wechselt auf das experimentelle CPython-Backend (@deepseek-ai/dsh-experimental-ptc-runtime-python), womit Sprache, generierter SDK-Prompt und Darstellung von run_code auf Python umstellen. Erfordert POSIX und CPython ≥ 3.10 (unter Windows nicht verfügbar) und ist mit dem workflow-Tool unvereinbar — die offizielle Python-Komposition deaktiviert workflow ebenfalls, deshalb bleibt die workflow-Seite aller vier Varianten so lange aus (dein Workflow-Wert bleibt erhalten und kehrt nach dem Ausschalten zurück). Wirkt nach einem Neustart von dsh; dies ist derselbe Schalter auf der Karte von dsh-ptc-cordis-preset — beide Seiten teilen einen Zustand. Nur sichtbar, solange dsh-ptc-cordis-preset installiert ist. Bleibt das Einschalten ohne Wirkung, nennt das dsh-Startprotokoll den Grund.",
236
+ "python.degraded": "Backend nicht verfügbar, weiterhin Node (Grund im dsh-Startprotokoll)",
237
+ "python.blocked": "Dieser Host ist Windows: Das experimentelle Python-Backend unterstützt nur POSIX, der Schalter ist nicht verfügbar.",
201
238
  },
202
239
  /* locale: fr */
203
240
  "fr": {
@@ -231,6 +268,13 @@ window.__ModuleLoader__.load({
231
268
  "sec.dedupe": "Dédoublonnage avec le mode création PTC",
232
269
  "dedupe.label": "Entrée en double « mode création · Git Bash »",
233
270
  "dedupe.hint": "Lorsque dsh-ptc-cordis-preset est installé en même temps, son « mode création PTC » est déjà la version Git Bash grâce à l'appairage : lui et le « mode création · Git Bash » de ce plugin désignent la même chose. Une fois le dédoublonnage activé, ce plugin n'enregistre plus sa propre entrée (une entrée de moins dans le catalogue) ; désactivé par défaut, ce qui laisse les quatre variantes intactes. Cet interrupteur est exactement le même que sur la carte de réglages d'en face — les deux côtés partagent un seul état, toute modification d'un côté est synchronisée immédiatement de l'autre. Affiché uniquement lorsque dsh-ptc-cordis-preset est installé.",
271
+ "sec.python": "Backend run_code (Python expérimental)",
272
+ "python.label": "Backend run_code",
273
+ "python.on": "Python (expérimental)",
274
+ "python.off": "Node / TypeScript (par défaut)",
275
+ "python.hint": "Désactivé (par défaut), run_code utilise le backend officiel Node/TypeScript, identique octet pour octet à la composition ptc livrée ; activé, dsh bascule sur le backend CPython expérimental (@deepseek-ai/dsh-experimental-ptc-runtime-python) : la langue, l'invite SDK générée et la présentation de run_code passent en Python. Exige POSIX et CPython ≥ 3.10 (indisponible sous Windows) et est incompatible avec l'outil workflow — la composition Python officielle désactive aussi workflow, donc le côté workflow des quatre variantes reste désactivé tant que l'option est active (ta valeur est conservée et revient à la désactivation). Prend effet après un redémarrage de dsh ; c'est le même interrupteur que sur la carte de dsh-ptc-cordis-preset — les deux côtés partagent un seul état. Affiché uniquement si dsh-ptc-cordis-preset est installé. Si l'activation reste sans effet, le journal de démarrage de dsh en indique la raison.",
276
+ "python.degraded": "backend indisponible, toujours Node (raison dans le journal de démarrage de dsh)",
277
+ "python.blocked": "Cet hôte est sous Windows : le backend Python expérimental n'est disponible que sur POSIX, l'interrupteur est indisponible.",
234
278
  },
235
279
  /* locale: hi */
236
280
  "hi": {
@@ -264,6 +308,13 @@ window.__ModuleLoader__.load({
264
308
  "sec.dedupe": "PTC क्रिएशन मोड के साथ डुप्लीकेट हटाना",
265
309
  "dedupe.label": "«क्रिएशन मोड · Git Bash» की डुप्लीकेट प्रविष्टि",
266
310
  "dedupe.hint": "जब dsh-ptc-cordis-preset साथ में इंस्टॉल होता है, तो लिंक-अप के कारण उसका «PTC क्रिएशन मोड» पहले से Git Bash रूप है, और वह इस प्लगइन के «क्रिएशन मोड · Git Bash» के साथ एक ही चीज़ दर्शाता है। डुप्लीकेट हटाना चालू करने पर यह प्लगइन अपनी वह प्रविष्टि पंजीकृत नहीं करता (सूची में एक कम); डिफ़ॉल्ट रूप से बंद, जिससे चारों वेरिएंट अपरिवर्तित रहते हैं। यह स्विच सामने वाले की सेटिंग कार्ड पर मौजूद ठीक वही स्विच है — दोनों ओर एक ही स्थिति साझा होती है, किसी एक ओर बदलाव तुरंत दूसरी ओर सिंक होता है। यह केवल तभी दिखता है जब dsh-ptc-cordis-preset इंस्टॉल हो।",
311
+ "sec.python": "run_code बैकएंड (प्रयोगात्मक Python)",
312
+ "python.label": "run_code बैकएंड",
313
+ "python.on": "Python (प्रयोगात्मक)",
314
+ "python.off": "Node / TypeScript (डिफ़ॉल्ट)",
315
+ "python.hint": "बंद (डिफ़ॉल्ट) रहने पर run_code आधिकारिक Node/TypeScript बैकएंड इस्तेमाल करता है, जो भेजे गए ptc संयोजन से पूरी तरह मेल खाता है; चालू करने पर dsh का प्रयोगात्मक CPython बैकएंड (@deepseek-ai/dsh-experimental-ptc-runtime-python) चलता है और run_code की भाषा, बना SDK प्रॉम्प्ट तथा प्रस्तुति Python में बदल जाती है। इसके लिए POSIX और CPython ≥ 3.10 चाहिए (Windows पर उपलब्ध नहीं), और यह workflow टूल से परस्पर अनन्य है — आधिकारिक Python संयोजन भी workflow बंद करता है, इसलिए चालू रहने तक चारों वेरिएंट का workflow पक्ष बंद रहता है (आपकी workflow सेटिंग सुरक्षित रहती है और बंद करने पर लौट आती है)। बदलाव dsh को फिर से शुरू करने के बाद लागू होता है; यह dsh-ptc-cordis-preset के कार्ड पर मौजूद वही स्विच है — दोनों ओर एक ही स्थिति साझा होती है। यह केवल तभी दिखता है जब dsh-ptc-cordis-preset इंस्टॉल हो। चालू करने पर असर न हो तो कारण dsh के स्टार्टअप लॉग में मिलेगा।",
316
+ "python.degraded": "बैकएंड उपलब्ध नहीं, अब भी Node (कारण dsh स्टार्टअप लॉग में)",
317
+ "python.blocked": "यह होस्ट Windows है: प्रयोगात्मक Python बैकएंड केवल POSIX पर चलता है, इसलिए यह स्विच उपलब्ध नहीं है।",
267
318
  },
268
319
  /* locale: id */
269
320
  "id": {
@@ -297,6 +348,13 @@ window.__ModuleLoader__.load({
297
348
  "sec.dedupe": "Deduplikasi dengan mode kreatif PTC",
298
349
  "dedupe.label": "Entri duplikat «mode kreatif · Git Bash»",
299
350
  "dedupe.hint": "Saat dsh-ptc-cordis-preset terpasang bersama, «mode kreatif PTC» miliknya sudah menjadi versi Git Bash berkat keterkaitan, sehingga ia dan «mode kreatif · Git Bash» plugin ini menunjuk hal yang sama. Dengan deduplikasi aktif, plugin ini berhenti mendaftarkan entrinya sendiri (berkurang satu di daftar); nonaktif secara bawaan, sehingga keempat varian tetap utuh. Sakelar ini adalah sakelar yang sama di kartu setelan pihak lain — kedua sisi berbagi satu status, perubahan di salah satu sisi langsung tersinkron ke sisi lain. Hanya tampil saat dsh-ptc-cordis-preset terpasang.",
351
+ "sec.python": "Backend run_code (Python eksperimental)",
352
+ "python.label": "Backend run_code",
353
+ "python.on": "Python (eksperimental)",
354
+ "python.off": "Node / TypeScript (bawaan)",
355
+ "python.hint": "Saat nonaktif (bawaan), run_code memakai backend resmi Node/TypeScript, identik byte demi byte dengan komposisi ptc resmi; saat aktif, dsh memakai backend CPython eksperimental (@deepseek-ai/dsh-experimental-ptc-runtime-python) sehingga bahasa run_code, prompt SDK yang dihasilkan, dan penyajiannya beralih ke Python. Memerlukan POSIX dan CPython ≥ 3.10 (tidak tersedia di Windows) serta saling eksklusif dengan alat workflow — komposisi Python resmi juga menonaktifkan workflow, jadi sisi workflow keempat varian tetap mati selama ini aktif (nilai workflow-mu dipertahankan dan kembali saat dimatikan). Berlaku setelah dsh dimulai ulang; ini sakelar yang sama di kartu dsh-ptc-cordis-preset — kedua sisi berbagi satu status. Hanya tampil saat dsh-ptc-cordis-preset terpasang. Jika diaktifkan tetapi tidak berpengaruh, alasannya ada di log mulai dsh.",
356
+ "python.degraded": "backend tidak tersedia, masih Node (alasan di log mulai dsh)",
357
+ "python.blocked": "Host ini Windows: backend Python eksperimental hanya mendukung POSIX, sakelar ini tidak tersedia.",
300
358
  },
301
359
  /* locale: it */
302
360
  "it": {
@@ -330,6 +388,13 @@ window.__ModuleLoader__.load({
330
388
  "sec.dedupe": "Deduplicazione con la modalità creazione PTC",
331
389
  "dedupe.label": "Voce duplicata «modalità creazione · Git Bash»",
332
390
  "dedupe.hint": "Quando dsh-ptc-cordis-preset è installato insieme, la sua «modalità creazione PTC» è già la versione Git Bash grazie al collegamento: essa e la «modalità creazione · Git Bash» di questo plugin indicano la stessa cosa. Attivando la deduplicazione questo plugin non registra più la propria voce (una in meno nell'elenco); disattivata per impostazione predefinita, lascia intatte le quattro varianti. Questo interruttore è lo stesso presente sulla scheda impostazioni dell'altra parte — entrambe le parti condividono un unico stato, una modifica su un lato si sincronizza subito sull'altro. Visibile solo quando dsh-ptc-cordis-preset è installato.",
391
+ "sec.python": "Backend run_code (Python sperimentale)",
392
+ "python.label": "Backend run_code",
393
+ "python.on": "Python (sperimentale)",
394
+ "python.off": "Node / TypeScript (predefinito)",
395
+ "python.hint": "Disattivato (predefinito) run_code usa il backend ufficiale Node/TypeScript, identico byte per byte alla composizione ptc distribuita; attivandolo dsh passa al backend CPython sperimentale (@deepseek-ai/dsh-experimental-ptc-runtime-python): lingua, prompt SDK generato e presentazione di run_code passano a Python. Richiede POSIX e CPython ≥ 3.10 (non disponibile su Windows) ed è incompatibile con lo strumento workflow — anche la composizione Python ufficiale disattiva workflow, quindi il lato workflow di tutte e quattro le varianti resta spento finché è attivo (il tuo valore viene conservato e torna alla disattivazione). Ha effetto dopo il riavvio di dsh; è lo stesso interruttore sulla scheda di dsh-ptc-cordis-preset — entrambi i lati condividono un unico stato. Visibile solo quando dsh-ptc-cordis-preset è installato. Se l'attivazione non ha effetto, il motivo è nel log di avvio di dsh.",
396
+ "python.degraded": "backend non disponibile, resta Node (motivo nel log di avvio di dsh)",
397
+ "python.blocked": "Questo host è Windows: il backend Python sperimentale supporta solo POSIX, l'interruttore non è disponibile.",
333
398
  },
334
399
  /* locale: ja */
335
400
  "ja": {
@@ -363,6 +428,13 @@ window.__ModuleLoader__.load({
363
428
  "sec.dedupe": "PTC 創造モードとの重複排除",
364
429
  "dedupe.label": "「創造モード · Git Bash」の重複項目",
365
430
  "dedupe.hint": "dsh-ptc-cordis-preset を併用している場合、連携により相手の「PTC 創造モード」はすでに Git Bash 版であり、本プラグインの「創造モード · Git Bash」と同じものを指します。重複排除を有効にすると本プラグインは自前の項目を登録しなくなります(名簿が 1 件減ります)。既定は無効で、4 つのバリアントは変わりません。このスイッチは相手の設定カードにあるものと同一で、両側が同じ状態を共有し、どちらかで変更すればもう一方へ即座に同期されます。dsh-ptc-cordis-preset がインストールされているときだけ表示されます。",
431
+ "sec.python": "run_code バックエンド(実験的 Python)",
432
+ "python.label": "run_code バックエンド",
433
+ "python.on": "Python(実験的)",
434
+ "python.off": "Node / TypeScript(既定)",
435
+ "python.hint": "オフ(既定)では run_code は公式の Node/TypeScript バックエンドを使い、公式 ptc 構成とバイト単位で一致します。オンにすると dsh の実験的 CPython バックエンド(@deepseek-ai/dsh-experimental-ptc-runtime-python)に切り替わり、run_code の言語・生成される SDK プロンプト・提示が Python に変わります。POSIX と CPython ≥ 3.10 が必要(Windows では利用不可)で、workflow ツールとは排他です —— 公式 Python 構成も workflow を無効化するため、オン期間中は 4 変体すべてで workflow 側が強制的にオフになります(ワークフロー設定値は保持され、オフに戻すと復帰)。変更は dsh の再起動後に有効です。これは dsh-ptc-cordis-preset のカードにある同じスイッチで、両側が同一状態を共有します。dsh-ptc-cordis-preset がインストールされているときだけ表示されます。 オンにしても効かない場合の理由は dsh の起動ログにあります。",
436
+ "python.degraded": "バックエンド利用不可・現在も Node(理由は dsh の起動ログ)",
437
+ "python.blocked": "このホストは Windows です。実験的 Python バックエンドは POSIX 専用のため、このスイッチは利用できません。",
366
438
  },
367
439
  /* locale: ko */
368
440
  "ko": {
@@ -396,6 +468,13 @@ window.__ModuleLoader__.load({
396
468
  "sec.dedupe": "PTC 창조 모드와 중복 제거",
397
469
  "dedupe.label": "«창조 모드 · Git Bash» 중복 항목",
398
470
  "dedupe.hint": "dsh-ptc-cordis-preset을 함께 설치하면 연동으로 인해 상대의 «PTC 창조 모드»가 이미 Git Bash 버전이므로, 그것과 이 플러그인의 «창조 모드 · Git Bash»는 같은 것을 가리킵니다. 중복 제거를 켜면 이 플러그인은 자기 항목을 더 이상 등록하지 않습니다(명부에서 하나 줄어듦). 기본값은 꺼짐이며 네 가지 변형은 그대로 유지됩니다. 이 스위치는 상대 설정 카드에 있는 바로 그 스위치입니다 — 양쪽이 같은 상태를 공유하므로 어느 쪽에서 바꾸든 다른 쪽에 즉시 동기화됩니다. dsh-ptc-cordis-preset이 설치되어 있을 때만 표시됩니다.",
471
+ "sec.python": "run_code 백엔드(실험적 Python)",
472
+ "python.label": "run_code 백엔드",
473
+ "python.on": "Python(실험적)",
474
+ "python.off": "Node / TypeScript(기본)",
475
+ "python.hint": "끄면(기본) run_code는 공식 Node/TypeScript 백엔드를 사용해 공식 ptc 구성과 바이트 단위로 일치합니다. 켜면 dsh의 실험적 CPython 백엔드(@deepseek-ai/dsh-experimental-ptc-runtime-python)로 바뀌어 run_code의 언어, 생성되는 SDK 프롬프트, 도구 표시가 Python으로 전환됩니다. POSIX와 CPython ≥ 3.10이 필요하며(Windows에서는 사용 불가) workflow 도구와 상호 배타적입니다 — 공식 Python 구성도 workflow를 끄므로 켜져 있는 동안 네 변형 모두 workflow 쪽이 강제로 꺼집니다(워크플로 설정값은 유지되고 끄면 복구됩니다). 변경은 dsh 재시작 후 적용됩니다. 이 스위치는 dsh-ptc-cordis-preset 카드에 있는 바로 그 스위치이며 양쪽이 같은 상태를 공유합니다. dsh-ptc-cordis-preset이 설치되어 있을 때만 표시됩니다. 켠 뒤에도 적용되지 않으면 그 이유는 dsh 시작 로그에 있습니다.",
476
+ "python.degraded": "백엔드 사용 불가, 여전히 Node(이유는 dsh 시작 로그)",
477
+ "python.blocked": "이 호스트는 Windows입니다. 실험적 Python 백엔드는 POSIX만 지원하므로 이 스위치를 쓸 수 없습니다.",
399
478
  },
400
479
  /* locale: nl */
401
480
  "nl": {
@@ -429,6 +508,13 @@ window.__ModuleLoader__.load({
429
508
  "sec.dedupe": "Deduplicatie met de PTC-creatiemodus",
430
509
  "dedupe.label": "Dubbele vermelding ‘creatiemodus · Git Bash’",
431
510
  "dedupe.hint": "Als dsh-ptc-cordis-preset meegaat, is zijn ‘PTC-creatiemodus’ door de koppeling al de Git Bash-variant, dus die en de ‘creatiemodus · Git Bash’ van deze plugin wijzen op hetzelfde. Met deduplicatie aan registreert deze plugin die eigen vermelding niet meer (één minder in de lijst); standaard uit, waardoor de vier varianten ongewijzigd blijven. Deze schakelaar is dezelfde als op de instellingenkaart van de andere kant — beide kanten delen één status, een wijziging aan één kant synct direct naar de andere. Alleen zichtbaar zolang dsh-ptc-cordis-preset is geïnstalleerd.",
511
+ "sec.python": "run_code-backend (experimenteel Python)",
512
+ "python.label": "run_code-backend",
513
+ "python.on": "Python (experimenteel)",
514
+ "python.off": "Node / TypeScript (standaard)",
515
+ "python.hint": "Uit (standaard) gebruikt run_code de officiële Node/TypeScript-backend, byte voor byte gelijk aan de meegeleverde ptc-compositie; aan schakelt dsh over op de experimentele CPython-backend (@deepseek-ai/dsh-experimental-ptc-runtime-python), waardoor taal, gegenereerde SDK-prompt en weergave van run_code naar Python gaan. Vereist POSIX en CPython ≥ 3.10 (niet beschikbaar op Windows) en is onverenigbaar met de workflow-tool — de officiële Python-compositie schakelt workflow ook uit, dus de workflow-kant van alle vier varianten blijft uit zolang dit aan staat (je workflow-waarde blijft bewaard en keert terug als je het uitzet). Werkt na een herstart van dsh; dit is dezelfde schakelaar op de kaart van dsh-ptc-cordis-preset — beide kanten delen één status. Alleen zichtbaar zolang dsh-ptc-cordis-preset is geïnstalleerd. Werkt het aanzetten niet, dan staat de reden in het opstartlogboek van dsh.",
516
+ "python.degraded": "backend niet beschikbaar, nog steeds Node (reden in het dsh-opstartlogboek)",
517
+ "python.blocked": "Deze host is Windows: de experimentele Python-backend ondersteunt alleen POSIX, deze schakelaar is niet beschikbaar.",
432
518
  },
433
519
  /* locale: pl */
434
520
  "pl": {
@@ -462,6 +548,13 @@ window.__ModuleLoader__.load({
462
548
  "sec.dedupe": "Deduplikacja z trybem tworzenia PTC",
463
549
  "dedupe.label": "Zduplikowany wpis „tryb tworzenia · Git Bash”",
464
550
  "dedupe.hint": "Gdy dsh-ptc-cordis-preset jest zainstalowany razem, jego „tryb tworzenia PTC” jest już dzięki powiązaniu wersją Git Bash, więc on i „tryb tworzenia · Git Bash” tej wtyczki oznaczają to samo. Po włączeniu deduplikacji ta wtyczka nie rejestruje już własnego wpisu (o jeden mniej w wykazie); domyślnie wyłączona, dzięki czemu cztery warianty pozostają bez zmian. Ten przełącznik to ten sam przełącznik na karcie ustawień drugiej strony — obie strony dzielą jeden stan, zmiana po jednej stronie natychmiast synchronizuje się z drugą. Widoczny tylko, gdy dsh-ptc-cordis-preset jest zainstalowany.",
551
+ "sec.python": "Backend run_code (eksperymentalny Python)",
552
+ "python.label": "Backend run_code",
553
+ "python.on": "Python (eksperymentalny)",
554
+ "python.off": "Node / TypeScript (domyślnie)",
555
+ "python.hint": "Wyłączony (domyślnie) run_code używa oficjalnego backendu Node/TypeScript, identycznego co do bajtu z dostarczaną kompozycją ptc; włączenie przełącza dsh na eksperymentalny backend CPython (@deepseek-ai/dsh-experimental-ptc-runtime-python), więc język, generowany prompt SDK i prezentacja run_code przechodzą na Python. Wymaga POSIX i CPython ≥ 3.10 (niedostępny w Windows) i jest wykluczający z narzędziem workflow — oficjalna kompozycja Python również wyłącza workflow, więc strona workflow wszystkich czterech wariantów pozostaje wyłączona, dopóki to jest włączone (twoje ustawienie workflow jest zachowane i wraca po wyłączeniu). Zmiana działa po restarcie dsh; to ten sam przełącznik na karcie dsh-ptc-cordis-preset — obie strony dzielą jeden stan. Widoczny tylko, gdy dsh-ptc-cordis-preset jest zainstalowany. Jeśli włączenie nie przyniesie skutku, powód znajdziesz w logu startowym dsh.",
556
+ "python.degraded": "backend niedostępny, nadal Node (powód w logu startowym dsh)",
557
+ "python.blocked": "Ten host to Windows: eksperymentalny backend Python obsługuje tylko POSIX, przełącznik jest niedostępny.",
465
558
  },
466
559
  /* locale: pt */
467
560
  "pt": {
@@ -495,6 +588,13 @@ window.__ModuleLoader__.load({
495
588
  "sec.dedupe": "Desduplicação com o modo de criação PTC",
496
589
  "dedupe.label": "Entrada duplicada «modo de criação · Git Bash»",
497
590
  "dedupe.hint": "Quando o dsh-ptc-cordis-preset está instalado em conjunto, o «modo de criação PTC» dele já é a versão Git Bash graças à integração, então ele e o «modo de criação · Git Bash» deste plugin apontam para a mesma coisa. Com a desduplicação ligada, este plugin deixa de registar a sua própria entrada (uma a menos na lista); desligada por padrão, mantendo as quatro variantes inalteradas. Este interruptor é o mesmo do cartão de definições do outro lado — os dois lados partilham um único estado, e uma alteração de um lado sincroniza imediatamente com o outro. Só aparece quando o dsh-ptc-cordis-preset está instalado.",
591
+ "sec.python": "Backend run_code (Python experimental)",
592
+ "python.label": "Backend run_code",
593
+ "python.on": "Python (experimental)",
594
+ "python.off": "Node / TypeScript (padrão)",
595
+ "python.hint": "Desligado (padrão), o run_code usa o backend oficial Node/TypeScript, idêntico byte a byte à composição ptc distribuída; ligado, o dsh passa para o backend CPython experimental (@deepseek-ai/dsh-experimental-ptc-runtime-python), e a linguagem, o prompt SDK gerado e a apresentação do run_code passam para Python. Exige POSIX e CPython ≥ 3.10 (indisponível no Windows) e é incompatível com a ferramenta workflow — a composição Python oficial também desativa workflow, pelo que o lado workflow das quatro variantes fica desligado enquanto isto estiver ligado (o teu valor é mantido e regressa ao desligar). Produz efeito após reiniciar o dsh; é o mesmo interruptor no cartão do dsh-ptc-cordis-preset — os dois lados partilham um único estado. Só aparece quando o dsh-ptc-cordis-preset está instalado. Se ligar não tiver efeito, o motivo está no registo de arranque do dsh.",
596
+ "python.degraded": "backend indisponível, continua Node (motivo no registo de arranque do dsh)",
597
+ "python.blocked": "Este anfitrião é Windows: o backend Python experimental só suporta POSIX, pelo que este interruptor não está disponível.",
498
598
  },
499
599
  /* locale: ru */
500
600
  "ru": {
@@ -528,6 +628,13 @@ window.__ModuleLoader__.load({
528
628
  "sec.dedupe": "Удаление дубликата с творческим режимом PTC",
529
629
  "dedupe.label": "Дублирующая запись «творческий режим · Git Bash»",
530
630
  "dedupe.hint": "Если dsh-ptc-cordis-preset установлен вместе, его «творческий режим PTC» благодаря связке уже является версией Git Bash, поэтому он и «творческий режим · Git Bash» этого плагина указывают на одно и то же. При включённом удалении дубликатов плагин больше не регистрирует свою запись (в списке на одну меньше); по умолчанию выключено, четыре варианта остаются без изменений. Этот переключатель — тот же самый на карточке настроек у второй стороны: обе стороны делят одно состояние, изменение с любой стороны сразу синхронизируется с другой. Показывается только когда установлен dsh-ptc-cordis-preset.",
631
+ "sec.python": "Бэкенд run_code (экспериментальный Python)",
632
+ "python.label": "Бэкенд run_code",
633
+ "python.on": "Python (экспериментальный)",
634
+ "python.off": "Node / TypeScript (по умолчанию)",
635
+ "python.hint": "Выключено (по умолчанию) — run_code использует официальный бэкенд Node/TypeScript, побайтово совпадающий с поставляемой композицией ptc; при включении dsh переходит на экспериментальный бэкенд CPython (@deepseek-ai/dsh-experimental-ptc-runtime-python), и язык, сгенерированная подсказка SDK и представление run_code переключаются на Python. Требуются POSIX и CPython ≥ 3.10 (в Windows недоступно), и это несовместимо с инструментом workflow — официальная композиция Python тоже отключает workflow, поэтому сторона workflow всех четырёх вариантов остаётся выключенной, пока это включено (ваша настройка workflow сохраняется и возвращается после выключения). Изменение действует после перезапуска dsh; это тот же переключатель на карточке dsh-ptc-cordis-preset — обе стороны делят одно состояние. Показывается только когда установлен dsh-ptc-cordis-preset. Если включение не подействовало, причина указана в журнале запуска dsh.",
636
+ "python.degraded": "бэкенд недоступен, по-прежнему Node (причина в журнале запуска dsh)",
637
+ "python.blocked": "Этот хост — Windows: экспериментальный бэкенд Python поддерживает только POSIX, переключатель недоступен.",
531
638
  },
532
639
  /* locale: sv */
533
640
  "sv": {
@@ -561,6 +668,13 @@ window.__ModuleLoader__.load({
561
668
  "sec.dedupe": "Deduplicering med PTC-skaparläget",
562
669
  "dedupe.label": "Dubblerad post ”skaparläge · Git Bash”",
563
670
  "dedupe.hint": "När dsh-ptc-cordis-preset är installerat samtidigt är dess ”PTC-skaparläge” redan Git Bash-versionen tack vare kopplingen, så det och det här pluginets ”skaparläge · Git Bash” pekar på samma sak. Med deduplicering på registrerar pluginet inte längre sin egen post (en färre i listan); av som standard, vilket lämnar de fyra varianterna oförändrade. Den här växeln är samma växel som på motpartens inställningskort — båda sidor delar ett tillstånd, en ändring på ena sidan synkas direkt till den andra. Visas bara när dsh-ptc-cordis-preset är installerat.",
671
+ "sec.python": "run_code-backend (experimentell Python)",
672
+ "python.label": "run_code-backend",
673
+ "python.on": "Python (experimentell)",
674
+ "python.off": "Node / TypeScript (standard)",
675
+ "python.hint": "Av (standard) använder run_code den officiella Node/TypeScript-backenden, byte för byte identisk med den medföljande ptc-kompositionen; på växlar dsh till den experimentella CPython-backenden (@deepseek-ai/dsh-experimental-ptc-runtime-python), vilket även byter run_codes språk, genererade SDK-prompt och presentation till Python. Kräver POSIX och CPython ≥ 3.10 (ej tillgängligt i Windows) och utesluter workflow-verktyget — den officiella Python-kompositionen stänger också av workflow, så workflow-sidan i alla fyra varianter hålls avstängd medan detta är på (ditt workflow-värde behålls och återställs när du stänger av). Gäller efter omstart av dsh; detta är samma växel på dsh-ptc-cordis-presets kort — båda sidor delar ett tillstånd. Visas bara när dsh-ptc-cordis-preset är installerat. Om påslaget inte får effekt står orsaken i dsh:s startlogg.",
676
+ "python.degraded": "backend otillgänglig, fortfarande Node (orsak i dsh-startloggen)",
677
+ "python.blocked": "Den här värden är Windows: den experimentella Python-backenden stöder bara POSIX, så växeln är otillgänglig.",
564
678
  },
565
679
  /* locale: th */
566
680
  "th": {
@@ -594,6 +708,13 @@ window.__ModuleLoader__.load({
594
708
  "sec.dedupe": "ตัดรายการซ้ำกับโหมดสร้างสรรค์ PTC",
595
709
  "dedupe.label": "รายการซ้ำ «โหมดสร้างสรรค์ · Git Bash»",
596
710
  "dedupe.hint": "เมื่อติดตั้ง dsh-ptc-cordis-preset ควบคู่กัน «โหมดสร้างสรรค์ PTC» ของมันเป็นเวอร์ชัน Git Bash อยู่แล้วจากการเชื่อมโยง จึงชี้ไปที่สิ่งเดียวกันกับ «โหมดสร้างสรรค์ · Git Bash» ของปลั๊กอินนี้ เมื่อเปิดการตัดรายการซ้ำ ปลั๊กอินนี้จะไม่ลงทะเบียนรายการของตัวเองอีก (รายการในสารบบลดลงหนึ่งรายการ); ปิดไว้เป็นค่าเริ่มต้น จึงคงสี่รูปแบบไว้เหมือนเดิม สวิตช์นี้คือสวิตช์เดียวกันกับบนการ์ดตั้งค่าของอีกฝ่าย — ทั้งสองฝั่งใช้สถานะเดียวกัน แก้ที่ฝั่งใดอีกฝั่งจะซิงก์ทันที แสดงเฉพาะเมื่อติดตั้ง dsh-ptc-cordis-preset แล้วเท่านั้น",
711
+ "sec.python": "แบ็กเอนด์ run_code (Python ทดลอง)",
712
+ "python.label": "แบ็กเอนด์ run_code",
713
+ "python.on": "Python (ทดลอง)",
714
+ "python.off": "Node / TypeScript (ค่าเริ่มต้น)",
715
+ "python.hint": "เมื่อปิด (ค่าเริ่มต้น) run_code จะใช้แบ็กเอนด์ Node/TypeScript อย่างเป็นทางการ ซึ่งเหมือนกับคอมโพซิชัน ptc ที่จัดส่งทุกไบต์; เมื่อเปิด dsh จะเปลี่ยนไปใช้แบ็กเอนด์ CPython ทดลอง (@deepseek-ai/dsh-experimental-ptc-runtime-python) ภาษา พรอมป์ต์ SDK ที่สร้างขึ้น และการนำเสนอของ run_code จะเปลี่ยนเป็น Python ต้องใช้ POSIX และ CPython ≥ 3.10 (ใช้ไม่ได้บน Windows) และใช้ร่วมกับเครื่องมือ workflow ไม่ได้ — คอมโพซิชัน Python อย่างเป็นทางการก็ปิด workflow เช่นกัน ฝั่ง workflow ของทั้งสี่รูปแบบจึงถูกปิดขณะเปิดอยู่ (ค่าที่คุณตั้งไว้จะถูกเก็บและกลับมาเมื่อปิด) การเปลี่ยนแปลงมีผลหลังรีสตาร์ต dsh; นี่คือสวิตช์เดียวกันบนการ์ดของ dsh-ptc-cordis-preset — ทั้งสองฝั่งใช้สถานะเดียวกัน แสดงเฉพาะเมื่อติดตั้ง dsh-ptc-cordis-preset แล้วเท่านั้น หากเปิดแล้วไม่เกิดผล เหตุผลอยู่ในบันทึกการเริ่มต้นของ dsh",
716
+ "python.degraded": "แบ็กเอนด์ใช้ไม่ได้ ยังเป็น Node (เหตุผลในบันทึกเริ่มต้นของ dsh)",
717
+ "python.blocked": "โฮสต์นี้เป็น Windows: แบ็กเอนด์ Python ทดลองรองรับเฉพาะ POSIX สวิตช์นี้จึงใช้ไม่ได้",
597
718
  },
598
719
  /* locale: tr */
599
720
  "tr": {
@@ -627,6 +748,13 @@ window.__ModuleLoader__.load({
627
748
  "sec.dedupe": "PTC yaratma moduyla yinelenen kaydı kaldırma",
628
749
  "dedupe.label": "«Yaratma modu · Git Bash» yinelenen kaydı",
629
750
  "dedupe.hint": "dsh-ptc-cordis-preset birlikte kuruluysa, bağlantı sayesinde onun «PTC yaratma modu» zaten Git Bash sürümüdür; dolayısıyla o ve bu eklentinin «Yaratma modu · Git Bash» kaydı aynı şeyi gösterir. Yinelenen kaydı kaldırma açıkken bu eklenti kendi kaydını artık kaydetmez (listede bir eksik); varsayılan olarak kapalıdır ve dört varyant değişmeden kalır. Bu anahtar, karşı tarafın ayar kartındaki anahtarın ta kendisidir — iki taraf aynı durumu paylaşır, bir taraftaki değişiklik anında diğerine eşitlenir. Yalnızca dsh-ptc-cordis-preset kurulu olduğunda görünür.",
751
+ "sec.python": "run_code arka ucu (deneysel Python)",
752
+ "python.label": "run_code arka ucu",
753
+ "python.on": "Python (deneysel)",
754
+ "python.off": "Node / TypeScript (varsayılan)",
755
+ "python.hint": "Kapalıyken (varsayılan) run_code resmî Node/TypeScript arka ucunu kullanır ve gönderilen ptc bileşimiyle bayt bayt aynıdır; açıldığında dsh deneysel CPython arka ucuna (@deepseek-ai/dsh-experimental-ptc-runtime-python) geçer; run_code dil, üretilen SDK istemi ve sunum Python'a döner. POSIX ve CPython ≥ 3.10 gerektirir (Windows'ta kullanılamaz) ve workflow aracıyla birbirini dışlar — resmî Python bileşimi de workflow'u kapatır, bu yüzden bu açıkken dört varyantın workflow tarafı kapalı kalır (workflow ayarın korunur ve kapatınca geri gelir). Değişiklik dsh yeniden başlatıldıktan sonra geçerli olur; bu, dsh-ptc-cordis-preset kartındaki aynı anahtardır — iki taraf tek durumu paylaşır. Yalnızca dsh-ptc-cordis-preset kurulu olduğunda görünür. Açmak etkili olmazsa nedeni dsh başlangıç günlüğünde yazar.",
756
+ "python.degraded": "arka uç kullanılamıyor, hâlâ Node (neden dsh başlangıç günlüğünde)",
757
+ "python.blocked": "Bu ana makine Windows: deneysel Python arka ucu yalnızca POSIX destekler, bu anahtar kullanılamaz.",
630
758
  },
631
759
  /* locale: vi */
632
760
  "vi": {
@@ -660,6 +788,13 @@ window.__ModuleLoader__.load({
660
788
  "sec.dedupe": "Loại bỏ trùng lặp với chế độ sáng tạo PTC",
661
789
  "dedupe.label": "Mục trùng lặp «chế độ sáng tạo · Git Bash»",
662
790
  "dedupe.hint": "Khi cài chung dsh-ptc-cordis-preset, nhờ liên kết mà «chế độ sáng tạo PTC» của nó đã là bản Git Bash, nên nó và «chế độ sáng tạo · Git Bash» của plugin này cùng chỉ một thứ. Khi bật loại bỏ trùng lặp, plugin này không đăng ký mục của riêng nó nữa (danh mục bớt một mục); mặc định tắt, giữ nguyên bốn biến thể. Công tắc này chính là công tắc trên thẻ cài đặt của bên kia — hai bên dùng chung một trạng thái, thay đổi ở bên nào cũng đồng bộ ngay sang bên kia. Chỉ hiện khi đã cài dsh-ptc-cordis-preset.",
791
+ "sec.python": "Backend run_code (Python thử nghiệm)",
792
+ "python.label": "Backend run_code",
793
+ "python.on": "Python (thử nghiệm)",
794
+ "python.off": "Node / TypeScript (mặc định)",
795
+ "python.hint": "Khi tắt (mặc định), run_code dùng backend Node/TypeScript chính thức, giống từng byte với tổ hợp ptc được phát hành; khi bật, dsh chuyển sang backend CPython thử nghiệm (@deepseek-ai/dsh-experimental-ptc-runtime-python), kéo theo ngôn ngữ, prompt SDK được sinh và cách trình bày của run_code chuyển sang Python. Yêu cầu POSIX và CPython ≥ 3.10 (không dùng được trên Windows) và loại trừ lẫn nhau với công cụ workflow — tổ hợp Python chính thức cũng tắt workflow, nên phía workflow của cả bốn biến thể bị tắt trong lúc bật (giá trị workflow của bạn được giữ và trở lại khi tắt). Thay đổi có hiệu lực sau khi khởi động lại dsh; đây chính là công tắc trên thẻ của dsh-ptc-cordis-preset — hai bên dùng chung một trạng thái. Chỉ hiện khi đã cài dsh-ptc-cordis-preset. Nếu bật mà không có hiệu lực, lý do nằm trong nhật ký khởi động dsh.",
796
+ "python.degraded": "backend không khả dụng, vẫn là Node (lý do trong nhật ký khởi động dsh)",
797
+ "python.blocked": "Máy chủ này là Windows: backend Python thử nghiệm chỉ hỗ trợ POSIX, nên công tắc này không dùng được.",
663
798
  },
664
799
  /* locale: zh-hk */
665
800
  "zh-hk": {
@@ -693,6 +828,13 @@ window.__ModuleLoader__.load({
693
828
  "sec.dedupe": "與 PTC 創造模式去重",
694
829
  "dedupe.label": "「創造模式 · Git Bash」重複項",
695
830
  "dedupe.hint": "裝埋 dsh-ptc-cordis-preset 嗰陣,佢嘅「PTC 創造模式」喺聯動下已經係 Git Bash 版,同本插件嘅「創造模式 · Git Bash」指向同一件事。開咗去重之後本插件唔再註冊嗰一條(名錄少一項);預設關閉,保持四個變體不變。呢個開關就係對方設定卡上面同一個開關——兩邊共享同一份狀態,任一邊改動另一邊即刻同步。只喺已安裝 dsh-ptc-cordis-preset 時顯示。",
831
+ "sec.python": "run_code 後端(實驗性 Python)",
832
+ "python.label": "run_code 後端",
833
+ "python.on": "Python(實驗性)",
834
+ "python.off": "Node / TypeScript(預設)",
835
+ "python.hint": "閂咗(預設)嗰陣 run_code 用官方 Node/TypeScript 後端,同官方 ptc 組合逐位元組一致;開咗就轉用 dsh 實驗性 CPython 後端(@deepseek-ai/dsh-experimental-ptc-runtime-python),run_code 嘅語言、生成嘅 SDK 提示詞同工具呈現都會轉去 Python。需要 POSIX 平台同 CPython ≥ 3.10(Windows 用唔到),而且同 workflow 工具互斥——官方 Python 組合同樣停用 workflow,所以開住嗰陣本插件四個變體嘅 workflow 側會強制關閉(你嘅工作流設定值會保留,閂咗之後恢復)。改動要重啟 dsh 先生效;呢個開關就係 dsh-ptc-cordis-preset 設定卡上面同一個開關——兩邊共享同一份狀態。只喺已安裝 dsh-ptc-cordis-preset 時顯示。開咗之後唔生效,原因喺 dsh 啟動日誌度。",
836
+ "python.degraded": "後端用唔到,暫時仍然係 Node(原因喺 dsh 啟動日誌)",
837
+ "python.blocked": "呢部主機係 Windows:實驗性 Python 後端淨係支援 POSIX,所以呢個開關用唔到。",
696
838
  },
697
839
  /* locale: zh-mo */
698
840
  "zh-mo": {
@@ -726,6 +868,13 @@ window.__ModuleLoader__.load({
726
868
  "sec.dedupe": "與 PTC 創造模式去重",
727
869
  "dedupe.label": "「創造模式 · Git Bash」重複項",
728
870
  "dedupe.hint": "裝埋 dsh-ptc-cordis-preset 嗰陣,佢嘅「PTC 創造模式」喺聯動下已經係 Git Bash 版,同本插件嘅「創造模式 · Git Bash」指向同一件事。開咗去重之後本插件唔再註冊嗰一條(名錄少一項);預設關閉,保持四個變體不變。呢個開關就係對方設定卡上面同一個開關——兩邊共享同一份狀態,任一邊改動另一邊即刻同步。只喺已安裝 dsh-ptc-cordis-preset 時顯示。",
871
+ "sec.python": "run_code 後端(實驗性 Python)",
872
+ "python.label": "run_code 後端",
873
+ "python.on": "Python(實驗性)",
874
+ "python.off": "Node / TypeScript(預設)",
875
+ "python.hint": "閂咗(預設)嗰陣 run_code 用官方 Node/TypeScript 後端,同官方 ptc 組合逐位元組一致;開咗就轉用 dsh 實驗性 CPython 後端(@deepseek-ai/dsh-experimental-ptc-runtime-python),run_code 嘅語言、生成嘅 SDK 提示詞同工具呈現都會轉去 Python。需要 POSIX 平台同 CPython ≥ 3.10(Windows 用唔到),而且同 workflow 工具互斥——官方 Python 組合同樣停用 workflow,所以開住嗰陣本插件四個變體嘅 workflow 側會強制關閉(你嘅工作流設定值會保留,閂咗之後恢復)。改動要重啟 dsh 先生效;呢個開關就係 dsh-ptc-cordis-preset 設定卡上面同一個開關——兩邊共享同一份狀態。只喺已安裝 dsh-ptc-cordis-preset 時顯示。開咗之後唔生效,原因喺 dsh 啟動日誌度。",
876
+ "python.degraded": "後端用唔到,暫時仍然係 Node(原因喺 dsh 啟動日誌)",
877
+ "python.blocked": "呢部主機係 Windows:實驗性 Python 後端淨係支援 POSIX,所以呢個開關用唔到。",
729
878
  },
730
879
  /* locale: zh-tw */
731
880
  "zh-tw": {
@@ -759,6 +908,13 @@ window.__ModuleLoader__.load({
759
908
  "sec.dedupe": "與 PTC 創造模式去重",
760
909
  "dedupe.label": "「創造模式 · Git Bash」重複項目",
761
910
  "dedupe.hint": "同時安裝 dsh-ptc-cordis-preset 時,它的「PTC 創造模式」在聯動下已是 Git Bash 版,與本插件的「創造模式 · Git Bash」指向同一件事。開啟去重後本插件不再註冊那一條(清單少一項);預設關閉,保持四個變體不變。這個開關就是對方設定卡上的同一個開關——兩側共享同一份狀態,任一側改動另一側立即同步。僅在已安裝 dsh-ptc-cordis-preset 時顯示。",
911
+ "sec.python": "run_code 後端(實驗性 Python)",
912
+ "python.label": "run_code 後端",
913
+ "python.on": "Python(實驗性)",
914
+ "python.off": "Node / TypeScript(預設)",
915
+ "python.hint": "關閉(預設)時 run_code 使用官方 Node/TypeScript 後端,與官方 ptc 組合逐位元組一致;開啟後改用 dsh 實驗性 CPython 後端(@deepseek-ai/dsh-experimental-ptc-runtime-python),run_code 的語言、產生的 SDK 提示詞與工具呈現都會切換到 Python。需要 POSIX 平台與 CPython ≥ 3.10(Windows 無法使用),且與 workflow 工具互斥——官方 Python 組合同樣會停用 workflow,因此開啟期間本外掛四個變體的 workflow 側強制關閉(你的工作流設定值會保留,關閉後恢復)。變更需重新啟動 dsh 後生效;這個開關就是 dsh-ptc-cordis-preset 設定卡上的同一個開關——兩側共用同一份狀態。僅在已安裝 dsh-ptc-cordis-preset 時顯示。若設為開啟後未生效,原因見 dsh 啟動日誌。",
916
+ "python.degraded": "後端無法使用,目前仍為 Node(原因見 dsh 啟動日誌)",
917
+ "python.blocked": "此主機是 Windows:實驗性 Python 後端僅支援 POSIX,因此這個開關無法使用。",
762
918
  },
763
919
  };
764
920
 
@@ -980,6 +1136,25 @@ window.__ModuleLoader__.load({
980
1136
  return typeof unsubscribe === "function" ? unsubscribe : undefined;
981
1137
  }, []);
982
1138
 
1139
+ /* The experimental Python backend refuses to load on Windows
1140
+ (packages/experimental/ptc-runtime-python: POSIX rlimits, fd-3
1141
+ stdio, process-group signals), and a browser cannot see the host
1142
+ OS. The one host fact this card can read is the remote face's
1143
+ reported home: a drive-letter path means a Windows host, which is
1144
+ exactly where that backend cannot run. Absent or unreadable keeps
1145
+ the switch usable — the host side still rejects an impossible
1146
+ write. */
1147
+ var winState = useState(false);
1148
+ var winHost = winState[0];
1149
+ var setWinHost = winState[1];
1150
+ useEffect(function () {
1151
+ try {
1152
+ var remote = props.ctx === undefined || props.ctx === null ? undefined : props.ctx.get("remote");
1153
+ var host = remote && remote.$host ? remote.$host.home : undefined;
1154
+ if (typeof host === "string" && /^[A-Za-z]:[\\/]/.test(host)) setWinHost(true);
1155
+ } catch (error_) { /* keep the switch usable */ }
1156
+ }, []);
1157
+
983
1158
  var bashState = useState("");
984
1159
  var bashDraft = bashState[0];
985
1160
  var setBashDraft = bashState[1];
@@ -1137,10 +1312,68 @@ window.__ModuleLoader__.load({
1137
1312
  ),
1138
1313
  ) : null;
1139
1314
 
1315
+ /* Python row (v0.26.0): the SECOND seat of the PEER's switch. Unlike
1316
+ the dedupe row above, the value does NOT live on our row — the
1317
+ experimental run_code backend replaces a profile-level row, so its
1318
+ authoritative state is dsh-ptc-cordis-preset's own `pythonRuntime`
1319
+ field and BOTH cards read/write that one form. Drawn only when the
1320
+ peer's snapshot actually carries the field (an older peer without
1321
+ the switch draws nothing), and the buttons write through the peer
1322
+ form so either side syncs the other immediately. On a Windows host
1323
+ the switch is inert — the CPython backend refuses to load there —
1324
+ so the buttons give way to that reason. */
1325
+ var pythonOffered = peerSnap.status === "ready" && peerSnap.value !== null
1326
+ && typeof peerSnap.value === "object"
1327
+ && Object.prototype.hasOwnProperty.call(peerSnap.value, PEER_PYTHON_FIELD);
1328
+ var pythonOn = pythonOffered && peerSnap.value[PEER_PYTHON_FIELD] === true;
1329
+ var peerPythonBackend = "";
1330
+ if (pythonOffered && typeof peerSnap.value[PEER_PYTHON_BACKEND_FIELD] === "string") {
1331
+ peerPythonBackend = peerSnap.value[PEER_PYTHON_BACKEND_FIELD];
1332
+ }
1333
+ /* Intent on + effective node = the user asked for Python and the host
1334
+ is still running Node behind the official rows. */
1335
+ var pythonDegraded = pythonOn && peerPythonBackend === "node";
1336
+ function writePython(next) {
1337
+ setError("");
1338
+ if (peer === null || typeof peer.set !== "function") return;
1339
+ try {
1340
+ Promise.resolve(peer.set(PEER_PYTHON_FIELD, next)).then(
1341
+ function () { bumpTick(function (n) { return n + 1; }); },
1342
+ function (err) {
1343
+ bumpTick(function (n) { return n + 1; });
1344
+ setError(t("error") + ": " + (err && err.message ? err.message : String(err)));
1345
+ },
1346
+ );
1347
+ } catch (err) {
1348
+ bumpTick(function (n) { return n + 1; });
1349
+ setError(t("error") + ": " + (err && err.message ? err.message : String(err)));
1350
+ }
1351
+ }
1352
+
1353
+ var pythonSection = pythonOffered ? E("div", { className: "gb-section" },
1354
+ E("div", { className: "gb-sectionTitle" }, t("sec.python")),
1355
+ E("div", { className: "gb-stack" },
1356
+ E("div", { className: "gb-row" },
1357
+ E("span", { className: "gb-rowLabel" }, t("python.label") + ":"),
1358
+ E("span", { className: "gb-rowValue" }, pythonOn
1359
+ ? (pythonDegraded ? t("python.on") + " · " + t("python.degraded") : t("python.on"))
1360
+ : t("python.off")),
1361
+ ),
1362
+ winHost ? null : E("div", { className: "gb-seg" },
1363
+ E("button", { type: "button", className: "gb-segBtn" + (pythonOn ? " gb-segActive" : ""), onClick: function () { if (!pythonOn) writePython(true); } }, t("switch.on")),
1364
+ E("button", { type: "button", className: "gb-segBtn" + (!pythonOn ? " gb-segActive" : ""), onClick: function () { if (pythonOn) writePython(false); } }, t("switch.off")),
1365
+ ),
1366
+ E("p", { className: "gb-hint" }, t("python.hint")),
1367
+ winHost ? E("p", { className: "gb-error" }, t("python.blocked")) : null,
1368
+ pythonDegraded ? E("p", { className: "gb-error" }, t("python.degraded")) : null,
1369
+ ),
1370
+ ) : null;
1371
+
1140
1372
  var bodyContent = E("div", { className: "gb-body" },
1141
1373
  dialectSection,
1142
1374
  terminalSection,
1143
1375
  dedupeSection,
1376
+ pythonSection,
1144
1377
  error ? E("p", { className: "gb-error" }, error) : null,
1145
1378
  );
1146
1379
 
@@ -12,7 +12,12 @@
12
12
  * one Git Bash delta: the bash rows are always on and the pwsh rows are
13
13
  * always off (the host executor is this plugin's shell.js — on non-Windows
14
14
  * hosts that is the native stack anyway, which is exactly what the old
15
- * materialized variants encoded).
15
+ * materialized variants encoded). A second, conditional delta exists while
16
+ * dsh-ptc-cordis-preset reports its experimental-CPython backend ACTIVE: the
17
+ * two workflow rows follow the official Python composition and go off (see
18
+ * `pythonActive` below). While that backend is off — the default, and also
19
+ * whenever the peer's preflight failed — the rows are the official ones
20
+ * unchanged.
16
21
  */
17
22
 
18
23
  /** Default Git Bash binary — must match src/shell.js and the patch config. */
@@ -44,13 +49,25 @@ When ready, call exit_plan_mode with the complete plan markdown, starting with a
44
49
  * @param {boolean} input.gitBash - bash rows always on, pwsh rows always off.
45
50
  * @param {string|undefined} input.skillsDir - Creation authoring skills
46
51
  * directory (cordis variant only; resolved beside the agent-preset package).
52
+ * @param {boolean} [input.pythonActive] - whether the experimental CPython
53
+ * backend is the one run_code will ACTUALLY use (the peer's effective
54
+ * backend, not the bare user intent: when its preflight fails the
55
+ * composition still runs Node and the workflow rows must stay live).
56
+ * `workflow-ptc` hard-requires `ctx.ptcRuntime.language === 'typescript'`
57
+ * (packages/workflow/workflow-ptc/src/index.ts:117) while the CPython
58
+ * backend reports 'python', and a throwing preset row rejects the WHOLE
59
+ * mount (agent-preset-registry mount.ts). The official Python composition
60
+ * disables both workflow rows for exactly this reason
61
+ * (snapshots/session/ptc-python-turn/cordis.yml), so while CPython is
62
+ * active every variant mirrors that: the two rows go off, the user's own
63
+ * workflow setting is untouched and returns once it is not.
47
64
  * @returns {object[]} the declarative plugins list.
48
65
  */
49
- export function pluginsFor({ kind, gitBash, skillsDir }) {
66
+ export function pluginsFor({ kind, gitBash, skillsDir, pythonActive = false }) {
50
67
  const win = typeof process !== 'undefined' && process.platform === 'win32'
51
68
  const bashDisabled = gitBash ? false : win
52
69
  const pwshDisabled = gitBash ? true : !win
53
- const workflowOn = kind !== 'ptc'
70
+ const workflowOn = kind !== 'ptc' && pythonActive !== true
54
71
  const rows = [
55
72
  {
56
73
  id: 'persona',
package/src/index.js CHANGED
@@ -102,9 +102,84 @@ export const PRESET_IDS = ['standard-gitbash', 'minimal-gitbash', 'code-gitbash'
102
102
  */
103
103
  export const PEER_COVERED_PRESET_ID = 'cordis-gitbash'
104
104
 
105
- /** Service dsh-ptc-cordis-preset publishes: `{ id, gitBashActive }`. */
105
+ /**
106
+ * Service dsh-ptc-cordis-preset publishes:
107
+ * `{ id, gitBashActive, pythonRuntime, pythonBackend? }`. `pythonRuntime` is
108
+ * the user's INTENT for the experimental CPython run_code backend (the field
109
+ * the settings card writes); `pythonBackend` ('python' | 'node', v0.15.1+,
110
+ * additive) is the backend that is ACTUALLY active after the peer's own
111
+ * preflight — package resolvable, interpreter qualified, POSIX host.
112
+ */
106
113
  export const PEER_CAPABILITY = 'ptcCordisPreset'
107
114
 
115
+ /**
116
+ * The peer's CPython intent field — on its capability AND on its row Config
117
+ * (the field both settings cards read and write).
118
+ */
119
+ export const PEER_PYTHON_FIELD = 'pythonRuntime'
120
+
121
+ /** The peer's EFFECTIVE backend field on the capability ('python' | 'node'). */
122
+ export const PEER_PYTHON_BACKEND_FIELD = 'pythonBackend'
123
+
124
+ /**
125
+ * Read one boolean fact off the peer's capability object. A getter is honoured
126
+ * so a live peer can report its current switch rather than a boot-time copy;
127
+ * anything absent, of the wrong type, or throwing reads as false — the
128
+ * conservative direction is always "the official Node backend is in use".
129
+ * @param {object|undefined} capability - the peer's published capability.
130
+ * @param {string} field - the field name to read.
131
+ * @returns {boolean} the fact, false when it cannot be established.
132
+ */
133
+ export function peerFact(capability, field) {
134
+ if (capability === null || capability === undefined) return false
135
+ try {
136
+ const raw = capability[field]
137
+ const value = typeof raw === 'function' ? raw.call(capability) : raw
138
+ return value === true
139
+ } catch {
140
+ return false
141
+ }
142
+ }
143
+
144
+ /**
145
+ * The peer's EFFECTIVE run_code backend, as the closed two-value vocabulary it
146
+ * publishes. `undefined` means "the peer does not report one" — an older peer,
147
+ * a getter that threw, or a value outside the vocabulary — and every caller
148
+ * must then fall back to the INTENT, which is the pre-v0.15.1 behavior.
149
+ * @param {object|undefined} capability - the peer's published capability.
150
+ * @returns {'python'|'node'|undefined} the reported backend.
151
+ */
152
+ export function peerBackend(capability) {
153
+ if (capability === null || capability === undefined) return undefined
154
+ try {
155
+ const raw = capability[PEER_PYTHON_BACKEND_FIELD]
156
+ const value = typeof raw === 'function' ? raw.call(capability) : raw
157
+ return value === 'python' || value === 'node' ? value : undefined
158
+ } catch {
159
+ return undefined
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Is the experimental CPython backend ACTUALLY the one run_code will use? The
165
+ * composition's workflow mutex keys on this, never on the bare intent: when the
166
+ * peer's preflight fails (package removed, interpreter too old, win32) the
167
+ * composition still runs Node, so forcing the workflow rows off would cost the
168
+ * user a capability for nothing.
169
+ *
170
+ * An older peer without the effective field reports no backend, and the intent
171
+ * stands in for it — exactly the pre-v0.15.1 behavior, so the linkage never
172
+ * changes shape because a field is missing.
173
+ * @param {object|undefined} capability - the peer's published capability.
174
+ * @returns {boolean} true only while the CPython backend is the active one.
175
+ */
176
+ export function pythonBackendActive(capability) {
177
+ const intent = peerFact(capability, PEER_PYTHON_FIELD)
178
+ const reported = peerBackend(capability)
179
+ if (reported === undefined) return intent
180
+ return intent && reported === 'python'
181
+ }
182
+
108
183
  /**
109
184
  * The roster this plugin serves: the configured list, minus the variant a peer
110
185
  * already covers. Two independent facts must BOTH hold before anything is
@@ -956,9 +1031,16 @@ export async function detectPeerCoverage(ctx, timeoutMs = 1000, intervalMs = 25)
956
1031
  // a path as a whole-value FIELD, which never goes through here (driveToMsys).
957
1032
  // The lookbehind set rejects URL schemes (https:), file:// forms, and anything
958
1033
  // already mid-word, so only real drive-letter paths are translated. Separators
959
- // normalize to single slashes.
960
- const BARE_WIN_PATH = /(?<![A-Za-z0-9:\\/"'`])([A-Za-z]):(?:\\|\/)([^\s"'`<>|),;:!?]+(?: [^\s"'`<>|),;:!?]*[\\/][^\s"'`<>|),;:!?]*)*)/g
961
- const QUOTED_WIN_PATH = /(["'`])([A-Za-z]):(?:\\|\/)([^`]*?)\1/g
1034
+ // normalize to single slashes. The separator group after the colon consumes
1035
+ // EVERY consecutive separator (`[\\/]+`), not just one (v0.26.0, issue #10):
1036
+ // JSON-escaped Windows paths ("D:\\dsh\\工作" as the host renders
1037
+ // `${JSON.stringify(workspaceRoot)}` in sandbox:policy) carry a DOUBLED
1038
+ // backslash, and a single-separator atom left the second one at the head of
1039
+ // `rest`, where the separator normalization turned it into a leading slash —
1040
+ // "/d/" + "/dsh/工作" = "/d//dsh/工作", a non-canonical workspace root the
1041
+ // model then copied. Single-separator inputs are byte-for-byte unchanged.
1042
+ const BARE_WIN_PATH = /(?<![A-Za-z0-9:\\/"'`])([A-Za-z]):[\\/]+([^\s"'`<>|),;:!?]+(?: [^\s"'`<>|),;:!?]*[\\/][^\s"'`<>|),;:!?]*)*)/g
1043
+ const QUOTED_WIN_PATH = /(["'`])([A-Za-z]):[\\/]+([^`]*?)\1/g
962
1044
 
963
1045
  /** Rewrite every Windows absolute path in a text to the MSYS form; pure. */
964
1046
  export function windowsToMsys(text) {
@@ -2022,12 +2104,12 @@ function cleanupLegacyTrees(presetIds) {
2022
2104
  * failures stay visible through the roster's broken diagnostic instead of
2023
2105
  * failing the boot.
2024
2106
  */
2025
- async function registerVariant(ctx, presetId, { gitBashActive, skillsDir }) {
2107
+ async function registerVariant(ctx, presetId, { gitBashActive, skillsDir, pythonActive }) {
2026
2108
  const meta = PRESET_META[presetId]
2027
2109
  if (!meta) return undefined
2028
2110
  const plugins = meta.kind === 'minimal'
2029
2111
  ? minimalPluginsFor()
2030
- : pluginsFor({ kind: meta.kind, gitBash: gitBashActive, skillsDir })
2112
+ : pluginsFor({ kind: meta.kind, gitBash: gitBashActive, skillsDir, pythonActive })
2031
2113
  return ctx.agentPresets.register({
2032
2114
  id: presetId,
2033
2115
  name: meta.name,
@@ -2040,10 +2122,13 @@ async function registerVariant(ctx, presetId, { gitBashActive, skillsDir }) {
2040
2122
  /**
2041
2123
  * Declarative-era wiring: keep exactly one registration per VARIANT THIS HOST
2042
2124
  * SHOULD SERVE for the plugin's lifetime, and re-reconcile whenever that set
2043
- * changes. Two inputs drive it — the live `suppressPeerCordis` switch and the
2125
+ * changes. Three inputs drive it — the live `suppressPeerCordis` switch, the
2044
2126
  * peer capability appearing (or leaving) via `ctx.inject`, which fires
2045
- * independent of row activation order — and the peer's own coverage only
2046
- * counts while it reports a Git Bash-materialized preset.
2127
+ * independent of row activation order, and the peer's EFFECTIVE CPython
2128
+ * backend (`pythonBackend`, falling back to the `pythonRuntime` intent on a
2129
+ * peer that does not report one), which changes the ROWS of every variant —
2130
+ * and the peer's own coverage only counts while it reports a Git Bash-
2131
+ * materialized preset.
2047
2132
  *
2048
2133
  * The roster picks entries up immediately; sessions already pinned to a
2049
2134
  * variant keep their revision until recomposed, so suppressing a variant never
@@ -2060,6 +2145,9 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress) {
2060
2145
  /** presetId -> unregister, i.e. exactly what is live right now. */
2061
2146
  const live = new Map()
2062
2147
  let peerGitBash = false
2148
+ let peerPython = false
2149
+ /** The CPython fact the LIVE registrations were built with. */
2150
+ let registeredPython = false
2063
2151
  let serial = Promise.resolve()
2064
2152
 
2065
2153
  const desired = () => effectivePresetIds(presetIds, { suppress: readSuppress(), peerGitBash })
@@ -2067,6 +2155,24 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress) {
2067
2155
  const reconcile = () => {
2068
2156
  serial = serial.then(async () => {
2069
2157
  const want = desired()
2158
+ // The peer's EFFECTIVE CPython backend rewrites the workflow rows of
2159
+ // EVERY variant (the official Python composition disables them, and
2160
+ // workflow-ptc refuses a non-TypeScript backend), so a flip re-registers
2161
+ // the live variants instead of leaving stale rows mounted. Same cadence
2162
+ // as the backend swap itself: the peer's patch is evaluated at boot. A
2163
+ // bare INTENT without the effective backend changes nothing here — the
2164
+ // composition still runs Node, so the workflow rows must stay live.
2165
+ if (live.size > 0 && registeredPython !== peerPython) {
2166
+ for (const [presetId, off] of [...live]) {
2167
+ live.delete(presetId)
2168
+ try {
2169
+ await off()
2170
+ console.log(TAG + " preset '" + presetId + "' retired (peer CPython backend changed; rows are rebuilt)")
2171
+ } catch (error) {
2172
+ console.log(TAG + " preset '" + presetId + "' retirement failed: " + (error && error.message ? error.message : error))
2173
+ }
2174
+ }
2175
+ }
2070
2176
  for (const [presetId, off] of [...live]) {
2071
2177
  if (want.includes(presetId)) continue
2072
2178
  live.delete(presetId)
@@ -2080,7 +2186,7 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress) {
2080
2186
  for (const presetId of want) {
2081
2187
  if (live.has(presetId)) continue
2082
2188
  try {
2083
- const unregister = await registerVariant(ctx, presetId, { gitBashActive, skillsDir })
2189
+ const unregister = await registerVariant(ctx, presetId, { gitBashActive, skillsDir, pythonActive: peerPython })
2084
2190
  if (unregister) {
2085
2191
  live.set(presetId, unregister)
2086
2192
  console.log(TAG + " preset '" + presetId + "' registered declaratively")
@@ -2089,6 +2195,7 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress) {
2089
2195
  console.log(TAG + " preset '" + presetId + "' registration failed: " + (error && error.message ? error.message : error))
2090
2196
  }
2091
2197
  }
2198
+ registeredPython = peerPython
2092
2199
  }).catch((error) => {
2093
2200
  console.log(TAG + ' preset reconcile failed: ' + (error && error.message ? error.message : error))
2094
2201
  })
@@ -2105,17 +2212,31 @@ async function runDeclarativeEra(ctx, presetIds, readSuppress) {
2105
2212
  ctx.inject([PEER_CAPABILITY], (peerCtx) => {
2106
2213
  try {
2107
2214
  const coverage = peerCtx[PEER_CAPABILITY] ?? peerCtx.get(PEER_CAPABILITY)
2108
- const next = coverage?.gitBashActive === true
2109
- if (next !== peerGitBash) {
2110
- peerGitBash = next
2215
+ const nextGitBash = peerFact(coverage, 'gitBashActive')
2216
+ // INTENT (what the user asked for) vs EFFECTIVE (what run_code will
2217
+ // actually use). Only the effective fact may cost the user a variant's
2218
+ // workflow rows; the intent alone is reported, never acted on.
2219
+ const intentPython = peerFact(coverage, PEER_PYTHON_FIELD)
2220
+ const reportedBackend = peerBackend(coverage)
2221
+ const nextPython = pythonBackendActive(coverage)
2222
+ if (nextGitBash !== peerGitBash || nextPython !== peerPython) {
2223
+ peerGitBash = nextGitBash
2224
+ peerPython = nextPython
2225
+ if (nextPython) console.log(TAG + ' peer reports the experimental CPython run_code backend: workflow rows go off in every variant')
2226
+ else if (intentPython) {
2227
+ console.log(TAG + ' peer has the CPython switch on but the effective backend is '
2228
+ + (reportedBackend === undefined ? 'unreported (older peer: the intent stands in)' : reportedBackend)
2229
+ + ': workflow rows stay on (reason in the host log)')
2230
+ }
2111
2231
  void reconcile()
2112
2232
  }
2113
2233
  } catch (error) {
2114
2234
  console.log(TAG + ' peer coverage read failed: ' + (error && error.message ? error.message : error))
2115
2235
  }
2116
2236
  peerCtx.effect(() => () => {
2117
- if (!peerGitBash) return
2237
+ if (!peerGitBash && !peerPython) return
2118
2238
  peerGitBash = false
2239
+ peerPython = false
2119
2240
  void reconcile()
2120
2241
  }, 'dsh-gitbash-shell: peer coverage release')
2121
2242
  })
@@ -2596,4 +2717,4 @@ export async function apply(ctx, config = {}) {
2596
2717
  }
2597
2718
 
2598
2719
  // Test surface: pure helpers, no Cordis context required.
2599
- export const _internal = { PRESET_IDS, PEER_COVERED_PRESET_ID, PEER_CAPABILITY, effectivePresetIds, detectPeerCoverage, readSuppressPeerCordis, translateDispatch, translateMsysPath, translatePathArguments, rewriteCodePaths, scanCodeLiterals, programPrelude, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, rewriteErrorMessage, rewriteFailureMessage, msysEcho, driveToMsys, pathEcho, ERROR_CONTENT_TOOLS, readPosixPaths, readAdoptSidebar, readDialectSettings, windowsToMsys, rewriteResultPaths, adoptSidebarShell, MARKER_FILE, classify, materialize, cleanupOnDispose, firstUserRoot, hashTree, skillsHashes, syncDecision, installRegisterShim, baseForRoster, detectBase, pickComposition, personaEraForText, detectPersonaEra, injectPresentRow, hostHasToolPresent, detectPresentSupport, injectPluginManagerRow, hostHasPluginManagerTools, rowFormOf, rowFormsOf, alignEngineRow, alignRalphRow, ROW_SOURCE }
2720
+ export const _internal = { PRESET_IDS, PEER_COVERED_PRESET_ID, PEER_CAPABILITY, PEER_PYTHON_FIELD, PEER_PYTHON_BACKEND_FIELD, peerFact, peerBackend, pythonBackendActive, effectivePresetIds, detectPeerCoverage, readSuppressPeerCordis, translateDispatch, translateMsysPath, translatePathArguments, rewriteCodePaths, scanCodeLiterals, programPrelude, translateGlobArguments, buildTranslateEnv, rewriteErrorContent, rewriteErrorMessage, rewriteFailureMessage, msysEcho, driveToMsys, pathEcho, ERROR_CONTENT_TOOLS, readPosixPaths, readAdoptSidebar, readDialectSettings, windowsToMsys, rewriteResultPaths, adoptSidebarShell, MARKER_FILE, classify, materialize, cleanupOnDispose, firstUserRoot, hashTree, skillsHashes, syncDecision, installRegisterShim, baseForRoster, detectBase, pickComposition, personaEraForText, detectPersonaEra, injectPresentRow, hostHasToolPresent, detectPresentSupport, injectPluginManagerRow, hostHasPluginManagerTools, rowFormOf, rowFormsOf, alignEngineRow, alignRalphRow, ROW_SOURCE }