diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6992c48 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,54 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + quality: + name: Node.js ${{ matrix.node-version }} + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + node-version: + - 22 + - 24 + + steps: + - name: Check out repository + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + run_install: false + + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Type-check and test + run: pnpm check + + - name: Build package + run: pnpm build diff --git a/CHANGELOG.md b/CHANGELOG.md index 2213d30..0fa7d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to ContextPilot are documented here. +## Unreleased + +### Added + +- GitHub Actions continuous integration for Node.js 22 and 24, running + type-checking, tests, and production builds on pull requests and `main` + ## 0.1.0 - 2026-07-28 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0adfea..2cfc724 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -216,6 +216,16 @@ pnpm release:check pnpm release:rehearse ``` +### Continuous integration + +The `CI` GitHub Actions workflow runs for pull requests, pushes to `main`, and +manual dispatches. It executes `pnpm check` and `pnpm build` against Node.js 22 +and 24 with `pnpm install --frozen-lockfile`. + +All matrix jobs must pass before merging. When a CI failure is platform- or +version-specific, reproduce it with the corresponding supported Node.js major +instead of weakening the matrix or marking the job as allowed to fail. + ## Commits Write imperative, specific commit subjects. Conventional Commit prefixes are diff --git a/README.md b/README.md index af40cda..ac6dac2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # ContextPilot +[![CI](https://github.com/opencorex-org/context-pilot/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/opencorex-org/context-pilot/actions/workflows/ci.yml) + ContextPilot is a local-first context optimizer for coding agents. It indexes a repository, ranks files and symbols for a task, reuses cached summaries, and compiles a compact Markdown context bundle that fits a configurable token @@ -18,8 +20,12 @@ budget. - Symbol-level excerpts instead of whole large files - Hierarchical `AGENTS.md` discovery - Budgeted Markdown context bundles and usage reports +- Remaining-budget, utilization, overage, and pressure-status estimates +- Stage-by-stage savings for symbol extraction and optional compact compression +- Actionable optimization hints when a bundle is near or over its budget - Per-task and cumulative estimated token-reduction history - Git diff context for pull-request review +- Opt-in published-version checks and global CLI updates - Optional MCP server exposing `prepare_context`, `index_repository`, and `diff_context` @@ -36,6 +42,8 @@ service. important modules, development, and testing - [Architecture](docs/ARCHITECTURE.md) — boundaries, data flow, design decisions, privacy, reliability, and extension points +- [Product roadmap](docs/ROADMAP.md) — strategic product vision, architectural + milestones, and planned deliverables - [Contributing](CONTRIBUTING.md) — development workflow, standards, tests, and pull-request expectations - [Security policy](SECURITY.md) — supported versions and private reporting @@ -78,11 +86,17 @@ pnpm context-pilot --help # Build or refresh the local index. pnpm context-pilot index -# Prepare a context bundle for a coding task. +# Prepare a context bundle for a coding task with skill options. pnpm context-pilot prepare \ --task "Fix duplicate invoice numbers under concurrent requests" \ + --skill bugfix \ --budget 12000 +# Convert a raw prompt into a structured task prompt. +pnpm context-pilot convert-prompt \ + --task "Improve summary index performance" \ + --skill perf + # Produce review context for a branch. pnpm context-pilot diff-context main...HEAD --budget 16000 @@ -91,12 +105,17 @@ pnpm context-pilot stats # Compare estimated usage across recent tasks. pnpm context-pilot history --limit 20 + +# Check whether a newer release is available (global installs). +context-pilot update --check ``` `prepare` writes a file under `.context-pilot/tasks/` and prints a usage estimate. The generated prompt tells the coding agent which files and symbols matter, preserves applicable repository instructions, and identifies content -that was omitted to stay within budget. +that was omitted to stay within budget. Usage output also reports the estimated +budget utilization and remaining capacity. Use `--compact` when a bundle is +near its limit to remove comments and repeated blank lines from code excerpts. ## Connect to the Codex app @@ -136,7 +155,7 @@ Use ContextPilot to prepare focused context for this task before exploring the repository: fix duplicate invoice-number generation under concurrency. ``` -ContextPilot exposes `prepare_context`, `index_repository`, `diff_context`, and +ContextPilot exposes `prepare_context`, `convert_prompt`, `index_repository`, `diff_context`, and `context_stats`, plus `context_history`. Its MCP instructions encourage Codex to prepare focused context before broad repository exploration. @@ -156,6 +175,9 @@ context-pilot index [--root PATH] [--json] ```bash context-pilot prepare \ --task "Add refund approval workflow" \ + [--skill bugfix|refactor|feature|test|security|perf|docs|architecture|auto] \ + [--refine-prompt] \ + [--compact] \ [--budget 12000] \ [--root PATH] \ [--output PATH] \ @@ -164,13 +186,24 @@ context-pilot prepare \ Context priority is: -1. Task +1. Task & Active Skills 2. Applicable `AGENTS.md` instructions 3. Current Git changes 4. Matching symbols and source excerpts 5. Tests 6. Compact file summaries +### `context-pilot convert-prompt` + +Converts a raw task prompt into an enhanced, structured prompt with skill guidelines and verification criteria: + +```bash +context-pilot convert-prompt \ + --task "Fix memory leakage during large file indexing" \ + [--skill perf,bugfix] \ + [--json] +``` + ### `context-pilot diff-context` ```bash @@ -228,6 +261,48 @@ measurement of what Codex would actually have loaded. “With ContextPilot” is the estimated size of the generated task bundle. ContextPilot cannot observe Codex’s hidden context, prompt cache, output tokens, or billing. +### `context-pilot update` + +Version checks and updates are explicit and opt-in. ContextPilot never contacts +the npm registry in the background, preserving its local-first default. + +Check for a new published release without changing the installation: + +```bash +context-pilot update --check +``` + +Install the latest release with the same package manager used for the global +installation: + +```bash +# npm global installation (default) +context-pilot update + +# pnpm global installation +context-pilot update --package-manager pnpm +``` + +For scripts and tooling, add `--json` to either form: + +```bash +context-pilot update --check --json +context-pilot update --json +``` + +The updater reads the current version from the installed package metadata, then +reads the latest `codex-context-pilot` version from the npm registry. It +installs only when that version is newer, pins the exact version observed by +the check, and never changes repository files or `.context-pilot/` data. +Restart the Codex app or any running MCP server after an update. + +If the package manager reports a global-install permission error, fix the +global npm/pnpm directory ownership or configuration and run the command again. +Avoid running ContextPilot itself with elevated privileges. The update command +updates a globally installed CLI; it does not update a source checkout. For a +checkout, use the development workflow below (`git pull`, `pnpm install`, and +`pnpm build`). + ## Generated data ContextPilot writes only to `.context-pilot/` in the target repository: @@ -269,6 +344,10 @@ pnpm release:check npm run release:rehearse ``` +GitHub Actions runs `pnpm check` and `pnpm build` on Node.js 22 and 24 for +pull requests and pushes to `main`. The workflow uses the frozen pnpm lockfile +and can also be started manually. + ## Releasing The npm package name is `codex-context-pilot`, while its global executable diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index 034c902..86d7ddf 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node import { resolve } from "node:path"; import { execFile } from "node:child_process"; -import { realpathSync } from "node:fs"; +import { readFileSync, realpathSync } from "node:fs"; import { access } from "node:fs/promises"; import { homedir } from "node:os"; import { pathToFileURL } from "node:url"; @@ -10,10 +10,34 @@ import { repositoryStats, prepareContext, taskHistory, + convertPrompt, + AVAILABLE_SKILL_NAMES, + SKILL_PRESETS, } from "../../../packages/core/src/index.js"; import { indexRepository } from "../../../packages/indexer/src/index.js"; const execFileAsync = promisify(execFile); +const PACKAGE_NAME = "codex-context-pilot"; + +function installedPackageVersion(): string { + const candidates = [ + new URL("../../../../package.json", import.meta.url), + new URL("../../../package.json", import.meta.url), + ]; + for (const candidate of candidates) { + try { + const manifest = JSON.parse(readFileSync(candidate, "utf8")) as { version?: unknown }; + if (typeof manifest.version === "string") return manifest.version; + } catch { + // Try the next layout: built package first, source checkout second. + } + } + throw new Error("Could not read the installed ContextPilot package version."); +} + +const CURRENT_VERSION = installedPackageVersion(); + +type PackageManager = "npm" | "pnpm"; interface ParsedArguments { command?: string; @@ -67,10 +91,13 @@ function printHelp(): void { Usage: context-pilot index [--root PATH] [--json] - context-pilot prepare --task TEXT [--budget 12000] [--output PATH] [--json] + context-pilot prepare --task TEXT [--skill NAME] [--refine-prompt] [--compact] [--budget 12000] [--output PATH] [--json] + context-pilot convert-prompt --task TEXT [--skill NAME] [--json] context-pilot diff-context [BASE...HEAD] [--budget 16000] [--output PATH] [--json] context-pilot stats [--root PATH] [--json] context-pilot history [--root PATH] [--limit 20] [--json] + context-pilot update --check [--package-manager npm|pnpm] [--json] + context-pilot update [--package-manager npm|pnpm] [--json] context-pilot mcp context-pilot codex install context-pilot codex status @@ -79,15 +106,148 @@ Usage: Options: --root PATH Repository root (default: current directory) --task TEXT Developer task to optimize context for + --skill NAME Apply skill option (${AVAILABLE_SKILL_NAMES.join(", ")}, auto) + --refine-prompt Convert prompt into enhanced task prompt using selected/auto skills + --compact Enable high-density code compression (strips comments & blank lines) --budget TOKENS Maximum estimated bundle size --output PATH Output Markdown path --max-files N Maximum candidates before budget compilation --limit N Number of task-history records to show + --check Check for a newer published version without installing it + --package-manager Package manager used for global updates (npm or pnpm; default: npm) --json Emit machine-readable output --help Show this help --version Show the installed version`); } +function parseVersion(value: string): { core: number[]; prerelease?: string } { + const match = value.trim().match(/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/); + if (!match) throw new Error(`Invalid published version: ${value}`); + const core = match.slice(1, 4).map((part) => Number.parseInt(part ?? "0", 10)); + return { core, ...(match[4] ? { prerelease: match[4] } : {}) }; +} + +export function compareVersions(left: string, right: string): number { + const leftVersion = parseVersion(left); + const rightVersion = parseVersion(right); + for (let index = 0; index < 3; index += 1) { + const difference = (leftVersion.core[index] ?? 0) - (rightVersion.core[index] ?? 0); + if (difference !== 0) return Math.sign(difference); + } + if (leftVersion.prerelease === rightVersion.prerelease) return 0; + if (!leftVersion.prerelease) return 1; + if (!rightVersion.prerelease) return -1; + const leftParts = leftVersion.prerelease.split("."); + const rightParts = rightVersion.prerelease.split("."); + for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) { + const leftPart = leftParts[index]; + const rightPart = rightParts[index]; + if (leftPart === undefined) return -1; + if (rightPart === undefined) return 1; + if (leftPart === rightPart) continue; + const leftNumeric = /^\d+$/.test(leftPart); + const rightNumeric = /^\d+$/.test(rightPart); + if (leftNumeric && rightNumeric) { + return Math.sign(Number.parseInt(leftPart, 10) - Number.parseInt(rightPart, 10)); + } + if (leftNumeric) return -1; + if (rightNumeric) return 1; + return Math.sign(leftPart.localeCompare(rightPart)); + } + return 0; +} + +function packageManagerFlag(args: ParsedArguments): PackageManager { + const value = stringFlag(args, "package-manager") ?? "npm"; + if (value !== "npm" && value !== "pnpm") { + throw new Error("--package-manager must be npm or pnpm"); + } + return value; +} + +async function publishedVersion(packageManager: PackageManager): Promise { + const { stdout } = await execFileAsync( + packageManager, + ["view", PACKAGE_NAME, "version"], + { encoding: "utf8" }, + ); + const version = stdout.trim().replace(/^['\"]|['\"]$/g, ""); + parseVersion(version); + return version; +} + +async function runUpdate(args: ParsedArguments, json: boolean): Promise { + const packageManager = packageManagerFlag(args); + let latestVersion: string; + try { + latestVersion = await publishedVersion(packageManager); + } catch (error) { + const detail = + error && typeof error === "object" && "stderr" in error + ? String(error.stderr).trim() + : error instanceof Error + ? error.message + : String(error); + throw new Error(`Could not check the npm registry. ${detail}`); + } + + const comparison = compareVersions(CURRENT_VERSION, latestVersion); + const updateAvailable = comparison < 0; + if (args.flags.has("check") || !updateAvailable) { + const status = comparison > 0 ? "local-newer" : updateAvailable ? "update-available" : "up-to-date"; + if (json) { + console.log(JSON.stringify({ + package: PACKAGE_NAME, + currentVersion: CURRENT_VERSION, + latestVersion, + updateAvailable, + status, + }, null, 2)); + } else if (status === "update-available") { + console.log(`Update available: ${CURRENT_VERSION} → ${latestVersion}`); + console.log(`Run: context-pilot update --package-manager ${packageManager}`); + } else if (status === "local-newer") { + console.log(`Local version ${CURRENT_VERSION} is newer than published version ${latestVersion}.`); + } else { + console.log(`ContextPilot ${CURRENT_VERSION} is up to date.`); + } + return; + } + + const installArgs = packageManager === "npm" + ? ["install", "--global", `${PACKAGE_NAME}@${latestVersion}`] + : ["add", "--global", `${PACKAGE_NAME}@${latestVersion}`]; + try { + const { stdout, stderr } = await execFileAsync(packageManager, installArgs, { + encoding: "utf8", + }); + if (!json && stdout.trim()) console.log(stdout.trim()); + if (!json && stderr.trim()) console.error(stderr.trim()); + } catch (error) { + const detail = + error && typeof error === "object" && "stderr" in error + ? String(error.stderr).trim() + : error instanceof Error + ? error.message + : String(error); + throw new Error( + `Update failed with ${packageManager}. Check your global package-manager permissions. ${detail}`, + ); + } + if (json) { + console.log(JSON.stringify({ + package: PACKAGE_NAME, + previousVersion: CURRENT_VERSION, + installedVersion: latestVersion, + packageManager, + status: "updated", + }, null, 2)); + } else { + console.log(`ContextPilot updated: ${CURRENT_VERSION} → ${latestVersion}`); + console.log("Restart any running ContextPilot MCP server or the Codex app to use the new version."); + } +} + function printCodexConfig(): void { console.log(`[mcp_servers.context-pilot] command = "context-pilot" @@ -181,6 +341,9 @@ enabled = true`; function reportPrepare(result: Awaited>): void { console.log(`Context bundle: ${result.outputPath}`); + if (result.appliedSkills?.length) { + console.log(`Applied skills: ${result.appliedSkills.join(", ")}`); + } console.log(`Selected files: ${result.selected.length}`); console.log(`Changed files: ${result.changedFiles.length}`); console.log( @@ -195,6 +358,23 @@ function reportPrepare(result: Awaited>): void console.log( `Estimated reduction: ${result.usage.estimatedContextReductionPercent.toFixed(1)}%`, ); + console.log( + `Budget: ~${result.usage.estimatedTotalInputTokens.toLocaleString()} / ${result.usage.budget.toLocaleString()} tokens (${result.usage.budgetUtilizationPercent.toFixed(1)}%, ${result.usage.budgetStatus})`, + ); + if (result.usage.budgetOverageTokens > 0) { + console.log(`Estimated over budget: ~${result.usage.budgetOverageTokens.toLocaleString()} tokens`); + } else { + console.log(`Estimated remaining: ~${result.usage.budgetRemainingTokens.toLocaleString()} tokens`); + } + console.log( + `Symbol extraction saved: ~${result.usage.symbolExtractionTokensSaved.toLocaleString()} tokens (${result.usage.symbolExtractionReductionPercent.toFixed(1)}%)`, + ); + if (result.usage.compressionTokensSaved > 0) { + console.log( + `Compact compression saved: ~${result.usage.compressionTokensSaved.toLocaleString()} tokens (${result.usage.compressionReductionPercent.toFixed(1)}%)`, + ); + } + for (const hint of result.usage.optimizationHints) console.log(`Tip: ${hint}`); console.log( `Index: ${result.index.updated} updated, ${result.index.reused} reused, ${result.index.skipped} skipped`, ); @@ -206,7 +386,7 @@ async function run(argv = process.argv.slice(2)): Promise { return; } if (argv[0] === "--version" || argv[0] === "-v") { - console.log("0.1.0"); + console.log(CURRENT_VERSION); return; } const args = parseArguments(argv); @@ -231,11 +411,19 @@ async function run(argv = process.argv.slice(2)): Promise { const task = stringFlag(args, "task") ?? args.positional.join(" "); if (!task) throw new Error("prepare requires --task \"...\""); const output = stringFlag(args, "output"); + const rawSkills = stringFlag(args, "skill"); + const skills = rawSkills ? rawSkills.split(",").map((s) => s.trim()) : undefined; + const refinePrompt = args.flags.has("refine-prompt"); + const compact = args.flags.has("compact"); + const result = await prepareContext({ root, task, budget: numberFlag(args, "budget", 12_000), maxFiles: numberFlag(args, "max-files", 24), + ...(skills ? { skills } : {}), + ...(refinePrompt ? { refinePrompt: true } : {}), + ...(compact ? { compact: true } : {}), ...(output ? { output } : {}), }); if (json) { @@ -243,6 +431,8 @@ async function run(argv = process.argv.slice(2)): Promise { JSON.stringify( { outputPath: result.outputPath, + appliedSkills: result.appliedSkills, + convertedTask: result.convertedTask, selectedFiles: result.selected.map(({ file, score, reasons }) => ({ path: file.path, score, @@ -265,6 +455,24 @@ async function run(argv = process.argv.slice(2)): Promise { } else reportPrepare(result); return; } + case "refine-prompt": + case "convert-prompt": { + const task = stringFlag(args, "task") ?? args.positional.join(" "); + if (!task) throw new Error("convert-prompt requires --task \"...\""); + const rawSkills = stringFlag(args, "skill"); + const skills = rawSkills ? rawSkills.split(",").map((s) => s.trim()) : undefined; + + const converted = convertPrompt({ task, skills }); + if (json) { + console.log(JSON.stringify(converted, null, 2)); + } else { + console.log(`Original Task: ${converted.originalTask}`); + console.log(`Applied Skills: ${converted.appliedSkills.join(", ") || "none"}\n`); + console.log("--- Converted Task Prompt ---"); + console.log(converted.convertedTask); + } + return; + } case "diff-context": { const range = args.positional[0] ?? "HEAD"; const task = stringFlag(args, "task") ?? `Review changes in ${range}`; @@ -313,7 +521,7 @@ async function run(argv = process.argv.slice(2)): Promise { for (const run of runs) { console.log(`${run.createdAt} ${run.task}`); console.log( - ` without ~${run.estimatedWithoutContextPilotTokens.toLocaleString()} · with ~${run.estimatedWithContextPilotTokens.toLocaleString()} · saved ~${run.estimatedTokensSaved.toLocaleString()} · reduction ${run.estimatedContextReductionPercent.toFixed(1)}%`, + ` without ~${run.estimatedWithoutContextPilotTokens.toLocaleString()} · with ~${run.estimatedWithContextPilotTokens.toLocaleString()} · saved ~${run.estimatedTokensSaved.toLocaleString()} · reduction ${run.estimatedContextReductionPercent.toFixed(1)}% · budget ${run.budgetUtilizationPercent.toFixed(1)}% · remaining ~${run.budgetRemainingTokens.toLocaleString()}`, ); } const without = runs.reduce( @@ -332,6 +540,9 @@ async function run(argv = process.argv.slice(2)): Promise { } return; } + case "update": + await runUpdate(args, json); + return; case "mcp": { const { startMcpServer } = await import("../../../servers/mcp-server/src/index.js"); await startMcpServer(); diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..050608c --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,138 @@ +# ContextPilot Product Roadmap 🚀 + +This document outlines the strategic product vision, architectural milestones, and planned feature deliverables for **ContextPilot** — the local-first context optimizer and prompt compiler for AI coding agents. + +--- + +## 🎯 Vision & Guiding Principles + +ContextPilot bridges developer intent and AI agent context limitations by selecting, compressing, and structuring repository knowledge into high-impact prompt bundles. + +1. **Local-First & Private**: Repository code and metadata remain strictly local on the developer's host machine. +2. **Deterministic & Explainable**: Retrieval and scoring decisions are transparent, reproducible, and accompanied by human-readable ranking reasons. +3. **Token-Budget Aware**: Fits context bundles within configurable token limits, eliminating context window bloat and truncation errors. +4. **Skill-Enriched Prompting**: Transforms raw developer tasks into structured prompts enriched with domain best practices, execution steps, and verification criteria. + +--- + +## 🗺️ Product Roadmap Overview + +```text +Phase 1 (Q3 2026) Phase 2 (Q4 2026) Phase 3 (Q1 2027) Phase 4 (Q2 2027) +├── VS Code Sidebar ├── Tree-Sitter AST ├── Shared Knowledge Base ├── Multi-Repo Monorepos +├── Interactive TUI ├── ONNX Local Embeddings ├── PII & Secret Scrubbing ├── Local Web Dashboard +├── Custom Project Skills ├── Realtime File Watcher ├── Subagent Context Slice├── CI/CD PR Audit Bot +└── Adaptive Auto-Scaler └── Call-Graph Tracing └── LSP Integration └── Agent Benchmarks +``` + +--- + +## Phase 1: IDE Extensions & Developer Experience (Q3 2026) + +Focus: Integrate ContextPilot directly into developers' everyday coding environments with visual tools and customizable rules. + +### 1.1 VS Code Sidebar Extension (`vscode-context-pilot`) +- **Visual Prompt Refiner**: Interactive task prompt entry box with domain skill checkboxes (`bugfix`, `refactor`, `ddd`, `react`, `docker`, etc.). +- **Live Token Allocation Gauge**: Real-time visualization of selected files, symbol excerpts, and total estimated token usage against budget. +- **Context Inspector & Pin Controls**: Easily include, exclude, or pin specific files and symbols before compiling context bundles. +- **One-Click Agent Dispatch**: Directly send compiled context bundles to Codex, Cursor, or Claude Code interfaces. + +### 1.2 Interactive CLI TUI (`context-pilot ui`) +- Terminal user interface built with Ink / Blessed for terminal-native developers. +- Interactive fuzzy-search skill picker, file tree inspection, and budget tuning controls. + +### 1.3 Project-Level Custom Skills (`.context-pilot/skills/`) +- Support local team skill definitions stored in `.context-pilot/skills/*.yml`. +- Allow project teams to define project-specific coding standards, architecture constraints, and verification checklists. + +### 1.4 Adaptive Token Budget Auto-Scaler +- Dynamically calibrate token budget recommendations based on target model context limits (e.g. 8k, 32k, 128k, 200k tokens). +- Prevent model truncation penalties while maximizing relevant code context density. + +--- + +## Phase 2: Deep AST Parsing & Local Intelligence (Q4 2026) + +Focus: Advance from lexical pattern extraction to full syntactic and semantic comprehension of multi-file codebases. + +### 2.1 Native Tree-Sitter AST Parsers +- Replace regex-based symbol extractors with native **Tree-Sitter** parsers. +- Extract 100% precise AST symbol boundaries, type definitions, and class inheritance structures across TypeScript, Go, Python, Rust, Java, C#, and C++. + +### 2.2 Privacy-Preserving Local Embeddings (ONNX / Wasm) +- Add optional, 100% local vector embedding generation (e.g. `nomic-embed-text` or `bge-small` running via ONNX Runtime / WebAssembly). +- Enable hybrid search (Lexical BM25 + Vector Similarity + Git Recency signals) without sending code to third-party cloud embedding APIs. + +### 2.3 Realtime Workspace File Watcher (`context-pilot watch`) +- Background file system daemon watching workspace modifications for instant, millisecond index updates in `.context-pilot/cache.db`. +- Git branch state caching for zero-latency context switching when checking out branches. + +### 2.4 Multi-File Call-Graph & Type Tracing +- Trace upstream callers and downstream callees across import dependency chains. +- Automatically include prerequisite interface and type definitions when a function signature is selected for context compilation. + +--- + +## Phase 3: Shared Team Knowledge, Security & Subagents (Q1 2027) + +Focus: Shared architectural context across development teams, strict security guardrails, and subagent orchestration. + +### 3.1 Shared Team Knowledge Base (`.context-pilot/knowledge/`) +- Option to commit deterministic, version-controlled architecture summaries (`.context-pilot/knowledge/architecture.md`) into Git repositories. +- Provides instant, zero-cost architecture onboarding for new team members and AI agents. + +### 3.2 Local Secret & PII Scrubbing Engine +- Automatic local detection and sanitization of API keys, JWT tokens, DB connection strings, and sensitive PII from context bundles before sending to agents. +- Compliance rules to prevent accidentally leaking private credentials in prompt context. + +### 3.3 Subagent-Specific Context Slicing +- Slice targeted context bundles tailored for specialized subagents (e.g., Backend Subagent bundle, Frontend UI bundle, QA/Test Subagent bundle). +- Optimize subagent token budgets by delivering only domain-relevant code slices. + +### 3.4 Agent Feedback & Relevance Auto-Tuning +- Track task outcome success (e.g., whether generated code passed test suites cleanly). +- Automatically adjust file ranking weights based on historical task success data. + +### 3.5 Language Server Protocol (LSP) Integration +- Connect to background LSPs (`tsserver`, `gopls`, `pyright`, `rust-analyzer`) for exact jump-to-definition and symbol reference resolution. + +--- + +## Phase 4: Enterprise Scale & Local Web Dashboard (Q2 2027) + +Focus: Large-scale microservice monorepos, local web visualization dashboard, and automated CI/CD PR context auditing. + +### 4.1 Local Web Analytics Dashboard (`context-pilot dashboard`) +- Local web interface (`http://localhost:3333`) displaying visual dependency graphs, estimated token savings analytics, task history metrics, and skill usage statistics. + +### 4.2 Multi-Repository Workspace Orchestration +- Cross-repository context preparation for microservice architectures. +- Index dependent packages and shared client libraries across workspace roots. + +### 4.3 CI/CD Context & Documentation Auditor +- GitHub Action bot that audits PR context overhead and flags outdated documentation. +- Automatically generates PR review bundles (`context-pilot diff-context`). + +### 4.4 Agent Retrieval Benchmarking Suite +- Open-source benchmark suite measuring token reduction percentage vs. coding task completion accuracy across open-source repositories. + +--- + +## 📊 Summary Feature Matrix + +| Feature | Target Release | Primary Benefit | Status | +| :--- | :--- | :--- | :--- | +| **Local SQLite Cache** | v0.1.0 | Fast, content-addressed file indexing | ✅ Completed | +| **30+ Skill Presets & Prompt Engine** | v0.1.0 | Converts raw tasks into structured prompts | ✅ Completed | +| **MCP Server (`prepare_context`)** | v0.1.0 | Direct integration with Codex and MCP clients | ✅ Completed | +| **Automatic `.gitignore` Entry** | v0.1.0 | Prevents `.context-pilot/` from being committed | ✅ Completed | +| **VS Code Extension** | Q3 2026 | Visual sidebar & context inspector UI | ⏳ Planned | +| **Adaptive Budget Auto-Scaler** | Q3 2026 | Dynamic token budget calibration per AI model | ⏳ Planned | +| **Tree-Sitter AST Integration** | Q4 2026 | 100% precise symbol boundaries | ⏳ Planned | +| **ONNX Local Embeddings** | Q4 2026 | Local-first hybrid vector search | ⏳ Planned | +| **Realtime File Watcher** | Q4 2026 | Millisecond background index updates | ⏳ Planned | +| **Local Secret & PII Scrubbing** | Q1 2027 | Prevents secret and PII leakage in prompts | ⏳ Planned | +| **Subagent Context Slicing** | Q1 2027 | Tailored context bundles per specialized agent | ⏳ Planned | +| **Shared Team Knowledge Base** | Q1 2027 | Committed architecture summaries | ⏳ Planned | +| **Local Web Dashboard** | Q2 2027 | Visual dependency graphs and token analytics | ⏳ Planned | +| **Multi-Repo Workspace Support** | Q2 2027 | Cross-microservice context bundles | ⏳ Planned | diff --git a/packages/cache/src/index.ts b/packages/cache/src/index.ts index 88e69cd..3ee9c2f 100644 --- a/packages/cache/src/index.ts +++ b/packages/cache/src/index.ts @@ -2,6 +2,7 @@ import { mkdirSync } from "node:fs"; import { dirname, join } from "node:path"; import { DatabaseSync } from "node:sqlite"; import type { CacheStats, FileRecord, TaskRunRecord } from "../../core/src/types.js"; +import { analyzeTokenBudget } from "../../token-estimator/src/index.js"; export class SummaryCache implements Disposable { readonly databasePath: string; @@ -140,18 +141,25 @@ export class SummaryCache implements Disposable { budget: number; selected_files: string; }>; - return rows.map((row) => ({ - id: row.id, - task: row.task, - createdAt: row.created_at, - outputPath: row.output_path, - estimatedWithoutContextPilotTokens: row.without_tokens, - estimatedWithContextPilotTokens: row.with_tokens, - estimatedTokensSaved: row.saved_tokens, - estimatedContextReductionPercent: row.reduction_percent, - budget: row.budget, - selectedFiles: JSON.parse(row.selected_files) as string[], - })); + return rows.map((row) => { + const budget = analyzeTokenBudget(row.with_tokens, row.budget); + return { + id: row.id, + task: row.task, + createdAt: row.created_at, + outputPath: row.output_path, + estimatedWithoutContextPilotTokens: row.without_tokens, + estimatedWithContextPilotTokens: row.with_tokens, + estimatedTokensSaved: row.saved_tokens, + estimatedContextReductionPercent: row.reduction_percent, + budget: row.budget, + selectedFiles: JSON.parse(row.selected_files) as string[], + budgetRemainingTokens: budget.remainingTokens, + budgetOverageTokens: budget.overBudgetTokens, + budgetUtilizationPercent: budget.utilizationPercent, + budgetStatus: budget.status, + }; + }); } close(): void { diff --git a/packages/core/src/gitignore.ts b/packages/core/src/gitignore.ts new file mode 100644 index 0000000..72a35a6 --- /dev/null +++ b/packages/core/src/gitignore.ts @@ -0,0 +1,38 @@ +import { readFile, writeFile } from "node:fs/promises"; +import { join } from "node:path"; + +export async function ensureGitignoreEntry( + root: string, + entry = ".context-pilot/", +): Promise { + const gitignorePath = join(root, ".gitignore"); + let content = ""; + let exists = false; + + try { + content = await readFile(gitignorePath, "utf8"); + exists = true; + } catch { + exists = false; + } + + const lines = content.split(/\r?\n/); + const normalizedEntry = entry.replace(/\/$/, ""); + const alreadyPresent = lines.some((line) => { + const trimmed = line.trim(); + return ( + trimmed === entry || + trimmed === normalizedEntry || + trimmed === `${normalizedEntry}/` + ); + }); + + if (alreadyPresent) { + return false; + } + + const newline = content.length === 0 || content.endsWith("\n") ? "" : "\n"; + const updatedContent = `${content}${newline}${entry}\n`; + await writeFile(gitignorePath, updatedContent, "utf8"); + return true; +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8ecab5f..962d008 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -3,9 +3,10 @@ import { basename, dirname, isAbsolute, join, resolve } from "node:path"; import { SummaryCache } from "../../cache/src/index.js"; import { getChangedFiles, getDiff } from "../../git-analyzer/src/index.js"; import { indexRepository } from "../../indexer/src/index.js"; -import { compilePrompt } from "../../prompt-compiler/src/index.js"; +import { compilePrompt, convertPrompt } from "../../prompt-compiler/src/index.js"; import { retrieveFiles } from "../../retriever/src/index.js"; import { estimateRepositoryTokens } from "../../token-estimator/src/index.js"; +import { analyzeTokenBudget } from "../../token-estimator/src/index.js"; import type { CacheStats, PrepareOptions, @@ -14,6 +15,22 @@ import type { } from "./types.js"; export * from "./types.js"; +export { ensureGitignoreEntry } from "./gitignore.js"; +export { + convertPrompt, + detectSkills, + getSkillDefinition, + getSkillsByCategory, + SKILL_PRESETS, + AVAILABLE_SKILL_NAMES, + ALL_SKILL_DEFINITIONS, + compressExcerpt, +} from "../../prompt-compiler/src/index.js"; +export type { + ConvertPromptOptions, + ConvertPromptResult, + SkillDefinition, +} from "../../prompt-compiler/src/index.js"; function slugify(value: string): string { return ( @@ -63,9 +80,24 @@ export async function prepareContext(options: PrepareOptions): Promise file.path), + budgetRemainingTokens: budgetAnalysis.remainingTokens, + budgetOverageTokens: budgetAnalysis.overBudgetTokens, + budgetUtilizationPercent: budgetAnalysis.utilizationPercent, + budgetStatus: budgetAnalysis.status, }); } finally { historyCache.close(); @@ -132,6 +174,8 @@ export async function prepareContext(options: PrepareOptions): Promise { const started = performance.now(); + await ensureGitignoreEntry(root); const absoluteFiles = await collectFiles(root); const files: FileRecord[] = []; const cache = new SummaryCache(root); diff --git a/packages/prompt-compiler/src/compressor.ts b/packages/prompt-compiler/src/compressor.ts new file mode 100644 index 0000000..f449c0c --- /dev/null +++ b/packages/prompt-compiler/src/compressor.ts @@ -0,0 +1,50 @@ +export function compressExcerpt(code: string): string { + const lines = code.split(/\r?\n/); + const processed: string[] = []; + + let inBlockComment = false; + + for (const rawLine of lines) { + const trimmed = rawLine.trim(); + + if (inBlockComment) { + if (trimmed.includes("*/")) { + inBlockComment = false; + } + continue; + } + + if (trimmed.startsWith("/*") && !trimmed.endsWith("*/")) { + inBlockComment = true; + continue; + } + + if (trimmed.startsWith("/*") && trimmed.endsWith("*/")) { + continue; + } + + if (trimmed.startsWith("//") || trimmed.startsWith("# ")) { + continue; + } + + processed.push(rawLine.trimEnd()); + } + + const collapsed: string[] = []; + let prevEmpty = false; + + for (const line of processed) { + const isEmpty = line.trim().length === 0; + if (isEmpty) { + if (!prevEmpty) { + collapsed.push(""); + prevEmpty = true; + } + } else { + collapsed.push(line); + prevEmpty = false; + } + } + + return collapsed.join("\n").trim(); +} diff --git a/packages/prompt-compiler/src/index.ts b/packages/prompt-compiler/src/index.ts index 088da29..fed88ed 100644 --- a/packages/prompt-compiler/src/index.ts +++ b/packages/prompt-compiler/src/index.ts @@ -1,7 +1,16 @@ import { readFile } from "node:fs/promises"; import { extname, join } from "node:path"; import type { RankedFile, UsageEstimate } from "../../core/src/types.js"; -import { estimateTokens, truncateToTokens } from "../../token-estimator/src/index.js"; +import { + analyzeTokenBudget, + calculateTokenReduction, + estimateTokens, + truncateToTokens, +} from "../../token-estimator/src/index.js"; +import { compressExcerpt } from "./compressor.js"; + +export * from "./skills/index.js"; +export * from "./compressor.js"; export interface CompileInput { root: string; @@ -12,6 +21,8 @@ export interface CompileInput { instructions: Array<{ path: string; content: string }>; repositoryEstimatedTokens: number; diff?: string; + skills?: string[]; + compact?: boolean; } export interface CompileResult { @@ -38,7 +49,10 @@ function fenceFor(path: string): string { } function usageReport(usage: UsageEstimate): string { - return [ + const budgetLine = usage.budgetOverageTokens > 0 + ? `- Budget overage: ${usage.budgetOverageTokens.toLocaleString()} tokens` + : `- Estimated budget remaining: ${usage.budgetRemainingTokens.toLocaleString()} tokens`; + const lines = [ "## Estimated usage", "", "> Estimates only. ContextPilot cannot see the coding agent's internal prompt, cache, or billing.", @@ -48,12 +62,22 @@ function usageReport(usage: UsageEstimate): string { `- Estimated tokens saved: ${usage.estimatedTokensSaved.toLocaleString()} tokens`, `- Estimated reduction: ${usage.estimatedContextReductionPercent.toFixed(1)}%`, "", - `- Raw selected context: ${usage.rawSelectedTokens.toLocaleString()} tokens`, - `- After symbol extraction: ${usage.afterSymbolExtractionTokens.toLocaleString()} tokens`, - `- After summary compression: ${usage.afterSummaryCompressionTokens.toLocaleString()} tokens`, + `- Budget utilization: ${usage.budgetUtilizationPercent.toFixed(1)}% (${usage.budgetStatus})`, + budgetLine, + `- Files included / omitted: ${usage.selectedFileCount} / ${usage.omittedFileCount}`, + "", + "### Reduction stages", + "", + `- Raw selected file content: ${usage.rawSelectedTokens.toLocaleString()} tokens`, + `- After symbol extraction: ${usage.afterSymbolExtractionTokens.toLocaleString()} tokens (saved ${usage.symbolExtractionTokensSaved.toLocaleString()}, ${usage.symbolExtractionReductionPercent.toFixed(1)}%)`, + `- After optional compact compression: ${usage.afterSummaryCompressionTokens.toLocaleString()} tokens (saved ${usage.compressionTokensSaved.toLocaleString()}, ${usage.compressionReductionPercent.toFixed(1)}%)`, `- Instructions: ${usage.instructionTokens.toLocaleString()} tokens`, - `- Budget usage: ${usage.estimatedTotalInputTokens.toLocaleString()} / ${usage.budget.toLocaleString()} tokens`, - ].join("\n"); + `- Final bundle: ${usage.estimatedTotalInputTokens.toLocaleString()} / ${usage.budget.toLocaleString()} tokens`, + ]; + if (usage.optimizationHints.length) { + lines.push("", "### Optimization hints", "", ...usage.optimizationHints.map((hint) => `- ${hint}`)); + } + return lines.join("\n"); } export async function compilePrompt(input: CompileInput): Promise { @@ -70,9 +94,17 @@ export async function compilePrompt(input: CompileInput): Promise (total, content) => total + estimateTokens(content, "code"), 0, ); - const afterSymbolExtractionTokens = input.ranked.reduce( - (total, item) => total + estimateTokens(item.excerpt ?? item.file.summary, "code"), - 0, + const extractedContents = input.ranked.map((item) => item.excerpt ?? item.file.summary); + const afterSymbolExtractionTokens = extractedContents.reduce( + (total, content) => total + estimateTokens(content, "code"), 0, + ); + const compressedContents = input.ranked.map((item, index) => + input.compact && item.excerpt + ? compressExcerpt(extractedContents[index] ?? "") + : extractedContents[index] ?? "", + ); + const afterSummaryCompressionTokens = compressedContents.reduce( + (total, content) => total + estimateTokens(content, "code"), 0, ); const instructionTokens = input.instructions.reduce( (total, instruction) => total + estimateTokens(instruction.content), @@ -85,6 +117,18 @@ export async function compilePrompt(input: CompileInput): Promise "## Task", "", input.task, + ]; + + if (input.skills && input.skills.length > 0) { + headerParts.push( + "", + "## Active Skills", + "", + ...input.skills.map((skill) => `- ${skill}`), + ); + } + + headerParts.push( "", "## Agent guidance", "", @@ -92,7 +136,7 @@ export async function compilePrompt(input: CompileInput): Promise "- Inspect additional repository files only when the bundle is insufficient.", "- Treat excerpts as partial files; preserve surrounding behavior when editing.", "- Run the repository's relevant validation commands after changes.", - ]; + ); if (input.instructions.length) { headerParts.push("", "## Repository instructions", ""); @@ -125,9 +169,8 @@ export async function compilePrompt(input: CompileInput): Promise const sections = [headerParts.join("\n")]; let consumed = estimateTokens(sections[0] ?? ""); - const reserveForReport = 250; + const reserveForReport = Math.min(450, Math.max(300, Math.floor(input.budget * 0.25))); const included: RankedFile[] = []; - let summaryTokens = 0; if (input.diff) { const available = input.budget - consumed - reserveForReport; @@ -150,8 +193,12 @@ export async function compilePrompt(input: CompileInput): Promise "", rankedFile.file.summary, ].join("\n"); - const excerpt = rankedFile.excerpt - ? `\n\n\`\`\`${fenceFor(rankedFile.file.path)}\n${rankedFile.excerpt}\n\`\`\`` + let rawExcerpt = rankedFile.excerpt; + if (rawExcerpt && input.compact) { + rawExcerpt = compressExcerpt(rawExcerpt); + } + const excerpt = rawExcerpt + ? `\n\n\`\`\`${fenceFor(rankedFile.file.path)}\n${rawExcerpt}\n\`\`\`` : ""; let section = `${summary}${excerpt}`; const available = input.budget - consumed - reserveForReport; @@ -160,7 +207,6 @@ export async function compilePrompt(input: CompileInput): Promise sections.push(section); const sectionTokens = estimateTokens(section, "code"); consumed += sectionTokens; - summaryTokens += estimateTokens(summary); included.push(rankedFile); } @@ -173,38 +219,62 @@ export async function compilePrompt(input: CompileInput): Promise const estimatedWithoutContextPilotTokens = input.repositoryEstimatedTokens + estimateTokens(input.task); - const provisionalUsage: UsageEstimate = { - estimatedWithoutContextPilotTokens, - estimatedWithContextPilotTokens: consumed, - estimatedTokensSaved: Math.max(0, estimatedWithoutContextPilotTokens - consumed), - rawSelectedTokens, + const symbolReduction = calculateTokenReduction(rawSelectedTokens, afterSymbolExtractionTokens); + const compressionReduction = calculateTokenReduction( afterSymbolExtractionTokens, - afterSummaryCompressionTokens: summaryTokens, - instructionTokens, - estimatedTotalInputTokens: consumed, - estimatedContextReductionPercent: - estimatedWithoutContextPilotTokens > 0 - ? Math.max(0, (1 - consumed / estimatedWithoutContextPilotTokens) * 100) - : 0, - budget: input.budget, - }; - sections.push(usageReport(provisionalUsage)); - const markdown = `${sections.join("\n\n").trim()}\n`; - const estimatedTotalInputTokens = estimateTokens(markdown, "code"); - const usage = { - ...provisionalUsage, - estimatedWithContextPilotTokens: estimatedTotalInputTokens, - estimatedTokensSaved: Math.max( - 0, - estimatedWithoutContextPilotTokens - estimatedTotalInputTokens, - ), - estimatedTotalInputTokens, - estimatedContextReductionPercent: - estimatedWithoutContextPilotTokens > 0 - ? Math.max(0, (1 - estimatedTotalInputTokens / estimatedWithoutContextPilotTokens) * 100) - : 0, + afterSummaryCompressionTokens, + ); + const createUsage = (totalTokens: number): UsageEstimate => { + const budget = analyzeTokenBudget(totalTokens, input.budget); + const overallReduction = calculateTokenReduction( + estimatedWithoutContextPilotTokens, + totalTokens, + ); + const optimizationHints: string[] = []; + if (budget.status === "over-budget") { + optimizationHints.push("Reduce the task scope, lower `--max-files`, or increase `--budget`."); + } else if ((budget.status === "near-limit" || budget.status === "at-limit") && !input.compact) { + optimizationHints.push("Use `--compact` to remove comments and excess blank lines from excerpts."); + } + if (omitted > 0) { + optimizationHints.push(`${omitted} relevant file${omitted === 1 ? " was" : "s were"} omitted; increase the budget only if that context is needed.`); + } + return { + estimatedWithoutContextPilotTokens, + estimatedWithContextPilotTokens: totalTokens, + estimatedTokensSaved: overallReduction.savedTokens, + rawSelectedTokens, + afterSymbolExtractionTokens, + afterSummaryCompressionTokens, + instructionTokens, + estimatedTotalInputTokens: totalTokens, + estimatedContextReductionPercent: overallReduction.reductionPercent, + budget: input.budget, + budgetRemainingTokens: budget.remainingTokens, + budgetOverageTokens: budget.overBudgetTokens, + budgetUtilizationPercent: budget.utilizationPercent, + budgetStatus: budget.status, + symbolExtractionTokensSaved: symbolReduction.savedTokens, + symbolExtractionReductionPercent: symbolReduction.reductionPercent, + compressionTokensSaved: compressionReduction.savedTokens, + compressionReductionPercent: compressionReduction.reductionPercent, + selectedFileCount: included.length, + omittedFileCount: omitted, + optimizationHints, + }; }; - sections[sections.length - 1] = usageReport(usage); - return { markdown: `${sections.join("\n\n").trim()}\n`, included, usage }; + let estimatedTotalInputTokens = consumed + reserveForReport; + let usage = createUsage(estimatedTotalInputTokens); + let markdown = ""; + for (let pass = 0; pass < 4; pass += 1) { + markdown = `${[...sections, usageReport(usage)].join("\n\n").trim()}\n`; + const measured = estimateTokens(markdown, "code"); + usage = createUsage(measured); + if (measured === estimatedTotalInputTokens) break; + estimatedTotalInputTokens = measured; + } + markdown = `${[...sections, usageReport(usage)].join("\n\n").trim()}\n`; + + return { markdown, included, usage }; } diff --git a/packages/prompt-compiler/src/skills.ts b/packages/prompt-compiler/src/skills.ts new file mode 100644 index 0000000..a265760 --- /dev/null +++ b/packages/prompt-compiler/src/skills.ts @@ -0,0 +1 @@ +export * from "./skills/index.js"; diff --git a/packages/prompt-compiler/src/skills/converter.ts b/packages/prompt-compiler/src/skills/converter.ts new file mode 100644 index 0000000..cd87988 --- /dev/null +++ b/packages/prompt-compiler/src/skills/converter.ts @@ -0,0 +1,80 @@ +import type { ConvertPromptOptions, ConvertPromptResult, SkillDefinition } from "./types.js"; +import { SKILL_PRESETS, detectSkills } from "./registry.js"; + +export function convertPrompt(options: ConvertPromptOptions): ConvertPromptResult { + const originalTask = options.task.trim(); + const requestedSkills = options.skills ?? []; + const selectedSkillsSet = new Set(); + + for (const rawSkill of requestedSkills) { + for (const part of rawSkill.split(",")) { + const trimmed = part.trim().toLowerCase(); + if (trimmed === "auto") { + detectSkills(originalTask).forEach((skill) => selectedSkillsSet.add(skill)); + } else if (SKILL_PRESETS[trimmed]) { + selectedSkillsSet.add(SKILL_PRESETS[trimmed].name); + } + } + } + + if (selectedSkillsSet.size === 0 && options.autoDetect !== false) { + detectSkills(originalTask).forEach((skill) => selectedSkillsSet.add(skill)); + } + + const appliedSkills = Array.from(selectedSkillsSet); + const skillDefs = appliedSkills + .map((name) => SKILL_PRESETS[name]) + .filter((def): def is SkillDefinition => Boolean(def)); + + const skillGuidelines = Array.from( + new Set(skillDefs.flatMap((def) => def.guidelines)), + ); + const executionSteps = Array.from( + new Set(skillDefs.flatMap((def) => def.executionSteps)), + ); + const verificationRules = Array.from( + new Set(skillDefs.flatMap((def) => def.verificationRules)), + ); + + const lines: string[] = [ + `# Enhanced Task: ${originalTask}`, + "", + "## Objective", + originalTask, + ]; + + if (appliedSkills.length > 0) { + lines.push( + "", + "## Applied Skills", + ...appliedSkills.map((skill) => `- **${SKILL_PRESETS[skill]?.label ?? skill}** (${SKILL_PRESETS[skill]?.category ?? "General"})`), + ); + } + + if (skillGuidelines.length > 0) { + lines.push("", "## Skill Guidelines & Constraints", ...skillGuidelines.map((g) => `- ${g}`)); + } + + if (executionSteps.length > 0) { + lines.push("", "## Execution Strategy", ...executionSteps.map((step, idx) => `${idx + 1}. ${step}`)); + } + + if (verificationRules.length > 0) { + lines.push("", "## Verification Criteria", ...verificationRules.map((v) => `- ${v}`)); + } + + if (options.customInstructions && options.customInstructions.trim()) { + lines.push("", "## Additional Instructions", options.customInstructions.trim()); + } + + const convertedTask = lines.join("\n"); + + return { + originalTask, + convertedTask, + appliedSkills, + skillGuidelines, + executionSteps, + verificationRules, + }; +} diff --git a/packages/prompt-compiler/src/skills/definitions/advanced-data.ts b/packages/prompt-compiler/src/skills/definitions/advanced-data.ts new file mode 100644 index 0000000..fda37d3 --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/advanced-data.ts @@ -0,0 +1,42 @@ +import type { SkillDefinition } from "../types.js"; + +export const advancedDataSkills: SkillDefinition[] = [ + { + name: "database-sharding", + label: "Database Sharding & Partitioning", + category: "Advanced Data Engineering", + description: "Design horizontal data sharding strategies, shard key selection, and cross-shard query resolution.", + keywords: ["sharding", "shard", "partitioning", "partition-key", "horizontal-scaling", "distributed-db", "citus"], + guidelines: [ + "Select high-cardinality shard keys to ensure uniform data distribution.", + "Avoid cross-shard join queries wherever possible.", + ], + executionSteps: [ + "Evaluate domain access patterns and select shard key attributes.", + "Implement application shard router or proxy configuration.", + "Write multi-shard scatter-gather query aggregation handlers.", + ], + verificationRules: [ + "Verify query routing to target shard instances and payload aggregation correctness.", + ], + }, + { + name: "cdc-change-data-capture", + label: "Change Data Capture (CDC) & Event Streams", + category: "Advanced Data Engineering", + description: "Stream database commit log mutations in realtime to event buses using Debezium, Kafka, or AWS Kinesis.", + keywords: ["cdc", "change-data-capture", "debezium", "commit-log", "kafka-connect", "wal", "event-streaming"], + guidelines: [ + "Use database transaction logs (WAL/binlog) for zero-impact change extraction.", + "Ensure downstream event consumers process CDC payloads idempotently.", + ], + executionSteps: [ + "Configure database replication parameters and logical decoding slots.", + "Set up Debezium / Kafka Connect connector pipelines.", + "Implement consumer event handlers for cache invalidation or search index sync.", + ], + verificationRules: [ + "Verify real-time event emission on DB inserts/updates and downstream consumer state sync.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/ai-ml-engineering.ts b/packages/prompt-compiler/src/skills/definitions/ai-ml-engineering.ts new file mode 100644 index 0000000..009241e --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/ai-ml-engineering.ts @@ -0,0 +1,61 @@ +import type { SkillDefinition } from "../types.js"; + +export const aiMlEngineeringSkills: SkillDefinition[] = [ + { + name: "llm-integration", + label: "LLM Integration & Function Calling", + category: "AI & ML Engineering", + description: "Integrate LLM API providers, construct structured JSON schema output specifications, and handle function calling.", + keywords: ["llm", "ai", "openai", "claude", "gemini", "prompt-engineering", "function-calling", "structured-output", "langchain"], + guidelines: [ + "Use explicit Zod/JSON schemas for LLM structured outputs.", + "Implement defensive schema validation and retry parsing on malformed responses.", + ], + executionSteps: [ + "Define JSON schemas for LLM tool calling interfaces.", + "Construct system prompts with clear constraints and examples.", + "Implement client call wrappers with token budgeting and parsing validation.", + ], + verificationRules: [ + "Verify schema validation of LLM JSON outputs and fallback handling.", + ], + }, + { + name: "rag-architecture", + label: "RAG (Retrieval-Augmented Generation)", + category: "AI & ML Engineering", + description: "Architect RAG pipelines: document ingestion, chunking strategies, vector retrieval, and prompt context synthesis.", + keywords: ["rag", "retrieval-augmented", "chunking", "embeddings", "vector-search", "hybrid-search", "reranking"], + guidelines: [ + "Select optimal text chunk sizes with overlapping windows to preserve semantic continuity.", + "Use hybrid lexical + vector search reranking for high precision retrieval.", + ], + executionSteps: [ + "Build document parser and semantic chunking pipeline.", + "Generate vector embeddings and index into vector database.", + "Implement context retrieval, ranker, and LLM prompt compiler.", + ], + verificationRules: [ + "Verify chunking boundaries, retrieval recall accuracy, and context window budget compliance.", + ], + }, + { + name: "vector-database", + label: "Vector Database & Embeddings Storage", + category: "AI & ML Engineering", + description: "Store and query high-dimensional vector embeddings using pgvector, Pinecone, Qdrant, or Weaviate.", + keywords: ["vector-database", "vector", "pgvector", "pinecone", "qdrant", "weaviate", "cosine-similarity", "hnsw"], + guidelines: [ + "Use HNSW or IVFFlat indexes for scalable vector distance lookups.", + "Store original document metadata alongside vector embeddings for fast filtering.", + ], + executionSteps: [ + "Define vector table schemas and dimension metadata.", + "Create cosine/Euclidean distance indexes.", + "Implement vector similarity search query handlers with metadata filters.", + ], + verificationRules: [ + "Verify vector insertion, similarity search recall, and query latency.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/backend-services.ts b/packages/prompt-compiler/src/skills/definitions/backend-services.ts new file mode 100644 index 0000000..4567edf --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/backend-services.ts @@ -0,0 +1,119 @@ +import type { SkillDefinition } from "../types.js"; + +export const backendServicesSkills: SkillDefinition[] = [ + { + name: "backend-api", + label: "Backend API Design & Implementation", + category: "Backend & Services", + description: "Build robust, scalable backend server logic, controllers, and service layers.", + keywords: ["backend", "api", "server", "express", "fastify", "nest", "controller", "service", "route"], + guidelines: [ + "Keep controllers lightweight; delegate logic to service layers.", + "Return standardized HTTP status codes and response bodies.", + "Implement robust request body validation.", + ], + executionSteps: [ + "Define request/response contracts and DTO schemas.", + "Implement router middleware, controllers, and service handlers.", + "Attach request validation and centralized exception handling.", + ], + verificationRules: [ + "Test endpoint handlers with mock payloads and verify status responses.", + ], + }, + { + name: "rest-api", + label: "RESTful API Standards", + category: "Backend & Services", + description: "Design clean RESTful resource URIs, HTTP verbs, pagination, and status handling.", + keywords: ["rest", "restful", "http", "post", "get", "put", "delete", "endpoint", "status-code"], + guidelines: [ + "Use noun-based resource URIs (`/api/v1/invoices`).", + "Use HTTP verbs correctly (GET for retrieval, POST for creation, PUT/PATCH for updates, DELETE for removal).", + ], + executionSteps: [ + "Design API resource endpoints and HTTP verb mappings.", + "Implement query filtering, sorting, and cursor/page pagination.", + "Add standardized error JSON responses.", + ], + verificationRules: [ + "Verify REST URI compliance and standard HTTP status code returns.", + ], + }, + { + name: "graphql-api", + label: "GraphQL Schema & Resolvers", + category: "Backend & Services", + description: "Implement GraphQL schemas, query/mutation resolvers, dataloaders, and N+1 query prevention.", + keywords: ["graphql", "schema", "resolver", "mutation", "query", "dataloader", "apollo", "type-graphql"], + guidelines: [ + "Avoid N+1 query problems using DataLoader batching.", + "Maintain clear GraphQL schema type definitions.", + ], + executionSteps: [ + "Define GraphQL type definitions and mutation schemas.", + "Implement resolvers with batch loading handlers.", + "Add validation for GraphQL query inputs.", + ], + verificationRules: [ + "Verify GraphQL query responses and DataLoader batching efficiency.", + ], + }, + { + name: "microservices", + label: "Microservices Architecture", + category: "Backend & Services", + description: "Architect distributed microservices, event queues, message brokers (Kafka, RabbitMQ, NATS).", + keywords: ["microservice", "distributed", "event-driven", "kafka", "rabbitmq", "nats", "pubsub", "message"], + guidelines: [ + "Ensure service independence and loose coupling.", + "Use idempotent message processing in event handlers.", + ], + executionSteps: [ + "Define message payload contracts and event topics.", + "Implement event producer and consumer handlers.", + "Add retry queues and dead-letter queue (DLQ) processing.", + ], + verificationRules: [ + "Verify message serialization, event dispatch, and error recovery.", + ], + }, + { + name: "websocket-realtime", + label: "WebSocket & Realtime Communication", + category: "Backend & Services", + description: "Build bidirectional realtime features using WebSockets, Socket.io, or SSE (Server-Sent Events).", + keywords: ["websocket", "ws", "socket", "realtime", "sse", "broadcast", "channel", "push"], + guidelines: [ + "Manage client socket connections and reconnection lifecycles gracefully.", + "Authenticate socket connections on initial handshake.", + ], + executionSteps: [ + "Set up WebSocket server gateway and room/channel handlers.", + "Implement message broadcasting and heartbeat ping/pong handlers.", + "Add connection drop and reconnect state recovery.", + ], + verificationRules: [ + "Verify connection handshake, event broadcasting, and disconnect cleanup.", + ], + }, + { + name: "grpc-protobuf", + label: "gRPC & Protocol Buffers", + category: "Backend & Services", + description: "Implement high-performance RPC services using Protobuf schemas and gRPC servers.", + keywords: ["grpc", "protobuf", "proto", "rpc", "service-definition", "binary-protocol"], + guidelines: [ + "Maintain backward compatibility in `.proto` field numbers.", + "Use streaming RPCs for large data transfers.", + ], + executionSteps: [ + "Define `.proto` service interfaces and message types.", + "Generate stub code and implement service handlers.", + "Add gRPC client connection pooling.", + ], + verificationRules: [ + "Verify proto compilation and gRPC service method execution.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/coding-architecture.ts b/packages/prompt-compiler/src/skills/definitions/coding-architecture.ts new file mode 100644 index 0000000..196479d --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/coding-architecture.ts @@ -0,0 +1,124 @@ +import type { SkillDefinition } from "../types.js"; + +export const codingArchitectureSkills: SkillDefinition[] = [ + { + name: "bugfix", + label: "Bug Fixing & Troubleshooting", + category: "Coding & Architecture", + description: "Diagnose root causes, resolve defects, and prevent regression bugs.", + keywords: ["bug", "fix", "error", "fail", "issue", "crash", "defect", "patch", "repair", "exception"], + guidelines: [ + "Isolate the root cause before attempting code mutations.", + "Minimize side effects to surrounding working code.", + "Ensure existing API contracts and public interfaces remain unbroken.", + ], + executionSteps: [ + "Reproduce and identify the precise failure trigger.", + "Trace execution flow and state transformations upstream.", + "Apply targeted fix for the underlying fault.", + "Add or update regression tests verifying the fix.", + ], + verificationRules: [ + "Verify that the reproduction scenario passes cleanly.", + "Run existing test suite to ensure no regression was introduced.", + ], + }, + { + name: "refactor", + label: "Code Refactoring & Cleanup", + category: "Coding & Architecture", + description: "Improve code structure, readability, and maintainability without altering runtime behavior.", + keywords: ["refactor", "clean", "simplify", "restructure", "reorganize", "decouple", "extract", "deduplicate"], + guidelines: [ + "Strictly preserve current functional behavior and return types.", + "Reduce cyclomatic complexity and duplicate logic.", + "Maintain modular separation of concerns.", + ], + executionSteps: [ + "Identify target code anti-patterns and candidate abstractions.", + "Extract helper modules or refactor internal functions incrementally.", + "Keep method signatures backward compatible where applicable.", + ], + verificationRules: [ + "Verify all pre-existing tests continue to pass without modifications to test logic.", + ], + }, + { + name: "clean-code", + label: "Clean Code & Quality Standards", + category: "Coding & Architecture", + description: "Apply clean code principles, meaningful naming, small functions, and clear separation.", + keywords: ["clean", "naming", "readable", "maintainable", "quality", "lint", "formatting", "standards"], + guidelines: [ + "Use clear, descriptive, intention-revealing names.", + "Keep functions short and single-purpose.", + "Eliminate dead code and unneeded comments.", + ], + executionSteps: [ + "Review symbol naming and function length.", + "Simplify nested conditional branches.", + "Format code according to project linter rules.", + ], + verificationRules: [ + "Ensure static analysis and linter checks pass with zero warnings.", + ], + }, + { + name: "architecture", + label: "Architecture & System Design", + category: "Coding & Architecture", + description: "Evaluate system boundaries, component coupling, dependency flow, and structural design.", + keywords: ["architecture", "design", "structure", "module", "system", "boundary", "decouple", "pattern"], + guidelines: [ + "Maintain clear package and layer boundaries.", + "Prefer explicit data flow over hidden global state.", + "Document architectural decisions and trade-offs.", + ], + executionSteps: [ + "Map out component relationships and dependency graphs.", + "Design clean abstract interfaces and contract definitions.", + "Formulate modular migration or integration plans.", + ], + verificationRules: [ + "Verify structural coherence and clean separation of concerns.", + ], + }, + { + name: "design-patterns", + label: "Design Patterns & Abstractions", + category: "Coding & Architecture", + description: "Implement proven design patterns (Factory, Strategy, Observer, Repository, Adapter).", + keywords: ["pattern", "factory", "strategy", "observer", "repository", "adapter", "singleton", "builder"], + guidelines: [ + "Select design patterns that solve concrete complexity without over-engineering.", + "Maintain clean interface abstractions.", + ], + executionSteps: [ + "Define abstract interfaces for key behavioral contracts.", + "Implement concrete pattern providers or factories.", + "Wire dependency injection or creation registries.", + ], + verificationRules: [ + "Verify pattern contracts using unit test suites.", + ], + }, + { + name: "code-review", + label: "Code Review & Quality Audit", + category: "Coding & Architecture", + description: "Conduct thorough code reviews checking correctness, performance, security, and standards.", + keywords: ["review", "pr", "pull-request", "audit", "diff", "inspection", "quality-gate"], + guidelines: [ + "Check functional correctness, edge case handling, and error states.", + "Inspect test coverage and potential breaking changes.", + ], + executionSteps: [ + "Analyze Git diff and modified symbols.", + "Highlight potential bugs, edge-case flaws, or performance risks.", + "Provide constructive, actionable feedback and structural suggestions.", + ], + verificationRules: [ + "Confirm all reviewer checklist criteria are satisfied.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/database-storage.ts b/packages/prompt-compiler/src/skills/definitions/database-storage.ts new file mode 100644 index 0000000..72499f2 --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/database-storage.ts @@ -0,0 +1,100 @@ +import type { SkillDefinition } from "../types.js"; + +export const databaseStorageSkills: SkillDefinition[] = [ + { + name: "database-sql", + label: "Relational SQL Databases", + category: "Databases & Storage", + description: "Design relational database schemas, indexes, complex SQL queries (PostgreSQL, MySQL, SQLite).", + keywords: ["sql", "postgres", "postgresql", "mysql", "sqlite", "relational", "join", "index", "query", "transaction"], + guidelines: [ + "Normalize database tables to reduce redundancy.", + "Add indexes for high-frequency lookup fields.", + "Use explicit transactions for multi-statement atomic mutations.", + ], + executionSteps: [ + "Define table schemas, primary keys, and foreign key constraints.", + "Write optimized SQL queries and joins.", + "Add index declarations for foreign keys and filter columns.", + ], + verificationRules: [ + "Verify query execution plans and index usage.", + ], + }, + { + name: "database-nosql", + label: "NoSQL & Document Databases", + category: "Databases & Storage", + description: "Architect MongoDB, DynamoDB, Cassandra, or Firestore schemas and document models.", + keywords: ["nosql", "mongodb", "dynamodb", "document", "collection", "firestore", "cassandra"], + guidelines: [ + "Design document schemas around application query access patterns.", + "Avoid unbounded array growth within single documents.", + ], + executionSteps: [ + "Define document model interfaces and index keys.", + "Implement CRUD operations and query aggregations.", + "Handle eventual consistency and atomic updates.", + ], + verificationRules: [ + "Verify document queries and projection operations.", + ], + }, + { + name: "orm-prisma", + label: "ORM & Database Mapping (Prisma/TypeORM/Drizzle)", + category: "Databases & Storage", + description: "Manage database access via Prisma, TypeORM, Drizzle, or Sequelize ORMs.", + keywords: ["orm", "prisma", "typeorm", "drizzle", "sequelize", "schema.prisma", "entity", "migration"], + guidelines: [ + "Keep schema definitions synchronized with database state.", + "Avoid N+1 lazy loading by using explicit relation inclusions.", + ], + executionSteps: [ + "Define ORM model entities and relation fields.", + "Generate ORM client and write type-safe query calls.", + "Run schema migrations.", + ], + verificationRules: [ + "Verify ORM client queries and schema type safety.", + ], + }, + { + name: "database-migration", + label: "Database Migration Management", + category: "Databases & Storage", + description: "Write zero-downtime database schema migrations, rollback scripts, and seed files.", + keywords: ["migration", "migrate", "schema-change", "rollback", "seed", "ddl", "column-add"], + guidelines: [ + "Ensure migrations are backward-compatible and non-breaking for running code.", + "Provide explicit down/rollback migration scripts.", + ], + executionSteps: [ + "Draft up and down migration scripts.", + "Apply migration locally and verify schema delta.", + "Write data seeding or transformation scripts.", + ], + verificationRules: [ + "Test up and down migration cycles without data corruption.", + ], + }, + { + name: "caching-redis", + label: "Caching & Redis In-Memory Storage", + category: "Databases & Storage", + description: "Implement caching strategies, Redis key-value storage, pub/sub, rate limiting, and TTLs.", + keywords: ["cache", "redis", "ttl", "memcached", "in-memory", "rate-limit", "eviction", "key-value"], + guidelines: [ + "Set reasonable TTLs (Time-To-Live) on cached data.", + "Implement cache invalidation strategies (Cache-Aside, Write-Through).", + ], + executionSteps: [ + "Define cache key naming schemas and TTL values.", + "Implement cache lookup and fallback database fetching logic.", + "Add cache eviction or invalidation on data mutations.", + ], + verificationRules: [ + "Verify cache hits, miss fallbacks, and TTL expiration.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/devops-cloud.ts b/packages/prompt-compiler/src/skills/definitions/devops-cloud.ts new file mode 100644 index 0000000..a4eb6fa --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/devops-cloud.ts @@ -0,0 +1,99 @@ +import type { SkillDefinition } from "../types.js"; + +export const devopsCloudSkills: SkillDefinition[] = [ + { + name: "devops-docker", + label: "Docker Containerization & Compose", + category: "DevOps & Cloud", + description: "Write Dockerfiles, multi-stage builds, `.dockerignore` files, and `docker-compose.yml` setups.", + keywords: ["docker", "container", "dockerfile", "docker-compose", "multi-stage", "image", "entrypoint"], + guidelines: [ + "Use multi-stage Docker builds to minimize final image size.", + "Run containers as non-root users for security.", + ], + executionSteps: [ + "Draft multi-stage Dockerfile with dependency caching layer.", + "Configure `docker-compose.yml` services, volumes, and networks.", + "Verify container build and startup efficiency.", + ], + verificationRules: [ + "Verify container build succeeds and service passes health checks.", + ], + }, + { + name: "kubernetes", + label: "Kubernetes Orchestration", + category: "DevOps & Cloud", + description: "Create Kubernetes manifests (Deployments, Services, Ingress, ConfigMaps, Secrets, Helm charts).", + keywords: ["kubernetes", "k8s", "helm", "kubectl", "deployment", "service", "ingress", "pod", "configmap"], + guidelines: [ + "Specify resource requests and limits for all containers.", + "Configure readiness and liveness probes.", + ], + executionSteps: [ + "Define Kubernetes Deployment, Service, and ConfigMap YAML manifests.", + "Configure ingress routing rules and TLS cert manager.", + "Verify manifest validation with `kubectl apply --dry-run=client`.", + ], + verificationRules: [ + "Verify Kubernetes manifest syntax and resource limit definitions.", + ], + }, + { + name: "ci-cd-pipeline", + label: "CI/CD Pipeline Automation", + category: "DevOps & Cloud", + description: "Configure GitHub Actions, GitLab CI, or CircleCI workflows for automated testing and deployment.", + keywords: ["ci", "cd", "pipeline", "github-actions", "workflow", "gitlab-ci", "deploy", "release"], + guidelines: [ + "Cache package dependencies across workflow runs.", + "Fail fast on failing tests or static analysis checks.", + ], + executionSteps: [ + "Create workflow YAML specification.", + "Configure job steps for setup, lint, build, test, and release.", + "Wire repository secrets for automated deployment.", + ], + verificationRules: [ + "Verify workflow YAML syntax and step execution order.", + ], + }, + { + name: "aws-cloud", + label: "AWS & Cloud Infrastructure (Serverless, S3, ECS)", + category: "DevOps & Cloud", + description: "Architect AWS services (Lambda, S3, DynamoDB, ECS, CloudFront, Terraform/CDK).", + keywords: ["aws", "cloud", "lambda", "s3", "ecs", "cloudfront", "terraform", "cdk", "serverless", "iam"], + guidelines: [ + "Apply least-privilege IAM policy roles.", + "Use infrastructure as code (Terraform or AWS CDK).", + ], + executionSteps: [ + "Define infrastructure components using Terraform or CDK.", + "Set up IAM policies, bucket access, and serverless handlers.", + "Plan and deploy infrastructure resources.", + ], + verificationRules: [ + "Verify IaC syntax and resource security policies.", + ], + }, + { + name: "monitoring-logging", + label: "Monitoring, Logging & Observability", + category: "DevOps & Cloud", + description: "Implement structured JSON logging, Prometheus metrics, OpenTelemetry tracing, and Sentry tracking.", + keywords: ["monitoring", "logging", "tracing", "opentelemetry", "prometheus", "grafana", "sentry", "winston", "pino"], + guidelines: [ + "Use structured JSON format for machine-parseable log outputs.", + "Sanitize PII and sensitive tokens from log outputs.", + ], + executionSteps: [ + "Configure structured logger with log-level filtering.", + "Add request correlation IDs for distributed tracing.", + "Wire exception tracking and metric counters.", + ], + verificationRules: [ + "Verify log formatting, correlation IDs, and error capture.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/distributed-resilience.ts b/packages/prompt-compiler/src/skills/definitions/distributed-resilience.ts new file mode 100644 index 0000000..5fa968c --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/distributed-resilience.ts @@ -0,0 +1,61 @@ +import type { SkillDefinition } from "../types.js"; + +export const distributedResilienceSkills: SkillDefinition[] = [ + { + name: "circuit-breaker", + label: "Circuit Breaker & Resilience Patterns", + category: "Distributed Systems", + description: "Prevent cascading failures in distributed systems using Circuit Breakers, Bulkheads, and Fallback handlers.", + keywords: ["circuit-breaker", "resilience", "fallback", "bulkhead", "hystrix", "resilience4j", "failure-threshold"], + guidelines: [ + "Track failure rates and trip circuit breakers to open state before downstream services collapse.", + "Provide immediate, graceful fallback responses when a circuit is open.", + ], + executionSteps: [ + "Configure error rate thresholds, sliding window sizes, and half-open timeout durations.", + "Wrap outbound RPC/HTTP calls in circuit breaker execution handlers.", + "Implement fallback state logic for open circuit conditions.", + ], + verificationRules: [ + "Test circuit state transitions (Closed -> Open -> Half-Open -> Closed) under simulated downstream failures.", + ], + }, + { + name: "zero-downtime-deployment", + label: "Zero-Downtime Deployment & Canary Releases", + category: "Distributed Systems", + description: "Execute safe deployments using Blue-Green strategies, Canary rollouts, and multi-version API support.", + keywords: ["zero-downtime", "canary", "blue-green", "rolling-update", "backward-compatible", "feature-flag"], + guidelines: [ + "Ensure database migrations are strictly backward compatible across N and N+1 code versions.", + "Use feature flags to decouple code deployment from feature exposure.", + ], + executionSteps: [ + "Design dual-write or backward-compatible schema changes.", + "Configure progressive Canary traffic routing rules.", + "Implement automated rollback triggers based on error rate metrics.", + ], + verificationRules: [ + "Verify system health during dual-version execution and rollout state transition.", + ], + }, + { + name: "fault-tolerance", + label: "Fault Tolerance & Rate Limiting", + category: "Distributed Systems", + description: "Implement exponential backoff retries, jitter, rate limiting, and distributed concurrency locks.", + keywords: ["fault-tolerance", "exponential-backoff", "jitter", "rate-limit", "leaky-bucket", "token-bucket", "distributed-lock"], + guidelines: [ + "Add randomized jitter to exponential backoff retries to prevent thundering herd problems.", + "Enforce distributed rate limiting at the network edge.", + ], + executionSteps: [ + "Implement retry handlers with exponential backoff and jitter.", + "Set up edge rate limiting (Token Bucket / Sliding Window).", + "Add distributed lock acquisition with automatic TTL expiration.", + ], + verificationRules: [ + "Verify retry frequency under failure and edge rate limiting enforcement.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/documentation-i18n.ts b/packages/prompt-compiler/src/skills/definitions/documentation-i18n.ts new file mode 100644 index 0000000..3f6b5f5 --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/documentation-i18n.ts @@ -0,0 +1,176 @@ +import type { SkillDefinition } from "../types.js"; + +export const documentationI18nSkills: SkillDefinition[] = [ + { + name: "docs", + label: "Documentation & Technical Writing", + category: "Docs & Specifications", + description: "Write clear, precise, and up-to-date technical documentation, READMEs, and API guides.", + keywords: ["doc", "docs", "readme", "comment", "guide", "changelog", "explain", "markdown"], + guidelines: [ + "Use clear, concise, Markdown-formatted prose.", + "Provide practical code snippets and CLI usage examples.", + "Keep docs in sync with actual exported types and signatures.", + ], + executionSteps: [ + "Review target feature or API for accurate detail.", + "Draft concise documentation sections with examples.", + "Verify links, code examples, and command formatting.", + ], + verificationRules: [ + "Check doc formatting and link/code correctness.", + ], + }, + { + name: "api-spec-openapi", + label: "OpenAPI / Swagger Specifications", + category: "Docs & Specifications", + description: "Generate and maintain OpenAPI 3.0 / Swagger API specification documents and schemas.", + keywords: ["openapi", "swagger", "api-spec", "json-schema", "postman"], + guidelines: [ + "Define explicit schema models for request bodies and responses.", + "Include detailed description and example fields for endpoints.", + ], + executionSteps: [ + "Draft OpenAPI 3.0 YAML or JSON specification.", + "Annotate API parameters, request schemas, and HTTP response codes.", + "Validate specification using OpenAPI linter.", + ], + verificationRules: [ + "Verify OpenAPI document passes validation checks.", + ], + }, + { + name: "i18n-localization", + label: "Internationalization (i18n) & Localization", + category: "Docs & Specifications", + description: "Implement multi-language i18n translation keys, locale formatting, and RTL support.", + keywords: ["i18n", "l10n", "translation", "locale", "internationalization", "localization", "rtl"], + guidelines: [ + "Never hardcode user-facing strings directly in components or logic.", + "Use ICU message syntax for plurals and interpolation.", + ], + executionSteps: [ + "Extract hardcoded strings into structured locale JSON files.", + "Implement translation key lookup wrappers.", + "Add date, currency, and number locale formatters.", + ], + verificationRules: [ + "Verify missing key fallbacks and locale rendering correctness.", + ], + }, + { + name: "architecture-decision-records", + label: "Architecture Decision Records (ADR)", + category: "Docs & Specifications", + description: "Document software architecture choices using structured ADR files recording context, decisions, and consequences.", + keywords: ["adr", "architecture-decision", "decision-record", "decision-log", "consequences"], + guidelines: [ + "Record architectural context, options considered, decision outcome, and positive/negative consequences.", + "Keep ADRs immutable once accepted; create a new ADR for decision updates.", + ], + executionSteps: [ + "Create ADR template with Status, Context, Decision, and Consequences sections.", + "Draft clear problem statement and trade-off comparisons.", + "Link related ADRs and document system impact.", + ], + verificationRules: [ + "Verify Markdown ADR structure and trade-off completeness.", + ], + }, + { + name: "jsdoc-typedoc", + label: "JSDoc & TSDoc Code Documentation", + category: "Docs & Specifications", + description: "Annotate source code with comprehensive JSDoc/TSDoc comments, `@param`, `@returns`, `@throws`, and `@example` tags.", + keywords: ["jsdoc", "typedoc", "tsdoc", "comment", "param", "returns", "annotation"], + guidelines: [ + "Document all exported types, interfaces, classes, and public functions.", + "Include `@example` usage snippets for complex API functions.", + ], + executionSteps: [ + "Review exported symbols and add block JSDoc/TSDoc comments.", + "Specify `@param` descriptions and return types.", + "Add TypeDoc generation script check.", + ], + verificationRules: [ + "Verify TSDoc comment compilation and API generator rendering.", + ], + }, + { + name: "mermaid-diagrams", + label: "Mermaid Architecture Diagrams", + category: "Docs & Specifications", + description: "Create interactive sequence diagrams, flowcharts, ER diagrams, and state diagrams using Mermaid Markdown blocks.", + keywords: ["mermaid", "diagram", "sequence-diagram", "flowchart", "er-diagram", "visualize"], + guidelines: [ + "Use clean Mermaid block syntax with clear node aliases.", + "Enclose labels with special characters in quotes.", + ], + executionSteps: [ + "Design component interaction or flow sequence.", + "Write Mermaid syntax fenced code blocks (` ```mermaid `).", + "Verify visual rendering of diagrams.", + ], + verificationRules: [ + "Verify Mermaid syntax validity and node connectivity.", + ], + }, + { + name: "changelog-release-notes", + label: "Changelogs & Release Notes", + category: "Docs & Specifications", + description: "Maintain Keep-a-Changelog release documents, Semantic Versioning tags, breaking change notes, and migration steps.", + keywords: ["changelog", "release-notes", "semver", "version", "breaking-change", "migration-guide"], + guidelines: [ + "Categorize changes under Added, Changed, Deprecated, Removed, Fixed, and Security headers.", + "Highlight breaking changes prominently with migration instructions.", + ], + executionSteps: [ + "Review git commits and PR summaries since last release.", + "Draft structured CHANGELOG entry adhering to Keep a Changelog standard.", + "Add explicit migration steps for any breaking API changes.", + ], + verificationRules: [ + "Verify CHANGELOG formatting and version tag alignment.", + ], + }, + { + name: "user-guides-tutorials", + label: "Developer Guides & Tutorials", + category: "Docs & Specifications", + description: "Write step-by-step developer onboarding guides, getting started tutorials, and troubleshooting FAQs.", + keywords: ["tutorial", "guide", "onboarding", "getting-started", "faq", "walkthrough"], + guidelines: [ + "Provide copy-pasteable shell commands and code blocks.", + "Include prerequisite dependencies and expected outputs.", + ], + executionSteps: [ + "Outline user journey from installation to feature execution.", + "Draft step-by-step instructions with code blocks.", + "Add common error resolution FAQ section.", + ], + verificationRules: [ + "Verify code example execution from a clean environment.", + ], + }, + { + name: "sdk-api-reference", + label: "SDK & Library API Reference", + category: "Docs & Specifications", + description: "Author complete SDK API reference manuals detailing class methods, parameters, return types, and code snippets.", + keywords: ["sdk", "sdk-docs", "api-reference", "library-docs", "manual"], + guidelines: [ + "List all public methods with full type signatures and default parameter values.", + "Provide runnable code snippets for each major API method.", + ], + executionSteps: [ + "Catalog all client SDK entrypoints and helper methods.", + "Write comprehensive parameter tables and code examples.", + "Document error codes and exception types.", + ], + verificationRules: [ + "Verify SDK method signature accuracy and code snippet validity.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/performance-optimization.ts b/packages/prompt-compiler/src/skills/definitions/performance-optimization.ts new file mode 100644 index 0000000..e8c6d91 --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/performance-optimization.ts @@ -0,0 +1,99 @@ +import type { SkillDefinition } from "../types.js"; + +export const performanceOptimizationSkills: SkillDefinition[] = [ + { + name: "perf", + label: "Performance & Optimization Overview", + category: "Performance & Async", + description: "Optimize execution speed, memory consumption, caching, and algorithmic efficiency.", + keywords: ["perf", "performance", "optimize", "fast", "speed", "latency", "throughput", "bottleneck"], + guidelines: [ + "Target empirical bottlenecks backed by benchmark measurements.", + "Prefer O(1) or O(N) lookup structures over nested iterations.", + ], + executionSteps: [ + "Identify hot code paths and execution bottlenecks.", + "Apply algorithmic improvements, caching, or memory reuse.", + "Verify performance gains with benchmark tests.", + ], + verificationRules: [ + "Verify functional correctness and measure time/memory savings.", + ], + }, + { + name: "memory-optimization", + label: "Memory Leak & Garbage Collection Optimization", + category: "Performance & Async", + description: "Diagnose Node.js / browser memory leaks, heap retention, buffer reuse, and object pooling.", + keywords: ["memory", "heap", "leak", "gc", "garbage-collection", "buffer", "allocation", "profile"], + guidelines: [ + "Avoid global object reference retainers.", + "Stream or chunk large payload processing instead of loading entire files into RAM.", + ], + executionSteps: [ + "Take heap snapshots to identify retained objects.", + "Implement stream/chunk processing or object pooling.", + "Verify memory release post-execution.", + ], + verificationRules: [ + "Confirm memory consumption stabilizes and leaks are eliminated.", + ], + }, + { + name: "async-concurrency", + label: "Async Concurrency & Parallel Execution", + category: "Performance & Async", + description: "Manage async operations, Worker threads, task queues, promise concurrency limits, and locks.", + keywords: ["async", "concurrency", "parallel", "worker", "promise", "race-condition", "mutex", "lock", "queue"], + guidelines: [ + "Control concurrency limits (e.g. `p-limit`) to prevent resource starvation.", + "Use mutexes or atomic operations when mutating shared resources under concurrency.", + ], + executionSteps: [ + "Identify blocking or sequential async calls that can run concurrently.", + "Implement bounded concurrency queues or worker thread pools.", + "Add synchronization locks for critical sections.", + ], + verificationRules: [ + "Test concurrent execution under high workload without data race conditions.", + ], + }, + { + name: "load-testing", + label: "Load & Stress Testing", + category: "Performance & Async", + description: "Simulate concurrent user traffic and measure throughput/latency breaking points using k6 or Autocannon.", + keywords: ["load-testing", "stress", "benchmark", "k6", "autocannon", "rps", "throughput", "p99"], + guidelines: [ + "Measure p95 and p99 latency metrics under load.", + "Identify infrastructure breaking points.", + ], + executionSteps: [ + "Write load test scripts simulating real-world traffic profiles.", + "Execute load tests against target endpoints.", + "Analyze response latency histograms and error rates.", + ], + verificationRules: [ + "Verify system meets Target RPS and latency SLA constraints.", + ], + }, + { + name: "latency-reduction", + label: "Low-Latency & Network Optimization", + category: "Performance & Async", + description: "Reduce network roundtrips, optimize connection pooling, compression, and payload sizes.", + keywords: ["latency", "roundtrip", "compression", "gzip", "brotli", "connection-pool", "payload"], + guidelines: [ + "Enable HTTP response compression (Gzip / Brotli).", + "Reuse TCP connection pools for outbound HTTP/database calls.", + ], + executionSteps: [ + "Audit payload sizes and strip unnecessary JSON fields.", + "Configure persistent HTTP keep-alive agents and connection pools.", + "Measure roundtrip latency reduction.", + ], + verificationRules: [ + "Verify payload size reduction and network response speedups.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/security-auth.ts b/packages/prompt-compiler/src/skills/definitions/security-auth.ts new file mode 100644 index 0000000..7d56e5f --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/security-auth.ts @@ -0,0 +1,82 @@ +import type { SkillDefinition } from "../types.js"; + +export const securityAuthSkills: SkillDefinition[] = [ + { + name: "security-audit", + label: "Security Audit & Remediation", + category: "Security & Auth", + description: "Identify threat vectors, sanitize inputs, enforce strict access controls, and patch vulnerabilities.", + keywords: ["security", "audit", "vulnerability", "threat", "protect", "cve", "owasp", "leak", "exploit"], + guidelines: [ + "Enforce principle of least privilege and strict input validation.", + "Prevent data leakage in logs, error messages, and task summaries.", + "Use safe local handling for sensitive metadata.", + ], + executionSteps: [ + "Audit input boundaries, state mutations, and data persistence paths.", + "Implement sanitization, validation, and defensive checks.", + "Ensure failure modes fail securely.", + ], + verificationRules: [ + "Verify sanitized handling and secure failure handling paths.", + ], + }, + { + name: "authentication-oauth", + label: "Authentication & Authorization (JWT, OAuth2, RBAC)", + category: "Security & Auth", + description: "Implement secure user authentication, JWT tokens, OAuth2 providers, and RBAC permissions.", + keywords: ["auth", "authentication", "authorization", "jwt", "oauth", "oauth2", "token", "rbac", "session", "passport"], + guidelines: [ + "Never store plain text passwords; use bcrypt or Argon2 hashing.", + "Validate JWT signatures, expiration, and issuer claims.", + "Enforce RBAC role checks on protected endpoints.", + ], + executionSteps: [ + "Implement password hashing and token generation service.", + "Set up auth verification middleware for routes/endpoints.", + "Add permission and role evaluation logic.", + ], + verificationRules: [ + "Verify authenticated access, invalid token rejection, and forbidden role access.", + ], + }, + { + name: "input-sanitization", + label: "Input Validation & XSS/SQLi Prevention", + category: "Security & Auth", + description: "Prevent XSS, SQL injection, Command Injection, and CSRF attacks via strict input validation.", + keywords: ["sanitization", "xss", "sqli", "injection", "csrf", "validator", "zod", "joi", "escape"], + guidelines: [ + "Never interpolate raw user input directly into SQL queries or shell commands.", + "Sanitize HTML strings before rendering in DOM.", + ], + executionSteps: [ + "Add strict schema validation (e.g. Zod/Joi) for all API body/query inputs.", + "Use parameterized queries for database operations.", + "Apply HTML escaping and anti-CSRF headers.", + ], + verificationRules: [ + "Verify malformed and malicious input payloads are rejected cleanly.", + ], + }, + { + name: "encryption-crypto", + label: "Cryptography & Data Protection", + category: "Security & Auth", + description: "Implement AES-256 encryption at rest, TLS in transit, secure hashing, and secrets management.", + keywords: ["crypto", "encryption", "cipher", "hash", "secret", "vault", "tls", "ssl", "aes", "rsa"], + guidelines: [ + "Use standard crypto libraries (e.g. `node:crypto`); do not write custom crypto routines.", + "Never hardcode secrets or private keys in repository source files.", + ], + executionSteps: [ + "Configure environment variable secrets management.", + "Implement AES-GCM encryption/decryption routines for sensitive payload storage.", + "Add HMAC message signing verification.", + ], + verificationRules: [ + "Verify ciphertext output, decryption recovery, and HMAC signature checks.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/senior-architecture.ts b/packages/prompt-compiler/src/skills/definitions/senior-architecture.ts new file mode 100644 index 0000000..e50e5f9 --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/senior-architecture.ts @@ -0,0 +1,101 @@ +import type { SkillDefinition } from "../types.js"; + +export const seniorArchitectureSkills: SkillDefinition[] = [ + { + name: "domain-driven-design", + label: "Domain-Driven Design (DDD)", + category: "Senior Architecture", + description: "Architect complex software systems using Bounded Contexts, Aggregates, Entities, Value Objects, and Ubiquitous Language.", + keywords: ["ddd", "domain-driven", "bounded-context", "aggregate", "entity", "value-object", "domain-event", "ubiquitous-language"], + guidelines: [ + "Define explicit Bounded Contexts to insulate domain models from external boundaries.", + "Encapsulate state mutations within Aggregate Roots to guarantee transactional consistency.", + "Represent immutable domain state using Value Objects without identity.", + ], + executionSteps: [ + "Map out domain model boundaries, aggregates, and value objects.", + "Design domain event publishers for cross-aggregate notifications.", + "Decouple domain logic completely from database persistence framework models.", + ], + verificationRules: [ + "Verify domain entities compile with zero framework or database dependencies.", + ], + }, + { + name: "cqrs-event-sourcing", + label: "CQRS & Event Sourcing Architecture", + category: "Senior Architecture", + description: "Separate Command and Query responsibility models, store state as immutable event streams, and project read models.", + keywords: ["cqrs", "event-sourcing", "command", "query", "projection", "event-store", "read-model", "replay"], + guidelines: [ + "Strictly isolate read query models from write command validation state.", + "Treat stored domain events as the single source of truth.", + "Ensure asynchronous projection handlers process events idempotently.", + ], + executionSteps: [ + "Define command DTOs and command handler validation logic.", + "Implement event store append handlers and domain event publishing.", + "Build optimized read model projections for fast UI query lookups.", + ], + verificationRules: [ + "Verify event store append operations and deterministic event replay projections.", + ], + }, + { + name: "hexagonal-architecture", + label: "Hexagonal Architecture (Ports & Adapters)", + category: "Senior Architecture", + description: "Isolate core domain logic behind input/output Ports and implement infrastructure Adapters.", + keywords: ["hexagonal", "ports-and-adapters", "clean-architecture", "onion", "decoupled", "adapter", "port"], + guidelines: [ + "Depend on abstraction ports rather than concrete infrastructure implementations.", + "Keep core application services free of HTTP or database dependencies.", + ], + executionSteps: [ + "Define driving (inbound) and driven (outbound) TypeScript port interfaces.", + "Implement core application domain services implementing inbound ports.", + "Write infrastructure adapters (REST controllers, ORM repositories) bound to outbound ports.", + ], + verificationRules: [ + "Verify core application services pass tests using in-memory port stubs.", + ], + }, + { + name: "tech-debt-remediation", + label: "Technical Debt Remediation & Strategy", + category: "Senior Architecture", + description: "Quantify, prioritize, and systematically refactor technical debt while keeping delivery velocity high.", + keywords: ["tech-debt", "technical-debt", "remediation", "legacy", "code-smell", "debt", "modernize"], + guidelines: [ + "Quantify architectural risk and maintenance overhead for target debt areas.", + "Refactor incrementally alongside active feature development rather than massive rewrites.", + ], + executionSteps: [ + "Audit high-churn, low-coverage modules for anti-patterns.", + "Establish automated safety nets with unit and integration coverage.", + "Execute targeted refactoring passes to simplify complexity.", + ], + verificationRules: [ + "Verify cyclomatic complexity reduction and zero regression in test suites.", + ], + }, + { + name: "legacy-modernization", + label: "Legacy System Modernization (Strangler Fig)", + category: "Senior Architecture", + description: "Incrementally replace legacy monolithic systems using the Strangler Fig pattern and modular migration routes.", + keywords: ["strangler", "strangler-fig", "modernization", "monolith-to-microservices", "legacy-migration", "interception"], + guidelines: [ + "Intercept legacy route calls at the API gateway layer.", + "Migrate single services or domains incrementally while legacy system runs parallel.", + ], + executionSteps: [ + "Deploy API gateway or routing proxy to intercept incoming traffic.", + "Implement modern service handler for the target sub-domain.", + "Shift traffic incrementally (1% -> 10% -> 100%) and deprecate legacy paths.", + ], + verificationRules: [ + "Verify routing proxy dispatch and data consistency between legacy and modern services.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/testing-qa.ts b/packages/prompt-compiler/src/skills/definitions/testing-qa.ts new file mode 100644 index 0000000..333bcdb --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/testing-qa.ts @@ -0,0 +1,80 @@ +import type { SkillDefinition } from "../types.js"; + +export const testingQASkills: SkillDefinition[] = [ + { + name: "unit-testing", + label: "Unit Testing & Assertion", + category: "Testing & Quality", + description: "Write fast, isolated unit tests checking individual functions, methods, and modules.", + keywords: ["test", "unit", "spec", "jest", "vitest", "mocha", "assert", "coverage"], + guidelines: [ + "Keep tests independent, fast, and deterministic.", + "Assert precise expected outputs and error exceptions.", + ], + executionSteps: [ + "Identify target module functions and state paths.", + "Construct explicit unit test cases for standard, boundary, and error scenarios.", + "Run test runner and verify 100% test pass rate.", + ], + verificationRules: [ + "Execute unit test suite and confirm clean pass execution.", + ], + }, + { + name: "integration-testing", + label: "Integration Testing", + category: "Testing & Quality", + description: "Verify cross-module interactions, database queries, API endpoints, and service integrations.", + keywords: ["integration", "supertest", "api-test", "db-test", "component-test"], + guidelines: [ + "Use isolated test databases or containers for integration tests.", + "Clean up test state after test suite execution.", + ], + executionSteps: [ + "Set up test environment and mock fixtures.", + "Execute multi-component workflow calls.", + "Assert final database or service state.", + ], + verificationRules: [ + "Confirm integration scenarios pass without leaving dirty state.", + ], + }, + { + name: "e2e-testing", + label: "End-to-End (E2E) Testing", + category: "Testing & Quality", + description: "Automate user flow testing using Playwright, Cypress, or Selenium.", + keywords: ["e2e", "playwright", "cypress", "selenium", "browser-test", "user-flow"], + guidelines: [ + "Use robust data-testid or semantic role selectors.", + "Avoid artificial sleep waits; wait for explicit UI state triggers.", + ], + executionSteps: [ + "Define critical user journeys and test scripts.", + "Implement Page Object Model (POM) or test fixture helpers.", + "Execute headless browser tests.", + ], + verificationRules: [ + "Verify headless browser flow execution and screenshot/video artifacts on failure.", + ], + }, + { + name: "mocking-stubbing", + label: "Mocking, Stubbing & Test Spies", + category: "Testing & Quality", + description: "Stub network calls, mock third-party SDK dependencies, and inspect call spies.", + keywords: ["mock", "stub", "spy", "nock", "sinon", "msw", "double"], + guidelines: [ + "Avoid over-mocking internal implementation details.", + "Reset mock states between tests.", + ], + executionSteps: [ + "Configure mock servers or dependency replacement stubs.", + "Execute test scenario with controlled mock responses.", + "Assert mock call parameters and call counts.", + ], + verificationRules: [ + "Verify test execution behavior with deterministic mock payloads.", + ], + }, +]; diff --git a/packages/prompt-compiler/src/skills/definitions/web-frontend.ts b/packages/prompt-compiler/src/skills/definitions/web-frontend.ts new file mode 100644 index 0000000..ada2b14 --- /dev/null +++ b/packages/prompt-compiler/src/skills/definitions/web-frontend.ts @@ -0,0 +1,121 @@ +import type { SkillDefinition } from "../types.js"; + +export const webFrontendSkills: SkillDefinition[] = [ + { + name: "frontend-ui", + label: "Frontend UI & Component Design", + category: "Web & Frontend", + description: "Build interactive, responsive, and aesthetically pleasing user interfaces.", + keywords: ["frontend", "ui", "component", "widget", "layout", "view", "interface", "design"], + guidelines: [ + "Keep UI state local and component boundaries modular.", + "Ensure responsive layouts adapt smoothly across viewports.", + "Maintain consistent styling and component props APIs.", + ], + executionSteps: [ + "Define component props interface and component tree.", + "Implement rendering logic and interactive state handlers.", + "Apply component styles and responsive breakpoint rules.", + ], + verificationRules: [ + "Verify visual fidelity, prop types, and responsive rendering.", + ], + }, + { + name: "react-nextjs", + label: "React & Next.js Architecture", + category: "Web & Frontend", + description: "Develop modern React app features using hooks, server components, and Next.js router rules.", + keywords: ["react", "next", "nextjs", "jsx", "tsx", "hook", "usecontext", "usestate", "useeffect", "server-component"], + guidelines: [ + "Follow React hooks rules and avoid unneeded re-renders.", + "Leverage server components for data fetching where applicable.", + "Keep client components lightweight.", + ], + executionSteps: [ + "Structure page routes, layouts, and reusable components.", + "Manage client hooks state and server fetching logic.", + "Ensure strict TypeScript prop typing.", + ], + verificationRules: [ + "Verify component lifecycle, state updates, and build check compilation.", + ], + }, + { + name: "state-management", + label: "State Management & Data Flow", + category: "Web & Frontend", + description: "Architect predictable state management (Zustand, Redux, Context API, MobX).", + keywords: ["state", "store", "redux", "zustand", "context", "mobx", "action", "reducer", "selector"], + guidelines: [ + "Avoid mutating state directly; use immutable state transitions.", + "Normalize state structures for fast selector lookups.", + "Keep UI components decoupled from state storage implementation.", + ], + executionSteps: [ + "Define store schema, initial state, and state mutator actions.", + "Wire hooks and selectors into consumer components.", + "Add unit tests for store reducers/actions.", + ], + verificationRules: [ + "Verify deterministic state transitions in store unit tests.", + ], + }, + { + name: "css-styling", + label: "CSS & Styling Systems", + category: "Web & Frontend", + description: "Style interfaces using Vanilla CSS, TailwindCSS, CSS Modules, or Styled Components.", + keywords: ["css", "styles", "tailwind", "styled-components", "flexbox", "grid", "responsive", "theme"], + guidelines: [ + "Use CSS custom properties for color palettes and spacing tokens.", + "Maintain clean class names and layout flexbox/grid containers.", + ], + executionSteps: [ + "Configure design tokens, themes, and color variables.", + "Implement element layout rules, transitions, and media queries.", + ], + verificationRules: [ + "Check visual presentation across responsive breakpoints.", + ], + }, + { + name: "accessibility-a11y", + label: "Accessibility (a11y) & Usability", + category: "Web & Frontend", + description: "Ensure WCAG compliance, keyboard navigation, screen reader support, and ARIA attributes.", + keywords: ["a11y", "accessibility", "aria", "wcag", "keyboard", "screen-reader", "contrast", "focus"], + guidelines: [ + "Provide semantic HTML elements (`