You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chore: address adversarial review findings for monorepo pre-shape
Follow-ups from the PR #1254 review (no behavior change to shipped CLI):
- check-patches.ts: harden resolvePackageFile() to derive the package
root from the FIRST `<pkgName>/` after the last `node_modules/`
boundary, instead of `lastIndexOf('/<pkgName>/')`. A package that
vendors a nested copy of itself would otherwise truncate at the wrong
inner segment. Also refresh the stale `node-linker=hoisted` comment.
- biome.jsonc / packages/cli/.gitignore: reconcile the contradictory
comments about which .gitignore Biome reads. Biome honors the
workspace-root .gitignore via `vcs.root: "../.."`; the package-level
.gitignore is for plain git only. Drop the dead `!docs` ignore
(no packages/cli/docs after the move).
- build.ts / bundle.ts: fix comments that still claimed deps are
"hoisted to the workspace-root node_modules" — under node-linker=isolated
they live in the isolated store; the code (module resolution / `pnpm
exec`) is unchanged and correct.
- packages/cli/AGENTS.md: replace stale Bun-era guidance with the current
pnpm/Node/Vitest reality — command reference, "Use Node.js APIs"
section, test-runner isolation notes (VITEST_POOL_ID), vitest imports
and `vi.mock`, moved docs path (apps/cli-docs), and removed the dangling
`.cursor/rules/bun-cli.mdc` reference.
Verified: typecheck, lint, all check:* scripts, build (+ binary smoke).
<!-- This section is maintained by the coding agent via lore (https://github.com/BYK/loreai) -->
2
+
## Long-term Knowledge
3
+
4
+
For long-term knowledge entries managed by [lore](https://github.com/BYK/loreai) (gotchas, patterns, decisions, architecture), see [`.lore.md`](.lore.md) in the project root.
Copy file name to clipboardExpand all lines: packages/cli/AGENTS.md
+55-57Lines changed: 55 additions & 57 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,15 +4,15 @@ Guidelines for AI agents working in this codebase.
4
4
5
5
## Project Overview
6
6
7
-
**Sentry CLI** is a command-line interface for [Sentry](https://sentry.io), built with [Bun](https://bun.sh) and [Stricli](https://bloomberg.github.io/stricli/).
7
+
**Sentry CLI** is a command-line interface for [Sentry](https://sentry.io), built with Node.js, [pnpm](https://pnpm.io), and [Stricli](https://bloomberg.github.io/stricli/). It lives in `packages/cli` of a pnpm workspace; the docs site lives in `apps/cli-docs`.
8
8
9
9
### Goals
10
10
11
11
-**Zero-config experience** - Auto-detect project context from DSNs in source code and env files
12
12
-**AI-powered debugging** - Integrate Seer AI for root cause analysis and fix plans
13
13
-**Developer-friendly** - Follow `gh` CLI conventions for intuitive UX
14
14
-**Agent-friendly** - JSON output and predictable behavior for AI coding agents
15
-
-**Fast** - Native binaries via Bun, SQLite caching for API responses
15
+
-**Fast** - Native binaries via Node SEA (fossilize), SQLite caching for API responses
16
16
17
17
### Key Features
18
18
@@ -28,86 +28,83 @@ Guidelines for AI agents working in this codebase.
28
28
29
29
Before working on this codebase, read the Cursor rules:
30
30
31
-
-**`.cursor/rules/bun-cli.mdc`** - Bun API usage, file I/O, process spawning, testing
pnpm run cli -- <args># Run the CLI with arguments
43
43
44
44
# Build
45
-
bun run build# Build for current platform
46
-
bun run build:all# Build for all platforms
45
+
pnpm run build # Build for current platform
46
+
pnpm run build:all # Build for all platforms
47
47
48
48
# Type Checking
49
-
bun run typecheck # Check types
49
+
pnpm run typecheck # Check types (tsc)
50
50
51
51
# Linting & Formatting
52
-
bun run lint # Check for issues
53
-
bun run lint:fix # Auto-fix issues (run before committing)
54
-
55
-
# Testing
56
-
bun test# Run all tests
57
-
bun test path/to/file.test.ts # Run single test file
58
-
bun test --watch # Watch mode
59
-
bun test --filter "test name"# Run tests matching pattern
60
-
bun run test:unit # Run unit tests only
61
-
bun run test:e2e # Run e2e tests only
52
+
pnpm run lint # Check for issues (Biome)
53
+
pnpm run lint:fix # Auto-fix issues (run before committing)
54
+
55
+
# Testing (Vitest)
56
+
pnpm run test:unit # Run unit tests
57
+
pnpm run test:e2e # Run e2e tests
58
+
pnpm exec vitest run test/lib/foo.test.ts # Run a single test file (skips generate steps)
59
+
pnpm exec vitest # Watch mode
62
60
```
63
61
64
62
## Rules: No Runtime Dependencies
65
63
66
-
**CRITICAL**: All packages must be in `devDependencies`, never `dependencies`. Everything is bundled at build time via esbuild. CI enforces this with `bun run check:deps`.
64
+
**CRITICAL**: All packages must be in `devDependencies`, never `dependencies`. Everything is bundled at build time via esbuild. CI enforces this with `pnpm run check:deps`.
67
65
68
-
When adding a package, always use `bun add -d <package>` (the `-d` flag).
66
+
When adding a package, always use `pnpm add -D <package>` (the `-D` flag).
69
67
70
68
When the `@sentry/api` SDK provides types for an API response, import them directly from `@sentry/api` instead of creating redundant Zod schemas in `src/types/sentry.ts`.
71
69
72
-
## Rules: Use Bun APIs
70
+
## Rules: Use Node.js APIs
73
71
74
-
**CRITICAL**: This project uses Bun as runtime. Always prefer Bun-native APIs over Node.js equivalents.
72
+
**CRITICAL**: This project runs on Node.js. Use Node.js standard-library
73
+
(`node:*`) APIs; there is no Bun runtime. (This project was migrated from Bun to
74
+
Node — do not reintroduce `Bun.*` globals, `bun:test`, or `bun` CLI commands.)
75
75
76
-
Read the full guidelines in `.cursor/rules/bun-cli.mdc`.
76
+
### Quick API Reference
77
77
78
-
**Bun Documentation**: https://bun.sh/docs - Consult these docs when unsure about Bun APIs.
**Exception**: Use `node:fs` for directory creation with permissions:
90
+
Use `node:fs` for directory creation with permissions:
95
91
```typescript
96
92
import { mkdirSync } from"node:fs";
97
93
mkdirSync(dir, { recursive: true, mode: 0o700 });
98
94
```
99
95
100
-
**Exception**: `Bun.$` (shell tagged template) has no shim in `script/node-polyfills.ts` and will crash on the npm/node distribution. Until a shim is added, use `execSync` from `node:child_process` for shell commands that must work in both runtimes:
96
+
For shell commands, prefer `execFileSync` with array args over `execSync` with a
97
+
string when passing user-controlled values, to avoid shell injection:
-**`docs/`** — documentation site (Astro + Starlight); **`script/`** — build/utility
131
-
scripts; **`.cursor/rules/`** — Cursor AI rules; **`biome.jsonc`** — lint config.
127
+
-**`../../apps/cli-docs/`** — documentation site (Astro + Starlight);
128
+
**`script/`** — build/utility scripts; **`.cursor/rules/`** — Cursor AI rules;
129
+
**`biome.jsonc`** — lint config.
132
130
133
131
## Key Patterns
134
132
@@ -409,12 +407,12 @@ Use `"date"` for timestamp-based sort (not `"time"`). Export sort types from the
409
407
410
408
### Generated Docs & Skills
411
409
412
-
All command docs and skill files are generated via `bun run generate:docs` (which runs `generate:command-docs` then `generate:skill`). This runs automatically as part of `dev`, `build`, `typecheck`, and `test` scripts.
410
+
All command docs and skill files are generated via `pnpm run generate:docs` (which runs `generate:command-docs` then `generate:skill`). This runs automatically as part of `dev`, `build`, `typecheck`, and `test` scripts.
413
411
414
412
-**Command docs** (`docs/src/content/docs/commands/*.md`) are **gitignored** and generated from CLI metadata + hand-written fragments in `docs/src/fragments/commands/`.
415
413
-**Skill files** (`plugins/sentry-cli/skills/sentry-cli/`) are **committed** (consumed by external plugin systems) and auto-committed by CI when stale.
416
414
- Edit fragments in `docs/src/fragments/commands/` for custom examples and guides.
417
-
-`bun run check:fragments` validates fragment ↔ route consistency.
415
+
-`pnpm run check:fragments` validates fragment ↔ route consistency.
418
416
- Positional `placeholder` values must be descriptive: `"org/project/trace-id"` not `"args"`.
419
417
420
418
### Zod Schemas for Validation
@@ -510,7 +508,7 @@ CliError (base, exitCode=1)
510
508
- Pass `alternatives: []` when defaults are irrelevant (e.g., for missing Trace ID, Event ID)
511
509
- Use `" and "` in `resource` for plural grammar: `"Trace ID and span ID"` → "are required"
512
510
513
-
**CI enforcement:**`bun run check:errors` scans for `ContextError` with multiline commands, `CliError` with ad-hoc "Try:" strings, and silent `catch` blocks (advisory).
511
+
**CI enforcement:**`pnpm run check:errors` scans for `ContextError` with multiline commands, `CliError` with ad-hoc "Try:" strings, and silent `catch` blocks (advisory).
514
512
515
513
```typescript
516
514
// Usage examples
@@ -554,7 +552,7 @@ catch (error) {
554
552
555
553
Use `logger.withTag("command-name")` for tagged logging in command files.
556
554
557
-
**CI enforcement:**`bun run check:errors` includes a silent-catch scan that flags
555
+
**CI enforcement:**`pnpm run check:errors` includes a silent-catch scan that flags
558
556
`catch` blocks which are empty, comment-only, or return-only without surfacing the
559
557
error. It is currently **advisory** (warns, does not fail CI) because of a pre-existing
560
558
backlog; run with `SENTRY_STRICT_SILENT_CATCH=1` to enforce. Do not add new silent
@@ -700,7 +698,7 @@ await deleteUserData(userId)
700
698
### Goal
701
699
Minimal comments, maximum clarity. Comments explain **intent and reasoning**, not syntax.
702
700
703
-
## Testing (bun:test + fast-check)
701
+
## Testing (Vitest + fast-check)
704
702
705
703
**Prefer property-based and model-based testing** over traditional unit tests. These approaches find edge cases automatically and provide better coverage with less code.
706
704
@@ -734,7 +732,7 @@ Tests that need a database or config directory **must** use `useTestConfigDir()`
734
732
-`const baseDir = process.env[CONFIG_DIR_ENV_VAR]!` at module scope — This captures a value that may be stale
735
733
- Manual `beforeEach`/`afterEach` that sets/deletes `SENTRY_CONFIG_DIR`
736
734
737
-
**Why**: Bun's test runner uses `--isolate --parallel`(see `test:unit` in `package.json`), so each test file runs in a fresh global environment within a worker process. That bounds most cross-file leaks to a single worker, but `process.env` is still shared within a file's lifecycle — if your `afterEach` deletes the env var, the next describe/test's module-level code (or a beforeEach that re-reads env) gets `undefined`, causing `TypeError: The "paths[0]" property must be of type string`. Also, `TEST_TMP_DIR` is namespaced by `BUN_TEST_WORKER_ID` in `test/constants.ts` so parallel workers don't wipe each other's temp state during preload.
735
+
**Why**: Vitest runs each test file in a worker pool (see `test:unit` in `package.json`), so each file runs in its own worker process. That bounds most cross-file leaks to a single worker, but `process.env` is still shared within a file's lifecycle — if your `afterEach` deletes the env var, the next describe/test's module-level code (or a beforeEach that re-reads env) gets `undefined`, causing `TypeError: The "paths[0]" property must be of type string`. Also, `TEST_TMP_DIR` is namespaced by `VITEST_POOL_ID` in `test/constants.ts` so parallel workers don't wipe each other's temp state during preload.
0 commit comments