skillhub/docs/superpowers/specs/2026-07-28-cli-namespace-errors-design.md
dongmucat a94073004f docs(cli): define namespace error fix plan (#606)
Signed-off-by: dongmucat <1127093059@qq.com>
2026-07-28 16:58:31 +08:00

4.8 KiB

CLI Namespace Coordinates and Structured Errors Design

Context and approval

GitHub issue #606 reports two coupled CLI 0.1.9 failures: namespaced install coordinates can silently resolve against global, and JSON API responses with HTTP 403 are always rewritten as a token-scope error. The Multica issue's technical-analysis comment defines the desired normalization, conflict, error, documentation, and package-verification behavior. The project manager then assigned implementation against that design on fix/cli-namespace-errors, so that comment and assignment are the approved design baseline.

Considered approaches

  1. Centralize coordinate normalization and structured response errors in the existing shared parser and client. This is the selected approach because all commands receive one interpretation and tests can exercise the public contract without duplicating parsing or status handling.
  2. Patch install only. This would be smaller, but remove --remote already consumes the same parser and would retain inconsistent behavior.
  3. Change the server or documentation to accept only --namespace. This would preserve the CLI bug and contradict documented coordinate forms.

Coordinate contract

The CLI accepts these equivalent inputs:

Input Namespace Slug
my-skill global my-skill
team/my-skill team my-skill
@team/my-skill team my-skill
team--my-skill team my-skill
my-skill --namespace team team my-skill

The command parser must not inject global before coordinate normalization. global is applied only when the input is a bare slug and no explicit --namespace is supplied. If a coordinate and --namespace name the same namespace, the input is accepted. If they differ, the command fails with a usage error instead of silently choosing either value.

Structurally incomplete coordinates such as an empty string, @team, team/, /my-skill, --my-skill, and team-- fail with a usage error. The normalizer does not add new namespace or slug character restrictions; server validation remains authoritative for those rules.

Error contract

For unsuccessful JSON API responses, the client reads the body once and only uses the documented public fields msg and requestId when they are non-empty strings. A server msg becomes the CliError message. A requestId is stored in error details and rendered in both JSON and human-readable CLI output.

Exit classification remains stable:

  • 401 and 403 use the authentication exit code.
  • 404 and other application failures use the generic exit code.
  • 502 and 503 use the network exit code.

When msg is absent, invalid, or the body is not JSON, the CLI uses a status- specific fallback. In particular, the 403 fallback is access denied and does not speculate about token scope. Raw non-JSON bodies and unrecognized fields are not surfaced, avoiding disclosure of internal response content. Download responses use the same structured error extraction while retaining their download-specific fallbacks.

Components and data flow

  • cli/src/shared/skill-name-parser.ts parses and resolves coordinates, including explicit namespace conflict detection.
  • cli/src/commands/install.ts and cli/src/commands/remove.ts consume the resolved coordinate.
  • cli/src/index.ts leaves --namespace unset unless the caller supplies it.
  • cli/src/clients/skillhub-client.ts converts unsuccessful responses into structured CliError instances.
  • cli/src/shared/output.ts renders requestId for human users; JSON output already serializes error details.
  • cli/src/commands/help.ts, cli/README.md, and cli/CHANGELOG.md document supported forms, conflicts, and the 403 behavior change.

Testing and package verification

Unit tests cover the coordinate matrix, malformed inputs, matching/conflicting --namespace, structured and unstructured 401/403/404/500/502 responses, and human request-ID rendering. An integration install test executes the real CLI argument parser against a fake registry so the former default: 'global' override cannot regress.

The release check builds and packs the CLI, inspects the tarball file list, and runs the packed executable for version/help plus focused coordinate/error smoke tests. The published npm 0.1.9 package is retained only as a comparison artifact; no package publication or main-branch merge is part of this work.

Risks

  • Rejecting ambiguous coordinate/flag combinations is an intentional behavior tightening and is called out in release notes.
  • Server msg is treated as the public localized message defined by the API envelope. Raw body content is deliberately not exposed.
  • This change does not publish a new npm version; release owners must verify the future dist-tag after the approved PR is merged and released.