chore: single-source CLI normalization helpers

Merged
UN
4mo ago
+248-202

Summary

  • Single-source create/update legacy none/null collection normalization in legacy-none-tokens.
  • Single-source runtime schema --unset field resolution in shared-unset-fields while preserving existing test-only aliases.
  • Export the canonical ConfigKey union from the positional config router and reuse it in config.ts.
  • Record implementation and verification evidence on pm-92if.

Verification

  • node scripts/run-tests.mjs coverage -> 256 files, 5137 tests, 100/100/100/100 coverage.
  • pm test pm-92if --run --progress -> 7/7 linked checks passed, including Sentry/telemetry best-effort.
  • pnpm lint
  • pnpm typecheck
  • pnpm quality:static -> duplicate_chunks=0, docstring coverage 100%.
  • pnpm contracts:check
  • pnpm security:scan
  • pnpm changelog:pm:check -> pm-changelog 2026.6.27, CHANGELOG.md unchanged.
  • pnpm audit --audit-level moderate
  • pm health --check-only --summary --json
  • pm validate --check-resolution --check-history-drift --json -> history drift ok; existing closed-item resolution metadata warning backlog remains.
  • node dist/cli.js package doctor --project --detail deep --json
  • Manual temp-dir smoke in isolated PM_PATH/PM_GLOBAL_PATH passed init/config/create/update/files/docs/test/comments/close/release/health/validate.

GitHub sweep

  • No open PRs before this branch.
  • No open Dependabot alerts.
  • No open code-scanning alerts.
  • pnpm audit --audit-level moderate clean.
  • Issue #374 remains externally blocked by missing release RELEASE_PAT configuration, not by code in this branch.

Summary by cubic

Centralized CLI helpers for legacy "none"/"null" collection handling and runtime --unset field resolution, shared by create and update. Exported canonical ConfigKey, normalized unset matching, and hardened guards to reduce duplicates while keeping behavior strict.

  • Refactors

    • Single-sourced legacy none/null normalizer; maps tokens to clear flags, disables conflicting replace flags, and blocks mixing with entries.
    • Single-sourced runtime --unset resolver; create/update reuse it and test-only aliases still work.
    • Exported ConfigKey from the positional router and reused it in config.
  • Bug Fixes

    • Scoped runtime --unset to command_to_fields.
    • Normalized unset tokens and candidate forms (case and dash/underscore) so camelCase dynamic fields still match lowercased input.
    • Rejected non-string collection entries and ignored malformed/missing runtime field metadata (key/metadata_key/cli_flag/cli_aliases) when matching unset tokens.