From 0349ca4be46e644cc3e8f3dde8cec75eb7a6b1f2 Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Thu, 19 Mar 2026 00:22:40 +0100 Subject: [PATCH 1/3] fix: resolve documentation inconsistencies and minor code issues - Remove phantom `archgate mcp` command from README - Fix plugin path in CLAUDE.md to `../plugins/claude-code` - Add ARCH-008, ARCH-009 to CLAUDE.md ADR list - Replace `bun run build` with `bun run build:check` in CLAUDE.md - Update .prototools versions in CLAUDE.md (Bun 1.3.9, npm 11.11.0) - Add all undocumented commands/subcommands to CLAUDE.md table - Fix command description mismatches to match source code - Add review-context and session-context to CLI docs (en + pt-br) - Replace direct console.log with logInfo in git.ts and login-flow.ts - Update signup error message to direct users to `archgate login` - Add 3s timeout to WSL spawn in resolveCommand to prevent hangs - Add missing tests for adr/index.ts and plugin/index.ts --- CLAUDE.md | 42 +++++++---- README.md | 3 +- .../docs/pt-br/reference/cli-commands.mdx | 75 +++++++++++++++++++ .../content/docs/reference/cli-commands.mdx | 75 +++++++++++++++++++ src/helpers/git.ts | 4 +- src/helpers/login-flow.ts | 12 ++- src/helpers/platform.ts | 13 +++- tests/commands/adr/index.test.ts | 49 ++++++++++++ tests/commands/plugin/index.test.ts | 35 +++++++++ 9 files changed, 278 insertions(+), 30 deletions(-) create mode 100644 tests/commands/adr/index.test.ts create mode 100644 tests/commands/plugin/index.test.ts diff --git a/CLAUDE.md b/CLAUDE.md index 923b77cf..0dc28645 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ # CLAUDE.md -Archgate is a CLI tool for AI governance via Architecture Decision Records (ADRs) — combining human-readable docs with machine-checkable rules. The CLI dogfoods itself via ADRs in `.archgate/adrs/`. AI features are delivered as a Claude Code plugin (`archgate/claude-code-plugin`), not via direct API calls. +Archgate is a CLI tool for AI governance via Architecture Decision Records (ADRs) — combining human-readable docs with machine-checkable rules. The CLI dogfoods itself via ADRs in `.archgate/adrs/`. AI features are delivered as a Claude Code plugin (`../plugins/claude-code`), not via direct API calls. ## Technology Stack @@ -19,7 +19,7 @@ bun run format # oxfmt --write bun run format:check # oxfmt --check bun test # all tests bun run validate # MANDATORY: lint + typecheck + format + test + ADR check + build check -bun run build # binaries → dist/ (darwin-arm64, linux-x64, win32-x64) +bun run build:check # verify build compiles (CI builds binaries via release workflow) bun run commit # conventional commit wizard ``` @@ -33,19 +33,27 @@ bun run commit # conventional commit wizard Entry point: `src/cli.ts` (shebang `#!/usr/bin/env bun`). Commands registered via `register*Command(program)`. -| Command | File | Description | -| ----------------- | ----------------------------------- | -------------------------------------------- | -| `init` | `commands/init.ts` | Initialize `.archgate/` skeleton | -| `check` | `commands/check.ts` | Run ADR compliance checks | -| `adr create` | `commands/adr/create.ts` | Create ADR interactively | -| `adr list` | `commands/adr/list.ts` | List ADRs (`--json`, `--domain`) | -| `adr show ` | `commands/adr/show.ts` | Show ADR by ID | -| `adr update` | `commands/adr/update.ts` | Update ADR by ID | -| `login` | `commands/login.ts` | GitHub auth for editor plugins | -| `review-context` | `commands/review-context.ts` | Pre-compute review context for changed files | -| `session-context` | `commands/session-context/index.ts` | Read AI editor session transcripts | -| `upgrade` | `commands/upgrade.ts` | Upgrade CLI via npm | -| `clean` | `commands/clean.ts` | Remove `~/.archgate/` cache | +| Command | File | Description | +| ----------------------------- | ----------------------------------------- | --------------------------------------------------------------- | +| `init` | `commands/init.ts` | Initialize Archgate governance in the current project | +| `check` | `commands/check.ts` | Run ADR compliance checks | +| `adr create` | `commands/adr/create.ts` | Create a new ADR | +| `adr list` | `commands/adr/list.ts` | List all ADRs (`--json`, `--domain`) | +| `adr show ` | `commands/adr/show.ts` | Show a specific ADR by ID | +| `adr update` | `commands/adr/update.ts` | Update an existing ADR by ID | +| `login` | `commands/login.ts` | Authenticate with GitHub to access archgate plugins | +| `login status` | `commands/login.ts` | Show current authentication status | +| `login logout` | `commands/login.ts` | Remove stored credentials | +| `login refresh` | `commands/login.ts` | Re-authenticate and claim a new token | +| `review-context` | `commands/review-context.ts` | Pre-compute review context with ADR briefings for changed files | +| `session-context` | `commands/session-context/index.ts` | Read AI editor session transcripts | +| `session-context claude-code` | `commands/session-context/claude-code.ts` | Read Claude Code session transcript for the project | +| `session-context cursor` | `commands/session-context/cursor.ts` | Read Cursor agent session transcript for the project | +| `plugin` | `commands/plugin/index.ts` | Manage archgate editor plugins | +| `plugin install` | `commands/plugin/install.ts` | Install the archgate plugin for the specified editor | +| `plugin url` | `commands/plugin/url.ts` | Print the authenticated plugin repository URL | +| `upgrade` | `commands/upgrade.ts` | Upgrade Archgate to the latest version | +| `clean` | `commands/clean.ts` | Clean the CLI temp files | ### Key Paths @@ -69,7 +77,7 @@ Zod schemas are the single source of truth. Types derived via `z.infer<>` — ne ## Toolchain (`.prototools`) -Bun 1.3.8, Moon 1.39.4, Node LTS, npm 11.6.0. Minimum user-facing Bun: `>=1.2.21` (enforced in `src/cli.ts`). +Bun 1.3.9, Node LTS, npm 11.11.0. Minimum user-facing Bun: `>=1.2.21` (enforced in `src/cli.ts`). ## Self-Governance ADRs (`.archgate/adrs/`) @@ -80,6 +88,8 @@ Bun 1.3.8, Moon 1.39.4, Node LTS, npm 11.6.0. Minimum user-facing Bun: `>=1.2.21 - `ARCH-005` — Testing standards (Bun test, fixtures, 80% coverage) - `ARCH-006` — Dependency policy (minimal deps, Bun built-ins) - `ARCH-007` — Cross-platform subprocess execution (Bun.spawn, no Bun.$) +- `ARCH-008` — Typed command options (use addOption for choices/argParser) +- `ARCH-009` — Centralized platform detection (use helpers/platform) - `GEN-001` — Documentation site (Astro Starlight) - `GEN-002` — Documentation internationalization (en + pt-br parity) diff --git a/README.md b/README.md index 98a4c1da..78643d29 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,6 @@ See the [writing rules guide](https://cli.archgate.dev/guides/writing-rules/) fo | `archgate adr show ` | Print a specific ADR | | `archgate adr update` | Update an ADR's frontmatter | | `archgate login` | Authenticate with GitHub for editor plugins | -| `archgate mcp` | Start the MCP server for AI agent integration | | `archgate upgrade` | Upgrade to the latest release | | `archgate clean` | Remove the CLI cache (`~/.archgate/`) | @@ -135,7 +134,7 @@ Add `archgate check` to your CI pipeline or pre-commit hooks to block merges tha ## Documentation -Full documentation is available at **[cli.archgate.dev](https://cli.archgate.dev)** — including guides for writing ADRs, writing rules, CI integration, editor plugin setup, and the complete CLI and MCP reference. +Full documentation is available at **[cli.archgate.dev](https://cli.archgate.dev)** — including guides for writing ADRs, writing rules, CI integration, editor plugin setup, and the complete CLI reference. ## Contributing diff --git a/docs/src/content/docs/pt-br/reference/cli-commands.mdx b/docs/src/content/docs/pt-br/reference/cli-commands.mdx index 76ecae8d..2bcfed77 100644 --- a/docs/src/content/docs/pt-br/reference/cli-commands.mdx +++ b/docs/src/content/docs/pt-br/reference/cli-commands.mdx @@ -514,6 +514,81 @@ archgate adr update \ --- +## archgate review-context + +Pré-computa o contexto de revisão com briefings de ADRs para arquivos alterados. Projetado para integrações de CI e plugins de editor que precisam de um resumo de quais ADRs se aplicam aos arquivos sendo alterados. + +```bash +archgate review-context [options] +``` + +### Opções + +| Opção | Descrição | +| ------------------- | ---------------------------------------- | +| `--staged` | Incluir apenas arquivos no git stage | +| `--run-checks` | Incluir resultados de verificação de ADR | +| `--domain ` | Filtrar por um único domínio | + +### Exemplo + +```bash +archgate review-context --staged +``` + +--- + +## archgate session-context + +Lê transcrições de sessão de editores de IA para o projeto. Útil para auditar o que um agente de IA fez durante uma sessão de codificação. + +```bash +archgate session-context [options] +``` + +### Subcomandos + +#### archgate session-context claude-code + +Lê a transcrição de sessão do Claude Code para o projeto. + +```bash +archgate session-context claude-code [options] +``` + +| Opção | Descrição | +| ------------------- | ------------------------------------------- | +| `--max-entries ` | Máximo de entradas a retornar (padrão: 200) | + +#### archgate session-context cursor + +Lê a transcrição de sessão do agente Cursor para o projeto. + +```bash +archgate session-context cursor [options] +``` + +| Opção | Descrição | +| ------------------- | ------------------------------------------- | +| `--max-entries ` | Máximo de entradas a retornar (padrão: 200) | +| `--session-id ` | UUID específico da sessão a ser lida | + +### Exemplos + +Ler a última sessão do Claude Code: + +```bash +archgate session-context claude-code +``` + +Ler uma sessão específica do Cursor: + +```bash +archgate session-context cursor --session-id abc123 +``` + +--- + ## archgate upgrade Atualiza o Archgate para a versão mais recente via npm. diff --git a/docs/src/content/docs/reference/cli-commands.mdx b/docs/src/content/docs/reference/cli-commands.mdx index 104f3fe5..f1211fdf 100644 --- a/docs/src/content/docs/reference/cli-commands.mdx +++ b/docs/src/content/docs/reference/cli-commands.mdx @@ -514,6 +514,81 @@ archgate adr update \ --- +## archgate review-context + +Pre-compute review context with ADR briefings for changed files. Designed for CI and editor plugin integrations that need a summary of which ADRs apply to the files being changed. + +```bash +archgate review-context [options] +``` + +### Options + +| Option | Description | +| ------------------- | ------------------------------------ | +| `--staged` | Only include git-staged files | +| `--run-checks` | Include ADR compliance check results | +| `--domain ` | Filter to a single domain | + +### Example + +```bash +archgate review-context --staged +``` + +--- + +## archgate session-context + +Read AI editor session transcripts for the project. Useful for auditing what an AI agent did during a coding session. + +```bash +archgate session-context [options] +``` + +### Subcommands + +#### archgate session-context claude-code + +Read the Claude Code session transcript for the project. + +```bash +archgate session-context claude-code [options] +``` + +| Option | Description | +| ------------------- | ---------------------------------------- | +| `--max-entries ` | Maximum entries to return (default: 200) | + +#### archgate session-context cursor + +Read the Cursor agent session transcript for the project. + +```bash +archgate session-context cursor [options] +``` + +| Option | Description | +| ------------------- | ---------------------------------------- | +| `--max-entries ` | Maximum entries to return (default: 200) | +| `--session-id ` | Specific session UUID to read | + +### Examples + +Read the latest Claude Code session: + +```bash +archgate session-context claude-code +``` + +Read a specific Cursor session: + +```bash +archgate session-context cursor --session-id abc123 +``` + +--- + ## archgate upgrade Upgrade Archgate to the latest version via npm. diff --git a/src/helpers/git.ts b/src/helpers/git.ts index d6f7048f..fdc80c0e 100644 --- a/src/helpers/git.ts +++ b/src/helpers/git.ts @@ -1,4 +1,4 @@ -import { logDebug } from "./log"; +import { logDebug, logInfo } from "./log"; import { isWindows, isMacOS, resolveCommand } from "./platform"; export async function installGit() { @@ -6,7 +6,7 @@ export async function installGit() { logDebug("Git is already installed"); return; } - console.log("Git is not installed. Installing..."); + logInfo("Git is not installed. Installing..."); if (isWindows()) { throw new Error( "Git is not installed. Install it from https://git-scm.com/download/win and make sure it is on your PATH." diff --git a/src/helpers/login-flow.ts b/src/helpers/login-flow.ts index 6da3bdeb..713d300f 100644 --- a/src/helpers/login-flow.ts +++ b/src/helpers/login-flow.ts @@ -42,7 +42,7 @@ export interface LoginFlowResult { export async function runLoginFlow( options?: LoginFlowOptions ): Promise { - console.log("Authenticating with GitHub...\n"); + logInfo("Authenticating with GitHub...\n"); const deviceCode = await requestDeviceCode(); console.log( @@ -63,7 +63,7 @@ export async function runLoginFlow( await getGitHubUser(githubToken); logInfo(`GitHub user: ${styleText("bold", githubUser)}`); - console.log("Claiming archgate plugin token..."); + logInfo("Claiming archgate plugin token..."); let archgateToken: string; try { archgateToken = await claimArchgateToken(githubToken); @@ -140,18 +140,16 @@ async function runSignupPrompt( v.trim().length > 0 || "Please describe your use case", }); - console.log("\nSubmitting signup request..."); + logInfo("\nSubmitting signup request..."); const result = await requestSignup(githubUser, email, useCase, editor!); if (!result.ok) { - logError( - "Signup request failed. Please try again or sign up at https://plugins.archgate.dev" - ); + logError("Signup request failed. Please try again with `archgate login`."); return null; } if (result.token) return result.token; - console.log("Claiming archgate plugin token..."); + logInfo("Claiming archgate plugin token..."); return claimArchgateToken(githubToken); } diff --git a/src/helpers/platform.ts b/src/helpers/platform.ts index 35f6bb5d..2f759c76 100644 --- a/src/helpers/platform.ts +++ b/src/helpers/platform.ts @@ -210,15 +210,22 @@ export async function resolveCommand(name: string): Promise { if (Bun.which(exeName)) return exeName; } - // 3. Native Windows: try WSL + // 3. Native Windows: try WSL (with timeout to avoid hanging when WSL is slow) if (info.runtime === "win32") { try { const proc = Bun.spawn(["wsl", "which", name], { stdout: "pipe", stderr: "pipe", }); - const exitCode = await proc.exited; - if (exitCode === 0) return name; + const timeout = new Promise<"timeout">((resolve) => + setTimeout(() => resolve("timeout"), 3000) + ); + const result = await Promise.race([proc.exited, timeout]); + if (result === "timeout") { + proc.kill(); + return null; + } + if (result === 0) return name; } catch { // wsl not available } diff --git a/tests/commands/adr/index.test.ts b/tests/commands/adr/index.test.ts new file mode 100644 index 00000000..9cfb5de0 --- /dev/null +++ b/tests/commands/adr/index.test.ts @@ -0,0 +1,49 @@ +import { describe, expect, test } from "bun:test"; + +import { Command } from "@commander-js/extra-typings"; + +import { registerAdrCommand } from "../../../src/commands/adr/index"; + +describe("registerAdrCommand", () => { + test("registers 'adr' as a subcommand", () => { + const program = new Command(); + registerAdrCommand(program); + const sub = program.commands.find((c) => c.name() === "adr"); + expect(sub).toBeDefined(); + }); + + test("has a description", () => { + const program = new Command(); + registerAdrCommand(program); + const sub = program.commands.find((c) => c.name() === "adr")!; + expect(sub.description()).toBeTruthy(); + }); + + test("registers 'create' subcommand", () => { + const program = new Command(); + registerAdrCommand(program); + const adr = program.commands.find((c) => c.name() === "adr")!; + expect(adr.commands.find((c) => c.name() === "create")).toBeDefined(); + }); + + test("registers 'list' subcommand", () => { + const program = new Command(); + registerAdrCommand(program); + const adr = program.commands.find((c) => c.name() === "adr")!; + expect(adr.commands.find((c) => c.name() === "list")).toBeDefined(); + }); + + test("registers 'show' subcommand", () => { + const program = new Command(); + registerAdrCommand(program); + const adr = program.commands.find((c) => c.name() === "adr")!; + expect(adr.commands.find((c) => c.name() === "show")).toBeDefined(); + }); + + test("registers 'update' subcommand", () => { + const program = new Command(); + registerAdrCommand(program); + const adr = program.commands.find((c) => c.name() === "adr")!; + expect(adr.commands.find((c) => c.name() === "update")).toBeDefined(); + }); +}); diff --git a/tests/commands/plugin/index.test.ts b/tests/commands/plugin/index.test.ts new file mode 100644 index 00000000..ade86384 --- /dev/null +++ b/tests/commands/plugin/index.test.ts @@ -0,0 +1,35 @@ +import { describe, expect, test } from "bun:test"; + +import { Command } from "@commander-js/extra-typings"; + +import { registerPluginCommand } from "../../../src/commands/plugin/index"; + +describe("registerPluginCommand", () => { + test("registers 'plugin' as a subcommand", () => { + const program = new Command(); + registerPluginCommand(program); + const sub = program.commands.find((c) => c.name() === "plugin"); + expect(sub).toBeDefined(); + }); + + test("has a description", () => { + const program = new Command(); + registerPluginCommand(program); + const sub = program.commands.find((c) => c.name() === "plugin")!; + expect(sub.description()).toBeTruthy(); + }); + + test("registers 'url' subcommand", () => { + const program = new Command(); + registerPluginCommand(program); + const plugin = program.commands.find((c) => c.name() === "plugin")!; + expect(plugin.commands.find((c) => c.name() === "url")).toBeDefined(); + }); + + test("registers 'install' subcommand", () => { + const program = new Command(); + registerPluginCommand(program); + const plugin = program.commands.find((c) => c.name() === "plugin")!; + expect(plugin.commands.find((c) => c.name() === "install")).toBeDefined(); + }); +}); From 1dae7c24f088b8eb0bfff0e5c32f29d1774ba11b Mon Sep 17 00:00:00 2001 From: rhuanbarreto <283004+rhuanbarreto@users.noreply.github.com> Date: Wed, 18 Mar 2026 23:23:48 +0000 Subject: [PATCH 2/3] docs: regenerate llms-full.txt --- docs/public/llms-full.txt | 75 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt index 3464f72b..b390006b 100644 --- a/docs/public/llms-full.txt +++ b/docs/public/llms-full.txt @@ -3291,6 +3291,81 @@ archgate adr update \ --- +## archgate review-context + +Pre-compute review context with ADR briefings for changed files. Designed for CI and editor plugin integrations that need a summary of which ADRs apply to the files being changed. + +```bash +archgate review-context [options] +``` + +### Options + +| Option | Description | +| ------------------- | ------------------------------------ | +| `--staged` | Only include git-staged files | +| `--run-checks` | Include ADR compliance check results | +| `--domain ` | Filter to a single domain | + +### Example + +```bash +archgate review-context --staged +``` + +--- + +## archgate session-context + +Read AI editor session transcripts for the project. Useful for auditing what an AI agent did during a coding session. + +```bash +archgate session-context [options] +``` + +### Subcommands + +#### archgate session-context claude-code + +Read the Claude Code session transcript for the project. + +```bash +archgate session-context claude-code [options] +``` + +| Option | Description | +| ------------------- | ---------------------------------------- | +| `--max-entries ` | Maximum entries to return (default: 200) | + +#### archgate session-context cursor + +Read the Cursor agent session transcript for the project. + +```bash +archgate session-context cursor [options] +``` + +| Option | Description | +| ------------------- | ---------------------------------------- | +| `--max-entries ` | Maximum entries to return (default: 200) | +| `--session-id ` | Specific session UUID to read | + +### Examples + +Read the latest Claude Code session: + +```bash +archgate session-context claude-code +``` + +Read a specific Cursor session: + +```bash +archgate session-context cursor --session-id abc123 +``` + +--- + ## archgate upgrade Upgrade Archgate to the latest version via npm. From 88410a623966df54142fe62a77c4f313daf0d676 Mon Sep 17 00:00:00 2001 From: Rhuan Barreto Date: Thu, 19 Mar 2026 00:30:35 +0100 Subject: [PATCH 3/3] feat: add use-log-helpers rule to ARCH-002 Extend ARCH-002 to enforce centralized logging in helper and engine files. The new `use-log-helpers` rule flags direct console.log/warn/info calls, requiring logInfo/logWarn/logDebug from helpers/log.ts instead. Command files are exempt (I/O layer), along with log.ts (canonical implementation), reporter.ts (check output system), and login-flow.ts (interactive device flow UI). --- .archgate/adrs/ARCH-002-error-handling.md | 4 ++- .../adrs/ARCH-002-error-handling.rules.ts | 28 +++++++++++++++++++ CLAUDE.md | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/.archgate/adrs/ARCH-002-error-handling.md b/.archgate/adrs/ARCH-002-error-handling.md index c44b0390..d1db6e61 100644 --- a/.archgate/adrs/ARCH-002-error-handling.md +++ b/.archgate/adrs/ARCH-002-error-handling.md @@ -54,6 +54,7 @@ Use three exit codes with clear semantics: - Don't catch and swallow unexpected errors — let them propagate - Don't show stack traces for user errors - Don't use `console.error()` directly — use `logError()` for consistent formatting +- Don't use `console.log()` or `console.warn()` directly in helper or engine files — use `logInfo()` or `logWarn()` (command files are the I/O layer and may use console directly) - Don't exit with code 0 when an operation fails - Don't use exit codes other than 0, 1, or 2 @@ -122,7 +123,7 @@ try { ### Risks - **Swallowed errors in async code** — Async functions that catch errors without re-throwing can silently fail. Unhandled promise rejections in Bun terminate the process with a non-zero exit code, which provides a safety net, but the error message may be unclear. - - **Mitigation:** The `logError()` convention makes explicit error handling visible in code review. The `use-log-error` automated rule flags direct `console.error()` usage, nudging developers toward the standard pattern. + - **Mitigation:** The log helper convention makes explicit error handling visible in code review. The `use-log-error` rule flags direct `console.error()` usage, and the `use-log-helpers` rule flags direct `console.log()`/`console.warn()` in helper and engine files, nudging developers toward the standard pattern. - **Exit code 2 masking real issues** — If an unexpected error occurs in a rule file, the CLI exits with code 2 ("internal error") rather than code 1 ("violations"). This could confuse CI systems that only check for non-zero exit. - **Mitigation:** The check engine wraps rule execution with timeout and error boundaries, reporting rule errors separately from violations. The `--verbose` flag shows which rules errored. @@ -131,6 +132,7 @@ try { ### Automated Enforcement - **Archgate rule** `ARCH-002/use-log-error`: Scans all source files (excluding `helpers/log.ts` and test files) for `console.error()` usage and flags violations. Severity: `error`. +- **Archgate rule** `ARCH-002/use-log-helpers`: Scans helper and engine files for direct `console.log()`, `console.warn()`, or `console.info()` usage. Excludes `helpers/log.ts` (canonical implementation), `engine/reporter.ts` (check output system), `helpers/login-flow.ts` (interactive device flow UI), and test files. Command files are exempt since they are the I/O layer. Severity: `error`. - **Archgate rule** `ARCH-002/exit-code-convention`: Scans all source files for `process.exit()` calls and verifies the exit code is 0, 1, or 2. Severity: `error`. ### Manual Enforcement diff --git a/.archgate/adrs/ARCH-002-error-handling.rules.ts b/.archgate/adrs/ARCH-002-error-handling.rules.ts index 5d52ece0..a9c2d8d3 100644 --- a/.archgate/adrs/ARCH-002-error-handling.rules.ts +++ b/.archgate/adrs/ARCH-002-error-handling.rules.ts @@ -24,6 +24,34 @@ export default defineRules({ } }, }, + "use-log-helpers": { + description: + "Use log helpers instead of console.log/warn/info in helper and engine files", + async check(ctx) { + const files = ctx.scopedFiles.filter( + (f) => + (f.includes("helpers/") || f.includes("engine/")) && + !f.endsWith("helpers/log.ts") && + !f.endsWith("engine/reporter.ts") && + !f.endsWith("helpers/login-flow.ts") && + !f.includes("tests/") + ); + const matches = await Promise.all( + files.map((file) => ctx.grep(file, /console\.(log|warn|info)\s*\(/)) + ); + for (const fileMatches of matches) { + for (const m of fileMatches) { + ctx.report.violation({ + message: + "Use logInfo/logWarn/logDebug from helpers/log.ts instead of direct console output", + file: m.file, + line: m.line, + fix: "Import { logInfo, logWarn } from '../helpers/log' and use logInfo() or logWarn()", + }); + } + } + }, + }, "exit-code-convention": { description: "Process.exit should use codes 0, 1, or 2 only", async check(ctx) { diff --git a/CLAUDE.md b/CLAUDE.md index 0dc28645..ea74169c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -82,7 +82,7 @@ Bun 1.3.9, Node LTS, npm 11.11.0. Minimum user-facing Bun: `>=1.2.21` (enforced ## Self-Governance ADRs (`.archgate/adrs/`) - `ARCH-001` — Command structure (register pattern, no business logic) -- `ARCH-002` — Error handling (exit codes, logError) +- `ARCH-002` — Error handling (exit codes, log helpers) - `ARCH-003` — Output formatting (styleText, --json, no emoji) - `ARCH-004` — No barrel files (direct imports only) - `ARCH-005` — Testing standards (Bun test, fixtures, 80% coverage)