LearnNewsExamplesServices
Frontmatter
id11817
titleStandardize AI script CLI parsing on Commander
stateClosed
labels
enhancementdeveloper-experienceaitestingbuildmodel-experience
assigneesneo-gpt
createdAtMay 23, 2026, 4:02 AM
updatedAtMay 24, 2026, 10:50 AM
githubUrlhttps://github.com/neomjs/neo/issues/11817
authorneo-gpt
commentsCount3
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 24, 2026, 10:50 AM

Standardize AI script CLI parsing on Commander

Closed v13.0.0/archive-v13-0-0-chunk-13 enhancementdeveloper-experienceaitestingbuildmodel-experience
neo-gpt
neo-gpt commented on May 23, 2026, 4:02 AM

Context

During PR #11815 review, operator feedback surfaced a recurring friction pattern: new AI/operator scripts keep adding bespoke parseArgs() implementations even though commander is already present in package.json and used by multiple repo CLIs.

The immediate #11815 blocker is PR-local and should be fixed there. This ticket captures the broader substrate improvement so future scripts do not reintroduce the same hand-rolled parsing drift.

The Problem

Hand-rolled CLI parsers repeatedly miss failure semantics that an established parser gives for free: unknown-flag rejection, missing option-value handling, consistent help text, and predictable option defaults.

Fresh evidence from the #11815 review:

  • package.json lists commander as a direct devDependency.
  • Existing repo CLIs use Commander patterns such as new Command() / program.option().
  • ai/scripts/revalidationSweep.mjs introduced a manual parseArgs() switch where unknown flags are silently ignored; for example, a typo like --aply with a valid --family stays in dry-run mode instead of failing fast.
  • Synced issue-content sweep found prior parseArgs-heavy work and a recent Commander conversion (#11743), but no existing ticket that standardizes the pattern for AI scripts.

The Architectural Reality

The affected substrate is the right-hemisphere AI/build CLI layer, not the browser/runtime Body layer.

Observed parser surfaces include:

  • Commander-backed examples: buildScripts/ai/kbPushClient.mjs, buildScripts/ai/mcpHealthcheck.mjs, buildScripts/ai/defragChromaDB.mjs.
  • Bespoke parseArgs() examples: ai/scripts/lint-agents.mjs, ai/scripts/lint-skill-manifest.mjs, ai/scripts/migrateWakeSubscriptions.mjs, ai/scripts/normalizeGraphIdentities.mjs, ai/scripts/backfillChromaSharedUserId.mjs, buildScripts/ai/ingestTenant.mjs, buildScripts/ai/restore.mjs.

The goal is not to churn every legacy parser blindly. The goal is to establish a default for new and actively touched AI/operator scripts, with targeted conversion where friction is already observed.

The Fix

Define and implement a Commander-backed CLI parsing standard for AI/operator scripts:

  1. Convert the active friction point from PR #11815 to Commander as part of that PR's review response.
  2. Add a short documented convention in an appropriate low-load substrate, or extend existing script/testing documentation if a suitable owner already exists.
  3. Add targeted tests for at least one converted script proving:
    • valid defaults,
    • valid option values,
    • unknown flags reject,
    • missing option values reject,
    • help path remains deterministic.
  4. Optionally add a lightweight lint/check guard for newly touched ai/scripts/*.mjs parser surfaces if it can be done without noisy false positives.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
AI/operator CLI parser convention package.json Commander dependency + existing Commander-backed scripts New or actively touched AI/operator CLIs use Commander-backed parsing by default A bespoke parser is allowed only with explicit rationale and tests for unknown/missing option failure semantics Add/extend the lowest-load relevant docs surface; avoid always-loaded substrate unless necessary Unit tests for converted parser behavior + grep/audit showing no new unguarded parser added in the touched scope
PR review friction from #11815 PR #11815 review PRR_kwDODSospM8AAAABA0E6oQ revalidationSweep parsing moves from manual switch to Commander-backed semantics Keep current behavior only if Commander cannot support the required exported/testable parser shape, with rationale PR body explains the chosen shape Focused revalidationSweep tests include unknown/missing option rejection

Decision Record Impact

none. This aligns with existing dependency and script practice; it does not amend or supersede an ADR.

Acceptance Criteria

  • AC1 — Document the default rule for AI/operator scripts: use Commander-backed parsing for new or actively touched CLI surfaces unless a scoped exception is justified.
  • AC2 — Convert at least the #11815 revalidationSweep parser to Commander-backed parsing, or link the already-landed PR that did so.
  • AC3 — Parser tests cover valid defaults, valid supplied values, unknown flags, and missing option values for the converted surface.
  • AC4 — Audit existing AI/build parser surfaces and classify them as converted now, legacy tolerated, or future-touch conversion target; do not churn legacy scripts without evidence of friction.
  • AC5 — If a guard/lint is added, it must avoid false positives for legacy tolerated parsers and include tests.

Out of Scope

  • Rewriting every historical parseArgs() implementation in one pass.
  • Changing CLI business logic unrelated to parser semantics.
  • Introducing a new dependency; Commander already exists.
  • Adding always-loaded agent substrate unless the chosen documentation location requires it and the PR justifies the loaded-byte cost.

Avoided Traps / Gold Standards Rejected

  • Blind mass migration rejected: legacy parsers with stable behavior can remain until touched; this keeps the ticket ROI-positive.
  • Convention-only rejected: the pattern needs tests and either documentation or a guard, otherwise the next script can reintroduce the same parser drift.
  • Always-loaded rule rejected by default: this is script/tooling discipline, not a core per-turn invariant.

Related

Handoff Retrieval Hint: query_raw_memories("PR #11815 Commander parseArgs friction") or query_raw_memories("hand-rolled parseArgs commander package.json").

tobiu referenced in commit 106395a - "docs(agentos): add CLI parser ADR (#11817) (#11839) on May 24, 2026, 10:50 AM
tobiu closed this issue on May 24, 2026, 10:50 AM