Skip to content

[Tech Debt] E8 · CLI & shared-library packaging robustness #65

Description

@hojinzs

Part of the 2026-06 code-hygiene / technical-debt audit. Full backlog with evidence: docs/TECH_DEBT_BACKLOG-2026-06-25.md (epic E8).

Why

The published eb CLI has no build-before-publish guarantee, brittle string-matched error handling, scattered exit codes, and duplicated types — to be deduped by vendoring, not by depending on the private shared package.

Related issues / notes

Note: see #55/#56 for the CLI vendoring decision and smoke-test follow-up.

Checklist

  • P2·med · M — Natural fix (CLI depending on shared) is blocked: @evidence-browser/shared is private and changeset-ignored ⚠️ Reframed per Add packed-install smoke coverage for CLI bundle commands #55: remaining debt = guarantee/test the vendoring, not add a shared dependency.
    • Fix: Decide the boundary explicitly: either (a) make shared publishable (drop private, remove from changeset ignore, add version + publishConfig) so the CLI can depend on it, or (b) bundle shared into the CLI at build time (tsup/rollup noExte…
    • Evidence: packages/shared/package.json:4, .changeset/config.json:13, .github/workflows/release.yml:39-43
  • P2·med · M — validateApiKey detects auth failures by regex-matching the error message string
    • Fix: Throw a typed error from api-client.request() carrying the numeric status (e.g. class ApiError extends Error { constructor(public status: number, message: string) }), and have validateApiKey/whoami branch on err.status === 401. Update CL…
    • Evidence: packages/cli/src/commands/auth.ts:104-108, packages/cli/src/lib/api-client.ts:143-146, packages/cli/src/commands/auth.ts:192
  • P2·med · S — CLI publishes with no build guarantee — npm publish can ship a stale or empty dist ↔ Add packed-install smoke coverage for CLI bundle commands #55 covers the smoke test; residual = add a prepublishOnly build guard.
    • Fix: Add a prepublishOnly (or prepare) script to packages/cli/package.json that runs npm run build, so dist is always rebuilt as part of npm publish and the artifact is self-contained regardless of caller.
    • Evidence: packages/cli/package.json:11-18, packages/cli/package.json:19-26, .github/workflows/release.yml:42-49
  • P3·low · M — Inconsistent exit-code / error handling: process.exit scattered through async actions, no shared convention
    • Fix: Standardize on one wrapper (e.g. runAction in lib/output.ts) that runs the action, prints errors to stderr, and sets a single non-zero exit code; have every command use it. Move whoami's status-based exits into the same path. Add a CLI t…
    • Evidence: packages/cli/src/commands/auth.ts:201,203, packages/cli/src/commands/upload.ts:22-29,42-45, packages/cli/src/commands/bundle.ts:37-40
  • P3·low · S — updateWorkspace makes a redundant GET to resolve slug->id before every PATCH
    • Fix: If the API can PATCH by slug, do so and drop the lookup. If it requires an id, expose a slug-PATCH endpoint, or at minimum reuse the already-fetched workspace object. Add a test covering the two-call path so a future single-call API does…
    • Evidence: packages/cli/src/lib/api-client.ts:251-274
  • P3·low · S — Mixed-language (Korean) error messages baked into shared validation/manifest errors ↔ already covered by Internationalize user-facing strings — make English the default and consistent #47 (i18n).
    • Fix: Centralize these messages (constants or a small message map) so the duplicated literal exists once, and pick one language for thrown errors in shared (English is the lingua franca for the published CLI/API); if localized user-facing copy…
    • Evidence: packages/shared/src/bundle/types.ts:48,55,62, packages/shared/src/bundle/validate-zip.ts:40,46, packages/shared/src/bundle/manifest.ts:35,44
  • P3·low · S — shared barrel re-exports every module while package.json exposes granular subpaths — two import styles, barrel unused
    • Fix: Pick one convention. Recommended: keep the granular subpath exports (tree-shakeable, already how everyone imports) and either drop the root barrel or add a CI check that every module in the exports map stays in sync with the barrel. Docu…
    • Evidence: packages/shared/src/index.ts:1-6, packages/shared/package.json:7-36, packages/api/src/lib/bundle/security.ts:1

Scope

7 item(s) — 🔴 0 · 🟡 3 · ⚪ 4. These are tracked as checklist items within this single epic issue (not separate issues).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttech-debtCode hygiene / technical debt (2026-06 audit)

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions