Phase 1 — CLI skeleton + typed client + auth login + get. The first immediately-useful slice.
Part of #1 .
Scope
Bootstrap the TS project: Node + TypeScript, CLI framework (oclif or commander), tsconfig, ESLint/Prettier, Vitest, CI (GitHub Actions).
Layer 0 — Auth/HTTP: login-token handling, session cookie + CSRF, auto re-login, rate-limit/retry. Store token in macOS Keychain (fallback .env).
ct auth login — capture personal token, verify, persist to Keychain.
Layer 1 — Typed client: generate from OpenAPI (openapi-typescript + openapi-fetch); script to regenerate on CT release.
Layer 2 — imperative get commands: ct get groups | campuses | group-types | … with basic filtering + JSON/table output.
README with install + usage.
Definition of done
ct auth login then ct get campuses returns live data from our CT instance.
Typed client compiles against the real spec; regeneration documented.
CI green (lint + typecheck + tests).
Distribution (stub, not blocking)
Homebrew tap eqrm/tap/ct or npm bin — wire up later; Phase 1 just needs a local ct binary.
Phase 1 — CLI skeleton + typed client +
auth login+get. The first immediately-useful slice.Part of #1.
Scope
ocliforcommander),tsconfig, ESLint/Prettier, Vitest, CI (GitHub Actions)..env).ct auth login— capture personal token, verify, persist to Keychain.openapi-typescript+openapi-fetch); script to regenerate on CT release.getcommands:ct get groups | campuses | group-types | …with basic filtering + JSON/table output.Definition of done
ct auth loginthenct get campusesreturns live data from our CT instance.Distribution (stub, not blocking)
eqrm/tap/ctor npm bin — wire up later; Phase 1 just needs a localctbinary.