LearnNewsExamplesServices
Frontmatter
id11775
titleExtract reusable Windows batch spawn helper
stateClosed
labels
enhancementwindowsairefactoringbuild
assigneesneo-gpt
createdAtMay 22, 2026, 7:57 PM
updatedAtMay 22, 2026, 8:42 PM
githubUrlhttps://github.com/neomjs/neo/issues/11775
authorneo-gpt
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 22, 2026, 8:42 PM

Extract reusable Windows batch spawn helper

Closed v13.0.0/archive-v13-0-0-chunk-13 enhancementwindowsairefactoringbuild
neo-gpt
neo-gpt commented on May 22, 2026, 7:57 PM

Context

PR #11769 repaired #11767 / #10684 by removing the direct cross-spawn dependency and owning the Windows .cmd dispatch path inside ai/scripts/resumeHarness.mjs. The operator explicitly called out that this should not grow #11769: the active PR should remain the Antigravity dependency-removal fix, while reusable helper work belongs in a separate ticket.

Pre-creation duplicate sweep:

  • Knowledge Base ticket search for Windows batch spawn helper cross-spawn cmd.exe quoting reusable subprocess helper ticket found related historical Windows/subprocess issues (#7795, #10795), but no equivalent ticket for a reusable batch-spawn helper.
  • Exact repo sweep over resources/content/issues and resources/content/discussions for cross-spawn, cmd.exe, spawn helper, windows batch, batch spawn, and .cmd found related mentions but no equivalent ticket.

The Problem

The repo-owned Windows batch quoting logic now exists in one script because #11769 needed a contained fix. That is correct for the PR scope, but it leaves follow-up risk:

  • ai/scripts/resumeHarness.mjs owns isWindowsBatchCommand(), quoteWindowsBatchArgument(), buildWindowsBatchCommandLine(), and createSpawnRequest() locally.
  • Other agent/build subprocess surfaces still have their own platform handling or raw child-process calls.
  • Future Windows .cmd fixes could reintroduce ad hoc quoting, shell: true, or another direct dependency if there is no reusable local primitive.

The Architectural Reality

Current evidence from the code sweep:

  • ai/scripts/resumeHarness.mjs now contains the repo-owned helper functions used by #11769.
  • test/playwright/unit/ai/scripts/resumeHarness.spec.mjs contains adversarial coverage for the current helper behavior.
  • buildScripts/build/all.mjs selects npm.cmd on Windows and uses spawnSync(..., {shell: true}) across several build steps.
  • buildScripts/webpack/buildThreads.mjs uses spawnSync(..., {shell: true}) for webpack command dispatch.
  • buildScripts/webpack/development/webpack.config.appworker.mjs and buildScripts/webpack/production/webpack.config.appworker.mjs pass a composed copyFolder.mjs -s ... -t ... string through a shell path.
  • ai/scripts/heartbeatLock.mjs, ai/scripts/bridge-daemon.mjs, ai/daemons/SwarmHeartbeatService.mjs, and ai/services/neural-link/ConnectionService.mjs have generic subprocess call sites that may need consistent Windows batch-wrapper behavior later.
  • ai/daemons/services/PrimaryRepoSyncService.mjs already has explicit npm.cmd handling through injected execFileSyncFn test seams.

This is not a request to rewrite every subprocess caller in one PR. The immediate substrate is the helper primitive and its first consumer migration.

The Fix

Create a small repo-owned Windows batch spawn helper and migrate the current resumeHarness implementation to consume it.

Expected shape:

  • Extract the Windows batch detection, quoting, command-line construction, and spawn-request construction from ai/scripts/resumeHarness.mjs into a shared .mjs helper selected through structural pre-flight at implementation time.
  • Preserve the existing direct-spawn path for POSIX hosts and native Windows executables.
  • Keep .cmd / .bat dispatch scoped to cmd.exe /d /s /v:off /c with repo-owned quoting.
  • Move or duplicate the existing adversarial unit coverage to the helper boundary.
  • Migrate resumeHarness as the first consumer.
  • Optionally migrate one additional low-risk agent subprocess consumer if the helper API proves clean and the diff remains small.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
Repo-owned Windows batch spawn helper ai/scripts/resumeHarness.mjs behavior introduced by PR #11769 Build spawn requests that execute .cmd / .bat through cmd.exe /d /s /v:off /c with escaped payload data POSIX and native executables keep direct spawn(cmd, args) behavior JSDoc @summary on exported helper functions Unit coverage with adversarial metacharacter and newline payloads
resumeHarness subprocess dispatch #11767 / PR #11769 Consume the shared helper without changing harness behavior Existing #11769 logic remains the behavior baseline Existing resumeHarness JSDoc references updated if needed Existing resumeHarness.spec.mjs assertions still pass
Future subprocess callers Codebase sweep listed above Provide a small local primitive so future migrations do not add cross-spawn or ad hoc shell quoting Callers can remain unchanged until separately migrated Ticket/PR notes identify candidates without forcing broad churn Follow-up PR shows at least one migrated consumer or a clear non-migration rationale

Acceptance Criteria

  • Shared helper exists in a structurally justified location, with JSDoc @summary and clear exported API.
  • resumeHarness imports and uses the shared helper instead of owning the helper functions locally.
  • Unit coverage verifies Windows .cmd dispatch through cmd.exe /d /s /v:off /c and adversarial argument escaping.
  • Unit coverage verifies POSIX/native executable paths remain direct-spawn requests.
  • PR body lists audited subprocess candidates and explicitly states which were migrated versus deferred.
  • No direct cross-spawn dependency is added.

Out of Scope

  • Broad conversion of all shell: true build-script call sites.
  • Rewriting build orchestration or webpack command topology.
  • Changing PR #11769 behavior or widening its scope.
  • Solving unrelated Windows shell compatibility issues without a concrete caller and test.
  • Adding a third-party subprocess abstraction dependency.

Avoided Traps

  • Do not treat cross-spawn as the standard answer here. The operator rejected the dependency path for #11769 because this behavior is small enough to own locally.
  • Do not turn this into a sweeping build-system cleanup. The value is a reusable primitive plus one proven consumer, not a giant shell migration.
  • Do not rely on negated close-keyword phrasing in PR bodies when referencing related tickets; GitHub can still parse close targets incorrectly.

Related

Origin Session ID: 2741c4bd-92b2-428b-92d3-ab718d9a7c41

Retrieval Hint: Windows batch spawn helper cross-spawn cmd.exe quoting resumeHarness PR #11769 Retrieval Hint: quoteWindowsBatchArgument buildWindowsBatchCommandLine createSpawnRequest

tobiu referenced in commit ebf5b87 - "refactor(ai): extract Windows batch spawn helper (#11775) (#11776) on May 22, 2026, 8:42 PM
tobiu closed this issue on May 22, 2026, 8:42 PM