Skip to content

Commit 0260a30

Browse files
committed
chore: fix stale line-number comment and CLAUDE.md WSL doc reference
1 parent dfded5f commit 0260a30

2 files changed

Lines changed: 238 additions & 1 deletion

File tree

CLAUDE.md

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Zoo Code is a community fork of Roo Code — a VS Code extension that provides an AI-powered coding assistant in the editor. It supports multiple AI providers (Anthropic, OpenAI, Gemini, OpenRouter, Ollama, etc.) through a React webview UI backed by a TypeScript extension host.
8+
9+
## Monorepo Structure
10+
11+
```
12+
src/ # VS Code extension (main workspace package, legacy location — intended to be apps/vscode)
13+
core/ # Extension core: webview provider, task system, tools, config, prompts, checkpoints
14+
api/ # API abstraction layer for AI providers
15+
services/ # MCP, code-index, marketplace, ripgrep, tree-sitter, glob, skills, telemetry
16+
integrations/ # VS Code integrations: editor, terminal, diagnostics, workspace, theme
17+
shared/ # Shared types and utilities (modes, tools, costs, context-mentions, etc.)
18+
utils/ # Utility functions (safeWriteJson, shell allowlist, etc.)
19+
extension.ts # Extension entry point
20+
activate/ # Activation helpers: commands, code actions, URI handlers
21+
webview-ui/ # React frontend (Vite + Tailwind CSS + shadcn/ui)
22+
apps/
23+
cli/ # CLI tool
24+
vscode-e2e/ # End-to-end tests using @vscode/test-electron
25+
vscode-nightly/ # Nightly build configuration
26+
packages/
27+
build/ # esbuild-based build helper
28+
cloud/ # Cloud service client (auth, licensing)
29+
config-eslint/ # Shared ESLint config
30+
config-typescript/ # Shared TypeScript config
31+
core/ # Shared core types/interfaces (@roo-code/core)
32+
ipc/ # IPC protocol between extension and webview
33+
telemetry/ # Telemetry service (PostHog-based)
34+
types/ # Shared type definitions (@roo-code/types)
35+
vscode-shim/ # VS Code API shim for non-extension contexts
36+
```
37+
38+
## Environment Requirements
39+
40+
- **Node.js**: `20.20.2` (see `.nvmrc`). Other versions may work but are not tested.
41+
- **pnpm**: `10.8.1` (see root `package.json``packageManager`). The repo enforces pnpm via `only-allow`.
42+
- **VS Code**: `^1.84.0` for extension development (see `src/package.json``engines.vscode`).
43+
44+
## Essential Commands
45+
46+
```bash
47+
# Install dependencies (uses frozen-lockfile for CI/reproducible installs)
48+
pnpm install
49+
50+
# Install:vsix and install:vsix:nightly explicitly use --frozen-lockfile
51+
52+
# Build all packages
53+
pnpm build
54+
55+
# Bundle only (esbuild for extension + vite for webview; faster than full build)
56+
pnpm bundle
57+
58+
# Type checking
59+
pnpm check-types
60+
61+
# Linting
62+
pnpm lint
63+
64+
# Run all tests (depends on @roo-code/types#build — types must compile first)
65+
pnpm test
66+
67+
# Run tests from specific workspace (critical — must run from workspace dir, not root)
68+
cd src && npx vitest run path/to/test.spec.ts
69+
cd webview-ui && npx vitest run src/path/to/test.spec.ts
70+
71+
# Format code (also runs automatically on commit via lint-staged)
72+
pnpm format
73+
74+
# Build VSIX package
75+
pnpm vsix
76+
77+
# Install VSIX directly into VS Code (builds, uninstalls old version, installs new, prompts restart)
78+
pnpm install:vsix [-y] [--editor=<code|cursor|code-insiders>]
79+
80+
# Clean build artifacts
81+
pnpm clean
82+
```
83+
84+
### Build Details
85+
86+
The extension bundle is handled by [src/esbuild.mjs](src/esbuild.mjs) (not a CLI invocation):
87+
88+
- **Two entry points**: `extension.ts``dist/extension.js` (CJS) and `workers/countTokens.ts``dist/workers/`
89+
- **Three externals**: `vscode`, `esbuild`, `global-agent` — global-agent must stay external because it dynamically patches Node.js http/https; undici is bundled because the VSIX is packaged with `--no-dependencies`
90+
- **Four plugins**: `copyFiles` (README, CHANGELOG, LICENSE, .env, material-icons, audio, marketplace assets), `copyWasms`, `copyLocales`, `esbuild-problem-matcher`
91+
- **Windows EBUSY**: Rebuilds run sequentially (`extensionCtx.rebuild()` then `workerCtx.rebuild()`) — NOT `Promise.all` — to avoid concurrent `onEnd` hooks copying the same asset directories. `distDir` cleanup retries up to 5 times with linear backoff for `ENOTEMPTY`/`EBUSY`/`EPERM`
92+
- **Build-time defines**: `process.env.PKG_RELEASE_CHANNEL` (default `"stable"`) and `process.env.POSTHOG_API_KEY` (default `""`)
93+
- **Sourcemaps**: Always generated (`sourcemap: true`) with `sourcesContent: false`
94+
95+
### Pre-commit Hooks
96+
97+
The repo uses **husky** + **lint-staged**. On every commit, staged files matching `*.{js,jsx,ts,tsx,json,css,md}` are auto-formatted with Prettier. This is configured in root `package.json``lint-staged`.
98+
99+
## Code Style
100+
101+
- **Prettier**: tabs (width 4), no semicolons, 120-char print width. See `.prettierrc.json`.
102+
- **ESLint**: Shared configs in `@roo-code/config-eslint` (`packages/config-eslint/`) with three presets: `base` (TS + prettier + turbo), `react` (extends base), `next-js` (extends react). Each workspace has its own `eslint.config.mjs` that imports one of these.
103+
- **pnpm-lock.yaml** is the lockfile. `package-lock.json` is gitignored.
104+
105+
## Rebranding Context
106+
107+
Zoo Code is a community fork of Roo Code. Many internal identifiers still reflect the transition:
108+
- Command prefix: `zoo-code.*` (new), but config keys may use `roo-cline.*` (legacy)
109+
- Extension manifest in `src/package.json` is `zoo-code`, but root `package.json` is still `roo-code`
110+
- The `src/` directory was intended to be `apps/vscode` (see `pnpm-workspace.yaml` comment)
111+
- Some packages (`@roo-code/types`, `@roo-code/core`) retain the old namespace
112+
- Do not assume consistent naming — always check actual identifiers before referencing them
113+
114+
## Changesets
115+
116+
This project uses [changesets](https://github.com/changesets/changesets) for versioning and changelog management:
117+
- Run `pnpm changeset:version` to bump versions based on pending changesets (also copies `CHANGELOG.md` to `src/`)
118+
- Changeset config is in `.changeset/config.json`
119+
- The core extension is in a **fixed group** (`[["zoo-code"]]`) — always versioned together
120+
- `@roo-code/cli` is **ignored** by changesets (CLI versioning is independent)
121+
- Custom changelog formatter in `.changeset/changelog-config.js` — summaries are bullet-pointed; dependency updates produce no changelog lines
122+
123+
## CI/CD
124+
125+
GitHub Actions workflows in `.github/workflows/`:
126+
127+
| Workflow | Trigger | Purpose |
128+
|---|---|---|
129+
| `code-qa.yml` | PRs to main | Lint, type-check, knip dead-code check, unit tests (ubuntu + windows), translation validation |
130+
| `e2e.yml` | PRs to main | E2E tests with caching: if source hash previously passed, tests are skipped entirely |
131+
| `marketplace-publish.yml` | `v*.*.*` tag | Publish to VS Code Marketplace + Open VSX Registry + GitHub Release |
132+
| `nightly-publish.yml` | Push to main | Pre-release publish to VS Code Marketplace only (odd minor version + run_number) |
133+
| `release-validation.yml` | PRs touching release files | Validates semver, changelog entries, README sync, VSIX contents |
134+
| `cli-release.yml` | Manual trigger | Multi-platform CLI build (darwin-arm64, linux-x64, linux-arm64) |
135+
136+
**Codecov strategy** (`code-qa.yml` unit-test job): Three separate coverage uploads on ubuntu only — non-core, core-unit, core-integration — each with distinct flags to prevent duplicate line counting when paths overlap. See `codecov.yml`.
137+
138+
**Translation validation** (`check-translations` job): Runs `scripts/find-missing-translations.js` which compares non-English locale files against English baselines across all three i18n systems. Supports `--locale`, `--file`, `--area` filters.
139+
140+
## Test Rules
141+
142+
- **Tests MUST be run from the correct workspace directory, NOT from the monorepo root.** `npx vitest` at root fails with "command not found."
143+
- `vitest` globals (`vi`, `describe`, `it`, `expect`) are configured via `globals: true` in each workspace's config — no imports needed.
144+
- Both `src/` and `webview-ui/` have a `pretest` script that runs `turbo run bundle --cwd ..`. Bundle must succeed before tests execute.
145+
- `turbo.json` `test` task depends on `@roo-code/types#build`. Type generation from `packages/types/` must complete before any test can run.
146+
- Prefer the narrowest test layer: unit tests in `__tests__/` for logic, e2e in `apps/vscode-e2e/` only for real VS Code extension host behavior.
147+
148+
**Per-workspace test environments:**
149+
150+
| Workspace | Environment | Test file pattern | Notes |
151+
|---|---|---|---|
152+
| `src/` | node (default) | `*.test.ts` | VS Code mocked in `__mocks__/vscode.js` |
153+
| `webview-ui/` | **jsdom** | `*.spec.{ts,tsx}` | VS Code mocked in `src/__mocks__/vscode.ts`; aliases: `@``./src` |
154+
| `apps/cli/` | node | `*.test.{ts,tsx}` | 120s timeout for integration tests |
155+
| `packages/core/` | node | `*.test.ts` | Separate unit and integration configs via `scripts/test-config.ts` |
156+
157+
**Coverage**: Codecov with project target `auto`, patch target 80%. Only ubuntu uploads coverage in CI — three separate uploads (non-core, core-unit, core-integration) to avoid double-counting overlapping paths.
158+
159+
## Environment Variables
160+
161+
**Build-time** (defined in esbuild `define`):
162+
- `PKG_RELEASE_CHANNEL``"stable"` or `"prerelease"` (nightly)
163+
- `POSTHOG_API_KEY` — analytics key (empty by default)
164+
165+
**CLI** (`apps/cli/`): `ROO_AUTH_BASE_URL`, `ROO_SDK_BASE_URL`, `ROO_CODE_PROVIDER_URL` — point to production or local dev services. At runtime in release builds: `ROO_CLI_ROOT`, `ROO_EXTENSION_PATH`, `ROO_RIPGREP_PATH`.
166+
167+
**E2E** (`apps/vscode-e2e/.env.local.sample`): Provider API keys for test runs.
168+
169+
**CI secrets**: `VSCE_PAT`, `OVSX_PAT`, `POSTHOG_API_KEY`, `CODECOV_TOKEN`.
170+
171+
## Key Architecture Patterns
172+
173+
### API Provider System
174+
All AI providers live in [src/api/providers/](src/api/providers/). Each provider extends `BaseProvider` ([base-provider.ts](src/api/providers/base-provider.ts)) and implements model fetching + request handling. OpenAI-compatible providers extend `BaseOpenAiCompatibleProvider` ([base-openai-compatible-provider.ts](src/api/providers/base-openai-compatible-provider.ts)). The main API entry point is [src/api/index.ts](src/api/index.ts).
175+
176+
### Extension Activation Flow
177+
[extension.ts](src/extension.ts) is the entry point. It:
178+
1. Loads environment variables, initializes network proxy, i18n
179+
2. Creates `ContextProxy` for workspace configuration
180+
3. Instantiates `ClineProvider` (the webview provider), `McpServerManager`, `CodeIndexManager`, `MdmService`
181+
4. Registers commands, code actions, terminal actions, URI handlers from [activate/](src/activate/)
182+
183+
### Webview ↔ Extension Communication
184+
Uses VS Code's `postMessage` API. The `ClineProvider` in [src/core/webview/ClineProvider.ts](src/core/webview/ClineProvider.ts) manages two-way communication. The `WebviewMessage` type in [src/shared/WebviewMessage.ts](src/shared/WebviewMessage.ts) defines the message protocol.
185+
186+
### Task System
187+
`src/core/task/` implements the main agent loop — handling user messages, tool execution, context management, and checkpoint creation. `src/core/task-persistence/` handles saving/restoring task state.
188+
189+
### Context Management
190+
`src/core/context/` and `src/core/context-management/` manage the context window — condensing long conversations, tracking token usage, and managing context mentions.
191+
192+
## Mandatory Patterns
193+
194+
- **safeWriteJson** ([src/utils/safeWriteJson.ts](src/utils/safeWriteJson.ts)): All JSON file writes MUST use this. It provides atomic writes with file locking, temp files, backup, and rollback. Creates parent directories automatically — do NOT call `mkdir` before it. Test files are exempt.
195+
- **Settings View Pattern**: Settings inputs in webview-ui must bind to local `cachedState`, NOT live `useExtensionState()`. Direct wiring causes race conditions.
196+
- **Shell Detection**: [src/utils/shell.ts](src/utils/shell.ts) uses `vscode.env.shell` (VS Code 1.37+) as the primary shell resolution source, with platform-specific fallback chains (`userInfo().shell``COMSPEC`/`SHELL` → platform default). Both external terminal (`Terminal.ts`) and inline terminal (`ExecaTerminalProcess.ts`) use a unified shell resolution: `getExecaShellPath() || getShell()`. The external terminal path falls back to the inline path only when VS Code shell integration is unavailable (WSL, disabled, or unsupported shell) — `no_shell_integration` is emitted per-command. `Terminal.getConfiguredWslProfileArgs()` reads trusted-scope VS Code WSL profile args for supplementary distro detection (two-tier with `getShell()`).
197+
- **Tailwind over inline styles**: In webview-ui, use Tailwind CSS classes. VS Code CSS variables must be registered in [webview-ui/src/index.css](webview-ui/src/index.css) before use in Tailwind classes.
198+
199+
### Terminal Execution
200+
201+
There are two terminal execution paths — any terminal-related change must consider both:
202+
203+
1. **Inline Terminal** (default, recommended): Uses `execa` via [`ExecaTerminalProcess.ts`](src/integrations/terminal/ExecaTerminalProcess.ts). Bypasses VS Code shell integration. Debug logs use `[ExecaTerminalProcess#run]` and `[ExecaTerminalProcess#abort]` prefixes.
204+
2. **VS Code Terminal**: Uses `vscode.window.createTerminal` via [`Terminal.ts`](src/integrations/terminal/Terminal.ts). Supports shell integration but can time out (default 15s), falling back to Inline Terminal with a `no_shell_integration` event.
205+
206+
**`TerminalProcess` is a critical, stable interface** — see [src/integrations/terminal/README.md](src/integrations/terminal/README.md). Modifying it without understanding VS Code shell integration architecture can break terminal output reliability. Key design points:
207+
208+
- 100ms throttled event output, zero-copy with index-based tracking (no substring ops)
209+
- `fullOutput` is never split on carriage returns; regex is avoided (500x slower than string parsing for large outputs)
210+
- The return type `RooTerminalProcessResultPromise` is both a `RooTerminalProcess` (event emitter) and a `Promise<void>` (completion)
211+
- Upstream VS Code bug [#237208](https://github.com/microsoft/vscode/issues/237208) may affect escape sequence handling
212+
213+
### Internationalization (i18n)
214+
215+
The extension is localized into 17+ languages. There are **three separate i18n systems**:
216+
217+
1. **Extension manifest i18n**: Uses `%key%` placeholders resolved from `package.nls.*.json` files in `src/`. Controls VS Code commands, views, configuration contributions.
218+
2. **Webview UI i18n**: Uses `i18next` with resource files in `src/i18n/locales/`. Controls the React UI text.
219+
3. **Root documentation i18n**: Translated README and CONTRIBUTING docs in `locales/`.
220+
221+
Always add new user-facing extension strings to `package.nls.json` (English base) at minimum. Webview UI strings go in `src/i18n/locales/`. These systems are independent — updating one does not affect the others.
222+
223+
**Backend loader** ([src/i18n/setup.ts](src/i18n/setup.ts)): At runtime, uses Node.js `fs` to scan language directories and load JSON translation files by namespace (e.g., `chat.json`, `common.json`). In test environments (`NODE_ENV === "test"`), file-system loading is skipped entirely and empty resources are returned.
224+
225+
**Translation validation**: `scripts/find-missing-translations.js` recursively diffs non-English locale files against English baselines across all three systems. Supports `--locale`, `--file`, `--area` (core/webview/package-nls/all) filters.
226+
227+
## Debugging
228+
229+
- **F5 in VS Code**: The pre-configured launch config in `.vscode/launch.json` starts an Extension Development Host with `NODE_ENV=development` and `VSCODE_DEBUG_MODE=true`. The default build task runs three parallel watchers (webview, bundle, tsc).
230+
- **Webview DevTools**: Command Palette → "Developer: Open Webview Developer Tools" (NOT F12). The webview runs in an isolated VSCode context — `localStorage` and filesystem access are unavailable.
231+
- **Extension host logs**: View → Output → select "Extension Host" (NOT the Debug Console).
232+
- **Shell integration**: Check the "Roo Code" output channel for shell integration status messages and timeouts.
233+
- **CLI debugging** (`apps/cli/`): `console.log` breaks the TUI display. Use file-based logging — write to `/tmp/roo-cli-debug.log` with `fs.appendFileSync()`.
234+
235+
## Contribution Workflow
236+
237+
Per `CONTRIBUTING.md`: **File a GitHub Issue and get it assigned before submitting a PR.** PRs without linked issues will not be reviewed. All PRs start as drafts.

src/integrations/terminal/Terminal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ export class Terminal extends BaseTerminal {
435435
return undefined
436436
}
437437

438-
// Normalize args — same filtering as getProfileShell() (line 581-585):
438+
// Normalize args — same filtering as getProfileShell():
439439
// string → [string], arrays filtered to typeof string entries only.
440440
const args = Array.isArray(profile.args)
441441
? profile.args.filter((arg): arg is string => typeof arg === "string")

0 commit comments

Comments
 (0)