mixdog 0.9.31 → 0.9.32

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "0.9.31",
3
+ "version": "0.9.32",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone mixdog coding-agent CLI/TUI workspace.",
@@ -28,6 +28,15 @@ test('grep head_limit/offset/-C as numeric strings coerce', () => {
28
28
  assert.equal(a['-C'], 2);
29
29
  });
30
30
 
31
+ test('grep empty context strings are treated as omitted', () => {
32
+ const a = { pattern: 'x', output_mode: 'content_with_context', '-A': '', '-B': '', '-C': '', context: '' };
33
+ assert.equal(validateBuiltinArgs('grep', a), null);
34
+ assert.equal(Object.prototype.hasOwnProperty.call(a, '-A'), false);
35
+ assert.equal(Object.prototype.hasOwnProperty.call(a, '-B'), false);
36
+ assert.equal(Object.prototype.hasOwnProperty.call(a, '-C'), false);
37
+ assert.equal(Object.prototype.hasOwnProperty.call(a, 'context'), false);
38
+ });
39
+
31
40
  test('list/find/glob head_limit as numeric string coerces', () => {
32
41
  const l = { path: '.', head_limit: '5' };
33
42
  assert.equal(validateBuiltinArgs('list', l), null);
@@ -399,6 +399,10 @@ function guardGrep(a) {
399
399
  if (err) return err;
400
400
  }
401
401
  for (const k of ['-A', '-B', '-C', 'context']) {
402
+ if (hasOwn(a, k) && a[k] === '') {
403
+ delete a[k];
404
+ continue;
405
+ }
402
406
  const err = checkIntInRange(a, k, 0, GREP_CONTEXT_MAX, { clamp: true });
403
407
  if (err) return err;
404
408
  }
@@ -290,12 +290,15 @@ export async function startPg({ runtimeDir, pgdataDir, port: preferredPort = 554
290
290
  // so we return the instant pg_isready succeeds rather than waiting on pg_ctl.
291
291
  // Only the long-lived child handle is unref'd; poll timers stay ref'd.
292
292
  async function startAndWaitReady() {
293
- // detached on win32: give pg_ctl (and the postmaster it spawns) its own
294
- // process group / console so an ancestor `taskkill /F /T` cannot enumerate
295
- // it via the Node process tree. The orphaned postmaster survives and is
296
- // re-adopted next boot via supervisor tryReusePgInstance (postmaster.pid).
297
- const detached = process.platform === 'win32'
298
- const child = spawn(pgctl, startArgs, { env, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true, detached })
293
+ // NEVER set `detached` on win32: DETACHED_PROCESS makes the OS ignore
294
+ // `windowsHide`, so pg_ctl + the postmaster it launches allocate a VISIBLE
295
+ // console (see shared/spawn-flags.mjs). Detachment gave no real isolation
296
+ // here anyway: `pg_ctl start` daemonizes the postmaster and exits at once,
297
+ // so the postmaster is already reparented OUT of the Node process tree
298
+ // detached only isolated the short-lived pg_ctl. Shutdown/reuse target
299
+ // pgdata/postmaster.pid (pg_ctl stop -D, tryReusePgInstance), not a
300
+ // Node-tree taskkill, so `windowsHide` alone is correct on all platforms.
301
+ const child = spawn(pgctl, startArgs, { env, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true })
299
302
  child.unref?.()
300
303
  let stdout = '', stderr = '', closed = false, exitCode = null
301
304
  child.stdout?.on('data', d => { stdout += d.toString() })