|
| 1 | +# Codacy Cloud CLI |
| 2 | + |
| 3 | +A command-line Node.js + TypeScript tool to interact with the Codacy API. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This CLI wraps the [Codacy Cloud API v3](https://api.codacy.com/api/api-docs) using an auto-generated TypeScript client. The goal is to provide a clean, well-structured CLI that lets users interact with Codacy directly from the terminal. |
| 8 | + |
| 9 | +**Current state:** The project has a working boilerplate with Commander.js, an auto-generated API client, and a few prototype commands (`user`, `orgs`, `repos`) that will be removed and rebuilt. The foundation (entry point, API generation pipeline, utilities) is stable and should be preserved. |
| 10 | + |
| 11 | +## Quick Reference |
| 12 | + |
| 13 | +| Action | Command | |
| 14 | +|---|---| |
| 15 | +| Run in dev mode | `npx ts-node src/index.ts <command>` | |
| 16 | +| Build | `npm run build` | |
| 17 | +| Run built version | `node dist/index.js <command>` | |
| 18 | +| Fetch latest API spec | `npm run fetch-api` | |
| 19 | +| Regenerate API client | `npm run generate-api` | |
| 20 | +| Full API update | `npm run update-api` | |
| 21 | +| Run tests | `npm test` | |
| 22 | + |
| 23 | +## Architecture & Project Structure |
| 24 | + |
| 25 | +``` |
| 26 | +codacy-cloud-cli/ |
| 27 | +├── src/ |
| 28 | +│ ├── index.ts # CLI entry point (Commander.js setup) |
| 29 | +│ ├── api/ |
| 30 | +│ │ └── client/ # AUTO-GENERATED - do NOT edit manually |
| 31 | +│ │ ├── core/ # Request handling, auth, errors |
| 32 | +│ │ ├── models/ # 520+ TypeScript interfaces from OpenAPI |
| 33 | +│ │ └── services/ # 28 service classes wrapping API endpoints |
| 34 | +│ ├── commands/ # One file per command (see Command Pattern below) |
| 35 | +│ │ └── CLAUDE.md # Design decisions for commands |
| 36 | +│ └── utils/ # Shared utilities (auth, error handling, output formatting, formatting helpers) |
| 37 | +├── api-v3/ |
| 38 | +│ └── api-swagger.yaml # OpenAPI 3.0.1 spec (source of truth for client generation) |
| 39 | +├── dist/ # Compiled JS output (gitignored) |
| 40 | +├── SPECS/ # Specs and backlog - agents MUST read SPECS/README.md |
| 41 | +│ ├── README.md # Agent landing page: pending tasks, command table, changelog |
| 42 | +│ ├── commands/ # One spec file per command |
| 43 | +│ ├── setup.md # Test framework, build, utilities |
| 44 | +│ └── deployment.md # npm publishing, CI pipelines |
| 45 | +├── TODO.md # Redirects to SPECS/README.md |
| 46 | +├── CLAUDE.md # This file |
| 47 | +├── package.json |
| 48 | +└── tsconfig.json |
| 49 | +``` |
| 50 | + |
| 51 | +## Critical Rules |
| 52 | + |
| 53 | +### For All Agents |
| 54 | + |
| 55 | +1. **Read `SPECS/README.md` before starting work.** It shows pending tasks, the command inventory, and the changelog. When completing a task, update the pending table and add a changelog entry. |
| 56 | +2. **Never edit files under `src/api/client/`.** This directory is auto-generated. If the API client needs updating, run `npm run update-api`. |
| 57 | +3. **Ask before assuming.** If a task in SPECS or a user instruction is ambiguous, ask clarifying questions before writing code. Do not guess intent. |
| 58 | +4. **Document what you build.** Every command, utility, or significant piece of logic must include: |
| 59 | + - Inline comments where the logic isn't self-evident |
| 60 | + - A `CLAUDE.md` in the relevant folder explaining design and implementation decisions when the folder contains multiple related files |
| 61 | +5. **Write tests for everything.** Every command must have corresponding tests. See Testing section below. |
| 62 | +6. **One command per file.** Each CLI command lives in its own file inside `src/commands/`. The file exports a `register<Name>Command(program: Command)` function. |
| 63 | +7. **Keep the entry point thin.** `src/index.ts` only handles Commander setup and command registration. No business logic belongs there. |
| 64 | +8. **Keep `README.md` up to date, but concise.** The README contains only a short summary table of available commands and their one-line descriptions. Do **not** document per-command arguments, options, or examples in the README — users run `codacy <command> --help` for that. After adding or renaming a command, add or update its row in the summary table only. |
| 65 | + |
| 66 | +### Code Style & Conventions |
| 67 | + |
| 68 | +- **Language:** TypeScript (strict mode) |
| 69 | +- **Module system:** CommonJS (`"module": "commonjs"` in tsconfig) |
| 70 | +- **CLI framework:** Commander.js v14 |
| 71 | +- **Terminal output libraries:** |
| 72 | + - `ansis` for colors/styling |
| 73 | + - `cli-table3` for tabular output — always use `createTable()` from `utils/output.ts` (applies borderless styling and bold white headers) |
| 74 | + - `ora` for loading spinners |
| 75 | + - `dayjs` for date formatting — for "last updated" style dates, use `formatFriendlyDate()` from `utils/output.ts` (relative for today, "Yesterday", otherwise YYYY-MM-DD) |
| 76 | +- **Output:** Default output is human readable with tables and colors, but can be overridden with the `--output json` flag. |
| 77 | +- **Pagination:** All commands calling paginated APIs must call `printPaginationWarning(response.pagination, hint)` from `utils/output.ts` after displaying results. The hint should suggest command-specific filtering options. |
| 78 | +- **Error handling:** Use `try/catch` with the shared `handleError()` from `src/utils/error.ts` |
| 79 | +- **Authentication:** All commands that call the API must call `checkApiToken()` from `src/utils/auth.ts` before making requests |
| 80 | +- **API base URL:** `https://app.codacy.com/api/v3` (configured in `src/index.ts` via `OpenAPI.BASE`) |
| 81 | +- **Auth mechanism:** `CODACY_API_TOKEN` environment variable, sent as `api-token` header |
| 82 | + |
| 83 | +### Command Pattern |
| 84 | + |
| 85 | +Every command file follows this structure: |
| 86 | + |
| 87 | +```typescript |
| 88 | +// src/commands/<command-name>.ts |
| 89 | +import { Command } from "commander"; |
| 90 | +import ora from "ora"; |
| 91 | +import { checkApiToken } from "../utils/auth"; |
| 92 | +import { handleError } from "../utils/error"; |
| 93 | +// Import relevant API service(s) |
| 94 | + |
| 95 | +export function register<Name>Command(program: Command) { |
| 96 | + program |
| 97 | + .command("<command-name>") |
| 98 | + .description("Clear description of what this command does") |
| 99 | + .argument("[args]", "Description of arguments") |
| 100 | + .option("--flag <value>", "Description of options") |
| 101 | + .action(async (args, options) => { |
| 102 | + try { |
| 103 | + checkApiToken(); |
| 104 | + const spinner = ora("Loading...").start(); |
| 105 | + // Call API service |
| 106 | + // Format and display output |
| 107 | + spinner.succeed("Done."); |
| 108 | + } catch (err) { |
| 109 | + handleError(err); |
| 110 | + } |
| 111 | + }); |
| 112 | +} |
| 113 | +``` |
| 114 | + |
| 115 | +Then register it in `src/index.ts`: |
| 116 | +```typescript |
| 117 | +import { register<Name>Command } from "./commands/<command-name>"; |
| 118 | +registerNameCommand(program); |
| 119 | +``` |
| 120 | + |
| 121 | +## API Client Generation |
| 122 | + |
| 123 | +The API client is auto-generated from the Codacy OpenAPI spec. **Never edit generated files.** |
| 124 | + |
| 125 | +- **Spec location:** `api-v3/api-swagger.yaml` |
| 126 | +- **Generator:** `@codacy/openapi-typescript-codegen@0.0.8` |
| 127 | +- **Output:** `src/api/client/` (models, services, core) |
| 128 | +- **Client type:** fetch-based |
| 129 | + |
| 130 | +To update the API client: |
| 131 | +```bash |
| 132 | +npm run update-api # Fetches latest spec + regenerates client |
| 133 | +npm run fetch-api # Only fetch the spec |
| 134 | +npm run generate-api # Only regenerate from existing spec |
| 135 | +``` |
| 136 | + |
| 137 | +When referencing API operations, look at the generated services in `src/api/client/services/` to find available methods and their signatures. The models in `src/api/client/models/` define the request/response types. |
| 138 | + |
| 139 | +## Testing |
| 140 | + |
| 141 | +### Setup |
| 142 | + |
| 143 | +Tests must be configured with a proper test framework (Vitest or Jest - check `package.json` for which is installed). Each command must have corresponding test files. |
| 144 | + |
| 145 | +### Test Strategy |
| 146 | + |
| 147 | +- **Unit tests** for utility functions and output formatting logic |
| 148 | +- **Integration tests** for commands that call the Codacy API |
| 149 | + - These tests will use a dedicated test organization and repository in Codacy with known, predictable data |
| 150 | + - The test org/repo details will be configured via environment variables or test fixtures |
| 151 | +- **Test file naming:** `<module>.test.ts` co-located next to the source file, or in a `__tests__/` directory within the same folder |
| 152 | +- **Mocking:** Mock API service calls for unit tests; use real API calls (with test credentials) for integration tests |
| 153 | + |
| 154 | +### Running Tests |
| 155 | + |
| 156 | +```bash |
| 157 | +npm test |
| 158 | +``` |
| 159 | + |
| 160 | +## Specs & Backlog |
| 161 | + |
| 162 | +The `SPECS/` folder at the project root is the single source of truth for specs and the project backlog. |
| 163 | + |
| 164 | +- **`SPECS/README.md`** — agent landing page: pending tasks table, command inventory, changelog |
| 165 | +- **`SPECS/commands/<command>.md`** — full spec for each command (API endpoints, output format, options, test counts) |
| 166 | +- **`SPECS/setup.md`** — test framework, utilities reference |
| 167 | +- **`SPECS/deployment.md`** — CI pipelines, npm publishing |
| 168 | + |
| 169 | +**Agents must:** |
| 170 | +1. Read `SPECS/README.md` at the start of every session |
| 171 | +2. Pick up the next pending task from the pending table (or the one specified by the user) |
| 172 | +3. Read the relevant `SPECS/commands/<command>.md` before implementing a command |
| 173 | +4. Update `SPECS/README.md` (mark tasks done, add changelog entry) when completing work |
| 174 | +5. Add new tasks to `SPECS/README.md` pending table when discovered during work |
| 175 | + |
| 176 | +## Environment Variables |
| 177 | + |
| 178 | +| Variable | Required | Description | |
| 179 | +|---|---|---| |
| 180 | +| `CODACY_API_TOKEN` | Yes | API token for authenticating with Codacy. Get it from Codacy > Account > API Tokens | |
| 181 | + |
| 182 | +## Useful Context |
| 183 | + |
| 184 | +- Codacy API docs: https://api.codacy.com/api/api-docs |
| 185 | +- The CLI targets Codacy Cloud (app.codacy.com), not self-hosted instances |
| 186 | +- Provider shortcodes used in commands: `gh` (GitHub), `gl` (GitLab), `bb` (Bitbucket) |
0 commit comments