diff --git a/.claude/rules/mf-and-deploy.md b/.claude/rules/mf-and-deploy.md new file mode 100644 index 0000000..ef90927 --- /dev/null +++ b/.claude/rules/mf-and-deploy.md @@ -0,0 +1,51 @@ +--- +description: Module Federation remote surface + Vercel deployment rules for cv-builder +paths: + - "packages/browser-app/**" + - "packages/browser-app/vite.config.ts" + - "vercel.json" +--- + +# Module Federation & deployment (cv-builder) + +Path-conditional guidance (ADR-0081 Layer 1): loads when editing the browser-app MF surface or +the Vercel deploy config. Repo-wide policy is in the root `CLAUDE.md`. + +## Frame OS / MF remote + +Resume Builder is a **Module Federation remote** in the Frame OS cluster (see +`domain-knowledge/frame-os-context.md`). It exposes a `FrameBeadLike` implementation via +`GET /api/beads` (ADR-0016 / Gas Town Sprint 1), mapping `JobListing` entities to the universal +FrameBead shape for ShellAgent consumption (fields: `type`, `created_at`, `updated_at`, +`sourceApp` for Mayor compatibility). The AgentBead bridge (ADR-0043) maps Claude Code lifecycle +events to Gas Town bead emissions. The shell's `/api/beads` aggregation uses a Dolt-first strategy +with filesystem fallback. + +### MF remote surface area +`packages/browser-app/vite.config.ts` exposes two components: +- `./Dashboard` — loaded by the shell as the main content view +- `./Settings` — bare settings panel loaded inside the shell's `SettingsModal` + +### Shared singletons (must match shell exactly) +```typescript +shared: { + react: { singleton: true, requiredVersion: '^18.3.1' }, + 'react-dom': { singleton: true, requiredVersion: '^18.3.1' }, + '@reduxjs/toolkit': { singleton: true, requiredVersion: '^2.5.0' }, + 'react-redux': { singleton: true, requiredVersion: '^9.2.0' }, + '@carbon/react': { singleton: true, requiredVersion: '^1.67.0' }, +} as any // 'as any' required — singleton/requiredVersion typed as commented-out in plugin types +``` + +### Local MF dev +`@originjs/vite-plugin-federation` only generates `remoteEntry.js` on `vite build`, NOT `vite dev`. +For MF local dev: `pnpm --filter @cv-builder/browser-app build && pnpm --filter @cv-builder/browser-app preview` + +**Note**: `@originjs/vite-plugin-federation` 1.4.1 is the latest release and the plugin appears unmaintained. Per-chunk minification is not supported. Long-term, migration to Vite's native Module Federation (Vite 6+) is recommended. + +## Deployment (Vercel) + +cv.jim.software (Vercel) — auto-deploys on push to main. +Branch protection: PR required, rebase-only merge (GitHub Ruleset). + +**Cache headers**: `vercel.json` header rules must list specific paths (e.g., `remoteEntry.js` with `no-store`) **before** the catch-all `(.*)` rule. Vercel evaluates later rules with higher priority, so the catch-all must come first to be overridden by specific paths. See commit `9b84f80`. diff --git a/CLAUDE.md b/CLAUDE.md index 3946cf2..fedebdf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,319 +2,54 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +> **Loading discipline (ADR-0081):** this root file is the always-loaded Layer 0 — project identity, the command quick-start, and must-keep invariants (security, deployment safety). Deeper material is routed out: agent authoring → `packages/agent-core/CLAUDE.md`; Module Federation + Vercel deploy → `.claude/rules/mf-and-deploy.md` (auto-loads when editing the MF surface); env/tooling/ESLint/hooks + architecture detail → `docs/claude-reference.md`; canonical architecture narrative → `docs/ARCHITECTURE.md`. + ## Project Overview -Resume Builder is an AI-powered resume and career development tool that uses Claude AI agents to help users create tailored resumes, prepare for interviews, and develop professional skills. The system uses a **secure client-server architecture** with a multi-agent system where specialized agents run server-side and communicate with the browser through a REST API. +Resume Builder is an AI-powered resume and career development tool that uses Claude AI agents to help users create tailored resumes, prepare for interviews, and develop professional skills. The system uses a **secure client-server architecture** with a multi-agent system where specialized agents run **server-side only** and communicate with the browser through a REST API. -**Key Architecture Changes** (as of latest update): -- All agents now run **server-side only** via a new Express API (`packages/api/`) -- API keys are stored securely in `env.json` on the server (never exposed to browser) -- Browser app communicates through REST API with proper security middleware -- Removed `dangerouslyAllowBrowser` flag from all agents +Invariants (durable): +- All agents run **server-side only** via the Express API (`packages/api/`); the browser never holds API keys. +- API keys live in `env.json` on the server (gitignored, never exposed to the browser). +- No `dangerouslyAllowBrowser` anywhere. -For detailed architecture documentation, see `ARCHITECTURE.md`. +For detailed architecture, see `docs/ARCHITECTURE.md` and `docs/claude-reference.md`. ## Package Manager -This project uses **pnpm** as its package manager. The pnpm version is pinned in the `packageManager` field of `package.json`. The Node version is pinned to LTS via `.nvmrc`. - -### Prerequisites -- Node.js 24.11.1+ (use `fnm use` to switch to the correct version) -- pnpm 9.0.0+ (install via `corepack enable && corepack prepare pnpm@9.15.4 --activate`) — CI reads the version from the `packageManager` field in `package.json`, not the action config -- **Optional**: `uv` (Python package manager) — required to use the AWS Documentation MCP server in Claude Code. Install from https://docs.astral.sh/uv/. Copy `.mcp.json.example` (when available) or create `.mcp.json` locally with `{"mcpServers":{"aws-documentation":{"command":"uvx","args":["awslabs.aws-documentation-mcp-server@1.1.18"]}}}`. The `.mcp.json` file is gitignored (personal dev config). +This project uses **pnpm** (version pinned in `package.json`'s `packageManager`; Node pinned via `.nvmrc`). Full prerequisites (Node/pnpm versions, optional `uv` for the AWS MCP server) → `docs/claude-reference.md`. ## Development Commands -### Running the Application - -**Development Mode (Recommended)**: ```bash -# Run both API server and browser app together +# Run API server (3001) + browser app (3000) together pnpm dev:all +# Or separately: +pnpm dev:api # API server (port 3001) +pnpm dev # Browser app (port 3000) + +# CLI +pnpm cli # interactive +pnpm cli:headless -- --job jobs/example.json # headless + +# Build / quality +pnpm build # production build (runs security checks first) +pnpm type-check # type-check without building +pnpm preview # preview production build +pnpm lint # ESLint (@frame/eslint-plugin custom rules) +pnpm lint:fix # ESLint with auto-fix + +# Security +pnpm security:verify # comprehensive audit +pnpm security:scan # scan source for API keys +pnpm security:check # checks used by prebuild ``` -**Alternative - Run services separately**: -```bash -# Terminal 1: API server (port 3001) -pnpm dev:api - -# Terminal 2: Browser app (port 3000) -pnpm dev -``` - -**CLI Mode**: -```bash -# CLI interactive mode -pnpm cli - -# CLI headless mode (requires job file) -pnpm cli:headless -- --job jobs/example.json -``` - -### Build and Type Checking -```bash -# Build for production (TypeScript compilation + Vite build) -# Includes automatic security checks before build -pnpm build - -# Type check without building -pnpm type-check - -# Preview production build -pnpm preview -``` - -### Code Quality & Linting -```bash -# Run ESLint with @frame/eslint-plugin custom rules -pnpm lint - -# Auto-fix where possible -pnpm lint:fix -``` - -The project uses `@frame/eslint-plugin` with custom rules enforcing monorepo safety: -- **`no-source-maps-in-production`** — errors if sourceMap is enabled in production build configs -- **`no-api-keys-in-client`** — errors on API keys or `dangerouslyAllowBrowser` in browser code -- **`enforce-singleton-versions`** — warns on hardcoded versions in Module Federation shared configs -- **`no-cross-package-relative-imports`** — errors on relative imports crossing workspace package boundaries -- **`require-zod-validation-at-boundaries`** — warns if route handlers access `req.body`/`req.params`/`req.query` without Zod validation -- **`no-console-in-production`** — warns on console.log/debug/warn in production source files -- **`no-untyped-schema-fields`** — warns on flat `z.array(z.string())` for enrichable schema fields (see TD-002/TD-003) -- **`require-test-for-new-exports`** — warns when exported functions have no corresponding test file - -A **post-build artifact scanner** (`scripts/artifact-scanner.ts`) runs automatically after `pnpm build` via the `postbuild` hook, scanning `dist/` for `.map` files, `sourceMappingURL` directives, embedded API keys, and debugger statements. - -### Claude Code Hooks - -The project uses Claude Code hooks (`.claude/settings.json`) to integrate ESLint rules as **LLM instructions**: - -- **PreToolUse (`lint-before-edit.sh`)** — Before Claude edits a file, runs ESLint and injects violations as `additionalContext`. Claude sees warnings and fixes them alongside its intended edit. -- **PostToolUse (`lint-after-edit.sh`)** — After editing, compares violation count before/after. Reports regressions (new violations introduced by the edit). -- **PostToolUse (`scan-after-write.sh`)** — Scans files written to `dist/` for source maps, API keys, debugger statements. -- **PostToolUse (`log-skill.sh`)** — Logs skill invocations to `~/.claude/skill-telemetry.jsonl`. - -Global hooks (`~/.claude/settings.json`): -- **PostToolUse (`log-tool-use.sh`)** — Logs all tool calls to `~/.claude/tool-telemetry.jsonl`. -- **SessionStart (`log-session.sh`)** — Logs session metadata to `~/.claude/session-telemetry.jsonl`. -- **UserPromptSubmit (`suggest-skill.sh`)** — Fuzzy-matches prompts to the skill catalog and suggests relevant skills. - -Telemetry analysis: `bash scripts/hooks/../../../core/scripts/analyze-telemetry.sh` - -### Security Commands -```bash -# Run comprehensive security audit -pnpm security:verify - -# Scan for API keys in source code -pnpm security:scan - -# Run security checks (used by prebuild) -pnpm security:check -``` - -## Environment Setup - -### Configuration - -The application supports two configuration methods (env.json is recommended): - -1. **env.json (Recommended)**: Create `packages/agent-core/env.json` with API key and settings (note: the package is now `@cv-builder/agent-core`) - ```bash - cp packages/agent-core/env.json.example packages/agent-core/env.json - # Edit env.json and add your Anthropic API key - ``` - -2. **Legacy .env.local**: Create `.env.local` with `ANTHROPIC_API_KEY` (copy from `.env.example`) - ```bash - cp .env.example .env.local - ``` - -The app uses the Claude Sonnet 4 model (`claude-sonnet-4-20250514`) by default. - -**⚠️ SECURITY WARNING**: NEVER commit `env.json` or `.env.local` to git. These files contain API keys and must remain local only. The repository is configured to automatically prevent this. - -### Security Best Practices - -**Before committing code:** -1. Run `pnpm security:verify` to check for security issues -2. Pre-commit hooks automatically scan for API keys -3. NEVER commit `dist/` or `build/` directories -4. Store all secrets in `env.json` (gitignored) - -**If you accidentally commit a secret:** -1. Immediately rotate the API key at console.anthropic.com -2. Remove the file from git history (see `SECURITY.md`) -3. Report the incident in GitHub issues - -See `SECURITY.md` for comprehensive security documentation. - -### Data Directories - -The application uses a **three-tier storage structure** for organized data management: - -1. **`personal/`** - User data (gitignored, private) - - `bios/` - Uploaded resumes and bio data - - `jobs/` - Job listings - - `output/` - Generated resumes and documents - - `research/` - Research data - -2. **`dev/`** - Mock data for development (tracked in git) - - Contains sample files with the same structure as `personal/` - - Used for consistent testing and development - - See `dev/README.md` for details - -3. **`temp/`** - Ephemeral test files (gitignored) - - Same structure as `personal/` and `dev/` - - Used for temporary testing and experiments - -Example data is in `public/examples/` and `dev/` directories. +ESLint custom-rule catalog, the Claude Code hook wiring, and env setup → `docs/claude-reference.md`. -## Architecture +## Security (must-keep) -### Multi-Agent System - -The codebase uses a **multi-agent architecture** where specialized Claude agents coordinate to handle different tasks: - -1. **Orchestrator Agent** (`packages/agent-core/src/agents/orchestrator-agent.ts`): Coordinates other agents, parses requests, and manages workflow -2. **Resume Generator Agent**: Creates and formats resumes -3. **Job Analysis Agent**: Extracts requirements from job descriptions -4. **Tailoring Agent**: Customizes resumes for specific jobs -5. **Skills Gap Analyzer Agent**: Identifies learning opportunities -6. **Interview Coach Agent**: Prepares cover letters and interview guidance -7. **Research Agent**: Finds best practices and industry trends - -All specialized agents are fully implemented in the agent-core package. - -### Agent Communication Flow -``` -Browser App → API Server → Orchestrator Agent → Specialized Agents (parallel execution) -``` - -All agents extend `BaseAgent` class which provides: -- Anthropic client setup -- Conversation history management -- Streaming and non-streaming chat methods -- System prompt abstraction - -### Monorepo Structure -This project uses a monorepo structure with pnpm workspaces: - -``` -packages/ -├── agent-core/ # @cv-builder/agent-core -│ ├── src/ -│ │ ├── agents/ # Agent implementations (BaseAgent, specialized agents) -│ │ ├── cli/ # Command-line interface -│ │ ├── models/ # Zod schemas and TypeScript types (Bio, Job, Output, Research) -│ │ └── utils/ # Config and file storage utilities (Node.js only) -│ └── package.json -├── api/ # @cv-builder/api -│ ├── src/ -│ │ ├── routes/ # Express API routes for agent operations -│ │ ├── middleware/ # Auth, validation, error handling -│ │ └── services/ # Agent manager for server-side execution -│ └── package.json -├── browser-app/ # @cv-builder/browser-app -│ ├── src/ -│ │ ├── components/ # Dashboard components for Bio, Jobs, Outputs, Chat (container-presenter decomposition) -│ │ ├── services/ # Browser orchestrator -│ │ └── store/ # Redux state management -│ └── package.json -├── tsconfig/ # @frame/tsconfig — shared TypeScript presets -│ ├── base.json # Shared base (ES2022, strict, bundler) -│ ├── node.json # Node.js packages -│ ├── browser.json # Browser/React packages -│ └── node-emit.json # Node packages that emit JS (sourceMap: false) -└── eslint-plugin/ # @frame/eslint-plugin — custom ESLint rules - ├── src/rules/ # 8 custom rules (source maps, API keys, MF singletons, etc.) - ├── tests/ # RuleTester-based test suites - └── package.json -``` - -### Data Models - -All models use **Zod** for runtime validation and type inference, located in `packages/agent-core/src/models/`: - -- **Bio**: Personal info, experiences, education, skills, projects, certifications, publications -- **JobListing**: Job details, requirements, company info -- **Output**: Generated resumes, analyses, learning paths -- **ResearchEntry**: Research findings, industry analysis, company intelligence - -Data stored as JSON files in respective directories (CLI/API) or browser localStorage (browser app). - -### Package Imports - -The monorepo uses package references for cross-package imports: - -```typescript -// Import from agent-core (main exports) -import { BaseAgent, Bio, JobListing } from '@cv-builder/agent-core' - -// Import Node.js-only utilities (server-side) -import { FileStorage } from '@cv-builder/agent-core/utils/file-storage' -import { OrchestratorAgent } from '@cv-builder/agent-core/agents/orchestrator-agent' -``` - -## Agent System - -All specialized agents are now implemented: - -- **Resume Generator** (`resume-generator-agent.ts`): Creates formatted resumes -- **Job Analysis** (`job-analysis-agent.ts`): Analyzes jobs and calculates match scores -- **Tailoring** (`tailoring-agent.ts`): Customizes resumes for specific jobs -- **Skills Gap Analyzer** (`skills-gap-agent.ts`): Creates learning paths -- **Interview Coach** (`interview-coach-agent.ts`): Generates cover letters and interview prep - -The `OrchestratorAgent` coordinates all agents, loads data, and manages workflows. - -**For detailed agent usage instructions, see `docs/AGENTS_GUIDE.md`** - this comprehensive guide includes: -- How to use each agent -- Common workflows (job application package, learning path generation) -- Code examples -- Best practices for system prompts, streaming, and error handling - -## Adding New Agents - -When creating a new agent: - -1. Create a new file in `packages/agent-core/src/agents/` extending `BaseAgent` -2. Implement `getSystemPrompt()` with the agent's role and responsibilities -3. Add public methods for the agent's functionality (use `chat()` or `streamChat()`) -4. Define input/output types in `packages/agent-core/src/models/` with Zod schemas -5. Export the agent from `packages/agent-core/src/index.ts` (if browser-compatible) -6. Integrate with `OrchestratorAgent` for coordination -7. Add API routes in `packages/api/src/routes/` for server-side execution -8. Update `docs/AGENTS_GUIDE.md` with usage examples - -See `docs/how-to/01-building-features.md` and `docs/AGENTS_GUIDE.md` for detailed walkthroughs. - -## Supporting Agents -## Available Agents - -Claude can load and execute specialized agents from `.agents/` directory: - -- `agent:pre-commit` - Run pre-commit validation -- `agent:issue-manager` - Manage GitHub issues -- `agent:pr-manager` - Handle pull requests -- `agent:pr-educator` - Analyze PRs and generate educational senior engineering commentary -- `agent:screenshot-commenter` - Generate test reports with embedded screenshots -- `agent:quality-check` - Run quality validation -- `agent:build-validator` - Validate build configuration - -To use an agent, simply say: "Run the pre-commit validator agent" -or "Use the issue manager agent to create a new issue" -or "Analyze PR #41 with the pr-educator agent" - -## Key Technologies - -- **TypeScript**: Strict mode enabled with ES2022 target -- **React**: For web UI with IBM Carbon Design System (`@carbon/react`) -- **Vite**: Build tool and dev server -- **Anthropic SDK**: Claude API integration -- **Zod**: Runtime schema validation -- **Commander**: CLI argument parsing -- **tsx**: TypeScript execution for CLI +**NEVER commit `env.json` or `.env.local`** — they hold API keys and must remain local (the repo is configured to prevent it). Store all secrets in `env.json` (gitignored). Full security practices + incident response → `docs/claude-reference.md`; `SECURITY.md`. ## Testing Philosophy @@ -324,43 +59,13 @@ The project emphasizes iterative development: Plan → Implement → Test → Re Personal data (bio, jobs, outputs) is gitignored. Only example data in `public/examples/` should be committed. ---- - -## Frame OS Integration - -Resume Builder is a **Module Federation remote** in the Frame OS cluster (see `domain-knowledge/frame-os-context.md`). It exposes a `FrameBeadLike` implementation via `GET /api/beads` (see ADR-0016 / Gas Town Sprint 1), mapping `JobListing` entities to the universal FrameBead shape for ShellAgent consumption. The bead mapper now includes `type`, `created_at`, `updated_at`, and `sourceApp` fields for Mayor compatibility. The AgentBead bridge (ADR-0043) maps Claude Code lifecycle events to Gas Town bead emissions; bead hooks and session coordination are deployed (see commit `7e5d8aa`). The shell's `/api/beads` aggregation uses a Dolt-first strategy with filesystem fallback. - -### MF remote surface area -`packages/browser-app/vite.config.ts` exposes two components: -- `./Dashboard` — loaded by the shell as the main content view -- `./Settings` — bare settings panel loaded inside the shell's `SettingsModal` - -### Shared singletons (must match shell exactly) -```typescript -shared: { - react: { singleton: true, requiredVersion: '^18.3.1' }, - 'react-dom': { singleton: true, requiredVersion: '^18.3.1' }, - '@reduxjs/toolkit': { singleton: true, requiredVersion: '^2.5.0' }, - 'react-redux': { singleton: true, requiredVersion: '^9.2.0' }, - '@carbon/react': { singleton: true, requiredVersion: '^1.67.0' }, -} as any // 'as any' required — singleton/requiredVersion typed as commented-out in plugin types -``` - -### Local MF dev -`@originjs/vite-plugin-federation` only generates `remoteEntry.js` on `vite build`, NOT `vite dev`. -For MF local dev: `pnpm --filter @cv-builder/browser-app build && pnpm --filter @cv-builder/browser-app preview` - -**Note**: `@originjs/vite-plugin-federation` 1.4.1 is the latest release and the plugin appears unmaintained. Per-chunk minification is not supported. Long-term, migration to Vite's native Module Federation (Vite 6+) is recommended. - -### Production deployment -cv.jim.software (Vercel) — auto-deploys on push to main. -Branch protection: PR required, rebase-only merge (GitHub Ruleset). - -**Cache headers**: `vercel.json` header rules must list specific paths (e.g., `remoteEntry.js` with `no-store`) **before** the catch-all `(.*)` rule. Vercel evaluates later rules with higher priority, so the catch-all must come first to be overridden by specific paths. See commit `9b84f80`. - -## Deployment +## Deployment (must-keep) **NEVER deploy directly to production** via CLI (`vercel deploy --prod`, `vercel promote`, etc.). All production deployments go through the GitHub PR → CI → merge → automated deploy pipeline. -The only exception is `workflow_dispatch` for manual CI triggers. -Local Vercel CLI usage is restricted to preview deploys only. +The only exception is `workflow_dispatch` for manual CI triggers. Local Vercel CLI usage is restricted to preview deploys only. MF/Vercel cache-header rules → `.claude/rules/mf-and-deploy.md`. + +## Agents + +- **Authoring a new agent** → `packages/agent-core/CLAUDE.md` (loads when editing that package). +- **Multi-agent system, communication flow, the `.agents/` capability catalog** → `docs/claude-reference.md`. diff --git a/docs/claude-reference.md b/docs/claude-reference.md new file mode 100644 index 0000000..7b2b4f6 --- /dev/null +++ b/docs/claude-reference.md @@ -0,0 +1,241 @@ +# Claude reference — cv-builder + +Deep reference relocated from the root `CLAUDE.md` (ADR-0081 Layer 2 — task reference, not +always-loaded). Repo-wide policy and the command quick-start stay in the root `CLAUDE.md`; +agent-authoring guidance is in `packages/agent-core/CLAUDE.md`; the canonical architecture +narrative is `docs/ARCHITECTURE.md`. This file holds the operational/tooling detail and the +agent/monorepo specifics that `docs/ARCHITECTURE.md` does not cover. + +## Prerequisites (full) + +- Node.js 24.11.1+ (use `fnm use` to switch to the correct version) +- pnpm 9.0.0+ (install via `corepack enable && corepack prepare pnpm@9.15.4 --activate`) — CI reads the version from the `packageManager` field in `package.json`, not the action config +- **Optional**: `uv` (Python package manager) — required to use the AWS Documentation MCP server in Claude Code. Install from https://docs.astral.sh/uv/. Copy `.mcp.json.example` (when available) or create `.mcp.json` locally with `{"mcpServers":{"aws-documentation":{"command":"uvx","args":["awslabs.aws-documentation-mcp-server@1.1.18"]}}}`. The `.mcp.json` file is gitignored (personal dev config). + +## ESLint custom rules + +The project uses `@frame/eslint-plugin` with custom rules enforcing monorepo safety: +- **`no-source-maps-in-production`** — errors if sourceMap is enabled in production build configs +- **`no-api-keys-in-client`** — errors on API keys or `dangerouslyAllowBrowser` in browser code +- **`enforce-singleton-versions`** — warns on hardcoded versions in Module Federation shared configs +- **`no-cross-package-relative-imports`** — errors on relative imports crossing workspace package boundaries +- **`require-zod-validation-at-boundaries`** — warns if route handlers access `req.body`/`req.params`/`req.query` without Zod validation +- **`no-console-in-production`** — warns on console.log/debug/warn in production source files +- **`no-untyped-schema-fields`** — warns on flat `z.array(z.string())` for enrichable schema fields (see TD-002/TD-003) +- **`require-test-for-new-exports`** — warns when exported functions have no corresponding test file + +A **post-build artifact scanner** (`scripts/artifact-scanner.ts`) runs automatically after `pnpm build` via the `postbuild` hook, scanning `dist/` for `.map` files, `sourceMappingURL` directives, embedded API keys, and debugger statements. + +## Claude Code Hooks + +The project uses Claude Code hooks (`.claude/settings.json`) to integrate ESLint rules as **LLM instructions**: + +- **PreToolUse (`lint-before-edit.sh`)** — Before Claude edits a file, runs ESLint and injects violations as `additionalContext`. Claude sees warnings and fixes them alongside its intended edit. +- **PostToolUse (`lint-after-edit.sh`)** — After editing, compares violation count before/after. Reports regressions (new violations introduced by the edit). +- **PostToolUse (`scan-after-write.sh`)** — Scans files written to `dist/` for source maps, API keys, debugger statements. +- **PostToolUse (`log-skill.sh`)** — Logs skill invocations to `~/.claude/skill-telemetry.jsonl`. + +Global hooks (`~/.claude/settings.json`): +- **PostToolUse (`log-tool-use.sh`)** — Logs all tool calls to `~/.claude/tool-telemetry.jsonl`. +- **SessionStart (`log-session.sh`)** — Logs session metadata to `~/.claude/session-telemetry.jsonl`. +- **UserPromptSubmit (`suggest-skill.sh`)** — Fuzzy-matches prompts to the skill catalog and suggests relevant skills. + +Telemetry analysis: `bash scripts/hooks/../../../core/scripts/analyze-telemetry.sh` + +## Security commands + +```bash +# Run comprehensive security audit +pnpm security:verify + +# Scan for API keys in source code +pnpm security:scan + +# Run security checks (used by prebuild) +pnpm security:check +``` + +## Environment Setup + +### Configuration + +The application supports two configuration methods (env.json is recommended): + +1. **env.json (Recommended)**: Create `packages/agent-core/env.json` with API key and settings (note: the package is now `@cv-builder/agent-core`) + ```bash + cp packages/agent-core/env.json.example packages/agent-core/env.json + # Edit env.json and add your Anthropic API key + ``` + +2. **Legacy .env.local**: Create `.env.local` with `ANTHROPIC_API_KEY` (copy from `.env.example`) + ```bash + cp .env.example .env.local + ``` + +The app uses the Claude Sonnet 4 model (`claude-sonnet-4-20250514`) by default. + +**⚠️ SECURITY WARNING**: NEVER commit `env.json` or `.env.local` to git. These files contain API keys and must remain local only. The repository is configured to automatically prevent this. + +### Security Best Practices + +**Before committing code:** +1. Run `pnpm security:verify` to check for security issues +2. Pre-commit hooks automatically scan for API keys +3. NEVER commit `dist/` or `build/` directories +4. Store all secrets in `env.json` (gitignored) + +**If you accidentally commit a secret:** +1. Immediately rotate the API key at console.anthropic.com +2. Remove the file from git history (see `SECURITY.md`) +3. Report the incident in GitHub issues + +See `SECURITY.md` for comprehensive security documentation. + +### Data Directories + +The application uses a **three-tier storage structure** for organized data management: + +1. **`personal/`** - User data (gitignored, private) + - `bios/` - Uploaded resumes and bio data + - `jobs/` - Job listings + - `output/` - Generated resumes and documents + - `research/` - Research data + +2. **`dev/`** - Mock data for development (tracked in git) + - Contains sample files with the same structure as `personal/` + - Used for consistent testing and development + - See `dev/README.md` for details + +3. **`temp/`** - Ephemeral test files (gitignored) + - Same structure as `personal/` and `dev/` + - Used for temporary testing and experiments + +Example data is in `public/examples/` and `dev/` directories. + +## Architecture detail + +### Multi-Agent System + +The codebase uses a **multi-agent architecture** where specialized Claude agents coordinate to handle different tasks: + +1. **Orchestrator Agent** (`packages/agent-core/src/agents/orchestrator-agent.ts`): Coordinates other agents, parses requests, and manages workflow +2. **Resume Generator Agent**: Creates and formats resumes +3. **Job Analysis Agent**: Extracts requirements from job descriptions +4. **Tailoring Agent**: Customizes resumes for specific jobs +5. **Skills Gap Analyzer Agent**: Identifies learning opportunities +6. **Interview Coach Agent**: Prepares cover letters and interview guidance +7. **Research Agent**: Finds best practices and industry trends + +All specialized agents are fully implemented in the agent-core package. + +### Agent Communication Flow +``` +Browser App → API Server → Orchestrator Agent → Specialized Agents (parallel execution) +``` + +All agents extend `BaseAgent` class which provides: +- Anthropic client setup +- Conversation history management +- Streaming and non-streaming chat methods +- System prompt abstraction + +### Monorepo Structure +This project uses a monorepo structure with pnpm workspaces: + +``` +packages/ +├── agent-core/ # @cv-builder/agent-core +│ ├── src/ +│ │ ├── agents/ # Agent implementations (BaseAgent, specialized agents) +│ │ ├── cli/ # Command-line interface +│ │ ├── models/ # Zod schemas and TypeScript types (Bio, Job, Output, Research) +│ │ └── utils/ # Config and file storage utilities (Node.js only) +│ └── package.json +├── api/ # @cv-builder/api +│ ├── src/ +│ │ ├── routes/ # Express API routes for agent operations +│ │ ├── middleware/ # Auth, validation, error handling +│ │ └── services/ # Agent manager for server-side execution +│ └── package.json +├── browser-app/ # @cv-builder/browser-app +│ ├── src/ +│ │ ├── components/ # Dashboard components for Bio, Jobs, Outputs, Chat (container-presenter decomposition) +│ │ ├── services/ # Browser orchestrator +│ │ └── store/ # Redux state management +│ └── package.json +├── tsconfig/ # @frame/tsconfig — shared TypeScript presets +│ ├── base.json # Shared base (ES2022, strict, bundler) +│ ├── node.json # Node.js packages +│ ├── browser.json # Browser/React packages +│ └── node-emit.json # Node packages that emit JS (sourceMap: false) +└── eslint-plugin/ # @frame/eslint-plugin — custom ESLint rules + ├── src/rules/ # 8 custom rules (source maps, API keys, MF singletons, etc.) + ├── tests/ # RuleTester-based test suites + └── package.json +``` + +### Data Models + +All models use **Zod** for runtime validation and type inference, located in `packages/agent-core/src/models/`: + +- **Bio**: Personal info, experiences, education, skills, projects, certifications, publications +- **JobListing**: Job details, requirements, company info +- **Output**: Generated resumes, analyses, learning paths +- **ResearchEntry**: Research findings, industry analysis, company intelligence + +Data stored as JSON files in respective directories (CLI/API) or browser localStorage (browser app). + +### Package Imports + +The monorepo uses package references for cross-package imports: + +```typescript +// Import from agent-core (main exports) +import { BaseAgent, Bio, JobListing } from '@cv-builder/agent-core' + +// Import Node.js-only utilities (server-side) +import { FileStorage } from '@cv-builder/agent-core/utils/file-storage' +import { OrchestratorAgent } from '@cv-builder/agent-core/agents/orchestrator-agent' +``` + +## Agent System (implemented) + +All specialized agents are now implemented: + +- **Resume Generator** (`resume-generator-agent.ts`): Creates formatted resumes +- **Job Analysis** (`job-analysis-agent.ts`): Analyzes jobs and calculates match scores +- **Tailoring** (`tailoring-agent.ts`): Customizes resumes for specific jobs +- **Skills Gap Analyzer** (`skills-gap-agent.ts`): Creates learning paths +- **Interview Coach** (`interview-coach-agent.ts`): Generates cover letters and interview prep + +The `OrchestratorAgent` coordinates all agents, loads data, and manages workflows. + +**For detailed agent usage instructions, see `docs/AGENTS_GUIDE.md`** - this comprehensive guide includes: +- How to use each agent +- Common workflows (job application package, learning path generation) +- Code examples +- Best practices for system prompts, streaming, and error handling + +## Available Agents (`.agents/` directory) + +Claude can load and execute specialized agents from `.agents/` directory: + +- `agent:pre-commit` - Run pre-commit validation +- `agent:issue-manager` - Manage GitHub issues +- `agent:pr-manager` - Handle pull requests +- `agent:pr-educator` - Analyze PRs and generate educational senior engineering commentary +- `agent:screenshot-commenter` - Generate test reports with embedded screenshots +- `agent:quality-check` - Run quality validation +- `agent:build-validator` - Validate build configuration + +To use an agent, simply say: "Run the pre-commit validator agent" or "Use the issue manager agent to create a new issue" or "Analyze PR #41 with the pr-educator agent" + +## Key Technologies + +- **TypeScript**: Strict mode enabled with ES2022 target +- **React**: For web UI with IBM Carbon Design System (`@carbon/react`) +- **Vite**: Build tool and dev server +- **Anthropic SDK**: Claude API integration +- **Zod**: Runtime schema validation +- **Commander**: CLI argument parsing +- **tsx**: TypeScript execution for CLI diff --git a/packages/agent-core/CLAUDE.md b/packages/agent-core/CLAUDE.md new file mode 100644 index 0000000..1bec7dc --- /dev/null +++ b/packages/agent-core/CLAUDE.md @@ -0,0 +1,30 @@ +# agent-core — agent authoring guidance + +Path-conditional guidance (ADR-0081 Layer 1): loads when editing the `packages/agent-core/` +package. Repo-wide policy is in the root `CLAUDE.md`; deep architecture reference is in +`docs/ARCHITECTURE.md` and `docs/claude-reference.md`. + +All specialized agents extend `BaseAgent`, which provides Anthropic client setup, conversation +history management, streaming/non-streaming chat methods, and system-prompt abstraction. Agents +run **server-side only** (never in the browser; no `dangerouslyAllowBrowser`). + +## Adding New Agents + +When creating a new agent: + +1. Create a new file in `packages/agent-core/src/agents/` extending `BaseAgent` +2. Implement `getSystemPrompt()` with the agent's role and responsibilities +3. Add public methods for the agent's functionality (use `chat()` or `streamChat()`) +4. Define input/output types in `packages/agent-core/src/models/` with Zod schemas +5. Export the agent from `packages/agent-core/src/index.ts` (if browser-compatible) +6. Integrate with `OrchestratorAgent` for coordination +7. Add API routes in `packages/api/src/routes/` for server-side execution +8. Update `docs/AGENTS_GUIDE.md` with usage examples + +See `docs/how-to/01-building-features.md` and `docs/AGENTS_GUIDE.md` for detailed walkthroughs. + +## Models + +Data models use **Zod** for runtime validation and type inference, in +`packages/agent-core/src/models/` (Bio, JobListing, Output, ResearchEntry). Data is stored as JSON +files (CLI/API) or browser localStorage (browser app). Full schema detail: `docs/ARCHITECTURE.md`.