dsh-gitbash-shell 0.38.2 → 0.38.3

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,15 @@
3
3
  > 倒序排列,新版本条目在最上面。条目格式:`## vX.Y.Z — YYYY-MM-DD` + 类型(feat / fix / docs / chore)+ 要点 + 相关链接。
4
4
  > 纪律见 AGENTS.md「变更记录纪律」:发版前先更新本文件并随版本提交;事故复盘、复现与真机验证记录也记在这里。
5
5
 
6
+ ## v0.38.3 — 2026-10-13
7
+
8
+ **类型**:fix(补位激活的 scope 上下文时序;用户终端日志一锤定音)。
9
+
10
+ - **根因(日志 `official tool-bash activation failed: Cannot read properties of undefined (reading 'shell')`)**:cordis 的 `ctx.plugin()` **只创建 Fiber 就返回,插件的 apply 回调是异步启动的**(`vendor/cordis/lib/index.js:1619`,wrapped fiber 是 thenable)——`createScope` 返回时 `childCtx` 还是 `undefined`,`mod.apply(undefined, {})` 在官方模块第一行 `ctx.shell.sandboxMode` 上炸。此前的解析修复(v0.38.1)已生效:模块拿到了,死在最后一步。
11
+ - **修复**:`createScope` 返回 `{ fiber, get ctx(), dispose }`;`activateOfficialBash` 与 `providePwsh`(同款隐患,此前 pwsh7 开了也会静默发不出)在动手前 `await scope.fiber` 等回调跑完,再校验 `scope.ctx` 就绪。
12
+ - **冒烟**:118 项全绿。
13
+ - **真机判据**:升级重启新建会话 → 工具面出现 `bash`;日志出现 `official bash tool activated for this agent`。若再现 activation failed,错误行会指向官方模块内部的真实原因(而非 ctx undefined)。
14
+
6
15
  ## v0.38.2 — 2026-10-13
7
16
 
8
17
  **类型**:fix(v0.38.0 折叠分区在真机上完全失效;用户截图定位)。
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-gitbash-shell",
3
- "version": "0.38.2",
3
+ "version": "0.38.3",
4
4
  "main": "./src/index.js",
5
5
  "description": "Windows 全模式 Git Bash:用 Git for Windows bash 替换 PowerShell 执行器;官方四个模式经行内工具补位直接获得 Git Bash(v0.35.0,默认),四个 *·Git Bash 变体 preset 可开关;附带 gitbash_pwsh(系统 PowerShell 7)与 gb_* FastCtx 文件工具,检测到 dsh-ops 自动让位。联动:dsh-ptc-cordis-preset(PTC 创造模式带 Git Bash 行且可去重)+ dsh-better-sidebar(终端标签自动切 Git Bash)。",
6
6
  "engines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-gitbash-shell",
3
- "version": "0.38.2",
3
+ "version": "0.38.3",
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/index.js CHANGED
@@ -2618,7 +2618,14 @@ export async function apply(ctx, config = {}) {
2618
2618
  let childCtx
2619
2619
  const fiber = agentCtx.plugin((c) => { childCtx = c })
2620
2620
  return {
2621
- ctx: childCtx,
2621
+ // cordis plugin() starts the fiber ASYNCHRONOUSLY — the apply
2622
+ // callback that captures childCtx has NOT run when plugin()
2623
+ // returns. The wrapped fiber is a thenable (`fiber.await()`):
2624
+ // awaiting it is the only way to observe childCtx being set
2625
+ // (v0.38.3, real machine: apply(undefined) crashed with
2626
+ // "Cannot read properties of undefined (reading 'shell')").
2627
+ fiber,
2628
+ get ctx() { return childCtx },
2622
2629
  dispose: async () => { try { await fiber?.dispose?.() } catch { /* already gone */ } },
2623
2630
  }
2624
2631
  },
@@ -279,6 +279,20 @@ export async function activateOfficialBash(agent, resolved, createScopeFn, log)
279
279
  return undefined
280
280
  }
281
281
  const scope = createScopeFn(agent.ctx)
282
+ // plugin() starts the fiber asynchronously; awaiting the wrapped thenable
283
+ // guarantees the apply callback has captured scope.ctx before we hand it
284
+ // to the official module (v0.38.2-and-earlier passed undefined here and
285
+ // crashed inside `ctx.shell`).
286
+ if (scope.fiber) {
287
+ try { await scope.fiber } catch (error) {
288
+ log(`official tool-bash scope fiber failed to start: ${error?.message ?? error}`)
289
+ return undefined
290
+ }
291
+ }
292
+ if (!scope.ctx) {
293
+ log('official tool-bash scope context did not initialize; activation skipped')
294
+ return undefined
295
+ }
282
296
  try {
283
297
  await mod.apply(scope.ctx, {})
284
298
  return scope
@@ -332,12 +346,15 @@ export function mountInlineTools(ctx, deps) {
332
346
  * pure ADDITION — it shadows nothing and requires no deny juggling. The
333
347
  * scope keeps the registration revertible at agent disposal.
334
348
  */
335
- const providePwsh = (agent, state) => {
349
+ const providePwsh = async (agent, state) => {
336
350
  if (state.pwshScope) return
337
351
  if (typeof spawn !== 'function' || !pwshPath) return
338
352
  if (!createScope) return
339
353
  try {
340
354
  const scope = createScope(agent.ctx)
355
+ // Same asynchronous-fiber shape as activateOfficialBash: wait for the
356
+ // apply callback to capture scope.ctx before touching its tools.
357
+ if (scope.fiber) { try { await scope.fiber } catch { /* disposed */ } }
341
358
  const registry = scope.ctx?.tools
342
359
  if (!registry || typeof registry.register !== 'function') {
343
360
  void scope.dispose().catch(() => {})
@@ -400,7 +417,7 @@ export function mountInlineTools(ctx, deps) {
400
417
  log(`fake-pwsh deny failed: ${error?.message ?? error}`)
401
418
  }
402
419
  }
403
- if (deps.pwshEnabled && deps.pwshEnabled() === true) providePwsh(agent, state)
420
+ if (deps.pwshEnabled && deps.pwshEnabled() === true) void providePwsh(agent, state)
404
421
  }
405
422
  }
406
423
  if (needs.needsBash && !state.scope) {