refactor(settings): derive permission vocabulary from one declaration
Purpose and evidence
Adding all in PR #2363 (e656ff158a5c7641564106c73ea4e9b787244b9f) updates two PermissionTarget unions, a target array, parser comparisons, usage text and CLI membership. These independently maintained declarations make one vocabulary change span unrelated projections.
Evidence: contract declarations, public client type, CLI validation.
Required behavior
- In the existing settings contract, declare readonly collections for the current permission vocabularies and derive their union types. Preserve the current mobile/macOS subsets: a shared declaration must not widen what any surface accepts.
- Derive parser membership, public client permission types, CLI membership and permission-name usage fragments from those collections. Public client derivation must use type-only imports: do not introduce runtime loading of
settings.ts and its AppError dependency through the client type surface. Preserve existing exports, normalization, accepted values, errors and ordering of help text.
- Keep platform-native permission mappings and device support checks in their existing owners. A name existing in the vocabulary does not imply platform support.
Illustrative declaration shape (names are not prescribed): type MobilePermissionTarget = (typeof MOBILE_PERMISSION_TARGETS)[number]; public client types may compose the existing mobile and macOS subsets.
Scope and exclusions
Own packages/contracts/src/settings.ts, client-settings.ts, src/commands/capture/settings.ts, and their direct tests/consumers. No new package, registry, schema framework, compatibility re-export, platform behavior change or Maestro support-policy redesign. #2544 already tracks moving the Maestro adapter; that move is unrelated.
Completion and validation
- Characterize the existing accepted/rejected names per surface, case/whitespace normalization and error/help strings before refactoring. Use fixed expected data, not expectations derived from the new collection.
- Both exported types retain their current assignability, including the macOS-only names where currently accepted.
- Replay a temporary vocabulary addition with no backend implementation: type/parser/CLI membership/help projections update from the owning collection without edits to parallel lists. Remove the temporary value before publication and record the before/after independently edited declarations.
- Existing settings/CLI tests and
pnpm check:affected --run pass. Follow docs/agents/testing.md; no device behavior changes are intended.
- Delete superseded declarations; report the actual reduction. Stop and report if sharing forces acceptance widening or an import cycle.
Dependencies and readiness
Blocked by: #2363 landing. Re-audit its merged result before implementation; do not implement against pre-#2363 main or modify that PR independently. This is a follow-up, not a merge blocker. No matching implementation issue was found in the current tracker; #2410 concerns command-option declarations, not this repeated settings vocabulary.
Effort: S–M. Risk: low–medium (public type subsets and validation semantics).
refactor(settings): derive permission vocabulary from one declaration
Purpose and evidence
Adding
allin PR #2363 (e656ff158a5c7641564106c73ea4e9b787244b9f) updates twoPermissionTargetunions, a target array, parser comparisons, usage text and CLI membership. These independently maintained declarations make one vocabulary change span unrelated projections.Evidence: contract declarations, public client type, CLI validation.
Required behavior
settings.tsand itsAppErrordependency through the client type surface. Preserve existing exports, normalization, accepted values, errors and ordering of help text.Illustrative declaration shape (names are not prescribed):
type MobilePermissionTarget = (typeof MOBILE_PERMISSION_TARGETS)[number]; public client types may compose the existing mobile and macOS subsets.Scope and exclusions
Own
packages/contracts/src/settings.ts,client-settings.ts,src/commands/capture/settings.ts, and their direct tests/consumers. No new package, registry, schema framework, compatibility re-export, platform behavior change or Maestro support-policy redesign. #2544 already tracks moving the Maestro adapter; that move is unrelated.Completion and validation
pnpm check:affected --runpass. Followdocs/agents/testing.md; no device behavior changes are intended.Dependencies and readiness
Blocked by: #2363 landing. Re-audit its merged result before implementation; do not implement against pre-#2363 main or modify that PR independently. This is a follow-up, not a merge blocker. No matching implementation issue was found in the current tracker; #2410 concerns command-option declarations, not this repeated settings vocabulary.
Effort: S–M. Risk: low–medium (public type subsets and validation semantics).