Procházet zdrojové kódy

fix(terminal-bash): fall back to dialect defaults when Schemastery materializes empty shell values

Huanqi Cao před 1 měsícem
rodič
revize
82c53ee209

+ 10 - 4
packages/terminal/terminal-bash/src/config.ts

@@ -59,8 +59,10 @@ export const DEFAULT_PWSH_ARGS = ['-NoLogo', '-NoProfile']
 
 /**
  * Resolve the effective per-dialect shell specification. Defaulting is this
- * explicit step: an unset `shellPath`/`shellArgs` selects the dialect's
- * defaults, while an explicit value always wins.
+ * explicit step: an unset or empty `shellPath`/`shellArgs` selects the
+ * dialect's defaults, while a non-empty explicit value always wins.
+ * (Schemastery materializes an absent optional array as `[]`, so emptiness —
+ * not just `undefined` — means "dialect default".)
  * @param config - Schemastery-resolved plugin configuration.
  * @returns the fully resolved configuration.
  */
@@ -69,8 +71,12 @@ export function resolveConfig(config: Config): ResolvedConfig {
   return {
     ...(config as Required<Config>),
     shellDialect,
-    shellPath: config.shellPath ?? (shellDialect === 'pwsh' ? resolvePwshPath() : DEFAULT_BASH_SHELL),
-    shellArgs: config.shellArgs ?? (shellDialect === 'pwsh' ? DEFAULT_PWSH_ARGS : DEFAULT_BASH_ARGS),
+    shellPath: config.shellPath !== undefined && config.shellPath.length > 0
+      ? config.shellPath
+      : (shellDialect === 'pwsh' ? resolvePwshPath() : DEFAULT_BASH_SHELL),
+    shellArgs: config.shellArgs !== undefined && config.shellArgs.length > 0
+      ? config.shellArgs
+      : (shellDialect === 'pwsh' ? DEFAULT_PWSH_ARGS : DEFAULT_BASH_ARGS),
   }
 }
 

+ 11 - 0
packages/terminal/terminal-bash/tests/config.spec.ts

@@ -54,6 +54,17 @@ describe('terminal-bash dialect resolution', () => {
     expect(resolved.shellArgs).toEqual(['-NoProfile'])
   })
 
+  it('treats empty shell values as unset so Schemastery materialization cannot drop the dialect defaults', () => {
+    // Schemastery materializes an absent optional array as `[]`; the resolver
+    // must treat that shape like an unset value or a real bash spawn would
+    // start non-interactive without the controlled prompt.
+    const resolved = resolveConfig({
+      backendType: 'shell', shellDialect: 'bash', shellPath: '', shellArgs: [], rows: 24, cols: 80,
+    })
+    expect(resolved.shellPath).toBe('/bin/bash')
+    expect(resolved.shellArgs).toEqual(['--noprofile', '--norc', '-i'])
+  })
+
   it('validates the effective shell path, not only the raw one', () => {
     expect(() => { validateConfig(resolveConfig({ backendType: 'shell', shellDialect: 'bash', rows: 24, cols: 80 })) }).not.toThrow()
     expect(() => { validateConfig(resolveConfig({ backendType: 'shell', shellDialect: 'pwsh', rows: 24, cols: 80 })) }).not.toThrow()