From 640c7c6b67a8f3c78a893b5239e228d84faa4a92 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Tue, 3 Feb 2026 22:05:56 -0700 Subject: [PATCH 01/19] chore: vnext updates --- .github/ISSUE_TEMPLATE/bug_report.md | 23 + .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/feature_request.md | 13 + .github/PULL_REQUEST_TEMPLATE.md | 10 + .github/workflows/ci.yml | 34 ++ .github/workflows/release-please.yml | 19 + .gitignore | 1 + .prettierrc.json | 5 + CHANGELOG.md | 12 + CODEOWNERS | 1 + CONTRIBUTING.md | 34 ++ LICENSE | 21 + PLAN.md | 76 ++- README.md | 128 ++++- SECURITY.md | 7 + eslint.config.js | 45 ++ examples/README.md | 14 + examples/primer.eval.json | 15 + package.json | 24 +- primer.eval.json | 2 +- release-please-config.json | 9 + release-please-manifest.json | 3 + src/cli.ts | 15 +- src/commands/batch.tsx | 29 +- src/commands/eval.ts | 5 +- src/commands/init.ts | 85 ++- src/commands/pr.ts | 97 +++- src/commands/readiness.ts | 120 ++++ src/services/__tests__/analyzer.test.ts | 31 ++ src/services/analyzer.ts | 142 ++++- src/services/azureDevops.ts | 235 ++++++++ src/services/evaluator.ts | 461 ++++++++++++++- src/services/git.ts | 22 +- src/services/readiness.ts | 648 ++++++++++++++++++++++ src/ui/BatchTuiAzure.tsx | 526 ++++++++++++++++++ src/ui/README.md | 2 + src/ui/tui.tsx | 166 +++++- vitest.config.ts | 12 + 38 files changed, 2996 insertions(+), 101 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release-please.yml create mode 100644 .prettierrc.json create mode 100644 CHANGELOG.md create mode 100644 CODEOWNERS create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 SECURITY.md create mode 100644 eslint.config.js create mode 100644 examples/README.md create mode 100644 examples/primer.eval.json create mode 100644 release-please-config.json create mode 100644 release-please-manifest.json create mode 100644 src/commands/readiness.ts create mode 100644 src/services/__tests__/analyzer.test.ts create mode 100644 src/services/azureDevops.ts create mode 100644 src/services/readiness.ts create mode 100644 src/ui/BatchTuiAzure.tsx create mode 100644 vitest.config.ts diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..c7f8e50 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +description: Report a problem with Primer +labels: [bug] +--- + +## Description + +## Steps to reproduce + +1. +2. +3. + +## Expected behavior + +## Actual behavior + +## Environment + +- OS: +- Node version: +- Primer version: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3624ac5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Questions + url: https://github.com/pierceboggan/primer/discussions + about: Ask questions and discuss ideas here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..dabc116 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,13 @@ +--- +name: Feature request +description: Suggest an enhancement for Primer +labels: [enhancement] +--- + +## Summary + +## Problem statement + +## Proposed solution + +## Additional context diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..84350e7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +## Summary + +- [ ] What changed +- [ ] Why it changed + +## Checklist + +- [ ] Tests added or updated +- [ ] Lint/typecheck pass +- [ ] Docs updated if needed diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cb9b04c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + - name: Install + run: npm ci + - name: Lint + run: npm run lint + - name: Typecheck + run: npm run typecheck + - name: Test + run: npm run test:coverage + - name: Build + run: npm run build + - name: Upload coverage + uses: actions/upload-artifact@v4 + with: + name: coverage + path: coverage + if-no-files-found: ignore diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..3547bac --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,19 @@ +name: Release Please + +on: + push: + branches: [main] + +permissions: + contents: write + pull-requests: write + +jobs: + release-please: + runs-on: ubuntu-latest + steps: + - name: Release + uses: google-github-actions/release-please-action@v4 + with: + config-file: release-please-config.json + manifest-file: release-please-manifest.json diff --git a/.gitignore b/.gitignore index 6b4a136..89da78c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ node_modules/ # Build output dist/ +coverage/ # IDE .vscode/ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..1ad2e3d --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": false, + "trailingComma": "none", + "printWidth": 100 +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e91d5ff --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [Unreleased] + +- Readiness report with monorepo support and fix-first checklist. +- CI workflow with lint, typecheck, tests, and build steps. +- Release automation via release-please. +- ESLint, Prettier, and Vitest tooling plus starter tests. +- Added contributing, security, and issue/PR templates. +- Added examples folder with sample configs. diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..77511c7 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @pierceboggan diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e66fc98 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,34 @@ +# Contributing + +Thanks for contributing to Primer. + +## Quick start + +1. Fork and clone the repo. +2. Install dependencies: npm install +3. Build locally: npm run build +4. Run lint/typecheck/tests before opening a PR: + - npm run lint + - npm run typecheck + - npm run test + +## Development workflow + +- Create a feature branch from main. +- Use clear, conventional commit messages (e.g. feat: add readiness report). +- Keep PRs focused and include context in the description. +- Add or update tests when behavior changes. + +## Code style + +- ESLint + Prettier are enforced in CI. +- Prefer small, composable functions with clear types. + +## Reporting issues + +- Use GitHub Issues for bugs and feature requests. +- Provide steps to reproduce and expected behavior. + +## Releasing + +Releases are automated with release-please when changes are merged to main. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cb6db3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Primer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/PLAN.md b/PLAN.md index 3dcc268..46f5b83 100644 --- a/PLAN.md +++ b/PLAN.md @@ -16,9 +16,14 @@ Make any repository "AI-ready" with a single command — generating optimal conf - Detect language(s), frameworks, and project structure - Identify existing AI configurations - Analyze package managers, build tools, and testing frameworks -- Detect monorepo vs single-project structure +- Detect monorepo vs single-project structure (workspace-aware) -### 2. **Configuration Generation** +### 2. **Readiness Report** +- Score AI readiness across key pillars +- Provide fix-first checklists and maturity levels +- Support monorepos with app-scoped checks + +### 3. **Configuration Generation** | Config Type | Description | |-------------|-------------| @@ -26,19 +31,19 @@ Make any repository "AI-ready" with a single command — generating optimal conf | **MCP Server Config** | `.vscode/mcp.json` for Model Context Protocol servers | | **VS Code Settings** | `.vscode/settings.json` with AI-optimized workspace settings | -### 3. **GitHub Integration** +### 4. **GitHub Integration** - Authenticate via GitHub CLI (`gh auth`) or OAuth device flow - List and select from accessible repositories - Clone repos temporarily for analysis - **Auto-create PRs** with generated configurations - Support for GitHub Enterprise -### 4. **Local Repository Support** +### 5. **Local Repository Support** - Detect local Git repositories - Work offline with local-only mode - Push changes to remote when ready -### 5. **Interactive & Non-Interactive Modes** +### 6. **Interactive & Non-Interactive Modes** - Beautiful TUI with prompts and previews - CI/CD-friendly `--yes` flag for automation - JSON output for scripting @@ -99,6 +104,9 @@ primer pr owner/repo # Analyze repo without making changes primer analyze +# Readiness report +primer readiness + # Update existing configurations primer update @@ -107,6 +115,18 @@ primer templates # Configure CLI settings primer config + +# Generate instructions +primer instructions + +# Run evaluations +primer eval primer.eval.json + +# Run TUI +primer tui + +# Batch processing +primer batch ``` --- @@ -370,23 +390,33 @@ primer/ │ ├── index.ts # Entry point │ ├── cli.ts # Commander setup │ ├── commands/ -│ │ ├── init.ts -│ │ ├── generate.ts │ │ ├── analyze.ts +│ │ ├── batch.tsx +│ │ ├── config.ts +│ │ ├── eval.ts +│ │ ├── generate.ts +│ │ ├── init.ts +│ │ ├── instructions.tsx │ │ ├── pr.ts -│ │ └── config.ts +│ │ ├── readiness.ts +│ │ ├── templates.ts +│ │ ├── tui.tsx +│ │ └── update.ts │ ├── services/ -│ │ ├── github.ts # GitHub API interactions │ │ ├── analyzer.ts # Repo analysis logic +│ │ ├── azureDevops.ts # Azure DevOps integration +│ │ ├── evaluator.ts # Eval runner │ │ ├── generator.ts # Config generation -│ │ └── git.ts # Local git operations +│ │ ├── git.ts # Local git operations +│ │ ├── github.ts # GitHub API interactions +│ │ └── instructions.ts # Copilot SDK integration │ ├── ui/ -│ │ ├── prompts.ts # Inquirer prompts -│ │ ├── spinner.ts # Loading indicators -│ │ └── preview.ts # File previews +│ │ ├── AnimatedBanner.tsx +│ │ ├── BatchTui.tsx +│ │ ├── BatchTuiAzure.tsx +│ │ └── tui.tsx │ └── utils/ │ ├── fs.ts # File system helpers -│ ├── detection.ts # Language/framework detection │ └── logger.ts # Styled console output ├── package.json ├── tsconfig.json @@ -476,24 +506,24 @@ Create example repos for each major stack: # Install dependencies npm install -# Development with watch mode -npm run dev - # Build for production npm run build -# Run tests -npm test - # Lint and format npm run lint npm run format +# Type check +npm run typecheck + +# Run tests +npm run test + +# Coverage +npm run test:coverage + # Link globally for testing npm link - -# Create standalone binaries -npm run package ``` --- diff --git a/README.md b/README.md index 7c5dd6c..ab2da0a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ > Prime your repositories for AI-assisted development. +[![CI](https://github.com/pierceboggan/primer/actions/workflows/ci.yml/badge.svg)](https://github.com/pierceboggan/primer/actions/workflows/ci.yml) +[![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) + Primer is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants understand your project better. It supports single repos, batch processing across organizations, and includes an evaluation framework to measure instruction effectiveness. ![Primer](primer.png) @@ -12,6 +15,7 @@ Primer is a CLI tool that analyzes your codebase and generates `.github/copilot- - **AI-Powered Generation** - Uses the Copilot SDK to analyze your codebase and generate context-aware instructions - **Batch Processing** - Process multiple repos across organizations with a single command - **Evaluation Framework** - Test and measure how well your instructions improve AI responses +- **Readiness Report** - Score AI readiness across key pillars with a fix-first checklist - **GitHub Integration** - Clone repos, create branches, and open PRs automatically - **Interactive TUI** - Beautiful terminal interface built with Ink - **Config Generation** - Generate MCP and VS Code configurations @@ -22,14 +26,31 @@ Primer is a CLI tool that analyzes your codebase and generates `.github/copilot- 2. **GitHub Copilot CLI** - Installed via VS Code's Copilot Chat extension 3. **Copilot CLI Authentication** - Run `copilot` then `/login` to authenticate 4. **GitHub CLI (optional)** - For batch processing and PR creation: `brew install gh && gh auth login` +5. **Azure DevOps PAT (optional)** - For Azure DevOps batch/PR workflows: set `AZURE_DEVOPS_PAT` ## Installation ```bash -# Clone and install +# Install from npm +npm install -g primer +``` + +### Quick Install + +```bash +primer --help +``` + +### Local Development Install + +```bash +# Clone and install dependencies git clone https://github.com/pierceboggan/primer.git cd primer npm install + +# Build and link the local CLI +npm run build ``` ## Usage @@ -40,26 +61,29 @@ The easiest way to get started is with the `init` command: ```bash # Interactive setup for current directory -npx tsx src/index.ts init +primer init # Accept defaults and generate instructions automatically -npx tsx src/index.ts init --yes +primer init --yes # Work with a GitHub repository -npx tsx src/index.ts init --github +primer init --github + +# Work with an Azure DevOps repository +primer init --provider azure ``` ### Interactive Mode (TUI) ```bash # Run TUI in current directory -npx tsx src/index.ts tui +primer tui # Run on a specific repo -npx tsx src/index.ts tui --repo /path/to/repo +primer tui --repo /path/to/repo # Skip the animated intro -npx tsx src/index.ts tui --no-animation +primer tui --no-animation ``` **Keys:** @@ -73,13 +97,13 @@ npx tsx src/index.ts tui --no-animation ```bash # Generate instructions for current directory -npx tsx src/index.ts instructions +primer instructions # Generate for specific repo with custom output -npx tsx src/index.ts instructions --repo /path/to/repo --output ./instructions.md +primer instructions --repo /path/to/repo --output ./instructions.md # Use a specific model -npx tsx src/index.ts instructions --model gpt-5 +primer instructions --model gpt-5 ``` ### Batch Processing @@ -88,10 +112,13 @@ Process multiple repositories across organizations: ```bash # Launch batch TUI -npx tsx src/index.ts batch +primer batch + +# Launch batch TUI for Azure DevOps +primer batch --provider azure # Save results to file -npx tsx src/index.ts batch --output results.json +primer batch --output results.json ``` **Batch TUI Keys:** @@ -105,31 +132,53 @@ npx tsx src/index.ts batch --output results.json ```bash # Analyze current directory -npx tsx src/index.ts analyze +primer analyze # Analyze specific path with JSON output -npx tsx src/index.ts analyze /path/to/repo --json +primer analyze /path/to/repo --json ``` +### Readiness Report + +Assess how ready a repository is for AI agents and get a prioritized checklist of fixes: + +```bash +# Run readiness report in current directory +primer readiness + +# Run readiness report on a specific repo +primer readiness /path/to/repo + +# Output JSON only +primer readiness --json + +# Write JSON report to a file +primer readiness --output readiness.json +``` + +### Examples + +See [examples/README.md](examples/README.md) for quick usage snippets and a sample eval config. + ### Generate Configs Generate configuration files for your repo: ```bash # Generate MCP config -npx tsx src/index.ts generate mcp +primer generate mcp # Generate VS Code settings -npx tsx src/index.ts generate vscode --force +primer generate vscode --force # Generate custom prompts -npx tsx src/index.ts generate prompts +primer generate prompts # Generate agent configs -npx tsx src/index.ts generate agents +primer generate agents # Generate .aiignore file -npx tsx src/index.ts generate aiignore +primer generate aiignore ``` ### Manage Templates @@ -137,7 +186,7 @@ npx tsx src/index.ts generate aiignore View available instruction templates: ```bash -npx tsx src/index.ts templates +primer templates ``` ### Configuration @@ -145,7 +194,7 @@ npx tsx src/index.ts templates View and manage Primer configuration: ```bash -npx tsx src/index.ts config +primer config ``` ### Update @@ -153,7 +202,7 @@ npx tsx src/index.ts config Check for and apply updates: ```bash -npx tsx src/index.ts update +primer update ``` ### Create Pull Requests @@ -162,10 +211,13 @@ Automatically create a PR to add Primer configs to a repository: ```bash # Create PR for a GitHub repo -npx tsx src/index.ts pr owner/repo-name +primer pr owner/repo-name # Use custom branch name -npx tsx src/index.ts pr owner/repo-name --branch primer/custom-branch +primer pr owner/repo-name --branch primer/custom-branch + +# Create PR for an Azure DevOps repo (org/project/repo) +primer pr my-org/my-project/my-repo --provider azure ``` ### Evaluation Framework @@ -174,19 +226,22 @@ Test how well your instructions improve AI responses: ```bash # Create a starter eval config -npx tsx src/index.ts eval --init +primer eval --init # Run evaluation -npx tsx src/index.ts eval primer.eval.json --repo /path/to/repo +primer eval primer.eval.json --repo /path/to/repo # Save results and use specific models -npx tsx src/index.ts eval --output results.json --model gpt-5 --judge-model gpt-5 +primer eval --output results.json --model gpt-5 --judge-model gpt-5 ``` +When `--output` is provided (or `outputPath` is set in the eval config), Primer writes a JSON report that includes per-case metrics and trajectory events, and also generates a companion HTML trajectory viewer next to the JSON file. + Example `primer.eval.json`: ```json { "instructionFile": ".github/copilot-instructions.md", + "outputPath": "eval-results.json", "cases": [ { "id": "project-overview", @@ -264,8 +319,23 @@ primer/ # Type check npx tsc -p tsconfig.json --noEmit -# Run in dev mode -npx tsx src/index.ts +# Lint +npm run lint + +# Format +npm run format + +# Test +npm run test + +# Coverage +npm run test:coverage + +# Build and link the local CLI +npm run build + +# Run locally +primer ``` ## Troubleshooting diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..0f09971 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security issues privately by emailing the maintainer or opening a GitHub security advisory. Avoid filing public issues for vulnerabilities. + +We aim to respond within 72 hours and will work with you on remediation and disclosure. diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..309d504 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,45 @@ +import js from "@eslint/js"; +import tseslint from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import eslintConfigPrettier from "eslint-config-prettier"; +import importPlugin from "eslint-plugin-import"; +import nPlugin from "eslint-plugin-n"; +import promisePlugin from "eslint-plugin-promise"; + +const sourceGlobs = ["**/*.{ts,tsx,js,jsx}"]; + +export default [ + { + ignores: ["dist/**", "node_modules/**", "coverage/**"] + }, + js.configs.recommended, + { + files: sourceGlobs, + languageOptions: { + parser: tsParser, + parserOptions: { + project: "./tsconfig.json", + sourceType: "module", + ecmaVersion: "latest" + } + }, + plugins: { + "@typescript-eslint": tseslint, + import: importPlugin, + n: nPlugin, + promise: promisePlugin + }, + rules: { + "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }], + "@typescript-eslint/consistent-type-imports": ["warn", { "prefer": "type-imports" }], + "import/order": [ + "warn", + { + "newlines-between": "always", + "alphabetize": { "order": "asc", "caseInsensitive": true } + } + ] + } + }, + eslintConfigPrettier +]; diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..1be29f8 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,14 @@ +# Primer Examples + +This folder includes quick examples to help you get started. + +## CLI usage + +- Analyze a repo: primer analyze /path/to/repo +- Generate instructions: primer instructions --repo /path/to/repo +- Run readiness: primer readiness /path/to/repo +- Run evals: primer eval primer.eval.json --repo /path/to/repo + +## Sample eval config + +See primer.eval.json for a starter eval config you can customize. diff --git a/examples/primer.eval.json b/examples/primer.eval.json new file mode 100644 index 0000000..1294fb1 --- /dev/null +++ b/examples/primer.eval.json @@ -0,0 +1,15 @@ +{ + "instructionFile": ".github/copilot-instructions.md", + "cases": [ + { + "id": "project-overview", + "prompt": "Summarize what this project does and list the main entry points.", + "expectation": "Should mention the primary purpose and key files/directories." + }, + { + "id": "build-commands", + "prompt": "How do I build and test this project?", + "expectation": "Should provide the correct build and test commands from package.json or equivalent." + } + ] +} diff --git a/package.json b/package.json index 2a15771..bf64dc8 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,17 @@ "name": "primer", "version": "1.0.0", "description": "", - "main": "index.js", + "main": "dist/index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "tsc && npm link", + "prepare": "tsc", + "lint": "eslint .", + "format": "prettier --write .", + "format:check": "prettier --check .", + "typecheck": "tsc -p tsconfig.json --noEmit", + "test": "vitest run", + "test:watch": "vitest", + "test:coverage": "vitest run --coverage" }, "keywords": [], "author": "", @@ -23,9 +31,19 @@ "devDependencies": { "@types/node": "^25.1.0", "@types/react": "^19.2.10", + "@typescript-eslint/eslint-plugin": "^8.5.0", + "@typescript-eslint/parser": "^8.5.0", + "@vitest/coverage-v8": "^2.1.4", + "eslint": "^9.7.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.30.0", + "eslint-plugin-n": "^17.10.2", + "eslint-plugin-promise": "^7.1.0", + "prettier": "^3.3.3", "tsup": "^8.5.1", "tsx": "^4.21.0", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "vitest": "^2.1.4" }, "type": "module", "bin": { diff --git a/primer.eval.json b/primer.eval.json index 3b77578..bc1fa99 100644 --- a/primer.eval.json +++ b/primer.eval.json @@ -7,4 +7,4 @@ "expectation": "Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI." } ] -} +} \ No newline at end of file diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..0ef4665 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,9 @@ +{ + "release-type": "node", + "packages": { + ".": { + "package-name": "primer", + "changelog-path": "CHANGELOG.md" + } + } +} diff --git a/release-please-manifest.json b/release-please-manifest.json new file mode 100644 index 0000000..37fcefa --- /dev/null +++ b/release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "1.0.0" +} diff --git a/src/cli.ts b/src/cli.ts index 86bcf74..3a667c1 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,6 +10,7 @@ import { evalCommand } from "./commands/eval"; import { tuiCommand } from "./commands/tui"; import { instructionsCommand } from "./commands/instructions"; import { batchCommand } from "./commands/batch"; +import { readinessCommand } from "./commands/readiness"; export function runCli(argv: string[]): void { const program = new Command(); @@ -23,6 +24,7 @@ export function runCli(argv: string[]): void { .command("init") .argument("[path]", "Path to a local repository") .option("--github", "Use a GitHub repository") + .option("--provider ", "Repo provider (github|azure)") .option("--yes", "Accept defaults and skip prompts") .option("--force", "Overwrite existing files") .action(initCommand); @@ -42,8 +44,9 @@ export function runCli(argv: string[]): void { program .command("pr") - .argument("[repo]", "GitHub repo in owner/name form") - .option("--branch ", "Branch name", "primer/add-configs") + .argument("[repo]", "Repo identifier (github: owner/name, azure: org/project/repo)") + .option("--branch ", "Branch name") + .option("--provider ", "Repo provider (github|azure)") .action(prCommand); program @@ -69,10 +72,18 @@ export function runCli(argv: string[]): void { .option("--model ", "Model for instructions generation", "gpt-4.1") .action(instructionsCommand); + program + .command("readiness") + .argument("[path]", "Path to a local repository") + .option("--json", "Output JSON") + .option("--output ", "Write JSON report to file") + .action(readinessCommand); + program .command("batch") .description("Batch process multiple repos across orgs") .option("--output ", "Write results JSON to file") + .option("--provider ", "Repo provider (github|azure)", "github") .action(batchCommand); program.command("templates").action(templatesCommand); diff --git a/src/commands/batch.tsx b/src/commands/batch.tsx index eb69267..bce2c3f 100644 --- a/src/commands/batch.tsx +++ b/src/commands/batch.tsx @@ -2,14 +2,41 @@ import React from "react"; import { render } from "ink"; import { BatchTui } from "../ui/BatchTui"; import { getGitHubToken } from "../services/github"; +import { BatchTuiAzure } from "../ui/BatchTuiAzure"; +import { getAzureDevOpsToken } from "../services/azureDevops"; type BatchOptions = { output?: string; + provider?: string; }; export async function batchCommand(options: BatchOptions): Promise { + const provider = options.provider ?? "github"; + if (provider !== "github" && provider !== "azure") { + console.error("Invalid provider. Use github or azure."); + process.exitCode = 1; + return; + } + + if (provider === "azure") { + const token = getAzureDevOpsToken(); + if (!token) { + console.error("Error: Azure DevOps authentication required."); + console.error(""); + console.error("Set a PAT environment variable:"); + console.error(" export AZURE_DEVOPS_PAT="); + process.exitCode = 1; + return; + } + + const { waitUntilExit } = render( + + ); + await waitUntilExit(); + return; + } + const token = await getGitHubToken(); - if (!token) { console.error("Error: GitHub authentication required."); console.error(""); diff --git a/src/commands/eval.ts b/src/commands/eval.ts index b875f97..bee399d 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -53,7 +53,7 @@ export async function evalCommand(configPathArg: string | undefined, options: Ev const configPath = path.resolve(configPathArg ?? path.join(repoPath, "primer.eval.json")); - const { summary } = await runEval({ + const { summary, viewerPath } = await runEval({ configPath, repoPath, model: options.model ?? "gpt-5", @@ -62,4 +62,7 @@ export async function evalCommand(configPathArg: string | undefined, options: Ev }); console.log(summary); + if (viewerPath) { + console.log(`Trajectory viewer: ${viewerPath}`); + } } diff --git a/src/commands/init.ts b/src/commands/init.ts index 4f22389..2c6ed94 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -4,21 +4,38 @@ import { checkbox, select } from "@inquirer/prompts"; import { analyzeRepo } from "../services/analyzer"; import { generateConfigs } from "../services/generator"; import { GitHubRepo, listAccessibleRepos } from "../services/github"; -import { cloneRepo, isGitRepo } from "../services/git"; +import { + AzureDevOpsOrg, + AzureDevOpsProject, + AzureDevOpsRepo, + getAzureDevOpsToken, + listOrganizations, + listProjects, + listRepos +} from "../services/azureDevops"; +import { buildAuthedUrl, cloneRepo, isGitRepo } from "../services/git"; import { generateCopilotInstructions } from "../services/instructions"; import { ensureDir } from "../utils/fs"; import { prettyPrintSummary } from "../utils/logger"; type InitOptions = { github?: boolean; + provider?: string; yes?: boolean; force?: boolean; }; export async function initCommand(repoPathArg: string | undefined, options: InitOptions): Promise { let repoPath = path.resolve(repoPathArg ?? process.cwd()); + const provider = options.provider ?? (options.github ? "github" : undefined); - if (options.github) { + if (provider && provider !== "github" && provider !== "azure") { + console.error("Invalid provider. Use github or azure."); + process.exitCode = 1; + return; + } + + if (provider === "github") { const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN; if (!token) { console.error("Set GITHUB_TOKEN or GH_TOKEN to use GitHub mode."); @@ -50,6 +67,70 @@ export async function initCommand(repoPathArg: string | undefined, options: Init await cloneRepo(selection.cloneUrl, repoPath); } } + + if (provider === "azure") { + const token = getAzureDevOpsToken(); + if (!token) { + console.error("Set AZURE_DEVOPS_PAT (or AZDO_PAT) to use Azure DevOps mode."); + process.exitCode = 1; + return; + } + + const orgs = await listOrganizations(token); + if (orgs.length === 0) { + console.error("No Azure DevOps organizations found."); + process.exitCode = 1; + return; + } + + const orgSelection = await select({ + message: "Choose an Azure DevOps organization", + choices: orgs.map((org) => ({ + name: org.name, + value: org + })) + }); + + const projects = await listProjects(token, orgSelection.name); + if (projects.length === 0) { + console.error("No Azure DevOps projects found."); + process.exitCode = 1; + return; + } + + const projectSelection = await select({ + message: "Choose an Azure DevOps project", + choices: projects.map((project) => ({ + name: project.name, + value: project + })) + }); + + const repos = await listRepos(token, orgSelection.name, projectSelection.name); + if (repos.length === 0) { + console.error("No Azure DevOps repositories found."); + process.exitCode = 1; + return; + } + + const repoSelection = await select({ + message: "Choose a repository", + choices: repos.map((repo) => ({ + name: `${repo.name}${repo.isPrivate ? " (private)" : ""}`, + value: repo + })) + }); + + const cacheRoot = path.join(process.cwd(), ".primer-cache"); + repoPath = path.join(cacheRoot, orgSelection.name, projectSelection.name, repoSelection.name); + await ensureDir(repoPath); + + const hasGit = await isGitRepo(repoPath); + if (!hasGit) { + const authedUrl = buildAuthedUrl(repoSelection.cloneUrl, token, "azure"); + await cloneRepo(authedUrl, repoPath); + } + } const analysis = await analyzeRepo(repoPath); prettyPrintSummary(analysis); diff --git a/src/commands/pr.ts b/src/commands/pr.ts index d8ce79b..7050840 100644 --- a/src/commands/pr.ts +++ b/src/commands/pr.ts @@ -1,21 +1,88 @@ import path from "path"; +import fs from "fs/promises"; import { analyzeRepo } from "../services/analyzer"; import { generateConfigs } from "../services/generator"; import { createPullRequest, getRepo } from "../services/github"; -import { checkoutBranch, cloneRepo, commitAll, isGitRepo, pushBranch } from "../services/git"; +import { generateCopilotInstructions } from "../services/instructions"; +import { + createPullRequest as createAzurePullRequest, + getAzureDevOpsToken, + getRepo as getAzureRepo +} from "../services/azureDevops"; +import { buildAuthedUrl, checkoutBranch, cloneRepo, commitAll, isGitRepo, pushBranch } from "../services/git"; import { ensureDir } from "../utils/fs"; type PrOptions = { branch?: string; + provider?: string; }; export async function prCommand(repo: string | undefined, options: PrOptions): Promise { + const provider = options.provider ?? "github"; + if (provider !== "github" && provider !== "azure") { + console.error("Invalid provider. Use github or azure."); + process.exitCode = 1; + return; + } + if (!repo) { - console.error("Provide a repo in owner/name form."); + console.error("Provide a repo identifier (github: owner/name, azure: org/project/repo)."); process.exitCode = 1; return; } + if (provider === "azure") { + const token = getAzureDevOpsToken(); + if (!token) { + console.error("Set AZURE_DEVOPS_PAT (or AZDO_PAT) to use Azure DevOps PR automation."); + process.exitCode = 1; + return; + } + + const [organization, project, name] = repo.split("/"); + if (!organization || !project || !name) { + console.error("Invalid Azure DevOps repo format. Use org/project/repo."); + process.exitCode = 1; + return; + } + + const repoInfo = await getAzureRepo(token, organization, project, name); + const cacheRoot = path.join(process.cwd(), ".primer-cache"); + const repoPath = path.join(cacheRoot, organization, project, name); + await ensureDir(repoPath); + + if (!(await isGitRepo(repoPath))) { + const authedUrl = buildAuthedUrl(repoInfo.cloneUrl, token, "azure"); + await cloneRepo(authedUrl, repoPath); + } + + const branch = options.branch ?? "primer/add-instructions"; + await checkoutBranch(repoPath, branch); + + const instructions = await generateCopilotInstructions({ repoPath, model: "gpt-4.1" }); + const instructionsPath = path.join(repoPath, ".github", "copilot-instructions.md"); + await ensureDir(path.dirname(instructionsPath)); + await fs.writeFile(instructionsPath, instructions, "utf8"); + + await commitAll(repoPath, "chore: add copilot instructions via Primer"); + await pushBranch(repoPath, branch, token, "azure"); + + const prUrl = await createAzurePullRequest({ + token, + organization, + project, + repoId: repoInfo.id, + repoName: repoInfo.name, + title: "🤖 Add Copilot instructions via Primer", + body: buildInstructionsPrBody(), + sourceBranch: branch, + targetBranch: repoInfo.defaultBranch + }); + + console.log(`Created PR: ${prUrl}`); + return; + } + const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN; if (!token) { console.error("Set GITHUB_TOKEN or GH_TOKEN to use PR automation."); @@ -89,3 +156,29 @@ function buildPrBody(): string { "*Generated by Primer*" ].join("\n"); } + +function buildInstructionsPrBody(): string { + return [ + "## 🤖 Copilot Instructions Added", + "", + "This PR adds a `.github/copilot-instructions.md` file to help GitHub Copilot understand this codebase better.", + "", + "### What's Included", + "", + "The instructions file contains:", + "- Project overview and architecture", + "- Tech stack and conventions", + "- Build/test commands", + "- Key directories and files", + "", + "### Benefits", + "", + "With these instructions, Copilot will:", + "- Generate more contextually-aware code suggestions", + "- Follow project-specific patterns and conventions", + "- Understand the codebase structure", + "", + "---", + "*Generated by [Primer](https://github.com/pierceboggan/primer) - Prime your repos for AI*" + ].join("\n"); +} diff --git a/src/commands/readiness.ts b/src/commands/readiness.ts new file mode 100644 index 0000000..c2b65fa --- /dev/null +++ b/src/commands/readiness.ts @@ -0,0 +1,120 @@ +import path from "path"; +import fs from "fs/promises"; +import chalk from "chalk"; +import { + ReadinessReport, + ReadinessCriterionResult, + runReadinessReport +} from "../services/readiness"; + +type ReadinessOptions = { + json?: boolean; + output?: string; +}; + +export async function readinessCommand(repoPathArg: string | undefined, options: ReadinessOptions): Promise { + const repoPath = path.resolve(repoPathArg ?? process.cwd()); + const report = await runReadinessReport({ repoPath }); + + if (options.output) { + const outputPath = path.resolve(options.output); + await fs.writeFile(outputPath, JSON.stringify(report, null, 2), "utf8"); + } + + if (options.json) { + console.log(JSON.stringify(report, null, 2)); + return; + } + + printReadinessChecklist(report); +} + +function printReadinessChecklist(report: ReadinessReport): void { + console.log(chalk.bold("Readiness report")); + console.log(`- Repo: ${report.repoPath}`); + console.log(`- Monorepo: ${report.isMonorepo ? "yes" : "no"}${report.apps.length ? ` (${report.apps.length} apps)` : ""}`); + console.log(`- Level: ${report.achievedLevel || 1} (${levelName(report.achievedLevel || 1)})`); + + console.log(chalk.bold("\nPillars")); + for (const pillar of report.pillars) { + const rate = formatPercent(pillar.passRate); + const icon = pillar.passRate >= 0.8 ? chalk.green("●") : chalk.yellow("●"); + console.log(`${icon} ${pillar.name}: ${pillar.passed}/${pillar.total} (${rate})`); + } + + console.log(chalk.bold("\nFix first")); + const fixes = rankFixes(report.criteria); + if (!fixes.length) { + console.log(chalk.green("✔ No failing criteria detected.")); + } else { + for (const fix of fixes) { + const impact = colorImpact(fix.impact); + const effort = colorEffort(fix.effort); + const scope = fix.scope === "app" ? "app" : "repo"; + const detail = fix.appSummary + ? ` (${fix.appSummary.passed}/${fix.appSummary.total} apps)` + : ""; + console.log(`- ${impact} impact / ${effort} effort • ${fix.title}${detail} [${scope}]`); + if (fix.reason) { + console.log(` ${chalk.dim(fix.reason)}`); + } + if (fix.appFailures?.length) { + console.log(` ${chalk.dim(`Apps: ${fix.appFailures.join(", ")}`)}`); + } + } + } + + if (report.extras.length) { + console.log(chalk.bold("\nAI readiness extras")); + for (const extra of report.extras) { + const icon = extra.status === "pass" ? chalk.green("✔") : chalk.red("✖"); + console.log(`${icon} ${extra.title}`); + } + } +} + +function rankFixes(criteria: ReadinessCriterionResult[]): ReadinessCriterionResult[] { + return criteria + .filter((criterion) => criterion.status === "fail") + .sort((a, b) => { + const impactDelta = impactWeight(b.impact) - impactWeight(a.impact); + if (impactDelta !== 0) return impactDelta; + return effortWeight(a.effort) - effortWeight(b.effort); + }); +} + +function impactWeight(value: "high" | "medium" | "low"): number { + if (value === "high") return 3; + if (value === "medium") return 2; + return 1; +} + +function effortWeight(value: "low" | "medium" | "high"): number { + if (value === "low") return 1; + if (value === "medium") return 2; + return 3; +} + +function colorImpact(value: "high" | "medium" | "low"): string { + if (value === "high") return chalk.red("High"); + if (value === "medium") return chalk.yellow("Medium"); + return chalk.green("Low"); +} + +function colorEffort(value: "low" | "medium" | "high"): string { + if (value === "high") return chalk.red("High"); + if (value === "medium") return chalk.yellow("Medium"); + return chalk.green("Low"); +} + +function formatPercent(value: number): string { + return `${Math.round(value * 100)}%`; +} + +function levelName(level: number): string { + if (level === 2) return "Documented"; + if (level === 3) return "Standardized"; + if (level === 4) return "Optimized"; + if (level === 5) return "Autonomous"; + return "Functional"; +} \ No newline at end of file diff --git a/src/services/__tests__/analyzer.test.ts b/src/services/__tests__/analyzer.test.ts new file mode 100644 index 0000000..724678f --- /dev/null +++ b/src/services/__tests__/analyzer.test.ts @@ -0,0 +1,31 @@ +import fs from "fs/promises"; +import os from "os"; +import path from "path"; +import { describe, expect, it } from "vitest"; + +import { analyzeRepo } from "../analyzer"; + +describe("analyzeRepo", () => { + it("detects TypeScript and npm workspace", async () => { + const repoPath = await fs.mkdtemp(path.join(os.tmpdir(), "primer-test-")); + const packageJson = { + name: "demo", + workspaces: ["packages/*"], + dependencies: { react: "^19.0.0" } + }; + + await fs.writeFile(path.join(repoPath, "package.json"), JSON.stringify(packageJson, null, 2)); + await fs.writeFile(path.join(repoPath, "tsconfig.json"), "{}", "utf8"); + await fs.mkdir(path.join(repoPath, "packages", "app"), { recursive: true }); + await fs.writeFile( + path.join(repoPath, "packages", "app", "package.json"), + JSON.stringify({ name: "app", scripts: { build: "tsc" } }, null, 2) + ); + + const result = await analyzeRepo(repoPath); + + expect(result.languages).toContain("TypeScript"); + expect(result.workspaceType).toBe("npm"); + expect(result.apps?.length).toBe(1); + }); +}); diff --git a/src/services/analyzer.ts b/src/services/analyzer.ts index bd1b28a..a9e0566 100644 --- a/src/services/analyzer.ts +++ b/src/services/analyzer.ts @@ -1,13 +1,26 @@ import fs from "fs/promises"; import path from "path"; +import fg from "fast-glob"; import { isGitRepo } from "./git"; +export type RepoApp = { + name: string; + path: string; + packageJsonPath: string; + scripts: Record; + hasTsConfig: boolean; +}; + export type RepoAnalysis = { path: string; isGitRepo: boolean; languages: string[]; frameworks: string[]; packageManager?: string; + isMonorepo?: boolean; + workspaceType?: "npm" | "pnpm" | "yarn"; + workspacePatterns?: string[]; + apps?: RepoApp[]; }; const PACKAGE_MANAGERS: Array<{ file: string; name: string }> = [ @@ -41,15 +54,27 @@ export async function analyzeRepo(repoPath: string): Promise { analysis.packageManager = await detectPackageManager(repoPath, files); + let rootPackageJson: Record | undefined; + if (hasPackageJson) { - const packageJson = await readJson(path.join(repoPath, "package.json")); + rootPackageJson = await readJson(path.join(repoPath, "package.json")); const deps = Object.keys({ - ...(packageJson?.dependencies ?? {}), - ...(packageJson?.devDependencies ?? {}) + ...(rootPackageJson?.dependencies ?? {}), + ...(rootPackageJson?.devDependencies ?? {}) }); analysis.frameworks.push(...detectFrameworks(deps, files)); } + const workspace = await detectWorkspace(repoPath, files, rootPackageJson); + if (workspace) { + analysis.workspaceType = workspace.type; + analysis.workspacePatterns = workspace.patterns; + } + + const apps = await resolveWorkspaceApps(repoPath, workspace?.patterns ?? [], rootPackageJson); + analysis.apps = apps; + analysis.isMonorepo = apps.length > 1; + analysis.languages = unique(analysis.languages); analysis.frameworks = unique(analysis.frameworks); @@ -99,6 +124,117 @@ async function readJson(filePath: string): Promise | und } } +type WorkspaceConfig = { + type: "npm" | "pnpm" | "yarn"; + patterns: string[]; +}; + +async function detectWorkspace( + repoPath: string, + files: string[], + packageJson?: Record +): Promise { + if (files.includes("pnpm-workspace.yaml")) { + const patterns = await readPnpmWorkspace(path.join(repoPath, "pnpm-workspace.yaml")); + if (patterns.length) return { type: "pnpm", patterns }; + } + + const workspaces = packageJson?.workspaces; + if (Array.isArray(workspaces)) { + return { type: files.includes("yarn.lock") ? "yarn" : "npm", patterns: workspaces.map(String) }; + } + + if (workspaces && typeof workspaces === "object") { + const packages = (workspaces as { packages?: unknown }).packages; + if (Array.isArray(packages)) { + return { type: files.includes("yarn.lock") ? "yarn" : "npm", patterns: packages.map(String) }; + } + } + + return undefined; +} + +async function readPnpmWorkspace(filePath: string): Promise { + try { + const raw = await fs.readFile(filePath, "utf8"); + const lines = raw.split(/\r?\n/u); + const patterns: string[] = []; + let inPackages = false; + for (const line of lines) { + if (!inPackages && /^\s*packages\s*:/u.test(line)) { + inPackages = true; + continue; + } + if (inPackages) { + const match = line.match(/^\s*-\s*(.+)$/u); + if (match?.[1]) { + patterns.push(match[1].trim().replace(/^['"]|['"]$/gu, "")); + continue; + } + if (/^\S/u.test(line)) break; + } + } + return patterns; + } catch { + return []; + } +} + +async function resolveWorkspaceApps( + repoPath: string, + patterns: string[], + rootPackageJson?: Record +): Promise { + const workspacePatterns = patterns + .map((pattern) => pattern.replace(/\\/gu, "/")) + .map((pattern) => (pattern.endsWith("package.json") ? pattern : path.posix.join(pattern, "package.json"))); + + const packageJsonPaths = workspacePatterns.length + ? await fg(workspacePatterns, { cwd: repoPath, absolute: true, onlyFiles: true, dot: false }) + : []; + + if (!packageJsonPaths.length && rootPackageJson) { + const rootPath = path.join(repoPath, "package.json"); + return [await buildRepoApp(repoPath, rootPath, rootPackageJson)]; + } + + const apps = await Promise.all( + packageJsonPaths.map(async (pkgPath) => { + const pkg = await readJson(pkgPath); + return buildRepoApp(path.dirname(pkgPath), pkgPath, pkg); + }) + ); + + return apps.filter(Boolean) as RepoApp[]; +} + +async function buildRepoApp( + appPath: string, + packageJsonPath: string, + packageJson?: Record +): Promise { + const scripts = (packageJson?.scripts ?? {}) as Record; + const name = typeof packageJson?.name === "string" ? packageJson.name : path.basename(appPath); + const hasTsConfig = await fileExists(path.join(appPath, "tsconfig.json")); + + return { + name, + path: appPath, + packageJsonPath, + scripts, + hasTsConfig + }; +} + +async function fileExists(filePath: string): Promise { + try { + await fs.access(filePath); + return true; + } catch { + return false; + } +} + function unique(items: T[]): T[] { return Array.from(new Set(items)); } diff --git a/src/services/azureDevops.ts b/src/services/azureDevops.ts new file mode 100644 index 0000000..bebe975 --- /dev/null +++ b/src/services/azureDevops.ts @@ -0,0 +1,235 @@ +type AzureDevOpsProfileResponse = { + id: string; + displayName: string; +}; + +type AzureDevOpsAccountResponse = { + accountId: string; + accountName: string; + accountUri: string; +}; + +type AzureDevOpsListResponse = { + value: T[]; +}; + +type AzureDevOpsProjectResponse = { + id: string; + name: string; + url: string; +}; + +type AzureDevOpsRepoResponse = { + id: string; + name: string; + webUrl: string; + remoteUrl: string; + isPrivate: boolean; + defaultBranch?: string; + project?: { + id: string; + name: string; + }; +}; + +export type AzureDevOpsOrg = { + id: string; + name: string; + url: string; +}; + +export type AzureDevOpsProject = { + id: string; + name: string; + organization: string; + url: string; +}; + +export type AzureDevOpsRepo = { + id: string; + name: string; + organization: string; + project: string; + projectId: string; + webUrl: string; + cloneUrl: string; + isPrivate: boolean; + defaultBranch: string; + hasInstructions?: boolean; +}; + +const PROFILE_URL = "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=7.1-preview.1"; + +function getAuthHeader(token: string): string { + const encoded = Buffer.from(`:${token}`).toString("base64"); + return `Basic ${encoded}`; +} + +async function adoRequest(url: string, token: string, init?: RequestInit): Promise { + const response = await fetch(url, { + ...init, + headers: { + "Content-Type": "application/json", + Authorization: getAuthHeader(token), + ...(init?.headers ?? {}) + } + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`Azure DevOps request failed (${response.status}): ${text}`); + } + + return (await response.json()) as T; +} + +export function getAzureDevOpsToken(): string | null { + return process.env.AZURE_DEVOPS_PAT ?? process.env.AZDO_PAT ?? null; +} + +export async function listOrganizations(token: string): Promise { + const profile = await adoRequest(PROFILE_URL, token); + const accountsUrl = `https://app.vssps.visualstudio.com/_apis/accounts?memberId=${profile.id}&api-version=7.1-preview.1`; + const accounts = await adoRequest>(accountsUrl, token); + + return accounts.value.map((account) => ({ + id: account.accountId, + name: account.accountName, + url: account.accountUri + })); +} + +export async function listProjects(token: string, organization: string): Promise { + const url = `https://dev.azure.com/${organization}/_apis/projects?stateFilter=wellFormed&api-version=7.1-preview.1`; + const response = await adoRequest>(url, token); + + return response.value.map((project) => ({ + id: project.id, + name: project.name, + organization, + url: project.url + })); +} + +export async function listRepos(token: string, organization: string, project: string): Promise { + const url = `https://dev.azure.com/${organization}/${project}/_apis/git/repositories?api-version=7.1-preview.1`; + const response = await adoRequest>(url, token); + + return response.value.map((repo) => ({ + id: repo.id, + name: repo.name, + organization, + project, + projectId: repo.project?.id ?? "", + webUrl: repo.webUrl, + cloneUrl: repo.remoteUrl, + isPrivate: repo.isPrivate, + defaultBranch: repo.defaultBranch ?? "refs/heads/main" + })); +} + +export async function getRepo( + token: string, + organization: string, + project: string, + repo: string +): Promise { + const url = `https://dev.azure.com/${organization}/${project}/_apis/git/repositories/${repo}?api-version=7.1-preview.1`; + const response = await adoRequest(url, token); + + return { + id: response.id, + name: response.name, + organization, + project, + projectId: response.project?.id ?? "", + webUrl: response.webUrl, + cloneUrl: response.remoteUrl, + isPrivate: response.isPrivate, + defaultBranch: response.defaultBranch ?? "refs/heads/main" + }; +} + +function toRefName(branch: string): string { + if (branch.startsWith("refs/")) return branch; + return `refs/heads/${branch}`; +} + +export async function createPullRequest(params: { + token: string; + organization: string; + project: string; + repoId: string; + repoName: string; + title: string; + body: string; + sourceBranch: string; + targetBranch: string; +}): Promise { + const url = `https://dev.azure.com/${params.organization}/${params.project}/_apis/git/repositories/${params.repoId}/pullrequests?api-version=7.1-preview.1`; + const payload = { + title: params.title, + description: params.body, + sourceRefName: toRefName(params.sourceBranch), + targetRefName: toRefName(params.targetBranch) + }; + + const response = await adoRequest<{ pullRequestId: number }>(url, params.token, { + method: "POST", + body: JSON.stringify(payload) + }); + + return `https://dev.azure.com/${params.organization}/${params.project}/_git/${encodeURIComponent( + params.repoName + )}/pullrequest/${response.pullRequestId}`; +} + +export async function checkRepoHasInstructions( + token: string, + organization: string, + project: string, + repoId: string +): Promise { + const url = `https://dev.azure.com/${organization}/${project}/_apis/git/repositories/${repoId}/items?path=/.github/copilot-instructions.md&includeContentMetadata=true&api-version=7.1-preview.1`; + const response = await fetch(url, { + headers: { + Authorization: getAuthHeader(token) + } + }); + + if (response.status === 404) { + return false; + } + + return response.ok; +} + +export async function checkReposForInstructions( + token: string, + repos: AzureDevOpsRepo[], + onProgress?: (checked: number, total: number) => void +): Promise { + const concurrency = 10; + const results: AzureDevOpsRepo[] = []; + let checked = 0; + + for (let i = 0; i < repos.length; i += concurrency) { + const batch = repos.slice(i, i + concurrency); + const checks = await Promise.all( + batch.map(async (repo) => { + const hasInstructions = await checkRepoHasInstructions( + token, + repo.organization, + repo.project, + repo.id + ); + return { ...repo, hasInstructions }; + }) + ); + results.push(...checks); + checked += batch.length; + onProgress?.(checked, repos.length); + } + + return results; +} \ No newline at end of file diff --git a/src/services/evaluator.ts b/src/services/evaluator.ts index 6a30001..adddce6 100644 --- a/src/services/evaluator.ts +++ b/src/services/evaluator.ts @@ -15,6 +15,7 @@ type EvalConfig = { instructionFile?: string; cases: EvalCase[]; systemMessage?: string; + outputPath?: string; }; type EvalRunOptions = { @@ -26,6 +27,40 @@ type EvalRunOptions = { onProgress?: (message: string) => void; }; +type TokenUsage = { + promptTokens?: number; + completionTokens?: number; + totalTokens?: number; +}; + +type ToolCallSummary = { + count: number; + byName: Record; + totalDurationMs: number; +}; + +type AskMetrics = { + durationMs: number; + tokenUsage?: TokenUsage; + toolCalls: ToolCallSummary; +}; + +type EvalMetrics = { + withoutInstructions: AskMetrics; + withInstructions: AskMetrics; + judge: AskMetrics; + totalDurationMs: number; +}; + +type EvalPhase = "withoutInstructions" | "withInstructions" | "judge"; + +type TrajectoryEvent = { + timestampMs: number; + phase: EvalPhase; + type: string; + data?: Record; +}; + export type EvalResult = { id: string; prompt: string; @@ -35,14 +70,18 @@ export type EvalResult = { verdict?: "pass" | "fail" | "unknown"; score?: number; rationale?: string; + metrics?: EvalMetrics; + trajectory?: TrajectoryEvent[]; }; -export async function runEval(options: EvalRunOptions): Promise<{ summary: string; results: EvalResult[] }> { +export async function runEval(options: EvalRunOptions): Promise<{ summary: string; results: EvalResult[]; viewerPath?: string }> { const config = await loadConfig(options.configPath); const instructionFile = config.instructionFile ?? ".github/copilot-instructions.md"; const instructionPath = path.resolve(options.repoPath, instructionFile); const instructionText = await readOptionalFile(instructionPath); const progress = options.onProgress ?? (() => {}); + const outputPath = resolveOutputPath(options.repoPath, options.outputPath, config.outputPath); + const runStartedAt = Date.now(); progress("Starting Copilot SDK..."); const cliPath = await findCopilotCliPath(); @@ -56,19 +95,22 @@ export async function runEval(options: EvalRunOptions): Promise<{ summary: strin for (const [index, testCase] of config.cases.entries()) { const id = testCase.id ?? `case-${index + 1}`; const prompt = buildPrompt(options.repoPath, testCase.prompt); + const caseStartedAt = Date.now(); progress(`Running eval ${index + 1}/${total}: ${id} (without instructions)...`); - const withoutInstructions = await askOnce(client, { + const withoutResult = await askOnce(client, { prompt, model: options.model, - systemMessage: config.systemMessage + systemMessage: config.systemMessage, + phase: "withoutInstructions" }); progress(`Running eval ${index + 1}/${total}: ${id} (with instructions)...`); - const withInstructions = await askOnce(client, { + const withResult = await askOnce(client, { prompt, model: options.model, - systemMessage: [config.systemMessage, instructionText].filter(Boolean).join("\n\n") + systemMessage: [config.systemMessage, instructionText].filter(Boolean).join("\n\n"), + phase: "withInstructions" }); progress(`Running eval ${index + 1}/${total}: ${id} (judging)...`); @@ -76,36 +118,60 @@ export async function runEval(options: EvalRunOptions): Promise<{ summary: strin model: options.judgeModel, prompt: testCase.prompt, expectation: testCase.expectation, - withoutInstructions, - withInstructions + withoutInstructions: withoutResult.content, + withInstructions: withResult.content }); + const metrics: EvalMetrics = { + withoutInstructions: withoutResult.metrics, + withInstructions: withResult.metrics, + judge: judgment.metrics, + totalDurationMs: Date.now() - caseStartedAt + }; + + const trajectory = [ + ...withoutResult.trajectory, + ...withResult.trajectory, + ...judgment.trajectory + ]; + results.push({ id, prompt: testCase.prompt, expectation: testCase.expectation, - withInstructions, - withoutInstructions, - verdict: judgment.verdict, - score: judgment.score, - rationale: judgment.rationale + withInstructions: withResult.content, + withoutInstructions: withoutResult.content, + verdict: judgment.result.verdict, + score: judgment.result.score, + rationale: judgment.result.rationale, + metrics, + trajectory }); - progress(`Eval ${index + 1}/${total}: ${id} → ${judgment.verdict} (score: ${judgment.score})`); + progress(`Eval ${index + 1}/${total}: ${id} → ${judgment.result.verdict} (score: ${judgment.result.score})`); } - if (options.outputPath) { - const output = { - repoPath: options.repoPath, - model: options.model, - judgeModel: options.judgeModel, - results - }; - await fs.writeFile(options.outputPath, JSON.stringify(output, null, 2), "utf8"); + const runFinishedAt = Date.now(); + const output = { + repoPath: options.repoPath, + model: options.model, + judgeModel: options.judgeModel, + runMetrics: { + startedAt: new Date(runStartedAt).toISOString(), + finishedAt: new Date(runFinishedAt).toISOString(), + durationMs: runFinishedAt - runStartedAt + }, + results + }; + let viewerPath: string | undefined; + if (outputPath) { + await fs.writeFile(outputPath, JSON.stringify(output, null, 2), "utf8"); + viewerPath = buildViewerPath(outputPath); + await fs.writeFile(viewerPath, buildTrajectoryViewerHtml(output), "utf8"); } - const summary = formatSummary(results); - return { summary, results }; + const summary = formatSummary(results, runFinishedAt - runStartedAt); + return { summary, results, viewerPath }; } finally { await client.stop(); } @@ -115,12 +181,19 @@ type AskOptions = { prompt: string; model: string; systemMessage?: string; + phase: EvalPhase; +}; + +type AskResult = { + content: string; + metrics: AskMetrics; + trajectory: TrajectoryEvent[]; }; async function askOnce( client: { createSession: (config?: Record) => Promise }, options: AskOptions -): Promise { +): Promise { const session = await client.createSession({ model: options.model, streaming: true, @@ -131,7 +204,10 @@ async function askOnce( }); let content = ""; + const telemetry = createTelemetry(options.phase); + const startedAt = Date.now(); session.on((event: { type: string; data?: Record }) => { + captureTelemetryEvent(event, telemetry); if (event.type === "assistant.message_delta") { const delta = event.data?.deltaContent as string | undefined; if (delta) content += delta; @@ -140,7 +216,16 @@ async function askOnce( await session.sendAndWait({ prompt: options.prompt }, 120000); await session.destroy(); - return content.trim(); + const finishedAt = Date.now(); + return { + content: content.trim(), + metrics: { + durationMs: finishedAt - startedAt, + tokenUsage: normalizeTokenUsage(telemetry.tokenUsage), + toolCalls: telemetry.toolCalls + }, + trajectory: telemetry.trajectory + }; } type JudgeOptions = { @@ -160,7 +245,7 @@ type JudgeResult = { async function judge( client: { createSession: (config?: Record) => Promise }, options: JudgeOptions -): Promise { +): Promise<{ result: JudgeResult; metrics: AskMetrics; trajectory: TrajectoryEvent[] }> { const session = await client.createSession({ model: options.model, streaming: true, @@ -171,7 +256,10 @@ async function judge( }); let content = ""; + const telemetry = createTelemetry("judge"); + const startedAt = Date.now(); session.on((event: { type: string; data?: Record }) => { + captureTelemetryEvent(event, telemetry); if (event.type === "assistant.message_delta") { const delta = event.data?.deltaContent as string | undefined; if (delta) content += delta; @@ -195,7 +283,16 @@ async function judge( await session.sendAndWait({ prompt }, 120000); await session.destroy(); - return parseJudge(content); + const finishedAt = Date.now(); + return { + result: parseJudge(content), + metrics: { + durationMs: finishedAt - startedAt, + tokenUsage: normalizeTokenUsage(telemetry.tokenUsage), + toolCalls: telemetry.toolCalls + }, + trajectory: telemetry.trajectory + }; } function parseJudge(content: string): JudgeResult { @@ -271,14 +368,18 @@ function buildPrompt(repoPath: string, userPrompt: string): string { ].join("\n"); } -function formatSummary(results: EvalResult[]): string { +function formatSummary(results: EvalResult[], runDurationMs: number): string { const total = results.length; const passed = results.filter((r) => r.verdict === "pass").length; const failed = results.filter((r) => r.verdict === "fail").length; const unknown = results.filter((r) => r.verdict === "unknown").length; + const totalUsage = aggregateTokenUsage(results); + const hasUsage = Boolean(totalUsage.promptTokens || totalUsage.completionTokens || totalUsage.totalTokens); const lines = [ - `Eval results: ${passed}/${total} pass, ${failed} fail, ${unknown} unknown.` + `Eval results: ${passed}/${total} pass, ${failed} fail, ${unknown} unknown.`, + `Runtime: ${formatDuration(runDurationMs)}.`, + hasUsage ? `Token usage: ${formatTokenUsage(totalUsage)}.` : "Token usage: unavailable." ]; for (const result of results) { @@ -289,3 +390,305 @@ function formatSummary(results: EvalResult[]): string { return `\n${lines.join("\n")}`; } + +type TelemetryCollector = { + trajectory: TrajectoryEvent[]; + tokenUsage: TokenUsage; + toolCalls: ToolCallSummary; + toolCallMap: Map; + phase: EvalPhase; +}; + +function createTelemetry(phase: EvalPhase): TelemetryCollector { + return { + trajectory: [], + tokenUsage: {}, + toolCalls: { count: 0, byName: {}, totalDurationMs: 0 }, + toolCallMap: new Map(), + phase + }; +} + +function captureTelemetryEvent( + event: { type: string; data?: Record }, + telemetry: TelemetryCollector +): void { + const timestampMs = Date.now(); + telemetry.trajectory.push({ + timestampMs, + phase: telemetry.phase, + type: event.type, + data: sanitizeEventData(event.data) + }); + + if (event.type === "tool.execution_start") { + const toolName = (event.data?.toolName as string | undefined) ?? "unknown"; + const toolId = resolveToolId(event.data, toolName, telemetry.toolCallMap.size); + telemetry.toolCallMap.set(toolId, { name: toolName, startMs: timestampMs }); + telemetry.toolCalls.count += 1; + telemetry.toolCalls.byName[toolName] = (telemetry.toolCalls.byName[toolName] ?? 0) + 1; + } else if (event.type === "tool.execution_finish" || event.type === "tool.execution_error") { + const toolName = (event.data?.toolName as string | undefined) ?? "unknown"; + const toolId = resolveToolId(event.data, toolName, telemetry.toolCallMap.size); + const entry = telemetry.toolCallMap.get(toolId) ?? findLatestToolByName(telemetry.toolCallMap, toolName); + if (entry) { + const durationMs = timestampMs - entry.startMs; + telemetry.toolCalls.totalDurationMs += durationMs; + telemetry.toolCallMap.delete(toolId); + } + } + + const usage = extractTokenUsage(event.data); + if (usage) { + telemetry.tokenUsage = mergeTokenUsage(telemetry.tokenUsage, usage); + } +} + +function resolveToolId( + data: Record | undefined, + toolName: string, + index: number +): string { + const rawId = data?.executionId ?? data?.toolCallId ?? data?.callId ?? data?.id; + if (typeof rawId === "string" || typeof rawId === "number") { + return String(rawId); + } + return `${toolName}-${index + 1}`; +} + +function findLatestToolByName( + map: Map, + toolName: string +): { name?: string; startMs: number } | undefined { + const entries = Array.from(map.values()).filter((entry) => entry.name === toolName); + return entries.at(-1); +} + +function extractTokenUsage(data: Record | undefined): TokenUsage | null { + if (!data) return null; + const usage = (data.usage ?? data.tokenUsage ?? data.tokens) as Record | undefined; + const promptTokens = getNumber(usage?.prompt_tokens ?? usage?.promptTokens ?? data.promptTokens ?? data.inputTokens); + const completionTokens = getNumber(usage?.completion_tokens ?? usage?.completionTokens ?? data.completionTokens ?? data.outputTokens); + const totalTokens = getNumber(usage?.total_tokens ?? usage?.totalTokens ?? data.totalTokens); + + if (promptTokens == null && completionTokens == null && totalTokens == null) { + return null; + } + + return { + promptTokens: promptTokens ?? undefined, + completionTokens: completionTokens ?? undefined, + totalTokens: totalTokens ?? undefined + }; +} + +function getNumber(value: unknown): number | null { + if (typeof value === "number" && Number.isFinite(value)) return value; + if (typeof value === "string" && value.trim()) { + const parsed = Number(value); + return Number.isFinite(parsed) ? parsed : null; + } + return null; +} + +function mergeTokenUsage(existing: TokenUsage, next: TokenUsage): TokenUsage { + return { + promptTokens: Math.max(existing.promptTokens ?? 0, next.promptTokens ?? 0) || undefined, + completionTokens: Math.max(existing.completionTokens ?? 0, next.completionTokens ?? 0) || undefined, + totalTokens: Math.max(existing.totalTokens ?? 0, next.totalTokens ?? 0) || undefined + }; +} + +function normalizeTokenUsage(usage: TokenUsage): TokenUsage | undefined { + if (!usage.promptTokens && !usage.completionTokens && !usage.totalTokens) return undefined; + return usage; +} + +function aggregateTokenUsage(results: EvalResult[]): TokenUsage { + const total: TokenUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 }; + for (const result of results) { + const metrics = result.metrics; + if (!metrics) continue; + const usages = [metrics.withoutInstructions.tokenUsage, metrics.withInstructions.tokenUsage, metrics.judge.tokenUsage]; + for (const usage of usages) { + if (!usage) continue; + total.promptTokens = (total.promptTokens ?? 0) + (usage.promptTokens ?? 0); + total.completionTokens = (total.completionTokens ?? 0) + (usage.completionTokens ?? 0); + total.totalTokens = (total.totalTokens ?? 0) + (usage.totalTokens ?? 0); + } + } + return total; +} + +function formatDuration(durationMs: number): string { + const seconds = Math.round(durationMs / 100) / 10; + if (seconds < 60) return `${seconds}s`; + const minutes = Math.floor(seconds / 60); + const remaining = Math.round((seconds % 60) * 10) / 10; + return `${minutes}m ${remaining}s`; +} + +function formatTokenUsage(usage: TokenUsage): string { + const prompt = usage.promptTokens ?? 0; + const completion = usage.completionTokens ?? 0; + const total = usage.totalTokens ?? prompt + completion; + return `prompt ${prompt}, completion ${completion}, total ${total}`; +} + +function resolveOutputPath(repoPath: string, override?: string, configValue?: string): string | undefined { + const chosen = override ?? configValue; + if (!chosen) return undefined; + return path.isAbsolute(chosen) ? chosen : path.resolve(repoPath, chosen); +} + +function buildViewerPath(outputPath: string): string { + if (outputPath.endsWith(".json")) { + return outputPath.replace(/\.json$/u, ".html"); + } + return `${outputPath}.html`; +} + +function buildTrajectoryViewerHtml(data: Record): string { + const serialized = JSON.stringify(data).replace(/ + + + + + Primer Eval Trajectory + + + +

Primer Eval Trajectory

+
+
+
+
+
+ + +`; +} + +function sanitizeEventData(data: Record | undefined): Record | undefined { + if (!data) return undefined; + const sanitized: Record = {}; + for (const [key, value] of Object.entries(data)) { + if (key === "deltaContent" && typeof value === "string") { + sanitized.deltaChars = value.length; + sanitized.deltaPreview = value.slice(0, 120); + continue; + } + sanitized[key] = sanitizeValue(value, 0); + } + return sanitized; +} + +function sanitizeValue(value: unknown, depth: number): unknown { + if (depth > 4) return "[depth-limit]"; + if (typeof value === "string") { + return value.length > 2000 ? `${value.slice(0, 2000)}…` : value; + } + if (Array.isArray(value)) { + return value.slice(0, 50).map((entry) => sanitizeValue(entry, depth + 1)); + } + if (value && typeof value === "object") { + const obj: Record = {}; + for (const [key, entry] of Object.entries(value as Record)) { + obj[key] = sanitizeValue(entry, depth + 1); + } + return obj; + } + return value; +} diff --git a/src/services/git.ts b/src/services/git.ts index a8b1e79..5eceb3a 100644 --- a/src/services/git.ts +++ b/src/services/git.ts @@ -65,6 +65,8 @@ export async function commitAll(repoPath: string, message: string): Promise { +export function buildAuthedUrl(url: string, token: string, provider: AuthProvider): string { + const normalizedUrl = normalizeGitUrl(url); + if (!normalizedUrl.startsWith("https://")) return normalizedUrl; + if (provider === "azure") { + return normalizedUrl.replace("https://", `https://pat:${token}@`); + } + return normalizedUrl.replace("https://", `https://x-access-token:${token}@`); +} + +export async function pushBranch( + repoPath: string, + branch: string, + token?: string, + provider: AuthProvider = "github" +): Promise { const git = simpleGit(repoPath); if (token) { @@ -85,7 +103,7 @@ export async function pushBranch(repoPath: string, branch: string, token?: strin const remoteUrl = (await git.remote(["get-url", "origin"])) ?? ""; const normalizedUrl = normalizeGitUrl(remoteUrl); if (normalizedUrl.startsWith("https://")) { - const authedUrl = normalizedUrl.replace("https://", `https://x-access-token:${token}@`); + const authedUrl = buildAuthedUrl(normalizedUrl, token, provider); await git.remote(["set-url", "origin", authedUrl]); try { await git.push(["-u", "origin", branch]); diff --git a/src/services/readiness.ts b/src/services/readiness.ts new file mode 100644 index 0000000..ea55e77 --- /dev/null +++ b/src/services/readiness.ts @@ -0,0 +1,648 @@ +import fs from "fs/promises"; +import path from "path"; +import { analyzeRepo, RepoApp, RepoAnalysis } from "./analyzer"; + +export type ReadinessPillar = + | "style-validation" + | "build-system" + | "testing" + | "documentation" + | "dev-environment" + | "code-quality" + | "observability" + | "security-governance"; + +export type ReadinessScope = "repo" | "app"; + +export type ReadinessStatus = "pass" | "fail" | "skip"; + +export type ReadinessCriterionResult = { + id: string; + title: string; + pillar: ReadinessPillar; + level: number; + scope: ReadinessScope; + impact: "high" | "medium" | "low"; + effort: "low" | "medium" | "high"; + status: ReadinessStatus; + reason?: string; + evidence?: string[]; + passRate?: number; + appSummary?: { passed: number; total: number }; + appFailures?: string[]; +}; + +export type ReadinessExtraResult = { + id: string; + title: string; + status: ReadinessStatus; + reason?: string; +}; + +export type ReadinessPillarSummary = { + id: ReadinessPillar; + name: string; + passed: number; + total: number; + passRate: number; +}; + +export type ReadinessLevelSummary = { + level: number; + name: string; + passed: number; + total: number; + passRate: number; + achieved: boolean; +}; + +export type ReadinessReport = { + repoPath: string; + generatedAt: string; + isMonorepo: boolean; + apps: Array<{ name: string; path: string }>; + pillars: ReadinessPillarSummary[]; + levels: ReadinessLevelSummary[]; + achievedLevel: number; + criteria: ReadinessCriterionResult[]; + extras: ReadinessExtraResult[]; +}; + +type ReadinessOptions = { + repoPath: string; + includeExtras?: boolean; +}; + +type ReadinessContext = { + repoPath: string; + analysis: RepoAnalysis; + apps: RepoApp[]; + rootFiles: string[]; + rootPackageJson?: Record; +}; + +type ReadinessCriterion = { + id: string; + title: string; + pillar: ReadinessPillar; + level: number; + scope: ReadinessScope; + impact: "high" | "medium" | "low"; + effort: "low" | "medium" | "high"; + check: (context: ReadinessContext, app?: RepoApp) => Promise; +}; + +type CheckResult = { + status: ReadinessStatus; + reason?: string; + evidence?: string[]; +}; + +export async function runReadinessReport(options: ReadinessOptions): Promise { + const repoPath = options.repoPath; + const analysis = await analyzeRepo(repoPath); + const rootFiles = await safeReadDir(repoPath); + const rootPackageJson = await readJson(path.join(repoPath, "package.json")); + const apps = analysis.apps?.length ? analysis.apps : []; + + const context: ReadinessContext = { + repoPath, + analysis, + apps, + rootFiles, + rootPackageJson + }; + + const criteria = buildCriteria(); + const criteriaResults: ReadinessCriterionResult[] = []; + + for (const criterion of criteria) { + if (criterion.scope === "repo") { + const result = await criterion.check(context); + criteriaResults.push({ + id: criterion.id, + title: criterion.title, + pillar: criterion.pillar, + level: criterion.level, + scope: criterion.scope, + impact: criterion.impact, + effort: criterion.effort, + status: result.status, + reason: result.reason, + evidence: result.evidence + }); + continue; + } + + const appResults = await Promise.all( + apps.map(async (app) => ({ + app, + result: await criterion.check(context, app) + })) + ); + + if (!appResults.length) { + criteriaResults.push({ + id: criterion.id, + title: criterion.title, + pillar: criterion.pillar, + level: criterion.level, + scope: criterion.scope, + impact: criterion.impact, + effort: criterion.effort, + status: "skip", + reason: "No application packages detected." + }); + continue; + } + + const passed = appResults.filter((entry) => entry.result.status === "pass").length; + const total = appResults.length; + const passRate = total ? passed / total : 0; + const status: ReadinessStatus = passRate >= 0.8 ? "pass" : "fail"; + const failures = appResults + .filter((entry) => entry.result.status !== "pass") + .map((entry) => entry.app.name); + + criteriaResults.push({ + id: criterion.id, + title: criterion.title, + pillar: criterion.pillar, + level: criterion.level, + scope: criterion.scope, + impact: criterion.impact, + effort: criterion.effort, + status, + reason: status === "pass" ? undefined : `Only ${passed}/${total} apps pass this check.`, + passRate, + appSummary: { passed, total }, + appFailures: failures + }); + } + + const pillars = summarizePillars(criteriaResults); + const levels = summarizeLevels(criteriaResults); + const achievedLevel = levels.filter((level) => level.achieved).reduce((acc, level) => Math.max(acc, level.level), 0); + + const extras = options.includeExtras === false ? [] : await runExtras(context); + + return { + repoPath, + generatedAt: new Date().toISOString(), + isMonorepo: analysis.isMonorepo ?? false, + apps: apps.map((app) => ({ name: app.name, path: app.path })), + pillars, + levels, + achievedLevel, + criteria: criteriaResults, + extras + }; +} + +function buildCriteria(): ReadinessCriterion[] { + return [ + { + id: "lint-config", + title: "Linting configured", + pillar: "style-validation", + level: 1, + scope: "repo", + impact: "high", + effort: "low", + check: async (context) => ({ + status: (await hasLintConfig(context.repoPath)) ? "pass" : "fail", + reason: "Missing ESLint/Biome/Prettier configuration.", + evidence: ["eslint.config.js", ".eslintrc", "biome.json", ".prettierrc"] + }) + }, + { + id: "typecheck-config", + title: "Type checking configured", + pillar: "style-validation", + level: 2, + scope: "repo", + impact: "medium", + effort: "low", + check: async (context) => ({ + status: (await hasTypecheckConfig(context.repoPath)) ? "pass" : "fail", + reason: "Missing type checking config (tsconfig or equivalent).", + evidence: ["tsconfig.json", "pyproject.toml", "mypy.ini"] + }) + }, + { + id: "build-script", + title: "Build script present", + pillar: "build-system", + level: 1, + scope: "app", + impact: "high", + effort: "low", + check: async (_context, app) => ({ + status: app?.scripts?.build ? "pass" : "fail", + reason: "Missing build script in package.json." + }) + }, + { + id: "ci-config", + title: "CI workflow configured", + pillar: "build-system", + level: 2, + scope: "repo", + impact: "high", + effort: "medium", + check: async (context) => ({ + status: (await hasGithubWorkflows(context.repoPath)) ? "pass" : "fail", + reason: "Missing .github/workflows CI configuration.", + evidence: [".github/workflows"] + }) + }, + { + id: "test-script", + title: "Test script present", + pillar: "testing", + level: 1, + scope: "app", + impact: "high", + effort: "low", + check: async (_context, app) => ({ + status: app?.scripts?.test ? "pass" : "fail", + reason: "Missing test script in package.json." + }) + }, + { + id: "readme", + title: "README present", + pillar: "documentation", + level: 1, + scope: "repo", + impact: "high", + effort: "low", + check: async (context) => ({ + status: (await hasReadme(context.repoPath)) ? "pass" : "fail", + reason: "Missing README documentation.", + evidence: ["README.md"] + }) + }, + { + id: "contributing", + title: "CONTRIBUTING guide present", + pillar: "documentation", + level: 2, + scope: "repo", + impact: "medium", + effort: "low", + check: async (context) => ({ + status: (await fileExists(path.join(context.repoPath, "CONTRIBUTING.md"))) ? "pass" : "fail", + reason: "Missing CONTRIBUTING.md for contributor workflows." + }) + }, + { + id: "lockfile", + title: "Lockfile present", + pillar: "dev-environment", + level: 1, + scope: "repo", + impact: "high", + effort: "low", + check: async (context) => ({ + status: hasAnyFile(context.rootFiles, ["pnpm-lock.yaml", "yarn.lock", "package-lock.json", "bun.lockb"]) ? "pass" : "fail", + reason: "Missing package manager lockfile." + }) + }, + { + id: "env-example", + title: "Environment example present", + pillar: "dev-environment", + level: 2, + scope: "repo", + impact: "medium", + effort: "low", + check: async (context) => ({ + status: hasAnyFile(context.rootFiles, [".env.example", ".env.sample"]) ? "pass" : "fail", + reason: "Missing .env.example or .env.sample for setup guidance." + }) + }, + { + id: "format-config", + title: "Formatter configured", + pillar: "code-quality", + level: 2, + scope: "repo", + impact: "medium", + effort: "low", + check: async (context) => ({ + status: (await hasFormatterConfig(context.repoPath)) ? "pass" : "fail", + reason: "Missing Prettier/Biome formatting config." + }) + }, + { + id: "codeowners", + title: "CODEOWNERS present", + pillar: "security-governance", + level: 2, + scope: "repo", + impact: "medium", + effort: "low", + check: async (context) => ({ + status: (await hasCodeowners(context.repoPath)) ? "pass" : "fail", + reason: "Missing CODEOWNERS file." + }) + }, + { + id: "license", + title: "LICENSE present", + pillar: "security-governance", + level: 1, + scope: "repo", + impact: "medium", + effort: "low", + check: async (context) => ({ + status: (await hasLicense(context.repoPath)) ? "pass" : "fail", + reason: "Missing LICENSE file." + }) + }, + { + id: "security-policy", + title: "Security policy present", + pillar: "security-governance", + level: 3, + scope: "repo", + impact: "high", + effort: "low", + check: async (context) => ({ + status: (await fileExists(path.join(context.repoPath, "SECURITY.md"))) ? "pass" : "fail", + reason: "Missing SECURITY.md policy." + }) + }, + { + id: "dependabot", + title: "Dependabot configured", + pillar: "security-governance", + level: 3, + scope: "repo", + impact: "medium", + effort: "medium", + check: async (context) => ({ + status: (await fileExists(path.join(context.repoPath, ".github", "dependabot.yml"))) ? "pass" : "fail", + reason: "Missing .github/dependabot.yml configuration." + }) + }, + { + id: "observability", + title: "Observability tooling present", + pillar: "observability", + level: 3, + scope: "repo", + impact: "medium", + effort: "medium", + check: async (context) => { + const deps = await readAllDependencies(context); + const has = deps.some((dep) => ["@opentelemetry/api", "@opentelemetry/sdk", "pino", "winston", "bunyan"].includes(dep)); + return { + status: has ? "pass" : "fail", + reason: "No observability dependencies detected (OpenTelemetry/logging)." + }; + } + } + ]; +} + +async function runExtras(context: ReadinessContext): Promise { + const results: ReadinessExtraResult[] = []; + + results.push({ + id: "agents-doc", + title: "AGENTS.md present", + status: (await fileExists(path.join(context.repoPath, "AGENTS.md"))) ? "pass" : "fail", + reason: "Missing AGENTS.md to guide coding agents." + }); + + results.push({ + id: "pr-template", + title: "Pull request template present", + status: (await hasPullRequestTemplate(context.repoPath)) ? "pass" : "fail", + reason: "Missing PR template for consistent reviews." + }); + + results.push({ + id: "pre-commit", + title: "Pre-commit hooks configured", + status: (await hasPrecommitConfig(context.repoPath)) ? "pass" : "fail", + reason: "Missing pre-commit or Husky configuration for fast feedback." + }); + + results.push({ + id: "architecture-doc", + title: "Architecture guide present", + status: (await hasArchitectureDoc(context.repoPath)) ? "pass" : "fail", + reason: "Missing architecture documentation." + }); + + return results; +} + +function summarizePillars(criteria: ReadinessCriterionResult[]): ReadinessPillarSummary[] { + const pillarNames: Record = { + "style-validation": "Style & Validation", + "build-system": "Build System", + testing: "Testing", + documentation: "Documentation", + "dev-environment": "Dev Environment", + "code-quality": "Code Quality", + observability: "Observability", + "security-governance": "Security & Governance" + }; + + return (Object.keys(pillarNames) as ReadinessPillar[]).map((pillar) => { + const items = criteria.filter((criterion) => criterion.pillar === pillar); + const { passed, total } = countStatus(items); + return { + id: pillar, + name: pillarNames[pillar], + passed, + total, + passRate: total ? passed / total : 0 + }; + }); +} + +function summarizeLevels(criteria: ReadinessCriterionResult[]): ReadinessLevelSummary[] { + const levelNames: Record = { + 1: "Functional", + 2: "Documented", + 3: "Standardized", + 4: "Optimized", + 5: "Autonomous" + }; + + const summaries: ReadinessLevelSummary[] = []; + for (let level = 1; level <= 5; level += 1) { + const items = criteria.filter((criterion) => criterion.level === level); + const { passed, total } = countStatus(items); + const passRate = total ? passed / total : 0; + summaries.push({ + level, + name: levelNames[level], + passed, + total, + passRate, + achieved: false + }); + } + + for (const summary of summaries) { + const allPrior = summaries.filter((candidate) => candidate.level <= summary.level); + const achieved = allPrior.every((candidate) => candidate.total === 0 || candidate.passRate >= 0.8); + summary.achieved = achieved; + } + + return summaries; +} + +function countStatus(items: ReadinessCriterionResult[]): { passed: number; total: number } { + const relevant = items.filter((item) => item.status !== "skip"); + const passed = relevant.filter((item) => item.status === "pass").length; + return { passed, total: relevant.length }; +} + +async function safeReadDir(dirPath: string): Promise { + try { + return await fs.readdir(dirPath); + } catch { + return []; + } +} + +async function readJson(filePath: string): Promise | undefined> { + try { + const raw = await fs.readFile(filePath, "utf8"); + return JSON.parse(raw) as Record; + } catch { + return undefined; + } +} + +async function fileExists(filePath: string): Promise { + try { + await fs.access(filePath); + return true; + } catch { + return false; + } +} + +function hasAnyFile(files: string[], candidates: string[]): boolean { + return candidates.some((candidate) => files.includes(candidate)); +} + +async function hasReadme(repoPath: string): Promise { + const files = await safeReadDir(repoPath); + return files.some((file) => file.toLowerCase() === "readme.md" || file.toLowerCase() === "readme"); +} + +async function hasLintConfig(repoPath: string): Promise { + return hasAnyFile(await safeReadDir(repoPath), [ + "eslint.config.js", + "eslint.config.mjs", + ".eslintrc", + ".eslintrc.js", + ".eslintrc.cjs", + ".eslintrc.json", + ".eslintrc.yml", + ".eslintrc.yaml", + "biome.json", + "biome.jsonc", + ".prettierrc", + ".prettierrc.json", + ".prettierrc.js", + ".prettierrc.cjs", + "prettier.config.js", + "prettier.config.cjs" + ]); +} + +async function hasFormatterConfig(repoPath: string): Promise { + return hasAnyFile(await safeReadDir(repoPath), [ + "biome.json", + "biome.jsonc", + ".prettierrc", + ".prettierrc.json", + ".prettierrc.js", + ".prettierrc.cjs", + "prettier.config.js", + "prettier.config.cjs" + ]); +} + +async function hasTypecheckConfig(repoPath: string): Promise { + return hasAnyFile(await safeReadDir(repoPath), [ + "tsconfig.json", + "tsconfig.base.json", + "pyproject.toml", + "mypy.ini" + ]); +} + +async function hasGithubWorkflows(repoPath: string): Promise { + return fileExists(path.join(repoPath, ".github", "workflows")); +} + +async function hasCodeowners(repoPath: string): Promise { + const root = await fileExists(path.join(repoPath, "CODEOWNERS")); + const github = await fileExists(path.join(repoPath, ".github", "CODEOWNERS")); + return root || github; +} + +async function hasLicense(repoPath: string): Promise { + const files = await safeReadDir(repoPath); + return files.some((file) => file.toLowerCase().startsWith("license")); +} + +async function hasPullRequestTemplate(repoPath: string): Promise { + const direct = await fileExists(path.join(repoPath, ".github", "PULL_REQUEST_TEMPLATE.md")); + if (direct) return true; + const dir = path.join(repoPath, ".github", "PULL_REQUEST_TEMPLATE"); + try { + const entries = await fs.readdir(dir); + return entries.some((entry) => entry.toLowerCase().endsWith(".md")); + } catch { + return false; + } +} + +async function hasPrecommitConfig(repoPath: string): Promise { + const precommit = await fileExists(path.join(repoPath, ".pre-commit-config.yaml")); + if (precommit) return true; + return fileExists(path.join(repoPath, ".husky")); +} + +async function hasArchitectureDoc(repoPath: string): Promise { + const files = await safeReadDir(repoPath); + if (files.some((file) => file.toLowerCase() === "architecture.md")) return true; + return fileExists(path.join(repoPath, "docs", "architecture.md")); +} + +async function readAllDependencies(context: ReadinessContext): Promise { + const dependencies: string[] = []; + const apps = context.apps.length ? context.apps : []; + for (const app of apps) { + const pkg = await readJson(app.packageJsonPath); + const deps = (pkg?.dependencies ?? {}) as Record; + const devDeps = (pkg?.devDependencies ?? {}) as Record; + dependencies.push(...Object.keys({ + ...deps, + ...devDeps + })); + } + + if (!apps.length && context.rootPackageJson) { + const rootDeps = (context.rootPackageJson.dependencies ?? {}) as Record; + const rootDevDeps = (context.rootPackageJson.devDependencies ?? {}) as Record; + dependencies.push(...Object.keys({ + ...rootDeps, + ...rootDevDeps + })); + } + + return Array.from(new Set(dependencies)); +} \ No newline at end of file diff --git a/src/ui/BatchTuiAzure.tsx b/src/ui/BatchTuiAzure.tsx new file mode 100644 index 0000000..8eb5fea --- /dev/null +++ b/src/ui/BatchTuiAzure.tsx @@ -0,0 +1,526 @@ +import React, { useEffect, useState } from "react"; +import { Box, Text, useApp, useInput } from "ink"; +import path from "path"; +import fs from "fs/promises"; +import { + AzureDevOpsOrg, + AzureDevOpsProject, + AzureDevOpsRepo, + listOrganizations, + listProjects, + listRepos, + checkReposForInstructions, + createPullRequest +} from "../services/azureDevops"; +import { + buildAuthedUrl, + checkoutBranch, + cloneRepo, + commitAll, + isGitRepo, + pushBranch +} from "../services/git"; +import { generateCopilotInstructions } from "../services/instructions"; +import { ensureDir } from "../utils/fs"; +import { StaticBanner } from "./AnimatedBanner"; + +type Props = { + token: string; + outputPath?: string; +}; + +type Status = + | "loading-orgs" + | "select-orgs" + | "loading-projects" + | "select-projects" + | "loading-repos" + | "select-repos" + | "confirm" + | "processing" + | "complete" + | "error"; + +type ProcessResult = { + repo: string; + success: boolean; + prUrl?: string; + error?: string; +}; + +export function BatchTuiAzure({ token, outputPath }: Props): React.JSX.Element { + const app = useApp(); + const [status, setStatus] = useState("loading-orgs"); + const [message, setMessage] = useState("Fetching organizations..."); + const [errorMessage, setErrorMessage] = useState(""); + + const [orgs, setOrgs] = useState([]); + const [projects, setProjects] = useState([]); + const [repos, setRepos] = useState([]); + const [selectedOrgIndices, setSelectedOrgIndices] = useState>(new Set()); + const [selectedProjectIndices, setSelectedProjectIndices] = useState>(new Set()); + const [selectedRepoIndices, setSelectedRepoIndices] = useState>(new Set()); + const [cursorIndex, setCursorIndex] = useState(0); + + const [results, setResults] = useState([]); + const [currentRepoIndex, setCurrentRepoIndex] = useState(0); + const [processingMessage, setProcessingMessage] = useState(""); + + useEffect(() => { + loadOrgs(); + }, []); + + async function loadOrgs() { + try { + const userOrgs = await listOrganizations(token); + setOrgs(userOrgs); + setStatus("select-orgs"); + setMessage("Select organizations (space to toggle, enter to confirm)"); + } catch (error) { + setStatus("error"); + setErrorMessage(error instanceof Error ? error.message : "Failed to fetch organizations"); + } + } + + async function loadProjects() { + setStatus("loading-projects"); + setMessage("Fetching projects..."); + + try { + const selectedOrgs = Array.from(selectedOrgIndices).map(i => orgs[i]); + let allProjects: AzureDevOpsProject[] = []; + + for (let idx = 0; idx < selectedOrgs.length; idx++) { + const org = selectedOrgs[idx]; + setMessage(`Fetching projects from ${org.name} (${idx + 1}/${selectedOrgs.length})...`); + const orgProjects = await listProjects(token, org.name); + allProjects = [...allProjects, ...orgProjects]; + } + + setProjects(allProjects); + setCursorIndex(0); + setSelectedProjectIndices(new Set()); + setStatus("select-projects"); + setMessage("Select projects (space to toggle, enter to confirm)"); + } catch (error) { + setStatus("error"); + setErrorMessage(error instanceof Error ? error.message : "Failed to fetch projects"); + } + } + + async function loadRepos() { + setStatus("loading-repos"); + setMessage("Fetching repositories..."); + + try { + const selectedProjects = Array.from(selectedProjectIndices).map(i => projects[i]); + let allRepos: AzureDevOpsRepo[] = []; + + for (let idx = 0; idx < selectedProjects.length; idx++) { + const project = selectedProjects[idx]; + setMessage( + `Fetching repos from ${project.organization}/${project.name} (${idx + 1}/${selectedProjects.length})...` + ); + const projectRepos = await listRepos(token, project.organization, project.name); + allRepos = [...allRepos, ...projectRepos]; + } + + const seen = new Set(); + const uniqueRepos = allRepos.filter((repo) => { + const key = `${repo.organization}/${repo.project}/${repo.name}`; + if (seen.has(key)) return false; + seen.add(key); + return true; + }); + + setMessage(`Checking ${uniqueRepos.length} repos for existing instructions...`); + const reposWithStatus = await checkReposForInstructions( + token, + uniqueRepos, + (checked, total) => setMessage(`Checking for existing instructions (${checked}/${total})...`) + ); + + reposWithStatus.sort((a, b) => { + if (a.hasInstructions === b.hasInstructions) return 0; + return a.hasInstructions ? 1 : -1; + }); + + const withInstructions = reposWithStatus.filter(r => r.hasInstructions).length; + const withoutInstructions = reposWithStatus.length - withInstructions; + + setRepos(reposWithStatus); + setCursorIndex(0); + setSelectedRepoIndices(new Set()); + setStatus("select-repos"); + setMessage(`Found ${reposWithStatus.length} repos (${withoutInstructions} need instructions, ${withInstructions} already have them)`); + } catch (error) { + setStatus("error"); + setErrorMessage(error instanceof Error ? error.message : "Failed to fetch repositories"); + } + } + + async function processRepos() { + const selectedRepos = Array.from(selectedRepoIndices).map(i => repos[i]); + setStatus("processing"); + setCurrentRepoIndex(0); + setResults([]); + + const nextResults: ProcessResult[] = []; + + for (let i = 0; i < selectedRepos.length; i++) { + const repo = selectedRepos[i]; + setCurrentRepoIndex(i); + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Cloning...`); + + try { + const cacheRoot = path.join(process.cwd(), ".primer-cache"); + const repoPath = path.join(cacheRoot, repo.organization, repo.project, repo.name); + await ensureDir(repoPath); + + if (!(await isGitRepo(repoPath))) { + const authedUrl = buildAuthedUrl(repo.cloneUrl, token, "azure"); + await cloneRepo(authedUrl, repoPath, { + shallow: true, + timeoutMs: 120000, + onProgress: (stage, progress) => { + setProcessingMessage( + `[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Cloning (${stage} ${progress}%)...` + ); + } + }); + } + + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Creating branch...`); + const branch = "primer/add-instructions"; + await checkoutBranch(repoPath, branch); + + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Generating instructions...`); + const timeoutMs = 120000; + const instructionsPromise = generateCopilotInstructions({ + repoPath, + model: "gpt-4.1", + onProgress: (msg) => { + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: ${msg}`); + } + }); + + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => reject(new Error("Generation timed out after 2 minutes")), timeoutMs); + }); + + const instructions = await Promise.race([instructionsPromise, timeoutPromise]); + + if (!instructions.trim()) { + throw new Error("Generated instructions were empty"); + } + + const instructionsPath = path.join(repoPath, ".github", "copilot-instructions.md"); + await fs.mkdir(path.dirname(instructionsPath), { recursive: true }); + await fs.writeFile(instructionsPath, instructions, "utf8"); + + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Committing...`); + await commitAll(repoPath, "chore: add copilot instructions via Primer"); + + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Pushing...`); + await pushBranch(repoPath, branch, token, "azure"); + + setProcessingMessage(`[${i + 1}/${selectedRepos.length}] ${repo.organization}/${repo.project}/${repo.name}: Creating PR...`); + const prUrl = await createPullRequest({ + token, + organization: repo.organization, + project: repo.project, + repoId: repo.id, + repoName: repo.name, + title: "🤖 Add Copilot instructions via Primer", + body: buildPrBody(), + sourceBranch: branch, + targetBranch: repo.defaultBranch + }); + + nextResults.push({ repo: `${repo.organization}/${repo.project}/${repo.name}`, success: true, prUrl }); + setResults([...nextResults]); + } catch (error) { + const errorMsg = error instanceof Error ? error.message : "Unknown error"; + nextResults.push({ repo: `${repo.organization}/${repo.project}/${repo.name}`, success: false, error: errorMsg }); + setResults([...nextResults]); + } + } + + if (outputPath) { + await fs.writeFile(outputPath, JSON.stringify(nextResults, null, 2), "utf8"); + } + + setStatus("complete"); + setMessage("Batch processing complete!"); + } + + useInput((input, key) => { + if (key.escape || input.toLowerCase() === "q") { + app.exit(); + return; + } + + if (status === "select-orgs") { + if (key.upArrow) { + setCursorIndex(prev => Math.max(0, prev - 1)); + } else if (key.downArrow) { + setCursorIndex(prev => Math.min(orgs.length - 1, prev + 1)); + } else if (input === " ") { + setSelectedOrgIndices(prev => { + const next = new Set(prev); + if (next.has(cursorIndex)) { + next.delete(cursorIndex); + } else { + next.add(cursorIndex); + } + return next; + }); + } else if (key.return && selectedOrgIndices.size > 0) { + loadProjects(); + } + } + + if (status === "select-projects") { + if (key.upArrow) { + setCursorIndex(prev => Math.max(0, prev - 1)); + } else if (key.downArrow) { + setCursorIndex(prev => Math.min(projects.length - 1, prev + 1)); + } else if (input === " ") { + setSelectedProjectIndices(prev => { + const next = new Set(prev); + if (next.has(cursorIndex)) { + next.delete(cursorIndex); + } else { + next.add(cursorIndex); + } + return next; + }); + } else if (key.return && selectedProjectIndices.size > 0) { + loadRepos(); + } + } + + if (status === "select-repos") { + if (key.upArrow) { + setCursorIndex(prev => Math.max(0, prev - 1)); + } else if (key.downArrow) { + setCursorIndex(prev => Math.min(repos.length - 1, prev + 1)); + } else if (input === " ") { + setSelectedRepoIndices(prev => { + const next = new Set(prev); + if (next.has(cursorIndex)) { + next.delete(cursorIndex); + } else { + next.add(cursorIndex); + } + return next; + }); + } else if (input.toLowerCase() === "a") { + const indicesWithoutInstructions = repos + .map((r, i) => ({ r, i })) + .filter(({ r }) => !r.hasInstructions) + .map(({ i }) => i); + setSelectedRepoIndices(new Set(indicesWithoutInstructions)); + } else if (key.return && selectedRepoIndices.size > 0) { + setStatus("confirm"); + setMessage(`Ready to process ${selectedRepoIndices.size} repositories. Press Y to confirm, N to go back.`); + } + } + + if (status === "confirm") { + if (input.toLowerCase() === "y") { + processRepos(); + } else if (input.toLowerCase() === "n") { + setStatus("select-repos"); + setMessage("Select repos (space to toggle, enter to confirm)"); + } + } + }); + + const windowSize = 15; + const getVisibleItems = (items: T[], cursor: number): { items: T[]; startIndex: number } => { + const start = Math.max(0, cursor - Math.floor(windowSize / 2)); + const end = Math.min(items.length, start + windowSize); + const adjustedStart = Math.max(0, end - windowSize); + return { items: items.slice(adjustedStart, end), startIndex: adjustedStart }; + }; + + return ( + + + Batch Processing - Azure DevOps + + {message} + + + {status === "error" && ( + + Error: {errorMessage} + + )} + + {status === "select-orgs" && ( + + {(() => { + const { items: visibleOrgs, startIndex } = getVisibleItems(orgs, cursorIndex); + return visibleOrgs.map((org, i) => { + const realIndex = startIndex + i; + const isSelected = selectedOrgIndices.has(realIndex); + const isCursor = realIndex === cursorIndex; + return ( + + {isCursor ? "❯ " : " "} + {isSelected ? "◉" : "○"} + {org.name} + + ); + }); + })()} + {orgs.length > windowSize && ( + + Showing {Math.min(windowSize, orgs.length)} of {orgs.length} • Use ↑↓ to scroll + + )} + + )} + + {status === "select-projects" && ( + + {(() => { + const { items: visibleProjects, startIndex } = getVisibleItems(projects, cursorIndex); + return visibleProjects.map((project, i) => { + const realIndex = startIndex + i; + const isSelected = selectedProjectIndices.has(realIndex); + const isCursor = realIndex === cursorIndex; + return ( + + {isCursor ? "❯ " : " "} + {isSelected ? "◉" : "○"} + {project.organization}/{project.name} + + ); + }); + })()} + {projects.length > windowSize && ( + + Showing {Math.min(windowSize, projects.length)} of {projects.length} • Use ↑↓ to scroll + + )} + + )} + + {status === "select-repos" && ( + + {(() => { + const { items: visibleRepos, startIndex } = getVisibleItems(repos, cursorIndex); + return visibleRepos.map((repo, i) => { + const realIndex = startIndex + i; + const isSelected = selectedRepoIndices.has(realIndex); + const isCursor = realIndex === cursorIndex; + return ( + + {isCursor ? "❯ " : " "} + {isSelected ? "◉" : "○"} + {repo.hasInstructions ? "✓" : "✗"} + + {repo.organization}/{repo.project}/{repo.name} + + {repo.isPrivate && (private)} + + ); + }); + })()} + {repos.length > windowSize && ( + + Showing {Math.min(windowSize, repos.length)} of {repos.length} • Use ↑↓ to scroll + + )} + + + Selected: {selectedRepoIndices.size} repos + + + + )} + + {status === "processing" && ( + + {processingMessage} + {results.length > 0 && ( + + Completed: + {results.slice(-5).map((r) => ( + + {r.success ? "✓" : "✗"} {r.repo} + {r.success && r.prUrl && → {r.prUrl}} + {!r.success && r.error && ({r.error})} + + ))} + + )} + + )} + + {status === "complete" && ( + + + ✓ Batch complete: {results.filter(r => r.success).length} succeeded, {results.filter(r => !r.success).length} failed + + + {results.map((r) => ( + + {r.success ? "✓" : "✗"} {r.repo} + {r.success && r.prUrl && → {r.prUrl}} + {!r.success && r.error && ({r.error})} + + ))} + + + )} + + + {status === "select-orgs" && ( + Keys: [Space] Toggle [Enter] Confirm [Q] Quit + )} + {status === "select-projects" && ( + Keys: [Space] Toggle [Enter] Confirm [Q] Quit + )} + {status === "select-repos" && ( + Keys: [Space] Toggle [A] Select Missing [Enter] Confirm [Q] Quit + )} + {status === "confirm" && ( + Keys: [Y] Yes, proceed [N] Go back [Q] Quit + )} + {(status === "complete" || status === "error") && ( + Keys: [Q] Quit + )} + + + ); +} + +function buildPrBody(): string { + return [ + "## 🤖 Copilot Instructions Added", + "", + "This PR adds a `.github/copilot-instructions.md` file to help GitHub Copilot understand this codebase better.", + "", + "### What's Included", + "", + "The instructions file contains:", + "- Project overview and architecture", + "- Tech stack and conventions", + "- Build/test commands", + "- Key directories and files", + "", + "### Benefits", + "", + "With these instructions, Copilot will:", + "- Generate more contextually-aware code suggestions", + "- Follow project-specific patterns and conventions", + "- Understand the codebase structure", + "", + "---", + "*Generated by [Primer](https://github.com/pierceboggan/primer) - Prime your repos for AI*" + ].join("\n"); +} \ No newline at end of file diff --git a/src/ui/README.md b/src/ui/README.md index a34f7c0..551d04e 100644 --- a/src/ui/README.md +++ b/src/ui/README.md @@ -1 +1,3 @@ Primer TUI components live here. + +Run the TUI with `primer tui`. diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index cfa8dbb..7991865 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -8,13 +8,79 @@ import { runEval, type EvalResult } from "../services/evaluator"; import { AnimatedBanner, StaticBanner } from "./AnimatedBanner"; import { BatchTui } from "./BatchTui"; import { getGitHubToken } from "../services/github"; +import { safeWriteFile } from "../utils/fs"; type Props = { repoPath: string; skipAnimation?: boolean; }; -type Status = "intro" | "idle" | "analyzing" | "generating" | "evaluating" | "preview" | "done" | "error" | "batch"; +type Status = + | "intro" + | "idle" + | "analyzing" + | "generating" + | "evaluating" + | "preview" + | "done" + | "error" + | "batch" + | "bootstrapEvalCount" + | "bootstrapEvalConfirm"; + +type EvalCase = { + id: string; + prompt: string; + expectation: string; +}; + +type EvalConfig = { + instructionFile?: string; + cases: EvalCase[]; + systemMessage?: string; + outputPath?: string; +}; + +function buildBootstrapEvalConfig(count: number): EvalConfig { + const templates = [ + { + prompt: "Summarize this repository's purpose and main entry points. Use the README and package.json if available.", + expectation: "A concise summary of repo purpose plus key entry points (CLI or main files) and how to run it." + }, + { + prompt: "Identify the primary languages, frameworks, and package manager used in this repo.", + expectation: "A brief list of languages/frameworks and the detected package manager, with short justification." + }, + { + prompt: "Draft a minimal .github/copilot-instructions.md tailored to this repo's conventions.", + expectation: "A short instruction file referencing observed conventions, avoiding assumptions or secrets." + }, + { + prompt: "Describe how to run the CLI and list its core commands and flags.", + expectation: "Clear usage instructions with command names and key flags derived from docs or source." + }, + { + prompt: "Propose an eval case that checks consistency between CLI and TUI behaviors.", + expectation: "One eval case that validates parity between CLI and TUI outputs or workflows." + } + ]; + + const cases = Array.from({ length: count }, (_, index) => { + const template = templates[index % templates.length]; + const variant = Math.floor(index / templates.length); + const suffix = variant > 0 ? ` (variant ${variant + 1})` : ""; + return { + id: `case-${index + 1}`, + prompt: `${template.prompt}${suffix}`, + expectation: `${template.expectation}${suffix}` + } satisfies EvalCase; + }); + + return { + instructionFile: ".github/copilot-instructions.md", + cases + }; +} export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX.Element { const app = useApp(); @@ -23,7 +89,10 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const [message, setMessage] = useState(""); const [generatedContent, setGeneratedContent] = useState(""); const [evalResults, setEvalResults] = useState(null); + const [evalViewerPath, setEvalViewerPath] = useState(null); const [batchToken, setBatchToken] = useState(null); + const [evalCaseCountInput, setEvalCaseCountInput] = useState(""); + const [evalBootstrapCount, setEvalBootstrapCount] = useState(null); const repoLabel = useMemo(() => repoPath, [repoPath]); const handleAnimationComplete = () => { @@ -67,6 +136,78 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return; } + if (status === "bootstrapEvalCount") { + if (key.return) { + const trimmed = evalCaseCountInput.trim(); + const count = Number.parseInt(trimmed, 10); + if (!trimmed || !Number.isFinite(count) || count <= 0) { + setMessage("Enter a positive number of eval cases, then press Enter."); + return; + } + + const configPath = path.join(repoPath, "primer.eval.json"); + setEvalBootstrapCount(count); + try { + await fs.access(configPath); + setStatus("bootstrapEvalConfirm"); + setMessage("primer.eval.json exists. Overwrite? (Y/N)"); + } catch { + const config = buildBootstrapEvalConfig(count); + const resultMessage = await safeWriteFile(configPath, JSON.stringify(config, null, 2), false); + setStatus("done"); + setMessage(`Bootstrapped eval: ${resultMessage}`); + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); + } + return; + } + + if (key.backspace || key.delete) { + setEvalCaseCountInput((prev) => prev.slice(0, -1)); + return; + } + + if (/^\d$/.test(input)) { + setEvalCaseCountInput((prev) => prev + input); + return; + } + + return; + } + + if (status === "bootstrapEvalConfirm") { + if (input.toLowerCase() === "y") { + const count = evalBootstrapCount ?? 0; + if (count <= 0) { + setStatus("error"); + setMessage("Missing eval case count. Restart bootstrap."); + return; + } + try { + const configPath = path.join(repoPath, "primer.eval.json"); + const config = buildBootstrapEvalConfig(count); + const resultMessage = await safeWriteFile(configPath, JSON.stringify(config, null, 2), true); + setStatus("done"); + setMessage(`Bootstrapped eval: ${resultMessage}`); + } catch (error) { + setStatus("error"); + setMessage(error instanceof Error ? error.message : "Failed to write eval config."); + } finally { + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); + } + return; + } + + if (input.toLowerCase() === "n") { + setStatus("idle"); + setMessage("Bootstrap cancelled."); + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); + } + return; + } + if (input.toLowerCase() === "a") { setStatus("analyzing"); try { @@ -133,8 +274,9 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setStatus("evaluating"); setMessage("Running evals... (this may take a few minutes)"); setEvalResults(null); + setEvalViewerPath(null); try { - const { results } = await runEval({ + const { results, viewerPath } = await runEval({ configPath, repoPath, model: "gpt-4.1", @@ -142,6 +284,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX // Note: onProgress removed - causes issues with SDK in React/Ink context }); setEvalResults(results); + setEvalViewerPath(viewerPath ?? null); const passed = results.filter(r => r.verdict === "pass").length; const failed = results.filter(r => r.verdict === "fail").length; setStatus("done"); @@ -151,6 +294,13 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setMessage(error instanceof Error ? error.message : "Eval failed."); } } + + if (input.toLowerCase() === "i") { + setStatus("bootstrapEvalCount"); + setMessage("Enter number of eval cases, then press Enter."); + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); + } }); const statusLabel = status === "intro" ? "..." : status === "idle" ? "ready (awaiting input)" : status; @@ -186,6 +336,11 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX {message} + {status === "bootstrapEvalCount" && ( + + Eval case count: {evalCaseCountInput || ""} + + )} {status === "preview" && generatedContent && ( Preview (.github/copilot-instructions.md): @@ -200,6 +355,9 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX {r.verdict === "pass" ? "✓" : r.verdict === "fail" ? "✗" : "?"} {r.id}: {r.verdict} (score: {r.score}) ))} + {evalViewerPath && ( + Trajectory viewer: {evalViewerPath} + )} )} @@ -207,8 +365,10 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX Press any key to skip animation... ) : status === "preview" ? ( Keys: [S] Save [D] Discard [Q] Quit + ) : status === "bootstrapEvalConfirm" ? ( + Keys: [Y] Overwrite [N] Cancel [Q] Quit ) : ( - Keys: [A] Analyze [G] Generate [E] Eval [B] Batch [Q] Quit + Keys: [A] Analyze [G] Generate [E] Eval [I] Init Eval [B] Batch [Q] Quit )} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..2481bee --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "node", + coverage: { + provider: "v8", + reporter: ["text", "html", "json-summary"], + reportsDirectory: "./coverage" + } + } +}); From 05a98bf29ac50b210e36e30d14b0dc04c94f82e0 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Tue, 3 Feb 2026 22:23:02 -0700 Subject: [PATCH 02/19] Refactor code structure for improved readability and maintainability --- eval-results.html | 160 + eval-results.json | 5273 +++++++++++++++++++++++++++- package-lock.json | 6917 ++++++++++++++++++++++++++++++++----- src/services/evaluator.ts | 193 +- src/ui/tui.tsx | 46 +- 5 files changed, 11586 insertions(+), 1003 deletions(-) create mode 100644 eval-results.html diff --git a/eval-results.html b/eval-results.html new file mode 100644 index 0000000..cdc38d9 --- /dev/null +++ b/eval-results.html @@ -0,0 +1,160 @@ + + + + + + Primer Eval Trajectory + + + +

Primer Eval Trajectory

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/eval-results.json b/eval-results.json index 765bd07..da3cda4 100644 --- a/eval-results.json +++ b/eval-results.json @@ -2,16 +2,5283 @@ "repoPath": "/Users/pierceboggan/Documents/get-ready", "model": "gpt-4.1", "judgeModel": "gpt-4.1", + "runMetrics": { + "startedAt": "2026-02-04T05:21:19.668Z", + "finishedAt": "2026-02-04T05:21:58.146Z", + "durationMs": 38478 + }, "results": [ { "id": "overview", "prompt": "Summarize what this application does and list the main entrypoints.", "expectation": "Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.", - "withInstructions": "This application, Primer, is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants (like Copilot) better understand your project. It detects languages, frameworks, and package managers, and can generate, preview, and save project-specific instructions using the Copilot SDK. \n\n**Main entrypoints:**\n- `src/index.ts` (primary entry)\n- `src/cli.ts` (CLI setup)\n- CLI commands in `src/commands/` (e.g., `analyze.ts`, `generate.ts`, `instructions.tsx`, `tui.tsx`, `pr.ts`, `eval.ts`, etc.)", - "withoutInstructions": "This application, Primer, is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants (like Copilot) better understand your project. It detects languages, frameworks, and package managers, and uses the Copilot SDK to generate project-specific instructions. \n\n**Main entrypoints:**\n- `src/index.ts`: Primary entrypoint for the CLI.\n- `src/cli.ts`: Sets up the command-line interface using Commander.\n- `src/commands/`: Contains subcommands for analyze, generate, and instructions.\n- `src/ui/tui.tsx`: Entry for the interactive terminal UI (TUI).", + "withInstructions": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.", + "withoutInstructions": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.", "verdict": "pass", "score": 100, - "rationale": "Both responses mention the foCLI entrypoint in src/index.ts and that this is the Primer CLI. Response B is slightly more complete, but both meet the expectation." + "rationale": "Response B best matches the expectation by explicitly mentioning the CLI entrypoint in src/index.ts, clarifying that it calls runCli in src/cli.ts, and identifying this as the Primer CLI. It also provides a more complete and accurate list of commands and features, aligning closely with the expectation.", + "metrics": { + "withoutInstructions": { + "durationMs": 11934, + "tokenUsage": { + "promptTokens": 10005, + "completionTokens": 289, + "totalTokens": 10294 + }, + "toolCalls": { + "count": 5, + "byName": { + "report_intent": 1, + "task": 1, + "view": 3 + }, + "totalDurationMs": 0 + } + }, + "withInstructions": { + "durationMs": 22221, + "tokenUsage": { + "promptTokens": 11011, + "completionTokens": 335, + "totalTokens": 11346 + }, + "toolCalls": { + "count": 7, + "byName": { + "report_intent": 1, + "task": 1, + "view": 3, + "glob": 1, + "grep": 1 + }, + "totalDurationMs": 0 + } + }, + "judge": { + "durationMs": 2774, + "tokenUsage": { + "promptTokens": 10011, + "completionTokens": 84, + "totalTokens": 10095 + }, + "toolCalls": { + "count": 0, + "byName": {}, + "totalDurationMs": 0 + } + }, + "totalDurationMs": 38461 + }, + "trajectory": [ + { + "timestampMs": 1770182481178, + "phase": "withoutInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770182481178, + "phase": "withoutInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770182483604, + "phase": "withoutInstructions", + "type": "user.message", + "data": { + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", + "transformedContent": "2026-02-04T05:21:23.352Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", + "attachments": [] + } + }, + { + "timestampMs": 1770182483604, + "phase": "withoutInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770182483604, + "phase": "withoutInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 10343, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770182485828, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 9710, + "outputTokens": 85, + "cacheReadTokens": 3840, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 2197, + "initiator": "user", + "apiCallId": "chatcmpl-D5PcKj8TBk6a1XH5WkxrNpJSXawfs", + "providerCallId": "E903:35A03D:33E28A:3D9614:6982D753", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770182485829, + "phase": "withoutInstructions", + "type": "assistant.message", + "data": { + "messageId": "93ddd8e5-b53b-4e65-ae4d-3c9ab4f51f3b", + "content": "", + "toolRequests": [ + { + "toolCallId": "call_tpnJMuSM0sryKLy4z7k2W06H", + "name": "report_intent", + "arguments": { + "intent": "Exploring codebase" + }, + "type": "function" + }, + { + "toolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "name": "task", + "arguments": { + "agent_type": "explore", + "description": "Summarizing application purpose", + "prompt": "Summarize what this application does and list the main entrypoints. Be concise and list file paths for entrypoints." + }, + "type": "function" + } + ] + } + }, + { + "timestampMs": 1770182485834, + "phase": "withoutInstructions", + "type": "tool.execution_start", + "data": { + "toolCallId": "call_tpnJMuSM0sryKLy4z7k2W06H", + "toolName": "report_intent", + "arguments": { + "intent": "Exploring codebase" + } + } + }, + { + "timestampMs": 1770182485837, + "phase": "withoutInstructions", + "type": "tool.execution_start", + "data": { + "toolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolName": "task", + "arguments": { + "agent_type": "explore", + "description": "Summarizing application purpose", + "prompt": "Summarize what this application does and list the main entrypoints. Be concise and list file paths for entrypoints." + } + } + }, + { + "timestampMs": 1770182485837, + "phase": "withoutInstructions", + "type": "tool.execution_complete", + "data": { + "toolCallId": "call_tpnJMuSM0sryKLy4z7k2W06H", + "success": true, + "result": { + "content": "Intent logged", + "detailedContent": "Exploring codebase" + }, + "toolTelemetry": {} + } + }, + { + "timestampMs": 1770182488411, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "claude-haiku-4.5", + "inputTokens": 2707, + "outputTokens": 289, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0.33, + "duration": 2250, + "initiator": "sub-agent", + "apiCallId": "msg_016BDLf3uZartGeaCcNnSoWD", + "providerCallId": "E903:35A03D:33EB57:3DA002:6982D756", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + }, + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg" + } + }, + { + "timestampMs": 1770182488411, + "phase": "withoutInstructions", + "type": "assistant.message", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "messageId": "7b744914-d9fc-49f0-80de-7c84c32a6b2c", + "content": "", + "toolRequests": [ + { + "toolCallId": "toolu_01CzbYettZVEcZ8aE2dMxFGW", + "name": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready" + }, + "type": "function" + }, + { + "toolCallId": "toolu_01FQ6TzCWfm56V3EwxeF2MRA", + "name": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/package.json" + }, + "type": "function" + }, + { + "toolCallId": "toolu_01NGYzuJkusQqT4meJPJuhD9", + "name": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/README.md" + }, + "type": "function" + } + ], + "reasoningOpaque": "3IOUA34d654sP/xOhtYd0oHMHIP6BSEfihGf5GWOyWK7q6GXOek2hymkrZygkkIadRZ4TN0p6q0c68r5514Y9GJBJYvm+dmAwPNxF1EP2lFKZowIJ2CxDiEydSmtN4FsoqK9SENjWhrk8SL/Vy3OGKEAFQP9UTJzSYLVc1EHT8RnBzA0vgAi7YMCma7ch40DCjCvwQUdQJMhoxVjUYXfVkIW041JasRO3g5SBz6EJjZEynwbAyf41sgLSyXJGYEP2IsTHRqHv6jmVHwZVd6ZS5Z13rUFDJewL+k1Krl10f4M1dVhTu9QXLkiuIYSBTQ65q8GengLmnoiSCaLwLIaOpyAe5l5Dqj1x2gWiS5jK9UDvnwlTyLCtoOxH6iGBY8SoqkPOhjuy2nuuODytX96I9Am+lPG11rgKfnhrsM7IJM/AmXEQCLb8kxRKlvqoRU3rmC3nozTQEXRLfyCY9ODN2OoRTc+Uhc4Ew1ZAi6WGFY01AiPJaSKCtgZ2O4+p8kp1p7dk2AKv2bGVe5k+yU101fYe3TwBTa4md2sF3E0zsw2TwlUtU8uTUJ6k1k32s2ynmeOQWYVOheNlXAflxAzgH1hqALbwIMKrxj1ge/ESB8MhP69y8UUSNe51kh2Y1eo2Lca0S5V6UIHZzzuUNHTaHa+TRivQeL+KQepRwsCO6a0NpWbV51KP8iQ7ihNlKa/j96y0BgarFAOHHnlgI0trQ05pwfTDK9E8af6Qvb1aQb5f2Eiyt7Hc3rnfF2INJs7cdK2eI8l+ajZIM6vnEPQgnlA5QPunF2HCOGS3K4bHUU4lNQwcPtIpufmWsXGt5s7sb87prrzirCNvQqB2S4nrGtpALAjOr3kFh/U2mdy6KxuEyxy9AxjE5bGGTWcdDYAKD/U7cndxcVVNF6v7Z7TlgSd22IPArf97HjHI8zMe0kIuSnKOy9eEjEKD+px9NLl5OHeOj9fq2X7/PHkjrmEq9B2v//+t2VRoPExfoHhmiIfmtHP0wlNwSASd4jcwScoHAmUZc9e3FTynXVfKGasUc1aCUt3rkNY+uhU6UUoWbKZB0KsSqe85SwSaeNV1+6qzqXVMo2/LO1gaETmvI8xhnXmfEm9AuKqdKX2nwUZSlHBULCFuZLqh9G0ACl2yu7djX9nLFMMJGIq1WG8aQYu5EGO/xwaTImJRf0Q5B/n7AroQdrJTDXd6DP9nvwdgGPN8mrerg3xmtIEWreDnczsvZpAbhmaFTubp6YFzN+pQjYAIC8G0vRtD+vx0kzwLvX8LL5g7ULQljhtVKd9x09h+idh21t0wr6HbypZFxHc3oSTriUPuguqCkTO1fGOaFpCGvGoXhPC3mF3k71GOoehCWDxVD2LCfDmWlzPhPRh9u2hhy9JH5UuleOHgs6XMXFofeZ9McXvhjIQjn779zrjI+QgUD6m/4FwEvLL2Od/tSg0PswA2nCbCG8+0aJQQyJ+9I47NFlxose045GGhS4Je9c0U0GjV3uDodpPIRA11AUOz84gXBsK5Jj/X6vO", + "reasoningText": "The user wants me to summarize what this application does and list the main entrypoints with file paths. I should:\n\n1. First, explore the repository structure to understand what it is\n2. Look for package.json, README, or other documentation to understand the purpose\n3. Find the main entrypoints (typically in package.json, or main files like index.ts, index.js, main.ts, etc.)\n\nLet me start by looking at the directory structure and key files like package.json, README.md, etc." + } + }, + { + "timestampMs": 1770182488412, + "phase": "withoutInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolCallId": "toolu_01CzbYettZVEcZ8aE2dMxFGW", + "toolName": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready" + } + } + }, + { + "timestampMs": 1770182488412, + "phase": "withoutInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolCallId": "toolu_01FQ6TzCWfm56V3EwxeF2MRA", + "toolName": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/package.json" + } + } + }, + { + "timestampMs": 1770182488412, + "phase": "withoutInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolCallId": "toolu_01NGYzuJkusQqT4meJPJuhD9", + "toolName": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/README.md" + } + } + }, + { + "timestampMs": 1770182488413, + "phase": "withoutInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolCallId": "toolu_01FQ6TzCWfm56V3EwxeF2MRA", + "success": true, + "result": { + "content": "1. {\n2. \"name\": \"primer\",\n3. \"version\": \"1.0.0\",\n4. \"description\": \"\",\n5. \"main\": \"dist/index.js\",\n6. \"scripts\": {\n7. \"build\": \"tsc && npm link\",\n8. \"prepare\": \"tsc\",\n9. \"lint\": \"eslint .\",\n10. \"format\": \"prettier --write .\",\n11. \"format:check\": \"prettier --check .\",\n12. \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n13. \"test\": \"vitest run\",\n14. \"test:watch\": \"vitest\",\n15. \"test:coverage\": \"vitest run --coverage\"\n16. },\n17. \"keywords\": [],\n18. \"author\": \"\",\n19. \"license\": \"ISC\",\n20. \"dependencies\": {\n21. \"@github/copilot-sdk\": \"^0.1.19\",\n22. \"@inquirer/prompts\": \"^8.2.0\",\n23. \"@octokit/rest\": \"^22.0.1\",\n24. \"chalk\": \"^5.6.2\",\n25. \"commander\": \"^14.0.2\",\n26. \"fast-glob\": \"^3.3.3\",\n27. \"ink\": \"^6.6.0\",\n28. \"react\": \"^19.2.4\",\n29. \"simple-git\": \"^3.30.0\"\n30. },\n31. \"devDependencies\": {\n32. \"@types/node\": \"^25.1.0\",\n33. \"@types/react\": \"^19.2.10\",\n34. \"@typescript-eslint/eslint-plugin\": \"^8.5.0\",\n35. \"@typescript-eslint/parser\": \"^8.5.0\",\n36. \"@vitest/coverage-v8\": \"^2.1.4\",\n37. \"eslint\": \"^9.7.0\",\n38. \"eslint-config-prettier\": \"^9.1.0\",\n39. \"eslint-plugin-import\": \"^2.30.0\",\n40. \"eslint-plugin-n\": \"^17.10.2\",\n41. \"eslint-plugin-promise\": \"^7.1.0\",\n42. \"prettier\": \"^3.3.3\",\n43. \"tsup\": \"^8.5.1\",\n44. \"tsx\": \"^4.21.0\",\n45. \"typescript\": \"^5.9.3\",\n46. \"vitest\": \"^2.1.4\"\n47. },\n48. \"type\": \"module\",\n49. \"bin\": {\n50. \"primer\": \"dist/index.js\"\n51. }\n52. }\n53. ", + "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/package.json b/Users/pierceboggan/Documents/get-ready/package.json\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/package.json\n+++ b/Users/pierceboggan/Documents/get-ready/package.json\n@@ -1,53 +1,53 @@\n {\n \"name\": \"primer\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"dist/index.js\",\n \"scripts\": {\n \"build\": \"tsc && npm link\",\n \"prepare\": \"tsc\",\n \"lint\": \"eslint .\",\n \"format\": \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"@github/copilot-sdk\": \"^0.1.19\",\n \"@inquirer/prompts\": \"^8.2.0\",\n \"@octokit/rest\": \"^22.0.1\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^14.0.2\",\n \"fast-glob\": \"^3.3.3\",\n \"ink\": \"^6.6.0\",\n \"react\": \"^19.2.4\",\n \"simple-git\": \"^3.30.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.1.0\",\n \"@types/react\": \"^19.2.10\",\n \"@typescript-eslint/eslint-plugin\": \"^8.5.0\",\n \"@typescript-eslint/parser\": \"^8.5.0\",\n \"@vitest/coverage-v8\": \"^2.1.4\",\n \"eslint\": \"^9.7.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-import\": \"^2.30.0\",\n \"eslint-plugin-n\": \"^17.10.2\",\n \"eslint-plugin-promise\": \"^7.1.0\",\n \"prettier\": \"^3.3.3\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^2.1.4\"\n },\n \"type\": \"module\",\n \"bin\": {\n \"primer\": \"dist/index.js\"\n }\n }\n \n" + } + } + }, + { + "timestampMs": 1770182488413, + "phase": "withoutInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolCallId": "toolu_01CzbYettZVEcZ8aE2dMxFGW", + "success": true, + "result": { + "content": ".DS_Store\n.git\n.github\n.gitignore\n.prettierrc.json\n.primer-cache\nCHANGELOG.md\nCODEOWNERS\nCONTRIBUTING.md\nLICENSE\nPLAN.md\nREADME.md\nSECURITY.md\ndist\neslint.config.js\neval-results.html\neval-results.json\nexamples\nnode_modules\npackage-lock.json\npackage.json\nprimer.eval.json\nprimer.png\nrelease-please-config.json\nrelease-please-manifest.json\nsrc\ntsconfig.json\nvitest.config.ts", + "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready b/Users/pierceboggan/Documents/get-ready\ncreate file mode 100644\nindex 0000000..0000000\n--- a/dev/null\n+++ b/Users/pierceboggan/Documents/get-ready\n@@ -1,0 +1,28 @@\n .DS_Store\n .git\n .github\n .gitignore\n .prettierrc.json\n .primer-cache\n CHANGELOG.md\n CODEOWNERS\n CONTRIBUTING.md\n LICENSE\n PLAN.md\n README.md\n SECURITY.md\n dist\n eslint.config.js\n eval-results.html\n eval-results.json\n examples\n node_modules\n package-lock.json\n package.json\n primer.eval.json\n primer.png\n release-please-config.json\n release-please-manifest.json\n src\n tsconfig.json\n vitest.config.ts\n" + } + } + }, + { + "timestampMs": 1770182488430, + "phase": "withoutInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "toolCallId": "toolu_01NGYzuJkusQqT4meJPJuhD9", + "success": true, + "result": { + "content": "1. # Primer\n2. \n3. > Prime your repositories for AI-assisted development.\n4. \n5. [![CI](https://github.com/pierceboggan/primer/actions/workflows/ci.yml/badge.svg)](https://github.com/pierceboggan/primer/actions/workflows/ci.yml)\n6. [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n7. \n8. Primer is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants understand your project better. It supports single repos, batch processing across organizations, and includes an evaluation framework to measure instruction effectiveness.\n9. \n10. ![Primer](primer.png)\n11. \n12. ## Features\n13. \n14. - **Repository Analysis** - Detects languages, frameworks, and package managers\n15. - **AI-Powered Generation** - Uses the Copilot SDK to analyze your codebase and generate context-aware instructions\n16. - **Batch Processing** - Process multiple repos across organizations with a single command\n17. - **Evaluation Framework** - Test and measure how well your instructions improve AI responses\n18. - **Readiness Report** - Score AI readiness across key pillars with a fix-first checklist\n19. - **GitHub Integration** - Clone repos, create branches, and open PRs automatically\n20. - **Interactive TUI** - Beautiful terminal interface built with Ink\n21. - **Config Generation** - Generate MCP and VS Code configurations\n22. \n23. ## Prerequisites\n24. \n25. 1. **Node.js 18+**\n26. 2. **GitHub Copilot CLI** - Installed via VS Code's Copilot Chat extension\n27. 3. **Copilot CLI Authentication** - Run `copilot` then `/login` to authenticate\n28. 4. **GitHub CLI (optional)** - For batch processing and PR creation: `brew install gh && gh auth login`\n29. 5. **Azure DevOps PAT (optional)** - For Azure DevOps batch/PR workflows: set `AZURE_DEVOPS_PAT`\n30. \n31. ## Installation\n32. \n33. ```bash\n34. # Install from npm\n35. npm install -g primer\n36. ```\n37. \n38. ### Quick Install\n39. \n40. ```bash\n41. primer --help\n42. ```\n43. \n44. ##…", + "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/README.md b/Users/pierceboggan/Documents/get-ready/README.md\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/README.md\n+++ b/Users/pierceboggan/Documents/get-ready/README.md\n@@ -1,362 +1,362 @@\n # Primer\n \n > Prime your repositories for AI-assisted development.\n \n [![CI](https://github.com/pierceboggan/primer/actions/workflows/ci.yml/badge.svg)](https://github.com/pierceboggan/primer/actions/workflows/ci.yml)\n [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n \n Primer is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants understand your project better. It supports single repos, batch processing across organizations, and includes an evaluation framework to measure instruction effectiveness.\n \n ![Primer](primer.png)\n \n ## Features\n \n - **Repository Analysis** - Detects languages, frameworks, and package managers\n - **AI-Powered Generation** - Uses the Copilot SDK to analyze your codebase and generate context-aware instructions\n - **Batch Processing** - Process multiple repos across organizations with a single command\n - **Evaluation Framework** - Test and measure how well your instructions improve AI responses\n - **Readiness Report** - Score AI readiness across key pillars with a fix-first checklist\n - **GitHub Integration** - Clone repos, create branches, and open PRs automatically\n - **Interactive TUI** - Beautiful terminal interface built with Ink\n - **Config Generation** - Generate MCP and VS Code configurations\n \n ## Prerequisites\n \n 1. **Node.js 18+**\n 2. **GitHub Copilot CLI** - Installed via VS Code's Copilot Chat extension\n 3. **Copilot CLI Authentication** - Run `copilot` then `/login` to authenticate\n 4. **GitHub CLI (optional)** - For batch processing and PR creation: `brew install gh && gh auth login`\n 5. **Azure DevOps PAT (optional)** - For Azure DevOps batch/PR workflows: set `AZ…" + } + } + }, + { + "timestampMs": 1770182490847, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "claude-haiku-4.5", + "inputTokens": 7343, + "outputTokens": 219, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0.33, + "duration": 2400, + "initiator": "sub-agent", + "apiCallId": "msg_01R8GGE5VmR6reyFGzX8mGHz", + "providerCallId": "E903:35A03D:33F2DB:3DA886:6982D758", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + }, + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg" + } + }, + { + "timestampMs": 1770182490847, + "phase": "withoutInstructions", + "type": "assistant.message", + "data": { + "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "messageId": "f887839e-d030-4ed2-b01a-f4c8902583da", + "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It features repository analysis, AI-powered instruction generation, batch processing, evaluation framework, readiness reports, and GitHub integration.\n\n**Main Entrypoints:**\n\n| File | Purpose |\n|------|---------|\n| `/Users/pierceboggan/Documents/get-ready/src/index.ts` | CLI entry point |\n| `/Users/pierceboggan/Documents/get-ready/src/cli.ts` | Commander CLI setup |\n\n**Key Commands:**\n- `primer init` - Interactive setup\n- `primer tui` - Terminal UI\n- `primer instructions` - Generate instructions\n- `primer analyze` - Repository analysis\n- `primer batch` - Batch processing\n- `primer readiness` - Readiness report\n- `primer eval` - Evaluation framework", + "toolRequests": [] + } + }, + { + "timestampMs": 1770182490886, + "phase": "withoutInstructions", + "type": "tool.execution_complete", + "data": { + "toolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", + "success": true, + "result": { + "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It features repository analysis, AI-powered instruction generation, batch processing, evaluation framework, readiness reports, and GitHub integration.\n\n**Main Entrypoints:**\n\n| File | Purpose |\n|------|---------|\n| `/Users/pierceboggan/Documents/get-ready/src/index.ts` | CLI entry point |\n| `/Users/pierceboggan/Documents/get-ready/src/cli.ts` | Commander CLI setup |\n\n**Key Commands:**\n- `primer init` - Interactive setup\n- `primer tui` - Terminal UI\n- `primer instructions` - Generate instructions\n- `primer analyze` - Repository analysis\n- `primer batch` - Batch processing\n- `primer readiness` - Readiness report\n- `primer eval` - Evaluation framework", + "detailedContent": "## Summary\n\n(Full response provided to agent)" + }, + "toolTelemetry": { + "properties": { + "prompt_length": "115", + "response_length": "828", + "hashed_agent_name": "6f281157ab246f0e1f35db82165d3448ee1e39077ab0d720fca7dddf014249d6", + "agent_type": "explore", + "execution_mode": "sync" + }, + "restrictedProperties": { + "agent_name": "explore" + }, + "metrics": { + "response_length": 828, + "numberOfToolCallsMadeByAgent": 3 + } + } + } + }, + { + "timestampMs": 1770182490886, + "phase": "withoutInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770182490886, + "phase": "withoutInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770182490886, + "phase": "withoutInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 10605, + "messagesLength": 5 + } + }, + { + "timestampMs": 1770182491922, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": "This", + "totalResponseSizeBytes": 4 + } + }, + { + "timestampMs": 1770182491923, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 12, + "deltaPreview": " application", + "totalResponseSizeBytes": 16 + } + }, + { + "timestampMs": 1770182491923, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 17 + } + }, + { + "timestampMs": 1770182491923, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 24 + } + }, + { + "timestampMs": 1770182491923, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 25 + } + }, + { + "timestampMs": 1770182491923, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 28 + } + }, + { + "timestampMs": 1770182491923, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 30 + } + }, + { + "timestampMs": 1770182492100, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 34 + } + }, + { + "timestampMs": 1770182492100, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": " tool", + "totalResponseSizeBytes": 39 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": " that", + "totalResponseSizeBytes": 44 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 9, + "deltaPreview": " analyzes", + "totalResponseSizeBytes": 53 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": " code", + "totalResponseSizeBytes": 58 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": "bases", + "totalResponseSizeBytes": 63 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 67 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 10, + "deltaPreview": " generates", + "totalResponseSizeBytes": 77 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": " `.", + "totalResponseSizeBytes": 80 + } + }, + { + "timestampMs": 1770182492101, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "github", + "totalResponseSizeBytes": 86 + } + }, + { + "timestampMs": 1770182492171, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": "/cop", + "totalResponseSizeBytes": 90 + } + }, + { + "timestampMs": 1770182492171, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 94 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": "-in", + "totalResponseSizeBytes": 97 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 10, + "deltaPreview": "structions", + "totalResponseSizeBytes": 107 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": ".md", + "totalResponseSizeBytes": 110 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 111 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " files", + "totalResponseSizeBytes": 117 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 120 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": " help", + "totalResponseSizeBytes": 125 + } + }, + { + "timestampMs": 1770182492172, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": " AI", + "totalResponseSizeBytes": 128 + } + }, + { + "timestampMs": 1770182492287, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 7, + "deltaPreview": " coding", + "totalResponseSizeBytes": 135 + } + }, + { + "timestampMs": 1770182492287, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 11, + "deltaPreview": " assistants", + "totalResponseSizeBytes": 146 + } + }, + { + "timestampMs": 1770182492287, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 11, + "deltaPreview": " understand", + "totalResponseSizeBytes": 157 + } + }, + { + "timestampMs": 1770182492287, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 9, + "deltaPreview": " projects", + "totalResponseSizeBytes": 166 + } + }, + { + "timestampMs": 1770182492288, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 7, + "deltaPreview": " better", + "totalResponseSizeBytes": 173 + } + }, + { + "timestampMs": 1770182492288, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 174 + } + }, + { + "timestampMs": 1770182492288, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": " It", + "totalResponseSizeBytes": 177 + } + }, + { + "timestampMs": 1770182492288, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 9, + "deltaPreview": " supports", + "totalResponseSizeBytes": 186 + } + }, + { + "timestampMs": 1770182492288, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 197 + } + }, + { + "timestampMs": 1770182492288, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 9, + "deltaPreview": " analysis", + "totalResponseSizeBytes": 206 + } + }, + { + "timestampMs": 1770182492404, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 207 + } + }, + { + "timestampMs": 1770182492404, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": " AI", + "totalResponseSizeBytes": 210 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 8, + "deltaPreview": "-powered", + "totalResponseSizeBytes": 218 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 12, + "deltaPreview": " instruction", + "totalResponseSizeBytes": 230 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 11, + "deltaPreview": " generation", + "totalResponseSizeBytes": 241 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 242 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " batch", + "totalResponseSizeBytes": 248 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 11, + "deltaPreview": " processing", + "totalResponseSizeBytes": 259 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 260 + } + }, + { + "timestampMs": 1770182492405, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 271 + } + }, + { + "timestampMs": 1770182492567, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 272 + } + }, + { + "timestampMs": 1770182492567, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 10, + "deltaPreview": " readiness", + "totalResponseSizeBytes": 282 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 8, + "deltaPreview": " reports", + "totalResponseSizeBytes": 290 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 291 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 295 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 299 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 302 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 12, + "deltaPreview": " integration", + "totalResponseSizeBytes": 314 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": ".\n\n", + "totalResponseSizeBytes": 317 + } + }, + { + "timestampMs": 1770182492568, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": "Main", + "totalResponseSizeBytes": 321 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " entry", + "totalResponseSizeBytes": 327 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "points", + "totalResponseSizeBytes": 333 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": ":\n", + "totalResponseSizeBytes": 335 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": "-", + "totalResponseSizeBytes": 336 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 340 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 346 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 349 + } + }, + { + "timestampMs": 1770182492747, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " —", + "totalResponseSizeBytes": 353 + } + }, + { + "timestampMs": 1770182492748, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 357 + } + }, + { + "timestampMs": 1770182492748, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " entry", + "totalResponseSizeBytes": 363 + } + }, + { + "timestampMs": 1770182492818, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " point", + "totalResponseSizeBytes": 369 + } + }, + { + "timestampMs": 1770182492818, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": "\n", + "totalResponseSizeBytes": 370 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": "-", + "totalResponseSizeBytes": 371 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 375 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 376 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": "cli", + "totalResponseSizeBytes": 379 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 382 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " —", + "totalResponseSizeBytes": 386 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 10, + "deltaPreview": " Commander", + "totalResponseSizeBytes": 396 + } + }, + { + "timestampMs": 1770182492819, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 400 + } + }, + { + "timestampMs": 1770182492924, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " setup", + "totalResponseSizeBytes": 406 + } + }, + { + "timestampMs": 1770182492924, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "\n\n", + "totalResponseSizeBytes": 408 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 3, + "deltaPreview": "Key", + "totalResponseSizeBytes": 411 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 420 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 8, + "deltaPreview": " include", + "totalResponseSizeBytes": 428 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 429 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 431 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 437 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": " init", + "totalResponseSizeBytes": 442 + } + }, + { + "timestampMs": 1770182492927, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 444 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 446 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 452 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " tui", + "totalResponseSizeBytes": 456 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 458 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 460 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 466 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 13, + "deltaPreview": " instructions", + "totalResponseSizeBytes": 479 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 481 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 483 + } + }, + { + "timestampMs": 1770182492962, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 489 + } + }, + { + "timestampMs": 1770182493032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 8, + "deltaPreview": " analyze", + "totalResponseSizeBytes": 497 + } + }, + { + "timestampMs": 1770182493032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 499 + } + }, + { + "timestampMs": 1770182493032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 501 + } + }, + { + "timestampMs": 1770182493032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 507 + } + }, + { + "timestampMs": 1770182493032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": " batch", + "totalResponseSizeBytes": 513 + } + }, + { + "timestampMs": 1770182493032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 515 + } + }, + { + "timestampMs": 1770182493033, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 517 + } + }, + { + "timestampMs": 1770182493033, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 523 + } + }, + { + "timestampMs": 1770182493033, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 10, + "deltaPreview": " readiness", + "totalResponseSizeBytes": 533 + } + }, + { + "timestampMs": 1770182493033, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 535 + } + }, + { + "timestampMs": 1770182493106, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 539 + } + }, + { + "timestampMs": 1770182493106, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 541 + } + }, + { + "timestampMs": 1770182493106, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 547 + } + }, + { + "timestampMs": 1770182493106, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 5, + "deltaPreview": " eval", + "totalResponseSizeBytes": 552 + } + }, + { + "timestampMs": 1770182493106, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "deltaChars": 2, + "deltaPreview": "`.", + "totalResponseSizeBytes": 554 + } + }, + { + "timestampMs": 1770182493106, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 10005, + "outputTokens": 114, + "cacheReadTokens": 9088, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 2219, + "initiator": "agent", + "apiCallId": "chatcmpl-D5PcRI6T4ILfUtZDNyDGjcQAeURGc", + "providerCallId": "E903:35A03D:33FAB6:3DB199:6982D75A", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770182493107, + "phase": "withoutInstructions", + "type": "assistant.message", + "data": { + "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "content": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.", + "toolRequests": [] + } + }, + { + "timestampMs": 1770182493107, + "phase": "withoutInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770182493107, + "phase": "withoutInstructions", + "type": "session.idle", + "data": {} + }, + { + "timestampMs": 1770182493132, + "phase": "withInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770182493132, + "phase": "withInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770182493866, + "phase": "withInstructions", + "type": "user.message", + "data": { + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", + "transformedContent": "2026-02-04T05:21:33.829Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", + "attachments": [] + } + }, + { + "timestampMs": 1770182493867, + "phase": "withInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770182493867, + "phase": "withInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 11015, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770182495951, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 10382, + "outputTokens": 94, + "cacheReadTokens": 9984, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 2080, + "initiator": "user", + "apiCallId": "chatcmpl-D5PcUtFiguAzEPDeiBTxJYeehvIh9", + "providerCallId": "E903:35A03D:340477:3DBCDB:6982D75D", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770182495951, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "messageId": "fa934988-cc62-4c45-8c26-b19e0fb419f0", + "content": "", + "toolRequests": [ + { + "toolCallId": "call_gQKcwh4lrRf8iHebDhI7mxBH", + "name": "report_intent", + "arguments": { + "intent": "Summarizing application purpose" + }, + "type": "function" + }, + { + "toolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "name": "task", + "arguments": { + "agent_type": "explore", + "description": "Summarizing app and entrypoints", + "prompt": "Summarize what this application does and list the main entrypoints. Be concise. List the main CLI commands or programmatic entrypoints if present." + }, + "type": "function" + } + ] + } + }, + { + "timestampMs": 1770182495951, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "toolCallId": "call_gQKcwh4lrRf8iHebDhI7mxBH", + "toolName": "report_intent", + "arguments": { + "intent": "Summarizing application purpose" + } + } + }, + { + "timestampMs": 1770182495951, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "toolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolName": "task", + "arguments": { + "agent_type": "explore", + "description": "Summarizing app and entrypoints", + "prompt": "Summarize what this application does and list the main entrypoints. Be concise. List the main CLI commands or programmatic entrypoints if present." + } + } + }, + { + "timestampMs": 1770182495951, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "toolCallId": "call_gQKcwh4lrRf8iHebDhI7mxBH", + "success": true, + "result": { + "content": "Intent logged", + "detailedContent": "Summarizing application purpose" + }, + "toolTelemetry": {} + } + }, + { + "timestampMs": 1770182499225, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "claude-haiku-4.5", + "inputTokens": 2713, + "outputTokens": 335, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0.33, + "duration": 2960, + "initiator": "sub-agent", + "apiCallId": "msg_017fmNqNjPGntbszM5ineEJx", + "providerCallId": "E903:35A03D:340C7D:3DC60F:6982D760", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + }, + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg" + } + }, + { + "timestampMs": 1770182499225, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "messageId": "531da1e7-1e5a-4994-9b81-e88dc0c26449", + "content": "", + "toolRequests": [ + { + "toolCallId": "toolu_01JKTy3e1wKbgcDnacNd6zAL", + "name": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready" + }, + "type": "function" + }, + { + "toolCallId": "toolu_01Gthn6BZZUdvXEe7xij4AxH", + "name": "glob", + "arguments": { + "pattern": "*.{json,md,ts,js}" + }, + "type": "function" + }, + { + "toolCallId": "toolu_018NEuFLeYuySsA57e7ng8dF", + "name": "grep", + "arguments": { + "pattern": "^#!/usr/bin|bin|entry|command", + "glob": "**/*.json", + "output_mode": "content", + "head_limit": 20 + }, + "type": "function" + } + ], + "reasoningOpaque": "Sj+mHN97bEs0KKkaaMzdSj9k5udHmn9TDLgFxNHMmOtmohC5w2RTGHP0gkk4nzgjLjiZXFpqEYIjDphd6pRNYl1buJlL1qwzgHGnbBvaXutwQn3158THudxBZiWZIu5XbbJuQBEeDw6cJ4p/bScgmeFlDS8GmPB9GVxO/eppM8McfXoHTcpCGxNKkWcBsQqrGDd0cYMYEIr5MX2VI7oivTcgXQ8l6oSd8HzzNQakIx6zg95+Pp2BOLzmDX1kj4Yg50FU1P8UvsHJDuIZxfZNDHSrq4w05NGpDDhi/EU+L1gAhr50lhoBkL+/p4Pmf4J2JSdLWK9jhaMjoRIT0NNgLOkweDgdSw2RWIQ/IMxUOLPAmA9gO3vVOYHrOR44t0JREP/kKEbKIAppOnt+bdhNZlmLrTiz89Z8spefLgVO+vA2HiLtaMChRp3SLMEPfWuUPyCOATQIMLaKRBJdj7UPxxs8qxIthVYC3I/OwGx/lYDgn4iyiV3Jldl2eyTTVkQ9I4dX3vMNRX5IEaIqy+KmR/poWT/RdJIeZvE08lnZcAfonYmHk9Y4G0L+d+1NnGsbkZNwDdbWtMgbE1rCeto9mL8F75j7sSDSQ/kbdmSBJB33Pp4Z9LM3mjdIIvdTpoXU4vKj+3tJJkDtW7Wzuk3wp0EWYdPU8g12huU5QA0I1t6UFbKt14NKAmNCvPDCv8BYjEONsvBgWCnjGuTzMZp9D/bFOrGaTT4RVZyO7+krVObs8ONJFeCVTkkMf9KhTrJXGcNxJf73J0JYRaZTp6ZtARjLL5uXOxQUz5mx0qwJYw3GnRctYmooc7WjFUFyHYarl9UVvfg0BrT10n4GWaZZbFWy4YKy0hrPc+yeq7uDM67b2686inCqmiTXXrtoXSchfbz65BYo9sONjRY+WA/ZZCYYeahImPej6UXy55R4pZmKlxGhWqg19RyzfJF5AUbIuK3fsKy3lGO35z328K+XhvKmgv5nUngBW6YVBk4vaqk9Qhq89xp7olwHK07SS+iNNMd+t8Mm9ljBWpzJy7JY+uDllcskjLnDlG14tmlCa69txWFpjHa9uugn0ZwZLWYCE1lRGb7BMT5MPXWr862a+AW+YYuANtYjKMOOh1g7dW9+5GbVO2+LUEbHkAlaUd4vXIpc6XyGl2rX767xFgmkpZKRg3yUPL16sUtdvDC2qowSsusAJwOV+rf5a05eQnA4h+hcpEA2SdXf3ZNk0RVKS7Pabbbvf2zCuIVEHS0Eh8yhqNsgKHO7A2Y9MTXgwYBf5+30oCi1bM1RjfAaBJ3b4jnPp1tRuMQ4dBZYGgjA0MGsA5FJX+X1WTgC1IKfB/LEHIqLBrqeuzanVvb1CHt0ROnf+UOCE6aQlOmi6SwNdw0bBAwjr/77WKbKZuOmlUFRhS/pACRz5qfZQxD37OF3PiwrqNlHjuWQxG6b2+VmH0sfe68qOnwWuZPijybKks8YWr5efUuNWEWTdUkrWC+y96Uh83ApY50iPhd3+qymzZvPI4BWa7LrLMSVMBT3tlgihTxTT3r2OZcOTRI7J/Ar49MNob7XDzJzIg==", + "reasoningText": "The user wants me to:\n1. Summarize what the application does\n2. List the main entrypoints\n3. List main CLI commands or programmatic entrypoints if present\n4. Be concise\n\nI should start by exploring the codebase structure to understand what this app does. Let me look at:\n1. The root directory structure\n2. Package.json or similar config files to understand what it is\n3. Main entry files\n4. README or documentation\n\nLet me start with viewing the root directory and searching for key files in parallel." + } + }, + { + "timestampMs": 1770182499225, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_01JKTy3e1wKbgcDnacNd6zAL", + "toolName": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready" + } + } + }, + { + "timestampMs": 1770182499225, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_01Gthn6BZZUdvXEe7xij4AxH", + "toolName": "glob", + "arguments": { + "pattern": "*.{json,md,ts,js}" + } + } + }, + { + "timestampMs": 1770182499225, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_018NEuFLeYuySsA57e7ng8dF", + "toolName": "grep", + "arguments": { + "pattern": "^#!/usr/bin|bin|entry|command", + "glob": "**/*.json", + "output_mode": "content", + "head_limit": 20 + } + } + }, + { + "timestampMs": 1770182499226, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_01JKTy3e1wKbgcDnacNd6zAL", + "success": true, + "result": { + "content": ".DS_Store\n.git\n.github\n.gitignore\n.prettierrc.json\n.primer-cache\nCHANGELOG.md\nCODEOWNERS\nCONTRIBUTING.md\nLICENSE\nPLAN.md\nREADME.md\nSECURITY.md\ndist\neslint.config.js\neval-results.html\neval-results.json\nexamples\nnode_modules\npackage-lock.json\npackage.json\nprimer.eval.json\nprimer.png\nrelease-please-config.json\nrelease-please-manifest.json\nsrc\ntsconfig.json\nvitest.config.ts", + "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready b/Users/pierceboggan/Documents/get-ready\ncreate file mode 100644\nindex 0000000..0000000\n--- a/dev/null\n+++ b/Users/pierceboggan/Documents/get-ready\n@@ -1,0 +1,28 @@\n .DS_Store\n .git\n .github\n .gitignore\n .prettierrc.json\n .primer-cache\n CHANGELOG.md\n CODEOWNERS\n CONTRIBUTING.md\n LICENSE\n PLAN.md\n README.md\n SECURITY.md\n dist\n eslint.config.js\n eval-results.html\n eval-results.json\n examples\n node_modules\n package-lock.json\n package.json\n primer.eval.json\n primer.png\n release-please-config.json\n release-please-manifest.json\n src\n tsconfig.json\n vitest.config.ts\n" + } + } + }, + { + "timestampMs": 1770182499238, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_01Gthn6BZZUdvXEe7xij4AxH", + "success": true, + "result": { + "content": "./release-please-config.json\n./vitest.config.ts\n./src/services/git.ts\n./primer.eval.json\n./src/services/instructions.ts\n./eslint.config.js\n./src/services/analyzer.ts\n./tsconfig.json\n./PLAN.md\n./src/index.ts\n./src/services/readiness.ts\n./src/services/github.ts\n./src/services/evaluator.ts\n./src/services/azureDevops.ts\n./src/services/generator.ts\n./.prettierrc.json\n./README.md\n./eval-results.json\n./CHANGELOG.md\n./release-please-manifest.json\n./package.json\n./package-lock.json\n./CONTRIBUTING.md\n./src/services/__tests__/analyzer.test.ts\n./src/cli.ts\n./examples/primer.eval.json\n./examples/README.md\n./SECURITY.md\n./src/utils/logger.ts\n./src/utils/fs.ts\n./.github/PULL_REQUEST_TEMPLATE.md\n./.github/copilot-instructions.md\n./src/commands/pr.ts\n./src/commands/eval.ts\n./src/commands/readiness.ts\n./src/commands/init.ts\n./src/commands/analyze.ts\n./src/commands/generate.ts\n./src/commands/templates.ts\n./src/commands/config.ts\n./src/commands/update.ts\n./.github/ISSUE_TEMPLATE/bug_report.md\n./.github/ISSUE_TEMPLATE/feature_request.md\n./src/ui/index.ts\n./src/ui/README.md", + "detailedContent": "./release-please-config.json\n./vitest.config.ts\n./src/services/git.ts\n./primer.eval.json\n./src/services/instructions.ts\n./eslint.config.js\n./src/services/analyzer.ts\n./tsconfig.json\n./PLAN.md\n./src/index.ts\n./src/services/readiness.ts\n./src/services/github.ts\n./src/services/evaluator.ts\n./src/services/azureDevops.ts\n./src/services/generator.ts\n./.prettierrc.json\n./README.md\n./eval-results.json\n./CHANGELOG.md\n./release-please-manifest.json\n./package.json\n./package-lock.json\n./CONTRIBUTING.md\n./src/services/__tests__/analyzer.test.ts\n./src/cli.ts\n./examples/primer.eval.json\n./examples/README.md\n./SECURITY.md\n./src/utils/logger.ts\n./src/utils/fs.ts\n./.github/PULL_REQUEST_TEMPLATE.md\n./.github/copilot-instructions.md\n./src/commands/pr.ts\n./src/commands/eval.ts\n./src/commands/readiness.ts\n./src/commands/init.ts\n./src/commands/analyze.ts\n./src/commands/generate.ts\n./src/commands/templates.ts\n./src/commands/config.ts\n./src/commands/update.ts\n./.github/ISSUE_TEMPLATE/bug_report.md\n./.github/ISSUE_TEMPLATE/feature_request.md\n./src/ui/index.ts\n./src/ui/README.md" + } + } + }, + { + "timestampMs": 1770182499260, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_018NEuFLeYuySsA57e7ng8dF", + "success": true, + "result": { + "content": "./package.json: \"commander\": \"^14.0.2\",\n./package.json: \"bin\": {\n./eval-results.json: \"prompt\": \"Summarize what this application does and list the main entrypoints.\",\n./eval-results.json: \"expectation\": \"Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\",\n./eval-results.json: \"withInstructions\": \"This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub integration, and an interactive terminal UI.\\n\\nMain entrypoints:\\n- dist/index.js (npm bin: primer) — Main CLI entry point\\n- src/index.ts — TypeScript entry point\\n- src/cli.ts — CLI command setup\\n\\nPrimary commands include: init, tui, instructions, analyze, batch, readiness, eval, pr, and generate.\",\n./eval-results.json: \"withoutInstructions\": \"This application, \\\"Primer,\\\" is a CLI tool that primes repositories for AI-assisted development. It analyzes codebases, generates `.github/copilot-instructions.md` files to help AI coding assistants, supports batch processing, provides an evaluation framework, and integrates with GitHub for automation.\\n\\n**Main entrypoints:**\\n- CLI command: `primer` (installed globally or run locally)\\n- Programmatic entry: `src/index.ts` (calls `runCli` in `src/cli.ts`)\\n- Key CLI commands: `init`, `analyze`, `generate`, `pr`, `eval`, `tui`, `instructions`, `readiness`, `batch`, `templates`, `update`, `config` (all wired in `src/cli.ts`)\",\n./eval-results.json: \"rationale\": \"Response B best matches the expectation by explicitly mentioning both the CLI entrypoint in src/index.ts and that this is the Primer CLI. It also provides a clear list of main entrypoints and commands, directly addressing the requirements. Response A is also accurate but less explicit about the entryp…", + "detailedContent": "./package.json: \"commander\": \"^14.0.2\",\n./package.json: \"bin\": {\n./eval-results.json: \"prompt\": \"Summarize what this application does and list the main entrypoints.\",\n./eval-results.json: \"expectation\": \"Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\",\n./eval-results.json: \"withInstructions\": \"This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub integration, and an interactive terminal UI.\\n\\nMain entrypoints:\\n- dist/index.js (npm bin: primer) — Main CLI entry point\\n- src/index.ts — TypeScript entry point\\n- src/cli.ts — CLI command setup\\n\\nPrimary commands include: init, tui, instructions, analyze, batch, readiness, eval, pr, and generate.\",\n./eval-results.json: \"withoutInstructions\": \"This application, \\\"Primer,\\\" is a CLI tool that primes repositories for AI-assisted development. It analyzes codebases, generates `.github/copilot-instructions.md` files to help AI coding assistants, supports batch processing, provides an evaluation framework, and integrates with GitHub for automation.\\n\\n**Main entrypoints:**\\n- CLI command: `primer` (installed globally or run locally)\\n- Programmatic entry: `src/index.ts` (calls `runCli` in `src/cli.ts`)\\n- Key CLI commands: `init`, `analyze`, `generate`, `pr`, `eval`, `tui`, `instructions`, `readiness`, `batch`, `templates`, `update`, `config` (all wired in `src/cli.ts`)\",\n./eval-results.json: \"rationale\": \"Response B best matches the expectation by explicitly mentioning both the CLI entrypoint in src/index.ts and that this is the Primer CLI. It also provides a clear list of main entrypoints and commands, directly addressing the requirements. Response A is also accurate but less explicit about the entryp…" + } + } + }, + { + "timestampMs": 1770182502888, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "claude-haiku-4.5", + "inputTokens": 9496, + "outputTokens": 165, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0.33, + "duration": 3626, + "initiator": "sub-agent", + "apiCallId": "msg_01285RH3mRmZCCKvqySHWWA9", + "providerCallId": "E903:35A03D:341602:3DD120:6982D763", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + }, + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg" + } + }, + { + "timestampMs": 1770182502888, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "messageId": "64122101-f836-4292-b6cf-9b2977b87e51", + "content": "Perfect! Now let me get a quick look at the main index and cli files:", + "toolRequests": [ + { + "toolCallId": "toolu_019LFBnAwWLkTJdZchDi3VH5", + "name": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/src/index.ts" + }, + "type": "function" + }, + { + "toolCallId": "toolu_019rGWXpe6FY43aGFY64R9XQ", + "name": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/src/cli.ts", + "view_range": [ + 1, + 95 + ] + }, + "type": "function" + } + ] + } + }, + { + "timestampMs": 1770182502889, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_019LFBnAwWLkTJdZchDi3VH5", + "toolName": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/src/index.ts" + } + } + }, + { + "timestampMs": 1770182502889, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_019rGWXpe6FY43aGFY64R9XQ", + "toolName": "view", + "arguments": { + "path": "/Users/pierceboggan/Documents/get-ready/src/cli.ts", + "view_range": [ + 1, + 95 + ] + } + } + }, + { + "timestampMs": 1770182502893, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_019LFBnAwWLkTJdZchDi3VH5", + "success": true, + "result": { + "content": "1. import { runCli } from \"./cli\";\n2. \n3. const [, , ...args] = process.argv;\n4. if (args.length === 0) {\n5. \trunCli([process.argv[0], process.argv[1], \"tui\"]);\n6. } else {\n7. \trunCli(process.argv);\n8. }\n9. ", + "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/src/index.ts b/Users/pierceboggan/Documents/get-ready/src/index.ts\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/src/index.ts\n+++ b/Users/pierceboggan/Documents/get-ready/src/index.ts\n@@ -1,9 +1,9 @@\n import { runCli } from \"./cli\";\n \n const [, , ...args] = process.argv;\n if (args.length === 0) {\n \trunCli([process.argv[0], process.argv[1], \"tui\"]);\n } else {\n \trunCli(process.argv);\n }\n \n" + } + } + }, + { + "timestampMs": 1770182502910, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "toolCallId": "toolu_019rGWXpe6FY43aGFY64R9XQ", + "success": true, + "result": { + "content": "1. import { Command } from \"commander\";\n2. import { initCommand } from \"./commands/init\";\n3. import { analyzeCommand } from \"./commands/analyze\";\n4. import { generateCommand } from \"./commands/generate\";\n5. import { prCommand } from \"./commands/pr\";\n6. import { templatesCommand } from \"./commands/templates\";\n7. import { updateCommand } from \"./commands/update\";\n8. import { configCommand } from \"./commands/config\";\n9. import { evalCommand } from \"./commands/eval\";\n10. import { tuiCommand } from \"./commands/tui\";\n11. import { instructionsCommand } from \"./commands/instructions\";\n12. import { batchCommand } from \"./commands/batch\";\n13. import { readinessCommand } from \"./commands/readiness\";\n14. \n15. export function runCli(argv: string[]): void {\n16. const program = new Command();\n17. \n18. program\n19. .name(\"primer\")\n20. .description(\"Prime repositories for AI-assisted development\")\n21. .version(\"0.1.0\");\n22. \n23. program\n24. .command(\"init\")\n25. .argument(\"[path]\", \"Path to a local repository\")\n26. .option(\"--github\", \"Use a GitHub repository\")\n27. .option(\"--provider \", \"Repo provider (github|azure)\")\n28. .option(\"--yes\", \"Accept defaults and skip prompts\")\n29. .option(\"--force\", \"Overwrite existing files\")\n30. .action(initCommand);\n31. \n32. program\n33. .command(\"analyze\")\n34. .argument(\"[path]\", \"Path to a local repository\")\n35. .option(\"--json\", \"Output JSON\")\n36. .action(analyzeCommand);\n37. \n38. program\n39. .command(\"generate\")\n40. .argument(\"\", \"prompts|agents|mcp|vscode|aiignore\")\n41. .argument(\"[path]\", \"Path to a local repository\")\n42. .option(\"--force\", \"Overwrite existing files\")\n43. .action(generateCommand);\n44. \n45. program\n46. .command(\"pr\")\n47. .argument(\"[repo]\", \"Repo identifier (github: owner/name, azure: org/project/repo)\")\n48. .option(\"--branch \", \"Branch name\")\n49. .option(\"--provider \", \"Repo provider (github|azu…", + "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/src/cli.ts b/Users/pierceboggan/Documents/get-ready/src/cli.ts\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/src/cli.ts\n+++ b/Users/pierceboggan/Documents/get-ready/src/cli.ts\n@@ -1,95 +1,95 @@\n import { Command } from \"commander\";\n import { initCommand } from \"./commands/init\";\n import { analyzeCommand } from \"./commands/analyze\";\n import { generateCommand } from \"./commands/generate\";\n import { prCommand } from \"./commands/pr\";\n import { templatesCommand } from \"./commands/templates\";\n import { updateCommand } from \"./commands/update\";\n import { configCommand } from \"./commands/config\";\n import { evalCommand } from \"./commands/eval\";\n import { tuiCommand } from \"./commands/tui\";\n import { instructionsCommand } from \"./commands/instructions\";\n import { batchCommand } from \"./commands/batch\";\n import { readinessCommand } from \"./commands/readiness\";\n \n export function runCli(argv: string[]): void {\n const program = new Command();\n \n program\n .name(\"primer\")\n .description(\"Prime repositories for AI-assisted development\")\n .version(\"0.1.0\");\n \n program\n .command(\"init\")\n .argument(\"[path]\", \"Path to a local repository\")\n .option(\"--github\", \"Use a GitHub repository\")\n .option(\"--provider \", \"Repo provider (github|azure)\")\n .option(\"--yes\", \"Accept defaults and skip prompts\")\n .option(\"--force\", \"Overwrite existing files\")\n .action(initCommand);\n \n program\n .command(\"analyze\")\n .argument(\"[path]\", \"Path to a local repository\")\n .option(\"--json\", \"Output JSON\")\n .action(analyzeCommand);\n \n program\n .command(\"generate\")\n .argument(\"\", \"prompts|agents|mcp|vscode|aiignore\")\n .argument(\"[path]\", \"Path to a local repository\")\n .option(\"--force\", \"Overwrite existing files\")\n .action(generateCommand);\n \n program\n .command(\"pr\")\n .argument(\"[repo]\", \"Repo identifier (github: owner/name, …" + } + } + }, + { + "timestampMs": 1770182507175, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "claude-haiku-4.5", + "inputTokens": 11011, + "outputTokens": 328, + "cacheReadTokens": 9489, + "cacheWriteTokens": 0, + "cost": 0.33, + "duration": 4250, + "initiator": "sub-agent", + "apiCallId": "msg_016HyJsAAcmf6gv9L4xZsF5b", + "providerCallId": "E903:35A03D:342219:3DDECD:6982D766", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + }, + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg" + } + }, + { + "timestampMs": 1770182507175, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "messageId": "0d741c5b-08d1-4f5a-861e-6167380217c7", + "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\n### Main Entrypoints\n\n**CLI Command:**\n- `primer` — Binary entrypoint (installed globally via `npm install -g primer`)\n\n**Programmatic Entry:**\n- `src/index.ts` → calls `runCli()` in `src/cli.ts`\n- Defaults to `tui` command if no args provided\n\n### Primary Commands\n\n- **init** — Initialize a repository with Primer\n- **analyze** — Analyze codebase structure \n- **generate** — Generate instructions, agents, MCP, VS Code, or .aiignore configs\n- **instructions** — Generate `.github/copilot-instructions.md` using Copilot SDK\n- **tui** — Interactive terminal UI (default)\n- **eval** — Evaluate instruction effectiveness against test cases\n- **readiness** — Score AI readiness across key pillars\n- **pr** — Create PRs with generated instructions (GitHub/Azure DevOps)\n- **batch** — Process multiple repos across organizations\n- **templates**, **config**, **update** — Utility commands", + "toolRequests": [] + } + }, + { + "timestampMs": 1770182507215, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "toolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", + "success": true, + "result": { + "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\n### Main Entrypoints\n\n**CLI Command:**\n- `primer` — Binary entrypoint (installed globally via `npm install -g primer`)\n\n**Programmatic Entry:**\n- `src/index.ts` → calls `runCli()` in `src/cli.ts`\n- Defaults to `tui` command if no args provided\n\n### Primary Commands\n\n- **init** — Initialize a repository with Primer\n- **analyze** — Analyze codebase structure \n- **generate** — Generate instructions, agents, MCP, VS Code, or .aiignore configs\n- **instructions** — Generate `.github/copilot-instructions.md` using Copilot SDK\n- **tui** — Interactive terminal UI (default)\n- **eval** — Evaluate instruction effectiveness against test cases\n- **readiness** — Score AI readiness across key pillars\n- **pr** — Create PRs with generated instructions (GitHub/Azure DevOps)\n- **batch** — Process multiple repos across organizations\n- **templates**, **config**, **update** — Utility commands", + "detailedContent": "## Summary\n\n(Full response provided to agent)" + }, + "toolTelemetry": { + "properties": { + "prompt_length": "146", + "response_length": "1262", + "hashed_agent_name": "6f281157ab246f0e1f35db82165d3448ee1e39077ab0d720fca7dddf014249d6", + "agent_type": "explore", + "execution_mode": "sync" + }, + "restrictedProperties": { + "agent_name": "explore" + }, + "metrics": { + "response_length": 1262, + "numberOfToolCallsMadeByAgent": 5 + } + } + } + }, + { + "timestampMs": 1770182507215, + "phase": "withInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770182507215, + "phase": "withInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770182507215, + "phase": "withInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 11390, + "messagesLength": 5 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "This", + "totalResponseSizeBytes": 4 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 12, + "deltaPreview": " application", + "totalResponseSizeBytes": 16 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 17 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 24 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 25 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 28 + } + }, + { + "timestampMs": 1770182508277, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 30 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 34 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": " tool", + "totalResponseSizeBytes": 39 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": " that", + "totalResponseSizeBytes": 44 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " analyzes", + "totalResponseSizeBytes": 53 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": " code", + "totalResponseSizeBytes": 58 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": "bases", + "totalResponseSizeBytes": 63 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 67 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 10, + "deltaPreview": " generates", + "totalResponseSizeBytes": 77 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " `.", + "totalResponseSizeBytes": 80 + } + }, + { + "timestampMs": 1770182508411, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": "github", + "totalResponseSizeBytes": 86 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "/cop", + "totalResponseSizeBytes": 90 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 94 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "-in", + "totalResponseSizeBytes": 97 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 10, + "deltaPreview": "structions", + "totalResponseSizeBytes": 107 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": ".md", + "totalResponseSizeBytes": 110 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 111 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": " files", + "totalResponseSizeBytes": 117 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 120 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": " help", + "totalResponseSizeBytes": 125 + } + }, + { + "timestampMs": 1770182508656, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " AI", + "totalResponseSizeBytes": 128 + } + }, + { + "timestampMs": 1770182508685, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 7, + "deltaPreview": " coding", + "totalResponseSizeBytes": 135 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 11, + "deltaPreview": " assistants", + "totalResponseSizeBytes": 146 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " (", + "totalResponseSizeBytes": 148 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "like", + "totalResponseSizeBytes": 152 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 156 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 159 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " Cop", + "totalResponseSizeBytes": 163 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 167 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ")", + "totalResponseSizeBytes": 168 + } + }, + { + "timestampMs": 1770182508686, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 11, + "deltaPreview": " understand", + "totalResponseSizeBytes": 179 + } + }, + { + "timestampMs": 1770182508748, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " projects", + "totalResponseSizeBytes": 188 + } + }, + { + "timestampMs": 1770182508748, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 7, + "deltaPreview": " better", + "totalResponseSizeBytes": 195 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 196 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " It", + "totalResponseSizeBytes": 199 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " supports", + "totalResponseSizeBytes": 208 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 219 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " analysis", + "totalResponseSizeBytes": 228 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 229 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " AI", + "totalResponseSizeBytes": 232 + } + }, + { + "timestampMs": 1770182508750, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 8, + "deltaPreview": "-powered", + "totalResponseSizeBytes": 240 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 12, + "deltaPreview": " instruction", + "totalResponseSizeBytes": 252 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 11, + "deltaPreview": " generation", + "totalResponseSizeBytes": 263 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 264 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 275 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 276 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 10, + "deltaPreview": " readiness", + "totalResponseSizeBytes": 286 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 10, + "deltaPreview": " reporting", + "totalResponseSizeBytes": 296 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 297 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 301 + } + }, + { + "timestampMs": 1770182508991, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 304 + } + }, + { + "timestampMs": 1770182509181, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "/A", + "totalResponseSizeBytes": 306 + } + }, + { + "timestampMs": 1770182509181, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "zure", + "totalResponseSizeBytes": 310 + } + }, + { + "timestampMs": 1770182509181, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " Dev", + "totalResponseSizeBytes": 314 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "Ops", + "totalResponseSizeBytes": 317 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 12, + "deltaPreview": " integration", + "totalResponseSizeBytes": 329 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 330 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 334 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " an", + "totalResponseSizeBytes": 337 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 12, + "deltaPreview": " interactive", + "totalResponseSizeBytes": 349 + } + }, + { + "timestampMs": 1770182509182, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " terminal", + "totalResponseSizeBytes": 358 + } + }, + { + "timestampMs": 1770182509220, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " UI", + "totalResponseSizeBytes": 361 + } + }, + { + "timestampMs": 1770182509220, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": ".\n\n", + "totalResponseSizeBytes": 364 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "Main", + "totalResponseSizeBytes": 368 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": " entry", + "totalResponseSizeBytes": 374 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": "points", + "totalResponseSizeBytes": 380 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": ":\n", + "totalResponseSizeBytes": 382 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "-", + "totalResponseSizeBytes": 383 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 387 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 388 + } + }, + { + "timestampMs": 1770182509222, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 390 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": "primer", + "totalResponseSizeBytes": 396 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 397 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " (", + "totalResponseSizeBytes": 399 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "main", + "totalResponseSizeBytes": 403 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 7, + "deltaPreview": " binary", + "totalResponseSizeBytes": 410 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 411 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 10, + "deltaPreview": " installed", + "totalResponseSizeBytes": 421 + } + }, + { + "timestampMs": 1770182509308, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " globally", + "totalResponseSizeBytes": 430 + } + }, + { + "timestampMs": 1770182509309, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": ")\n", + "totalResponseSizeBytes": 432 + } + }, + { + "timestampMs": 1770182509309, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "-", + "totalResponseSizeBytes": 433 + } + }, + { + "timestampMs": 1770182509373, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 8, + "deltaPreview": " Program", + "totalResponseSizeBytes": 441 + } + }, + { + "timestampMs": 1770182509373, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": "matic", + "totalResponseSizeBytes": 446 + } + }, + { + "timestampMs": 1770182509373, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 447 + } + }, + { + "timestampMs": 1770182509373, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 449 + } + }, + { + "timestampMs": 1770182509373, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "src", + "totalResponseSizeBytes": 452 + } + }, + { + "timestampMs": 1770182509374, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 458 + } + }, + { + "timestampMs": 1770182509374, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 461 + } + }, + { + "timestampMs": 1770182509374, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 462 + } + }, + { + "timestampMs": 1770182509374, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " (", + "totalResponseSizeBytes": 464 + } + }, + { + "timestampMs": 1770182509374, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": "calls", + "totalResponseSizeBytes": 469 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 471 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "run", + "totalResponseSizeBytes": 474 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "Cli", + "totalResponseSizeBytes": 477 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "()`", + "totalResponseSizeBytes": 480 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 483 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 485 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "src", + "totalResponseSizeBytes": 488 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 489 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": "cli", + "totalResponseSizeBytes": 492 + } + }, + { + "timestampMs": 1770182511802, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 495 + } + }, + { + "timestampMs": 1770182515040, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 496 + } + }, + { + "timestampMs": 1770182515040, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 3, + "deltaPreview": ")\n\n", + "totalResponseSizeBytes": 499 + } + }, + { + "timestampMs": 1770182515043, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 7, + "deltaPreview": "Primary", + "totalResponseSizeBytes": 506 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 515 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 8, + "deltaPreview": " include", + "totalResponseSizeBytes": 523 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 524 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 526 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "init", + "totalResponseSizeBytes": 530 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 532 + } + }, + { + "timestampMs": 1770182515044, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 534 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "an", + "totalResponseSizeBytes": 536 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": "alyze", + "totalResponseSizeBytes": 541 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 543 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 545 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 8, + "deltaPreview": "generate", + "totalResponseSizeBytes": 553 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 555 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 557 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 12, + "deltaPreview": "instructions", + "totalResponseSizeBytes": 569 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 571 + } + }, + { + "timestampMs": 1770182515108, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 573 + } + }, + { + "timestampMs": 1770182515170, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 1, + "deltaPreview": "t", + "totalResponseSizeBytes": 574 + } + }, + { + "timestampMs": 1770182515170, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "ui", + "totalResponseSizeBytes": 576 + } + }, + { + "timestampMs": 1770182515172, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 578 + } + }, + { + "timestampMs": 1770182515172, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 580 + } + }, + { + "timestampMs": 1770182515172, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "eval", + "totalResponseSizeBytes": 584 + } + }, + { + "timestampMs": 1770182515172, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 586 + } + }, + { + "timestampMs": 1770182515173, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 588 + } + }, + { + "timestampMs": 1770182515173, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": "read", + "totalResponseSizeBytes": 592 + } + }, + { + "timestampMs": 1770182515173, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": "iness", + "totalResponseSizeBytes": 597 + } + }, + { + "timestampMs": 1770182515173, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 599 + } + }, + { + "timestampMs": 1770182515321, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 601 + } + }, + { + "timestampMs": 1770182515321, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "pr", + "totalResponseSizeBytes": 603 + } + }, + { + "timestampMs": 1770182515322, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 605 + } + }, + { + "timestampMs": 1770182515322, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 607 + } + }, + { + "timestampMs": 1770182515323, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 5, + "deltaPreview": "batch", + "totalResponseSizeBytes": 612 + } + }, + { + "timestampMs": 1770182515323, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 614 + } + }, + { + "timestampMs": 1770182515323, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 616 + } + }, + { + "timestampMs": 1770182515323, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 9, + "deltaPreview": "templates", + "totalResponseSizeBytes": 625 + } + }, + { + "timestampMs": 1770182515323, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 627 + } + }, + { + "timestampMs": 1770182515323, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 629 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": "config", + "totalResponseSizeBytes": 635 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`,", + "totalResponseSizeBytes": 637 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 641 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 643 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 6, + "deltaPreview": "update", + "totalResponseSizeBytes": 649 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "deltaChars": 2, + "deltaPreview": "`.", + "totalResponseSizeBytes": 651 + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 10830, + "outputTokens": 155, + "cacheReadTokens": 10368, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 8136, + "initiator": "agent", + "apiCallId": "chatcmpl-D5PchQpqfCG6WGv6mtHggYQqLqUqA", + "providerCallId": "E903:35A03D:342FF2:3DEEEA:6982D76B", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "content": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.", + "toolRequests": [] + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770182515351, + "phase": "withInstructions", + "type": "session.idle", + "data": {} + }, + { + "timestampMs": 1770182515373, + "phase": "judge", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770182515373, + "phase": "judge", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770182516066, + "phase": "judge", + "type": "user.message", + "data": { + "content": "Evaluate which response best matches the expectation.\n\nExpectation: Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\n\nResponse A (without custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.\n\nResponse B (with custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.\n\nReturn JSON only.", + "transformedContent": "2026-02-04T05:21:56.033Z\n\nEvaluate which response best matches the expectation.\n\nExpectation: Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\n\nResponse A (without custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.\n\nResponse B (with custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.\n\nReturn JSON only.", + "attachments": [] + } + }, + { + "timestampMs": 1770182516066, + "phase": "judge", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770182516066, + "phase": "judge", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 10644, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": "{\n", + "totalResponseSizeBytes": 2 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 3 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 5 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": "ver", + "totalResponseSizeBytes": 8 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": "dict", + "totalResponseSizeBytes": 12 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 14 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 16 + } + }, + { + "timestampMs": 1770182516954, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": "pass", + "totalResponseSizeBytes": 20 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": "\",\n", + "totalResponseSizeBytes": 23 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 24 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 26 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": "score", + "totalResponseSizeBytes": 31 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 33 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 34 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": "100", + "totalResponseSizeBytes": 37 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": ",\n", + "totalResponseSizeBytes": 39 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 40 + } + }, + { + "timestampMs": 1770182517128, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 42 + } + }, + { + "timestampMs": 1770182517320, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": "r", + "totalResponseSizeBytes": 43 + } + }, + { + "timestampMs": 1770182517320, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 8, + "deltaPreview": "ationale", + "totalResponseSizeBytes": 51 + } + }, + { + "timestampMs": 1770182517322, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 53 + } + }, + { + "timestampMs": 1770182517322, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 55 + } + }, + { + "timestampMs": 1770182517322, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 8, + "deltaPreview": "Response", + "totalResponseSizeBytes": 63 + } + }, + { + "timestampMs": 1770182517322, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " B", + "totalResponseSizeBytes": 65 + } + }, + { + "timestampMs": 1770182517322, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " best", + "totalResponseSizeBytes": 70 + } + }, + { + "timestampMs": 1770182517322, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 8, + "deltaPreview": " matches", + "totalResponseSizeBytes": 78 + } + }, + { + "timestampMs": 1770182517323, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 82 + } + }, + { + "timestampMs": 1770182517323, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 94 + } + }, + { + "timestampMs": 1770182517396, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " by", + "totalResponseSizeBytes": 97 + } + }, + { + "timestampMs": 1770182517396, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 11, + "deltaPreview": " explicitly", + "totalResponseSizeBytes": 108 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 11, + "deltaPreview": " mentioning", + "totalResponseSizeBytes": 119 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 123 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 127 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 6, + "deltaPreview": " entry", + "totalResponseSizeBytes": 133 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": "point", + "totalResponseSizeBytes": 138 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 141 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 145 + } + }, + { + "timestampMs": 1770182517398, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 151 + } + }, + { + "timestampMs": 1770182517588, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 154 + } + }, + { + "timestampMs": 1770182517588, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 155 + } + }, + { + "timestampMs": 1770182517588, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " clar", + "totalResponseSizeBytes": 160 + } + }, + { + "timestampMs": 1770182517588, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 6, + "deltaPreview": "ifying", + "totalResponseSizeBytes": 166 + } + }, + { + "timestampMs": 1770182517588, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " that", + "totalResponseSizeBytes": 171 + } + }, + { + "timestampMs": 1770182517589, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " it", + "totalResponseSizeBytes": 174 + } + }, + { + "timestampMs": 1770182517589, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 6, + "deltaPreview": " calls", + "totalResponseSizeBytes": 180 + } + }, + { + "timestampMs": 1770182517589, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " run", + "totalResponseSizeBytes": 184 + } + }, + { + "timestampMs": 1770182517589, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": "Cli", + "totalResponseSizeBytes": 187 + } + }, + { + "timestampMs": 1770182517589, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 190 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 194 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 195 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": "cli", + "totalResponseSizeBytes": 198 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 201 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 202 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 206 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 12, + "deltaPreview": " identifying", + "totalResponseSizeBytes": 218 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " this", + "totalResponseSizeBytes": 223 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " as", + "totalResponseSizeBytes": 226 + } + }, + { + "timestampMs": 1770182517772, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 230 + } + }, + { + "timestampMs": 1770182517946, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 237 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 241 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 242 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " It", + "totalResponseSizeBytes": 245 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " also", + "totalResponseSizeBytes": 250 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 9, + "deltaPreview": " provides", + "totalResponseSizeBytes": 259 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 261 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " more", + "totalResponseSizeBytes": 266 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 9, + "deltaPreview": " complete", + "totalResponseSizeBytes": 275 + } + }, + { + "timestampMs": 1770182517947, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 279 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 9, + "deltaPreview": " accurate", + "totalResponseSizeBytes": 288 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " list", + "totalResponseSizeBytes": 293 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": " of", + "totalResponseSizeBytes": 296 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 305 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 309 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 9, + "deltaPreview": " features", + "totalResponseSizeBytes": 318 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 319 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 9, + "deltaPreview": " aligning", + "totalResponseSizeBytes": 328 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 8, + "deltaPreview": " closely", + "totalResponseSizeBytes": 336 + } + }, + { + "timestampMs": 1770182518109, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 341 + } + }, + { + "timestampMs": 1770182518143, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 345 + } + }, + { + "timestampMs": 1770182518143, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 357 + } + }, + { + "timestampMs": 1770182518144, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 3, + "deltaPreview": ".\"\n", + "totalResponseSizeBytes": 360 + } + }, + { + "timestampMs": 1770182518144, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "deltaChars": 1, + "deltaPreview": "}", + "totalResponseSizeBytes": 361 + } + }, + { + "timestampMs": 1770182518144, + "phase": "judge", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 10011, + "outputTokens": 84, + "cacheReadTokens": 9088, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 2076, + "initiator": "user", + "apiCallId": "chatcmpl-D5PcqfwwPo46O2E5lE3WeAmcIK1Zi", + "providerCallId": "E903:35A03D:344C2A:3E0F67:6982D774", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770182518144, + "phase": "judge", + "type": "assistant.message", + "data": { + "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "content": "{\n \"verdict\": \"pass\",\n \"score\": 100,\n \"rationale\": \"Response B best matches the expectation by explicitly mentioning the CLI entrypoint in src/index.ts, clarifying that it calls runCli in src/cli.ts, and identifying this as the Primer CLI. It also provides a more complete and accurate list of commands and features, aligning closely with the expectation.\"\n}", + "toolRequests": [] + } + }, + { + "timestampMs": 1770182518144, + "phase": "judge", + "type": "assistant.turn_end", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770182518144, + "phase": "judge", + "type": "session.idle", + "data": {} + } + ] } ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4679573..bd529fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,12 +19,25 @@ "react": "^19.2.4", "simple-git": "^3.30.0" }, + "bin": { + "primer": "dist/index.js" + }, "devDependencies": { "@types/node": "^25.1.0", "@types/react": "^19.2.10", + "@typescript-eslint/eslint-plugin": "^8.5.0", + "@typescript-eslint/parser": "^8.5.0", + "@vitest/coverage-v8": "^2.1.4", + "eslint": "^9.7.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.30.0", + "eslint-plugin-n": "^17.10.2", + "eslint-plugin-promise": "^7.1.0", + "prettier": "^3.3.3", "tsup": "^8.5.1", "tsx": "^4.21.0", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "vitest": "^2.1.4" } }, "node_modules/@alcalzone/ansi-tokenize": { @@ -40,6 +53,77 @@ "node": ">=18" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -482,6 +566,195 @@ "node": ">=18" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@github/copilot": { "version": "0.0.394", "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-0.0.394.tgz", @@ -609,6 +882,58 @@ "copilot-win32-x64": "copilot.exe" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@inquirer/ansi": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.3.tgz", @@ -937,6 +1262,77 @@ } } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1180,6 +1576,17 @@ "@octokit/openapi-types": "^27.0.0" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.57.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.0.tgz", @@ -1530,6 +1937,13 @@ "win32" ] }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1537,6 +1951,20 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz", @@ -1557,1446 +1985,5914 @@ "csstype": "^3.2.2" } }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", + "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/type-utils": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": ">=0.4.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.54.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/ansi-escapes": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", - "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "node_modules/@typescript-eslint/parser": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", + "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", + "dev": true, "license": "MIT", "dependencies": { - "environment": "^1.0.0" + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3" }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", + "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.54.0", + "@typescript-eslint/types": "^8.54.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", + "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", + "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0" + }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", + "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", "dev": true, - "license": "MIT" - }, - "node_modules/auto-bind": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", - "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", - "license": "Apache-2.0" - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/bundle-require": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", - "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", + "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", "dev": true, "license": "MIT", "dependencies": { - "load-tsconfig": "^0.2.3" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "esbuild": ">=0.18" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/@typescript-eslint/types": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", + "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/chardet": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", - "license": "MIT" - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", + "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", "dev": true, "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "@typescript-eslint/project-service": "8.54.0", + "@typescript-eslint/tsconfig-utils": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": ">= 14.16.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://paulmillr.com/funding/" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "node_modules/@typescript-eslint/utils": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", + "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", + "dev": true, "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", + "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", + "dev": true, "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "@typescript-eslint/types": "8.54.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cli-truncate": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", - "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", - "license": "MIT", - "dependencies": { - "slice-ansi": "^7.1.0", - "string-width": "^8.0.0" - }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=20" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "node_modules/@vitest/coverage-v8": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.9.tgz", + "integrity": "sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==", + "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=20" + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.7", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.12", + "magicast": "^0.3.5", + "std-env": "^3.8.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "license": "ISC", - "engines": { - "node": ">= 12" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "2.1.9", + "vitest": "2.1.9" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } } }, - "node_modules/code-excerpt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", - "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, "license": "MIT", "dependencies": { - "convert-to-spaces": "^2.0.1" + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/commander": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", - "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=20" + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", "dev": true, "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/convert-to-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", - "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, + "node_modules/@vitest/runner/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, "license": "MIT" }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "node_modules/@vitest/snapshot/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, "license": "MIT" }, - "node_modules/environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "tinyspy": "^3.0.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/es-toolkit": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.44.0.tgz", - "integrity": "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==", - "license": "MIT", - "workspaces": [ - "docs", - "benchmarks" - ] - }, - "node_modules/esbuild": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", - "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.2", - "@esbuild/android-arm": "0.27.2", - "@esbuild/android-arm64": "0.27.2", - "@esbuild/android-x64": "0.27.2", - "@esbuild/darwin-arm64": "0.27.2", - "@esbuild/darwin-x64": "0.27.2", - "@esbuild/freebsd-arm64": "0.27.2", - "@esbuild/freebsd-x64": "0.27.2", - "@esbuild/linux-arm": "0.27.2", - "@esbuild/linux-arm64": "0.27.2", - "@esbuild/linux-ia32": "0.27.2", - "@esbuild/linux-loong64": "0.27.2", - "@esbuild/linux-mips64el": "0.27.2", - "@esbuild/linux-ppc64": "0.27.2", - "@esbuild/linux-riscv64": "0.27.2", - "@esbuild/linux-s390x": "0.27.2", - "@esbuild/linux-x64": "0.27.2", - "@esbuild/netbsd-arm64": "0.27.2", - "@esbuild/netbsd-x64": "0.27.2", - "@esbuild/openbsd-arm64": "0.27.2", - "@esbuild/openbsd-x64": "0.27.2", - "@esbuild/openharmony-arm64": "0.27.2", - "@esbuild/sunos-x64": "0.27.2", - "@esbuild/win32-arm64": "0.27.2", - "@esbuild/win32-ia32": "0.27.2", - "@esbuild/win32-x64": "0.27.2" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/fast-content-type-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", - "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT" + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=8.6.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "license": "ISC", + "node_modules/ansi-escapes": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", + "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "license": "MIT", "dependencies": { - "reusify": "^1.0.4" + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" + "node": ">=12" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/fix-dts-default-cjs-exports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", - "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "magic-string": "^0.30.17", - "mlly": "^1.7.4", - "rollup": "^4.34.8" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "license": "MIT", "dependencies": { - "resolve-pkg-maps": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "license": "ISC", + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/auto-bind": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", + "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ink": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/ink/-/ink-6.6.0.tgz", - "integrity": "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", "dependencies": { - "@alcalzone/ansi-tokenize": "^0.2.1", - "ansi-escapes": "^7.2.0", - "ansi-styles": "^6.2.1", - "auto-bind": "^5.0.1", - "chalk": "^5.6.0", - "cli-boxes": "^3.0.0", - "cli-cursor": "^4.0.0", - "cli-truncate": "^5.1.1", - "code-excerpt": "^4.0.0", - "es-toolkit": "^1.39.10", - "indent-string": "^5.0.0", - "is-in-ci": "^2.0.0", - "patch-console": "^2.0.0", - "react-reconciler": "^0.33.0", - "signal-exit": "^3.0.7", - "slice-ansi": "^7.1.0", - "stack-utils": "^2.0.6", - "string-width": "^8.1.0", - "type-fest": "^4.27.0", - "widest-line": "^5.0.0", - "wrap-ansi": "^9.0.0", - "ws": "^8.18.0", - "yoga-layout": "~3.2.1" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">=20" + "node": ">= 0.4" }, - "peerDependencies": { - "@types/react": ">=19.0.0", - "react": ">=19.0.0", - "react-devtools-core": "^6.1.2" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react-devtools-core": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ink/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" }, - "node_modules/ink/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "node_modules/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "license": "Apache-2.0" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.3.0", - "strip-ansi": "^7.1.0" + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" }, "engines": { - "node": ">=20" + "node": ">=8" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.3.1" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/is-in-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", - "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, "license": "MIT", - "bin": { - "is-in-ci": "cli.js" + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { - "node": ">=20" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">=6" } }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", "engines": { - "node": ">=14" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/antonk52" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", "license": "MIT" }, - "node_modules/load-tsconfig": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", - "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 16" } }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "license": "MIT", "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=8.6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, "engines": { - "node": ">=8.6" + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=6" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mlly": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", - "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "license": "MIT", + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.15.0", - "pathe": "^2.0.3", - "pkg-types": "^1.3.1", - "ufo": "^1.6.1" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, "license": "MIT" }, - "node_modules/mute-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", - "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", - "license": "ISC", + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "license": "MIT", "engines": { - "node": "^20.17.0 || >=22.9.0" + "node": ">=20" } }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } + "license": "MIT" }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "^14.18.0 || >=16.10.0" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/patch-console": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", - "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 8" } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "devOptional": true, "license": "MIT" }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss-load-config": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", - "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "lilconfig": "^3.1.1" + "ms": "^2.1.3" }, "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "jiti": ">=1.21.0", - "postcss": ">=8.0.9", - "tsx": "^4.8.1", - "yaml": "^2.4.2" + "node": ">=6.0" }, "peerDependenciesMeta": { - "jiti": { - "optional": true - }, - "postcss": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { + "supports-color": { "optional": true } } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/react-reconciler": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", - "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { - "scheduler": "^0.27.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" }, - "peerDependencies": { - "react": "^19.2.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, "engines": { - "node": ">= 14.18.0" + "node": ">= 0.4" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" }, - "node_modules/rollup": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.0.tgz", - "integrity": "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==", + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.57.0", - "@rollup/rollup-android-arm64": "4.57.0", - "@rollup/rollup-darwin-arm64": "4.57.0", - "@rollup/rollup-darwin-x64": "4.57.0", - "@rollup/rollup-freebsd-arm64": "4.57.0", - "@rollup/rollup-freebsd-x64": "4.57.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", - "@rollup/rollup-linux-arm-musleabihf": "4.57.0", - "@rollup/rollup-linux-arm64-gnu": "4.57.0", - "@rollup/rollup-linux-arm64-musl": "4.57.0", - "@rollup/rollup-linux-loong64-gnu": "4.57.0", - "@rollup/rollup-linux-loong64-musl": "4.57.0", - "@rollup/rollup-linux-ppc64-gnu": "4.57.0", - "@rollup/rollup-linux-ppc64-musl": "4.57.0", - "@rollup/rollup-linux-riscv64-gnu": "4.57.0", - "@rollup/rollup-linux-riscv64-musl": "4.57.0", - "@rollup/rollup-linux-s390x-gnu": "4.57.0", - "@rollup/rollup-linux-x64-gnu": "4.57.0", - "@rollup/rollup-linux-x64-musl": "4.57.0", - "@rollup/rollup-openbsd-x64": "4.57.0", - "@rollup/rollup-openharmony-arm64": "4.57.0", - "@rollup/rollup-win32-arm64-msvc": "4.57.0", - "@rollup/rollup-win32-ia32-msvc": "4.57.0", - "@rollup/rollup-win32-x64-gnu": "4.57.0", - "@rollup/rollup-win32-x64-msvc": "4.57.0", - "fsevents": "~2.3.2" + "node": ">=10.13.0" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", "engines": { - "node": ">=14" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/simple-git": { - "version": "3.30.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.30.0.tgz", - "integrity": "sha512-q6lxyDsCmEal/MEGhP1aVyQ3oxnagGlBDOVSIB4XUVLl1iZh0Pah6ebC9V4xBap/RfgP2WlI8EKs0WS0rMEJHg==", + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, "license": "MIT", "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.4.0" + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">= 0.4" } }, - "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "engines": { - "node": ">= 12" + "node": ">= 0.4" } }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, "license": "MIT", "dependencies": { - "escape-string-regexp": "^2.0.0" + "es-errors": "^1.3.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" } }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": ">=18" + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.4" } }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sucrase": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", - "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "node_modules/es-toolkit": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.44.0.tgz", + "integrity": "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "tinyglobby": "^0.2.11", - "ts-interface-checker": "^0.1.9" - }, "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, - "node_modules/sucrase/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", "dependencies": { - "any-promise": "^1.0.0" + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, "license": "MIT", "dependencies": { - "thenify": ">= 3.1.0 < 4" + "semver": "^7.5.4" }, "engines": { - "node": ">=0.8" + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "node_modules/eslint-config-prettier": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.2.tgz", + "integrity": "sha512-iI1f+D2ViGn+uvv5HuHVUamg8ll4tN+JRHGc6IJi4TP9Kl976C57fzPXgseXNs8v0iA8aSJpHsTWjDb9QJamGQ==", "dev": true, - "license": "MIT" - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-n": { + "version": "17.23.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.2.tgz", + "integrity": "sha512-RhWBeb7YVPmNa2eggvJooiuehdL76/bbfj/OJewyoGT80qn5PXdz8zMOTO6YHOsI7byPt7+Ighh/i/4a5/v7hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz", + "integrity": "sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", + "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-6.6.0.tgz", + "integrity": "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ==", + "license": "MIT", + "dependencies": { + "@alcalzone/ansi-tokenize": "^0.2.1", + "ansi-escapes": "^7.2.0", + "ansi-styles": "^6.2.1", + "auto-bind": "^5.0.1", + "chalk": "^5.6.0", + "cli-boxes": "^3.0.0", + "cli-cursor": "^4.0.0", + "cli-truncate": "^5.1.1", + "code-excerpt": "^4.0.0", + "es-toolkit": "^1.39.10", + "indent-string": "^5.0.0", + "is-in-ci": "^2.0.0", + "patch-console": "^2.0.0", + "react-reconciler": "^0.33.0", + "signal-exit": "^3.0.7", + "slice-ansi": "^7.1.0", + "stack-utils": "^2.0.6", + "string-width": "^8.1.0", + "type-fest": "^4.27.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0", + "ws": "^8.18.0", + "yoga-layout": "~3.2.1" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@types/react": ">=19.0.0", + "react": ">=19.0.0", + "react-devtools-core": "^6.1.2" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-devtools-core": { + "optional": true + } + } + }, + "node_modules/ink/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/ink/node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-in-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz", + "integrity": "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w==", + "license": "MIT", + "bin": { + "is-in-ci": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-console": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", + "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-reconciler": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.33.0.tgz", + "integrity": "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.0.tgz", + "integrity": "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.57.0", + "@rollup/rollup-android-arm64": "4.57.0", + "@rollup/rollup-darwin-arm64": "4.57.0", + "@rollup/rollup-darwin-x64": "4.57.0", + "@rollup/rollup-freebsd-arm64": "4.57.0", + "@rollup/rollup-freebsd-x64": "4.57.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", + "@rollup/rollup-linux-arm-musleabihf": "4.57.0", + "@rollup/rollup-linux-arm64-gnu": "4.57.0", + "@rollup/rollup-linux-arm64-musl": "4.57.0", + "@rollup/rollup-linux-loong64-gnu": "4.57.0", + "@rollup/rollup-linux-loong64-musl": "4.57.0", + "@rollup/rollup-linux-ppc64-gnu": "4.57.0", + "@rollup/rollup-linux-ppc64-musl": "4.57.0", + "@rollup/rollup-linux-riscv64-gnu": "4.57.0", + "@rollup/rollup-linux-riscv64-musl": "4.57.0", + "@rollup/rollup-linux-s390x-gnu": "4.57.0", + "@rollup/rollup-linux-x64-gnu": "4.57.0", + "@rollup/rollup-linux-x64-musl": "4.57.0", + "@rollup/rollup-openbsd-x64": "4.57.0", + "@rollup/rollup-openharmony-arm64": "4.57.0", + "@rollup/rollup-win32-arm64-msvc": "4.57.0", + "@rollup/rollup-win32-ia32-msvc": "4.57.0", + "@rollup/rollup-win32-x64-gnu": "4.57.0", + "@rollup/rollup-win32-x64-msvc": "4.57.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-git": { + "version": "3.30.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.30.0.tgz", + "integrity": "sha512-q6lxyDsCmEal/MEGhP1aVyQ3oxnagGlBDOVSIB4XUVLl1iZh0Pah6ebC9V4xBap/RfgP2WlI8EKs0WS0rMEJHg==", + "license": "MIT", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, + "node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/test-exclude": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-declaration-location": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "license": "ISC" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=8.0" + "node": ">=12" } }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "bin": { - "tree-kill": "cli.js" + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, - "license": "Apache-2.0" - }, - "node_modules/tsup": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", - "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", "dev": true, "license": "MIT", "dependencies": { - "bundle-require": "^5.1.0", - "cac": "^6.7.14", - "chokidar": "^4.0.3", - "consola": "^3.4.0", - "debug": "^4.4.0", - "esbuild": "^0.27.0", - "fix-dts-default-cjs-exports": "^1.0.0", - "joycon": "^3.1.1", - "picocolors": "^1.1.1", - "postcss-load-config": "^6.0.1", - "resolve-from": "^5.0.0", - "rollup": "^4.34.8", - "source-map": "^0.7.6", - "sucrase": "^3.35.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.11", - "tree-kill": "^1.2.2" + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" }, "bin": { - "tsup": "dist/cli-default.js", - "tsup-node": "dist/cli-node.js" + "vitest": "vitest.mjs" }, "engines": { - "node": ">=18" + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@microsoft/api-extractor": "^7.36.0", - "@swc/core": "^1", - "postcss": "^8.4.12", - "typescript": ">=4.5.0" + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" }, "peerDependenciesMeta": { - "@microsoft/api-extractor": { + "@edge-runtime/vm": { "optional": true }, - "@swc/core": { + "@types/node": { "optional": true }, - "postcss": { + "@vitest/browser": { "optional": true }, - "typescript": { + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { "optional": true } } }, - "node_modules/tsx": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", - "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "node_modules/vitest/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true, + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", + "integrity": "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==", "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", "dependencies": { - "esbuild": "~0.27.0", - "get-tsconfig": "^4.7.5" + "isexe": "^2.0.0" }, "bin": { - "tsx": "dist/cli.mjs" + "node-which": "bin/node-which" }, "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "node": ">= 8" } }, - "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "license": "(MIT OR CC0-1.0)", + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, "engines": { - "node": ">=16" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" }, - "engines": { - "node": ">=14.17" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ufo": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", - "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, - "license": "MIT" - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "devOptional": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/universal-user-agent": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", - "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", - "license": "ISC" + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/vscode-jsonrpc": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", - "integrity": "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, "engines": { - "node": ">=14.0.0" + "node": ">=8" } }, "node_modules/widest-line": { @@ -3014,6 +7910,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", @@ -3031,6 +7937,96 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ws": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", @@ -3052,6 +8048,19 @@ } } }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yoga-layout": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz", diff --git a/src/services/evaluator.ts b/src/services/evaluator.ts index adddce6..9437a72 100644 --- a/src/services/evaluator.ts +++ b/src/services/evaluator.ts @@ -466,9 +466,13 @@ function findLatestToolByName( function extractTokenUsage(data: Record | undefined): TokenUsage | null { if (!data) return null; - const usage = (data.usage ?? data.tokenUsage ?? data.tokens) as Record | undefined; - const promptTokens = getNumber(usage?.prompt_tokens ?? usage?.promptTokens ?? data.promptTokens ?? data.inputTokens); - const completionTokens = getNumber(usage?.completion_tokens ?? usage?.completionTokens ?? data.completionTokens ?? data.outputTokens); + const usage = findUsageObject(data); + const promptTokens = getNumber( + usage?.prompt_tokens ?? usage?.promptTokens ?? data.promptTokens ?? data.inputTokens + ); + const completionTokens = getNumber( + usage?.completion_tokens ?? usage?.completionTokens ?? data.completionTokens ?? data.outputTokens + ); const totalTokens = getNumber(usage?.total_tokens ?? usage?.totalTokens ?? data.totalTokens); if (promptTokens == null && completionTokens == null && totalTokens == null) { @@ -482,6 +486,63 @@ function extractTokenUsage(data: Record | undefined): TokenUsag }; } +function findUsageObject(data: Record): Record | undefined { + const direct = (data.usage ?? data.tokenUsage ?? data.tokens) as Record | undefined; + if (direct) return direct; + + const candidates = [ + data.response, + data.result, + data.message, + data.metrics, + data.output + ]; + + for (const candidate of candidates) { + if (candidate && typeof candidate === "object") { + const nested = (candidate as Record).usage ?? (candidate as Record).tokenUsage; + if (nested && typeof nested === "object") return nested as Record; + } + } + + return scanForUsage(data, 0); +} + +function scanForUsage(value: unknown, depth: number): Record | undefined { + if (!value || typeof value !== "object" || depth > 4) return undefined; + if (Array.isArray(value)) { + for (const entry of value) { + const found = scanForUsage(entry, depth + 1); + if (found) return found; + } + return undefined; + } + + const record = value as Record; + if (hasTokenFields(record)) return record; + + for (const entry of Object.values(record)) { + const found = scanForUsage(entry, depth + 1); + if (found) return found; + } + + return undefined; +} + +function hasTokenFields(record: Record): boolean { + const keys = Object.keys(record); + return ( + keys.includes("prompt_tokens") || + keys.includes("completion_tokens") || + keys.includes("total_tokens") || + keys.includes("promptTokens") || + keys.includes("completionTokens") || + keys.includes("totalTokens") || + keys.includes("inputTokens") || + keys.includes("outputTokens") + ); +} + function getNumber(value: unknown): number | null { if (typeof value === "number" && Number.isFinite(value)) return value; if (typeof value === "string" && value.trim()) { @@ -501,6 +562,15 @@ function mergeTokenUsage(existing: TokenUsage, next: TokenUsage): TokenUsage { function normalizeTokenUsage(usage: TokenUsage): TokenUsage | undefined { if (!usage.promptTokens && !usage.completionTokens && !usage.totalTokens) return undefined; + if (!usage.totalTokens) { + const prompt = usage.promptTokens ?? 0; + const completion = usage.completionTokens ?? 0; + const total = prompt + completion; + return { + ...usage, + totalTokens: total || undefined + }; + } return usage; } @@ -593,16 +663,22 @@ function buildTrajectoryViewerHtml(data: Record): string { .replace(/'/g, '''); const results = data.results || []; - summaryEl.textContent = `Repo: ${data.repoPath || 'unknown'} • Model: ${data.model || 'unknown'} • Judge: ${data.judgeModel || 'unknown'}`; + summaryEl.textContent = + 'Repo: ' + + (data.repoPath || 'unknown') + + ' • Model: ' + + (data.model || 'unknown') + + ' • Judge: ' + + (data.judgeModel || 'unknown'); function renderCaseList(activeId) { caseListEl.innerHTML = ''; results.forEach((result) => { const row = document.createElement('div'); - row.className = `case ${result.id === activeId ? 'active' : ''}`; - row.textContent = `${result.id} (${result.verdict ?? 'unknown'})`; + row.className = 'case ' + (result.id === activeId ? 'active' : ''); + row.textContent = result.id + ' (' + (result.verdict ?? 'unknown') + ')'; const sub = document.createElement('span'); - sub.textContent = `Score: ${result.score ?? 0}`; + sub.textContent = 'Score: ' + (result.score ?? 0); row.appendChild(sub); row.addEventListener('click', () => renderCaseDetails(result.id)); caseListEl.appendChild(row); @@ -611,29 +687,65 @@ function buildTrajectoryViewerHtml(data: Record): string { function renderMetrics(metrics) { if (!metrics) return '

No metrics available.

'; - const fmt = (m) => `Duration: ${m.durationMs}ms • Tokens: ${(m.tokenUsage && (m.tokenUsage.totalTokens ?? 'n/a')) || 'n/a'} • Tool calls: ${m.toolCalls?.count ?? 0}`; - return ` -
-
Without Instructions
${fmt(metrics.withoutInstructions)}
-
With Instructions
${fmt(metrics.withInstructions)}
-
Judge
${fmt(metrics.judge)}
-
Total
${metrics.totalDurationMs}ms -
- `; + const fmt = (m) => { + const usage = m.tokenUsage; + const prompt = usage?.promptTokens ?? 'n/a'; + const completion = usage?.completionTokens ?? 'n/a'; + const total = usage?.totalTokens ?? (usage ? (Number(usage.promptTokens ?? 0) + Number(usage.completionTokens ?? 0)) : 'n/a'); + return ( + 'Duration: ' + + m.durationMs + + 'ms • Tokens: ' + + prompt + + ' / ' + + completion + + ' / ' + + total + + ' • Tool calls: ' + + (m.toolCalls?.count ?? 0) + ); + }; + return ( + '
' + + '
Without Instructions
' + + fmt(metrics.withoutInstructions) + + '
' + + '
With Instructions
' + + fmt(metrics.withInstructions) + + '
' + + '
Judge
' + + fmt(metrics.judge) + + '
' + + '
Total
' + + metrics.totalDurationMs + + 'ms' + + '
' + ); } function renderTrajectory(events) { if (!events || !events.length) return '

No trajectory events captured.

'; - return ` -
- ${events.map((event) => ` -
-
${event.type} ${event.phase} ${new Date(event.timestampMs).toISOString()}
-
${JSON.stringify(event.data ?? {}, null, 2)}
-
- `).join('')} -
- `; + return ( + '
' + + events + .map( + (event) => + '
' + + '
' + + event.type + + ' ' + + event.phase + + ' ' + + new Date(event.timestampMs).toISOString() + + '
' + + '
' +
+                JSON.stringify(event.data ?? {}, null, 2) +
+                '
' + + '
' + ) + .join('') + + '
' + ); } function renderCaseDetails(caseId) { @@ -643,16 +755,25 @@ function buildTrajectoryViewerHtml(data: Record): string { return; } renderCaseList(result.id); - caseDetailsEl.innerHTML = ` -

${escapeHtml(result.id)}

-

Verdict: ${escapeHtml(result.verdict ?? 'unknown')} (score: ${escapeHtml(result.score ?? 0)})

-

Prompt: ${escapeHtml(result.prompt ?? '')}

-

Expectation: ${escapeHtml(result.expectation ?? '')}

-

Metrics

- ${renderMetrics(result.metrics)} -

Trajectory

- ${renderTrajectory(result.trajectory)} - `; + caseDetailsEl.innerHTML = + '

' + + escapeHtml(result.id) + + '

' + + '

Verdict: ' + + escapeHtml(result.verdict ?? 'unknown') + + ' (score: ' + + escapeHtml(result.score ?? 0) + + ')

' + + '

Prompt: ' + + escapeHtml(result.prompt ?? '') + + '

' + + '

Expectation: ' + + escapeHtml(result.expectation ?? '') + + '

' + + '

Metrics

' + + renderMetrics(result.metrics) + + '

Trajectory

' + + renderTrajectory(result.trajectory); } renderCaseDetails(results[0]?.id); diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index 7991865..23f02b2 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -263,6 +263,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX if (input.toLowerCase() === "e") { const configPath = path.join(repoPath, "primer.eval.json"); + const outputPath = path.join(repoPath, "eval-results.json"); try { await fs.access(configPath); } catch { @@ -281,6 +282,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX repoPath, model: "gpt-4.1", judgeModel: "gpt-4.1", + outputPath, // Note: onProgress removed - causes issues with SDK in React/Ink context }); setEvalResults(results); @@ -303,7 +305,16 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } }); - const statusLabel = status === "intro" ? "..." : status === "idle" ? "ready (awaiting input)" : status; + const statusLabel = status === "intro" ? "starting" : status === "idle" ? "ready" : status; + const statusColor = status === "error" ? "red" : status === "done" ? "green" : "yellow"; + const formatTokens = (result: EvalResult): string => { + const withUsage = result.metrics?.withInstructions?.tokenUsage; + const withoutUsage = result.metrics?.withoutInstructions?.tokenUsage; + const withTotal = withUsage?.totalTokens ?? (withUsage ? (withUsage.promptTokens ?? 0) + (withUsage.completionTokens ?? 0) : undefined); + const withoutTotal = withoutUsage?.totalTokens ?? (withoutUsage ? (withoutUsage.promptTokens ?? 0) + (withoutUsage.completionTokens ?? 0) : undefined); + if (withTotal == null && withoutTotal == null) return "tokens n/a"; + return `tokens w/: ${withTotal ?? "n/a"} • w/o: ${withoutTotal ?? "n/a"}`; + }; // Truncate preview to fit terminal const previewLines = generatedContent.split("\n").slice(0, 20); @@ -315,26 +326,41 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } return ( - + {status === "intro" ? ( ) : ( )} - Prime your repo for AI. + + Prime your repo for AI + ● {statusLabel} + Repo: {repoLabel} - - Status: {statusLabel} - {analysis && ( - + + + + Repository signals + + {analysis ? ( + Languages: {analysis.languages.join(", ") || "unknown"} Frameworks: {analysis.frameworks.join(", ") || "none"} Package manager: {analysis.packageManager ?? "unknown"} + {analysis.isMonorepo && ( + Monorepo: yes ({analysis.apps?.length ?? 0} apps) + )} + ) : ( + Run analysis to populate repo signals. )} - - {message} + + + + Activity + + {message || "Awaiting input."} {status === "bootstrapEvalCount" && ( @@ -352,7 +378,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX Eval Results: {evalResults.map((r) => ( - {r.verdict === "pass" ? "✓" : r.verdict === "fail" ? "✗" : "?"} {r.id}: {r.verdict} (score: {r.score}) + {r.verdict === "pass" ? "✓" : r.verdict === "fail" ? "✗" : "?"} {r.id}: {r.verdict} (score: {r.score}) • {formatTokens(r)} ))} {evalViewerPath && ( From 4019d4e7cc08629a22fa204173317a9f42c60abe Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Tue, 3 Feb 2026 22:29:57 -0700 Subject: [PATCH 03/19] Enhance Copilot integration and evaluation features with new scaffolding and CLI options --- .github/copilot-instructions.md | 11 ++- primer.eval.json | 16 +++- src/cli.ts | 1 + src/commands/eval.ts | 31 +++----- src/services/copilot.ts | 45 ++++++++++++ src/services/evalScaffold.ts | 125 ++++++++++++++++++++++++++++++++ src/services/evaluator.ts | 84 ++++++++++++++++++++- src/services/instructions.ts | 50 +------------ src/ui/tui.tsx | 100 +++++++++---------------- 9 files changed, 319 insertions(+), 144 deletions(-) create mode 100644 src/services/copilot.ts create mode 100644 src/services/evalScaffold.ts diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 968515a..2bdc7ef 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,4 +1,13 @@ -# Copilot Instructions for Primer +# Copilot Instructions for This Repository + +- Use ESM syntax everywhere (see "type": "module" in package.json). +- TypeScript is strict; target ES2022, module ESNext (see tsconfig.json). +- Use Commander for CLI, Ink/React for TUI, and simple-git/Octokit for GitHub automation. +- Only overwrite config files (e.g., .vscode/settings.json, .vscode/mcp.json) with --force. +- All Copilot/VS Code settings reference this file and enable MCP. +- Place new CLI commands in src/commands/, core logic in src/services/, and TUI in src/ui/. +- Do not add new build/lint/test tools unless necessary; use existing npm scripts. + ## Overview diff --git a/primer.eval.json b/primer.eval.json index bc1fa99..bc8bd6a 100644 --- a/primer.eval.json +++ b/primer.eval.json @@ -2,9 +2,19 @@ "instructionFile": ".github/copilot-instructions.md", "cases": [ { - "id": "overview", - "prompt": "Summarize what this application does and list the main entrypoints.", - "expectation": "Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI." + "id": "case-1", + "prompt": "What is the main purpose of the Primer CLI tool and what are its key features?", + "expectation": "Primer is a CLI tool that analyzes codebases and generates .github/copilot-instructions.md files to help AI coding assistants understand projects better. Key features include repository analysis, AI-powered instruction generation, batch processing, an evaluation framework, readiness reports, GitHub integration, an interactive TUI, and config generation." + }, + { + "id": "case-2", + "prompt": "How do you run the Primer CLI locally to analyze a repository and generate VS Code settings?", + "expectation": "To analyze a repository, run `npx tsx src/index.ts analyze [path] --json`. To generate VS Code settings, run `npx tsx src/index.ts generate vscode [path] [--force]`." + }, + { + "id": "case-3", + "prompt": "Where should new CLI commands and core logic be placed in the Primer codebase, and what architectural patterns are followed?", + "expectation": "New CLI commands should be placed in src/commands/, and core logic in src/services/. The architecture uses Commander for CLI, Ink/React for TUI, and simple-git/Octokit for GitHub automation, following strict ESM TypeScript conventions." } ] } \ No newline at end of file diff --git a/src/cli.ts b/src/cli.ts index 3a667c1..4382f71 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -57,6 +57,7 @@ export function runCli(argv: string[]): void { .option("--judge-model ", "Model for judging", "gpt-5") .option("--output ", "Write results JSON to file") .option("--init", "Create a starter primer.eval.json file") + .option("--count ", "Number of eval cases to generate (with --init)") .action(evalCommand); program diff --git a/src/commands/eval.ts b/src/commands/eval.ts index bee399d..c592b1a 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -1,6 +1,7 @@ import path from "path"; import fs from "fs/promises"; import { runEval } from "../services/evaluator"; +import { generateEvalScaffold } from "../services/evalScaffold"; type EvalOptions = { repo?: string; @@ -8,27 +9,7 @@ type EvalOptions = { judgeModel?: string; output?: string; init?: boolean; -}; - -const EVAL_SCAFFOLD = { - instructionFile: ".github/copilot-instructions.md", - cases: [ - { - id: "project-overview", - prompt: "Summarize what this project does and list the main entry points.", - expectation: "Should mention the primary purpose and key files/directories." - }, - { - id: "tech-stack", - prompt: "What languages and frameworks does this project use?", - expectation: "Should correctly identify the main languages and frameworks." - }, - { - id: "build-commands", - prompt: "How do I build and test this project?", - expectation: "Should provide the correct build and test commands from package.json or equivalent." - } - ] + count?: string; }; export async function evalCommand(configPathArg: string | undefined, options: EvalOptions): Promise { @@ -37,6 +18,7 @@ export async function evalCommand(configPathArg: string | undefined, options: Ev // Handle --init flag if (options.init) { const outputPath = path.join(repoPath, "primer.eval.json"); + const desiredCount = Math.max(1, Number.parseInt(options.count ?? "5", 10) || 5); try { await fs.access(outputPath); console.error(`primer.eval.json already exists at ${outputPath}`); @@ -45,7 +27,12 @@ export async function evalCommand(configPathArg: string | undefined, options: Ev } catch { // File doesn't exist, create it } - await fs.writeFile(outputPath, JSON.stringify(EVAL_SCAFFOLD, null, 2), "utf8"); + const scaffold = await generateEvalScaffold({ + repoPath, + count: desiredCount, + model: options.model + }); + await fs.writeFile(outputPath, JSON.stringify(scaffold, null, 2), "utf8"); console.log(`Created ${outputPath}`); console.log("Edit the file to add your own test cases, then run 'primer eval' to test."); return; diff --git a/src/services/copilot.ts b/src/services/copilot.ts new file mode 100644 index 0000000..0cec90a --- /dev/null +++ b/src/services/copilot.ts @@ -0,0 +1,45 @@ +import fs from "fs/promises"; +import { execFile } from "node:child_process"; +import { promisify } from "node:util"; + +const execFileAsync = promisify(execFile); + +export async function assertCopilotCliReady(): Promise { + const cliPath = await findCopilotCliPath(); + + try { + await execFileAsync(cliPath, ["--version"], { timeout: 5000 }); + } catch { + throw new Error(`Copilot CLI at ${cliPath} is not working.`); + } + + return cliPath; +} + +async function findCopilotCliPath(): Promise { + try { + const { stdout } = await execFileAsync("which", ["copilot"], { timeout: 5000 }); + return stdout.trim(); + } catch { + // Ignore - will try VS Code location + } + + const home = process.env.HOME ?? ""; + const vscodeLocations = [ + `${home}/Library/Application Support/Code - Insiders/User/globalStorage/github.copilot-chat/copilotCli/copilot`, + `${home}/Library/Application Support/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot`, + `${home}/.vscode-insiders/extensions/github.copilot-chat-*/copilotCli/copilot`, + `${home}/.vscode/extensions/github.copilot-chat-*/copilotCli/copilot` + ]; + + for (const location of vscodeLocations) { + try { + await fs.access(location); + return location; + } catch { + // Try next location + } + } + + throw new Error("Copilot CLI not found. Install GitHub Copilot Chat extension in VS Code."); +} diff --git a/src/services/evalScaffold.ts b/src/services/evalScaffold.ts new file mode 100644 index 0000000..4fa19ea --- /dev/null +++ b/src/services/evalScaffold.ts @@ -0,0 +1,125 @@ +import process from "node:process"; + +import { assertCopilotCliReady } from "./copilot"; + +export type EvalCase = { + id: string; + prompt: string; + expectation: string; +}; + +export type EvalConfig = { + instructionFile?: string; + cases: EvalCase[]; + systemMessage?: string; + outputPath?: string; +}; + +type EvalScaffoldOptions = { + repoPath: string; + count: number; + model?: string; + // eslint-disable-next-line no-unused-vars + onProgress?: (message: string) => void; +}; + +export async function generateEvalScaffold(options: EvalScaffoldOptions): Promise { + const repoPath = options.repoPath; + const count = Math.max(1, options.count); + const progress = options.onProgress ?? (() => {}); + + const originalCwd = process.cwd(); + process.chdir(repoPath); + + progress("Checking Copilot CLI..."); + const cliPath = await assertCopilotCliReady(); + + progress("Starting Copilot SDK..."); + const sdk = await import("@github/copilot-sdk"); + const client = new sdk.CopilotClient({ cliPath }); + + try { + progress("Creating session..."); + const preferredModel = options.model ?? "gpt-4.1"; + const session = await client.createSession({ + model: preferredModel, + streaming: true, + systemMessage: { + content: + "You are an expert codebase analyst. Generate developer-oriented eval cases for this repository. Use tools (glob, view, grep) to inspect the codebase. Output ONLY JSON with keys: instructionFile, cases (array of {id,prompt,expectation})." + }, + infiniteSessions: { enabled: false } + }); + + let content = ""; + session.on((event: { type: string; data?: Record }) => { + if (event.type === "assistant.message_delta") { + const delta = event.data?.deltaContent as string | undefined; + if (delta) { + content += delta; + progress("Generating eval cases..."); + } + } else if (event.type === "tool.execution_start") { + const toolName = event.data?.toolName as string | undefined; + progress(`Using tool: ${toolName ?? "..."}`); + } else if (event.type === "session.error") { + const errorMsg = (event.data?.message as string) ?? "Unknown error"; + if (errorMsg.toLowerCase().includes("auth") || errorMsg.toLowerCase().includes("login")) { + throw new Error("Copilot CLI not logged in. Run `copilot` then `/login` to authenticate."); + } + } + }); + + const prompt = [ + `Analyze the repository at ${repoPath} and generate ${count} eval cases.`, + "The cases should mirror realistic developer questions about this repo.", + "Use tools to inspect README, package.json, CLI commands, and key files.", + "Ensure cases cover a range of topics: purpose, entrypoints, build/test, configuration, workflows.", + "Return JSON ONLY (no markdown, no commentary) in this schema:", + "{\n \"instructionFile\": \".github/copilot-instructions.md\",\n \"cases\": [\n {\"id\": \"case-1\", \"prompt\": \"...\", \"expectation\": \"...\"}\n ]\n}" + ].join("\n"); + + progress("Analyzing codebase..."); + await session.sendAndWait({ prompt }, 180000); + await session.destroy(); + + const parsed = parseEvalConfig(content); + const normalized = normalizeEvalConfig(parsed, count); + return normalized; + } finally { + await client.stop(); + process.chdir(originalCwd); + } +} + +function parseEvalConfig(raw: string): EvalConfig { + const match = raw.match(/\{[\s\S]*\}/u); + if (!match) { + throw new Error("Failed to parse eval scaffold JSON."); + } + const parsed = JSON.parse(match[0]) as EvalConfig; + if (!parsed || !Array.isArray(parsed.cases)) { + throw new Error("Eval scaffold JSON is missing cases."); + } + return parsed; +} + +function normalizeEvalConfig(parsed: EvalConfig, count: number): EvalConfig { + const cases = (parsed.cases ?? []).slice(0, count).map((entry, index) => { + const id = typeof entry.id === "string" && entry.id.trim() ? entry.id : `case-${index + 1}`; + return { + id, + prompt: String(entry.prompt ?? "").trim(), + expectation: String(entry.expectation ?? "").trim() + }; + }); + + if (!cases.length) { + throw new Error("Eval scaffold JSON did not include any usable cases."); + } + + return { + instructionFile: parsed.instructionFile ?? ".github/copilot-instructions.md", + cases + }; +} diff --git a/src/services/evaluator.ts b/src/services/evaluator.ts index 9437a72..d325e87 100644 --- a/src/services/evaluator.ts +++ b/src/services/evaluator.ts @@ -632,6 +632,13 @@ function buildTrajectoryViewerHtml(data: Record): string { .summary { margin-bottom: 24px; color: #b7bdc8; } .layout { display: grid; grid-template-columns: 280px 1fr; gap: 16px; } .panel { background: #151924; border: 1px solid #23283b; border-radius: 10px; padding: 12px; } + .section { margin-top: 16px; } + .section h3 { margin: 8px 0; font-size: 14px; color: #c7ccd6; } + .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; } + .chip { background: #1e2232; border: 1px solid #2c3250; border-radius: 999px; padding: 2px 8px; font-size: 12px; color: #c9d1e3; } + .muted { color: #8a93a5; font-size: 12px; } + .filters { display: flex; gap: 12px; align-items: center; margin-top: 8px; } + .filters label { font-size: 12px; color: #b7bdc8; } .case { padding: 8px; border-radius: 8px; cursor: pointer; margin-bottom: 6px; } .case.active { background: #23283b; } .case span { display: block; font-size: 12px; color: #9aa3b2; } @@ -645,6 +652,7 @@ function buildTrajectoryViewerHtml(data: Record): string {

Primer Eval Trajectory

+
@@ -652,6 +660,7 @@ function buildTrajectoryViewerHtml(data: Record): string { diff --git a/src/services/instructions.ts b/src/services/instructions.ts index a1ea882..1d7cf62 100644 --- a/src/services/instructions.ts +++ b/src/services/instructions.ts @@ -1,6 +1,4 @@ -import fs from "fs/promises"; -import { execFile } from "node:child_process"; -import { promisify } from "node:util"; +import { assertCopilotCliReady } from "./copilot"; type GenerateInstructionsOptions = { repoPath: string; @@ -86,49 +84,3 @@ Output ONLY the markdown content for the instructions file.`; process.chdir(originalCwd); } } - -const execFileAsync = promisify(execFile); - -async function findCopilotCliPath(): Promise { - // Try standard PATH first - try { - const { stdout } = await execFileAsync("which", ["copilot"], { timeout: 5000 }); - return stdout.trim(); - } catch { - // Ignore - will try VS Code location - } - - // VS Code Copilot Chat extension location - const home = process.env.HOME ?? ""; - const vscodeLocations = [ - `${home}/Library/Application Support/Code - Insiders/User/globalStorage/github.copilot-chat/copilotCli/copilot`, - `${home}/Library/Application Support/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot`, - `${home}/.vscode-insiders/extensions/github.copilot-chat-*/copilotCli/copilot`, - `${home}/.vscode/extensions/github.copilot-chat-*/copilotCli/copilot`, - ]; - - for (const location of vscodeLocations) { - try { - await fs.access(location); - return location; - } catch { - // Try next location - } - } - - throw new Error("Copilot CLI not found. Install GitHub Copilot Chat extension in VS Code."); -} - -async function assertCopilotCliReady(): Promise { - const cliPath = await findCopilotCliPath(); - - try { - await execFileAsync(cliPath, ["--version"], { timeout: 5000 }); - } catch { - throw new Error(`Copilot CLI at ${cliPath} is not working.`); - } - - // Note: Copilot CLI uses its own auth system, not gh CLI. - // User must run: copilot, then /login inside the CLI. - return cliPath; -} \ No newline at end of file diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index 23f02b2..02949d7 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -5,6 +5,7 @@ import path from "path"; import { analyzeRepo, RepoAnalysis } from "../services/analyzer"; import { generateCopilotInstructions } from "../services/instructions"; import { runEval, type EvalResult } from "../services/evaluator"; +import { generateEvalScaffold } from "../services/evalScaffold"; import { AnimatedBanner, StaticBanner } from "./AnimatedBanner"; import { BatchTui } from "./BatchTui"; import { getGitHubToken } from "../services/github"; @@ -20,6 +21,7 @@ type Status = | "idle" | "analyzing" | "generating" + | "bootstrapping" | "evaluating" | "preview" | "done" @@ -28,60 +30,13 @@ type Status = | "bootstrapEvalCount" | "bootstrapEvalConfirm"; -type EvalCase = { - id: string; - prompt: string; - expectation: string; -}; - type EvalConfig = { instructionFile?: string; - cases: EvalCase[]; + cases: Array<{ id: string; prompt: string; expectation: string }>; systemMessage?: string; outputPath?: string; }; -function buildBootstrapEvalConfig(count: number): EvalConfig { - const templates = [ - { - prompt: "Summarize this repository's purpose and main entry points. Use the README and package.json if available.", - expectation: "A concise summary of repo purpose plus key entry points (CLI or main files) and how to run it." - }, - { - prompt: "Identify the primary languages, frameworks, and package manager used in this repo.", - expectation: "A brief list of languages/frameworks and the detected package manager, with short justification." - }, - { - prompt: "Draft a minimal .github/copilot-instructions.md tailored to this repo's conventions.", - expectation: "A short instruction file referencing observed conventions, avoiding assumptions or secrets." - }, - { - prompt: "Describe how to run the CLI and list its core commands and flags.", - expectation: "Clear usage instructions with command names and key flags derived from docs or source." - }, - { - prompt: "Propose an eval case that checks consistency between CLI and TUI behaviors.", - expectation: "One eval case that validates parity between CLI and TUI outputs or workflows." - } - ]; - - const cases = Array.from({ length: count }, (_, index) => { - const template = templates[index % templates.length]; - const variant = Math.floor(index / templates.length); - const suffix = variant > 0 ? ` (variant ${variant + 1})` : ""; - return { - id: `case-${index + 1}`, - prompt: `${template.prompt}${suffix}`, - expectation: `${template.expectation}${suffix}` - } satisfies EvalCase; - }); - - return { - instructionFile: ".github/copilot-instructions.md", - cases - }; -} - export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX.Element { const app = useApp(); const [status, setStatus] = useState(skipAnimation ? "idle" : "intro"); @@ -99,6 +54,34 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setStatus("idle"); }; + const bootstrapEvalConfig = async (count: number, force: boolean): Promise => { + const configPath = path.join(repoPath, "primer.eval.json"); + try { + setStatus("bootstrapping"); + setMessage("Generating eval cases with Copilot SDK..."); + const config = await generateEvalScaffold({ + repoPath, + count, + model: "gpt-4.1", + onProgress: (msg) => setMessage(msg) + }); + const resultMessage = await safeWriteFile(configPath, JSON.stringify(config, null, 2), force); + setStatus("done"); + setMessage(`Bootstrapped eval: ${resultMessage}`); + } catch (error) { + setStatus("error"); + const message = error instanceof Error ? error.message : "Failed to generate eval cases."; + if (message.toLowerCase().includes("auth") || message.toLowerCase().includes("login")) { + setMessage(`${message} Run 'copilot' then '/login' in a separate terminal.`); + } else { + setMessage(message); + } + } finally { + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); + } + }; + useInput(async (input: string, key: Key) => { // During intro animation, any key skips it if (status === "intro") { @@ -152,12 +135,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setStatus("bootstrapEvalConfirm"); setMessage("primer.eval.json exists. Overwrite? (Y/N)"); } catch { - const config = buildBootstrapEvalConfig(count); - const resultMessage = await safeWriteFile(configPath, JSON.stringify(config, null, 2), false); - setStatus("done"); - setMessage(`Bootstrapped eval: ${resultMessage}`); - setEvalCaseCountInput(""); - setEvalBootstrapCount(null); + await bootstrapEvalConfig(count, false); } return; } @@ -183,19 +161,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setMessage("Missing eval case count. Restart bootstrap."); return; } - try { - const configPath = path.join(repoPath, "primer.eval.json"); - const config = buildBootstrapEvalConfig(count); - const resultMessage = await safeWriteFile(configPath, JSON.stringify(config, null, 2), true); - setStatus("done"); - setMessage(`Bootstrapped eval: ${resultMessage}`); - } catch (error) { - setStatus("error"); - setMessage(error instanceof Error ? error.message : "Failed to write eval config."); - } finally { - setEvalCaseCountInput(""); - setEvalBootstrapCount(null); - } + await bootstrapEvalConfig(count, true); return; } From ac7f562699dd180ab41e5613883980b918a1defc Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Tue, 3 Feb 2026 22:41:37 -0700 Subject: [PATCH 04/19] feat(cli): add option to list available Copilot models feat(eval): implement model listing functionality in eval command feat(copilot): create function to extract and list Copilot models from CLI help feat(evaluator): enhance trajectory viewer with phase filtering for tool calls feat(tui): add readiness report feature with detailed output and user interaction --- eval-results.html | 125 +- eval-results.json | 10406 ++++++++++++++++++++++++++---------- src/cli.ts | 1 + src/commands/eval.ts | 12 + src/services/copilot.ts | 36 + src/services/evaluator.ts | 47 +- src/ui/tui.tsx | 106 +- 7 files changed, 7935 insertions(+), 2798 deletions(-) diff --git a/eval-results.html b/eval-results.html index cdc38d9..3d2da62 100644 --- a/eval-results.html +++ b/eval-results.html @@ -10,6 +10,14 @@ .summary { margin-bottom: 24px; color: #b7bdc8; } .layout { display: grid; grid-template-columns: 280px 1fr; gap: 16px; } .panel { background: #151924; border: 1px solid #23283b; border-radius: 10px; padding: 12px; } + .section { margin-top: 16px; } + .section h3 { margin: 8px 0; font-size: 14px; color: #c7ccd6; } + .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; } + .chip { background: #1e2232; border: 1px solid #2c3250; border-radius: 999px; padding: 2px 8px; font-size: 12px; color: #c9d1e3; } + .chip.phase { background: #23283b; border-color: #3a4163; color: #aeb7c6; } + .muted { color: #8a93a5; font-size: 12px; } + .filters { display: flex; gap: 12px; align-items: center; margin-top: 8px; } + .filters label { font-size: 12px; color: #b7bdc8; } .case { padding: 8px; border-radius: 8px; cursor: pointer; margin-bottom: 6px; } .case.active { background: #23283b; } .case span { display: block; font-size: 12px; color: #9aa3b2; } @@ -23,13 +31,15 @@

Primer Eval Trajectory

+
diff --git a/eval-results.json b/eval-results.json index da3cda4..a61da80 100644 --- a/eval-results.json +++ b/eval-results.json @@ -3,63 +3,57 @@ "model": "gpt-4.1", "judgeModel": "gpt-4.1", "runMetrics": { - "startedAt": "2026-02-04T05:21:19.668Z", - "finishedAt": "2026-02-04T05:21:58.146Z", - "durationMs": 38478 + "startedAt": "2026-02-04T05:38:08.043Z", + "finishedAt": "2026-02-04T05:38:34.698Z", + "durationMs": 26655 }, "results": [ { - "id": "overview", - "prompt": "Summarize what this application does and list the main entrypoints.", - "expectation": "Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.", - "withInstructions": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.", - "withoutInstructions": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.", + "id": "case-1", + "prompt": "What is the main purpose of the Primer CLI tool and what are its key features?", + "expectation": "Primer is a CLI tool that analyzes codebases and generates .github/copilot-instructions.md files to help AI coding assistants understand projects better. Key features include repository analysis, AI-powered instruction generation, batch processing, an evaluation framework, readiness reports, GitHub integration, an interactive TUI, and config generation.", + "withInstructions": "The main purpose of the Primer CLI tool is to prime repositories for AI-assisted development and evaluation, especially for use with GitHub Copilot and similar agents. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone, branch, PR), and evaluating agent responses with/without instructions. It uses TypeScript, Commander for CLI, Ink/React for TUI, and integrates tightly with Copilot and GitHub automation.", + "withoutInstructions": "The Primer CLI tool is a TypeScript-based CLI for priming repositories for AI-assisted development and evaluation. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone/branch/PR), and providing an interactive TUI. It is designed for ESM/strict TypeScript, uses Commander for CLI, Ink/React for TUI, and integrates with Copilot and GitHub for automation and evaluation.", "verdict": "pass", - "score": 100, - "rationale": "Response B best matches the expectation by explicitly mentioning the CLI entrypoint in src/index.ts, clarifying that it calls runCli in src/cli.ts, and identifying this as the Primer CLI. It also provides a more complete and accurate list of commands and features, aligning closely with the expectation.", + "score": 95, + "rationale": "Response B best matches the expectation. It covers all key features: repository analysis, instruction generation, config generation, GitHub automation, and evaluation framework. Response A is also accurate but omits explicit mention of the evaluation framework and readiness reports, which are present in the expectation.", "metrics": { "withoutInstructions": { - "durationMs": 11934, + "durationMs": 4925, "tokenUsage": { - "promptTokens": 10005, - "completionTokens": 289, - "totalTokens": 10294 + "promptTokens": 12602, + "completionTokens": 98, + "totalTokens": 12700 }, "toolCalls": { - "count": 5, + "count": 1, "byName": { - "report_intent": 1, - "task": 1, - "view": 3 + "fetch_copilot_cli_documentation": 1 }, "totalDurationMs": 0 } }, "withInstructions": { - "durationMs": 22221, + "durationMs": 4457, "tokenUsage": { - "promptTokens": 11011, - "completionTokens": 335, - "totalTokens": 11346 + "promptTokens": 13420, + "completionTokens": 101, + "totalTokens": 13521 }, "toolCalls": { - "count": 7, + "count": 1, "byName": { - "report_intent": 1, - "task": 1, - "view": 3, - "glob": 1, - "grep": 1 + "fetch_copilot_cli_documentation": 1 }, "totalDurationMs": 0 } }, "judge": { - "durationMs": 2774, + "durationMs": 2212, "tokenUsage": { - "promptTokens": 10011, - "completionTokens": 84, - "totalTokens": 10095 + "promptTokens": 10133, + "completionTokens": 75, + "totalTokens": 10208 }, "toolCalls": { "count": 0, @@ -67,33 +61,33 @@ "totalDurationMs": 0 } }, - "totalDurationMs": 38461 + "totalDurationMs": 13112 }, "trajectory": [ { - "timestampMs": 1770182481178, + "timestampMs": 1770183489544, "phase": "withoutInstructions", "type": "pending_messages.modified", "data": {} }, { - "timestampMs": 1770182481178, + "timestampMs": 1770183489544, "phase": "withoutInstructions", "type": "pending_messages.modified", "data": {} }, { - "timestampMs": 1770182483604, + "timestampMs": 1770183492141, "phase": "withoutInstructions", "type": "user.message", "data": { - "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", - "transformedContent": "2026-02-04T05:21:23.352Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhat is the main purpose of the Primer CLI tool and what are its key features?", + "transformedContent": "2026-02-04T05:38:11.890Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhat is the main purpose of the Primer CLI tool and what are its key features?", "attachments": [] } }, { - "timestampMs": 1770182483604, + "timestampMs": 1770183492142, "phase": "withoutInstructions", "type": "assistant.turn_start", "data": { @@ -101,30 +95,30 @@ } }, { - "timestampMs": 1770182483604, + "timestampMs": 1770183492142, "phase": "withoutInstructions", "type": "session.usage_info", "data": { "tokenLimit": 64000, - "currentTokens": 10343, + "currentTokens": 10492, "messagesLength": 2 } }, { - "timestampMs": 1770182485828, + "timestampMs": 1770183493060, "phase": "withoutInstructions", "type": "assistant.usage", "data": { "model": "gpt-4.1", - "inputTokens": 9710, - "outputTokens": 85, - "cacheReadTokens": 3840, + "inputTokens": 9859, + "outputTokens": 15, + "cacheReadTokens": 0, "cacheWriteTokens": 0, "cost": 0, - "duration": 2197, + "duration": 919, "initiator": "user", - "apiCallId": "chatcmpl-D5PcKj8TBk6a1XH5WkxrNpJSXawfs", - "providerCallId": "E903:35A03D:33E28A:3D9614:6982D753", + "apiCallId": "chatcmpl-D5PsaIGMjW9rWUXpnMpRLIzN0Ib5a", + "providerCallId": "EEC8:177A35:701447:840410:6982DB43", "quotaSnapshots": { "chat": { "isUnlimitedEntitlement": true, @@ -170,1626 +164,1154 @@ } }, { - "timestampMs": 1770182485829, + "timestampMs": 1770183493060, "phase": "withoutInstructions", "type": "assistant.message", "data": { - "messageId": "93ddd8e5-b53b-4e65-ae4d-3c9ab4f51f3b", + "messageId": "574878eb-7d54-46c6-bb0b-396f8fafa6a3", "content": "", "toolRequests": [ { - "toolCallId": "call_tpnJMuSM0sryKLy4z7k2W06H", - "name": "report_intent", - "arguments": { - "intent": "Exploring codebase" - }, - "type": "function" - }, - { - "toolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "name": "task", - "arguments": { - "agent_type": "explore", - "description": "Summarizing application purpose", - "prompt": "Summarize what this application does and list the main entrypoints. Be concise and list file paths for entrypoints." - }, + "toolCallId": "call_AO5bxlCkmdExvADeTf3OAEod", + "name": "fetch_copilot_cli_documentation", + "arguments": {}, "type": "function" } ] } }, { - "timestampMs": 1770182485834, - "phase": "withoutInstructions", - "type": "tool.execution_start", - "data": { - "toolCallId": "call_tpnJMuSM0sryKLy4z7k2W06H", - "toolName": "report_intent", - "arguments": { - "intent": "Exploring codebase" - } - } - }, - { - "timestampMs": 1770182485837, + "timestampMs": 1770183493061, "phase": "withoutInstructions", "type": "tool.execution_start", "data": { - "toolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolName": "task", - "arguments": { - "agent_type": "explore", - "description": "Summarizing application purpose", - "prompt": "Summarize what this application does and list the main entrypoints. Be concise and list file paths for entrypoints." - } + "toolCallId": "call_AO5bxlCkmdExvADeTf3OAEod", + "toolName": "fetch_copilot_cli_documentation", + "arguments": {} } }, { - "timestampMs": 1770182485837, + "timestampMs": 1770183493098, "phase": "withoutInstructions", "type": "tool.execution_complete", "data": { - "toolCallId": "call_tpnJMuSM0sryKLy4z7k2W06H", + "toolCallId": "call_AO5bxlCkmdExvADeTf3OAEod", "success": true, "result": { - "content": "Intent logged", - "detailedContent": "Exploring codebase" + "content": "# GitHub Copilot CLI Documentation\n\n## README\n# GitHub Copilot CLI (Public Preview)\n\nThe power of GitHub Copilot, now in your terminal.\n\nGitHub Copilot CLI brings AI-powered coding assistance directly to your command line, enabling you to build, debug, and understand code through natural language conversations. Powered by the same agentic harness as GitHub's Copilot coding agent, it provides intelligent assistance while staying deeply integrated with your GitHub workflow.\n\nSee [our official documentation](https://docs.github.com/copilot/concepts/agents/about-copilot-cli) for more information.\n\n![Image of the splash screen for the Copilot CLI](https://github.com/user-attachments/assets/f40aa23d-09dd-499e-9457-1d57d3368887)\n\n\n## 🚀 Introduction and Overview\n\nWe're bringing the power of GitHub Copilot coding agent directly to your terminal. With GitHub Copilot CLI, you can work locally and synchronously with an AI agent that understands your code and GitHub context.\n\n- **Terminal-native development:** Work with Copilot coding agent directly in your command line — no context switching required.\n- **GitHub integration out of the box:** Access your repositories, issues, and pull requests using natural language, all authenticated with your existing GitHub account.\n- **Agentic capabilities:** Build, edit, debug, and refactor code with an AI collaborator that can plan and execute complex tasks.\n- **MCP-powered extensibility:** Take advantage of the fact that the coding agent ships with GitHub's MCP server by default and supports custom MCP servers to extend capabilities.\n- **Full control:** Preview every action before execution — nothing happens without your explicit approval.\n\nWe're still early in our journey, but with your feedback, we're rapidly iterating to make the GitHub Copilot CLI the best possible companion in your terminal.\n\n## 📦 Getting Started\n\n### Supported Platforms\n\n- **Linux**\n- **macOS**\n- **Windows**\n\n### Prerequisites\n\n- (On Windows) **PowerShell** v6 or …", + "detailedContent": "Fetched CLI documentation" }, "toolTelemetry": {} } }, { - "timestampMs": 1770182488411, + "timestampMs": 1770183493098, "phase": "withoutInstructions", - "type": "assistant.usage", + "type": "assistant.turn_end", "data": { - "model": "claude-haiku-4.5", - "inputTokens": 2707, - "outputTokens": 289, - "cacheReadTokens": 0, - "cacheWriteTokens": 0, - "cost": 0.33, - "duration": 2250, - "initiator": "sub-agent", - "apiCallId": "msg_016BDLf3uZartGeaCcNnSoWD", - "providerCallId": "E903:35A03D:33EB57:3DA002:6982D756", - "quotaSnapshots": { - "chat": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "completions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "premium_interactions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "premium_interactions_tbb": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - } - }, - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg" + "turnId": "0" } }, { - "timestampMs": 1770182488411, + "timestampMs": 1770183493098, "phase": "withoutInstructions", - "type": "assistant.message", + "type": "assistant.turn_start", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "messageId": "7b744914-d9fc-49f0-80de-7c84c32a6b2c", - "content": "", - "toolRequests": [ - { - "toolCallId": "toolu_01CzbYettZVEcZ8aE2dMxFGW", - "name": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready" - }, - "type": "function" - }, - { - "toolCallId": "toolu_01FQ6TzCWfm56V3EwxeF2MRA", - "name": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/package.json" - }, - "type": "function" - }, - { - "toolCallId": "toolu_01NGYzuJkusQqT4meJPJuhD9", - "name": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/README.md" - }, - "type": "function" - } - ], - "reasoningOpaque": "3IOUA34d654sP/xOhtYd0oHMHIP6BSEfihGf5GWOyWK7q6GXOek2hymkrZygkkIadRZ4TN0p6q0c68r5514Y9GJBJYvm+dmAwPNxF1EP2lFKZowIJ2CxDiEydSmtN4FsoqK9SENjWhrk8SL/Vy3OGKEAFQP9UTJzSYLVc1EHT8RnBzA0vgAi7YMCma7ch40DCjCvwQUdQJMhoxVjUYXfVkIW041JasRO3g5SBz6EJjZEynwbAyf41sgLSyXJGYEP2IsTHRqHv6jmVHwZVd6ZS5Z13rUFDJewL+k1Krl10f4M1dVhTu9QXLkiuIYSBTQ65q8GengLmnoiSCaLwLIaOpyAe5l5Dqj1x2gWiS5jK9UDvnwlTyLCtoOxH6iGBY8SoqkPOhjuy2nuuODytX96I9Am+lPG11rgKfnhrsM7IJM/AmXEQCLb8kxRKlvqoRU3rmC3nozTQEXRLfyCY9ODN2OoRTc+Uhc4Ew1ZAi6WGFY01AiPJaSKCtgZ2O4+p8kp1p7dk2AKv2bGVe5k+yU101fYe3TwBTa4md2sF3E0zsw2TwlUtU8uTUJ6k1k32s2ynmeOQWYVOheNlXAflxAzgH1hqALbwIMKrxj1ge/ESB8MhP69y8UUSNe51kh2Y1eo2Lca0S5V6UIHZzzuUNHTaHa+TRivQeL+KQepRwsCO6a0NpWbV51KP8iQ7ihNlKa/j96y0BgarFAOHHnlgI0trQ05pwfTDK9E8af6Qvb1aQb5f2Eiyt7Hc3rnfF2INJs7cdK2eI8l+ajZIM6vnEPQgnlA5QPunF2HCOGS3K4bHUU4lNQwcPtIpufmWsXGt5s7sb87prrzirCNvQqB2S4nrGtpALAjOr3kFh/U2mdy6KxuEyxy9AxjE5bGGTWcdDYAKD/U7cndxcVVNF6v7Z7TlgSd22IPArf97HjHI8zMe0kIuSnKOy9eEjEKD+px9NLl5OHeOj9fq2X7/PHkjrmEq9B2v//+t2VRoPExfoHhmiIfmtHP0wlNwSASd4jcwScoHAmUZc9e3FTynXVfKGasUc1aCUt3rkNY+uhU6UUoWbKZB0KsSqe85SwSaeNV1+6qzqXVMo2/LO1gaETmvI8xhnXmfEm9AuKqdKX2nwUZSlHBULCFuZLqh9G0ACl2yu7djX9nLFMMJGIq1WG8aQYu5EGO/xwaTImJRf0Q5B/n7AroQdrJTDXd6DP9nvwdgGPN8mrerg3xmtIEWreDnczsvZpAbhmaFTubp6YFzN+pQjYAIC8G0vRtD+vx0kzwLvX8LL5g7ULQljhtVKd9x09h+idh21t0wr6HbypZFxHc3oSTriUPuguqCkTO1fGOaFpCGvGoXhPC3mF3k71GOoehCWDxVD2LCfDmWlzPhPRh9u2hhy9JH5UuleOHgs6XMXFofeZ9McXvhjIQjn779zrjI+QgUD6m/4FwEvLL2Od/tSg0PswA2nCbCG8+0aJQQyJ+9I47NFlxose045GGhS4Je9c0U0GjV3uDodpPIRA11AUOz84gXBsK5Jj/X6vO", - "reasoningText": "The user wants me to summarize what this application does and list the main entrypoints with file paths. I should:\n\n1. First, explore the repository structure to understand what it is\n2. Look for package.json, README, or other documentation to understand the purpose\n3. Find the main entrypoints (typically in package.json, or main files like index.ts, index.js, main.ts, etc.)\n\nLet me start by looking at the directory structure and key files like package.json, README.md, etc." + "turnId": "1" } }, { - "timestampMs": 1770182488412, + "timestampMs": 1770183493098, "phase": "withoutInstructions", - "type": "tool.execution_start", + "type": "session.usage_info", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolCallId": "toolu_01CzbYettZVEcZ8aE2dMxFGW", - "toolName": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready" - } + "tokenLimit": 64000, + "currentTokens": 13226, + "messagesLength": 4 } }, { - "timestampMs": 1770182488412, + "timestampMs": 1770183493980, "phase": "withoutInstructions", - "type": "tool.execution_start", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolCallId": "toolu_01FQ6TzCWfm56V3EwxeF2MRA", - "toolName": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/package.json" - } + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": "The", + "totalResponseSizeBytes": 3 } }, { - "timestampMs": 1770182488412, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "tool.execution_start", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolCallId": "toolu_01NGYzuJkusQqT4meJPJuhD9", - "toolName": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/README.md" - } + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 10 } }, { - "timestampMs": 1770182488413, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "tool.execution_complete", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolCallId": "toolu_01FQ6TzCWfm56V3EwxeF2MRA", - "success": true, - "result": { - "content": "1. {\n2. \"name\": \"primer\",\n3. \"version\": \"1.0.0\",\n4. \"description\": \"\",\n5. \"main\": \"dist/index.js\",\n6. \"scripts\": {\n7. \"build\": \"tsc && npm link\",\n8. \"prepare\": \"tsc\",\n9. \"lint\": \"eslint .\",\n10. \"format\": \"prettier --write .\",\n11. \"format:check\": \"prettier --check .\",\n12. \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n13. \"test\": \"vitest run\",\n14. \"test:watch\": \"vitest\",\n15. \"test:coverage\": \"vitest run --coverage\"\n16. },\n17. \"keywords\": [],\n18. \"author\": \"\",\n19. \"license\": \"ISC\",\n20. \"dependencies\": {\n21. \"@github/copilot-sdk\": \"^0.1.19\",\n22. \"@inquirer/prompts\": \"^8.2.0\",\n23. \"@octokit/rest\": \"^22.0.1\",\n24. \"chalk\": \"^5.6.2\",\n25. \"commander\": \"^14.0.2\",\n26. \"fast-glob\": \"^3.3.3\",\n27. \"ink\": \"^6.6.0\",\n28. \"react\": \"^19.2.4\",\n29. \"simple-git\": \"^3.30.0\"\n30. },\n31. \"devDependencies\": {\n32. \"@types/node\": \"^25.1.0\",\n33. \"@types/react\": \"^19.2.10\",\n34. \"@typescript-eslint/eslint-plugin\": \"^8.5.0\",\n35. \"@typescript-eslint/parser\": \"^8.5.0\",\n36. \"@vitest/coverage-v8\": \"^2.1.4\",\n37. \"eslint\": \"^9.7.0\",\n38. \"eslint-config-prettier\": \"^9.1.0\",\n39. \"eslint-plugin-import\": \"^2.30.0\",\n40. \"eslint-plugin-n\": \"^17.10.2\",\n41. \"eslint-plugin-promise\": \"^7.1.0\",\n42. \"prettier\": \"^3.3.3\",\n43. \"tsup\": \"^8.5.1\",\n44. \"tsx\": \"^4.21.0\",\n45. \"typescript\": \"^5.9.3\",\n46. \"vitest\": \"^2.1.4\"\n47. },\n48. \"type\": \"module\",\n49. \"bin\": {\n50. \"primer\": \"dist/index.js\"\n51. }\n52. }\n53. ", - "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/package.json b/Users/pierceboggan/Documents/get-ready/package.json\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/package.json\n+++ b/Users/pierceboggan/Documents/get-ready/package.json\n@@ -1,53 +1,53 @@\n {\n \"name\": \"primer\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"dist/index.js\",\n \"scripts\": {\n \"build\": \"tsc && npm link\",\n \"prepare\": \"tsc\",\n \"lint\": \"eslint .\",\n \"format\": \"prettier --write .\",\n \"format:check\": \"prettier --check .\",\n \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\",\n \"dependencies\": {\n \"@github/copilot-sdk\": \"^0.1.19\",\n \"@inquirer/prompts\": \"^8.2.0\",\n \"@octokit/rest\": \"^22.0.1\",\n \"chalk\": \"^5.6.2\",\n \"commander\": \"^14.0.2\",\n \"fast-glob\": \"^3.3.3\",\n \"ink\": \"^6.6.0\",\n \"react\": \"^19.2.4\",\n \"simple-git\": \"^3.30.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^25.1.0\",\n \"@types/react\": \"^19.2.10\",\n \"@typescript-eslint/eslint-plugin\": \"^8.5.0\",\n \"@typescript-eslint/parser\": \"^8.5.0\",\n \"@vitest/coverage-v8\": \"^2.1.4\",\n \"eslint\": \"^9.7.0\",\n \"eslint-config-prettier\": \"^9.1.0\",\n \"eslint-plugin-import\": \"^2.30.0\",\n \"eslint-plugin-n\": \"^17.10.2\",\n \"eslint-plugin-promise\": \"^7.1.0\",\n \"prettier\": \"^3.3.3\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.21.0\",\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^2.1.4\"\n },\n \"type\": \"module\",\n \"bin\": {\n \"primer\": \"dist/index.js\"\n }\n }\n \n" - } + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 14 } }, { - "timestampMs": 1770182488413, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "tool.execution_complete", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolCallId": "toolu_01CzbYettZVEcZ8aE2dMxFGW", - "success": true, - "result": { - "content": ".DS_Store\n.git\n.github\n.gitignore\n.prettierrc.json\n.primer-cache\nCHANGELOG.md\nCODEOWNERS\nCONTRIBUTING.md\nLICENSE\nPLAN.md\nREADME.md\nSECURITY.md\ndist\neslint.config.js\neval-results.html\neval-results.json\nexamples\nnode_modules\npackage-lock.json\npackage.json\nprimer.eval.json\nprimer.png\nrelease-please-config.json\nrelease-please-manifest.json\nsrc\ntsconfig.json\nvitest.config.ts", - "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready b/Users/pierceboggan/Documents/get-ready\ncreate file mode 100644\nindex 0000000..0000000\n--- a/dev/null\n+++ b/Users/pierceboggan/Documents/get-ready\n@@ -1,0 +1,28 @@\n .DS_Store\n .git\n .github\n .gitignore\n .prettierrc.json\n .primer-cache\n CHANGELOG.md\n CODEOWNERS\n CONTRIBUTING.md\n LICENSE\n PLAN.md\n README.md\n SECURITY.md\n dist\n eslint.config.js\n eval-results.html\n eval-results.json\n examples\n node_modules\n package-lock.json\n package.json\n primer.eval.json\n primer.png\n release-please-config.json\n release-please-manifest.json\n src\n tsconfig.json\n vitest.config.ts\n" - } + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " tool", + "totalResponseSizeBytes": 19 } }, { - "timestampMs": 1770182488430, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "tool.execution_complete", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "toolCallId": "toolu_01NGYzuJkusQqT4meJPJuhD9", - "success": true, - "result": { - "content": "1. # Primer\n2. \n3. > Prime your repositories for AI-assisted development.\n4. \n5. [![CI](https://github.com/pierceboggan/primer/actions/workflows/ci.yml/badge.svg)](https://github.com/pierceboggan/primer/actions/workflows/ci.yml)\n6. [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n7. \n8. Primer is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants understand your project better. It supports single repos, batch processing across organizations, and includes an evaluation framework to measure instruction effectiveness.\n9. \n10. ![Primer](primer.png)\n11. \n12. ## Features\n13. \n14. - **Repository Analysis** - Detects languages, frameworks, and package managers\n15. - **AI-Powered Generation** - Uses the Copilot SDK to analyze your codebase and generate context-aware instructions\n16. - **Batch Processing** - Process multiple repos across organizations with a single command\n17. - **Evaluation Framework** - Test and measure how well your instructions improve AI responses\n18. - **Readiness Report** - Score AI readiness across key pillars with a fix-first checklist\n19. - **GitHub Integration** - Clone repos, create branches, and open PRs automatically\n20. - **Interactive TUI** - Beautiful terminal interface built with Ink\n21. - **Config Generation** - Generate MCP and VS Code configurations\n22. \n23. ## Prerequisites\n24. \n25. 1. **Node.js 18+**\n26. 2. **GitHub Copilot CLI** - Installed via VS Code's Copilot Chat extension\n27. 3. **Copilot CLI Authentication** - Run `copilot` then `/login` to authenticate\n28. 4. **GitHub CLI (optional)** - For batch processing and PR creation: `brew install gh && gh auth login`\n29. 5. **Azure DevOps PAT (optional)** - For Azure DevOps batch/PR workflows: set `AZURE_DEVOPS_PAT`\n30. \n31. ## Installation\n32. \n33. ```bash\n34. # Install from npm\n35. npm install -g primer\n36. ```\n37. \n38. ### Quick Install\n39. \n40. ```bash\n41. primer --help\n42. ```\n43. \n44. ##…", - "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/README.md b/Users/pierceboggan/Documents/get-ready/README.md\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/README.md\n+++ b/Users/pierceboggan/Documents/get-ready/README.md\n@@ -1,362 +1,362 @@\n # Primer\n \n > Prime your repositories for AI-assisted development.\n \n [![CI](https://github.com/pierceboggan/primer/actions/workflows/ci.yml/badge.svg)](https://github.com/pierceboggan/primer/actions/workflows/ci.yml)\n [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n \n Primer is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants understand your project better. It supports single repos, batch processing across organizations, and includes an evaluation framework to measure instruction effectiveness.\n \n ![Primer](primer.png)\n \n ## Features\n \n - **Repository Analysis** - Detects languages, frameworks, and package managers\n - **AI-Powered Generation** - Uses the Copilot SDK to analyze your codebase and generate context-aware instructions\n - **Batch Processing** - Process multiple repos across organizations with a single command\n - **Evaluation Framework** - Test and measure how well your instructions improve AI responses\n - **Readiness Report** - Score AI readiness across key pillars with a fix-first checklist\n - **GitHub Integration** - Clone repos, create branches, and open PRs automatically\n - **Interactive TUI** - Beautiful terminal interface built with Ink\n - **Config Generation** - Generate MCP and VS Code configurations\n \n ## Prerequisites\n \n 1. **Node.js 18+**\n 2. **GitHub Copilot CLI** - Installed via VS Code's Copilot Chat extension\n 3. **Copilot CLI Authentication** - Run `copilot` then `/login` to authenticate\n 4. **GitHub CLI (optional)** - For batch processing and PR creation: `brew install gh && gh auth login`\n 5. **Azure DevOps PAT (optional)** - For Azure DevOps batch/PR workflows: set `AZ…" - } + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 22 } }, { - "timestampMs": 1770182490847, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "assistant.usage", + "type": "assistant.message_delta", "data": { - "model": "claude-haiku-4.5", - "inputTokens": 7343, - "outputTokens": 219, - "cacheReadTokens": 0, - "cacheWriteTokens": 0, - "cost": 0.33, - "duration": 2400, - "initiator": "sub-agent", - "apiCallId": "msg_01R8GGE5VmR6reyFGzX8mGHz", - "providerCallId": "E903:35A03D:33F2DB:3DA886:6982D758", - "quotaSnapshots": { - "chat": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "completions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "premium_interactions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "premium_interactions_tbb": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - } - }, - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg" + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 24 } }, { - "timestampMs": 1770182490847, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "assistant.message", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "messageId": "f887839e-d030-4ed2-b01a-f4c8902583da", - "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It features repository analysis, AI-powered instruction generation, batch processing, evaluation framework, readiness reports, and GitHub integration.\n\n**Main Entrypoints:**\n\n| File | Purpose |\n|------|---------|\n| `/Users/pierceboggan/Documents/get-ready/src/index.ts` | CLI entry point |\n| `/Users/pierceboggan/Documents/get-ready/src/cli.ts` | Commander CLI setup |\n\n**Key Commands:**\n- `primer init` - Interactive setup\n- `primer tui` - Terminal UI\n- `primer instructions` - Generate instructions\n- `primer analyze` - Repository analysis\n- `primer batch` - Batch processing\n- `primer readiness` - Readiness report\n- `primer eval` - Evaluation framework", - "toolRequests": [] + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " Type", + "totalResponseSizeBytes": 29 } }, { - "timestampMs": 1770182490886, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "tool.execution_complete", + "type": "assistant.message_delta", "data": { - "toolCallId": "call_ijMhZpBYRRRLazj3rstyRJlg", - "success": true, - "result": { - "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It features repository analysis, AI-powered instruction generation, batch processing, evaluation framework, readiness reports, and GitHub integration.\n\n**Main Entrypoints:**\n\n| File | Purpose |\n|------|---------|\n| `/Users/pierceboggan/Documents/get-ready/src/index.ts` | CLI entry point |\n| `/Users/pierceboggan/Documents/get-ready/src/cli.ts` | Commander CLI setup |\n\n**Key Commands:**\n- `primer init` - Interactive setup\n- `primer tui` - Terminal UI\n- `primer instructions` - Generate instructions\n- `primer analyze` - Repository analysis\n- `primer batch` - Batch processing\n- `primer readiness` - Readiness report\n- `primer eval` - Evaluation framework", - "detailedContent": "## Summary\n\n(Full response provided to agent)" - }, - "toolTelemetry": { - "properties": { - "prompt_length": "115", - "response_length": "828", - "hashed_agent_name": "6f281157ab246f0e1f35db82165d3448ee1e39077ab0d720fca7dddf014249d6", - "agent_type": "explore", - "execution_mode": "sync" - }, - "restrictedProperties": { - "agent_name": "explore" - }, - "metrics": { - "response_length": 828, - "numberOfToolCallsMadeByAgent": 3 - } - } + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 6, + "deltaPreview": "Script", + "totalResponseSizeBytes": 35 } }, { - "timestampMs": 1770182490886, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "assistant.turn_end", + "type": "assistant.message_delta", "data": { - "turnId": "0" + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 6, + "deltaPreview": "-based", + "totalResponseSizeBytes": 41 } }, { - "timestampMs": 1770182490886, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "assistant.turn_start", + "type": "assistant.message_delta", "data": { - "turnId": "1" + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 45 } }, { - "timestampMs": 1770182490886, + "timestampMs": 1770183493981, "phase": "withoutInstructions", - "type": "session.usage_info", + "type": "assistant.message_delta", "data": { - "tokenLimit": 64000, - "currentTokens": 10605, - "messagesLength": 5 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 49 } }, { - "timestampMs": 1770182491922, + "timestampMs": 1770183493981, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": "This", - "totalResponseSizeBytes": 4 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " prim", + "totalResponseSizeBytes": 54 } }, { - "timestampMs": 1770182491923, + "timestampMs": 1770183493981, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 12, - "deltaPreview": " application", - "totalResponseSizeBytes": 16 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": "ing", + "totalResponseSizeBytes": 57 } }, { - "timestampMs": 1770182491923, + "timestampMs": 1770183493981, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 17 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 13, + "deltaPreview": " repositories", + "totalResponseSizeBytes": 70 } }, { - "timestampMs": 1770182491923, + "timestampMs": 1770183493981, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 7, - "deltaPreview": " Primer", - "totalResponseSizeBytes": 24 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 74 } }, { - "timestampMs": 1770182491923, + "timestampMs": 1770183493981, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 25 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": " AI", + "totalResponseSizeBytes": 77 } }, { - "timestampMs": 1770182491923, + "timestampMs": 1770183494031, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": " is", - "totalResponseSizeBytes": 28 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 9, + "deltaPreview": "-assisted", + "totalResponseSizeBytes": 86 } }, { - "timestampMs": 1770182491923, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " a", - "totalResponseSizeBytes": 30 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 12, + "deltaPreview": " development", + "totalResponseSizeBytes": 98 } }, { - "timestampMs": 1770182492100, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 34 + "deltaPreview": " and", + "totalResponseSizeBytes": 102 } }, { - "timestampMs": 1770182492100, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": " tool", - "totalResponseSizeBytes": 39 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 113 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": " that", - "totalResponseSizeBytes": 44 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 114 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 9, - "deltaPreview": " analyzes", - "totalResponseSizeBytes": 53 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " Its", + "totalResponseSizeBytes": 118 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": " code", - "totalResponseSizeBytes": 58 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " key", + "totalResponseSizeBytes": 122 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": "bases", - "totalResponseSizeBytes": 63 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 9, + "deltaPreview": " features", + "totalResponseSizeBytes": 131 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 67 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 8, + "deltaPreview": " include", + "totalResponseSizeBytes": 139 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 10, - "deltaPreview": " generates", - "totalResponseSizeBytes": 77 + "deltaPreview": " analyzing", + "totalResponseSizeBytes": 149 + } + }, + { + "timestampMs": 1770183494032, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 13, + "deltaPreview": " repositories", + "totalResponseSizeBytes": 162 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 3, - "deltaPreview": " `.", - "totalResponseSizeBytes": 80 + "deltaPreview": " to", + "totalResponseSizeBytes": 165 } }, { - "timestampMs": 1770182492101, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 6, - "deltaPreview": "github", - "totalResponseSizeBytes": 86 + "deltaPreview": " infer", + "totalResponseSizeBytes": 171 } }, { - "timestampMs": 1770182492171, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": "/cop", - "totalResponseSizeBytes": 90 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 10, + "deltaPreview": " languages", + "totalResponseSizeBytes": 181 } }, { - "timestampMs": 1770182492171, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 4, - "deltaPreview": "ilot", - "totalResponseSizeBytes": 94 + "deltaPreview": " and", + "totalResponseSizeBytes": 185 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": "-in", - "totalResponseSizeBytes": 97 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 11, + "deltaPreview": " frameworks", + "totalResponseSizeBytes": 196 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 10, - "deltaPreview": "structions", - "totalResponseSizeBytes": 107 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 197 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": ".md", - "totalResponseSizeBytes": 110 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 11, + "deltaPreview": " generating", + "totalResponseSizeBytes": 208 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": "`", - "totalResponseSizeBytes": 111 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " Cop", + "totalResponseSizeBytes": 212 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " files", - "totalResponseSizeBytes": 117 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 216 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494032, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": " to", - "totalResponseSizeBytes": 120 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 13, + "deltaPreview": " instructions", + "totalResponseSizeBytes": 229 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": " help", - "totalResponseSizeBytes": 125 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 233 } }, { - "timestampMs": 1770182492172, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 3, - "deltaPreview": " AI", - "totalResponseSizeBytes": 128 + "deltaPreview": " VS", + "totalResponseSizeBytes": 236 } }, { - "timestampMs": 1770182492287, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 7, - "deltaPreview": " coding", - "totalResponseSizeBytes": 135 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 241 } }, { - "timestampMs": 1770182492287, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 11, - "deltaPreview": " assistants", - "totalResponseSizeBytes": 146 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 250 } }, { - "timestampMs": 1770182492287, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 11, - "deltaPreview": " understand", - "totalResponseSizeBytes": 157 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 251 } }, { - "timestampMs": 1770182492287, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 9, - "deltaPreview": " projects", - "totalResponseSizeBytes": 166 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 6, + "deltaPreview": " autom", + "totalResponseSizeBytes": 257 } }, { - "timestampMs": 1770182492288, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 7, - "deltaPreview": " better", - "totalResponseSizeBytes": 173 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": "ating", + "totalResponseSizeBytes": 262 } }, { - "timestampMs": 1770182492288, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ".", - "totalResponseSizeBytes": 174 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 266 } }, { - "timestampMs": 1770182492288, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 3, - "deltaPreview": " It", - "totalResponseSizeBytes": 177 + "deltaPreview": "Hub", + "totalResponseSizeBytes": 269 } }, { - "timestampMs": 1770182492288, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 9, - "deltaPreview": " supports", - "totalResponseSizeBytes": 186 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 10, + "deltaPreview": " workflows", + "totalResponseSizeBytes": 279 } }, { - "timestampMs": 1770182492288, + "timestampMs": 1770183494172, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 11, - "deltaPreview": " repository", - "totalResponseSizeBytes": 197 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": " (", + "totalResponseSizeBytes": 281 } }, { - "timestampMs": 1770182492288, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 9, - "deltaPreview": " analysis", - "totalResponseSizeBytes": 206 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": "clone", + "totalResponseSizeBytes": 286 } }, { - "timestampMs": 1770182492404, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 207 + "deltaPreview": "/", + "totalResponseSizeBytes": 287 } }, { - "timestampMs": 1770182492404, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": " AI", - "totalResponseSizeBytes": 210 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 6, + "deltaPreview": "branch", + "totalResponseSizeBytes": 293 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 8, - "deltaPreview": "-powered", - "totalResponseSizeBytes": 218 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 294 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 12, - "deltaPreview": " instruction", - "totalResponseSizeBytes": 230 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": "PR", + "totalResponseSizeBytes": 296 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 11, - "deltaPreview": " generation", - "totalResponseSizeBytes": 241 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": "),", + "totalResponseSizeBytes": 298 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 242 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 302 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " batch", - "totalResponseSizeBytes": 248 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 10, + "deltaPreview": " providing", + "totalResponseSizeBytes": 312 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 11, - "deltaPreview": " processing", - "totalResponseSizeBytes": 259 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": " an", + "totalResponseSizeBytes": 315 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494173, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 260 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 12, + "deltaPreview": " interactive", + "totalResponseSizeBytes": 327 } }, { - "timestampMs": 1770182492405, + "timestampMs": 1770183494323, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 11, - "deltaPreview": " evaluation", - "totalResponseSizeBytes": 271 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": " T", + "totalResponseSizeBytes": 329 } }, { - "timestampMs": 1770182492567, + "timestampMs": 1770183494323, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 272 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": "UI", + "totalResponseSizeBytes": 331 } }, { - "timestampMs": 1770182492567, + "timestampMs": 1770183494323, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 10, - "deltaPreview": " readiness", - "totalResponseSizeBytes": 282 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 332 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 8, - "deltaPreview": " reports", - "totalResponseSizeBytes": 290 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": " It", + "totalResponseSizeBytes": 335 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 291 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 338 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 295 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 9, + "deltaPreview": " designed", + "totalResponseSizeBytes": 347 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 4, - "deltaPreview": " Git", - "totalResponseSizeBytes": 299 + "deltaPreview": " for", + "totalResponseSizeBytes": 351 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": "Hub", - "totalResponseSizeBytes": 302 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": " E", + "totalResponseSizeBytes": 353 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 12, - "deltaPreview": " integration", - "totalResponseSizeBytes": 314 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": "SM", + "totalResponseSizeBytes": 355 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": ".\n\n", - "totalResponseSizeBytes": 317 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 356 } }, { - "timestampMs": 1770182492568, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": "Main", - "totalResponseSizeBytes": 321 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 6, + "deltaPreview": "strict", + "totalResponseSizeBytes": 362 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " entry", - "totalResponseSizeBytes": 327 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " Type", + "totalResponseSizeBytes": 367 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 6, - "deltaPreview": "points", - "totalResponseSizeBytes": 333 + "deltaPreview": "Script", + "totalResponseSizeBytes": 373 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": ":\n", - "totalResponseSizeBytes": 335 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 374 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": "-", - "totalResponseSizeBytes": 336 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " uses", + "totalResponseSizeBytes": 379 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": " src", - "totalResponseSizeBytes": 340 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 10, + "deltaPreview": " Commander", + "totalResponseSizeBytes": 389 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "/index", - "totalResponseSizeBytes": 346 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 393 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": ".ts", - "totalResponseSizeBytes": 349 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 397 } }, { - "timestampMs": 1770182492747, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " —", - "totalResponseSizeBytes": 353 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 398 } }, { - "timestampMs": 1770182492748, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 357 + "deltaPreview": " Ink", + "totalResponseSizeBytes": 402 } }, { - "timestampMs": 1770182492748, + "timestampMs": 1770183494324, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " entry", - "totalResponseSizeBytes": 363 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 403 } }, { - "timestampMs": 1770182492818, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " point", - "totalResponseSizeBytes": 369 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": "React", + "totalResponseSizeBytes": 408 } }, { - "timestampMs": 1770182492818, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": "\n", - "totalResponseSizeBytes": 370 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 412 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": "-", - "totalResponseSizeBytes": 371 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": " T", + "totalResponseSizeBytes": 414 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": " src", - "totalResponseSizeBytes": 375 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 2, + "deltaPreview": "UI", + "totalResponseSizeBytes": 416 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 1, - "deltaPreview": "/", - "totalResponseSizeBytes": 376 + "deltaPreview": ",", + "totalResponseSizeBytes": 417 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": "cli", - "totalResponseSizeBytes": 379 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 421 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 3, - "deltaPreview": ".ts", - "totalResponseSizeBytes": 382 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 11, + "deltaPreview": " integrates", + "totalResponseSizeBytes": 432 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " —", - "totalResponseSizeBytes": 386 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 437 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 10, - "deltaPreview": " Commander", - "totalResponseSizeBytes": 396 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " Cop", + "totalResponseSizeBytes": 441 } }, { - "timestampMs": 1770182492819, + "timestampMs": 1770183494464, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 400 + "deltaPreview": "ilot", + "totalResponseSizeBytes": 445 } }, { - "timestampMs": 1770182492924, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " setup", - "totalResponseSizeBytes": 406 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 449 } }, { - "timestampMs": 1770182492924, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "\n\n", - "totalResponseSizeBytes": 408 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 453 } }, { - "timestampMs": 1770182492927, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 3, - "deltaPreview": "Key", - "totalResponseSizeBytes": 411 + "deltaPreview": "Hub", + "totalResponseSizeBytes": 456 } }, { - "timestampMs": 1770182492927, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 9, - "deltaPreview": " commands", - "totalResponseSizeBytes": 420 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 460 } }, { - "timestampMs": 1770182492927, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 8, - "deltaPreview": " include", - "totalResponseSizeBytes": 428 - } - }, - { - "timestampMs": 1770182492927, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 1, - "deltaPreview": ":", - "totalResponseSizeBytes": 429 - } - }, - { - "timestampMs": 1770182492927, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 431 - } - }, - { - "timestampMs": 1770182492927, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 437 - } - }, - { - "timestampMs": 1770182492927, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": " init", - "totalResponseSizeBytes": 442 - } - }, - { - "timestampMs": 1770182492927, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 444 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 446 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 452 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 4, - "deltaPreview": " tui", - "totalResponseSizeBytes": 456 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 458 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 460 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 466 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 13, - "deltaPreview": " instructions", - "totalResponseSizeBytes": 479 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 481 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 483 - } - }, - { - "timestampMs": 1770182492962, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 489 - } - }, - { - "timestampMs": 1770182493032, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 8, - "deltaPreview": " analyze", - "totalResponseSizeBytes": 497 - } - }, - { - "timestampMs": 1770182493032, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 499 - } - }, - { - "timestampMs": 1770182493032, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 501 - } - }, - { - "timestampMs": 1770182493032, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 507 - } - }, - { - "timestampMs": 1770182493032, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": " batch", - "totalResponseSizeBytes": 513 - } - }, - { - "timestampMs": 1770182493032, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 515 - } - }, - { - "timestampMs": 1770182493033, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 517 - } - }, - { - "timestampMs": 1770182493033, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 523 - } - }, - { - "timestampMs": 1770182493033, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 10, - "deltaPreview": " readiness", - "totalResponseSizeBytes": 533 - } - }, - { - "timestampMs": 1770182493033, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 535 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 11, + "deltaPreview": " automation", + "totalResponseSizeBytes": 471 } }, { - "timestampMs": 1770182493106, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", "deltaChars": 4, "deltaPreview": " and", - "totalResponseSizeBytes": 539 - } - }, - { - "timestampMs": 1770182493106, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 541 - } - }, - { - "timestampMs": 1770182493106, - "phase": "withoutInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 547 + "totalResponseSizeBytes": 475 } }, { - "timestampMs": 1770182493106, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 5, - "deltaPreview": " eval", - "totalResponseSizeBytes": 552 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 486 } }, { - "timestampMs": 1770182493106, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "deltaChars": 2, - "deltaPreview": "`.", - "totalResponseSizeBytes": 554 + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 487 } }, { - "timestampMs": 1770182493106, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.usage", "data": { "model": "gpt-4.1", - "inputTokens": 10005, - "outputTokens": 114, - "cacheReadTokens": 9088, + "inputTokens": 12602, + "outputTokens": 98, + "cacheReadTokens": 9856, "cacheWriteTokens": 0, "cost": 0, - "duration": 2219, + "duration": 1366, "initiator": "agent", - "apiCallId": "chatcmpl-D5PcRI6T4ILfUtZDNyDGjcQAeURGc", - "providerCallId": "E903:35A03D:33FAB6:3DB199:6982D75A", + "apiCallId": "chatcmpl-D5PsbzZBK3OPKNyoECnazAxf9UHku", + "providerCallId": "EEC8:177A35:7016EF:840736:6982DB45", "quotaSnapshots": { "chat": { "isUnlimitedEntitlement": true, @@ -1835,17 +1357,17 @@ } }, { - "timestampMs": 1770182493107, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.message", "data": { - "messageId": "4ff91b27-59f2-4757-a441-57cad2001acc", - "content": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.", + "messageId": "58370827-c0a0-4a5b-86b0-73ebaacd08a9", + "content": "The Primer CLI tool is a TypeScript-based CLI for priming repositories for AI-assisted development and evaluation. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone/branch/PR), and providing an interactive TUI. It is designed for ESM/strict TypeScript, uses Commander for CLI, Ink/React for TUI, and integrates with Copilot and GitHub for automation and evaluation.", "toolRequests": [] } }, { - "timestampMs": 1770182493107, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "assistant.turn_end", "data": { @@ -1853,35 +1375,35 @@ } }, { - "timestampMs": 1770182493107, + "timestampMs": 1770183494465, "phase": "withoutInstructions", "type": "session.idle", "data": {} }, { - "timestampMs": 1770182493132, + "timestampMs": 1770183494487, "phase": "withInstructions", "type": "pending_messages.modified", "data": {} }, { - "timestampMs": 1770182493132, + "timestampMs": 1770183494487, "phase": "withInstructions", "type": "pending_messages.modified", "data": {} }, { - "timestampMs": 1770182493866, + "timestampMs": 1770183495193, "phase": "withInstructions", "type": "user.message", "data": { - "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", - "transformedContent": "2026-02-04T05:21:33.829Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nSummarize what this application does and list the main entrypoints.", + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhat is the main purpose of the Primer CLI tool and what are its key features?", + "transformedContent": "2026-02-04T05:38:15.153Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhat is the main purpose of the Primer CLI tool and what are its key features?", "attachments": [] } }, { - "timestampMs": 1770182493867, + "timestampMs": 1770183495193, "phase": "withInstructions", "type": "assistant.turn_start", "data": { @@ -1889,30 +1411,30 @@ } }, { - "timestampMs": 1770182493867, + "timestampMs": 1770183495193, "phase": "withInstructions", "type": "session.usage_info", "data": { "tokenLimit": 64000, - "currentTokens": 11015, + "currentTokens": 11310, "messagesLength": 2 } }, { - "timestampMs": 1770182495951, + "timestampMs": 1770183496821, "phase": "withInstructions", "type": "assistant.usage", "data": { "model": "gpt-4.1", - "inputTokens": 10382, - "outputTokens": 94, - "cacheReadTokens": 9984, + "inputTokens": 10677, + "outputTokens": 15, + "cacheReadTokens": 0, "cacheWriteTokens": 0, "cost": 0, - "duration": 2080, + "duration": 1628, "initiator": "user", - "apiCallId": "chatcmpl-D5PcUtFiguAzEPDeiBTxJYeehvIh9", - "providerCallId": "E903:35A03D:340477:3DBCDB:6982D75D", + "apiCallId": "chatcmpl-D5PsdXXf8TXVsE9J7gwq3IK6hIN3T", + "providerCallId": "EEC8:177A35:701CC6:840DF8:6982DB47", "quotaSnapshots": { "chat": { "isUnlimitedEntitlement": true, @@ -1958,110 +1480,4813 @@ } }, { - "timestampMs": 1770182495951, + "timestampMs": 1770183496821, "phase": "withInstructions", "type": "assistant.message", "data": { - "messageId": "fa934988-cc62-4c45-8c26-b19e0fb419f0", + "messageId": "8f252ef5-b37e-44cb-8225-6b3a8ba2aedb", "content": "", "toolRequests": [ { - "toolCallId": "call_gQKcwh4lrRf8iHebDhI7mxBH", - "name": "report_intent", - "arguments": { - "intent": "Summarizing application purpose" - }, - "type": "function" - }, - { - "toolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "name": "task", - "arguments": { - "agent_type": "explore", - "description": "Summarizing app and entrypoints", - "prompt": "Summarize what this application does and list the main entrypoints. Be concise. List the main CLI commands or programmatic entrypoints if present." - }, + "toolCallId": "call_fge4ooiF8Y28j2OmwsFlyRxC", + "name": "fetch_copilot_cli_documentation", + "arguments": {}, "type": "function" } ] } }, { - "timestampMs": 1770182495951, - "phase": "withInstructions", - "type": "tool.execution_start", - "data": { - "toolCallId": "call_gQKcwh4lrRf8iHebDhI7mxBH", - "toolName": "report_intent", - "arguments": { - "intent": "Summarizing application purpose" - } - } - }, - { - "timestampMs": 1770182495951, + "timestampMs": 1770183496821, "phase": "withInstructions", "type": "tool.execution_start", "data": { - "toolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolName": "task", - "arguments": { - "agent_type": "explore", - "description": "Summarizing app and entrypoints", - "prompt": "Summarize what this application does and list the main entrypoints. Be concise. List the main CLI commands or programmatic entrypoints if present." - } + "toolCallId": "call_fge4ooiF8Y28j2OmwsFlyRxC", + "toolName": "fetch_copilot_cli_documentation", + "arguments": {} } }, { - "timestampMs": 1770182495951, + "timestampMs": 1770183496852, "phase": "withInstructions", "type": "tool.execution_complete", "data": { - "toolCallId": "call_gQKcwh4lrRf8iHebDhI7mxBH", + "toolCallId": "call_fge4ooiF8Y28j2OmwsFlyRxC", "success": true, "result": { - "content": "Intent logged", - "detailedContent": "Summarizing application purpose" + "content": "# GitHub Copilot CLI Documentation\n\n## README\n# GitHub Copilot CLI (Public Preview)\n\nThe power of GitHub Copilot, now in your terminal.\n\nGitHub Copilot CLI brings AI-powered coding assistance directly to your command line, enabling you to build, debug, and understand code through natural language conversations. Powered by the same agentic harness as GitHub's Copilot coding agent, it provides intelligent assistance while staying deeply integrated with your GitHub workflow.\n\nSee [our official documentation](https://docs.github.com/copilot/concepts/agents/about-copilot-cli) for more information.\n\n![Image of the splash screen for the Copilot CLI](https://github.com/user-attachments/assets/f40aa23d-09dd-499e-9457-1d57d3368887)\n\n\n## 🚀 Introduction and Overview\n\nWe're bringing the power of GitHub Copilot coding agent directly to your terminal. With GitHub Copilot CLI, you can work locally and synchronously with an AI agent that understands your code and GitHub context.\n\n- **Terminal-native development:** Work with Copilot coding agent directly in your command line — no context switching required.\n- **GitHub integration out of the box:** Access your repositories, issues, and pull requests using natural language, all authenticated with your existing GitHub account.\n- **Agentic capabilities:** Build, edit, debug, and refactor code with an AI collaborator that can plan and execute complex tasks.\n- **MCP-powered extensibility:** Take advantage of the fact that the coding agent ships with GitHub's MCP server by default and supports custom MCP servers to extend capabilities.\n- **Full control:** Preview every action before execution — nothing happens without your explicit approval.\n\nWe're still early in our journey, but with your feedback, we're rapidly iterating to make the GitHub Copilot CLI the best possible companion in your terminal.\n\n## 📦 Getting Started\n\n### Supported Platforms\n\n- **Linux**\n- **macOS**\n- **Windows**\n\n### Prerequisites\n\n- (On Windows) **PowerShell** v6 or …", + "detailedContent": "Fetched CLI documentation" }, "toolTelemetry": {} } }, { - "timestampMs": 1770182499225, + "timestampMs": 1770183496852, "phase": "withInstructions", - "type": "assistant.usage", + "type": "assistant.turn_end", "data": { - "model": "claude-haiku-4.5", - "inputTokens": 2713, - "outputTokens": 335, - "cacheReadTokens": 0, - "cacheWriteTokens": 0, - "cost": 0.33, - "duration": 2960, - "initiator": "sub-agent", - "apiCallId": "msg_017fmNqNjPGntbszM5ineEJx", - "providerCallId": "E903:35A03D:340C7D:3DC60F:6982D760", - "quotaSnapshots": { - "chat": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "completions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, + "turnId": "0" + } + }, + { + "timestampMs": 1770183496852, + "phase": "withInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770183496852, + "phase": "withInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 14044, + "messagesLength": 4 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": "The", + "totalResponseSizeBytes": 3 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " main", + "totalResponseSizeBytes": 8 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 8, + "deltaPreview": " purpose", + "totalResponseSizeBytes": 16 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " of", + "totalResponseSizeBytes": 19 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 23 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 30 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 34 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " tool", + "totalResponseSizeBytes": 39 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 42 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 45 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 6, + "deltaPreview": " prime", + "totalResponseSizeBytes": 51 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 13, + "deltaPreview": " repositories", + "totalResponseSizeBytes": 64 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 68 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " AI", + "totalResponseSizeBytes": 71 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 9, + "deltaPreview": "-assisted", + "totalResponseSizeBytes": 80 + } + }, + { + "timestampMs": 1770183497985, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 12, + "deltaPreview": " development", + "totalResponseSizeBytes": 92 + } + }, + { + "timestampMs": 1770183498282, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 96 + } + }, + { + "timestampMs": 1770183498282, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 107 + } + }, + { + "timestampMs": 1770183498282, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 108 + } + }, + { + "timestampMs": 1770183498282, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " especially", + "totalResponseSizeBytes": 119 + } + }, + { + "timestampMs": 1770183498282, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 123 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " use", + "totalResponseSizeBytes": 127 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 132 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 136 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 139 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Cop", + "totalResponseSizeBytes": 143 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 147 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 151 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 8, + "deltaPreview": " similar", + "totalResponseSizeBytes": 159 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 7, + "deltaPreview": " agents", + "totalResponseSizeBytes": 166 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 167 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Its", + "totalResponseSizeBytes": 171 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " key", + "totalResponseSizeBytes": 175 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 9, + "deltaPreview": " features", + "totalResponseSizeBytes": 184 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 8, + "deltaPreview": " include", + "totalResponseSizeBytes": 192 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 10, + "deltaPreview": " analyzing", + "totalResponseSizeBytes": 202 + } + }, + { + "timestampMs": 1770183498283, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 13, + "deltaPreview": " repositories", + "totalResponseSizeBytes": 215 + } + }, + { + "timestampMs": 1770183498428, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 218 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 6, + "deltaPreview": " infer", + "totalResponseSizeBytes": 224 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 10, + "deltaPreview": " languages", + "totalResponseSizeBytes": 234 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 238 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " frameworks", + "totalResponseSizeBytes": 249 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 250 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " generating", + "totalResponseSizeBytes": 261 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Cop", + "totalResponseSizeBytes": 265 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 269 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 13, + "deltaPreview": " instructions", + "totalResponseSizeBytes": 282 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 286 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " VS", + "totalResponseSizeBytes": 289 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 294 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 303 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 304 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 6, + "deltaPreview": " autom", + "totalResponseSizeBytes": 310 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": "ating", + "totalResponseSizeBytes": 315 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 319 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 322 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 10, + "deltaPreview": " workflows", + "totalResponseSizeBytes": 332 + } + }, + { + "timestampMs": 1770183498429, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 2, + "deltaPreview": " (", + "totalResponseSizeBytes": 334 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": "clone", + "totalResponseSizeBytes": 339 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 340 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 7, + "deltaPreview": " branch", + "totalResponseSizeBytes": 347 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 348 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " PR", + "totalResponseSizeBytes": 351 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 2, + "deltaPreview": "),", + "totalResponseSizeBytes": 353 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 357 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " evaluating", + "totalResponseSizeBytes": 368 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 6, + "deltaPreview": " agent", + "totalResponseSizeBytes": 374 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 10, + "deltaPreview": " responses", + "totalResponseSizeBytes": 384 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 389 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 390 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 7, + "deltaPreview": "without", + "totalResponseSizeBytes": 397 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 13, + "deltaPreview": " instructions", + "totalResponseSizeBytes": 410 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 411 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": " It", + "totalResponseSizeBytes": 414 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " uses", + "totalResponseSizeBytes": 419 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " Type", + "totalResponseSizeBytes": 424 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 6, + "deltaPreview": "Script", + "totalResponseSizeBytes": 430 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 431 + } + }, + { + "timestampMs": 1770183498591, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 10, + "deltaPreview": " Commander", + "totalResponseSizeBytes": 441 + } + }, + { + "timestampMs": 1770183498937, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 445 + } + }, + { + "timestampMs": 1770183498937, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 449 + } + }, + { + "timestampMs": 1770183498937, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 450 + } + }, + { + "timestampMs": 1770183498937, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Ink", + "totalResponseSizeBytes": 454 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 455 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": "React", + "totalResponseSizeBytes": 460 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 464 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 2, + "deltaPreview": " T", + "totalResponseSizeBytes": 466 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 2, + "deltaPreview": "UI", + "totalResponseSizeBytes": 468 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 469 + } + }, + { + "timestampMs": 1770183498941, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 473 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " integrates", + "totalResponseSizeBytes": 484 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 8, + "deltaPreview": " tightly", + "totalResponseSizeBytes": 492 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 497 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Cop", + "totalResponseSizeBytes": 501 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": "ilot", + "totalResponseSizeBytes": 505 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 509 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 513 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 516 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 11, + "deltaPreview": " automation", + "totalResponseSizeBytes": 527 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 528 + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 13420, + "outputTokens": 101, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 2090, + "initiator": "agent", + "apiCallId": "chatcmpl-D5Psf6vuQCGSvrdcTADGNeKRGib5T", + "providerCallId": "EEC8:177A35:702225:841435:6982DB48", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "messageId": "d9bf556a-5048-44b1-9a82-c451005ab990", + "content": "The main purpose of the Primer CLI tool is to prime repositories for AI-assisted development and evaluation, especially for use with GitHub Copilot and similar agents. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone, branch, PR), and evaluating agent responses with/without instructions. It uses TypeScript, Commander for CLI, Ink/React for TUI, and integrates tightly with Copilot and GitHub automation.", + "toolRequests": [] + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770183498942, + "phase": "withInstructions", + "type": "session.idle", + "data": {} + }, + { + "timestampMs": 1770183498961, + "phase": "judge", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183498961, + "phase": "judge", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183499607, + "phase": "judge", + "type": "user.message", + "data": { + "content": "Evaluate which response best matches the expectation.\n\nExpectation: Primer is a CLI tool that analyzes codebases and generates .github/copilot-instructions.md files to help AI coding assistants understand projects better. Key features include repository analysis, AI-powered instruction generation, batch processing, an evaluation framework, readiness reports, GitHub integration, an interactive TUI, and config generation.\n\nResponse A (without custom instructions):\nThe Primer CLI tool is a TypeScript-based CLI for priming repositories for AI-assisted development and evaluation. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone/branch/PR), and providing an interactive TUI. It is designed for ESM/strict TypeScript, uses Commander for CLI, Ink/React for TUI, and integrates with Copilot and GitHub for automation and evaluation.\n\nResponse B (with custom instructions):\nThe main purpose of the Primer CLI tool is to prime repositories for AI-assisted development and evaluation, especially for use with GitHub Copilot and similar agents. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone, branch, PR), and evaluating agent responses with/without instructions. It uses TypeScript, Commander for CLI, Ink/React for TUI, and integrates tightly with Copilot and GitHub automation.\n\nReturn JSON only.", + "transformedContent": "2026-02-04T05:38:19.581Z\n\nEvaluate which response best matches the expectation.\n\nExpectation: Primer is a CLI tool that analyzes codebases and generates .github/copilot-instructions.md files to help AI coding assistants understand projects better. Key features include repository analysis, AI-powered instruction generation, batch processing, an evaluation framework, readiness reports, GitHub integration, an interactive TUI, and config generation.\n\nResponse A (without custom instructions):\nThe Primer CLI tool is a TypeScript-based CLI for priming repositories for AI-assisted development and evaluation. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone/branch/PR), and providing an interactive TUI. It is designed for ESM/strict TypeScript, uses Commander for CLI, Ink/React for TUI, and integrates with Copilot and GitHub for automation and evaluation.\n\nResponse B (with custom instructions):\nThe main purpose of the Primer CLI tool is to prime repositories for AI-assisted development and evaluation, especially for use with GitHub Copilot and similar agents. Its key features include analyzing repositories to infer languages and frameworks, generating Copilot instructions and VS Code settings, automating GitHub workflows (clone, branch, PR), and evaluating agent responses with/without instructions. It uses TypeScript, Commander for CLI, Ink/React for TUI, and integrates tightly with Copilot and GitHub automation.\n\nReturn JSON only.", + "attachments": [] + } + }, + { + "timestampMs": 1770183499607, + "phase": "judge", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183499608, + "phase": "judge", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 10766, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": "{\"", + "totalResponseSizeBytes": 2 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": "ver", + "totalResponseSizeBytes": 5 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": "dict", + "totalResponseSizeBytes": 9 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 11 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 13 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": "pass", + "totalResponseSizeBytes": 17 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": "\",", + "totalResponseSizeBytes": 19 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 21 + } + }, + { + "timestampMs": 1770183500658, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 5, + "deltaPreview": "score", + "totalResponseSizeBytes": 26 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 28 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 29 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": "95", + "totalResponseSizeBytes": 31 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 32 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 34 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": "r", + "totalResponseSizeBytes": 35 + } + }, + { + "timestampMs": 1770183500659, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 8, + "deltaPreview": "ationale", + "totalResponseSizeBytes": 43 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 45 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 47 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 8, + "deltaPreview": "Response", + "totalResponseSizeBytes": 55 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": " B", + "totalResponseSizeBytes": 57 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 5, + "deltaPreview": " best", + "totalResponseSizeBytes": 62 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 8, + "deltaPreview": " matches", + "totalResponseSizeBytes": 70 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 74 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 86 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 87 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": " It", + "totalResponseSizeBytes": 90 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 7, + "deltaPreview": " covers", + "totalResponseSizeBytes": 97 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " all", + "totalResponseSizeBytes": 101 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " key", + "totalResponseSizeBytes": 105 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 9, + "deltaPreview": " features", + "totalResponseSizeBytes": 114 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 115 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 126 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 9, + "deltaPreview": " analysis", + "totalResponseSizeBytes": 135 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 136 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 12, + "deltaPreview": " instruction", + "totalResponseSizeBytes": 148 + } + }, + { + "timestampMs": 1770183500828, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 11, + "deltaPreview": " generation", + "totalResponseSizeBytes": 159 + } + }, + { + "timestampMs": 1770183500829, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 160 + } + }, + { + "timestampMs": 1770183501044, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 7, + "deltaPreview": " config", + "totalResponseSizeBytes": 167 + } + }, + { + "timestampMs": 1770183501044, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 11, + "deltaPreview": " generation", + "totalResponseSizeBytes": 178 + } + }, + { + "timestampMs": 1770183501044, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 179 + } + }, + { + "timestampMs": 1770183501044, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " Git", + "totalResponseSizeBytes": 183 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": "Hub", + "totalResponseSizeBytes": 186 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 11, + "deltaPreview": " automation", + "totalResponseSizeBytes": 197 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 198 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 202 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 213 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 10, + "deltaPreview": " framework", + "totalResponseSizeBytes": 223 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 224 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 9, + "deltaPreview": " Response", + "totalResponseSizeBytes": 233 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": " A", + "totalResponseSizeBytes": 235 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 238 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 5, + "deltaPreview": " also", + "totalResponseSizeBytes": 243 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 9, + "deltaPreview": " accurate", + "totalResponseSizeBytes": 252 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " but", + "totalResponseSizeBytes": 256 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": " om", + "totalResponseSizeBytes": 259 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": "its", + "totalResponseSizeBytes": 262 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 9, + "deltaPreview": " explicit", + "totalResponseSizeBytes": 271 + } + }, + { + "timestampMs": 1770183501045, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 8, + "deltaPreview": " mention", + "totalResponseSizeBytes": 279 + } + }, + { + "timestampMs": 1770183501168, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": " of", + "totalResponseSizeBytes": 282 + } + }, + { + "timestampMs": 1770183501168, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 286 + } + }, + { + "timestampMs": 1770183501168, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 11, + "deltaPreview": " evaluation", + "totalResponseSizeBytes": 297 + } + }, + { + "timestampMs": 1770183501168, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 10, + "deltaPreview": " framework", + "totalResponseSizeBytes": 307 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 311 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 10, + "deltaPreview": " readiness", + "totalResponseSizeBytes": 321 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 8, + "deltaPreview": " reports", + "totalResponseSizeBytes": 329 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 330 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 6, + "deltaPreview": " which", + "totalResponseSizeBytes": 336 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " are", + "totalResponseSizeBytes": 340 + } + }, + { + "timestampMs": 1770183501169, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 8, + "deltaPreview": " present", + "totalResponseSizeBytes": 348 + } + }, + { + "timestampMs": 1770183501170, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 351 + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 355 + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 367 + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 2, + "deltaPreview": ".\"", + "totalResponseSizeBytes": 369 + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "deltaChars": 1, + "deltaPreview": "}", + "totalResponseSizeBytes": 370 + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 10133, + "outputTokens": 75, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 1563, + "initiator": "user", + "apiCallId": "chatcmpl-D5PshX1lJ8uHcLqAdNFcoSYvs6GF2", + "providerCallId": "EEC8:177A35:702AFF:841E35:6982DB4B", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.message", + "data": { + "messageId": "63ed28dc-2e03-4578-a990-c89be4fcb0f7", + "content": "{\"verdict\": \"pass\", \"score\": 95, \"rationale\": \"Response B best matches the expectation. It covers all key features: repository analysis, instruction generation, config generation, GitHub automation, and evaluation framework. Response A is also accurate but omits explicit mention of the evaluation framework and readiness reports, which are present in the expectation.\"}", + "toolRequests": [] + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "assistant.turn_end", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183501171, + "phase": "judge", + "type": "session.idle", + "data": {} + } + ] + }, + { + "id": "case-2", + "prompt": "How do you run the Primer CLI locally to analyze a repository and generate VS Code settings?", + "expectation": "To analyze a repository, run `npx tsx src/index.ts analyze [path] --json`. To generate VS Code settings, run `npx tsx src/index.ts generate vscode [path] [--force]`.", + "withInstructions": "To run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze a repository: \n `npx tsx src/index.ts analyze [path] --json`\n\n2. Generate VS Code settings: \n `npx tsx src/index.ts generate vscode [path] [--force]`\n\nReplace `[path]` with your target repo path. No build step is required; just run these commands from the project root.", + "withoutInstructions": "To run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze the repository:\n ```\n npx tsx src/index.ts analyze [path] --json\n ```\n2. Generate VS Code settings:\n ```\n npx tsx src/index.ts generate vscode [path] [--force]\n ```\nReplace `[path]` with your target repository path. Use `--force` to overwrite existing settings if needed.", + "verdict": "pass", + "score": 100, + "rationale": "Both responses accurately match the expectation by providing the correct commands for analyzing a repository and generating VS Code settings. Response B is slightly better as it adds the helpful clarification that no build step is required and to run the commands from the project root, which aligns with the custom instructions. Therefore, Response B best matches the expectation.", + "metrics": { + "withoutInstructions": { + "durationMs": 3289, + "tokenUsage": { + "promptTokens": 12603, + "completionTokens": 97, + "totalTokens": 12700 + }, + "toolCalls": { + "count": 1, + "byName": { + "fetch_copilot_cli_documentation": 1 + }, + "totalDurationMs": 0 + } + }, + "withInstructions": { + "durationMs": 2813, + "tokenUsage": { + "promptTokens": 13421, + "completionTokens": 97, + "totalTokens": 13518 + }, + "toolCalls": { + "count": 1, + "byName": { + "fetch_copilot_cli_documentation": 1 + }, + "totalDurationMs": 0 + } + }, + "judge": { + "durationMs": 1822, + "tokenUsage": { + "promptTokens": 10112, + "completionTokens": 84, + "totalTokens": 10196 + }, + "toolCalls": { + "count": 0, + "byName": {}, + "totalDurationMs": 0 + } + }, + "totalDurationMs": 7977 + }, + "trajectory": [ + { + "timestampMs": 1770183501190, + "phase": "withoutInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183501190, + "phase": "withoutInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183501848, + "phase": "withoutInstructions", + "type": "user.message", + "data": { + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nHow do you run the Primer CLI locally to analyze a repository and generate VS Code settings?", + "transformedContent": "2026-02-04T05:38:21.819Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nHow do you run the Primer CLI locally to analyze a repository and generate VS Code settings?", + "attachments": [] + } + }, + { + "timestampMs": 1770183501848, + "phase": "withoutInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183501848, + "phase": "withoutInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 10493, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770183502957, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 9860, + "outputTokens": 15, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 1109, + "initiator": "user", + "apiCallId": "chatcmpl-D5PskDSy8z6soSsOeNEg4kCMPiYc1", + "providerCallId": "EEC8:177A35:70323F:8426B5:6982DB4D", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770183502957, + "phase": "withoutInstructions", + "type": "assistant.message", + "data": { + "messageId": "93cbbe16-a12a-41e9-a269-5c3bca6a6455", + "content": "", + "toolRequests": [ + { + "toolCallId": "call_7q4HHCZijMSTe83IliMRnQZz", + "name": "fetch_copilot_cli_documentation", + "arguments": {}, + "type": "function" + } + ] + } + }, + { + "timestampMs": 1770183502957, + "phase": "withoutInstructions", + "type": "tool.execution_start", + "data": { + "toolCallId": "call_7q4HHCZijMSTe83IliMRnQZz", + "toolName": "fetch_copilot_cli_documentation", + "arguments": {} + } + }, + { + "timestampMs": 1770183502992, + "phase": "withoutInstructions", + "type": "tool.execution_complete", + "data": { + "toolCallId": "call_7q4HHCZijMSTe83IliMRnQZz", + "success": true, + "result": { + "content": "# GitHub Copilot CLI Documentation\n\n## README\n# GitHub Copilot CLI (Public Preview)\n\nThe power of GitHub Copilot, now in your terminal.\n\nGitHub Copilot CLI brings AI-powered coding assistance directly to your command line, enabling you to build, debug, and understand code through natural language conversations. Powered by the same agentic harness as GitHub's Copilot coding agent, it provides intelligent assistance while staying deeply integrated with your GitHub workflow.\n\nSee [our official documentation](https://docs.github.com/copilot/concepts/agents/about-copilot-cli) for more information.\n\n![Image of the splash screen for the Copilot CLI](https://github.com/user-attachments/assets/f40aa23d-09dd-499e-9457-1d57d3368887)\n\n\n## 🚀 Introduction and Overview\n\nWe're bringing the power of GitHub Copilot coding agent directly to your terminal. With GitHub Copilot CLI, you can work locally and synchronously with an AI agent that understands your code and GitHub context.\n\n- **Terminal-native development:** Work with Copilot coding agent directly in your command line — no context switching required.\n- **GitHub integration out of the box:** Access your repositories, issues, and pull requests using natural language, all authenticated with your existing GitHub account.\n- **Agentic capabilities:** Build, edit, debug, and refactor code with an AI collaborator that can plan and execute complex tasks.\n- **MCP-powered extensibility:** Take advantage of the fact that the coding agent ships with GitHub's MCP server by default and supports custom MCP servers to extend capabilities.\n- **Full control:** Preview every action before execution — nothing happens without your explicit approval.\n\nWe're still early in our journey, but with your feedback, we're rapidly iterating to make the GitHub Copilot CLI the best possible companion in your terminal.\n\n## 📦 Getting Started\n\n### Supported Platforms\n\n- **Linux**\n- **macOS**\n- **Windows**\n\n### Prerequisites\n\n- (On Windows) **PowerShell** v6 or …", + "detailedContent": "Fetched CLI documentation" + }, + "toolTelemetry": {} + } + }, + { + "timestampMs": 1770183502992, + "phase": "withoutInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183502992, + "phase": "withoutInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770183502992, + "phase": "withoutInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 13227, + "messagesLength": 4 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": "To", + "totalResponseSizeBytes": 2 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " run", + "totalResponseSizeBytes": 6 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 10 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 17 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 21 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 8, + "deltaPreview": " locally", + "totalResponseSizeBytes": 29 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 33 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 10, + "deltaPreview": " analyzing", + "totalResponseSizeBytes": 43 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 45 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 56 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 60 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 11, + "deltaPreview": " generating", + "totalResponseSizeBytes": 71 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " VS", + "totalResponseSizeBytes": 74 + } + }, + { + "timestampMs": 1770183504069, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 79 + } + }, + { + "timestampMs": 1770183504070, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 88 + } + }, + { + "timestampMs": 1770183504070, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 89 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " use", + "totalResponseSizeBytes": 93 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 6, + "deltaPreview": " these", + "totalResponseSizeBytes": 99 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 108 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": ":\n\n", + "totalResponseSizeBytes": 111 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "1", + "totalResponseSizeBytes": 112 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 113 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 8, + "deltaPreview": " Analyze", + "totalResponseSizeBytes": 121 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 125 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 136 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": ":\n", + "totalResponseSizeBytes": 138 + } + }, + { + "timestampMs": 1770183504177, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 140 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " ```\n", + "totalResponseSizeBytes": 145 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 147 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " n", + "totalResponseSizeBytes": 149 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": "px", + "totalResponseSizeBytes": 151 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " ts", + "totalResponseSizeBytes": 154 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "x", + "totalResponseSizeBytes": 155 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 159 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 165 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 168 + } + }, + { + "timestampMs": 1770183504178, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 8, + "deltaPreview": " analyze", + "totalResponseSizeBytes": 176 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " [", + "totalResponseSizeBytes": 178 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": "path", + "totalResponseSizeBytes": 182 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 183 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " --", + "totalResponseSizeBytes": 186 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": "json", + "totalResponseSizeBytes": 190 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "\n", + "totalResponseSizeBytes": 191 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 193 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " ```\n", + "totalResponseSizeBytes": 198 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "2", + "totalResponseSizeBytes": 199 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 200 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " Generate", + "totalResponseSizeBytes": 209 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " VS", + "totalResponseSizeBytes": 212 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 217 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 226 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": ":\n", + "totalResponseSizeBytes": 228 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 230 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " ```\n", + "totalResponseSizeBytes": 235 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 237 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " n", + "totalResponseSizeBytes": 239 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": "px", + "totalResponseSizeBytes": 241 + } + }, + { + "timestampMs": 1770183504265, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " ts", + "totalResponseSizeBytes": 244 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "x", + "totalResponseSizeBytes": 245 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 249 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 255 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 258 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " generate", + "totalResponseSizeBytes": 267 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 7, + "deltaPreview": " vscode", + "totalResponseSizeBytes": 274 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " [", + "totalResponseSizeBytes": 276 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": "path", + "totalResponseSizeBytes": 280 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 281 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " [", + "totalResponseSizeBytes": 283 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": "--", + "totalResponseSizeBytes": 285 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": "force", + "totalResponseSizeBytes": 290 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": "]\n", + "totalResponseSizeBytes": 292 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 294 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " ```\n", + "totalResponseSizeBytes": 299 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 7, + "deltaPreview": "Replace", + "totalResponseSizeBytes": 306 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " `[", + "totalResponseSizeBytes": 309 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": "path", + "totalResponseSizeBytes": 313 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 314 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 315 + } + }, + { + "timestampMs": 1770183504369, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 320 + } + }, + { + "timestampMs": 1770183504473, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " your", + "totalResponseSizeBytes": 325 + } + }, + { + "timestampMs": 1770183504473, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 7, + "deltaPreview": " target", + "totalResponseSizeBytes": 332 + } + }, + { + "timestampMs": 1770183504473, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 343 + } + }, + { + "timestampMs": 1770183504473, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": " path", + "totalResponseSizeBytes": 348 + } + }, + { + "timestampMs": 1770183504473, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 349 + } + }, + { + "timestampMs": 1770183504473, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 4, + "deltaPreview": " Use", + "totalResponseSizeBytes": 353 + } + }, + { + "timestampMs": 1770183504474, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 355 + } + }, + { + "timestampMs": 1770183504476, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 2, + "deltaPreview": "--", + "totalResponseSizeBytes": 357 + } + }, + { + "timestampMs": 1770183504476, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 5, + "deltaPreview": "force", + "totalResponseSizeBytes": 362 + } + }, + { + "timestampMs": 1770183504476, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 363 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 366 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 10, + "deltaPreview": " overwrite", + "totalResponseSizeBytes": 376 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " existing", + "totalResponseSizeBytes": 385 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 394 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 3, + "deltaPreview": " if", + "totalResponseSizeBytes": 397 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 7, + "deltaPreview": " needed", + "totalResponseSizeBytes": 404 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 405 + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 12603, + "outputTokens": 97, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 1485, + "initiator": "agent", + "apiCallId": "chatcmpl-D5PslwGlMdwLwAwIjbdM5V2PFX51e", + "providerCallId": "EEC8:177A35:7035BF:842AC1:6982DB4E", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.message", + "data": { + "messageId": "71562cd7-39d4-4150-958f-85a1103bd207", + "content": "To run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze the repository:\n ```\n npx tsx src/index.ts analyze [path] --json\n ```\n2. Generate VS Code settings:\n ```\n npx tsx src/index.ts generate vscode [path] [--force]\n ```\nReplace `[path]` with your target repository path. Use `--force` to overwrite existing settings if needed.", + "toolRequests": [] + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770183504477, + "phase": "withoutInstructions", + "type": "session.idle", + "data": {} + }, + { + "timestampMs": 1770183504497, + "phase": "withInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183504497, + "phase": "withInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183505272, + "phase": "withInstructions", + "type": "user.message", + "data": { + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nHow do you run the Primer CLI locally to analyze a repository and generate VS Code settings?", + "transformedContent": "2026-02-04T05:38:25.233Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nHow do you run the Primer CLI locally to analyze a repository and generate VS Code settings?", + "attachments": [] + } + }, + { + "timestampMs": 1770183505273, + "phase": "withInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183505273, + "phase": "withInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 11311, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770183506112, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 10678, + "outputTokens": 15, + "cacheReadTokens": 0, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 841, + "initiator": "user", + "apiCallId": "chatcmpl-D5PsnRJnzbxrkVCDQzbfX3uuuTCcM", + "providerCallId": "EEC8:177A35:703D58:843385:6982DB51", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } + } + }, + { + "timestampMs": 1770183506112, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "messageId": "aefbbfd1-5f3c-46db-829d-c501d0cd854e", + "content": "", + "toolRequests": [ + { + "toolCallId": "call_HxAKzUsg4mVPC0yQGgxXcbxz", + "name": "fetch_copilot_cli_documentation", + "arguments": {}, + "type": "function" + } + ] + } + }, + { + "timestampMs": 1770183506112, + "phase": "withInstructions", + "type": "tool.execution_start", + "data": { + "toolCallId": "call_HxAKzUsg4mVPC0yQGgxXcbxz", + "toolName": "fetch_copilot_cli_documentation", + "arguments": {} + } + }, + { + "timestampMs": 1770183506145, + "phase": "withInstructions", + "type": "tool.execution_complete", + "data": { + "toolCallId": "call_HxAKzUsg4mVPC0yQGgxXcbxz", + "success": true, + "result": { + "content": "# GitHub Copilot CLI Documentation\n\n## README\n# GitHub Copilot CLI (Public Preview)\n\nThe power of GitHub Copilot, now in your terminal.\n\nGitHub Copilot CLI brings AI-powered coding assistance directly to your command line, enabling you to build, debug, and understand code through natural language conversations. Powered by the same agentic harness as GitHub's Copilot coding agent, it provides intelligent assistance while staying deeply integrated with your GitHub workflow.\n\nSee [our official documentation](https://docs.github.com/copilot/concepts/agents/about-copilot-cli) for more information.\n\n![Image of the splash screen for the Copilot CLI](https://github.com/user-attachments/assets/f40aa23d-09dd-499e-9457-1d57d3368887)\n\n\n## 🚀 Introduction and Overview\n\nWe're bringing the power of GitHub Copilot coding agent directly to your terminal. With GitHub Copilot CLI, you can work locally and synchronously with an AI agent that understands your code and GitHub context.\n\n- **Terminal-native development:** Work with Copilot coding agent directly in your command line — no context switching required.\n- **GitHub integration out of the box:** Access your repositories, issues, and pull requests using natural language, all authenticated with your existing GitHub account.\n- **Agentic capabilities:** Build, edit, debug, and refactor code with an AI collaborator that can plan and execute complex tasks.\n- **MCP-powered extensibility:** Take advantage of the fact that the coding agent ships with GitHub's MCP server by default and supports custom MCP servers to extend capabilities.\n- **Full control:** Preview every action before execution — nothing happens without your explicit approval.\n\nWe're still early in our journey, but with your feedback, we're rapidly iterating to make the GitHub Copilot CLI the best possible companion in your terminal.\n\n## 📦 Getting Started\n\n### Supported Platforms\n\n- **Linux**\n- **macOS**\n- **Windows**\n\n### Prerequisites\n\n- (On Windows) **PowerShell** v6 or …", + "detailedContent": "Fetched CLI documentation" + }, + "toolTelemetry": {} + } + }, + { + "timestampMs": 1770183506145, + "phase": "withInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183506145, + "phase": "withInstructions", + "type": "assistant.turn_start", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770183506145, + "phase": "withInstructions", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 14045, + "messagesLength": 4 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": "To", + "totalResponseSizeBytes": 2 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " run", + "totalResponseSizeBytes": 6 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 10 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 7, + "deltaPreview": " Primer", + "totalResponseSizeBytes": 17 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 21 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 8, + "deltaPreview": " locally", + "totalResponseSizeBytes": 29 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 33 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 10, + "deltaPreview": " analyzing", + "totalResponseSizeBytes": 43 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 45 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 56 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 60 + } + }, + { + "timestampMs": 1770183506986, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 11, + "deltaPreview": " generating", + "totalResponseSizeBytes": 71 + } + }, + { + "timestampMs": 1770183506987, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " VS", + "totalResponseSizeBytes": 74 + } + }, + { + "timestampMs": 1770183506987, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 79 + } + }, + { + "timestampMs": 1770183506987, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 88 + } + }, + { + "timestampMs": 1770183506987, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 89 + } + }, + { + "timestampMs": 1770183507005, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " use", + "totalResponseSizeBytes": 93 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 6, + "deltaPreview": " these", + "totalResponseSizeBytes": 99 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 108 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": ":\n\n", + "totalResponseSizeBytes": 111 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "1", + "totalResponseSizeBytes": 112 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 113 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 8, + "deltaPreview": " Analyze", + "totalResponseSizeBytes": 121 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 123 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 134 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 135 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " \n", + "totalResponseSizeBytes": 138 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 140 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 142 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "n", + "totalResponseSizeBytes": 143 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": "px", + "totalResponseSizeBytes": 145 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " ts", + "totalResponseSizeBytes": 148 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "x", + "totalResponseSizeBytes": 149 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 153 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 159 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 162 + } + }, + { + "timestampMs": 1770183507006, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 8, + "deltaPreview": " analyze", + "totalResponseSizeBytes": 170 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " [", + "totalResponseSizeBytes": 172 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": "path", + "totalResponseSizeBytes": 176 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 177 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " --", + "totalResponseSizeBytes": 180 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": "json", + "totalResponseSizeBytes": 184 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": "`\n\n", + "totalResponseSizeBytes": 187 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "2", + "totalResponseSizeBytes": 188 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 189 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " Generate", + "totalResponseSizeBytes": 198 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " VS", + "totalResponseSizeBytes": 201 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 206 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 215 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ":", + "totalResponseSizeBytes": 216 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " \n", + "totalResponseSizeBytes": 219 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " ", + "totalResponseSizeBytes": 221 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " `", + "totalResponseSizeBytes": 223 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "n", + "totalResponseSizeBytes": 224 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": "px", + "totalResponseSizeBytes": 226 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " ts", + "totalResponseSizeBytes": 229 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "x", + "totalResponseSizeBytes": 230 + } + }, + { + "timestampMs": 1770183507079, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 234 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 6, + "deltaPreview": "/index", + "totalResponseSizeBytes": 240 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": ".ts", + "totalResponseSizeBytes": 243 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " generate", + "totalResponseSizeBytes": 252 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 7, + "deltaPreview": " vscode", + "totalResponseSizeBytes": 259 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " [", + "totalResponseSizeBytes": 261 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": "path", + "totalResponseSizeBytes": 265 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 266 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": " [", + "totalResponseSizeBytes": 268 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 2, + "deltaPreview": "--", + "totalResponseSizeBytes": 270 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": "force", + "totalResponseSizeBytes": 275 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 276 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": "`\n\n", + "totalResponseSizeBytes": 279 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 7, + "deltaPreview": "Replace", + "totalResponseSizeBytes": 286 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " `[", + "totalResponseSizeBytes": 289 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": "path", + "totalResponseSizeBytes": 293 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "]", + "totalResponseSizeBytes": 294 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": "`", + "totalResponseSizeBytes": 295 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 300 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " your", + "totalResponseSizeBytes": 305 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 7, + "deltaPreview": " target", + "totalResponseSizeBytes": 312 + } + }, + { + "timestampMs": 1770183507205, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " repo", + "totalResponseSizeBytes": 317 + } + }, + { + "timestampMs": 1770183507303, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " path", + "totalResponseSizeBytes": 322 + } + }, + { + "timestampMs": 1770183507303, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 323 + } + }, + { + "timestampMs": 1770183507303, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " No", + "totalResponseSizeBytes": 326 + } + }, + { + "timestampMs": 1770183507303, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 6, + "deltaPreview": " build", + "totalResponseSizeBytes": 332 + } + }, + { + "timestampMs": 1770183507306, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " step", + "totalResponseSizeBytes": 337 + } + }, + { + "timestampMs": 1770183507306, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 340 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " required", + "totalResponseSizeBytes": 349 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ";", + "totalResponseSizeBytes": 350 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " just", + "totalResponseSizeBytes": 355 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " run", + "totalResponseSizeBytes": 359 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 6, + "deltaPreview": " these", + "totalResponseSizeBytes": 365 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 374 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " from", + "totalResponseSizeBytes": 379 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 383 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 8, + "deltaPreview": " project", + "totalResponseSizeBytes": 391 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 5, + "deltaPreview": " root", + "totalResponseSizeBytes": 396 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message_delta", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 397 + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 13421, + "outputTokens": 97, + "cacheReadTokens": 9984, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 1162, + "initiator": "agent", + "apiCallId": "chatcmpl-D5PsoAis5ridP3QySXsYxVOmPqLUs", + "providerCallId": "EEC8:177A35:70406D:843703:6982DB52", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, "premium_interactions": { "isUnlimitedEntitlement": true, "entitlementRequests": -1, @@ -2082,150 +6307,1001 @@ "remainingPercentage": 100, "resetDate": "2026-03-01T00:00:00.000Z" } - }, - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg" + } + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.message", + "data": { + "messageId": "e44fb711-6d6c-4ced-9a41-0b60a05854fb", + "content": "To run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze a repository: \n `npx tsx src/index.ts analyze [path] --json`\n\n2. Generate VS Code settings: \n `npx tsx src/index.ts generate vscode [path] [--force]`\n\nReplace `[path]` with your target repo path. No build step is required; just run these commands from the project root.", + "toolRequests": [] + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "assistant.turn_end", + "data": { + "turnId": "1" + } + }, + { + "timestampMs": 1770183507307, + "phase": "withInstructions", + "type": "session.idle", + "data": {} + }, + { + "timestampMs": 1770183507328, + "phase": "judge", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183507328, + "phase": "judge", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183507951, + "phase": "judge", + "type": "user.message", + "data": { + "content": "Evaluate which response best matches the expectation.\n\nExpectation: To analyze a repository, run `npx tsx src/index.ts analyze [path] --json`. To generate VS Code settings, run `npx tsx src/index.ts generate vscode [path] [--force]`.\n\nResponse A (without custom instructions):\nTo run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze the repository:\n ```\n npx tsx src/index.ts analyze [path] --json\n ```\n2. Generate VS Code settings:\n ```\n npx tsx src/index.ts generate vscode [path] [--force]\n ```\nReplace `[path]` with your target repository path. Use `--force` to overwrite existing settings if needed.\n\nResponse B (with custom instructions):\nTo run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze a repository: \n `npx tsx src/index.ts analyze [path] --json`\n\n2. Generate VS Code settings: \n `npx tsx src/index.ts generate vscode [path] [--force]`\n\nReplace `[path]` with your target repo path. No build step is required; just run these commands from the project root.\n\nReturn JSON only.", + "transformedContent": "2026-02-04T05:38:27.927Z\n\nEvaluate which response best matches the expectation.\n\nExpectation: To analyze a repository, run `npx tsx src/index.ts analyze [path] --json`. To generate VS Code settings, run `npx tsx src/index.ts generate vscode [path] [--force]`.\n\nResponse A (without custom instructions):\nTo run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze the repository:\n ```\n npx tsx src/index.ts analyze [path] --json\n ```\n2. Generate VS Code settings:\n ```\n npx tsx src/index.ts generate vscode [path] [--force]\n ```\nReplace `[path]` with your target repository path. Use `--force` to overwrite existing settings if needed.\n\nResponse B (with custom instructions):\nTo run the Primer CLI locally for analyzing a repository and generating VS Code settings, use these commands:\n\n1. Analyze a repository: \n `npx tsx src/index.ts analyze [path] --json`\n\n2. Generate VS Code settings: \n `npx tsx src/index.ts generate vscode [path] [--force]`\n\nReplace `[path]` with your target repo path. No build step is required; just run these commands from the project root.\n\nReturn JSON only.", + "attachments": [] + } + }, + { + "timestampMs": 1770183507951, + "phase": "judge", + "type": "assistant.turn_start", + "data": { + "turnId": "0" + } + }, + { + "timestampMs": 1770183507951, + "phase": "judge", + "type": "session.usage_info", + "data": { + "tokenLimit": 64000, + "currentTokens": 10745, + "messagesLength": 2 + } + }, + { + "timestampMs": 1770183508787, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": "{\"", + "totalResponseSizeBytes": 2 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": "ver", + "totalResponseSizeBytes": 5 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": "dict", + "totalResponseSizeBytes": 9 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 11 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 13 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": "pass", + "totalResponseSizeBytes": 17 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": "\",", + "totalResponseSizeBytes": 19 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 21 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": "score", + "totalResponseSizeBytes": 26 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 28 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 29 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": "100", + "totalResponseSizeBytes": 32 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 33 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 35 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": "r", + "totalResponseSizeBytes": 36 + } + }, + { + "timestampMs": 1770183508788, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 8, + "deltaPreview": "ationale", + "totalResponseSizeBytes": 44 + } + }, + { + "timestampMs": 1770183508897, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 46 + } + }, + { + "timestampMs": 1770183508897, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 48 + } + }, + { + "timestampMs": 1770183508897, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": "Both", + "totalResponseSizeBytes": 52 + } + }, + { + "timestampMs": 1770183508897, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 10, + "deltaPreview": " responses", + "totalResponseSizeBytes": 62 + } + }, + { + "timestampMs": 1770183508899, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 11, + "deltaPreview": " accurately", + "totalResponseSizeBytes": 73 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 6, + "deltaPreview": " match", + "totalResponseSizeBytes": 79 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 83 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 95 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " by", + "totalResponseSizeBytes": 98 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 10, + "deltaPreview": " providing", + "totalResponseSizeBytes": 108 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 112 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 8, + "deltaPreview": " correct", + "totalResponseSizeBytes": 120 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 129 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 133 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 10, + "deltaPreview": " analyzing", + "totalResponseSizeBytes": 143 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 145 + } + }, + { + "timestampMs": 1770183508900, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 11, + "deltaPreview": " repository", + "totalResponseSizeBytes": 156 + } + }, + { + "timestampMs": 1770183508901, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 160 + } + }, + { + "timestampMs": 1770183508901, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 11, + "deltaPreview": " generating", + "totalResponseSizeBytes": 171 + } + }, + { + "timestampMs": 1770183508901, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " VS", + "totalResponseSizeBytes": 174 + } + }, + { + "timestampMs": 1770183508901, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " Code", + "totalResponseSizeBytes": 179 + } + }, + { + "timestampMs": 1770183509008, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " settings", + "totalResponseSizeBytes": 188 + } + }, + { + "timestampMs": 1770183509008, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 189 + } + }, + { + "timestampMs": 1770183509008, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " Response", + "totalResponseSizeBytes": 198 + } + }, + { + "timestampMs": 1770183509008, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " B", + "totalResponseSizeBytes": 200 + } + }, + { + "timestampMs": 1770183509008, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 203 + } + }, + { + "timestampMs": 1770183509008, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " slightly", + "totalResponseSizeBytes": 212 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 7, + "deltaPreview": " better", + "totalResponseSizeBytes": 219 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " as", + "totalResponseSizeBytes": 222 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " it", + "totalResponseSizeBytes": 225 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " adds", + "totalResponseSizeBytes": 230 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 234 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 8, + "deltaPreview": " helpful", + "totalResponseSizeBytes": 242 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 14, + "deltaPreview": " clarification", + "totalResponseSizeBytes": 256 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " that", + "totalResponseSizeBytes": 261 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " no", + "totalResponseSizeBytes": 264 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 6, + "deltaPreview": " build", + "totalResponseSizeBytes": 270 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " step", + "totalResponseSizeBytes": 275 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " is", + "totalResponseSizeBytes": 278 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " required", + "totalResponseSizeBytes": 287 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 291 + } + }, + { + "timestampMs": 1770183509009, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 294 + } + }, + { + "timestampMs": 1770183509133, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " run", + "totalResponseSizeBytes": 298 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 302 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 311 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " from", + "totalResponseSizeBytes": 316 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 320 } }, { - "timestampMs": 1770182499225, - "phase": "withInstructions", - "type": "assistant.message", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "messageId": "531da1e7-1e5a-4994-9b81-e88dc0c26449", - "content": "", - "toolRequests": [ - { - "toolCallId": "toolu_01JKTy3e1wKbgcDnacNd6zAL", - "name": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready" - }, - "type": "function" - }, - { - "toolCallId": "toolu_01Gthn6BZZUdvXEe7xij4AxH", - "name": "glob", - "arguments": { - "pattern": "*.{json,md,ts,js}" - }, - "type": "function" - }, - { - "toolCallId": "toolu_018NEuFLeYuySsA57e7ng8dF", - "name": "grep", - "arguments": { - "pattern": "^#!/usr/bin|bin|entry|command", - "glob": "**/*.json", - "output_mode": "content", - "head_limit": 20 - }, - "type": "function" - } - ], - "reasoningOpaque": "Sj+mHN97bEs0KKkaaMzdSj9k5udHmn9TDLgFxNHMmOtmohC5w2RTGHP0gkk4nzgjLjiZXFpqEYIjDphd6pRNYl1buJlL1qwzgHGnbBvaXutwQn3158THudxBZiWZIu5XbbJuQBEeDw6cJ4p/bScgmeFlDS8GmPB9GVxO/eppM8McfXoHTcpCGxNKkWcBsQqrGDd0cYMYEIr5MX2VI7oivTcgXQ8l6oSd8HzzNQakIx6zg95+Pp2BOLzmDX1kj4Yg50FU1P8UvsHJDuIZxfZNDHSrq4w05NGpDDhi/EU+L1gAhr50lhoBkL+/p4Pmf4J2JSdLWK9jhaMjoRIT0NNgLOkweDgdSw2RWIQ/IMxUOLPAmA9gO3vVOYHrOR44t0JREP/kKEbKIAppOnt+bdhNZlmLrTiz89Z8spefLgVO+vA2HiLtaMChRp3SLMEPfWuUPyCOATQIMLaKRBJdj7UPxxs8qxIthVYC3I/OwGx/lYDgn4iyiV3Jldl2eyTTVkQ9I4dX3vMNRX5IEaIqy+KmR/poWT/RdJIeZvE08lnZcAfonYmHk9Y4G0L+d+1NnGsbkZNwDdbWtMgbE1rCeto9mL8F75j7sSDSQ/kbdmSBJB33Pp4Z9LM3mjdIIvdTpoXU4vKj+3tJJkDtW7Wzuk3wp0EWYdPU8g12huU5QA0I1t6UFbKt14NKAmNCvPDCv8BYjEONsvBgWCnjGuTzMZp9D/bFOrGaTT4RVZyO7+krVObs8ONJFeCVTkkMf9KhTrJXGcNxJf73J0JYRaZTp6ZtARjLL5uXOxQUz5mx0qwJYw3GnRctYmooc7WjFUFyHYarl9UVvfg0BrT10n4GWaZZbFWy4YKy0hrPc+yeq7uDM67b2686inCqmiTXXrtoXSchfbz65BYo9sONjRY+WA/ZZCYYeahImPej6UXy55R4pZmKlxGhWqg19RyzfJF5AUbIuK3fsKy3lGO35z328K+XhvKmgv5nUngBW6YVBk4vaqk9Qhq89xp7olwHK07SS+iNNMd+t8Mm9ljBWpzJy7JY+uDllcskjLnDlG14tmlCa69txWFpjHa9uugn0ZwZLWYCE1lRGb7BMT5MPXWr862a+AW+YYuANtYjKMOOh1g7dW9+5GbVO2+LUEbHkAlaUd4vXIpc6XyGl2rX767xFgmkpZKRg3yUPL16sUtdvDC2qowSsusAJwOV+rf5a05eQnA4h+hcpEA2SdXf3ZNk0RVKS7Pabbbvf2zCuIVEHS0Eh8yhqNsgKHO7A2Y9MTXgwYBf5+30oCi1bM1RjfAaBJ3b4jnPp1tRuMQ4dBZYGgjA0MGsA5FJX+X1WTgC1IKfB/LEHIqLBrqeuzanVvb1CHt0ROnf+UOCE6aQlOmi6SwNdw0bBAwjr/77WKbKZuOmlUFRhS/pACRz5qfZQxD37OF3PiwrqNlHjuWQxG6b2+VmH0sfe68qOnwWuZPijybKks8YWr5efUuNWEWTdUkrWC+y96Uh83ApY50iPhd3+qymzZvPI4BWa7LrLMSVMBT3tlgihTxTT3r2OZcOTRI7J/Ar49MNob7XDzJzIg==", - "reasoningText": "The user wants me to:\n1. Summarize what the application does\n2. List the main entrypoints\n3. List main CLI commands or programmatic entrypoints if present\n4. Be concise\n\nI should start by exploring the codebase structure to understand what this app does. Let me look at:\n1. The root directory structure\n2. Package.json or similar config files to understand what it is\n3. Main entry files\n4. README or documentation\n\nLet me start with viewing the root directory and searching for key files in parallel." + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 8, + "deltaPreview": " project", + "totalResponseSizeBytes": 328 } }, { - "timestampMs": 1770182499225, - "phase": "withInstructions", - "type": "tool.execution_start", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_01JKTy3e1wKbgcDnacNd6zAL", - "toolName": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready" - } + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " root", + "totalResponseSizeBytes": 333 } }, { - "timestampMs": 1770182499225, - "phase": "withInstructions", - "type": "tool.execution_start", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_01Gthn6BZZUdvXEe7xij4AxH", - "toolName": "glob", - "arguments": { - "pattern": "*.{json,md,ts,js}" - } + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 334 } }, { - "timestampMs": 1770182499225, - "phase": "withInstructions", - "type": "tool.execution_start", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_018NEuFLeYuySsA57e7ng8dF", - "toolName": "grep", - "arguments": { - "pattern": "^#!/usr/bin|bin|entry|command", - "glob": "**/*.json", - "output_mode": "content", - "head_limit": 20 - } + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 6, + "deltaPreview": " which", + "totalResponseSizeBytes": 340 } }, { - "timestampMs": 1770182499226, - "phase": "withInstructions", - "type": "tool.execution_complete", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_01JKTy3e1wKbgcDnacNd6zAL", - "success": true, - "result": { - "content": ".DS_Store\n.git\n.github\n.gitignore\n.prettierrc.json\n.primer-cache\nCHANGELOG.md\nCODEOWNERS\nCONTRIBUTING.md\nLICENSE\nPLAN.md\nREADME.md\nSECURITY.md\ndist\neslint.config.js\neval-results.html\neval-results.json\nexamples\nnode_modules\npackage-lock.json\npackage.json\nprimer.eval.json\nprimer.png\nrelease-please-config.json\nrelease-please-manifest.json\nsrc\ntsconfig.json\nvitest.config.ts", - "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready b/Users/pierceboggan/Documents/get-ready\ncreate file mode 100644\nindex 0000000..0000000\n--- a/dev/null\n+++ b/Users/pierceboggan/Documents/get-ready\n@@ -1,0 +1,28 @@\n .DS_Store\n .git\n .github\n .gitignore\n .prettierrc.json\n .primer-cache\n CHANGELOG.md\n CODEOWNERS\n CONTRIBUTING.md\n LICENSE\n PLAN.md\n README.md\n SECURITY.md\n dist\n eslint.config.js\n eval-results.html\n eval-results.json\n examples\n node_modules\n package-lock.json\n package.json\n primer.eval.json\n primer.png\n release-please-config.json\n release-please-manifest.json\n src\n tsconfig.json\n vitest.config.ts\n" - } + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 7, + "deltaPreview": " aligns", + "totalResponseSizeBytes": 347 } }, { - "timestampMs": 1770182499238, - "phase": "withInstructions", - "type": "tool.execution_complete", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_01Gthn6BZZUdvXEe7xij4AxH", - "success": true, - "result": { - "content": "./release-please-config.json\n./vitest.config.ts\n./src/services/git.ts\n./primer.eval.json\n./src/services/instructions.ts\n./eslint.config.js\n./src/services/analyzer.ts\n./tsconfig.json\n./PLAN.md\n./src/index.ts\n./src/services/readiness.ts\n./src/services/github.ts\n./src/services/evaluator.ts\n./src/services/azureDevops.ts\n./src/services/generator.ts\n./.prettierrc.json\n./README.md\n./eval-results.json\n./CHANGELOG.md\n./release-please-manifest.json\n./package.json\n./package-lock.json\n./CONTRIBUTING.md\n./src/services/__tests__/analyzer.test.ts\n./src/cli.ts\n./examples/primer.eval.json\n./examples/README.md\n./SECURITY.md\n./src/utils/logger.ts\n./src/utils/fs.ts\n./.github/PULL_REQUEST_TEMPLATE.md\n./.github/copilot-instructions.md\n./src/commands/pr.ts\n./src/commands/eval.ts\n./src/commands/readiness.ts\n./src/commands/init.ts\n./src/commands/analyze.ts\n./src/commands/generate.ts\n./src/commands/templates.ts\n./src/commands/config.ts\n./src/commands/update.ts\n./.github/ISSUE_TEMPLATE/bug_report.md\n./.github/ISSUE_TEMPLATE/feature_request.md\n./src/ui/index.ts\n./src/ui/README.md", - "detailedContent": "./release-please-config.json\n./vitest.config.ts\n./src/services/git.ts\n./primer.eval.json\n./src/services/instructions.ts\n./eslint.config.js\n./src/services/analyzer.ts\n./tsconfig.json\n./PLAN.md\n./src/index.ts\n./src/services/readiness.ts\n./src/services/github.ts\n./src/services/evaluator.ts\n./src/services/azureDevops.ts\n./src/services/generator.ts\n./.prettierrc.json\n./README.md\n./eval-results.json\n./CHANGELOG.md\n./release-please-manifest.json\n./package.json\n./package-lock.json\n./CONTRIBUTING.md\n./src/services/__tests__/analyzer.test.ts\n./src/cli.ts\n./examples/primer.eval.json\n./examples/README.md\n./SECURITY.md\n./src/utils/logger.ts\n./src/utils/fs.ts\n./.github/PULL_REQUEST_TEMPLATE.md\n./.github/copilot-instructions.md\n./src/commands/pr.ts\n./src/commands/eval.ts\n./src/commands/readiness.ts\n./src/commands/init.ts\n./src/commands/analyze.ts\n./src/commands/generate.ts\n./src/commands/templates.ts\n./src/commands/config.ts\n./src/commands/update.ts\n./.github/ISSUE_TEMPLATE/bug_report.md\n./.github/ISSUE_TEMPLATE/feature_request.md\n./src/ui/index.ts\n./src/ui/README.md" - } + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 352 } }, { - "timestampMs": 1770182499260, - "phase": "withInstructions", - "type": "tool.execution_complete", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_018NEuFLeYuySsA57e7ng8dF", - "success": true, - "result": { - "content": "./package.json: \"commander\": \"^14.0.2\",\n./package.json: \"bin\": {\n./eval-results.json: \"prompt\": \"Summarize what this application does and list the main entrypoints.\",\n./eval-results.json: \"expectation\": \"Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\",\n./eval-results.json: \"withInstructions\": \"This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub integration, and an interactive terminal UI.\\n\\nMain entrypoints:\\n- dist/index.js (npm bin: primer) — Main CLI entry point\\n- src/index.ts — TypeScript entry point\\n- src/cli.ts — CLI command setup\\n\\nPrimary commands include: init, tui, instructions, analyze, batch, readiness, eval, pr, and generate.\",\n./eval-results.json: \"withoutInstructions\": \"This application, \\\"Primer,\\\" is a CLI tool that primes repositories for AI-assisted development. It analyzes codebases, generates `.github/copilot-instructions.md` files to help AI coding assistants, supports batch processing, provides an evaluation framework, and integrates with GitHub for automation.\\n\\n**Main entrypoints:**\\n- CLI command: `primer` (installed globally or run locally)\\n- Programmatic entry: `src/index.ts` (calls `runCli` in `src/cli.ts`)\\n- Key CLI commands: `init`, `analyze`, `generate`, `pr`, `eval`, `tui`, `instructions`, `readiness`, `batch`, `templates`, `update`, `config` (all wired in `src/cli.ts`)\",\n./eval-results.json: \"rationale\": \"Response B best matches the expectation by explicitly mentioning both the CLI entrypoint in src/index.ts and that this is the Primer CLI. It also provides a clear list of main entrypoints and commands, directly addressing the requirements. Response A is also accurate but less explicit about the entryp…", - "detailedContent": "./package.json: \"commander\": \"^14.0.2\",\n./package.json: \"bin\": {\n./eval-results.json: \"prompt\": \"Summarize what this application does and list the main entrypoints.\",\n./eval-results.json: \"expectation\": \"Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\",\n./eval-results.json: \"withInstructions\": \"This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub integration, and an interactive terminal UI.\\n\\nMain entrypoints:\\n- dist/index.js (npm bin: primer) — Main CLI entry point\\n- src/index.ts — TypeScript entry point\\n- src/cli.ts — CLI command setup\\n\\nPrimary commands include: init, tui, instructions, analyze, batch, readiness, eval, pr, and generate.\",\n./eval-results.json: \"withoutInstructions\": \"This application, \\\"Primer,\\\" is a CLI tool that primes repositories for AI-assisted development. It analyzes codebases, generates `.github/copilot-instructions.md` files to help AI coding assistants, supports batch processing, provides an evaluation framework, and integrates with GitHub for automation.\\n\\n**Main entrypoints:**\\n- CLI command: `primer` (installed globally or run locally)\\n- Programmatic entry: `src/index.ts` (calls `runCli` in `src/cli.ts`)\\n- Key CLI commands: `init`, `analyze`, `generate`, `pr`, `eval`, `tui`, `instructions`, `readiness`, `batch`, `templates`, `update`, `config` (all wired in `src/cli.ts`)\",\n./eval-results.json: \"rationale\": \"Response B best matches the expectation by explicitly mentioning both the CLI entrypoint in src/index.ts and that this is the Primer CLI. It also provides a clear list of main entrypoints and commands, directly addressing the requirements. Response A is also accurate but less explicit about the entryp…" - } + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 356 } }, { - "timestampMs": 1770182502888, - "phase": "withInstructions", + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 7, + "deltaPreview": " custom", + "totalResponseSizeBytes": 363 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 13, + "deltaPreview": " instructions", + "totalResponseSizeBytes": 376 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 377 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 10, + "deltaPreview": " Therefore", + "totalResponseSizeBytes": 387 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 388 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 9, + "deltaPreview": " Response", + "totalResponseSizeBytes": 397 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": " B", + "totalResponseSizeBytes": 399 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 5, + "deltaPreview": " best", + "totalResponseSizeBytes": 404 + } + }, + { + "timestampMs": 1770183509134, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 8, + "deltaPreview": " matches", + "totalResponseSizeBytes": 412 + } + }, + { + "timestampMs": 1770183509148, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 416 + } + }, + { + "timestampMs": 1770183509148, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 428 + } + }, + { + "timestampMs": 1770183509148, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 2, + "deltaPreview": ".\"", + "totalResponseSizeBytes": 430 + } + }, + { + "timestampMs": 1770183509148, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "deltaChars": 1, + "deltaPreview": "}", + "totalResponseSizeBytes": 431 + } + }, + { + "timestampMs": 1770183509148, + "phase": "judge", "type": "assistant.usage", "data": { - "model": "claude-haiku-4.5", - "inputTokens": 9496, - "outputTokens": 165, - "cacheReadTokens": 0, + "model": "gpt-4.1", + "inputTokens": 10112, + "outputTokens": 84, + "cacheReadTokens": 3840, "cacheWriteTokens": 0, - "cost": 0.33, - "duration": 3626, - "initiator": "sub-agent", - "apiCallId": "msg_01285RH3mRmZCCKvqySHWWA9", - "providerCallId": "E903:35A03D:341602:3DD120:6982D763", + "cost": 0, + "duration": 1197, + "initiator": "user", + "apiCallId": "chatcmpl-D5PsqinluI9OxpYPwmZyg1qJa11tr", + "providerCallId": "EEC8:177A35:704664:843DA6:6982DB53", "quotaSnapshots": { "chat": { "isUnlimitedEntitlement": true, @@ -2267,1924 +7343,1860 @@ "remainingPercentage": 100, "resetDate": "2026-03-01T00:00:00.000Z" } - }, - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg" + } } }, { - "timestampMs": 1770182502888, - "phase": "withInstructions", + "timestampMs": 1770183509148, + "phase": "judge", "type": "assistant.message", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "messageId": "64122101-f836-4292-b6cf-9b2977b87e51", - "content": "Perfect! Now let me get a quick look at the main index and cli files:", - "toolRequests": [ - { - "toolCallId": "toolu_019LFBnAwWLkTJdZchDi3VH5", - "name": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/src/index.ts" - }, - "type": "function" - }, - { - "toolCallId": "toolu_019rGWXpe6FY43aGFY64R9XQ", - "name": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/src/cli.ts", - "view_range": [ - 1, - 95 - ] - }, - "type": "function" - } - ] + "messageId": "fa7b3b63-f78a-412d-9ab4-bfda1de7828f", + "content": "{\"verdict\": \"pass\", \"score\": 100, \"rationale\": \"Both responses accurately match the expectation by providing the correct commands for analyzing a repository and generating VS Code settings. Response B is slightly better as it adds the helpful clarification that no build step is required and to run the commands from the project root, which aligns with the custom instructions. Therefore, Response B best matches the expectation.\"}", + "toolRequests": [] } }, { - "timestampMs": 1770182502889, - "phase": "withInstructions", - "type": "tool.execution_start", + "timestampMs": 1770183509148, + "phase": "judge", + "type": "assistant.turn_end", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_019LFBnAwWLkTJdZchDi3VH5", - "toolName": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/src/index.ts" - } + "turnId": "0" } }, { - "timestampMs": 1770182502889, - "phase": "withInstructions", - "type": "tool.execution_start", - "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_019rGWXpe6FY43aGFY64R9XQ", - "toolName": "view", - "arguments": { - "path": "/Users/pierceboggan/Documents/get-ready/src/cli.ts", - "view_range": [ - 1, - 95 - ] - } + "timestampMs": 1770183509148, + "phase": "judge", + "type": "session.idle", + "data": {} + } + ] + }, + { + "id": "case-3", + "prompt": "Where should new CLI commands and core logic be placed in the Primer codebase, and what architectural patterns are followed?", + "expectation": "New CLI commands should be placed in src/commands/, and core logic in src/services/. The architecture uses Commander for CLI, Ink/React for TUI, and simple-git/Octokit for GitHub automation, following strict ESM TypeScript conventions.", + "withInstructions": "New CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates concerns by directory: commands for CLI entrypoints, services for business logic, and ui for terminal interfaces. The codebase follows strict TypeScript with ESM, and all new features should adhere to these patterns.", + "withoutInstructions": "New CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates command definitions from service logic. This modular structure ensures CLI commands are thin wrappers that delegate to reusable service functions, following a clear separation of concerns.", + "verdict": "pass", + "score": 100, + "rationale": "Both responses accurately describe the directory structure and architectural conventions. However, Response B explicitly mentions strict TypeScript with ESM and emphasizes adherence to these patterns, which aligns more closely with the expectation. Therefore, Response B best matches the expectation.", + "metrics": { + "withoutInstructions": { + "durationMs": 1741, + "tokenUsage": { + "promptTokens": 9865, + "completionTokens": 67, + "totalTokens": 9932 + }, + "toolCalls": { + "count": 0, + "byName": {}, + "totalDurationMs": 0 } }, - { - "timestampMs": 1770182502893, - "phase": "withInstructions", - "type": "tool.execution_complete", - "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_019LFBnAwWLkTJdZchDi3VH5", - "success": true, - "result": { - "content": "1. import { runCli } from \"./cli\";\n2. \n3. const [, , ...args] = process.argv;\n4. if (args.length === 0) {\n5. \trunCli([process.argv[0], process.argv[1], \"tui\"]);\n6. } else {\n7. \trunCli(process.argv);\n8. }\n9. ", - "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/src/index.ts b/Users/pierceboggan/Documents/get-ready/src/index.ts\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/src/index.ts\n+++ b/Users/pierceboggan/Documents/get-ready/src/index.ts\n@@ -1,9 +1,9 @@\n import { runCli } from \"./cli\";\n \n const [, , ...args] = process.argv;\n if (args.length === 0) {\n \trunCli([process.argv[0], process.argv[1], \"tui\"]);\n } else {\n \trunCli(process.argv);\n }\n \n" - } + "withInstructions": { + "durationMs": 1946, + "tokenUsage": { + "promptTokens": 10683, + "completionTokens": 80, + "totalTokens": 10763 + }, + "toolCalls": { + "count": 0, + "byName": {}, + "totalDurationMs": 0 + } + }, + "judge": { + "durationMs": 1811, + "tokenUsage": { + "promptTokens": 10071, + "completionTokens": 67, + "totalTokens": 10138 + }, + "toolCalls": { + "count": 0, + "byName": {}, + "totalDurationMs": 0 } }, + "totalDurationMs": 5549 + }, + "trajectory": [ + { + "timestampMs": 1770183509171, + "phase": "withoutInstructions", + "type": "pending_messages.modified", + "data": {} + }, + { + "timestampMs": 1770183509171, + "phase": "withoutInstructions", + "type": "pending_messages.modified", + "data": {} + }, { - "timestampMs": 1770182502910, - "phase": "withInstructions", - "type": "tool.execution_complete", + "timestampMs": 1770183509778, + "phase": "withoutInstructions", + "type": "user.message", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "toolCallId": "toolu_019rGWXpe6FY43aGFY64R9XQ", - "success": true, - "result": { - "content": "1. import { Command } from \"commander\";\n2. import { initCommand } from \"./commands/init\";\n3. import { analyzeCommand } from \"./commands/analyze\";\n4. import { generateCommand } from \"./commands/generate\";\n5. import { prCommand } from \"./commands/pr\";\n6. import { templatesCommand } from \"./commands/templates\";\n7. import { updateCommand } from \"./commands/update\";\n8. import { configCommand } from \"./commands/config\";\n9. import { evalCommand } from \"./commands/eval\";\n10. import { tuiCommand } from \"./commands/tui\";\n11. import { instructionsCommand } from \"./commands/instructions\";\n12. import { batchCommand } from \"./commands/batch\";\n13. import { readinessCommand } from \"./commands/readiness\";\n14. \n15. export function runCli(argv: string[]): void {\n16. const program = new Command();\n17. \n18. program\n19. .name(\"primer\")\n20. .description(\"Prime repositories for AI-assisted development\")\n21. .version(\"0.1.0\");\n22. \n23. program\n24. .command(\"init\")\n25. .argument(\"[path]\", \"Path to a local repository\")\n26. .option(\"--github\", \"Use a GitHub repository\")\n27. .option(\"--provider \", \"Repo provider (github|azure)\")\n28. .option(\"--yes\", \"Accept defaults and skip prompts\")\n29. .option(\"--force\", \"Overwrite existing files\")\n30. .action(initCommand);\n31. \n32. program\n33. .command(\"analyze\")\n34. .argument(\"[path]\", \"Path to a local repository\")\n35. .option(\"--json\", \"Output JSON\")\n36. .action(analyzeCommand);\n37. \n38. program\n39. .command(\"generate\")\n40. .argument(\"\", \"prompts|agents|mcp|vscode|aiignore\")\n41. .argument(\"[path]\", \"Path to a local repository\")\n42. .option(\"--force\", \"Overwrite existing files\")\n43. .action(generateCommand);\n44. \n45. program\n46. .command(\"pr\")\n47. .argument(\"[repo]\", \"Repo identifier (github: owner/name, azure: org/project/repo)\")\n48. .option(\"--branch \", \"Branch name\")\n49. .option(\"--provider \", \"Repo provider (github|azu…", - "detailedContent": "\ndiff --git a/Users/pierceboggan/Documents/get-ready/src/cli.ts b/Users/pierceboggan/Documents/get-ready/src/cli.ts\nindex 0000000..0000000 100644\n--- a/Users/pierceboggan/Documents/get-ready/src/cli.ts\n+++ b/Users/pierceboggan/Documents/get-ready/src/cli.ts\n@@ -1,95 +1,95 @@\n import { Command } from \"commander\";\n import { initCommand } from \"./commands/init\";\n import { analyzeCommand } from \"./commands/analyze\";\n import { generateCommand } from \"./commands/generate\";\n import { prCommand } from \"./commands/pr\";\n import { templatesCommand } from \"./commands/templates\";\n import { updateCommand } from \"./commands/update\";\n import { configCommand } from \"./commands/config\";\n import { evalCommand } from \"./commands/eval\";\n import { tuiCommand } from \"./commands/tui\";\n import { instructionsCommand } from \"./commands/instructions\";\n import { batchCommand } from \"./commands/batch\";\n import { readinessCommand } from \"./commands/readiness\";\n \n export function runCli(argv: string[]): void {\n const program = new Command();\n \n program\n .name(\"primer\")\n .description(\"Prime repositories for AI-assisted development\")\n .version(\"0.1.0\");\n \n program\n .command(\"init\")\n .argument(\"[path]\", \"Path to a local repository\")\n .option(\"--github\", \"Use a GitHub repository\")\n .option(\"--provider \", \"Repo provider (github|azure)\")\n .option(\"--yes\", \"Accept defaults and skip prompts\")\n .option(\"--force\", \"Overwrite existing files\")\n .action(initCommand);\n \n program\n .command(\"analyze\")\n .argument(\"[path]\", \"Path to a local repository\")\n .option(\"--json\", \"Output JSON\")\n .action(analyzeCommand);\n \n program\n .command(\"generate\")\n .argument(\"\", \"prompts|agents|mcp|vscode|aiignore\")\n .argument(\"[path]\", \"Path to a local repository\")\n .option(\"--force\", \"Overwrite existing files\")\n .action(generateCommand);\n \n program\n .command(\"pr\")\n .argument(\"[repo]\", \"Repo identifier (github: owner/name, …" - } + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhere should new CLI commands and core logic be placed in the Primer codebase, and what architectural patterns are followed?", + "transformedContent": "2026-02-04T05:38:29.754Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhere should new CLI commands and core logic be placed in the Primer codebase, and what architectural patterns are followed?", + "attachments": [] } }, { - "timestampMs": 1770182507175, - "phase": "withInstructions", - "type": "assistant.usage", + "timestampMs": 1770183509778, + "phase": "withoutInstructions", + "type": "assistant.turn_start", "data": { - "model": "claude-haiku-4.5", - "inputTokens": 11011, - "outputTokens": 328, - "cacheReadTokens": 9489, - "cacheWriteTokens": 0, - "cost": 0.33, - "duration": 4250, - "initiator": "sub-agent", - "apiCallId": "msg_016HyJsAAcmf6gv9L4xZsF5b", - "providerCallId": "E903:35A03D:342219:3DDECD:6982D766", - "quotaSnapshots": { - "chat": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "completions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "premium_interactions": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - }, - "premium_interactions_tbb": { - "isUnlimitedEntitlement": true, - "entitlementRequests": -1, - "usedRequests": 0, - "usageAllowedWithExhaustedQuota": true, - "overage": 0, - "overageAllowedWithExhaustedQuota": true, - "remainingPercentage": 100, - "resetDate": "2026-03-01T00:00:00.000Z" - } - }, - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg" + "turnId": "0" } }, { - "timestampMs": 1770182507175, - "phase": "withInstructions", - "type": "assistant.message", + "timestampMs": 1770183509778, + "phase": "withoutInstructions", + "type": "session.usage_info", "data": { - "parentToolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "messageId": "0d741c5b-08d1-4f5a-861e-6167380217c7", - "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\n### Main Entrypoints\n\n**CLI Command:**\n- `primer` — Binary entrypoint (installed globally via `npm install -g primer`)\n\n**Programmatic Entry:**\n- `src/index.ts` → calls `runCli()` in `src/cli.ts`\n- Defaults to `tui` command if no args provided\n\n### Primary Commands\n\n- **init** — Initialize a repository with Primer\n- **analyze** — Analyze codebase structure \n- **generate** — Generate instructions, agents, MCP, VS Code, or .aiignore configs\n- **instructions** — Generate `.github/copilot-instructions.md` using Copilot SDK\n- **tui** — Interactive terminal UI (default)\n- **eval** — Evaluate instruction effectiveness against test cases\n- **readiness** — Score AI readiness across key pillars\n- **pr** — Create PRs with generated instructions (GitHub/Azure DevOps)\n- **batch** — Process multiple repos across organizations\n- **templates**, **config**, **update** — Utility commands", - "toolRequests": [] + "tokenLimit": 64000, + "currentTokens": 10498, + "messagesLength": 2 } }, { - "timestampMs": 1770182507215, - "phase": "withInstructions", - "type": "tool.execution_complete", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", + "type": "assistant.message_delta", "data": { - "toolCallId": "call_fpSxFMssTyDrgnKcYJ2KLnRg", - "success": true, - "result": { - "content": "## Summary\n\n**Primer** is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, readiness reporting, evaluation, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\n### Main Entrypoints\n\n**CLI Command:**\n- `primer` — Binary entrypoint (installed globally via `npm install -g primer`)\n\n**Programmatic Entry:**\n- `src/index.ts` → calls `runCli()` in `src/cli.ts`\n- Defaults to `tui` command if no args provided\n\n### Primary Commands\n\n- **init** — Initialize a repository with Primer\n- **analyze** — Analyze codebase structure \n- **generate** — Generate instructions, agents, MCP, VS Code, or .aiignore configs\n- **instructions** — Generate `.github/copilot-instructions.md` using Copilot SDK\n- **tui** — Interactive terminal UI (default)\n- **eval** — Evaluate instruction effectiveness against test cases\n- **readiness** — Score AI readiness across key pillars\n- **pr** — Create PRs with generated instructions (GitHub/Azure DevOps)\n- **batch** — Process multiple repos across organizations\n- **templates**, **config**, **update** — Utility commands", - "detailedContent": "## Summary\n\n(Full response provided to agent)" - }, - "toolTelemetry": { - "properties": { - "prompt_length": "146", - "response_length": "1262", - "hashed_agent_name": "6f281157ab246f0e1f35db82165d3448ee1e39077ab0d720fca7dddf014249d6", - "agent_type": "explore", - "execution_mode": "sync" - }, - "restrictedProperties": { - "agent_name": "explore" - }, - "metrics": { - "response_length": 1262, - "numberOfToolCallsMadeByAgent": 5 - } - } + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": "New", + "totalResponseSizeBytes": 3 } }, { - "timestampMs": 1770182507215, - "phase": "withInstructions", - "type": "assistant.turn_end", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", + "type": "assistant.message_delta", "data": { - "turnId": "0" + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 7 } }, { - "timestampMs": 1770182507215, - "phase": "withInstructions", - "type": "assistant.turn_start", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", + "type": "assistant.message_delta", "data": { - "turnId": "1" + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 16 } }, { - "timestampMs": 1770182507215, - "phase": "withInstructions", - "type": "session.usage_info", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", + "type": "assistant.message_delta", "data": { - "tokenLimit": 64000, - "currentTokens": 11390, - "messagesLength": 5 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 7, + "deltaPreview": " should", + "totalResponseSizeBytes": 23 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "This", - "totalResponseSizeBytes": 4 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": " be", + "totalResponseSizeBytes": 26 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 12, - "deltaPreview": " application", - "totalResponseSizeBytes": 16 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 7, + "deltaPreview": " placed", + "totalResponseSizeBytes": 33 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 17 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 36 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 7, - "deltaPreview": " Primer", - "totalResponseSizeBytes": 24 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 40 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 25 + "deltaPreview": "/", + "totalResponseSizeBytes": 41 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " is", - "totalResponseSizeBytes": 28 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 8, + "deltaPreview": "commands", + "totalResponseSizeBytes": 49 } }, { - "timestampMs": 1770182508277, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 2, - "deltaPreview": " a", - "totalResponseSizeBytes": 30 + "deltaPreview": "/,", + "totalResponseSizeBytes": 51 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 34 + "deltaPreview": " and", + "totalResponseSizeBytes": 55 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 5, - "deltaPreview": " tool", - "totalResponseSizeBytes": 39 + "deltaPreview": " core", + "totalResponseSizeBytes": 60 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": " that", - "totalResponseSizeBytes": 44 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 6, + "deltaPreview": " logic", + "totalResponseSizeBytes": 66 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " analyzes", - "totalResponseSizeBytes": 53 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 7, + "deltaPreview": " should", + "totalResponseSizeBytes": 73 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510565, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": " code", - "totalResponseSizeBytes": 58 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": " go", + "totalResponseSizeBytes": 76 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510699, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": "bases", - "totalResponseSizeBytes": 63 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 79 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510699, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 67 + "deltaPreview": " src", + "totalResponseSizeBytes": 83 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 10, - "deltaPreview": " generates", - "totalResponseSizeBytes": 77 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": "/services", + "totalResponseSizeBytes": 92 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " `.", - "totalResponseSizeBytes": 80 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 2, + "deltaPreview": "/.", + "totalResponseSizeBytes": 94 } }, { - "timestampMs": 1770182508411, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": "github", - "totalResponseSizeBytes": 86 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " The", + "totalResponseSizeBytes": 98 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "/cop", - "totalResponseSizeBytes": 90 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 13, + "deltaPreview": " architecture", + "totalResponseSizeBytes": 111 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "ilot", - "totalResponseSizeBytes": 94 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 5, + "deltaPreview": " uses", + "totalResponseSizeBytes": 116 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "-in", - "totalResponseSizeBytes": 97 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 10, + "deltaPreview": " Commander", + "totalResponseSizeBytes": 126 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 10, - "deltaPreview": "structions", - "totalResponseSizeBytes": 107 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 130 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": ".md", - "totalResponseSizeBytes": 110 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 134 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": "`", - "totalResponseSizeBytes": 111 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 7, + "deltaPreview": " wiring", + "totalResponseSizeBytes": 141 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": " files", - "totalResponseSizeBytes": 117 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 142 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " to", - "totalResponseSizeBytes": 120 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " Ink", + "totalResponseSizeBytes": 146 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": " help", - "totalResponseSizeBytes": 125 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 147 } }, { - "timestampMs": 1770182508656, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " AI", - "totalResponseSizeBytes": 128 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 5, + "deltaPreview": "React", + "totalResponseSizeBytes": 152 } }, { - "timestampMs": 1770182508685, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 7, - "deltaPreview": " coding", - "totalResponseSizeBytes": 135 + "data": { + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 156 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 11, - "deltaPreview": " assistants", - "totalResponseSizeBytes": 146 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 2, + "deltaPreview": " T", + "totalResponseSizeBytes": 158 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 2, - "deltaPreview": " (", - "totalResponseSizeBytes": 148 + "deltaPreview": "UI", + "totalResponseSizeBytes": 160 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "like", - "totalResponseSizeBytes": 152 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 161 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 4, - "deltaPreview": " Git", - "totalResponseSizeBytes": 156 + "deltaPreview": " and", + "totalResponseSizeBytes": 165 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510700, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "Hub", - "totalResponseSizeBytes": 159 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 10, + "deltaPreview": " separates", + "totalResponseSizeBytes": 175 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": " Cop", - "totalResponseSizeBytes": 163 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 8, + "deltaPreview": " command", + "totalResponseSizeBytes": 183 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "ilot", - "totalResponseSizeBytes": 167 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 12, + "deltaPreview": " definitions", + "totalResponseSizeBytes": 195 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ")", - "totalResponseSizeBytes": 168 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 5, + "deltaPreview": " from", + "totalResponseSizeBytes": 200 } }, { - "timestampMs": 1770182508686, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 11, - "deltaPreview": " understand", - "totalResponseSizeBytes": 179 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 8, + "deltaPreview": " service", + "totalResponseSizeBytes": 208 } }, { - "timestampMs": 1770182508748, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " projects", - "totalResponseSizeBytes": 188 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 6, + "deltaPreview": " logic", + "totalResponseSizeBytes": 214 } }, { - "timestampMs": 1770182508748, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 7, - "deltaPreview": " better", - "totalResponseSizeBytes": 195 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 215 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ".", - "totalResponseSizeBytes": 196 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 5, + "deltaPreview": " This", + "totalResponseSizeBytes": 220 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " It", - "totalResponseSizeBytes": 199 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 8, + "deltaPreview": " modular", + "totalResponseSizeBytes": 228 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510853, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " supports", - "totalResponseSizeBytes": 208 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 10, + "deltaPreview": " structure", + "totalResponseSizeBytes": 238 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 11, - "deltaPreview": " repository", - "totalResponseSizeBytes": 219 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 8, + "deltaPreview": " ensures", + "totalResponseSizeBytes": 246 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " analysis", - "totalResponseSizeBytes": 228 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 250 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 229 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 259 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " AI", - "totalResponseSizeBytes": 232 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 4, + "deltaPreview": " are", + "totalResponseSizeBytes": 263 } }, { - "timestampMs": 1770182508750, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 8, - "deltaPreview": "-powered", - "totalResponseSizeBytes": 240 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 5, + "deltaPreview": " thin", + "totalResponseSizeBytes": 268 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 12, - "deltaPreview": " instruction", - "totalResponseSizeBytes": 252 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": " wrappers", + "totalResponseSizeBytes": 277 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 11, - "deltaPreview": " generation", - "totalResponseSizeBytes": 263 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 5, + "deltaPreview": " that", + "totalResponseSizeBytes": 282 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 264 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": " delegate", + "totalResponseSizeBytes": 291 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510854, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 11, - "deltaPreview": " evaluation", - "totalResponseSizeBytes": 275 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 294 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510856, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 276 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": " reusable", + "totalResponseSizeBytes": 303 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510856, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 10, - "deltaPreview": " readiness", - "totalResponseSizeBytes": 286 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 8, + "deltaPreview": " service", + "totalResponseSizeBytes": 311 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510856, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 10, - "deltaPreview": " reporting", - "totalResponseSizeBytes": 296 + "deltaPreview": " functions", + "totalResponseSizeBytes": 321 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", "deltaChars": 1, "deltaPreview": ",", - "totalResponseSizeBytes": 297 + "totalResponseSizeBytes": 322 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": " Git", - "totalResponseSizeBytes": 301 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 10, + "deltaPreview": " following", + "totalResponseSizeBytes": 332 } }, { - "timestampMs": 1770182508991, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "Hub", - "totalResponseSizeBytes": 304 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 2, + "deltaPreview": " a", + "totalResponseSizeBytes": 334 } }, { - "timestampMs": 1770182509181, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "/A", - "totalResponseSizeBytes": 306 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 6, + "deltaPreview": " clear", + "totalResponseSizeBytes": 340 } }, { - "timestampMs": 1770182509181, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "zure", - "totalResponseSizeBytes": 310 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 11, + "deltaPreview": " separation", + "totalResponseSizeBytes": 351 } }, { - "timestampMs": 1770182509181, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": " Dev", - "totalResponseSizeBytes": 314 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 3, + "deltaPreview": " of", + "totalResponseSizeBytes": 354 } }, { - "timestampMs": 1770182509182, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "Ops", - "totalResponseSizeBytes": 317 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 9, + "deltaPreview": " concerns", + "totalResponseSizeBytes": 363 } }, { - "timestampMs": 1770182509182, - "phase": "withInstructions", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 12, - "deltaPreview": " integration", - "totalResponseSizeBytes": 329 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 364 + } + }, + { + "timestampMs": 1770183510911, + "phase": "withoutInstructions", + "type": "assistant.usage", + "data": { + "model": "gpt-4.1", + "inputTokens": 9865, + "outputTokens": 67, + "cacheReadTokens": 9728, + "cacheWriteTokens": 0, + "cost": 0, + "duration": 1133, + "initiator": "user", + "apiCallId": "chatcmpl-D5Pss0idQc01h1Zn1PbmAqLROEQfz", + "providerCallId": "EEC8:177A35:704C54:84447B:6982DB55", + "quotaSnapshots": { + "chat": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "completions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + }, + "premium_interactions_tbb": { + "isUnlimitedEntitlement": true, + "entitlementRequests": -1, + "usedRequests": 0, + "usageAllowedWithExhaustedQuota": true, + "overage": 0, + "overageAllowedWithExhaustedQuota": true, + "remainingPercentage": 100, + "resetDate": "2026-03-01T00:00:00.000Z" + } + } } }, { - "timestampMs": 1770182509182, - "phase": "withInstructions", - "type": "assistant.message_delta", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", + "type": "assistant.message", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 330 + "messageId": "6e0b5102-6f63-4f76-b0d8-9bd7e7d7a28a", + "content": "New CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates command definitions from service logic. This modular structure ensures CLI commands are thin wrappers that delegate to reusable service functions, following a clear separation of concerns.", + "toolRequests": [] } }, { - "timestampMs": 1770182509182, - "phase": "withInstructions", - "type": "assistant.message_delta", + "timestampMs": 1770183510911, + "phase": "withoutInstructions", + "type": "assistant.turn_end", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 334 + "turnId": "0" } }, { - "timestampMs": 1770182509182, - "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " an", - "totalResponseSizeBytes": 337 - } + "timestampMs": 1770183510911, + "phase": "withoutInstructions", + "type": "session.idle", + "data": {} }, { - "timestampMs": 1770182509182, + "timestampMs": 1770183510928, "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 12, - "deltaPreview": " interactive", - "totalResponseSizeBytes": 349 - } + "type": "pending_messages.modified", + "data": {} }, { - "timestampMs": 1770182509182, + "timestampMs": 1770183510928, "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " terminal", - "totalResponseSizeBytes": 358 - } + "type": "pending_messages.modified", + "data": {} }, { - "timestampMs": 1770182509220, + "timestampMs": 1770183511591, "phase": "withInstructions", - "type": "assistant.message_delta", + "type": "user.message", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " UI", - "totalResponseSizeBytes": 361 + "content": "You are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhere should new CLI commands and core logic be placed in the Primer codebase, and what architectural patterns are followed?", + "transformedContent": "2026-02-04T05:38:31.564Z\n\nYou are working in this repository:\n/Users/pierceboggan/Documents/get-ready\nUse the file system tools when needed to inspect the codebase.\n\nWhere should new CLI commands and core logic be placed in the Primer codebase, and what architectural patterns are followed?", + "attachments": [] } }, { - "timestampMs": 1770182509220, + "timestampMs": 1770183511592, "phase": "withInstructions", - "type": "assistant.message_delta", + "type": "assistant.turn_start", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": ".\n\n", - "totalResponseSizeBytes": 364 + "turnId": "0" } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183511592, "phase": "withInstructions", - "type": "assistant.message_delta", + "type": "session.usage_info", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "Main", - "totalResponseSizeBytes": 368 + "tokenLimit": 64000, + "currentTokens": 11316, + "messagesLength": 2 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": " entry", - "totalResponseSizeBytes": 374 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": "New", + "totalResponseSizeBytes": 3 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": "points", - "totalResponseSizeBytes": 380 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 7 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": ":\n", - "totalResponseSizeBytes": 382 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 16 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": "-", - "totalResponseSizeBytes": 383 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " should", + "totalResponseSizeBytes": 23 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 387 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": " be", + "totalResponseSizeBytes": 26 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ":", - "totalResponseSizeBytes": 388 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " placed", + "totalResponseSizeBytes": 33 } }, { - "timestampMs": 1770182509222, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 390 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 36 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": "primer", - "totalResponseSizeBytes": 396 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 40 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 1, - "deltaPreview": "`", - "totalResponseSizeBytes": 397 + "deltaPreview": "/", + "totalResponseSizeBytes": 41 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512432, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " (", - "totalResponseSizeBytes": 399 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 8, + "deltaPreview": "commands", + "totalResponseSizeBytes": 49 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512433, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "main", - "totalResponseSizeBytes": 403 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 2, + "deltaPreview": "/,", + "totalResponseSizeBytes": 51 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512433, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 7, - "deltaPreview": " binary", - "totalResponseSizeBytes": 410 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 55 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512433, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 411 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 5, + "deltaPreview": " core", + "totalResponseSizeBytes": 60 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512433, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 10, - "deltaPreview": " installed", - "totalResponseSizeBytes": 421 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 6, + "deltaPreview": " logic", + "totalResponseSizeBytes": 66 } }, { - "timestampMs": 1770182509308, + "timestampMs": 1770183512433, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " globally", - "totalResponseSizeBytes": 430 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " should", + "totalResponseSizeBytes": 73 } }, { - "timestampMs": 1770182509309, + "timestampMs": 1770183512433, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": ")\n", - "totalResponseSizeBytes": 432 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": " go", + "totalResponseSizeBytes": 76 } }, { - "timestampMs": 1770182509309, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": "-", - "totalResponseSizeBytes": 433 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": " in", + "totalResponseSizeBytes": 79 } }, { - "timestampMs": 1770182509373, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 8, - "deltaPreview": " Program", - "totalResponseSizeBytes": 441 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " src", + "totalResponseSizeBytes": 83 } }, { - "timestampMs": 1770182509373, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": "matic", - "totalResponseSizeBytes": 446 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": "/services", + "totalResponseSizeBytes": 92 } }, { - "timestampMs": 1770182509373, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": ":", - "totalResponseSizeBytes": 447 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 2, + "deltaPreview": "/.", + "totalResponseSizeBytes": 94 } }, { - "timestampMs": 1770182509373, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 449 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " The", + "totalResponseSizeBytes": 98 } }, { - "timestampMs": 1770182509373, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "src", - "totalResponseSizeBytes": 452 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 13, + "deltaPreview": " architecture", + "totalResponseSizeBytes": 111 } }, { - "timestampMs": 1770182509374, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": "/index", - "totalResponseSizeBytes": 458 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 5, + "deltaPreview": " uses", + "totalResponseSizeBytes": 116 } }, { - "timestampMs": 1770182509374, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": ".ts", - "totalResponseSizeBytes": 461 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 10, + "deltaPreview": " Commander", + "totalResponseSizeBytes": 126 } }, { - "timestampMs": 1770182509374, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": "`", - "totalResponseSizeBytes": 462 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 130 } }, { - "timestampMs": 1770182509374, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " (", - "totalResponseSizeBytes": 464 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 134 } }, { - "timestampMs": 1770182509374, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": "calls", - "totalResponseSizeBytes": 469 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " wiring", + "totalResponseSizeBytes": 141 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 471 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 142 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "run", - "totalResponseSizeBytes": 474 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " Ink", + "totalResponseSizeBytes": 146 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "Cli", - "totalResponseSizeBytes": 477 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": "/", + "totalResponseSizeBytes": 147 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "()`", - "totalResponseSizeBytes": 480 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 5, + "deltaPreview": "React", + "totalResponseSizeBytes": 152 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": " in", - "totalResponseSizeBytes": 483 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 156 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 485 + "deltaPreview": " T", + "totalResponseSizeBytes": 158 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "src", - "totalResponseSizeBytes": 488 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 2, + "deltaPreview": "UI", + "totalResponseSizeBytes": 160 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 1, - "deltaPreview": "/", - "totalResponseSizeBytes": 489 + "deltaPreview": ",", + "totalResponseSizeBytes": 161 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": "cli", - "totalResponseSizeBytes": 492 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 165 } }, { - "timestampMs": 1770182511802, + "timestampMs": 1770183512570, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 3, - "deltaPreview": ".ts", - "totalResponseSizeBytes": 495 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 10, + "deltaPreview": " separates", + "totalResponseSizeBytes": 175 } }, { - "timestampMs": 1770182515040, + "timestampMs": 1770183512726, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": "`", - "totalResponseSizeBytes": 496 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " concerns", + "totalResponseSizeBytes": 184 } }, { - "timestampMs": 1770182515040, + "timestampMs": 1770183512726, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 3, - "deltaPreview": ")\n\n", - "totalResponseSizeBytes": 499 - } - }, - { - "timestampMs": 1770182515043, - "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 7, - "deltaPreview": "Primary", - "totalResponseSizeBytes": 506 - } - }, - { - "timestampMs": 1770182515044, - "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": " commands", - "totalResponseSizeBytes": 515 + "deltaPreview": " by", + "totalResponseSizeBytes": 187 } }, { - "timestampMs": 1770182515044, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 8, - "deltaPreview": " include", - "totalResponseSizeBytes": 523 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 10, + "deltaPreview": " directory", + "totalResponseSizeBytes": 197 } }, { - "timestampMs": 1770182515044, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 1, "deltaPreview": ":", - "totalResponseSizeBytes": 524 + "totalResponseSizeBytes": 198 } }, { - "timestampMs": 1770182515044, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 526 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " commands", + "totalResponseSizeBytes": 207 } }, { - "timestampMs": 1770182515044, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 4, - "deltaPreview": "init", - "totalResponseSizeBytes": 530 - } - }, - { - "timestampMs": 1770182515044, - "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 532 - } - }, - { - "timestampMs": 1770182515044, - "phase": "withInstructions", - "type": "assistant.message_delta", - "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 534 + "deltaPreview": " for", + "totalResponseSizeBytes": 211 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "an", - "totalResponseSizeBytes": 536 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " CLI", + "totalResponseSizeBytes": 215 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": "alyze", - "totalResponseSizeBytes": 541 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 6, + "deltaPreview": " entry", + "totalResponseSizeBytes": 221 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 543 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 6, + "deltaPreview": "points", + "totalResponseSizeBytes": 227 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 545 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 228 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 8, - "deltaPreview": "generate", - "totalResponseSizeBytes": 553 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " services", + "totalResponseSizeBytes": 237 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 555 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 241 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 557 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " business", + "totalResponseSizeBytes": 250 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 12, - "deltaPreview": "instructions", - "totalResponseSizeBytes": 569 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 6, + "deltaPreview": " logic", + "totalResponseSizeBytes": 256 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 571 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 257 } }, { - "timestampMs": 1770182515108, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 573 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 261 } }, { - "timestampMs": 1770182515170, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 1, - "deltaPreview": "t", - "totalResponseSizeBytes": 574 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": " ui", + "totalResponseSizeBytes": 264 } }, { - "timestampMs": 1770182515170, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "ui", - "totalResponseSizeBytes": 576 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " for", + "totalResponseSizeBytes": 268 } }, { - "timestampMs": 1770182515172, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 578 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " terminal", + "totalResponseSizeBytes": 277 } }, { - "timestampMs": 1770182515172, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 580 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 11, + "deltaPreview": " interfaces", + "totalResponseSizeBytes": 288 } }, { - "timestampMs": 1770182515172, + "timestampMs": 1770183512727, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": "eval", - "totalResponseSizeBytes": 584 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 289 } }, { - "timestampMs": 1770182515172, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 586 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " The", + "totalResponseSizeBytes": 293 } }, { - "timestampMs": 1770182515173, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 588 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 5, + "deltaPreview": " code", + "totalResponseSizeBytes": 298 } }, { - "timestampMs": 1770182515173, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 4, - "deltaPreview": "read", - "totalResponseSizeBytes": 592 + "deltaPreview": "base", + "totalResponseSizeBytes": 302 } }, { - "timestampMs": 1770182515173, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": "iness", - "totalResponseSizeBytes": 597 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 8, + "deltaPreview": " follows", + "totalResponseSizeBytes": 310 } }, { - "timestampMs": 1770182515173, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 599 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " strict", + "totalResponseSizeBytes": 317 } }, { - "timestampMs": 1770182515321, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 601 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 5, + "deltaPreview": " Type", + "totalResponseSizeBytes": 322 } }, { - "timestampMs": 1770182515321, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "pr", - "totalResponseSizeBytes": 603 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 6, + "deltaPreview": "Script", + "totalResponseSizeBytes": 328 } }, { - "timestampMs": 1770182515322, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 605 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 5, + "deltaPreview": " with", + "totalResponseSizeBytes": 333 } }, { - "timestampMs": 1770182515322, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 607 + "deltaPreview": " E", + "totalResponseSizeBytes": 335 } }, { - "timestampMs": 1770182515323, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 5, - "deltaPreview": "batch", - "totalResponseSizeBytes": 612 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 2, + "deltaPreview": "SM", + "totalResponseSizeBytes": 337 } }, { - "timestampMs": 1770182515323, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 614 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 338 } }, { - "timestampMs": 1770182515323, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 616 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 342 } }, { - "timestampMs": 1770182515323, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 9, - "deltaPreview": "templates", - "totalResponseSizeBytes": 625 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " all", + "totalResponseSizeBytes": 346 } }, { - "timestampMs": 1770182515323, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 627 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 4, + "deltaPreview": " new", + "totalResponseSizeBytes": 350 } }, { - "timestampMs": 1770182515323, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 629 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " features", + "totalResponseSizeBytes": 359 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": "config", - "totalResponseSizeBytes": 635 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " should", + "totalResponseSizeBytes": 366 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`,", - "totalResponseSizeBytes": 637 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 7, + "deltaPreview": " adhere", + "totalResponseSizeBytes": 373 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512871, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 641 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 3, + "deltaPreview": " to", + "totalResponseSizeBytes": 376 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": " `", - "totalResponseSizeBytes": 643 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 6, + "deltaPreview": " these", + "totalResponseSizeBytes": 382 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 6, - "deltaPreview": "update", - "totalResponseSizeBytes": 649 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 9, + "deltaPreview": " patterns", + "totalResponseSizeBytes": 391 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "assistant.message_delta", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "deltaChars": 2, - "deltaPreview": "`.", - "totalResponseSizeBytes": 651 + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 392 } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "assistant.usage", "data": { "model": "gpt-4.1", - "inputTokens": 10830, - "outputTokens": 155, - "cacheReadTokens": 10368, + "inputTokens": 10683, + "outputTokens": 80, + "cacheReadTokens": 0, "cacheWriteTokens": 0, "cost": 0, - "duration": 8136, - "initiator": "agent", - "apiCallId": "chatcmpl-D5PchQpqfCG6WGv6mtHggYQqLqUqA", - "providerCallId": "E903:35A03D:342FF2:3DEEEA:6982D76B", + "duration": 1280, + "initiator": "user", + "apiCallId": "chatcmpl-D5Pst1SRyrfoaXfmP71NWHGhxDTbx", + "providerCallId": "EEC8:177A35:7051FD:844B6C:6982DB57", "quotaSnapshots": { "chat": { "isUnlimitedEntitlement": true, @@ -4230,53 +9242,53 @@ } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "assistant.message", "data": { - "messageId": "b60af17a-24cd-4187-bbde-c7884f33ab13", - "content": "This application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.", + "messageId": "2d5cd1de-4ae7-4051-9934-5ffb545682d9", + "content": "New CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates concerns by directory: commands for CLI entrypoints, services for business logic, and ui for terminal interfaces. The codebase follows strict TypeScript with ESM, and all new features should adhere to these patterns.", "toolRequests": [] } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "assistant.turn_end", "data": { - "turnId": "1" + "turnId": "0" } }, { - "timestampMs": 1770182515351, + "timestampMs": 1770183512872, "phase": "withInstructions", "type": "session.idle", "data": {} }, { - "timestampMs": 1770182515373, + "timestampMs": 1770183512888, "phase": "judge", "type": "pending_messages.modified", "data": {} }, { - "timestampMs": 1770182515373, + "timestampMs": 1770183512888, "phase": "judge", "type": "pending_messages.modified", "data": {} }, { - "timestampMs": 1770182516066, + "timestampMs": 1770183513503, "phase": "judge", "type": "user.message", "data": { - "content": "Evaluate which response best matches the expectation.\n\nExpectation: Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\n\nResponse A (without custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.\n\nResponse B (with custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.\n\nReturn JSON only.", - "transformedContent": "2026-02-04T05:21:56.033Z\n\nEvaluate which response best matches the expectation.\n\nExpectation: Mentions the CLI entrypoint in src/index.ts and that this is the Primer CLI.\n\nResponse A (without custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants understand projects better. It supports repository analysis, AI-powered instruction generation, batch processing, evaluation, readiness reports, and GitHub integration.\n\nMain entrypoints:\n- src/index.ts — CLI entry point\n- src/cli.ts — Commander CLI setup\n\nKey commands include: `primer init`, `primer tui`, `primer instructions`, `primer analyze`, `primer batch`, `primer readiness`, and `primer eval`.\n\nResponse B (with custom instructions):\nThis application, Primer, is a CLI tool that analyzes codebases and generates `.github/copilot-instructions.md` files to help AI coding assistants (like GitHub Copilot) understand projects better. It supports repository analysis, AI-powered instruction generation, evaluation, readiness reporting, GitHub/Azure DevOps integration, and an interactive terminal UI.\n\nMain entrypoints:\n- CLI: `primer` (main binary, installed globally)\n- Programmatic: `src/index.ts` (calls `runCli()` in `src/cli.ts`)\n\nPrimary commands include: `init`, `analyze`, `generate`, `instructions`, `tui`, `eval`, `readiness`, `pr`, `batch`, `templates`, `config`, and `update`.\n\nReturn JSON only.", + "content": "Evaluate which response best matches the expectation.\n\nExpectation: New CLI commands should be placed in src/commands/, and core logic in src/services/. The architecture uses Commander for CLI, Ink/React for TUI, and simple-git/Octokit for GitHub automation, following strict ESM TypeScript conventions.\n\nResponse A (without custom instructions):\nNew CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates command definitions from service logic. This modular structure ensures CLI commands are thin wrappers that delegate to reusable service functions, following a clear separation of concerns.\n\nResponse B (with custom instructions):\nNew CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates concerns by directory: commands for CLI entrypoints, services for business logic, and ui for terminal interfaces. The codebase follows strict TypeScript with ESM, and all new features should adhere to these patterns.\n\nReturn JSON only.", + "transformedContent": "2026-02-04T05:38:33.477Z\n\nEvaluate which response best matches the expectation.\n\nExpectation: New CLI commands should be placed in src/commands/, and core logic in src/services/. The architecture uses Commander for CLI, Ink/React for TUI, and simple-git/Octokit for GitHub automation, following strict ESM TypeScript conventions.\n\nResponse A (without custom instructions):\nNew CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates command definitions from service logic. This modular structure ensures CLI commands are thin wrappers that delegate to reusable service functions, following a clear separation of concerns.\n\nResponse B (with custom instructions):\nNew CLI commands should be placed in src/commands/, and core logic should go in src/services/. The architecture uses Commander for CLI wiring, Ink/React for TUI, and separates concerns by directory: commands for CLI entrypoints, services for business logic, and ui for terminal interfaces. The codebase follows strict TypeScript with ESM, and all new features should adhere to these patterns.\n\nReturn JSON only.", "attachments": [] } }, { - "timestampMs": 1770182516066, + "timestampMs": 1770183513503, "phase": "judge", "type": "assistant.turn_start", "data": { @@ -4284,932 +9296,756 @@ } }, { - "timestampMs": 1770182516066, + "timestampMs": 1770183513503, "phase": "judge", "type": "session.usage_info", "data": { "tokenLimit": 64000, - "currentTokens": 10644, + "currentTokens": 10704, "messagesLength": 2 } }, { - "timestampMs": 1770182516954, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 2, - "deltaPreview": "{\n", + "deltaPreview": "{\"", "totalResponseSizeBytes": 2 } }, { - "timestampMs": 1770182516954, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": " ", - "totalResponseSizeBytes": 3 - } - }, - { - "timestampMs": 1770182516954, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": " \"", - "totalResponseSizeBytes": 5 - } - }, - { - "timestampMs": 1770182516954, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 3, "deltaPreview": "ver", - "totalResponseSizeBytes": 8 + "totalResponseSizeBytes": 5 } }, { - "timestampMs": 1770182516954, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 4, "deltaPreview": "dict", - "totalResponseSizeBytes": 12 + "totalResponseSizeBytes": 9 } }, { - "timestampMs": 1770182516954, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 2, "deltaPreview": "\":", - "totalResponseSizeBytes": 14 + "totalResponseSizeBytes": 11 } }, { - "timestampMs": 1770182516954, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 2, "deltaPreview": " \"", - "totalResponseSizeBytes": 16 + "totalResponseSizeBytes": 13 } }, { - "timestampMs": 1770182516954, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 4, "deltaPreview": "pass", - "totalResponseSizeBytes": 20 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": "\",\n", - "totalResponseSizeBytes": 23 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": " ", - "totalResponseSizeBytes": 24 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": " \"", - "totalResponseSizeBytes": 26 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": "score", - "totalResponseSizeBytes": 31 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": "\":", - "totalResponseSizeBytes": 33 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": " ", - "totalResponseSizeBytes": 34 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": "100", - "totalResponseSizeBytes": 37 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": ",\n", - "totalResponseSizeBytes": 39 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": " ", - "totalResponseSizeBytes": 40 - } - }, - { - "timestampMs": 1770182517128, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": " \"", - "totalResponseSizeBytes": 42 - } - }, - { - "timestampMs": 1770182517320, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": "r", - "totalResponseSizeBytes": 43 - } - }, - { - "timestampMs": 1770182517320, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 8, - "deltaPreview": "ationale", - "totalResponseSizeBytes": 51 - } - }, - { - "timestampMs": 1770182517322, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": "\":", - "totalResponseSizeBytes": 53 - } - }, - { - "timestampMs": 1770182517322, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": " \"", - "totalResponseSizeBytes": 55 - } - }, - { - "timestampMs": 1770182517322, - "phase": "judge", - "type": "assistant.message_delta", - "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 8, - "deltaPreview": "Response", - "totalResponseSizeBytes": 63 + "totalResponseSizeBytes": 17 } }, { - "timestampMs": 1770182517322, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 2, - "deltaPreview": " B", - "totalResponseSizeBytes": 65 + "deltaPreview": "\",", + "totalResponseSizeBytes": 19 } }, { - "timestampMs": 1770182517322, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": " best", - "totalResponseSizeBytes": 70 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 21 } }, { - "timestampMs": 1770182517322, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 8, - "deltaPreview": " matches", - "totalResponseSizeBytes": 78 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 5, + "deltaPreview": "score", + "totalResponseSizeBytes": 26 } }, { - "timestampMs": 1770182517323, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " the", - "totalResponseSizeBytes": 82 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 28 } }, { - "timestampMs": 1770182517323, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 12, - "deltaPreview": " expectation", - "totalResponseSizeBytes": 94 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": " ", + "totalResponseSizeBytes": 29 } }, { - "timestampMs": 1770182517396, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 3, - "deltaPreview": " by", - "totalResponseSizeBytes": 97 + "deltaPreview": "100", + "totalResponseSizeBytes": 32 } }, { - "timestampMs": 1770182517396, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 11, - "deltaPreview": " explicitly", - "totalResponseSizeBytes": 108 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 33 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 11, - "deltaPreview": " mentioning", - "totalResponseSizeBytes": 119 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 35 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " the", - "totalResponseSizeBytes": 123 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": "r", + "totalResponseSizeBytes": 36 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514361, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 127 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 8, + "deltaPreview": "ationale", + "totalResponseSizeBytes": 44 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514513, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 6, - "deltaPreview": " entry", - "totalResponseSizeBytes": 133 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": "\":", + "totalResponseSizeBytes": 46 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514513, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": "point", - "totalResponseSizeBytes": 138 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": " \"", + "totalResponseSizeBytes": 48 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514513, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": " in", - "totalResponseSizeBytes": 141 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 4, + "deltaPreview": "Both", + "totalResponseSizeBytes": 52 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514513, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " src", - "totalResponseSizeBytes": 145 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 10, + "deltaPreview": " responses", + "totalResponseSizeBytes": 62 } }, { - "timestampMs": 1770182517398, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 6, - "deltaPreview": "/index", - "totalResponseSizeBytes": 151 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 11, + "deltaPreview": " accurately", + "totalResponseSizeBytes": 73 } }, { - "timestampMs": 1770182517588, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": ".ts", - "totalResponseSizeBytes": 154 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 9, + "deltaPreview": " describe", + "totalResponseSizeBytes": 82 } }, { - "timestampMs": 1770182517588, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 155 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 86 } }, { - "timestampMs": 1770182517588, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": " clar", - "totalResponseSizeBytes": 160 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 10, + "deltaPreview": " directory", + "totalResponseSizeBytes": 96 } }, { - "timestampMs": 1770182517588, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 6, - "deltaPreview": "ifying", - "totalResponseSizeBytes": 166 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 10, + "deltaPreview": " structure", + "totalResponseSizeBytes": 106 } }, { - "timestampMs": 1770182517588, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": " that", - "totalResponseSizeBytes": 171 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 110 } }, { - "timestampMs": 1770182517589, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": " it", - "totalResponseSizeBytes": 174 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 14, + "deltaPreview": " architectural", + "totalResponseSizeBytes": 124 } }, { - "timestampMs": 1770182517589, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 6, - "deltaPreview": " calls", - "totalResponseSizeBytes": 180 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 12, + "deltaPreview": " conventions", + "totalResponseSizeBytes": 136 } }, { - "timestampMs": 1770182517589, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " run", - "totalResponseSizeBytes": 184 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 137 } }, { - "timestampMs": 1770182517589, + "timestampMs": 1770183514516, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": "Cli", - "totalResponseSizeBytes": 187 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 8, + "deltaPreview": " However", + "totalResponseSizeBytes": 145 } }, { - "timestampMs": 1770182517589, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": " in", - "totalResponseSizeBytes": 190 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 146 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " src", - "totalResponseSizeBytes": 194 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 9, + "deltaPreview": " Response", + "totalResponseSizeBytes": 155 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": "/", - "totalResponseSizeBytes": 195 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": " B", + "totalResponseSizeBytes": 157 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": "cli", - "totalResponseSizeBytes": 198 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 11, + "deltaPreview": " explicitly", + "totalResponseSizeBytes": 168 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": ".ts", - "totalResponseSizeBytes": 201 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 9, + "deltaPreview": " mentions", + "totalResponseSizeBytes": 177 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": ",", - "totalResponseSizeBytes": 202 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 7, + "deltaPreview": " strict", + "totalResponseSizeBytes": 184 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514517, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 206 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 5, + "deltaPreview": " Type", + "totalResponseSizeBytes": 189 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 12, - "deltaPreview": " identifying", - "totalResponseSizeBytes": 218 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 6, + "deltaPreview": "Script", + "totalResponseSizeBytes": 195 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 5, - "deltaPreview": " this", - "totalResponseSizeBytes": 223 + "deltaPreview": " with", + "totalResponseSizeBytes": 200 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": " as", - "totalResponseSizeBytes": 226 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": " E", + "totalResponseSizeBytes": 202 } }, { - "timestampMs": 1770182517772, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " the", - "totalResponseSizeBytes": 230 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": "SM", + "totalResponseSizeBytes": 204 } }, { - "timestampMs": 1770182517946, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 7, - "deltaPreview": " Primer", - "totalResponseSizeBytes": 237 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 4, + "deltaPreview": " and", + "totalResponseSizeBytes": 208 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " CLI", - "totalResponseSizeBytes": 241 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 11, + "deltaPreview": " emphasizes", + "totalResponseSizeBytes": 219 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 1, - "deltaPreview": ".", - "totalResponseSizeBytes": 242 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 10, + "deltaPreview": " adherence", + "totalResponseSizeBytes": 229 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 3, - "deltaPreview": " It", - "totalResponseSizeBytes": 245 + "deltaPreview": " to", + "totalResponseSizeBytes": 232 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": " also", - "totalResponseSizeBytes": 250 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 6, + "deltaPreview": " these", + "totalResponseSizeBytes": 238 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 9, - "deltaPreview": " provides", - "totalResponseSizeBytes": 259 + "deltaPreview": " patterns", + "totalResponseSizeBytes": 247 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 2, - "deltaPreview": " a", - "totalResponseSizeBytes": 261 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": ",", + "totalResponseSizeBytes": 248 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 5, - "deltaPreview": " more", - "totalResponseSizeBytes": 266 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 6, + "deltaPreview": " which", + "totalResponseSizeBytes": 254 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 9, - "deltaPreview": " complete", - "totalResponseSizeBytes": 275 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 7, + "deltaPreview": " aligns", + "totalResponseSizeBytes": 261 } }, { - "timestampMs": 1770182517947, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 279 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 5, + "deltaPreview": " more", + "totalResponseSizeBytes": 266 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 9, - "deltaPreview": " accurate", - "totalResponseSizeBytes": 288 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 8, + "deltaPreview": " closely", + "totalResponseSizeBytes": 274 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 5, - "deltaPreview": " list", - "totalResponseSizeBytes": 293 + "deltaPreview": " with", + "totalResponseSizeBytes": 279 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": " of", - "totalResponseSizeBytes": 296 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 4, + "deltaPreview": " the", + "totalResponseSizeBytes": 283 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 9, - "deltaPreview": " commands", - "totalResponseSizeBytes": 305 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 12, + "deltaPreview": " expectation", + "totalResponseSizeBytes": 295 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 4, - "deltaPreview": " and", - "totalResponseSizeBytes": 309 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 1, + "deltaPreview": ".", + "totalResponseSizeBytes": 296 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514647, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 9, - "deltaPreview": " features", - "totalResponseSizeBytes": 318 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 10, + "deltaPreview": " Therefore", + "totalResponseSizeBytes": 306 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514648, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 1, "deltaPreview": ",", - "totalResponseSizeBytes": 319 + "totalResponseSizeBytes": 307 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514696, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 9, - "deltaPreview": " aligning", - "totalResponseSizeBytes": 328 + "deltaPreview": " Response", + "totalResponseSizeBytes": 316 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 8, - "deltaPreview": " closely", - "totalResponseSizeBytes": 336 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": " B", + "totalResponseSizeBytes": 318 } }, { - "timestampMs": 1770182518109, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 5, - "deltaPreview": " with", - "totalResponseSizeBytes": 341 + "deltaPreview": " best", + "totalResponseSizeBytes": 323 + } + }, + { + "timestampMs": 1770183514697, + "phase": "judge", + "type": "assistant.message_delta", + "data": { + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 8, + "deltaPreview": " matches", + "totalResponseSizeBytes": 331 } }, { - "timestampMs": 1770182518143, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 4, "deltaPreview": " the", - "totalResponseSizeBytes": 345 + "totalResponseSizeBytes": 335 } }, { - "timestampMs": 1770182518143, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 12, "deltaPreview": " expectation", - "totalResponseSizeBytes": 357 + "totalResponseSizeBytes": 347 } }, { - "timestampMs": 1770182518144, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "deltaChars": 3, - "deltaPreview": ".\"\n", - "totalResponseSizeBytes": 360 + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "deltaChars": 2, + "deltaPreview": ".\"", + "totalResponseSizeBytes": 349 } }, { - "timestampMs": 1770182518144, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message_delta", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", "deltaChars": 1, "deltaPreview": "}", - "totalResponseSizeBytes": 361 + "totalResponseSizeBytes": 350 } }, { - "timestampMs": 1770182518144, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.usage", "data": { "model": "gpt-4.1", - "inputTokens": 10011, - "outputTokens": 84, - "cacheReadTokens": 9088, + "inputTokens": 10071, + "outputTokens": 67, + "cacheReadTokens": 0, "cacheWriteTokens": 0, "cost": 0, - "duration": 2076, + "duration": 1193, "initiator": "user", - "apiCallId": "chatcmpl-D5PcqfwwPo46O2E5lE3WeAmcIK1Zi", - "providerCallId": "E903:35A03D:344C2A:3E0F67:6982D774", + "apiCallId": "chatcmpl-D5PsvwVHQq8uzYv8tYIeUbH1KGMBI", + "providerCallId": "EEC8:177A35:7058AD:84531E:6982DB59", "quotaSnapshots": { "chat": { "isUnlimitedEntitlement": true, @@ -5255,17 +10091,17 @@ } }, { - "timestampMs": 1770182518144, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.message", "data": { - "messageId": "6ad656ac-ac73-46bf-84ec-17eb192a7cbe", - "content": "{\n \"verdict\": \"pass\",\n \"score\": 100,\n \"rationale\": \"Response B best matches the expectation by explicitly mentioning the CLI entrypoint in src/index.ts, clarifying that it calls runCli in src/cli.ts, and identifying this as the Primer CLI. It also provides a more complete and accurate list of commands and features, aligning closely with the expectation.\"\n}", + "messageId": "4f11d677-e5a6-4faa-ad11-da2ace577be9", + "content": "{\"verdict\": \"pass\", \"score\": 100, \"rationale\": \"Both responses accurately describe the directory structure and architectural conventions. However, Response B explicitly mentions strict TypeScript with ESM and emphasizes adherence to these patterns, which aligns more closely with the expectation. Therefore, Response B best matches the expectation.\"}", "toolRequests": [] } }, { - "timestampMs": 1770182518144, + "timestampMs": 1770183514697, "phase": "judge", "type": "assistant.turn_end", "data": { @@ -5273,7 +10109,7 @@ } }, { - "timestampMs": 1770182518144, + "timestampMs": 1770183514697, "phase": "judge", "type": "session.idle", "data": {} diff --git a/src/cli.ts b/src/cli.ts index 4382f71..77cf4a9 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -55,6 +55,7 @@ export function runCli(argv: string[]): void { .option("--repo ", "Repository path", process.cwd()) .option("--model ", "Model for responses", "gpt-5") .option("--judge-model ", "Model for judging", "gpt-5") + .option("--list-models", "List Copilot CLI models and exit") .option("--output ", "Write results JSON to file") .option("--init", "Create a starter primer.eval.json file") .option("--count ", "Number of eval cases to generate (with --init)") diff --git a/src/commands/eval.ts b/src/commands/eval.ts index c592b1a..104a069 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -1,6 +1,7 @@ import path from "path"; import fs from "fs/promises"; import { runEval } from "../services/evaluator"; +import { listCopilotModels } from "../services/copilot"; import { generateEvalScaffold } from "../services/evalScaffold"; type EvalOptions = { @@ -10,10 +11,21 @@ type EvalOptions = { output?: string; init?: boolean; count?: string; + listModels?: boolean; }; export async function evalCommand(configPathArg: string | undefined, options: EvalOptions): Promise { const repoPath = path.resolve(options.repo ?? process.cwd()); + + if (options.listModels) { + const models = await listCopilotModels(); + if (!models.length) { + console.log("No models detected from Copilot CLI."); + return; + } + console.log(models.join("\n")); + return; + } // Handle --init flag if (options.init) { diff --git a/src/services/copilot.ts b/src/services/copilot.ts index 0cec90a..38af3eb 100644 --- a/src/services/copilot.ts +++ b/src/services/copilot.ts @@ -16,6 +16,12 @@ export async function assertCopilotCliReady(): Promise { return cliPath; } +export async function listCopilotModels(): Promise { + const cliPath = await assertCopilotCliReady(); + const { stdout } = await execFileAsync(cliPath, ["--help"], { timeout: 5000 }); + return extractModelChoices(stdout); +} + async function findCopilotCliPath(): Promise { try { const { stdout } = await execFileAsync("which", ["copilot"], { timeout: 5000 }); @@ -43,3 +49,33 @@ async function findCopilotCliPath(): Promise { throw new Error("Copilot CLI not found. Install GitHub Copilot Chat extension in VS Code."); } + +function extractModelChoices(helpText: string): string[] { + const lines = helpText.split("\n"); + let captured = ""; + + for (let index = 0; index < lines.length; index += 1) { + const line = lines[index]; + if (!line.includes("--model")) continue; + + captured = line.trim(); + while (!captured.includes(")") && index + 1 < lines.length) { + index += 1; + captured += ` ${lines[index].trim()}`; + } + break; + } + + const match = captured.match(/choices:\s*([^)]*)/); + if (!match) return []; + + const models: string[] = []; + const matcher = /"([^"]+)"/g; + let entry = matcher.exec(match[1]); + while (entry) { + models.push(entry[1]); + entry = matcher.exec(match[1]); + } + + return models; +} diff --git a/src/services/evaluator.ts b/src/services/evaluator.ts index d325e87..ed7fce5 100644 --- a/src/services/evaluator.ts +++ b/src/services/evaluator.ts @@ -636,6 +636,7 @@ function buildTrajectoryViewerHtml(data: Record): string { .section h3 { margin: 8px 0; font-size: 14px; color: #c7ccd6; } .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; } .chip { background: #1e2232; border: 1px solid #2c3250; border-radius: 999px; padding: 2px 8px; font-size: 12px; color: #c9d1e3; } + .chip.phase { background: #23283b; border-color: #3a4163; color: #aeb7c6; } .muted { color: #8a93a5; font-size: 12px; } .filters { display: flex; gap: 12px; align-items: center; margin-top: 8px; } .filters label { font-size: 12px; color: #b7bdc8; } @@ -674,6 +675,7 @@ function buildTrajectoryViewerHtml(data: Record): string { const results = data.results || []; let activeCaseId = null; let toolsOnly = false; + let phaseFilter = 'all'; summaryEl.textContent = 'Repo: ' + (data.repoPath || 'unknown') + @@ -682,10 +684,11 @@ function buildTrajectoryViewerHtml(data: Record): string { ' • Judge: ' + (data.judgeModel || 'unknown'); - function collectToolCounts(events) { + function collectToolCounts(events, phase) { const counts = { total: 0, byName: {} }; if (!events) return counts; events.forEach((event) => { + if (phase && event.phase !== phase) return; if (event.type !== 'tool.execution_start') return; const name = (event.data && event.data.toolName) || 'unknown'; counts.total += 1; @@ -746,7 +749,7 @@ function buildTrajectoryViewerHtml(data: Record): string { return ( 'Duration: ' + m.durationMs + - 'ms • Tokens: ' + + 'ms • Tokens (prompt/completion/total): ' + prompt + ' / ' + completion + @@ -776,9 +779,11 @@ function buildTrajectoryViewerHtml(data: Record): string { function renderTrajectory(events) { if (!events || !events.length) return '

No trajectory events captured.

'; - const filtered = toolsOnly - ? events.filter((event) => event.type.startsWith('tool.')) - : events; + const filtered = events.filter((event) => { + if (phaseFilter !== 'all' && event.phase !== phaseFilter) return false; + if (toolsOnly && !event.type.startsWith('tool.')) return false; + return true; + }); return ( '
' + filtered @@ -811,12 +816,23 @@ function buildTrajectoryViewerHtml(data: Record): string { activeCaseId = result.id; renderCaseList(result.id); const toolCounts = collectToolCounts(result.trajectory || []); + const toolCountsWithout = collectToolCounts(result.trajectory || [], 'withoutInstructions'); + const toolCountsWith = collectToolCounts(result.trajectory || [], 'withInstructions'); + const toolCountsJudge = collectToolCounts(result.trajectory || [], 'judge'); caseDetailsEl.innerHTML = '

' + escapeHtml(result.id) + '

' + '
' + '' + + '' + '
' + '
' + '

Tool calls

' + @@ -824,6 +840,19 @@ function buildTrajectoryViewerHtml(data: Record): string { renderToolChips(toolCounts, 8) + '
' + '
' + + '

Tool calls by phase

' + + '
Without: ' + toolCountsWithout.total + ' • With: ' + toolCountsWith.total + ' • Judge: ' + toolCountsJudge.total + '
' + + '
' + + 'withoutInstructions' + renderToolChips(toolCountsWithout, 6) + + '
' + + '
' + + 'withInstructions' + renderToolChips(toolCountsWith, 6) + + '
' + + '
' + + 'judge' + renderToolChips(toolCountsJudge, 6) + + '
' + + '
' + + '
' + '

Summary

' + '

Verdict: ' + escapeHtml(result.verdict ?? 'unknown') + @@ -853,6 +882,14 @@ function buildTrajectoryViewerHtml(data: Record): string { renderCaseDetails(activeCaseId); }); } + + const phaseSelect = document.getElementById('phaseFilter'); + if (phaseSelect) { + phaseSelect.addEventListener('change', (event) => { + phaseFilter = event.target.value || 'all'; + renderCaseDetails(activeCaseId); + }); + } } renderOverallToolSummary(); diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index 02949d7..9c16ce6 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -8,8 +8,11 @@ import { runEval, type EvalResult } from "../services/evaluator"; import { generateEvalScaffold } from "../services/evalScaffold"; import { AnimatedBanner, StaticBanner } from "./AnimatedBanner"; import { BatchTui } from "./BatchTui"; +import { BatchTuiAzure } from "./BatchTuiAzure"; import { getGitHubToken } from "../services/github"; +import { getAzureDevOpsToken } from "../services/azureDevops"; import { safeWriteFile } from "../utils/fs"; +import { ReadinessReport, ReadinessCriterionResult, runReadinessReport } from "../services/readiness"; type Props = { repoPath: string; @@ -21,12 +24,14 @@ type Status = | "idle" | "analyzing" | "generating" + | "readiness" | "bootstrapping" | "evaluating" | "preview" | "done" | "error" - | "batch" + | "batch-github" + | "batch-azure" | "bootstrapEvalCount" | "bootstrapEvalConfirm"; @@ -46,8 +51,10 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const [evalResults, setEvalResults] = useState(null); const [evalViewerPath, setEvalViewerPath] = useState(null); const [batchToken, setBatchToken] = useState(null); + const [batchAzureToken, setBatchAzureToken] = useState(null); const [evalCaseCountInput, setEvalCaseCountInput] = useState(""); const [evalBootstrapCount, setEvalBootstrapCount] = useState(null); + const [readinessReport, setReadinessReport] = useState(null); const repoLabel = useMemo(() => repoPath, [repoPath]); const handleAnimationComplete = () => { @@ -223,7 +230,21 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return; } setBatchToken(token); - setStatus("batch"); + setStatus("batch-github"); + return; + } + + if (input.toLowerCase() === "z") { + setStatus("analyzing"); + setMessage("Checking Azure DevOps authentication..."); + const token = getAzureDevOpsToken(); + if (!token) { + setStatus("error"); + setMessage("Azure DevOps PAT required. Set AZURE_DEVOPS_PAT or AZDO_PAT."); + return; + } + setBatchAzureToken(token); + setStatus("batch-azure"); return; } @@ -269,6 +290,21 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setEvalCaseCountInput(""); setEvalBootstrapCount(null); } + + if (input.toLowerCase() === "r") { + setStatus("readiness"); + setMessage("Running readiness report..."); + setReadinessReport(null); + try { + const report = await runReadinessReport({ repoPath }); + setReadinessReport(report); + setStatus("done"); + setMessage("Readiness report complete."); + } catch (error) { + setStatus("error"); + setMessage(error instanceof Error ? error.message : "Readiness report failed."); + } + } }); const statusLabel = status === "intro" ? "starting" : status === "idle" ? "ready" : status; @@ -287,10 +323,14 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const truncatedPreview = previewLines.join("\n") + (generatedContent.split("\n").length > 20 ? "\n..." : ""); // Render BatchTui when in batch mode - if (status === "batch" && batchToken) { + if (status === "batch-github" && batchToken) { return ; } + if (status === "batch-azure" && batchAzureToken) { + return ; + } + return ( {status === "intro" ? ( @@ -352,6 +392,29 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX )} )} + {readinessReport && ( + + Readiness Report: + Level: {readinessReport.achievedLevel || 1} ({levelName(readinessReport.achievedLevel || 1)}) + Monorepo: {readinessReport.isMonorepo ? "yes" : "no"}{readinessReport.apps.length ? ` (${readinessReport.apps.length} apps)` : ""} + Pillars: + {readinessReport.pillars.map((pillar) => ( + = 0.8 ? "green" : "yellow"}> + {pillar.name}: {pillar.passed}/{pillar.total} ({formatPercent(pillar.passRate)}) + + ))} + {topFixes(readinessReport.criteria).length > 0 && ( + <> + Fix first: + {topFixes(readinessReport.criteria).map((fix) => ( + + - {fix.title} ({fix.impact}/{fix.effort}) + + ))} + + )} + + )} {status === "intro" ? ( Press any key to skip animation... @@ -360,9 +423,44 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX ) : status === "bootstrapEvalConfirm" ? ( Keys: [Y] Overwrite [N] Cancel [Q] Quit ) : ( - Keys: [A] Analyze [G] Generate [E] Eval [I] Init Eval [B] Batch [Q] Quit + Keys: [A] Analyze [G] Generate [R] Readiness [E] Eval [I] Init Eval [B] Batch [Z] Batch Azure [Q] Quit )} ); } + +function topFixes(criteria: ReadinessCriterionResult[]): ReadinessCriterionResult[] { + return criteria + .filter((criterion) => criterion.status === "fail") + .sort((a, b) => { + const impactDelta = impactWeight(b.impact) - impactWeight(a.impact); + if (impactDelta !== 0) return impactDelta; + return effortWeight(a.effort) - effortWeight(b.effort); + }) + .slice(0, 5); +} + +function impactWeight(value: "high" | "medium" | "low"): number { + if (value === "high") return 3; + if (value === "medium") return 2; + return 1; +} + +function effortWeight(value: "low" | "medium" | "high"): number { + if (value === "low") return 1; + if (value === "medium") return 2; + return 3; +} + +function formatPercent(value: number): string { + return `${Math.round(value * 100)}%`; +} + +function levelName(level: number): string { + if (level === 2) return "Documented"; + if (level === 3) return "Standardized"; + if (level === 4) return "Optimized"; + if (level === 5) return "Autonomous"; + return "Functional"; +} From 3dc1fe6e77dbf938319031a48a0ca52ce290d854 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Tue, 3 Feb 2026 22:46:33 -0700 Subject: [PATCH 05/19] Enhance evaluation scaffolding with system message for repository context - Added a systemMessage field to primer.eval.json to clarify response context. - Updated evalScaffold.ts to include instructions for incorporating the system message in generated cases. - Modified evaluator.ts to use a default system message when none is provided, ensuring responses are relevant to the repository. --- eval-results.html | 2 +- eval-results.json | 6687 ++++++++++++++-------------------- examples/primer.eval.json | 1 + src/services/evalScaffold.ts | 7 +- src/services/evaluator.ts | 8 +- 5 files changed, 2813 insertions(+), 3892 deletions(-) diff --git a/eval-results.html b/eval-results.html index 3d2da62..b7babab 100644 --- a/eval-results.html +++ b/eval-results.html @@ -37,7 +37,7 @@

Primer Eval Trajectory

`; } +// ── Helper Functions ────────────────────────────────────────────────── + function calculatePillarStats(reports: Array<{ repo: string; report: ReadinessReport }>): Array<{ id: string; name: string; @@ -494,18 +604,18 @@ function getTopFixesHtml(report: ReadinessReport): string { .slice(0, 3); if (failedCriteria.length === 0) { - return '
✅ All criteria passing!
'; + return '
All criteria passing
'; } return ` -
-
Top Fixes Needed:
-
    +
    +
    Top Fixes Needed
    +
      ${failedCriteria.map(c => ` -
    • - - ${escapeHtml(c.title)} - (${c.impact} impact, ${c.effort} effort) +
    • + + ${escapeHtml(c.title)} + ${c.impact} impact, ${c.effort} effort
    • `).join('')}
    @@ -524,12 +634,165 @@ function getLevelName(level: number): string { return names[level] || "Unknown"; } +function getLevelDescription(level: number): string { + const descriptions: Record = { + 1: "Repo builds, tests run, and basic tooling (linter, lockfile) is in place. AI agents can clone and get started.", + 2: "README, CONTRIBUTING guide, and custom AI instructions exist. Agents understand project context and conventions.", + 3: "CI/CD, security policies, CODEOWNERS, and observability are configured. Agents operate within well-defined guardrails.", + 4: "MCP servers, custom agents, and AI skills are set up. Agents have deep integration with project-specific tools and workflows.", + 5: "Full AI-native development: agents can independently plan, implement, test, and ship changes with minimal human oversight." + }; + return descriptions[level] || ""; +} + function getProgressClass(passRate: number): string { if (passRate >= 0.8) return "high"; if (passRate >= 0.5) return "medium"; return "low"; } +// ── AI Tooling Hero ─────────────────────────────────────────────────── + +type AiToolingCriterionSummary = { + id: string; + title: string; + passCount: number; + totalRepos: number; + status: "pass" | "fail"; + evidence: string[]; + reason: string; +}; + +type AiToolingData = { + criteria: AiToolingCriterionSummary[]; + passed: number; + total: number; + passRate: number; +}; + +function calculateAiToolingData(reports: Array<{ repo: string; report: ReadinessReport }>): AiToolingData { + const criterionMap = new Map(); + + for (const { report } of reports) { + const aiCriteria = report.criteria.filter(c => c.pillar === "ai-tooling"); + for (const c of aiCriteria) { + const existing = criterionMap.get(c.id); + if (existing) { + existing.totalRepos += 1; + if (c.status === "pass") existing.passCount += 1; + if (c.evidence) existing.evidence.push(...c.evidence); + } else { + criterionMap.set(c.id, { + id: c.id, + title: c.title, + passCount: c.status === "pass" ? 1 : 0, + totalRepos: 1, + status: c.status === "pass" ? "pass" : "fail", + evidence: c.evidence ? [...c.evidence] : [], + reason: c.reason || "" + }); + } + } + } + + const criteria = Array.from(criterionMap.values()).map(c => ({ + ...c, + status: (c.passCount / c.totalRepos >= 0.5 ? "pass" : "fail") as "pass" | "fail", + evidence: [...new Set(c.evidence)] + })); + + const passed = criteria.filter(c => c.status === "pass").length; + return { + criteria, + passed, + total: criteria.length, + passRate: criteria.length > 0 ? passed / criteria.length : 0 + }; +} + +function getAiScoreClass(passRate: number): string { + if (passRate >= 0.6) return "score-high"; + if (passRate >= 0.3) return "score-medium"; + return "score-low"; +} + +function getAiScoreLabel(passRate: number): string { + if (passRate >= 0.8) return "Excellent"; + if (passRate >= 0.6) return "Good"; + if (passRate >= 0.4) return "Fair"; + if (passRate >= 0.2) return "Getting Started"; + return "Not Started"; +} + +function getAiCriterionIcon(id: string): string { + const icons: Record = { + "custom-instructions": "📝", + "mcp-config": "🔌", + "custom-agents": "🤖", + "copilot-skills": "⚡" + }; + return icons[id] || "🔧"; +} + +function buildAiToolingHeroHtml(data: AiToolingData, reports: Array<{ repo: string; report: ReadinessReport }>): string { + if (data.criteria.length === 0) return ""; + + const pct = Math.round(data.passRate * 100); + const scoreClass = getAiScoreClass(data.passRate); + const scoreLabel = getAiScoreLabel(data.passRate); + + const multiRepo = reports.length > 1; + const perRepoHtml = multiRepo ? ` +
    +
    Per Repository
    +
    + ${reports.map(({ repo, report }) => { + const aiPillar = report.pillars.find(p => p.id === "ai-tooling"); + const repoPct = aiPillar ? Math.round(aiPillar.passRate * 100) : 0; + const repoPass = aiPillar?.passed ?? 0; + const repoTotal = aiPillar?.total ?? 0; + return `
    + ${escapeHtml(repo)} + ${repoPass}/${repoTotal} (${repoPct}%) +
    `; + }).join('')} +
    +
    + ` : ''; + + return ` +
    +

    AI Tooling Readiness

    +

    How well prepared ${multiRepo ? 'your repositories are' : 'this repository is'} for AI-assisted development

    + +
    +
    ${pct}%
    +
    +
    ${scoreLabel}
    +
    ${data.passed} of ${data.total} AI tooling checks passing${multiRepo ? ` across ${reports.length} repositories` : ''}
    +
    +
    + +
    + ${data.criteria.map(c => ` +
    +
    + ${c.status === 'pass' ? '✓' : '✗'} +
    +
    +
    ${getAiCriterionIcon(c.id)} ${escapeHtml(c.title)}
    +
    ${c.status === 'pass' + ? (multiRepo ? `${c.passCount}/${c.totalRepos} repos` : 'Detected') + : escapeHtml(c.reason)}
    +
    +
    + `).join('')} +
    + ${perRepoHtml} +
    + `; +} + function escapeHtml(text: string): string { const map: Record = { "&": "&", diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index 517e767..1399448 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from "react"; +import React, { useEffect, useMemo, useState, useRef } from "react"; import { Box, Key, Text, useApp, useInput } from "ink"; import fs from "fs/promises"; import path from "path"; @@ -12,7 +12,6 @@ import { BatchTuiAzure } from "./BatchTuiAzure"; import { getGitHubToken } from "../services/github"; import { getAzureDevOpsToken } from "../services/azureDevops"; import { safeWriteFile } from "../utils/fs"; -import { ReadinessReport, ReadinessCriterionResult, runReadinessReport } from "../services/readiness"; type Props = { repoPath: string; @@ -23,24 +22,70 @@ type Status = | "intro" | "idle" | "generating" - | "readiness" | "bootstrapping" | "evaluating" | "preview" | "done" | "error" + | "batch-pick" | "batch-github" | "batch-azure" + | "eval-pick" | "bootstrapEvalCount" | "bootstrapEvalConfirm"; -type EvalConfig = { - instructionFile?: string; - cases: Array<{ id: string; prompt: string; expectation: string }>; - systemMessage?: string; - outputPath?: string; +type LogEntry = { + text: string; + type: "info" | "success" | "error" | "progress"; + time: string; }; +const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; + +function useSpinner(active: boolean): string { + const [frame, setFrame] = useState(0); + useEffect(() => { + if (!active) return; + const interval = setInterval(() => { + setFrame((f) => (f + 1) % SPINNER_FRAMES.length); + }, 80); + return () => clearInterval(interval); + }, [active]); + return active ? SPINNER_FRAMES[frame] : ""; +} + +function timestamp(): string { + return new Date().toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" }); +} + +function KeyHint({ k, label }: { k: string; label: string }): React.JSX.Element { + return ( + + {"["} + {k} + {"]"} + {label} + + ); +} + +function Divider({ label }: { label?: string }): React.JSX.Element { + if (label) { + return ( + + {"── "} + {label} + {" ──────────────────────────────────────────"} + + ); + } + return ( + + {"────────────────────────────────────────────────────"} + + ); +} + export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX.Element { const app = useApp(); const [status, setStatus] = useState(skipAnimation ? "idle" : "intro"); @@ -52,11 +97,19 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const [batchAzureToken, setBatchAzureToken] = useState(null); const [evalCaseCountInput, setEvalCaseCountInput] = useState(""); const [evalBootstrapCount, setEvalBootstrapCount] = useState(null); - const [readinessReport, setReadinessReport] = useState(null); const [availableModels, setAvailableModels] = useState([]); const [evalModel, setEvalModel] = useState("gpt-4.1"); const [judgeModel, setJudgeModel] = useState("gpt-4.1"); - const repoLabel = useMemo(() => repoPath, [repoPath]); + const [hasEvalConfig, setHasEvalConfig] = useState(null); + const [activityLog, setActivityLog] = useState([]); + const repoLabel = useMemo(() => path.basename(repoPath), [repoPath]); + const repoFull = useMemo(() => repoPath, [repoPath]); + const isLoading = status === "generating" || status === "bootstrapping" || status === "evaluating"; + const spinner = useSpinner(isLoading); + + const addLog = (text: string, type: LogEntry["type"] = "info") => { + setActivityLog((prev) => [...prev.slice(-4), { text, type, time: timestamp() }]); + }; const handleAnimationComplete = () => { setStatus("idle"); @@ -69,6 +122,12 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return availableModels[nextIndex]; }; + // Check for eval config on mount + useEffect(() => { + const configPath = path.join(repoPath, "primer.eval.json"); + fs.access(configPath).then(() => setHasEvalConfig(true)).catch(() => setHasEvalConfig(false)); + }, [repoPath]); + useEffect(() => { let active = true; listCopilotModels() @@ -93,6 +152,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX try { setStatus("bootstrapping"); setMessage("Generating eval cases with Copilot SDK..."); + addLog("Generating eval scaffold...", "progress"); const config = await generateEvalScaffold({ repoPath, count, @@ -100,11 +160,16 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX onProgress: (msg) => setMessage(msg) }); await safeWriteFile(configPath, JSON.stringify(config, null, 2), force); + setHasEvalConfig(true); setStatus("idle"); - setMessage(`Generated primer.eval.json with ${config.cases.length} cases.`); + const msg = `Generated primer.eval.json with ${config.cases.length} cases.`; + setMessage(msg); + addLog(msg, "success"); } catch (error) { setStatus("error"); - setMessage(error instanceof Error ? error.message : "Failed to generate eval config."); + const msg = error instanceof Error ? error.message : "Failed to generate eval config."; + setMessage(msg); + addLog(msg, "error"); } }; @@ -126,17 +191,22 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX await fs.mkdir(path.dirname(outputPath), { recursive: true }); await fs.writeFile(outputPath, generatedContent, "utf8"); setStatus("done"); - setMessage("Saved to .github/copilot-instructions.md"); + const msg = "Saved to .github/copilot-instructions.md"; + setMessage(msg); + addLog(msg, "success"); setGeneratedContent(""); } catch (error) { setStatus("error"); - setMessage(error instanceof Error ? error.message : "Failed to save."); + const msg = error instanceof Error ? error.message : "Failed to save."; + setMessage(msg); + addLog(msg, "error"); } return; } if (input.toLowerCase() === "d") { setStatus("idle"); setMessage("Discarded generated instructions."); + addLog("Discarded instructions.", "info"); setGeneratedContent(""); return; } @@ -198,9 +268,110 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return; } + if (status === "eval-pick") { + if (input.toLowerCase() === "r") { + // Run eval + const configPath = path.join(repoPath, "primer.eval.json"); + const outputPath = path.join(repoPath, ".primer", "evals", buildTimestampedName("eval-results")); + try { + await fs.access(configPath); + } catch { + setStatus("error"); + const msg = "No primer.eval.json found. Press [E] then [I] to create one."; + setMessage(msg); + addLog(msg, "error"); + return; + } + + setStatus("evaluating"); + setMessage("Running evals... (this may take a few minutes)"); + addLog("Running evals...", "progress"); + setEvalResults(null); + setEvalViewerPath(null); + try { + const { results, viewerPath } = await runEval({ + configPath, + repoPath, + model: evalModel, + judgeModel: judgeModel, + outputPath + }); + setEvalResults(results); + setEvalViewerPath(viewerPath ?? null); + const passed = results.filter((r) => r.verdict === "pass").length; + const failed = results.filter((r) => r.verdict === "fail").length; + setStatus("done"); + const msg = `Eval complete: ${passed} pass, ${failed} fail out of ${results.length} cases.`; + setMessage(msg); + addLog(msg, "success"); + } catch (error) { + setStatus("error"); + const msg = error instanceof Error ? error.message : "Eval failed."; + setMessage(msg); + addLog(msg, "error"); + } + return; + } + if (input.toLowerCase() === "i") { + setStatus("bootstrapEvalCount"); + setMessage("Enter number of eval cases, then press Enter."); + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); + return; + } + if (key.escape || input.toLowerCase() === "b") { + setStatus("idle"); + setMessage(""); + return; + } + return; + } + + if (status === "batch-pick") { + if (input.toLowerCase() === "g") { + setStatus("generating"); + setMessage("Checking GitHub authentication..."); + addLog("Starting batch (GitHub)...", "progress"); + const token = await getGitHubToken(); + if (!token) { + setStatus("error"); + const msg = "GitHub auth required. Run 'gh auth login' or set GITHUB_TOKEN."; + setMessage(msg); + addLog(msg, "error"); + return; + } + setBatchToken(token); + setStatus("batch-github"); + return; + } + if (input.toLowerCase() === "a") { + setStatus("generating"); + setMessage("Checking Azure DevOps authentication..."); + addLog("Starting batch (Azure DevOps)...", "progress"); + const token = getAzureDevOpsToken(); + if (!token) { + setStatus("error"); + const msg = "Azure DevOps PAT required. Set AZURE_DEVOPS_PAT or AZDO_PAT."; + setMessage(msg); + addLog(msg, "error"); + return; + } + setBatchAzureToken(token); + setStatus("batch-azure"); + return; + } + if (key.escape || input.toLowerCase() === "b") { + setStatus("idle"); + setMessage(""); + return; + } + return; + } + if (input.toLowerCase() === "g") { setStatus("generating"); setMessage("Starting generation..."); + addLog("Generating copilot instructions...", "progress"); try { const content = await generateCopilotInstructions({ repoPath, @@ -212,78 +383,29 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setGeneratedContent(content); setStatus("preview"); setMessage("Review the generated instructions below."); + addLog("Instructions generated — review and save.", "success"); } catch (error) { setStatus("error"); - const message = error instanceof Error ? error.message : "Generation failed."; - if (message.toLowerCase().includes("auth") || message.toLowerCase().includes("login")) { - setMessage(`${message} Run 'copilot' then '/login' in a separate terminal.`); + const msg = error instanceof Error ? error.message : "Generation failed."; + if (msg.toLowerCase().includes("auth") || msg.toLowerCase().includes("login")) { + setMessage(`${msg} Run 'copilot' then '/login' in a separate terminal.`); } else { - setMessage(message); + setMessage(msg); } + addLog(msg, "error"); } } if (input.toLowerCase() === "b") { - setStatus("generating"); - setMessage("Checking GitHub authentication..."); - const token = await getGitHubToken(); - if (!token) { - setStatus("error"); - setMessage("GitHub auth required. Run 'gh auth login' or set GITHUB_TOKEN."); - return; - } - setBatchToken(token); - setStatus("batch-github"); - return; - } - - if (input.toLowerCase() === "z") { - setStatus("generating"); - setMessage("Checking Azure DevOps authentication..."); - const token = getAzureDevOpsToken(); - if (!token) { - setStatus("error"); - setMessage("Azure DevOps PAT required. Set AZURE_DEVOPS_PAT or AZDO_PAT."); - return; - } - setBatchAzureToken(token); - setStatus("batch-azure"); + setStatus("batch-pick"); + setMessage("Select batch provider."); return; } if (input.toLowerCase() === "e") { - const configPath = path.join(repoPath, "primer.eval.json"); - const outputPath = path.join(repoPath, ".primer", "evals", buildTimestampedName("eval-results")); - try { - await fs.access(configPath); - } catch { - setStatus("error"); - setMessage("No primer.eval.json found. Run 'primer eval --init' to create one."); - return; - } - - setStatus("evaluating"); - setMessage("Running evals... (this may take a few minutes)"); - setEvalResults(null); - setEvalViewerPath(null); - try { - const { results, viewerPath } = await runEval({ - configPath, - repoPath, - model: evalModel, - judgeModel: judgeModel, - outputPath - }); - setEvalResults(results); - setEvalViewerPath(viewerPath ?? null); - const passed = results.filter((r) => r.verdict === "pass").length; - const failed = results.filter((r) => r.verdict === "fail").length; - setStatus("done"); - setMessage(`Eval complete: ${passed} pass, ${failed} fail out of ${results.length} cases.`); - } catch (error) { - setStatus("error"); - setMessage(error instanceof Error ? error.message : "Eval failed."); - } + setStatus("eval-pick"); + setMessage("Select eval action."); + return; } if (input.toLowerCase() === "m") { @@ -293,7 +415,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } const next = cycleModel(evalModel); setEvalModel(next); - setMessage(`Eval model: ${next}`); + setMessage(`Eval model → ${next}`); return; } @@ -304,35 +426,15 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } const next = cycleModel(judgeModel); setJudgeModel(next); - setMessage(`Judge model: ${next}`); + setMessage(`Judge model → ${next}`); return; } - - if (input.toLowerCase() === "i") { - setStatus("bootstrapEvalCount"); - setMessage("Enter number of eval cases, then press Enter."); - setEvalCaseCountInput(""); - setEvalBootstrapCount(null); - } - - if (input.toLowerCase() === "r") { - setStatus("readiness"); - setMessage("Running readiness report..."); - setReadinessReport(null); - try { - const report = await runReadinessReport({ repoPath }); - setReadinessReport(report); - setStatus("done"); - setMessage("Readiness report complete."); - } catch (error) { - setStatus("error"); - setMessage(error instanceof Error ? error.message : "Readiness report failed."); - } - } }); - const statusLabel = status === "intro" ? "starting" : status === "idle" ? "ready" : status; - const statusColor = status === "error" ? "red" : status === "done" ? "green" : "yellow"; + const statusIcon = status === "error" ? "✗" : status === "done" ? "✓" : isLoading ? spinner : "●"; + const statusLabel = status === "intro" ? "starting" : status === "idle" ? "ready" : status === "bootstrapEvalCount" ? "input" : status === "bootstrapEvalConfirm" ? "confirm" : status === "eval-pick" ? "eval" : status === "batch-pick" ? "batch" : status; + const statusColor = status === "error" ? "red" : status === "done" ? "green" : isLoading ? "yellow" : "cyanBright"; + const formatTokens = (result: EvalResult): string => { const withUsage = result.metrics?.withInstructions?.tokenUsage; const withoutUsage = result.metrics?.withoutInstructions?.tokenUsage; @@ -342,11 +444,9 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return `tokens w/: ${withTotal ?? "n/a"} • w/o: ${withoutTotal ?? "n/a"}`; }; - // Truncate preview to fit terminal const previewLines = generatedContent.split("\n").slice(0, 20); const truncatedPreview = previewLines.join("\n") + (generatedContent.split("\n").length > 20 ? "\n..." : ""); - // Render BatchTui when in batch mode if (status === "batch-github" && batchToken) { return ; } @@ -362,75 +462,143 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX ) : ( )} + + {/* Status Bar */} - Prime your repo for AI - ● {statusLabel} + Prime your repo for AI + {statusIcon} {statusLabel} - Repo: {repoLabel} - Eval model: {evalModel} • Judge model: {judgeModel} - - - Activity + {/* Context */} + + + + Repo + {repoLabel} + {repoFull} + + + Model + {evalModel} + • Judge + {judgeModel} + {availableModels.length > 0 && ({availableModels.length} available)} + + + Eval + {hasEvalConfig === null ? ( + checking... + ) : hasEvalConfig ? ( + primer.eval.json found + ) : ( + no eval config — press [I] to create + )} - {message || "Awaiting input."} + + {/* Activity */} + + + {activityLog.length === 0 && !message ? ( + Awaiting input. + ) : ( + <> + {activityLog.slice(-3).map((entry, i) => ( + + {entry.time} + + {entry.text} + + + ))} + {message && !activityLog.some(e => e.text === message) && ( + + {isLoading ? `${spinner} ` : ""}{message} + + )} + + )} + + + {/* Input: eval case count */} {status === "bootstrapEvalCount" && ( - - Eval case count: {evalCaseCountInput || ""} + + Eval case count: + {evalCaseCountInput || "▍"} )} + + {/* Preview */} {status === "preview" && generatedContent && ( - Preview (.github/copilot-instructions.md): + Preview (.github/copilot-instructions.md) {truncatedPreview} )} + + {/* Eval Results */} {evalResults && evalResults.length > 0 && ( - - Eval Results: - {evalResults.map((r) => ( - - {r.verdict === "pass" ? "✓" : r.verdict === "fail" ? "✗" : "?"} {r.id}: {r.verdict} (score: {r.score}) • {formatTokens(r)} - - ))} - {evalViewerPath && ( - Trajectory viewer: {evalViewerPath} - )} - - )} - {readinessReport && ( - - Readiness Report: - Level: {readinessReport.achievedLevel || 1} ({levelName(readinessReport.achievedLevel || 1)}) - Monorepo: {readinessReport.isMonorepo ? "yes" : "no"}{readinessReport.apps.length ? ` (${readinessReport.apps.length} apps)` : ""} - Pillars: - {readinessReport.pillars.map((pillar) => ( - = 0.8 ? "green" : "yellow"}> - {pillar.name}: {pillar.passed}/{pillar.total} ({formatPercent(pillar.passRate)}) - - ))} - {topFixes(readinessReport.criteria).length > 0 && ( - <> - Fix first: - {topFixes(readinessReport.criteria).map((fix) => ( - - - {fix.title} ({fix.impact}/{fix.effort}) + <> + + + {evalResults.map((r) => ( + + + {r.verdict === "pass" ? "✓" : r.verdict === "fail" ? "✗" : "?"}{" "} - ))} - - )} - + {r.id} + score:{r.score} • {formatTokens(r)} + + ))} + {evalViewerPath && ( + Viewer: {evalViewerPath} + )} + + )} - + + {/* Commands */} + + {status === "intro" ? ( Press any key to skip animation... ) : status === "preview" ? ( - Keys: [S] Save [D] Discard [Q] Quit + + + + + ) : status === "bootstrapEvalConfirm" ? ( - Keys: [Y] Overwrite [N] Cancel [Q] Quit + + + + + + ) : status === "eval-pick" ? ( + + + + + + ) : status === "batch-pick" ? ( + + + + + ) : ( - Keys: [A] Analyze [G] Generate [R] Readiness [E] Eval [I] Init Eval [M] Model [J] Judge [B] Batch [Z] Batch Azure [Q] Quit + + + + + + + + + + + + )} @@ -441,38 +609,3 @@ function buildTimestampedName(baseName: string): string { const stamp = new Date().toISOString().replace(/[:.]/gu, "-"); return `${baseName}-${stamp}.json`; } - -function topFixes(criteria: ReadinessCriterionResult[]): ReadinessCriterionResult[] { - return criteria - .filter((criterion) => criterion.status === "fail") - .sort((a, b) => { - const impactDelta = impactWeight(b.impact) - impactWeight(a.impact); - if (impactDelta !== 0) return impactDelta; - return effortWeight(a.effort) - effortWeight(b.effort); - }) - .slice(0, 5); -} - -function impactWeight(value: "high" | "medium" | "low"): number { - if (value === "high") return 3; - if (value === "medium") return 2; - return 1; -} - -function effortWeight(value: "low" | "medium" | "high"): number { - if (value === "low") return 1; - if (value === "medium") return 2; - return 3; -} - -function formatPercent(value: number): string { - return `${Math.round(value * 100)}%`; -} - -function levelName(level: number): string { - if (level === 2) return "Documented"; - if (level === 3) return "Standardized"; - if (level === 4) return "Optimized"; - if (level === 5) return "Autonomous"; - return "Functional"; -} From 4fd6286c7bd081185b5fc67a9de10fb01d44376b Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Sun, 8 Feb 2026 20:43:37 -0700 Subject: [PATCH 10/19] Add tests for filesystem utilities, readiness report, and visual report generation - Implement tests for `ensureDir` and `safeWriteFile` in `fs.test.ts`. - Create comprehensive tests for `runReadinessReport` in `readiness.test.ts`, covering various criteria and pillars. - Add tests for `generateVisualReport` in `visualReport.test.ts`, ensuring correct HTML output and content. - Update `generateCopilotInstructions` to use a new preferred model. - Enhance TUI to support model selection and generation options for copilot instructions and agents. - Introduce `tsup` configuration for building the project. --- .github/workflows/ci.yml | 9 +- README.md | 374 +++++++------------- package.json | 19 +- src/cli.ts | 9 +- src/commands/generate.ts | 46 ++- src/services/__tests__/fs.test.ts | 73 ++++ src/services/__tests__/readiness.test.ts | 360 +++++++++++++++++++ src/services/__tests__/visualReport.test.ts | 190 ++++++++++ src/services/instructions.ts | 2 +- src/ui/tui.tsx | 319 ++++++++++++++--- tsup.config.ts | 20 ++ 11 files changed, 1103 insertions(+), 318 deletions(-) create mode 100644 src/services/__tests__/fs.test.ts create mode 100644 src/services/__tests__/readiness.test.ts create mode 100644 src/services/__tests__/visualReport.test.ts create mode 100644 tsup.config.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb9b04c..d336a10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [main] + branches: [main, vnext] pull_request: jobs: @@ -23,10 +23,15 @@ jobs: - name: Typecheck run: npm run typecheck - name: Test - run: npm run test:coverage + run: npm run test - name: Build run: npm run build + - name: Verify CLI + run: | + chmod +x dist/index.js + node dist/index.js --version - name: Upload coverage + if: always() uses: actions/upload-artifact@v4 with: name: coverage diff --git a/README.md b/README.md index 597d110..dd4a7f5 100644 --- a/README.md +++ b/README.md @@ -5,293 +5,190 @@ [![CI](https://github.com/pierceboggan/primer/actions/workflows/ci.yml/badge.svg)](https://github.com/pierceboggan/primer/actions/workflows/ci.yml) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) -Primer is a CLI tool that analyzes your codebase and generates `.github/copilot-instructions.md` files to help AI coding assistants understand your project better. It supports single repos, batch processing across organizations, and includes an evaluation framework to measure instruction effectiveness. - -![Primer](primer.png) +Primer is a CLI tool that helps teams prepare repositories for AI-assisted development. It generates custom instructions, assesses AI readiness with a maturity model, and supports batch processing across organizations — with an interactive TUI and beautiful visual reports. ## Features -- **Repository Analysis** - Detects languages, frameworks, and package managers -- **AI-Powered Generation** - Uses the Copilot SDK to analyze your codebase and generate context-aware instructions -- **Batch Processing** - Process multiple repos across organizations with a single command -- **Evaluation Framework** - Test and measure how well your instructions improve AI responses -- **Readiness Report** - Score AI readiness across key pillars with a fix-first checklist -- **Visual Reports** - Generate beautiful HTML reports for single or multiple repositories -- **Batch Readiness** - Consolidated visual reports for tracking AI readiness across entire organizations -- **GitHub Integration** - Clone repos, create branches, and open PRs automatically -- **Interactive TUI** - Beautiful terminal interface built with Ink -- **Config Generation** - Generate MCP and VS Code configurations +- **AI Readiness Reports** — Score repos across 9 pillars with a maturity model (Functional → Autonomous), including an AI tooling pillar that checks for MCP, custom agents, Copilot skills, and custom instructions +- **Visual Reports** — GitHub-themed HTML reports with light/dark toggle, expandable pillar details, and maturity model descriptions +- **Instruction Generation** — Generate `copilot-instructions.md` or `AGENTS.md` using the Copilot SDK, with per-app support for monorepos +- **Batch Processing** — Process multiple repos across GitHub or Azure DevOps organizations +- **Evaluation Framework** — Measure how instructions improve AI responses with a judge model +- **Interactive TUI** — Ink-based terminal UI with submenus, model picker, activity log, and animated banner +- **Config Generation** — Generate MCP and VS Code configurations +- **GitHub Integration** — Clone repos, create branches, and open PRs automatically ## Prerequisites -1. **Node.js 18+** -2. **GitHub Copilot CLI** - Installed via VS Code's Copilot Chat extension -3. **Copilot CLI Authentication** - Run `copilot` then `/login` to authenticate -4. **GitHub CLI (optional)** - For batch processing and PR creation: `brew install gh && gh auth login` -5. **Azure DevOps PAT (optional)** - For Azure DevOps batch/PR workflows: set `AZURE_DEVOPS_PAT` +1. **Node.js 20+** +2. **GitHub Copilot CLI** — Installed via VS Code's Copilot Chat extension +3. **Copilot CLI Authentication** — Run `copilot` then `/login` to authenticate +4. **GitHub CLI (optional)** — For batch processing and PR creation: `brew install gh && gh auth login` +5. **Azure DevOps PAT (optional)** — For Azure DevOps workflows: set `AZURE_DEVOPS_PAT` ## Installation ```bash -# Install from npm -npm install -g primer +# Clone and install +git clone https://github.com/pierceboggan/primer.git +cd primer +npm install +npm run build +npm link ``` -### Quick Install +Then use `primer` anywhere: ```bash primer --help ``` -### Local Development Install - -```bash -# Clone and install dependencies -git clone https://github.com/pierceboggan/primer.git -cd primer -npm install - -# Build and link the local CLI -npm run build -``` - ## Usage -### Quick Start (Init) - -The easiest way to get started is with the `init` command: +### Quick Start ```bash # Interactive setup for current directory primer init -# Accept defaults and generate instructions automatically +# Accept defaults and generate everything primer init --yes - -# Work with a GitHub repository -primer init --github - -# Work with an Azure DevOps repository -primer init --provider azure ``` -### Interactive Mode (TUI) +### Interactive TUI ```bash -# Run TUI in current directory primer tui - -# Run on a specific repo primer tui --repo /path/to/repo - -# Skip the animated intro -primer tui --no-animation ``` -**Keys:** -- `[A]` Analyze - Detect languages, frameworks, and package manager -- `[G]` Generate - Generate copilot-instructions.md using Copilot SDK -- `[S]` Save - Save generated instructions (in preview mode) -- `[D]` Discard - Discard generated instructions (in preview mode) +**Main menu:** +- `[G]` Generate → choose Copilot instructions or AGENTS.md (with per-app support for monorepos) +- `[E]` Eval → run evals or init eval config +- `[B]` Batch → pick GitHub or Azure DevOps +- `[M]` / `[J]` → pick eval/judge model from available models (arrow keys + Enter) - `[Q]` Quit ### Generate Instructions ```bash -# Generate instructions for current directory -primer instructions +# Generate copilot-instructions.md +primer generate instructions -# Generate for specific repo with custom output -primer instructions --repo /path/to/repo --output ./instructions.md +# Generate AGENTS.md +primer generate agents -# Use a specific model -primer instructions --model gpt-5 -``` +# Generate per-app in monorepos +primer generate instructions --per-app -### Batch Processing +# Generate MCP or VS Code configs +primer generate mcp +primer generate vscode --force +``` -Process multiple repositories across organizations: +Or use the standalone command: ```bash -# Launch batch TUI -primer batch - -# Launch batch TUI for Azure DevOps -primer batch --provider azure - -# Save results to file -primer batch --output results.json +primer instructions --repo /path/to/repo --model claude-sonnet-4.5 ``` -**Batch TUI Keys:** -- `[Space]` Toggle selection -- `[A]` Select all repos -- `[Enter]` Confirm selection -- `[Y/N]` Confirm/cancel processing -- `[Q]` Quit - ### Readiness Report -Assess how ready a repository is for AI agents and get a prioritized checklist of fixes: +Assess AI readiness across 9 pillars with a maturity model: ```bash -# Run readiness report in current directory +# Terminal output primer readiness -# Run readiness report on a specific repo -primer readiness /path/to/repo +# Visual HTML report (GitHub-themed, light/dark toggle) +primer readiness --visual -# Output JSON only +# JSON output primer readiness --json -# Write JSON report to a file -primer readiness --output readiness.json - -# Generate a beautiful visual HTML report -primer readiness --visual - -# Save visual report to a specific file +# Save to file primer readiness --output report.html ``` -#### Batch Readiness Report +**Maturity levels:** +| Level | Name | Description | +|-------|------|-------------| +| 1 | Functional | Builds, tests, basic tooling in place | +| 2 | Documented | README, CONTRIBUTING, custom AI instructions exist | +| 3 | Standardized | CI/CD, security policies, CODEOWNERS, observability | +| 4 | Optimized | MCP servers, custom agents, AI skills configured | +| 5 | Autonomous | Full AI-native development with minimal oversight | + +**AI Tooling checks:** +- Custom instructions (`copilot-instructions.md`, `CLAUDE.md`, `AGENTS.md`, `.cursorrules`) +- MCP configuration (`.vscode/mcp.json`, settings) +- Custom AI agents (`.github/agents/`, `.copilot/agents/`) +- Copilot/Claude skills (`.copilot/skills/`, `.github/skills/`) -Generate a consolidated visual report for multiple repositories across organizations: +#### Batch Readiness + +Consolidated visual report across multiple repositories: ```bash -# Launch interactive batch readiness report primer batch-readiness - -# Save report to a custom file primer batch-readiness --output team-readiness.html ``` -The visual report includes: -- **Summary Cards** - Total repositories, average readiness level, success rate -- **Pillar Performance** - AI readiness metrics across all repositories -- **Level Distribution** - Visual breakdown of repositories by maturity level -- **Repository Details** - Individual scores and top fixes for each repository -- **Beautiful UI** - Gradient backgrounds, responsive design, and interactive elements - -Perfect for AI enablement teams tracking improvement targets! - -### Examples - -See [examples/README.md](examples/README.md) for quick usage snippets and a sample eval config. - -### Generate Configs +### Batch Processing -Generate configuration files for your repo: +Process multiple repos across organizations: ```bash -# Generate MCP config -primer generate mcp - -# Generate VS Code settings -primer generate vscode --force - -# Generate custom prompts -primer generate prompts - -# Generate agent configs -primer generate agents - -# Generate .aiignore file -primer generate aiignore -``` - -### Manage Templates - -View available instruction templates: +# GitHub +primer batch -```bash -primer templates +# Azure DevOps +primer batch --provider azure ``` -### Configuration +### Evaluation Framework -View and manage Primer configuration: +Measure instruction effectiveness: ```bash -primer config -``` - -### Update +# Create eval config +primer eval --init -Check for and apply updates: +# Run evaluation (defaults to claude-sonnet-4.5) +primer eval primer.eval.json --repo /path/to/repo -```bash -primer update +# Custom models +primer eval --model claude-sonnet-4.5 --judge-model claude-sonnet-4.5 ``` ### Create Pull Requests -Automatically create a PR to add Primer configs to a repository: - ```bash -# Create PR for a GitHub repo primer pr owner/repo-name - -# Use custom branch name -primer pr owner/repo-name --branch primer/custom-branch - -# Create PR for an Azure DevOps repo (org/project/repo) primer pr my-org/my-project/my-repo --provider azure ``` -### Evaluation Framework - -Test how well your instructions improve AI responses: +## Development ```bash -# Create a starter eval config -primer eval --init - -# Run evaluation -primer eval primer.eval.json --repo /path/to/repo - -# Save results and use specific models -primer eval --output results.json --model gpt-5 --judge-model gpt-5 -``` - -When `--output` is provided (or `outputPath` is set in the eval config), Primer writes a JSON report that includes per-case metrics and trajectory events, and also generates a companion HTML trajectory viewer next to the JSON file. - -Example `primer.eval.json`: -```json -{ - "instructionFile": ".github/copilot-instructions.md", - "outputPath": "eval-results.json", - "cases": [ - { - "id": "project-overview", - "prompt": "Summarize what this project does and list the main entry points.", - "expectation": "Should mention the primary purpose and key files/directories." - } - ] -} -``` +# Type check +npm run typecheck -## How It Works +# Lint +npm run lint -1. **Analysis** - Scans the repository for: - - Language files (`.ts`, `.js`, `.py`, `.go`, etc.) - - Framework indicators (`package.json`, `tsconfig.json`, etc.) - - Package manager lock files +# Test (51 tests) +npm run test -2. **Generation** - Uses the Copilot SDK to: - - Start a Copilot CLI session - - Let the AI agent explore your codebase using tools (`glob`, `view`, `grep`) - - Generate concise, project-specific instructions +# Test with coverage +npm run test:coverage -3. **Batch Processing** - For multiple repos: - - Select organizations and repositories via TUI - - Clone, branch, generate, commit, push, and create PRs - - Track success/failure for each repository +# Build +npm run build -4. **Evaluation** - Measure instruction quality: - - Run prompts with and without instructions - - Use a judge model to score responses - - Generate comparison reports +# Run from source +npx tsx src/index.ts --help +``` ## Project Structure @@ -301,60 +198,37 @@ primer/ │ ├── index.ts # Entry point │ ├── cli.ts # Commander CLI setup │ ├── commands/ # CLI commands -│ │ ├── analyze.ts # Repository analysis -│ │ ├── batch.tsx # Batch processing -│ │ ├── config.ts # Config management -│ │ ├── eval.ts # Evaluation framework -│ │ ├── generate.ts # Config generation -│ │ ├── init.ts # Interactive setup -│ │ ├── instructions.tsx # Instructions generation -│ │ ├── pr.ts # PR creation -│ │ ├── templates.ts # Template management -│ │ ├── tui.tsx # TUI launcher -│ │ └── update.ts # Update command -│ ├── services/ # Core business logic -│ │ ├── analyzer.ts # Repository analysis -│ │ ├── evaluator.ts # Eval runner -│ │ ├── generator.ts # Config generation -│ │ ├── git.ts # Git operations -│ │ ├── github.ts # GitHub API -│ │ └── instructions.ts # Copilot SDK integration -│ ├── ui/ # Terminal UI +│ │ ├── batch.tsx # Batch processing (GitHub) +│ │ ├── batchReadiness.tsx # Batch readiness reports +│ │ ├── eval.ts # Evaluation framework +│ │ ├── generate.ts # Generate instructions/configs +│ │ ├── init.ts # Interactive setup +│ │ ├── instructions.tsx # Instructions generation +│ │ ├── pr.ts # PR creation +│ │ ├── readiness.ts # Readiness command +│ │ └── tui.tsx # TUI launcher +│ ├── services/ # Core logic +│ │ ├── analyzer.ts # Repository analysis +│ │ ├── evaluator.ts # Eval runner +│ │ ├── generator.ts # Config generation +│ │ ├── git.ts # Git operations +│ │ ├── github.ts # GitHub API +│ │ ├── instructions.ts # Copilot SDK integration +│ │ ├── readiness.ts # Readiness scoring engine +│ │ ├── visualReport.ts # HTML report generator +│ │ └── __tests__/ # Test suite +│ ├── ui/ # Terminal UI (Ink/React) │ │ ├── AnimatedBanner.tsx -│ │ ├── BatchTui.tsx # Batch processing UI -│ │ └── tui.tsx # Main TUI -│ └── utils/ # Helpers +│ │ ├── BatchTui.tsx +│ │ ├── BatchTuiAzure.tsx +│ │ ├── BatchReadinessTui.tsx +│ │ └── tui.tsx +│ └── utils/ │ ├── fs.ts │ └── logger.ts -├── package.json -├── tsconfig.json -├── primer.eval.json # Example eval config -└── PLAN.md # Project roadmap -``` - -## Development - -```bash -# Type check -npx tsc -p tsconfig.json --noEmit - -# Lint -npm run lint - -# Format -npm run format - -# Test -npm run test - -# Coverage -npm run test:coverage - -# Build and link the local CLI -npm run build - -# Run locally -primer +├── tsup.config.ts # Bundler config +├── vitest.config.ts # Test config +└── primer.eval.json # Example eval config ``` ## Troubleshooting @@ -365,16 +239,10 @@ Install the GitHub Copilot Chat extension in VS Code. The CLI is bundled with it ### "Copilot CLI not logged in" Run `copilot` in your terminal, then type `/login` to authenticate. -### "GitHub authentication required" (batch/PR commands) +### "GitHub authentication required" Install GitHub CLI and authenticate: `brew install gh && gh auth login` - Or set a token: `export GITHUB_TOKEN=` -### Generation hangs or times out -- Ensure you're authenticated with the Copilot CLI -- Check your network connection -- Try a smaller repository first - ## License MIT diff --git a/package.json b/package.json index bf64dc8..3c6fd55 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,18 @@ { - "name": "primer", + "name": "@anthropic/primer", "version": "1.0.0", - "description": "", + "description": "Prime repositories for AI-assisted development", "main": "dist/index.js", + "type": "module", + "bin": { + "primer": "dist/index.js" + }, + "files": [ + "dist" + ], "scripts": { - "build": "tsc && npm link", - "prepare": "tsc", + "build": "tsup", + "prepare": "test \"$CI\" = true || tsup", "lint": "eslint .", "format": "prettier --write .", "format:check": "prettier --check .", @@ -44,9 +51,5 @@ "tsx": "^4.21.0", "typescript": "^5.9.3", "vitest": "^2.1.4" - }, - "type": "module", - "bin": { - "primer": "dist/index.js" } } diff --git a/src/cli.ts b/src/cli.ts index 27f150e..6d8a169 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -29,9 +29,10 @@ export function runCli(argv: string[]): void { program .command("generate") - .argument("", "prompts|agents|mcp|vscode|aiignore") + .argument("", "instructions|agents|mcp|vscode") .argument("[path]", "Path to a local repository") .option("--force", "Overwrite existing files") + .option("--per-app", "Generate per-app in monorepos") .action(generateCommand); program @@ -45,8 +46,8 @@ export function runCli(argv: string[]): void { .command("eval") .argument("[path]", "Path to eval config JSON") .option("--repo ", "Repository path", process.cwd()) - .option("--model ", "Model for responses", "gpt-5") - .option("--judge-model ", "Model for judging", "gpt-5") + .option("--model ", "Model for responses", "claude-sonnet-4.5") + .option("--judge-model ", "Model for judging", "claude-sonnet-4.5") .option("--list-models", "List Copilot CLI models and exit") .option("--output ", "Write results JSON to file") .option("--init", "Create a starter primer.eval.json file") @@ -63,7 +64,7 @@ export function runCli(argv: string[]): void { .command("instructions") .option("--repo ", "Repository path", process.cwd()) .option("--output ", "Output path for copilot instructions") - .option("--model ", "Model for instructions generation", "gpt-4.1") + .option("--model ", "Model for instructions generation", "claude-sonnet-4.5") .action(instructionsCommand); program diff --git a/src/commands/generate.ts b/src/commands/generate.ts index a4c69c7..891f078 100644 --- a/src/commands/generate.ts +++ b/src/commands/generate.ts @@ -1,15 +1,19 @@ import path from "path"; +import fs from "fs/promises"; import { analyzeRepo } from "../services/analyzer"; import { generateConfigs } from "../services/generator"; +import { generateCopilotInstructions } from "../services/instructions"; +import { ensureDir } from "../utils/fs"; type GenerateOptions = { force?: boolean; + perApp?: boolean; }; export async function generateCommand(type: string, repoPathArg: string | undefined, options: GenerateOptions): Promise { - const allowed = new Set(["mcp", "vscode"]); + const allowed = new Set(["mcp", "vscode", "instructions", "agents"]); if (!allowed.has(type)) { - console.error("Invalid type. Use: mcp, vscode."); + console.error("Invalid type. Use: instructions, agents, mcp, vscode."); process.exitCode = 1; return; } @@ -17,6 +21,44 @@ export async function generateCommand(type: string, repoPathArg: string | undefi const repoPath = path.resolve(repoPathArg ?? process.cwd()); const analysis = await analyzeRepo(repoPath); + if (type === "instructions" || type === "agents") { + const apps = analysis.apps ?? []; + const targets: Array<{ repoPath: string; savePath: string; label: string }> = []; + + if (options.perApp && analysis.isMonorepo && apps.length > 1) { + for (const app of apps) { + const savePath = type === "instructions" + ? path.join(app.path, ".github", "copilot-instructions.md") + : path.join(app.path, "AGENTS.md"); + targets.push({ repoPath: app.path, savePath, label: app.name }); + } + } else { + const savePath = type === "instructions" + ? path.join(repoPath, ".github", "copilot-instructions.md") + : path.join(repoPath, "AGENTS.md"); + targets.push({ repoPath, savePath, label: path.basename(repoPath) }); + } + + for (const target of targets) { + console.log(`Generating ${type} for ${target.label}...`); + try { + const content = await generateCopilotInstructions({ + repoPath: target.repoPath, + }); + if (!content.trim()) { + console.error(` No content generated for ${target.label}.`); + continue; + } + await ensureDir(path.dirname(target.savePath)); + await fs.writeFile(target.savePath, content, "utf8"); + console.log(` ✓ ${path.relative(process.cwd(), target.savePath)}`); + } catch (error) { + console.error(` ✗ ${error instanceof Error ? error.message : String(error)}`); + } + } + return; + } + const selections = [type]; const result = await generateConfigs({ repoPath, diff --git a/src/services/__tests__/fs.test.ts b/src/services/__tests__/fs.test.ts new file mode 100644 index 0000000..bd9e28e --- /dev/null +++ b/src/services/__tests__/fs.test.ts @@ -0,0 +1,73 @@ +import fs from "fs/promises"; +import os from "os"; +import path from "path"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +import { ensureDir, safeWriteFile } from "../../utils/fs"; + +describe("ensureDir", () => { + let tmpDir: string; + + beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "primer-fs-")); + }); + + afterEach(async () => { + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it("creates a directory that does not exist", async () => { + const target = path.join(tmpDir, "a", "b", "c"); + await ensureDir(target); + + const stat = await fs.stat(target); + expect(stat.isDirectory()).toBe(true); + }); + + it("does not throw if directory already exists", async () => { + const target = path.join(tmpDir, "existing"); + await fs.mkdir(target); + await expect(ensureDir(target)).resolves.toBeUndefined(); + }); +}); + +describe("safeWriteFile", () => { + let tmpDir: string; + + beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "primer-fs-")); + }); + + afterEach(async () => { + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + + it("writes a new file", async () => { + const filePath = path.join(tmpDir, "test.txt"); + const result = await safeWriteFile(filePath, "hello", false); + + const content = await fs.readFile(filePath, "utf8"); + expect(content).toBe("hello"); + expect(result).toContain("Wrote"); + }); + + it("skips existing file without force", async () => { + const filePath = path.join(tmpDir, "test.txt"); + await fs.writeFile(filePath, "original"); + const result = await safeWriteFile(filePath, "new content", false); + + const content = await fs.readFile(filePath, "utf8"); + expect(content).toBe("original"); + expect(result).toContain("Skipped"); + }); + + it("overwrites existing file with force", async () => { + const filePath = path.join(tmpDir, "test.txt"); + await fs.writeFile(filePath, "original"); + const result = await safeWriteFile(filePath, "new content", true); + + const content = await fs.readFile(filePath, "utf8"); + expect(content).toBe("new content"); + expect(result).toContain("Wrote"); + }); +}); diff --git a/src/services/__tests__/readiness.test.ts b/src/services/__tests__/readiness.test.ts new file mode 100644 index 0000000..b6825cc --- /dev/null +++ b/src/services/__tests__/readiness.test.ts @@ -0,0 +1,360 @@ +import fs from "fs/promises"; +import os from "os"; +import path from "path"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +import { runReadinessReport, type ReadinessReport } from "../readiness"; + +describe("runReadinessReport", () => { + let repoPath: string; + + beforeEach(async () => { + repoPath = await fs.mkdtemp(path.join(os.tmpdir(), "primer-readiness-")); + }); + + afterEach(async () => { + await fs.rm(repoPath, { recursive: true, force: true }); + }); + + async function writeFile(relativePath: string, content: string): Promise { + const fullPath = path.join(repoPath, relativePath); + await fs.mkdir(path.dirname(fullPath), { recursive: true }); + await fs.writeFile(fullPath, content, "utf8"); + } + + async function writePackageJson(pkg: Record): Promise { + await writeFile("package.json", JSON.stringify(pkg, null, 2)); + } + + it("returns a valid report structure", async () => { + await writePackageJson({ name: "test-repo", scripts: { build: "tsc", test: "vitest" } }); + const report = await runReadinessReport({ repoPath }); + + expect(report.repoPath).toBe(repoPath); + expect(report.generatedAt).toBeTruthy(); + expect(report.pillars).toBeInstanceOf(Array); + expect(report.levels).toBeInstanceOf(Array); + expect(report.criteria).toBeInstanceOf(Array); + expect(typeof report.achievedLevel).toBe("number"); + }); + + it("has all expected pillars", async () => { + await writePackageJson({ name: "test-repo" }); + const report = await runReadinessReport({ repoPath }); + + const pillarIds = report.pillars.map((p) => p.id); + expect(pillarIds).toContain("style-validation"); + expect(pillarIds).toContain("build-system"); + expect(pillarIds).toContain("testing"); + expect(pillarIds).toContain("documentation"); + expect(pillarIds).toContain("dev-environment"); + expect(pillarIds).toContain("code-quality"); + expect(pillarIds).toContain("observability"); + expect(pillarIds).toContain("security-governance"); + expect(pillarIds).toContain("ai-tooling"); + }); + + it("has 5 maturity levels", async () => { + await writePackageJson({ name: "test-repo" }); + const report = await runReadinessReport({ repoPath }); + + expect(report.levels).toHaveLength(5); + expect(report.levels.map((l) => l.level)).toEqual([1, 2, 3, 4, 5]); + }); + + describe("style-validation pillar", () => { + it("passes lint-config when eslint.config.js exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("eslint.config.js", "export default [];"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "lint-config"); + + expect(criterion?.status).toBe("pass"); + }); + + it("fails lint-config when no lint config exists", async () => { + await writePackageJson({ name: "test-repo" }); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "lint-config"); + + expect(criterion?.status).toBe("fail"); + }); + + it("passes typecheck-config when tsconfig.json exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("tsconfig.json", "{}"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "typecheck-config"); + + expect(criterion?.status).toBe("pass"); + }); + }); + + describe("documentation pillar", () => { + it("passes readme when README.md exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("README.md", "# Test"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "readme"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes contributing when CONTRIBUTING.md exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("CONTRIBUTING.md", "# Contributing"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "contributing"); + + expect(criterion?.status).toBe("pass"); + }); + }); + + describe("dev-environment pillar", () => { + it("passes lockfile when package-lock.json exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("package-lock.json", "{}"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "lockfile"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes env-example when .env.example exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".env.example", "API_KEY=your-key"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "env-example"); + + expect(criterion?.status).toBe("pass"); + }); + }); + + describe("security-governance pillar", () => { + it("passes codeowners when CODEOWNERS exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("CODEOWNERS", "* @owner"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "codeowners"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes codeowners when .github/CODEOWNERS exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".github/CODEOWNERS", "* @owner"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "codeowners"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes license when LICENSE exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("LICENSE", "MIT License"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "license"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes security-policy when SECURITY.md exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("SECURITY.md", "# Security"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "security-policy"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes dependabot when .github/dependabot.yml exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".github/dependabot.yml", "version: 2"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "dependabot"); + + expect(criterion?.status).toBe("pass"); + }); + }); + + describe("ai-tooling pillar", () => { + it("passes custom-instructions when copilot-instructions.md exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".github/copilot-instructions.md", "# Instructions"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "custom-instructions"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes custom-instructions when CLAUDE.md exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("CLAUDE.md", "# Claude instructions"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "custom-instructions"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes custom-instructions when AGENTS.md exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("AGENTS.md", "# Agents guidance"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "custom-instructions"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes custom-instructions when .cursorrules exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".cursorrules", "rules here"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "custom-instructions"); + + expect(criterion?.status).toBe("pass"); + }); + + it("fails custom-instructions when none exist", async () => { + await writePackageJson({ name: "test-repo" }); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "custom-instructions"); + + expect(criterion?.status).toBe("fail"); + }); + + it("passes mcp-config when .vscode/mcp.json exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".vscode/mcp.json", "{}"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "mcp-config"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes mcp-config when .vscode/settings.json has mcp key", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile( + ".vscode/settings.json", + JSON.stringify({ "github.copilot.chat.mcp.enabled": true }) + ); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "mcp-config"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes custom-agents when .github/agents directory exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".github/agents/.gitkeep", ""); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "custom-agents"); + + expect(criterion?.status).toBe("pass"); + }); + + it("passes copilot-skills when .copilot/skills directory exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".copilot/skills/.gitkeep", ""); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "copilot-skills"); + + expect(criterion?.status).toBe("pass"); + }); + }); + + describe("build-system pillar", () => { + it("passes ci-config when .github/workflows exists", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile(".github/workflows/ci.yml", "name: CI"); + + const report = await runReadinessReport({ repoPath }); + const criterion = report.criteria.find((c) => c.id === "ci-config"); + + expect(criterion?.status).toBe("pass"); + }); + }); + + describe("achieved level", () => { + it("achieves level 1 with basic setup", async () => { + await writePackageJson({ + name: "test-repo", + scripts: { build: "tsc", test: "vitest" } + }); + await writeFile("eslint.config.js", "export default [];"); + await writeFile("README.md", "# Test"); + await writeFile("package-lock.json", "{}"); + await writeFile("LICENSE", "MIT"); + + const report = await runReadinessReport({ repoPath }); + + expect(report.achievedLevel).toBeGreaterThanOrEqual(1); + }); + + it("is 0 for an empty repo", async () => { + await writePackageJson({ name: "empty-repo" }); + + const report = await runReadinessReport({ repoPath }); + + // Level 0 means nothing achieved (most L1 checks fail) + expect(report.achievedLevel).toBeLessThanOrEqual(1); + }); + }); + + describe("pillar summaries", () => { + it("calculates passRate correctly", async () => { + await writePackageJson({ name: "test-repo" }); + await writeFile("eslint.config.js", "export default [];"); + + const report = await runReadinessReport({ repoPath }); + const stylePillar = report.pillars.find((p) => p.id === "style-validation"); + + expect(stylePillar).toBeDefined(); + expect(stylePillar!.passed).toBeGreaterThanOrEqual(1); + expect(stylePillar!.total).toBeGreaterThanOrEqual(1); + expect(stylePillar!.passRate).toBe(stylePillar!.passed / stylePillar!.total); + }); + }); + + describe("extras", () => { + it("includes extras by default", async () => { + await writePackageJson({ name: "test-repo" }); + + const report = await runReadinessReport({ repoPath }); + + expect(report.extras.length).toBeGreaterThan(0); + const extraIds = report.extras.map((e) => e.id); + expect(extraIds).toContain("pr-template"); + expect(extraIds).toContain("pre-commit"); + expect(extraIds).toContain("architecture-doc"); + }); + + it("excludes extras when disabled", async () => { + await writePackageJson({ name: "test-repo" }); + + const report = await runReadinessReport({ repoPath, includeExtras: false }); + + expect(report.extras).toHaveLength(0); + }); + }); +}); diff --git a/src/services/__tests__/visualReport.test.ts b/src/services/__tests__/visualReport.test.ts new file mode 100644 index 0000000..27f199b --- /dev/null +++ b/src/services/__tests__/visualReport.test.ts @@ -0,0 +1,190 @@ +import { describe, expect, it } from "vitest"; + +import { generateVisualReport } from "../visualReport"; +import type { ReadinessReport } from "../readiness"; + +function makeReport(overrides: Partial = {}): ReadinessReport { + return { + repoPath: "/tmp/test-repo", + generatedAt: "2026-01-01T00:00:00.000Z", + isMonorepo: false, + apps: [], + pillars: [ + { id: "style-validation", name: "Style & Validation", passed: 2, total: 2, passRate: 1 }, + { id: "build-system", name: "Build System", passed: 1, total: 2, passRate: 0.5 }, + { id: "testing", name: "Testing", passed: 0, total: 1, passRate: 0 }, + { id: "documentation", name: "Documentation", passed: 1, total: 2, passRate: 0.5 }, + { id: "dev-environment", name: "Dev Environment", passed: 1, total: 2, passRate: 0.5 }, + { id: "code-quality", name: "Code Quality", passed: 1, total: 1, passRate: 1 }, + { id: "observability", name: "Observability", passed: 0, total: 1, passRate: 0 }, + { id: "security-governance", name: "Security & Governance", passed: 2, total: 4, passRate: 0.5 }, + { id: "ai-tooling", name: "AI Tooling", passed: 1, total: 4, passRate: 0.25 }, + ], + levels: [ + { level: 1, name: "Functional", passed: 5, total: 6, passRate: 0.83, achieved: true }, + { level: 2, name: "Documented", passed: 3, total: 6, passRate: 0.5, achieved: false }, + { level: 3, name: "Standardized", passed: 1, total: 4, passRate: 0.25, achieved: false }, + { level: 4, name: "Optimized", passed: 0, total: 0, passRate: 0, achieved: false }, + { level: 5, name: "Autonomous", passed: 0, total: 0, passRate: 0, achieved: false }, + ], + achievedLevel: 1, + criteria: [ + { id: "lint-config", title: "Linting configured", pillar: "style-validation", level: 1, scope: "repo", impact: "high", effort: "low", status: "pass" }, + { id: "readme", title: "README present", pillar: "documentation", level: 1, scope: "repo", impact: "high", effort: "low", status: "pass" }, + { id: "custom-instructions", title: "Custom AI instructions", pillar: "ai-tooling", level: 1, scope: "repo", impact: "high", effort: "low", status: "pass" }, + { id: "mcp-config", title: "MCP config present", pillar: "ai-tooling", level: 2, scope: "repo", impact: "high", effort: "low", status: "fail", reason: "Missing MCP config." }, + ], + extras: [], + ...overrides, + }; +} + +describe("generateVisualReport", () => { + it("returns valid HTML", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain(""); + expect(html).toContain(""); + }); + + it("includes the report title", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + title: "My Custom Report", + }); + + expect(html).toContain("My Custom Report"); + }); + + it("includes repo name", () => { + const html = generateVisualReport({ + reports: [{ repo: "my-repo", report: makeReport() }], + }); + + expect(html).toContain("my-repo"); + }); + + it("includes pillar names", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain("Style & Validation"); + expect(html).toContain("Build System"); + expect(html).toContain("AI Tooling"); + }); + + it("includes maturity level badge", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport({ achievedLevel: 2 }) }], + }); + + expect(html).toContain("Maturity 2"); + expect(html).toContain("Documented"); + }); + + it("includes AI Tooling Readiness hero section", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain("AI Tooling Readiness"); + }); + + it("includes maturity model descriptions", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain("Functional"); + expect(html).toContain("Documented"); + expect(html).toContain("Standardized"); + expect(html).toContain("Optimized"); + expect(html).toContain("Autonomous"); + }); + + it("includes theme toggle", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain("toggleTheme"); + expect(html).toContain("data-theme"); + }); + + it("includes light theme CSS variables", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain('[data-theme="light"]'); + expect(html).toContain('[data-theme="dark"]'); + }); + + it("includes GitHub logo SVG", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain("header-logo"); + expect(html).toContain(" { + const html = generateVisualReport({ + reports: [ + { repo: "good-repo", report: makeReport() }, + { repo: "bad-repo", report: makeReport(), error: "Clone failed" }, + ], + }); + + expect(html).toContain("bad-repo"); + expect(html).toContain("Clone failed"); + }); + + it("shows summary cards with correct counts", () => { + const html = generateVisualReport({ + reports: [ + { repo: "repo-1", report: makeReport() }, + { repo: "repo-2", report: makeReport() }, + ], + }); + + // Total repos should be 2 + expect(html).toContain(">2<"); + }); + + it("includes top fixes for failing criteria", () => { + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report: makeReport() }], + }); + + expect(html).toContain("Top Fixes"); + expect(html).toContain("MCP config present"); + }); + + it("shows all criteria passing when all pass", () => { + const report = makeReport({ + criteria: [ + { id: "lint-config", title: "Linting configured", pillar: "style-validation", level: 1, scope: "repo", impact: "high", effort: "low", status: "pass" }, + ], + }); + + const html = generateVisualReport({ + reports: [{ repo: "test-repo", report }], + }); + + expect(html).toContain("All criteria passing"); + }); + + it("escapes HTML in repo names", () => { + const html = generateVisualReport({ + reports: [{ repo: '', report: makeReport() }], + }); + + expect(html).not.toContain(''); + expect(html).toContain("<script>"); + }); +}); diff --git a/src/services/instructions.ts b/src/services/instructions.ts index 1d7cf62..8135932 100644 --- a/src/services/instructions.ts +++ b/src/services/instructions.ts @@ -26,7 +26,7 @@ export async function generateCopilotInstructions(options: GenerateInstructionsO try { progress("Creating session..."); // Try requested model, fall back to gpt-4.1 if gpt-5 fails - const preferredModel = options.model ?? "gpt-4.1"; + const preferredModel = options.model ?? "claude-sonnet-4.5"; const session = await client.createSession({ model: preferredModel, streaming: true, diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index 1399448..0350a4f 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -12,6 +12,7 @@ import { BatchTuiAzure } from "./BatchTuiAzure"; import { getGitHubToken } from "../services/github"; import { getAzureDevOpsToken } from "../services/azureDevops"; import { safeWriteFile } from "../utils/fs"; +import { analyzeRepo, RepoApp } from "../services/analyzer"; type Props = { repoPath: string; @@ -31,6 +32,9 @@ type Status = | "batch-github" | "batch-azure" | "eval-pick" + | "model-pick" + | "generate-pick" + | "generate-app-pick" | "bootstrapEvalCount" | "bootstrapEvalConfirm"; @@ -86,6 +90,15 @@ function Divider({ label }: { label?: string }): React.JSX.Element { ); } +const PREFERRED_MODELS = ["claude-sonnet-4.5", "claude-sonnet-4", "gpt-4.1", "gpt-5"]; + +function pickBestModel(available: string[], fallback: string): string { + for (const preferred of PREFERRED_MODELS) { + if (available.includes(preferred)) return preferred; + } + return available[0] || fallback; +} + export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX.Element { const app = useApp(); const [status, setStatus] = useState(skipAnimation ? "idle" : "intro"); @@ -98,13 +111,20 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const [evalCaseCountInput, setEvalCaseCountInput] = useState(""); const [evalBootstrapCount, setEvalBootstrapCount] = useState(null); const [availableModels, setAvailableModels] = useState([]); - const [evalModel, setEvalModel] = useState("gpt-4.1"); - const [judgeModel, setJudgeModel] = useState("gpt-4.1"); + const [evalModel, setEvalModel] = useState("claude-sonnet-4.5"); + const [judgeModel, setJudgeModel] = useState("claude-sonnet-4.5"); + const [modelPickTarget, setModelPickTarget] = useState<"eval" | "judge">("eval"); + const [modelCursor, setModelCursor] = useState(0); const [hasEvalConfig, setHasEvalConfig] = useState(null); const [activityLog, setActivityLog] = useState([]); + const [generateTarget, setGenerateTarget] = useState<"copilot-instructions" | "agents-md">("copilot-instructions"); + const [generateSavePath, setGenerateSavePath] = useState(""); + const [repoApps, setRepoApps] = useState([]); + const [isMonorepo, setIsMonorepo] = useState(false); const repoLabel = useMemo(() => path.basename(repoPath), [repoPath]); const repoFull = useMemo(() => repoPath, [repoPath]); const isLoading = status === "generating" || status === "bootstrapping" || status === "evaluating"; + const isMenu = status === "model-pick" || status === "eval-pick" || status === "batch-pick" || status === "generate-pick" || status === "generate-app-pick"; const spinner = useSpinner(isLoading); const addLog = (text: string, type: LogEntry["type"] = "info") => { @@ -115,17 +135,15 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setStatus("idle"); }; - const cycleModel = (current: string): string => { - if (!availableModels.length) return current; - const index = availableModels.indexOf(current); - const nextIndex = index === -1 ? 0 : (index + 1) % availableModels.length; - return availableModels[nextIndex]; - }; - - // Check for eval config on mount + // Check for eval config and repo structure on mount useEffect(() => { const configPath = path.join(repoPath, "primer.eval.json"); fs.access(configPath).then(() => setHasEvalConfig(true)).catch(() => setHasEvalConfig(false)); + analyzeRepo(repoPath).then((analysis) => { + const apps = analysis.apps ?? []; + setRepoApps(apps); + setIsMonorepo(analysis.isMonorepo ?? false); + }).catch(() => {}); }, [repoPath]); useEffect(() => { @@ -135,8 +153,8 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX if (!active) return; setAvailableModels(models); if (models.length === 0) return; - setEvalModel((current) => (models.includes(current) ? current : models[0])); - setJudgeModel((current) => (models.includes(current) ? current : models[0])); + setEvalModel((current) => (models.includes(current) ? current : pickBestModel(models, current))); + setJudgeModel((current) => (models.includes(current) ? current : pickBestModel(models, current))); }) .catch(() => { if (!active) return; @@ -147,6 +165,35 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX }; }, []); + const doGenerate = async (targetRepoPath: string, savePath: string, target: string): Promise => { + setStatus("generating"); + setMessage(`Generating ${target}...`); + addLog(`Generating ${target}...`, "progress"); + try { + const content = await generateCopilotInstructions({ + repoPath: targetRepoPath, + onProgress: (msg) => setMessage(msg) + }); + if (!content.trim()) { + throw new Error("Copilot SDK returned empty content."); + } + setGeneratedContent(content); + setGenerateSavePath(savePath); + setStatus("preview"); + setMessage("Review the generated content below."); + addLog(`${target} generated — review and save.`, "success"); + } catch (error) { + setStatus("error"); + const msg = error instanceof Error ? error.message : "Generation failed."; + if (msg.toLowerCase().includes("auth") || msg.toLowerCase().includes("login")) { + setMessage(`${msg} Run 'copilot' then '/login' in a separate terminal.`); + } else { + setMessage(msg); + } + addLog(msg, "error"); + } + }; + const bootstrapEvalConfig = async (count: number, force: boolean): Promise => { const configPath = path.join(repoPath, "primer.eval.json"); try { @@ -187,11 +234,12 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX if (status === "preview") { if (input.toLowerCase() === "s") { try { - const outputPath = path.join(repoPath, ".github", "copilot-instructions.md"); + const outputPath = generateSavePath || path.join(repoPath, ".github", "copilot-instructions.md"); await fs.mkdir(path.dirname(outputPath), { recursive: true }); await fs.writeFile(outputPath, generatedContent, "utf8"); setStatus("done"); - const msg = "Saved to .github/copilot-instructions.md"; + const relPath = path.relative(repoPath, outputPath); + const msg = `Saved to ${relPath}`; setMessage(msg); addLog(msg, "success"); setGeneratedContent(""); @@ -268,6 +316,130 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return; } + if (status === "generate-pick") { + if (input.toLowerCase() === "c") { + setGenerateTarget("copilot-instructions"); + if (isMonorepo && repoApps.length > 1) { + setStatus("generate-app-pick"); + setMessage("Generate for root or per-app?"); + } else { + const savePath = path.join(repoPath, ".github", "copilot-instructions.md"); + setGenerateSavePath(savePath); + await doGenerate(repoPath, savePath, "copilot-instructions"); + } + return; + } + if (input.toLowerCase() === "a") { + setGenerateTarget("agents-md"); + if (isMonorepo && repoApps.length > 1) { + setStatus("generate-app-pick"); + setMessage("Generate for root or per-app?"); + } else { + const savePath = path.join(repoPath, "AGENTS.md"); + setGenerateSavePath(savePath); + await doGenerate(repoPath, savePath, "agents-md"); + } + return; + } + if (key.escape) { + setStatus("idle"); + setMessage(""); + return; + } + return; + } + + if (status === "generate-app-pick") { + if (input.toLowerCase() === "r") { + // Root only + const savePath = generateTarget === "copilot-instructions" + ? path.join(repoPath, ".github", "copilot-instructions.md") + : path.join(repoPath, "AGENTS.md"); + setGenerateSavePath(savePath); + await doGenerate(repoPath, savePath, generateTarget); + return; + } + if (input.toLowerCase() === "a") { + // All apps sequentially + setStatus("generating"); + addLog(`Generating ${generateTarget} for ${repoApps.length} apps...`, "progress"); + let count = 0; + for (const app of repoApps) { + const savePath = generateTarget === "copilot-instructions" + ? path.join(app.path, ".github", "copilot-instructions.md") + : path.join(app.path, "AGENTS.md"); + setMessage(`Generating for ${app.name} (${count + 1}/${repoApps.length})...`); + try { + const content = await generateCopilotInstructions({ + repoPath: app.path, + onProgress: (msg) => setMessage(`${app.name}: ${msg}`) + }); + if (content.trim()) { + await fs.mkdir(path.dirname(savePath), { recursive: true }); + await fs.writeFile(savePath, content, "utf8"); + count++; + addLog(`${app.name}: saved ${path.basename(savePath)}`, "success"); + } + } catch (error) { + const msg = error instanceof Error ? error.message : "Failed."; + addLog(`${app.name}: ${msg}`, "error"); + } + } + setStatus("done"); + setMessage(`Generated ${generateTarget} for ${count}/${repoApps.length} apps.`); + return; + } + // Number to pick a specific app + const num = Number.parseInt(input, 10); + if (Number.isFinite(num) && num >= 1 && num <= repoApps.length) { + const app = repoApps[num - 1]; + const savePath = generateTarget === "copilot-instructions" + ? path.join(app.path, ".github", "copilot-instructions.md") + : path.join(app.path, "AGENTS.md"); + setGenerateSavePath(savePath); + await doGenerate(app.path, savePath, generateTarget); + return; + } + if (key.escape) { + setStatus("generate-pick"); + setMessage("Select what to generate."); + return; + } + return; + } + + if (status === "model-pick") { + if (key.escape) { + setStatus("idle"); + setMessage(""); + return; + } + if (key.upArrow) { + setModelCursor((prev) => Math.max(0, prev - 1)); + return; + } + if (key.downArrow) { + setModelCursor((prev) => Math.min(availableModels.length - 1, prev + 1)); + return; + } + if (key.return) { + const chosen = availableModels[modelCursor]; + if (chosen) { + if (modelPickTarget === "eval") { + setEvalModel(chosen); + addLog(`Eval model → ${chosen}`, "success"); + } else { + setJudgeModel(chosen); + addLog(`Judge model → ${chosen}`, "success"); + } + setStatus("idle"); + setMessage(`${modelPickTarget === "eval" ? "Eval" : "Judge"} model set to ${chosen}`); + } + return; + } + return; + } + if (status === "eval-pick") { if (input.toLowerCase() === "r") { // Run eval @@ -369,31 +541,9 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } if (input.toLowerCase() === "g") { - setStatus("generating"); - setMessage("Starting generation..."); - addLog("Generating copilot instructions...", "progress"); - try { - const content = await generateCopilotInstructions({ - repoPath, - onProgress: (msg) => setMessage(msg) - }); - if (!content.trim()) { - throw new Error("Copilot SDK returned empty instructions."); - } - setGeneratedContent(content); - setStatus("preview"); - setMessage("Review the generated instructions below."); - addLog("Instructions generated — review and save.", "success"); - } catch (error) { - setStatus("error"); - const msg = error instanceof Error ? error.message : "Generation failed."; - if (msg.toLowerCase().includes("auth") || msg.toLowerCase().includes("login")) { - setMessage(`${msg} Run 'copilot' then '/login' in a separate terminal.`); - } else { - setMessage(msg); - } - addLog(msg, "error"); - } + setStatus("generate-pick"); + setMessage("Select what to generate."); + return; } if (input.toLowerCase() === "b") { @@ -413,9 +563,12 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setMessage("No Copilot CLI models detected; using defaults."); return; } - const next = cycleModel(evalModel); - setEvalModel(next); - setMessage(`Eval model → ${next}`); + setModelPickTarget("eval"); + setStatus("model-pick"); + setMessage("Pick eval model."); + // Set cursor to current model + const idx = availableModels.indexOf(evalModel); + setModelCursor(idx >= 0 ? idx : 0); return; } @@ -424,16 +577,18 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX setMessage("No Copilot CLI models detected; using defaults."); return; } - const next = cycleModel(judgeModel); - setJudgeModel(next); - setMessage(`Judge model → ${next}`); + setModelPickTarget("judge"); + setStatus("model-pick"); + setMessage("Pick judge model."); + const idx = availableModels.indexOf(judgeModel); + setModelCursor(idx >= 0 ? idx : 0); return; } }); const statusIcon = status === "error" ? "✗" : status === "done" ? "✓" : isLoading ? spinner : "●"; - const statusLabel = status === "intro" ? "starting" : status === "idle" ? "ready" : status === "bootstrapEvalCount" ? "input" : status === "bootstrapEvalConfirm" ? "confirm" : status === "eval-pick" ? "eval" : status === "batch-pick" ? "batch" : status; - const statusColor = status === "error" ? "red" : status === "done" ? "green" : isLoading ? "yellow" : "cyanBright"; + const statusLabel = status === "intro" ? "starting" : status === "idle" ? "ready" : status === "bootstrapEvalCount" ? "input" : status === "bootstrapEvalConfirm" ? "confirm" : status === "eval-pick" ? "eval" : status === "batch-pick" ? "batch" : status === "model-pick" ? "models" : status; + const statusColor = status === "error" ? "red" : status === "done" ? "green" : isLoading ? "yellow" : isMenu ? "magentaBright" : "cyanBright"; const formatTokens = (result: EvalResult): string => { const withUsage = result.metrics?.withInstructions?.tokenUsage; @@ -475,6 +630,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX Repo {repoLabel} + {isMonorepo && monorepo · {repoApps.length} apps} {repoFull} @@ -520,6 +676,47 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX )} + {/* Model Picker */} + {status === "model-pick" && availableModels.length > 0 && ( + <> + + + {availableModels.map((model, i) => { + const current = modelPickTarget === "eval" ? evalModel : judgeModel; + const isCurrent = model === current; + const isCursor = i === modelCursor; + return ( + + {isCursor ? "\u276F " : " "} + {model} + {isCurrent && (current)} + + ); + })} + {availableModels.length > 15 && ( + Use {"\u2191\u2193"} to scroll + )} + + + )} + + {/* App picker for monorepo generate */} + {status === "generate-app-pick" && repoApps.length > 0 && ( + <> + + + {repoApps.map((app, i) => ( + + {i + 1} + + {app.name} + {path.relative(repoPath, app.path)} + + ))} + + + )} + {/* Input: eval case count */} {status === "bootstrapEvalCount" && ( @@ -531,7 +728,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX {/* Preview */} {status === "preview" && generatedContent && ( - Preview (.github/copilot-instructions.md) + Preview ({path.relative(repoPath, generateSavePath) || generateTarget}) {truncatedPreview} )} @@ -574,6 +771,32 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX + ) : status === "model-pick" ? ( + + Use + {"\u2191\u2193"} + to navigate, + Enter + to select + + + ) : status === "generate-pick" ? ( + + + + + + ) : status === "generate-app-pick" ? ( + + + + or press + 1 + - + {repoApps.length} + + + ) : status === "eval-pick" ? ( diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 0000000..9d7c740 --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + target: "node20", + outDir: "dist", + clean: true, + splitting: false, + sourcemap: true, + dts: false, + banner: { + js: "#!/usr/bin/env node", + }, + // Keep node_modules as external — they'll be installed via npm + external: [/^[^./]/], + esbuildOptions(options) { + options.jsx = "automatic"; + }, +}); From 2cda58dab818c56cb04a1bf72c6e6ed3d3107120 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Sun, 8 Feb 2026 21:24:46 -0700 Subject: [PATCH 11/19] refactor: update key hints for clarity in TUI --- src/ui/tui.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index 0350a4f..d759e51 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -817,8 +817,8 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX - - + + From d1db06827587bc1a8da15b376916c85379c33c2c Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Sun, 8 Feb 2026 21:51:32 -0700 Subject: [PATCH 12/19] feat: update trajectory viewer with new design and metrics display --- src/services/evaluator.ts | 577 ++++++++++++++++++++------------------ 1 file changed, 305 insertions(+), 272 deletions(-) diff --git a/src/services/evaluator.ts b/src/services/evaluator.ts index 6e4b797..1a137cd 100644 --- a/src/services/evaluator.ts +++ b/src/services/evaluator.ts @@ -637,281 +637,314 @@ function buildViewerPath(outputPath: string): string { function buildTrajectoryViewerHtml(data: Record): string { const serialized = JSON.stringify(data).replace(/ - - - - - Primer Eval Trajectory - - - -

    Primer Eval Trajectory

    -
    -
    -
    -
    -
    + + + + +Primer Eval Results + + + +
    +
    + +
    +

    Eval Results

    +
    - - + '
    ' + + '
    ' + + '
    '; + }); + document.getElementById('caseDetails').innerHTML = html; +} +renderCaseDetails(); + + `; } From e87dd2f5e461cb3f4801a136c8d01937a325f8e7 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Wed, 11 Feb 2026 17:14:00 -0700 Subject: [PATCH 13/19] Enhance PrimerTui: Add eval case generation with Copilot SDK and improve error handling --- src/ui/tui.tsx | 101 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/src/ui/tui.tsx b/src/ui/tui.tsx index d759e51..43cb965 100644 --- a/src/ui/tui.tsx +++ b/src/ui/tui.tsx @@ -25,6 +25,7 @@ type Status = | "generating" | "bootstrapping" | "evaluating" + | "modelPicker" | "preview" | "done" | "error" @@ -44,6 +45,18 @@ type LogEntry = { time: string; }; +type EvalUiConfig = { + modelPicker?: "visible" | "hidden"; +}; + +type EvalConfig = { + instructionFile?: string; + cases: Array<{ id: string; prompt: string; expectation: string }>; + systemMessage?: string; + outputPath?: string; + ui?: EvalUiConfig; +}; + const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]; function useSpinner(active: boolean): string { @@ -113,6 +126,7 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const [availableModels, setAvailableModels] = useState([]); const [evalModel, setEvalModel] = useState("claude-sonnet-4.5"); const [judgeModel, setJudgeModel] = useState("claude-sonnet-4.5"); + const [hideModelPicker, setHideModelPicker] = useState(false); const [modelPickTarget, setModelPickTarget] = useState<"eval" | "judge">("eval"); const [modelCursor, setModelCursor] = useState(0); const [hasEvalConfig, setHasEvalConfig] = useState(null); @@ -146,6 +160,22 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX }).catch(() => {}); }, [repoPath]); + const indexForModel = (model: string): number => { + const index = availableModels.indexOf(model); + return index === -1 ? 0 : index; + }; + + const openModelPicker = (target: "eval" | "judge"): void => { + if (!availableModels.length) { + setMessage("No Copilot CLI models detected; using defaults."); + return; + } + setModelPickTarget(target); + setModelCursor(indexForModel(target === "eval" ? evalModel : judgeModel)); + setStatus("modelPicker"); + setMessage(`Select ${target} model.`); + }; + useEffect(() => { let active = true; listCopilotModels() @@ -194,6 +224,25 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } }; + useEffect(() => { + let active = true; + const configPath = path.join(repoPath, "primer.eval.json"); + fs.readFile(configPath, "utf8") + .then((raw) => { + if (!active) return; + const parsed = JSON.parse(raw) as EvalConfig; + const setting = parsed.ui?.modelPicker; + setHideModelPicker(setting === "hidden"); + }) + .catch(() => { + if (!active) return; + setHideModelPicker(false); + }); + return () => { + active = false; + }; + }, [repoPath]); + const bootstrapEvalConfig = async (count: number, force: boolean): Promise => { const configPath = path.join(repoPath, "primer.eval.json"); try { @@ -217,6 +266,9 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX const msg = error instanceof Error ? error.message : "Failed to generate eval config."; setMessage(msg); addLog(msg, "error"); + } finally { + setEvalCaseCountInput(""); + setEvalBootstrapCount(null); } }; @@ -226,6 +278,46 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX return; } + if (status === "modelPicker") { + if (key.escape) { + setStatus("idle"); + setMessage("Model picker cancelled."); + return; + } + + if (key.upArrow) { + setModelCursor((prev: number) => { + if (!availableModels.length) return 0; + return (prev - 1 + availableModels.length) % availableModels.length; + }); + return; + } + + if (key.downArrow) { + setModelCursor((prev: number) => { + if (!availableModels.length) return 0; + return (prev + 1) % availableModels.length; + }); + return; + } + + if (key.return) { + const selected = availableModels[modelCursor]; + if (!selected) return; + if (modelPickTarget === "eval") { + setEvalModel(selected); + setModelPickTarget("judge"); + setModelCursor(indexForModel(judgeModel)); + setMessage(`Eval model set: ${selected}. Select judge model.`); + return; + } + setJudgeModel(selected); + setStatus("idle"); + setMessage(`Models set: eval ${evalModel} • judge ${selected}.`); + } + return; + } + if (key.escape || input.toLowerCase() === "q") { app.exit(); return; @@ -559,22 +651,21 @@ export function PrimerTui({ repoPath, skipAnimation = false }: Props): React.JSX } if (input.toLowerCase() === "m") { - if (!availableModels.length) { - setMessage("No Copilot CLI models detected; using defaults."); + if (hideModelPicker) { + setMessage("Model picker hidden. Set ui.modelPicker to \"visible\" in primer.eval.json."); return; } setModelPickTarget("eval"); setStatus("model-pick"); setMessage("Pick eval model."); - // Set cursor to current model const idx = availableModels.indexOf(evalModel); setModelCursor(idx >= 0 ? idx : 0); return; } if (input.toLowerCase() === "j") { - if (!availableModels.length) { - setMessage("No Copilot CLI models detected; using defaults."); + if (hideModelPicker) { + setMessage("Model picker hidden. Set ui.modelPicker to \"visible\" in primer.eval.json."); return; } setModelPickTarget("judge"); From 2c8843eee26ff368c28ed9815e535e0c9196f097 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Wed, 11 Feb 2026 17:25:21 -0700 Subject: [PATCH 14/19] feat: add multi-model code review prompt and synthesize findings into a prioritized fix list --- .github/agents/code-review-codex.agent.md | 163 ++++++++++++++++++ .github/agents/code-review-gemini.agent.md | 163 ++++++++++++++++++ .github/agents/code-review-opus.agent.md | 163 ++++++++++++++++++ .github/prompts/deslop.prompt.md | 13 ++ .../prompts/generate-improvements.prompt.md | 87 ++++++++++ .github/prompts/review.prompt.md | 10 ++ 6 files changed, 599 insertions(+) create mode 100644 .github/agents/code-review-codex.agent.md create mode 100644 .github/agents/code-review-gemini.agent.md create mode 100644 .github/agents/code-review-opus.agent.md create mode 100644 .github/prompts/deslop.prompt.md create mode 100644 .github/prompts/generate-improvements.prompt.md create mode 100644 .github/prompts/review.prompt.md diff --git a/.github/agents/code-review-codex.agent.md b/.github/agents/code-review-codex.agent.md new file mode 100644 index 0000000..c4be7e6 --- /dev/null +++ b/.github/agents/code-review-codex.agent.md @@ -0,0 +1,163 @@ +--- +description: Code review following VS Code contribution standards — correctness, lifecycle, naming, layering, accessibility, and security +name: Code Review (Codex) +tools: ['search', 'read/problems', 'read/terminalLastCommand', 'web/githubRepo'] +model: GPT-5.3-Codex (copilot) +handoffs: + - label: Fix Issues + agent: agent + prompt: Fix the issues identified in the code review above. + send: false +--- + +You are a code reviewer for the VS Code codebase. Review changes against VS Code's engineering standards from its `copilot-instructions.md`, ESLint config, and codebase conventions. + +# Review Process + +1. **Understand context** — Read changed files and surrounding code to understand intent +2. **Check correctness** — Logic, edge cases, error handling, off-by-one errors +3. **Check VS Code conventions** — Naming, disposables, layering, localization, style, accessibility +4. **Check security** — OWASP Top 10 where relevant +5. **Check testing** — Disposable leak checks, coverage of new behavior + +# VS Code Conventions Checklist + +## Indentation + +- Use **tabs**, not spaces + +## Naming + +- **Classes, interfaces, enums, type aliases**: `PascalCase` +- **Interfaces**: prefix with `I` (e.g., `IDisposable`, `IEditorService`) +- **Enum values**: `PascalCase` +- **Functions, methods, properties, local variables**: `camelCase` +- **Private/protected members**: prefix with `_` (e.g., `private _myField`) +- **Service decorators**: `createDecorator('serviceName')` +- Use whole words in names when possible + +## Strings + +- Use `"double quotes"` for user-facing strings that need localization +- Use `'single quotes'` for everything else +- All user-visible strings must use `localize()` or `nls.localize()` +- Never concatenate localized strings — use placeholders (`{0}`, `{1}`) + +## UI Labels + +- Title-style capitalization for command labels, buttons, and menu items +- Don't capitalize prepositions of four or fewer letters unless first or last word + +## Types + +- Don't export types or functions unless shared across multiple components +- Don't introduce new types or values to the global namespace +- Don't use `any` or `unknown` unless absolutely necessary — define proper types + +## Comments + +- Use JSDoc style comments for functions, interfaces, enums, and classes + +## Style + +- Prefer arrow functions `=>` over anonymous function expressions +- Only surround arrow function parameters when necessary (`x => x` not `(x) => x`, but `(x, y) => x + y` is fine) +- Always surround loop and conditional bodies with curly braces +- Open curly braces on the same line as the statement +- Prefer top-level `export function x() {}` over `export const x = () => {}` (better stack traces) +- Prefer `async`/`await` over `.then()` chains +- Prefer named regex capture groups over numbered ones + +## Disposable Lifecycle + +- Classes holding resources must extend `Disposable` and use `this._register()` to track child disposables +- Use `DisposableStore`, `MutableDisposable`, or `DisposableMap` — never raw `IDisposable[]` +- Event listeners, file watchers, and providers must be registered via `this._register()` +- Do NOT register a disposable to the containing class if created in a method called repeatedly — return `IDisposable` from the method and let the caller register it +- Disposables must not be leaked: verify `dispose()` is called or ownership is transferred +- Prefer correlated file watchers (via `fileService.createWatcher`) over shared ones + +## Layering & Architecture + +- `/common/` — no DOM, no Node.js, no Electron imports +- `/browser/` — may use DOM APIs, never Node.js +- `/node/` or `/electron-main/` — may use Node.js APIs +- Never import `browser` from `common`, or `node` from `browser`/`common` +- Contributions use `registerWorkbenchContribution2()` with appropriate `WorkbenchPhase` +- Use `npm run valid-layers-check` to verify layering + +## Error Handling + +- Use `onUnexpectedError()` for errors in async flows that shouldn't crash +- Use typed error classes (e.g., `BugIndicatingError`) for programming errors +- Never swallow errors silently — at minimum log via `ILogService` + +## Events + +- Use `Emitter` for event sources, expose as `Event` via getter +- Register event listeners with `this._register()` to prevent leaks + +## File Headers + +- Every file must start with the Microsoft copyright header (MIT license) + +## Accessibility + +- Interactive elements must have ARIA labels +- Keyboard navigation must work for all new UI +- Screen reader announcements for dynamic state changes via `aria.alert()` +- Prefer `IHoverService` for tooltips over custom implementations + +## Code Quality + +- Never duplicate imports — reuse existing imports +- Don't duplicate code — look for existing utilities before writing new ones +- Don't use another component's storage keys directly — use proper API +- Clean up any temporary files or scripts created during development + +## Testing + +- `ensureNoDisposablesAreLeakedInTestSuite()` must be called in every test suite +- Minimize assertions — prefer one snapshot-style `assert.deepStrictEqual` over many small assertions +- Don't add tests to the wrong suite (e.g., appending to end of file instead of inside the relevant `suite`) +- Match existing test patterns (`describe`/`test` or `suite`/`test`) consistently + +# Severity Levels + +- **Critical**: Security vulnerabilities, disposable leaks in hot paths, layering violations. Must fix. +- **Major**: Bugs, missing error handling, naming violations, missing localization, `any` casts. Must fix. +- **Minor**: Style improvements, missing region markers, non-blocking refactors. Recommended. +- **Nit**: Cosmetic preferences. Optional. + +# Review Rules + +- Never approve code with Critical or Major findings +- Explain *why* something is a problem, not just *what* +- Suggest a concrete fix for Critical and Major findings +- Do not flag style preferences as Major issues +- Do not rewrite working code just because you would write it differently +- Limit feedback to actionable items — no praise or filler + +# Security Checklist + +- XSS: user content rendered via `MarkdownString` must set `supportHtml: false` or sanitize +- Trusted Types: use `TrustedTypePolicy` for dynamic script/style injection +- Secrets: no hardcoded credentials, tokens, or API keys in source +- Input validation: untrusted input validated at extension host / IPC boundaries +- Dependencies: no known vulnerable packages introduced + +# Output Format + +```markdown +## Summary +One-sentence summary of the overall change quality. + +## Findings +### [Severity] Title +**File:** `path/to/file.ts:L42` +**Issue:** Description of the problem and why it matters. +**Suggestion:** Concrete fix or approach. + +## Verdict +APPROVE | REQUEST_CHANGES | NEEDS_DISCUSSION +``` diff --git a/.github/agents/code-review-gemini.agent.md b/.github/agents/code-review-gemini.agent.md new file mode 100644 index 0000000..a903bc5 --- /dev/null +++ b/.github/agents/code-review-gemini.agent.md @@ -0,0 +1,163 @@ +--- +description: Code review following VS Code contribution standards — correctness, lifecycle, naming, layering, accessibility, and security +name: Code Review (Gemini) +tools: ['search', 'read/problems', 'read/terminalLastCommand', 'web/githubRepo'] +model: Gemini 3 Pro (Preview) (copilot) +handoffs: + - label: Fix Issues + agent: agent + prompt: Fix the issues identified in the code review above. + send: false +--- + +You are a code reviewer for the VS Code codebase. Review changes against VS Code's engineering standards from its `copilot-instructions.md`, ESLint config, and codebase conventions. + +# Review Process + +1. **Understand context** — Read changed files and surrounding code to understand intent +2. **Check correctness** — Logic, edge cases, error handling, off-by-one errors +3. **Check VS Code conventions** — Naming, disposables, layering, localization, style, accessibility +4. **Check security** — OWASP Top 10 where relevant +5. **Check testing** — Disposable leak checks, coverage of new behavior + +# VS Code Conventions Checklist + +## Indentation + +- Use **tabs**, not spaces + +## Naming + +- **Classes, interfaces, enums, type aliases**: `PascalCase` +- **Interfaces**: prefix with `I` (e.g., `IDisposable`, `IEditorService`) +- **Enum values**: `PascalCase` +- **Functions, methods, properties, local variables**: `camelCase` +- **Private/protected members**: prefix with `_` (e.g., `private _myField`) +- **Service decorators**: `createDecorator('serviceName')` +- Use whole words in names when possible + +## Strings + +- Use `"double quotes"` for user-facing strings that need localization +- Use `'single quotes'` for everything else +- All user-visible strings must use `localize()` or `nls.localize()` +- Never concatenate localized strings — use placeholders (`{0}`, `{1}`) + +## UI Labels + +- Title-style capitalization for command labels, buttons, and menu items +- Don't capitalize prepositions of four or fewer letters unless first or last word + +## Types + +- Don't export types or functions unless shared across multiple components +- Don't introduce new types or values to the global namespace +- Don't use `any` or `unknown` unless absolutely necessary — define proper types + +## Comments + +- Use JSDoc style comments for functions, interfaces, enums, and classes + +## Style + +- Prefer arrow functions `=>` over anonymous function expressions +- Only surround arrow function parameters when necessary (`x => x` not `(x) => x`, but `(x, y) => x + y` is fine) +- Always surround loop and conditional bodies with curly braces +- Open curly braces on the same line as the statement +- Prefer top-level `export function x() {}` over `export const x = () => {}` (better stack traces) +- Prefer `async`/`await` over `.then()` chains +- Prefer named regex capture groups over numbered ones + +## Disposable Lifecycle + +- Classes holding resources must extend `Disposable` and use `this._register()` to track child disposables +- Use `DisposableStore`, `MutableDisposable`, or `DisposableMap` — never raw `IDisposable[]` +- Event listeners, file watchers, and providers must be registered via `this._register()` +- Do NOT register a disposable to the containing class if created in a method called repeatedly — return `IDisposable` from the method and let the caller register it +- Disposables must not be leaked: verify `dispose()` is called or ownership is transferred +- Prefer correlated file watchers (via `fileService.createWatcher`) over shared ones + +## Layering & Architecture + +- `/common/` — no DOM, no Node.js, no Electron imports +- `/browser/` — may use DOM APIs, never Node.js +- `/node/` or `/electron-main/` — may use Node.js APIs +- Never import `browser` from `common`, or `node` from `browser`/`common` +- Contributions use `registerWorkbenchContribution2()` with appropriate `WorkbenchPhase` +- Use `npm run valid-layers-check` to verify layering + +## Error Handling + +- Use `onUnexpectedError()` for errors in async flows that shouldn't crash +- Use typed error classes (e.g., `BugIndicatingError`) for programming errors +- Never swallow errors silently — at minimum log via `ILogService` + +## Events + +- Use `Emitter` for event sources, expose as `Event` via getter +- Register event listeners with `this._register()` to prevent leaks + +## File Headers + +- Every file must start with the Microsoft copyright header (MIT license) + +## Accessibility + +- Interactive elements must have ARIA labels +- Keyboard navigation must work for all new UI +- Screen reader announcements for dynamic state changes via `aria.alert()` +- Prefer `IHoverService` for tooltips over custom implementations + +## Code Quality + +- Never duplicate imports — reuse existing imports +- Don't duplicate code — look for existing utilities before writing new ones +- Don't use another component's storage keys directly — use proper API +- Clean up any temporary files or scripts created during development + +## Testing + +- `ensureNoDisposablesAreLeakedInTestSuite()` must be called in every test suite +- Minimize assertions — prefer one snapshot-style `assert.deepStrictEqual` over many small assertions +- Don't add tests to the wrong suite (e.g., appending to end of file instead of inside the relevant `suite`) +- Match existing test patterns (`describe`/`test` or `suite`/`test`) consistently + +# Severity Levels + +- **Critical**: Security vulnerabilities, disposable leaks in hot paths, layering violations. Must fix. +- **Major**: Bugs, missing error handling, naming violations, missing localization, `any` casts. Must fix. +- **Minor**: Style improvements, missing region markers, non-blocking refactors. Recommended. +- **Nit**: Cosmetic preferences. Optional. + +# Review Rules + +- Never approve code with Critical or Major findings +- Explain *why* something is a problem, not just *what* +- Suggest a concrete fix for Critical and Major findings +- Do not flag style preferences as Major issues +- Do not rewrite working code just because you would write it differently +- Limit feedback to actionable items — no praise or filler + +# Security Checklist + +- XSS: user content rendered via `MarkdownString` must set `supportHtml: false` or sanitize +- Trusted Types: use `TrustedTypePolicy` for dynamic script/style injection +- Secrets: no hardcoded credentials, tokens, or API keys in source +- Input validation: untrusted input validated at extension host / IPC boundaries +- Dependencies: no known vulnerable packages introduced + +# Output Format + +```markdown +## Summary +One-sentence summary of the overall change quality. + +## Findings +### [Severity] Title +**File:** `path/to/file.ts:L42` +**Issue:** Description of the problem and why it matters. +**Suggestion:** Concrete fix or approach. + +## Verdict +APPROVE | REQUEST_CHANGES | NEEDS_DISCUSSION +``` diff --git a/.github/agents/code-review-opus.agent.md b/.github/agents/code-review-opus.agent.md new file mode 100644 index 0000000..264def9 --- /dev/null +++ b/.github/agents/code-review-opus.agent.md @@ -0,0 +1,163 @@ +--- +description: Code review following VS Code contribution standards — correctness, lifecycle, naming, layering, accessibility, and security +name: Code Review (Opus) +tools: ['search', 'read/problems', 'read/terminalLastCommand', 'web/githubRepo'] +model: Claude Opus 4.6 (fast mode) (Preview) (copilot) +handoffs: + - label: Fix Issues + agent: agent + prompt: Fix the issues identified in the code review above. + send: false +--- + +You are a code reviewer for the VS Code codebase. Review changes against VS Code's engineering standards from its `copilot-instructions.md`, ESLint config, and codebase conventions. + +# Review Process + +1. **Understand context** — Read changed files and surrounding code to understand intent +2. **Check correctness** — Logic, edge cases, error handling, off-by-one errors +3. **Check VS Code conventions** — Naming, disposables, layering, localization, style, accessibility +4. **Check security** — OWASP Top 10 where relevant +5. **Check testing** — Disposable leak checks, coverage of new behavior + +# VS Code Conventions Checklist + +## Indentation + +- Use **tabs**, not spaces + +## Naming + +- **Classes, interfaces, enums, type aliases**: `PascalCase` +- **Interfaces**: prefix with `I` (e.g., `IDisposable`, `IEditorService`) +- **Enum values**: `PascalCase` +- **Functions, methods, properties, local variables**: `camelCase` +- **Private/protected members**: prefix with `_` (e.g., `private _myField`) +- **Service decorators**: `createDecorator('serviceName')` +- Use whole words in names when possible + +## Strings + +- Use `"double quotes"` for user-facing strings that need localization +- Use `'single quotes'` for everything else +- All user-visible strings must use `localize()` or `nls.localize()` +- Never concatenate localized strings — use placeholders (`{0}`, `{1}`) + +## UI Labels + +- Title-style capitalization for command labels, buttons, and menu items +- Don't capitalize prepositions of four or fewer letters unless first or last word + +## Types + +- Don't export types or functions unless shared across multiple components +- Don't introduce new types or values to the global namespace +- Don't use `any` or `unknown` unless absolutely necessary — define proper types + +## Comments + +- Use JSDoc style comments for functions, interfaces, enums, and classes + +## Style + +- Prefer arrow functions `=>` over anonymous function expressions +- Only surround arrow function parameters when necessary (`x => x` not `(x) => x`, but `(x, y) => x + y` is fine) +- Always surround loop and conditional bodies with curly braces +- Open curly braces on the same line as the statement +- Prefer top-level `export function x() {}` over `export const x = () => {}` (better stack traces) +- Prefer `async`/`await` over `.then()` chains +- Prefer named regex capture groups over numbered ones + +## Disposable Lifecycle + +- Classes holding resources must extend `Disposable` and use `this._register()` to track child disposables +- Use `DisposableStore`, `MutableDisposable`, or `DisposableMap` — never raw `IDisposable[]` +- Event listeners, file watchers, and providers must be registered via `this._register()` +- Do NOT register a disposable to the containing class if created in a method called repeatedly — return `IDisposable` from the method and let the caller register it +- Disposables must not be leaked: verify `dispose()` is called or ownership is transferred +- Prefer correlated file watchers (via `fileService.createWatcher`) over shared ones + +## Layering & Architecture + +- `/common/` — no DOM, no Node.js, no Electron imports +- `/browser/` — may use DOM APIs, never Node.js +- `/node/` or `/electron-main/` — may use Node.js APIs +- Never import `browser` from `common`, or `node` from `browser`/`common` +- Contributions use `registerWorkbenchContribution2()` with appropriate `WorkbenchPhase` +- Use `npm run valid-layers-check` to verify layering + +## Error Handling + +- Use `onUnexpectedError()` for errors in async flows that shouldn't crash +- Use typed error classes (e.g., `BugIndicatingError`) for programming errors +- Never swallow errors silently — at minimum log via `ILogService` + +## Events + +- Use `Emitter` for event sources, expose as `Event` via getter +- Register event listeners with `this._register()` to prevent leaks + +## File Headers + +- Every file must start with the Microsoft copyright header (MIT license) + +## Accessibility + +- Interactive elements must have ARIA labels +- Keyboard navigation must work for all new UI +- Screen reader announcements for dynamic state changes via `aria.alert()` +- Prefer `IHoverService` for tooltips over custom implementations + +## Code Quality + +- Never duplicate imports — reuse existing imports +- Don't duplicate code — look for existing utilities before writing new ones +- Don't use another component's storage keys directly — use proper API +- Clean up any temporary files or scripts created during development + +## Testing + +- `ensureNoDisposablesAreLeakedInTestSuite()` must be called in every test suite +- Minimize assertions — prefer one snapshot-style `assert.deepStrictEqual` over many small assertions +- Don't add tests to the wrong suite (e.g., appending to end of file instead of inside the relevant `suite`) +- Match existing test patterns (`describe`/`test` or `suite`/`test`) consistently + +# Severity Levels + +- **Critical**: Security vulnerabilities, disposable leaks in hot paths, layering violations. Must fix. +- **Major**: Bugs, missing error handling, naming violations, missing localization, `any` casts. Must fix. +- **Minor**: Style improvements, missing region markers, non-blocking refactors. Recommended. +- **Nit**: Cosmetic preferences. Optional. + +# Review Rules + +- Never approve code with Critical or Major findings +- Explain *why* something is a problem, not just *what* +- Suggest a concrete fix for Critical and Major findings +- Do not flag style preferences as Major issues +- Do not rewrite working code just because you would write it differently +- Limit feedback to actionable items — no praise or filler + +# Security Checklist + +- XSS: user content rendered via `MarkdownString` must set `supportHtml: false` or sanitize +- Trusted Types: use `TrustedTypePolicy` for dynamic script/style injection +- Secrets: no hardcoded credentials, tokens, or API keys in source +- Input validation: untrusted input validated at extension host / IPC boundaries +- Dependencies: no known vulnerable packages introduced + +# Output Format + +```markdown +## Summary +One-sentence summary of the overall change quality. + +## Findings +### [Severity] Title +**File:** `path/to/file.ts:L42` +**Issue:** Description of the problem and why it matters. +**Suggestion:** Concrete fix or approach. + +## Verdict +APPROVE | REQUEST_CHANGES | NEEDS_DISCUSSION +``` diff --git a/.github/prompts/deslop.prompt.md b/.github/prompts/deslop.prompt.md new file mode 100644 index 0000000..3c7d492 --- /dev/null +++ b/.github/prompts/deslop.prompt.md @@ -0,0 +1,13 @@ +--- +name: deslop +description: Remove AI-generated slop from a branch by diffing against main +--- +Get the diff (`git diff main...HEAD`) and remove AI-generated slop from changed files: + +- Comments inconsistent with the rest of the file +- Defensive checks or try/catch blocks abnormal for that codepath +- `any` casts used to work around type issues +- Inline imports (move to top of file) +- Style inconsistencies with the surrounding code + +Preserve legitimate changes. Report a 1-3 sentence summary of what was removed. \ No newline at end of file diff --git a/.github/prompts/generate-improvements.prompt.md b/.github/prompts/generate-improvements.prompt.md new file mode 100644 index 0000000..deecf2c --- /dev/null +++ b/.github/prompts/generate-improvements.prompt.md @@ -0,0 +1,87 @@ +--- +description: Suggest improvements to the Prompt LSP project across features, bug fixes, security, performance, and engineering quality. +--- + +You are a senior software engineer reviewing the **Prompt LSP** project — a VS Code extension with a Language Server Protocol backend that analyzes, validates, and improves AI prompt files (`.prompt.md`, `.agent.md`, `.system.md`, `.instructions.md`). + +## Architecture Context + +The project has two main components: + +- **Language Server** (`src/server.ts`) — LSP server that parses prompt documents, runs analysis, and sends diagnostics. +- **VS Code Client** (`client/src/extension.ts`) — Extension that connects to the server, provides UI integration, and proxies LLM requests via `vscode.lm`. + +Analysis is split into two layers: + +1. **Static Analysis** (`src/analyzers/static.ts`) — Fast, free, runs on every keystroke. Handles variable validation, injection detection, instruction strength, ambiguity, tokenization, frontmatter validation, and composition link checking. +2. **LLM Analysis** (`src/analyzers/llm.ts`) — Semantic analysis via GitHub Copilot's `vscode.lm` API. Handles contradiction detection, persona consistency, safety guardrail analysis, cognitive load, output shape prediction, and semantic coverage. Runs on save with debouncing. + +Results are cached by content hash in `src/cache.ts` with TTL-based expiry. LSP features like CodeLens, hover, go-to-definition, and code actions are in `src/lspFeatures.ts`. + +## Your Task + +Analyze the full codebase and generate a prioritized list of **concrete, actionable improvements**. For each suggestion, provide: + +1. **Title** — short descriptive name +2. **Category** — one of: `feature`, `bug-fix`, `security`, `performance`, `engineering`, `testing`, `dx` (developer experience) +3. **Priority** — `critical`, `high`, `medium`, `low` +4. **Description** — what the problem or opportunity is and why it matters +5. **Suggested implementation** — specific code changes, files to modify, and approach + +## Areas to Evaluate + +### Features & Functionality +- What analyzers from the SPEC (`docs/SPEC.md`) are specified but not yet implemented? +- Are there LSP capabilities (completions, rename, folding ranges, inlay hints, semantic tokens) that would add value? +- Are there missing quick-fix code actions for existing diagnostics? +- Could the extension provide better onboarding or discoverability? + +### Bug Fixes & Correctness +- Are there edge cases in parsing (frontmatter, variables, composition links, sections) that would produce incorrect results? +- Do the LLM response parsers handle malformed JSON gracefully in every path? +- Are there race conditions in the debounce/caching/versioning logic? +- Does the `detectFileType` function correctly classify all supported file patterns? + +### Security +- Are composition link paths validated against path traversal attacks? +- Is user-controlled text from prompt documents safely handled when embedded in LLM analysis prompts (prompt injection risk)? +- Are there any risks from `fs.accessSync` / `fs.readFileSync` on user-supplied paths? +- Is the cache susceptible to poisoning or collision? + +### Performance +- Are there unnecessary re-analyses or redundant file reads? +- Could any analyses be lazily computed or incrementally updated? +- Is tiktoken encoding being efficiently managed (encoder caching, disposal)? +- Are there opportunities for parallelization or early termination? + +### Engineering Quality +- Are there TypeScript strict-mode violations or `any` types that should be eliminated? +- Is error handling consistent and informative? +- Are there dead code paths or unused exports? +- Could modules be better separated for testability? + +### Testing +- What is the current test coverage and where are the gaps? +- Are the LLM analyzer paths tested (even with mocked proxy)? +- Are edge cases in frontmatter parsing, composition links, and variable detection covered? +- Are there integration-level tests for the full diagnostic pipeline? + +### Developer Experience +- Is the build/watch/debug workflow smooth? +- Are there missing npm scripts, lint configs, or CI integrations? +- Is the extension easy to install, configure, and try out? + +## Output Format + +Return the improvements as a numbered list grouped by category. Use this structure: + +``` +## Category Name + +### 1. Title (Priority: critical/high/medium/low) +**Problem:** What's wrong or missing +**Suggestion:** Specific changes to make +**Files:** Which files to modify +``` + +Focus on substance over volume. Prefer 10 high-quality, specific suggestions over 30 vague ones. Always reference actual code, file paths, and function names from the codebase. \ No newline at end of file diff --git a/.github/prompts/review.prompt.md b/.github/prompts/review.prompt.md new file mode 100644 index 0000000..54a8d01 --- /dev/null +++ b/.github/prompts/review.prompt.md @@ -0,0 +1,10 @@ +--- +name: review +description: Run three parallel code reviews (Opus, Gemini, Codex) and synthesize findings into a prioritized fix list +--- +Run a multi-model code review: + +1. Invoke `code-review-opus`, `code-review-gemini`, and `code-review-codex` as three parallel subagents +2. Cross-grade: have each reviewer evaluate the other two reviews for false positives and missed issues +3. Synthesize a deduplicated list of findings ordered by severity (Critical > Major > Minor > Nit) +4. Output one final fix list with file, line, and suggested change for each item \ No newline at end of file From 8b7722c8bc356c256c2d538c8b750289c15d65c4 Mon Sep 17 00:00:00 2001 From: Pierce Boggan Date: Wed, 11 Feb 2026 17:53:16 -0700 Subject: [PATCH 15/19] feat: enhance language and package manager detection in analyzer service - Added support for additional languages (C#, Java, Ruby, PHP) in the analyzeRepo function. - Updated detectPackageManager to recognize new package managers (Maven, Gradle, Bundler, Composer). - Improved handling of pnpm workspace files by skipping comment-only lines and supporting inline arrays. fix: validate Azure DevOps slugs and improve error handling - Introduced validateAdoSlug function to ensure organization, project, and repo names are valid. - Updated API calls in Azure DevOps service to use validated slugs. - Enhanced error handling in checkRepoHasInstructions to throw descriptive errors on request failures. refactor: streamline Copilot CLI path resolution - Cached Copilot CLI path to avoid redundant lookups. - Improved findCopilotCliPath to handle platform-specific paths more effectively. - Added glob pattern matching for VS Code extension paths. chore: update evalScaffold and evaluator services - Refactored generateEvalScaffold to use withCwd for better directory management. - Simplified runEval by using assertCopilotCliReady for CLI path resolution. - Removed redundant EvalCase and EvalConfig type definitions from evaluator. fix: sanitize error messages in git push - Added error handling in pushBranch to sanitize embedded credentials from error messages. feat: enhance instruction generation and PR body creation - Updated generateCopilotInstructions to use withCwd for improved directory handling. - Created utility functions for building PR bodies for configurations and instructions. - Updated BatchTui and BatchTuiAzure to use DEFAULT_MODEL for instruction generation. chore: add utility functions for file system operations - Introduced validateCachePath to prevent path traversal vulnerabilities. - Enhanced safeWriteFile to reject symlinks and ensure safe file writing. --- .../prompts/generate-improvements.prompt.md | 121 ++++++++++------ package.json | 1 + src/cli.ts | 7 +- src/commands/eval.ts | 5 +- src/commands/init.ts | 8 +- src/commands/pr.ts | 62 +-------- src/commands/readiness.ts | 1 + src/config.ts | 2 + src/services/__tests__/analyzer.test.ts | 115 ++++++++++++++- src/services/__tests__/cachePath.test.ts | 41 ++++++ src/services/__tests__/generator.test.ts | 128 +++++++++++++++++ src/services/__tests__/git.test.ts | 47 +++++++ src/services/analyzer.ts | 30 +++- src/services/azureDevops.ts | 37 ++++- src/services/copilot.ts | 70 ++++++++-- src/services/evalScaffold.ts | 131 +++++++++--------- src/services/evaluator.ts | 61 ++------ src/services/git.ts | 6 + src/services/instructions.ts | 101 +++++++------- src/ui/BatchTui.tsx | 53 ++----- src/ui/BatchTuiAzure.tsx | 44 ++---- src/ui/tui.tsx | 30 ++-- src/utils/cwd.ts | 24 ++++ src/utils/fs.ts | 36 ++++- src/utils/pr.ts | 49 +++++++ 25 files changed, 824 insertions(+), 386 deletions(-) create mode 100644 src/config.ts create mode 100644 src/services/__tests__/cachePath.test.ts create mode 100644 src/services/__tests__/generator.test.ts create mode 100644 src/services/__tests__/git.test.ts create mode 100644 src/utils/cwd.ts create mode 100644 src/utils/pr.ts diff --git a/.github/prompts/generate-improvements.prompt.md b/.github/prompts/generate-improvements.prompt.md index deecf2c..774c0e3 100644 --- a/.github/prompts/generate-improvements.prompt.md +++ b/.github/prompts/generate-improvements.prompt.md @@ -1,22 +1,55 @@ --- -description: Suggest improvements to the Prompt LSP project across features, bug fixes, security, performance, and engineering quality. +description: Suggest improvements to the Primer CLI project across features, bug fixes, security, performance, and engineering quality. --- -You are a senior software engineer reviewing the **Prompt LSP** project — a VS Code extension with a Language Server Protocol backend that analyzes, validates, and improves AI prompt files (`.prompt.md`, `.agent.md`, `.system.md`, `.instructions.md`). +You are a senior software engineer reviewing the **Primer** project — a TypeScript CLI tool that primes repositories for AI-assisted development by analyzing codebases, generating Copilot instructions and VS Code configs, running evaluations, and producing AI readiness reports. ## Architecture Context -The project has two main components: - -- **Language Server** (`src/server.ts`) — LSP server that parses prompt documents, runs analysis, and sends diagnostics. -- **VS Code Client** (`client/src/extension.ts`) — Extension that connects to the server, provides UI integration, and proxies LLM requests via `vscode.lm`. - -Analysis is split into two layers: - -1. **Static Analysis** (`src/analyzers/static.ts`) — Fast, free, runs on every keystroke. Handles variable validation, injection detection, instruction strength, ambiguity, tokenization, frontmatter validation, and composition link checking. -2. **LLM Analysis** (`src/analyzers/llm.ts`) — Semantic analysis via GitHub Copilot's `vscode.lm` API. Handles contradiction detection, persona consistency, safety guardrail analysis, cognitive load, output shape prediction, and semantic coverage. Runs on save with debouncing. - -Results are cached by content hash in `src/cache.ts` with TTL-based expiry. LSP features like CodeLens, hover, go-to-definition, and code actions are in `src/lspFeatures.ts`. +- **Tech Stack:** TypeScript (ESM, strict), Node.js, React (Ink for TUI), Commander for CLI +- **Entrypoint:** `src/index.ts` → `runCli` in `src/cli.ts` +- **Dependencies:** `@github/copilot-sdk`, `@octokit/rest`, `simple-git`, `ink`, `commander`, `fast-glob`, `@inquirer/prompts` + +### Key Directories + +- `src/commands/` — CLI subcommands (`init`, `generate`, `pr`, `eval`, `tui`, `instructions`, `readiness`, `batch`, `batch-readiness`) +- `src/services/` — Core logic: + - `analyzer.ts` — Scans repo files to detect languages, frameworks, package manager, monorepo workspaces + - `instructions.ts` — Generates `.github/copilot-instructions.md` using Copilot SDK agent sessions + - `generator.ts` — Writes `.vscode/settings.json` and `.vscode/mcp.json` configs + - `evaluator.ts` — Runs eval cases comparing agent responses with/without instructions, builds trajectory viewer HTML + - `readiness.ts` — Multi-pillar AI readiness assessment (style, build, testing, docs, dev-env, code-quality, observability, security, ai-tooling) + - `visualReport.ts` — Generates beautiful HTML readiness reports with summary cards, pillar charts, level distribution + - `git.ts` — Clone/branch operations via `simple-git` + - `github.ts` / `azureDevops.ts` — GitHub (Octokit) and Azure DevOps API integrations + - `copilot.ts` — Locates and validates the Copilot CLI binary + - `evalScaffold.ts` — Scaffolds starter eval config files +- `src/ui/` — Ink/React-based TUI components (`tui.tsx`, `BatchTui.tsx`, `BatchReadinessTui.tsx`, `BatchTuiAzure.tsx`, `AnimatedBanner.tsx`) +- `src/utils/` — Shared utilities (`fs.ts` for safe file writes, `logger.ts`, `pr.ts`) + +### CLI Commands + +| Command | Description | +|---------|-------------| +| `primer init` | Interactive setup wizard (instructions + configs) | +| `primer generate ` | Generate `instructions`, `agents`, `mcp`, or `vscode` configs | +| `primer instructions` | Generate copilot-instructions.md via Copilot SDK | +| `primer eval` | Run evaluation cases comparing with/without instructions | +| `primer readiness` | AI readiness assessment with optional visual HTML report | +| `primer batch` | Batch process multiple repos across GitHub/Azure orgs | +| `primer batch-readiness` | Batch readiness reports across multiple repos | +| `primer pr` | Automate branch/PR creation for generated configs | +| `primer tui` | Interactive Ink-based terminal UI | + +### Key Patterns + +- ESM everywhere (`"type": "module"` in `package.json`) +- Strict TypeScript (ES2022 target, ESNext modules) +- Safe file writes: only overwrites with `--force` flag (`safeWriteFile` in `src/utils/fs.ts`) +- Copilot SDK integration via `@github/copilot-sdk` with session-based agent conversations +- GitHub token resolution: `GITHUB_TOKEN` → `GH_TOKEN` → `gh auth token` fallback chain +- Readiness uses a leveled criteria system (levels 1-5) across 9 pillars with pass/fail/skip status +- Build with `tsup`, test with `vitest`, lint with `eslint`, format with `prettier` ## Your Task @@ -31,45 +64,53 @@ Analyze the full codebase and generate a prioritized list of **concrete, actiona ## Areas to Evaluate ### Features & Functionality -- What analyzers from the SPEC (`docs/SPEC.md`) are specified but not yet implemented? -- Are there LSP capabilities (completions, rename, folding ranges, inlay hints, semantic tokens) that would add value? -- Are there missing quick-fix code actions for existing diagnostics? -- Could the extension provide better onboarding or discoverability? +- Are there CLI commands or flags referenced in README/help text that aren't fully implemented? +- Could `analyzeRepo` detect more languages, frameworks, or package managers (e.g., Gradle, Maven, .NET, Ruby)? +- Does `primer init --yes` skip useful defaults (currently only selects instructions, not MCP/VS Code configs)? +- Could `primer readiness` support more output formats (e.g., CSV, PDF) or comparison over time? +- Are there opportunities to improve the batch processing UX (progress, retries, parallel execution)? +- Could `primer eval` scaffold richer default eval cases or support custom grading rubrics? ### Bug Fixes & Correctness -- Are there edge cases in parsing (frontmatter, variables, composition links, sections) that would produce incorrect results? -- Do the LLM response parsers handle malformed JSON gracefully in every path? -- Are there race conditions in the debounce/caching/versioning logic? -- Does the `detectFileType` function correctly classify all supported file patterns? +- Does `analyzeRepo` correctly handle edge cases like empty repos, non-git directories, or deeply nested monorepos? +- Does `readPnpmWorkspace` handle all valid YAML edge cases or is the line-by-line parser fragile? +- Does the Copilot SDK session handling (`instructions.ts`) properly clean up on errors (session.destroy, client.stop)? +- Are there race conditions in batch processing when cloning/analyzing multiple repos concurrently? +- Does `process.chdir()` in `generateCopilotInstructions` create issues if called concurrently? ### Security -- Are composition link paths validated against path traversal attacks? -- Is user-controlled text from prompt documents safely handled when embedded in LLM analysis prompts (prompt injection risk)? -- Are there any risks from `fs.accessSync` / `fs.readFileSync` on user-supplied paths? -- Is the cache susceptible to poisoning or collision? +- Is the GitHub token (`getGitHubToken`) handled securely — never logged, never leaked in error messages? +- Are user-supplied repo paths validated against path traversal (e.g., `../../etc/passwd` as a repo path)? +- Does `execFileAsync` usage properly sanitize arguments to prevent command injection? +- Are Azure DevOps PAT tokens handled securely throughout the `azureDevops.ts` service? +- Is the `safeWriteFile` function safe against symlink attacks (writing through a symlink to an unintended location)? ### Performance -- Are there unnecessary re-analyses or redundant file reads? -- Could any analyses be lazily computed or incrementally updated? -- Is tiktoken encoding being efficiently managed (encoder caching, disposal)? -- Are there opportunities for parallelization or early termination? +- Could `analyzeRepo` avoid redundant `readdir`/`readFile` calls when the same repo is analyzed multiple times? +- Is `fast-glob` usage in workspace detection efficient for large monorepos with many packages? +- Could the Copilot CLI path lookup (`findCopilotCliPath` in `copilot.ts`) be cached across invocations? +- Are batch operations (batch, batch-readiness) parallelized effectively, or do they process repos sequentially? +- Does the eval trajectory viewer HTML (`evaluator.ts`) generate excessively large output for many eval cases? ### Engineering Quality -- Are there TypeScript strict-mode violations or `any` types that should be eliminated? -- Is error handling consistent and informative? -- Are there dead code paths or unused exports? -- Could modules be better separated for testability? +- Are there TypeScript strict-mode violations, `any` types, or `as` casts that should be eliminated? +- Is error handling consistent across services — do all commands give clear, actionable error messages? +- Are there dead code paths or unused exports in the services or commands? +- Could the `process.chdir()` pattern in `instructions.ts` be replaced with a safer approach (e.g., passing cwd to child processes)? +- Are service interfaces well-separated for testability, or are there tight couplings (e.g., direct `process.env` reads)? ### Testing -- What is the current test coverage and where are the gaps? -- Are the LLM analyzer paths tested (even with mocked proxy)? -- Are edge cases in frontmatter parsing, composition links, and variable detection covered? -- Are there integration-level tests for the full diagnostic pipeline? +- What is the current test coverage? Only `analyzer.test.ts`, `fs.test.ts`, `readiness.test.ts`, and `visualReport.test.ts` exist — many services and commands are untested. +- Are there tests for the Copilot SDK integration paths (even with mocked SDK)? +- Are edge cases in `readPnpmWorkspace`, `detectWorkspace`, and `resolveWorkspaceApps` covered? +- Are there integration tests for the full `primer init` or `primer generate` flows? +- Is the GitHub/Azure DevOps API integration tested with mocked HTTP responses? ### Developer Experience -- Is the build/watch/debug workflow smooth? -- Are there missing npm scripts, lint configs, or CI integrations? -- Is the extension easy to install, configure, and try out? +- Is the `npx tsx` workflow sufficient, or should there be a `dev` script for faster iteration? +- Are error messages clear when prerequisites are missing (Copilot CLI, GitHub token, `gh` CLI)? +- Is the TUI (`src/ui/tui.tsx`) tested or difficult to test due to Ink rendering? +- Are there missing npm scripts for common workflows (e.g., `npm run dev`, `npm run test:unit`)? ## Output Format diff --git a/package.json b/package.json index 3c6fd55..5c8c40a 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ ], "scripts": { "build": "tsup", + "dev": "tsx src/index.ts", "prepare": "test \"$CI\" = true || tsup", "lint": "eslint .", "format": "prettier --write .", diff --git a/src/cli.ts b/src/cli.ts index 6d8a169..4bfeabf 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -8,6 +8,7 @@ import { instructionsCommand } from "./commands/instructions"; import { batchCommand } from "./commands/batch"; import { readinessCommand } from "./commands/readiness"; import { batchReadinessCommand } from "./commands/batchReadiness"; +import { DEFAULT_MODEL, DEFAULT_JUDGE_MODEL } from "./config"; export function runCli(argv: string[]): void { const program = new Command(); @@ -46,8 +47,8 @@ export function runCli(argv: string[]): void { .command("eval") .argument("[path]", "Path to eval config JSON") .option("--repo ", "Repository path", process.cwd()) - .option("--model ", "Model for responses", "claude-sonnet-4.5") - .option("--judge-model ", "Model for judging", "claude-sonnet-4.5") + .option("--model ", "Model for responses", DEFAULT_MODEL) + .option("--judge-model ", "Model for judging", DEFAULT_JUDGE_MODEL) .option("--list-models", "List Copilot CLI models and exit") .option("--output ", "Write results JSON to file") .option("--init", "Create a starter primer.eval.json file") @@ -64,7 +65,7 @@ export function runCli(argv: string[]): void { .command("instructions") .option("--repo ", "Repository path", process.cwd()) .option("--output ", "Output path for copilot instructions") - .option("--model ", "Model for instructions generation", "claude-sonnet-4.5") + .option("--model ", "Model for instructions generation", DEFAULT_MODEL) .action(instructionsCommand); program diff --git a/src/commands/eval.ts b/src/commands/eval.ts index 104a069..ac9deba 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -3,6 +3,7 @@ import fs from "fs/promises"; import { runEval } from "../services/evaluator"; import { listCopilotModels } from "../services/copilot"; import { generateEvalScaffold } from "../services/evalScaffold"; +import { DEFAULT_MODEL, DEFAULT_JUDGE_MODEL } from "../config"; type EvalOptions = { repo?: string; @@ -55,8 +56,8 @@ export async function evalCommand(configPathArg: string | undefined, options: Ev const { summary, viewerPath } = await runEval({ configPath, repoPath, - model: options.model ?? "gpt-5", - judgeModel: options.judgeModel ?? "gpt-5", + model: options.model ?? DEFAULT_MODEL, + judgeModel: options.judgeModel ?? DEFAULT_JUDGE_MODEL, outputPath: options.output }); diff --git a/src/commands/init.ts b/src/commands/init.ts index 2c6ed94..1242547 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -15,7 +15,7 @@ import { } from "../services/azureDevops"; import { buildAuthedUrl, cloneRepo, isGitRepo } from "../services/git"; import { generateCopilotInstructions } from "../services/instructions"; -import { ensureDir } from "../utils/fs"; +import { ensureDir, validateCachePath } from "../utils/fs"; import { prettyPrintSummary } from "../utils/logger"; type InitOptions = { @@ -59,7 +59,7 @@ export async function initCommand(repoPathArg: string | undefined, options: Init }); const cacheRoot = path.join(process.cwd(), ".primer-cache"); - repoPath = path.join(cacheRoot, selection.owner, selection.name); + repoPath = validateCachePath(cacheRoot, selection.owner, selection.name); await ensureDir(repoPath); const hasGit = await isGitRepo(repoPath); @@ -122,7 +122,7 @@ export async function initCommand(repoPathArg: string | undefined, options: Init }); const cacheRoot = path.join(process.cwd(), ".primer-cache"); - repoPath = path.join(cacheRoot, orgSelection.name, projectSelection.name, repoSelection.name); + repoPath = validateCachePath(cacheRoot, orgSelection.name, projectSelection.name, repoSelection.name); await ensureDir(repoPath); const hasGit = await isGitRepo(repoPath); @@ -135,7 +135,7 @@ export async function initCommand(repoPathArg: string | undefined, options: Init prettyPrintSummary(analysis); const selections = options.yes - ? ["instructions"] + ? ["instructions", "mcp", "vscode"] : await checkbox({ message: "What would you like to generate?", choices: [ diff --git a/src/commands/pr.ts b/src/commands/pr.ts index 7050840..9f4c8ac 100644 --- a/src/commands/pr.ts +++ b/src/commands/pr.ts @@ -10,7 +10,9 @@ import { getRepo as getAzureRepo } from "../services/azureDevops"; import { buildAuthedUrl, checkoutBranch, cloneRepo, commitAll, isGitRepo, pushBranch } from "../services/git"; -import { ensureDir } from "../utils/fs"; +import { ensureDir, validateCachePath } from "../utils/fs"; +import { buildConfigsPrBody, buildInstructionsPrBody } from "../utils/pr"; +import { DEFAULT_MODEL } from "../config"; type PrOptions = { branch?: string; @@ -48,7 +50,7 @@ export async function prCommand(repo: string | undefined, options: PrOptions): P const repoInfo = await getAzureRepo(token, organization, project, name); const cacheRoot = path.join(process.cwd(), ".primer-cache"); - const repoPath = path.join(cacheRoot, organization, project, name); + const repoPath = validateCachePath(cacheRoot, organization, project, name); await ensureDir(repoPath); if (!(await isGitRepo(repoPath))) { @@ -59,7 +61,7 @@ export async function prCommand(repo: string | undefined, options: PrOptions): P const branch = options.branch ?? "primer/add-instructions"; await checkoutBranch(repoPath, branch); - const instructions = await generateCopilotInstructions({ repoPath, model: "gpt-4.1" }); + const instructions = await generateCopilotInstructions({ repoPath, model: DEFAULT_MODEL }); const instructionsPath = path.join(repoPath, ".github", "copilot-instructions.md"); await ensureDir(path.dirname(instructionsPath)); await fs.writeFile(instructionsPath, instructions, "utf8"); @@ -99,7 +101,7 @@ export async function prCommand(repo: string | undefined, options: PrOptions): P const repoInfo = await getRepo(token, owner, name); const cacheRoot = path.join(process.cwd(), ".primer-cache"); - const repoPath = path.join(cacheRoot, owner, name); + const repoPath = validateCachePath(cacheRoot, owner, name); await ensureDir(repoPath); if (!(await isGitRepo(repoPath))) { @@ -125,60 +127,10 @@ export async function prCommand(repo: string | undefined, options: PrOptions): P owner, repo: name, title: "🤖 Prime this repo for AI", - body: buildPrBody(), + body: buildConfigsPrBody(), head: `${owner}:${branch}`, base: repoInfo.defaultBranch }); console.log(`Created PR: ${prUrl}`); } - -function buildPrBody(): string { - return [ - "## 🤖 Primed for AI", - "", - "This PR adds configurations to prime this repository for AI coding assistants.", - "", - "### Added Files", - "", - "| File | Purpose |", - "|------|---------|", - "| `.vscode/settings.json` | VS Code settings for optimal AI assistance |", - "| `.vscode/mcp.json` | Model Context Protocol server configuration |", - "", - "### How to Use", - "", - "1. Merge this PR", - "2. Open the project in VS Code", - "3. Start chatting with Copilot — it now understands your project!", - "", - "---", - "*Generated by Primer*" - ].join("\n"); -} - -function buildInstructionsPrBody(): string { - return [ - "## 🤖 Copilot Instructions Added", - "", - "This PR adds a `.github/copilot-instructions.md` file to help GitHub Copilot understand this codebase better.", - "", - "### What's Included", - "", - "The instructions file contains:", - "- Project overview and architecture", - "- Tech stack and conventions", - "- Build/test commands", - "- Key directories and files", - "", - "### Benefits", - "", - "With these instructions, Copilot will:", - "- Generate more contextually-aware code suggestions", - "- Follow project-specific patterns and conventions", - "- Understand the codebase structure", - "", - "---", - "*Generated by [Primer](https://github.com/pierceboggan/primer) - Prime your repos for AI*" - ].join("\n"); -} diff --git a/src/commands/readiness.ts b/src/commands/readiness.ts index 642e471..5f2e09f 100644 --- a/src/commands/readiness.ts +++ b/src/commands/readiness.ts @@ -41,6 +41,7 @@ export async function readinessCommand(repoPathArg: string | undefined, options: const outputPath = path.resolve(options.output); await fs.writeFile(outputPath, JSON.stringify(report, null, 2), "utf8"); console.log(chalk.green(`✓ JSON report saved: ${outputPath}`)); + return; } if (options.json) { diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..a46583c --- /dev/null +++ b/src/config.ts @@ -0,0 +1,2 @@ +export const DEFAULT_MODEL = "claude-sonnet-4.5"; +export const DEFAULT_JUDGE_MODEL = "claude-sonnet-4.5"; diff --git a/src/services/__tests__/analyzer.test.ts b/src/services/__tests__/analyzer.test.ts index 724678f..9096e8e 100644 --- a/src/services/__tests__/analyzer.test.ts +++ b/src/services/__tests__/analyzer.test.ts @@ -1,13 +1,28 @@ import fs from "fs/promises"; import os from "os"; import path from "path"; -import { describe, expect, it } from "vitest"; +import { afterEach, describe, expect, it } from "vitest"; import { analyzeRepo } from "../analyzer"; describe("analyzeRepo", () => { + const tmpDirs: string[] = []; + + async function makeTmpDir(): Promise { + const dir = await fs.mkdtemp(path.join(os.tmpdir(), "primer-test-")); + tmpDirs.push(dir); + return dir; + } + + afterEach(async () => { + for (const dir of tmpDirs) { + await fs.rm(dir, { recursive: true, force: true }).catch(() => {}); + } + tmpDirs.length = 0; + }); + it("detects TypeScript and npm workspace", async () => { - const repoPath = await fs.mkdtemp(path.join(os.tmpdir(), "primer-test-")); + const repoPath = await makeTmpDir(); const packageJson = { name: "demo", workspaces: ["packages/*"], @@ -28,4 +43,100 @@ describe("analyzeRepo", () => { expect(result.workspaceType).toBe("npm"); expect(result.apps?.length).toBe(1); }); + + it("detects C# language", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "MyProject.csproj"), "", "utf8"); + + const result = await analyzeRepo(repoPath); + expect(result.languages).toContain("C#"); + }); + + it("detects Java via pom.xml", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "pom.xml"), "", "utf8"); + + const result = await analyzeRepo(repoPath); + expect(result.languages).toContain("Java"); + expect(result.packageManager).toBe("maven"); + }); + + it("detects Java via build.gradle", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "build.gradle"), "plugins {}", "utf8"); + + const result = await analyzeRepo(repoPath); + expect(result.languages).toContain("Java"); + expect(result.packageManager).toBe("gradle"); + }); + + it("detects Ruby", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "Gemfile"), "source 'https://rubygems.org'", "utf8"); + + const result = await analyzeRepo(repoPath); + expect(result.languages).toContain("Ruby"); + expect(result.packageManager).toBe("bundler"); + }); + + it("detects PHP", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "composer.json"), "{}", "utf8"); + + const result = await analyzeRepo(repoPath); + expect(result.languages).toContain("PHP"); + expect(result.packageManager).toBe("composer"); + }); + + it("returns empty analysis for empty directory", async () => { + const repoPath = await makeTmpDir(); + + const result = await analyzeRepo(repoPath); + expect(result.languages).toEqual([]); + expect(result.frameworks).toEqual([]); + expect(result.packageManager).toBeUndefined(); + }); + + it("detects pnpm workspace with comments in YAML", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "package.json"), JSON.stringify({ name: "root" })); + await fs.writeFile(path.join(repoPath, "pnpm-lock.yaml"), "lockfileVersion: 9"); + await fs.writeFile( + path.join(repoPath, "pnpm-workspace.yaml"), + [ + "# workspace config", + "packages:", + " - 'apps/*' # main apps", + " - 'libs/*'", + "# end" + ].join("\n") + ); + await fs.mkdir(path.join(repoPath, "apps", "web"), { recursive: true }); + await fs.writeFile( + path.join(repoPath, "apps", "web", "package.json"), + JSON.stringify({ name: "web", scripts: { build: "tsc" } }) + ); + + const result = await analyzeRepo(repoPath); + expect(result.workspaceType).toBe("pnpm"); + expect(result.workspacePatterns).toContain("apps/*"); + expect(result.workspacePatterns).toContain("libs/*"); + // Should not include comment text in patterns + expect(result.workspacePatterns?.some(p => p.includes("#"))).toBe(false); + }); + + it("detects pnpm inline array workspace", async () => { + const repoPath = await makeTmpDir(); + await fs.writeFile(path.join(repoPath, "package.json"), JSON.stringify({ name: "root" })); + await fs.writeFile(path.join(repoPath, "pnpm-lock.yaml"), "lockfileVersion: 9"); + await fs.writeFile( + path.join(repoPath, "pnpm-workspace.yaml"), + "packages: [\"apps/*\", \"libs/*\"]\n" + ); + + const result = await analyzeRepo(repoPath); + expect(result.workspaceType).toBe("pnpm"); + expect(result.workspacePatterns).toContain("apps/*"); + expect(result.workspacePatterns).toContain("libs/*"); + }); }); diff --git a/src/services/__tests__/cachePath.test.ts b/src/services/__tests__/cachePath.test.ts new file mode 100644 index 0000000..dc86c5d --- /dev/null +++ b/src/services/__tests__/cachePath.test.ts @@ -0,0 +1,41 @@ +import path from "path"; +import { describe, expect, it } from "vitest"; + +import { validateCachePath } from "../../utils/fs"; + +describe("validateCachePath", () => { + it("returns resolved path for normal segments", () => { + const cacheRoot = "/tmp/primer-cache"; + const result = validateCachePath(cacheRoot, "owner", "repo"); + expect(result).toBe(path.resolve(cacheRoot, "owner", "repo")); + }); + + it("throws on path traversal via ..", () => { + const cacheRoot = "/tmp/primer-cache"; + expect(() => validateCachePath(cacheRoot, "..", "..", "etc")).toThrow("escapes cache directory"); + }); + + it("throws on absolute path segment that escapes", () => { + const cacheRoot = "/tmp/primer-cache"; + expect(() => validateCachePath(cacheRoot, "/etc/passwd")).toThrow("escapes cache directory"); + }); + + it("allows the cache root itself", () => { + const cacheRoot = "/tmp/primer-cache"; + const result = validateCachePath(cacheRoot); + expect(result).toBe(path.resolve(cacheRoot)); + }); + + it("allows nested paths within cache root", () => { + const cacheRoot = "/tmp/primer-cache"; + const result = validateCachePath(cacheRoot, "org", "project", "repo"); + expect(result).toBe(path.resolve(cacheRoot, "org", "project", "repo")); + }); + + it("throws when segment contains .. to escape", () => { + const cacheRoot = "/tmp/primer-cache"; + expect(() => validateCachePath(cacheRoot, "owner", "repo", "..", "..", "..", "etc")).toThrow( + "escapes cache directory" + ); + }); +}); diff --git a/src/services/__tests__/generator.test.ts b/src/services/__tests__/generator.test.ts new file mode 100644 index 0000000..a64ec51 --- /dev/null +++ b/src/services/__tests__/generator.test.ts @@ -0,0 +1,128 @@ +import fs from "fs/promises"; +import os from "os"; +import path from "path"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; + +import { generateConfigs } from "../generator"; +import type { RepoAnalysis } from "../analyzer"; + +describe("generateConfigs", () => { + let tmpDir: string; + + beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "primer-gen-")); + }); + + afterEach(async () => { + await fs.rm(tmpDir, { recursive: true, force: true }); + }); + + function makeAnalysis(overrides?: Partial): RepoAnalysis { + return { + path: tmpDir, + isGitRepo: false, + languages: ["TypeScript"], + frameworks: [], + ...overrides + }; + } + + it("generates valid mcp.json", async () => { + const analysis = makeAnalysis(); + const { summary } = await generateConfigs({ + repoPath: tmpDir, + analysis, + selections: ["mcp"], + force: false + }); + + const content = await fs.readFile(path.join(tmpDir, ".vscode", "mcp.json"), "utf8"); + const parsed = JSON.parse(content); + + expect(parsed.servers).toBeDefined(); + expect(parsed.servers.github).toBeDefined(); + expect(parsed.servers.filesystem).toBeDefined(); + expect(summary).toContain("Wrote"); + }); + + it("generates valid vscode settings with frameworks", async () => { + const analysis = makeAnalysis({ frameworks: ["React", "Next.js"] }); + await generateConfigs({ + repoPath: tmpDir, + analysis, + selections: ["vscode"], + force: false + }); + + const content = await fs.readFile(path.join(tmpDir, ".vscode", "settings.json"), "utf8"); + const parsed = JSON.parse(content); + + expect(parsed["github.copilot.chat.codeGeneration.instructions"]).toBeDefined(); + expect(parsed["chat.mcp.enabled"]).toBe(true); + // Should mention frameworks in review instructions + const reviewText = parsed["github.copilot.chat.reviewSelection.instructions"][0].text; + expect(reviewText).toContain("React"); + expect(reviewText).toContain("Next.js"); + }); + + it("generates fallback review text when no frameworks", async () => { + const analysis = makeAnalysis({ frameworks: [] }); + await generateConfigs({ + repoPath: tmpDir, + analysis, + selections: ["vscode"], + force: false + }); + + const content = await fs.readFile(path.join(tmpDir, ".vscode", "settings.json"), "utf8"); + const parsed = JSON.parse(content); + const reviewText = parsed["github.copilot.chat.reviewSelection.instructions"][0].text; + expect(reviewText).toContain("repo conventions"); + }); + + it("skips existing files without force", async () => { + await fs.mkdir(path.join(tmpDir, ".vscode"), { recursive: true }); + await fs.writeFile(path.join(tmpDir, ".vscode", "mcp.json"), "original", "utf8"); + + const analysis = makeAnalysis(); + const { summary } = await generateConfigs({ + repoPath: tmpDir, + analysis, + selections: ["mcp"], + force: false + }); + + const content = await fs.readFile(path.join(tmpDir, ".vscode", "mcp.json"), "utf8"); + expect(content).toBe("original"); + expect(summary).toContain("Skipped"); + }); + + it("overwrites existing files with force", async () => { + await fs.mkdir(path.join(tmpDir, ".vscode"), { recursive: true }); + await fs.writeFile(path.join(tmpDir, ".vscode", "mcp.json"), "original", "utf8"); + + const analysis = makeAnalysis(); + const { summary } = await generateConfigs({ + repoPath: tmpDir, + analysis, + selections: ["mcp"], + force: true + }); + + const content = await fs.readFile(path.join(tmpDir, ".vscode", "mcp.json"), "utf8"); + expect(content).not.toBe("original"); + expect(summary).toContain("Wrote"); + }); + + it("does nothing with empty selections", async () => { + const analysis = makeAnalysis(); + const { summary } = await generateConfigs({ + repoPath: tmpDir, + analysis, + selections: [], + force: false + }); + + expect(summary).toBe("No changes made."); + }); +}); diff --git a/src/services/__tests__/git.test.ts b/src/services/__tests__/git.test.ts new file mode 100644 index 0000000..99c5a12 --- /dev/null +++ b/src/services/__tests__/git.test.ts @@ -0,0 +1,47 @@ +import { describe, expect, it } from "vitest"; + +import { buildAuthedUrl } from "../git"; + +describe("buildAuthedUrl", () => { + it("adds github x-access-token to https URL", () => { + expect( + buildAuthedUrl("https://github.com/owner/repo", "tok123", "github") + ).toBe("https://x-access-token:tok123@github.com/owner/repo"); + }); + + it("adds azure PAT to https URL", () => { + expect( + buildAuthedUrl("https://dev.azure.com/org/project/_git/repo", "pat123", "azure") + ).toBe("https://pat:pat123@dev.azure.com/org/project/_git/repo"); + }); + + it("strips trailing slashes before adding auth", () => { + expect( + buildAuthedUrl("https://github.com/owner/repo///", "tok", "github") + ).toBe("https://x-access-token:tok@github.com/owner/repo"); + }); + + it("replaces existing x-access-token auth", () => { + expect( + buildAuthedUrl("https://x-access-token:old@github.com/owner/repo", "new-tok", "github") + ).toBe("https://x-access-token:new-tok@github.com/owner/repo"); + }); + + it("replaces existing PAT auth for azure", () => { + expect( + buildAuthedUrl("https://pat:old@dev.azure.com/repo", "new-pat", "azure") + ).toBe("https://pat:new-pat@dev.azure.com/repo"); + }); + + it("returns non-https URLs unchanged", () => { + expect( + buildAuthedUrl("git@github.com:owner/repo.git", "tok", "github") + ).toBe("git@github.com:owner/repo.git"); + }); + + it("handles whitespace in URL", () => { + expect( + buildAuthedUrl(" https://github.com/owner/repo ", "tok", "github") + ).toBe("https://x-access-token:tok@github.com/owner/repo"); + }); +}); diff --git a/src/services/analyzer.ts b/src/services/analyzer.ts index a9e0566..55fac44 100644 --- a/src/services/analyzer.ts +++ b/src/services/analyzer.ts @@ -45,12 +45,21 @@ export async function analyzeRepo(repoPath: string): Promise { const hasRequirements = files.includes("requirements.txt"); const hasGoMod = files.includes("go.mod"); const hasCargo = files.includes("Cargo.toml"); + const hasCsproj = files.some(f => f.endsWith(".csproj") || f.endsWith(".sln")); + const hasPomXml = files.includes("pom.xml"); + const hasBuildGradle = files.includes("build.gradle") || files.includes("build.gradle.kts"); + const hasGemfile = files.includes("Gemfile"); + const hasComposerJson = files.includes("composer.json"); if (hasPackageJson) analysis.languages.push("JavaScript"); if (hasTsConfig) analysis.languages.push("TypeScript"); if (hasPyProject || hasRequirements) analysis.languages.push("Python"); if (hasGoMod) analysis.languages.push("Go"); if (hasCargo) analysis.languages.push("Rust"); + if (hasCsproj) analysis.languages.push("C#"); + if (hasPomXml || hasBuildGradle) analysis.languages.push("Java"); + if (hasGemfile) analysis.languages.push("Ruby"); + if (hasComposerJson) analysis.languages.push("PHP"); analysis.packageManager = await detectPackageManager(repoPath, files); @@ -88,6 +97,10 @@ async function detectPackageManager(repoPath: string, files: string[]): Promise< if (files.includes("package.json")) return "npm"; if (files.includes("pyproject.toml")) return "pip"; + if (files.includes("pom.xml")) return "maven"; + if (files.includes("build.gradle") || files.includes("build.gradle.kts")) return "gradle"; + if (files.includes("Gemfile")) return "bundler"; + if (files.includes("composer.json")) return "composer"; return undefined; } @@ -161,17 +174,30 @@ async function readPnpmWorkspace(filePath: string): Promise { const patterns: string[] = []; let inPackages = false; for (const line of lines) { + // Skip comment-only lines + if (/^\s*#/u.test(line)) continue; if (!inPackages && /^\s*packages\s*:/u.test(line)) { + // Handle inline array: packages: ["apps/*", "libs/*"] + const inline = line.match(/packages\s*:\s*\[([^\]]+)\]/u); + if (inline) { + const items = inline[1].split(",").map(s => + s.trim().replace(/^['"]|['"]$/gu, "") + ); + return items.filter(Boolean); + } inPackages = true; continue; } if (inPackages) { const match = line.match(/^\s*-\s*(.+)$/u); if (match?.[1]) { - patterns.push(match[1].trim().replace(/^['"]|['"]$/gu, "")); + // Strip trailing comments and quotes + const value = match[1].split("#")[0].trim().replace(/^['"]|['"]$/gu, ""); + if (value) patterns.push(value); continue; } - if (/^\S/u.test(line)) break; + // Non-indented, non-empty line means a new top-level key + if (/^\S/u.test(line) && line.trim()) break; } } return patterns; diff --git a/src/services/azureDevops.ts b/src/services/azureDevops.ts index bebe975..0600098 100644 --- a/src/services/azureDevops.ts +++ b/src/services/azureDevops.ts @@ -60,6 +60,15 @@ export type AzureDevOpsRepo = { const PROFILE_URL = "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=7.1-preview.1"; +const ADO_SLUG_RE = /^[\w][\w.-]*$/u; + +function validateAdoSlug(value: string, label: string): string { + if (!ADO_SLUG_RE.test(value)) { + throw new Error(`Invalid ${label}: ${value}`); + } + return encodeURIComponent(value); +} + function getAuthHeader(token: string): string { const encoded = Buffer.from(`:${token}`).toString("base64"); return `Basic ${encoded}`; @@ -100,7 +109,8 @@ export async function listOrganizations(token: string): Promise { - const url = `https://dev.azure.com/${organization}/_apis/projects?stateFilter=wellFormed&api-version=7.1-preview.1`; + const org = validateAdoSlug(organization, "organization"); + const url = `https://dev.azure.com/${org}/_apis/projects?stateFilter=wellFormed&api-version=7.1-preview.1`; const response = await adoRequest>(url, token); return response.value.map((project) => ({ @@ -112,7 +122,9 @@ export async function listProjects(token: string, organization: string): Promise } export async function listRepos(token: string, organization: string, project: string): Promise { - const url = `https://dev.azure.com/${organization}/${project}/_apis/git/repositories?api-version=7.1-preview.1`; + const org = validateAdoSlug(organization, "organization"); + const proj = validateAdoSlug(project, "project"); + const url = `https://dev.azure.com/${org}/${proj}/_apis/git/repositories?api-version=7.1-preview.1`; const response = await adoRequest>(url, token); return response.value.map((repo) => ({ @@ -134,7 +146,10 @@ export async function getRepo( project: string, repo: string ): Promise { - const url = `https://dev.azure.com/${organization}/${project}/_apis/git/repositories/${repo}?api-version=7.1-preview.1`; + const org = validateAdoSlug(organization, "organization"); + const proj = validateAdoSlug(project, "project"); + const r = validateAdoSlug(repo, "repo"); + const url = `https://dev.azure.com/${org}/${proj}/_apis/git/repositories/${r}?api-version=7.1-preview.1`; const response = await adoRequest(url, token); return { @@ -166,7 +181,9 @@ export async function createPullRequest(params: { sourceBranch: string; targetBranch: string; }): Promise { - const url = `https://dev.azure.com/${params.organization}/${params.project}/_apis/git/repositories/${params.repoId}/pullrequests?api-version=7.1-preview.1`; + const org = validateAdoSlug(params.organization, "organization"); + const proj = validateAdoSlug(params.project, "project"); + const url = `https://dev.azure.com/${org}/${proj}/_apis/git/repositories/${encodeURIComponent(params.repoId)}/pullrequests?api-version=7.1-preview.1`; const payload = { title: params.title, description: params.body, @@ -179,7 +196,7 @@ export async function createPullRequest(params: { body: JSON.stringify(payload) }); - return `https://dev.azure.com/${params.organization}/${params.project}/_git/${encodeURIComponent( + return `https://dev.azure.com/${org}/${proj}/_git/${encodeURIComponent( params.repoName )}/pullrequest/${response.pullRequestId}`; } @@ -190,7 +207,9 @@ export async function checkRepoHasInstructions( project: string, repoId: string ): Promise { - const url = `https://dev.azure.com/${organization}/${project}/_apis/git/repositories/${repoId}/items?path=/.github/copilot-instructions.md&includeContentMetadata=true&api-version=7.1-preview.1`; + const org = validateAdoSlug(organization, "organization"); + const proj = validateAdoSlug(project, "project"); + const url = `https://dev.azure.com/${org}/${proj}/_apis/git/repositories/${encodeURIComponent(repoId)}/items?path=/.github/copilot-instructions.md&includeContentMetadata=true&api-version=7.1-preview.1`; const response = await fetch(url, { headers: { Authorization: getAuthHeader(token) @@ -201,7 +220,11 @@ export async function checkRepoHasInstructions( return false; } - return response.ok; + if (!response.ok) { + throw new Error(`Azure DevOps request failed (${response.status})`); + } + + return true; } export async function checkReposForInstructions( diff --git a/src/services/copilot.ts b/src/services/copilot.ts index 38af3eb..903c762 100644 --- a/src/services/copilot.ts +++ b/src/services/copilot.ts @@ -1,9 +1,12 @@ import fs from "fs/promises"; +import fg from "fast-glob"; import { execFile } from "node:child_process"; import { promisify } from "node:util"; const execFileAsync = promisify(execFile); +let cachedCliPath: string | null = null; + export async function assertCopilotCliReady(): Promise { const cliPath = await findCopilotCliPath(); @@ -23,31 +26,74 @@ export async function listCopilotModels(): Promise { } async function findCopilotCliPath(): Promise { + if (cachedCliPath) return cachedCliPath; + + // Try PATH lookup first (works on all platforms) + const whichCmd = process.platform === "win32" ? "where" : "which"; try { - const { stdout } = await execFileAsync("which", ["copilot"], { timeout: 5000 }); - return stdout.trim(); + const { stdout } = await execFileAsync(whichCmd, ["copilot"], { timeout: 5000 }); + const found = stdout.trim().split(/\r?\n/)[0]; + if (found) { + cachedCliPath = found; + return found; + } } catch { - // Ignore - will try VS Code location + // Ignore - will try VS Code locations } - const home = process.env.HOME ?? ""; - const vscodeLocations = [ - `${home}/Library/Application Support/Code - Insiders/User/globalStorage/github.copilot-chat/copilotCli/copilot`, - `${home}/Library/Application Support/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot`, - `${home}/.vscode-insiders/extensions/github.copilot-chat-*/copilotCli/copilot`, - `${home}/.vscode/extensions/github.copilot-chat-*/copilotCli/copilot` - ]; + const home = process.env.HOME ?? process.env.USERPROFILE ?? ""; + const staticLocations: string[] = []; + + if (process.platform === "darwin") { + staticLocations.push( + `${home}/Library/Application Support/Code - Insiders/User/globalStorage/github.copilot-chat/copilotCli/copilot`, + `${home}/Library/Application Support/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot` + ); + } else if (process.platform === "linux") { + staticLocations.push( + `${home}/.config/Code - Insiders/User/globalStorage/github.copilot-chat/copilotCli/copilot`, + `${home}/.config/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot` + ); + } else if (process.platform === "win32") { + const appData = process.env.APPDATA ?? ""; + if (appData) { + staticLocations.push( + `${appData}\\Code - Insiders\\User\\globalStorage\\github.copilot-chat\\copilotCli\\copilot.exe`, + `${appData}\\Code\\User\\globalStorage\\github.copilot-chat\\copilotCli\\copilot.exe` + ); + } + } - for (const location of vscodeLocations) { + for (const location of staticLocations) { try { await fs.access(location); + cachedCliPath = location; return location; } catch { // Try next location } } - throw new Error("Copilot CLI not found. Install GitHub Copilot Chat extension in VS Code."); + const globPatterns = [ + `${home}/.vscode-insiders/extensions/github.copilot-chat-*/copilotCli/copilot`, + `${home}/.vscode/extensions/github.copilot-chat-*/copilotCli/copilot` + ]; + + for (const pattern of globPatterns) { + const matches = await fg(pattern, { onlyFiles: true }); + if (matches.length > 0) { + cachedCliPath = matches[0]; + return matches[0]; + } + } + + const platformHint = process.platform === "win32" + ? " Searched APPDATA and VS Code extension paths." + : process.platform === "linux" + ? " Searched ~/.config/Code and VS Code extension paths." + : " Searched ~/Library/Application Support/Code and VS Code extension paths."; + + throw new Error(`Copilot CLI not found. Install GitHub Copilot Chat extension in VS Code.${platformHint}`); } function extractModelChoices(helpText: string): string[] { diff --git a/src/services/evalScaffold.ts b/src/services/evalScaffold.ts index aa1f9a7..d9fde55 100644 --- a/src/services/evalScaffold.ts +++ b/src/services/evalScaffold.ts @@ -1,9 +1,9 @@ -import process from "node:process"; - import { assertCopilotCliReady } from "./copilot"; +import { DEFAULT_MODEL } from "../config"; +import { withCwd } from "../utils/cwd"; export type EvalCase = { - id: string; + id?: string; prompt: string; expectation: string; }; @@ -13,6 +13,9 @@ export type EvalConfig = { cases: EvalCase[]; systemMessage?: string; outputPath?: string; + ui?: { + modelPicker?: "visible" | "hidden"; + }; }; type EvalScaffoldOptions = { @@ -28,69 +31,67 @@ export async function generateEvalScaffold(options: EvalScaffoldOptions): Promis const count = Math.max(1, options.count); const progress = options.onProgress ?? (() => {}); - const originalCwd = process.cwd(); - process.chdir(repoPath); - - progress("Checking Copilot CLI..."); - const cliPath = await assertCopilotCliReady(); - - progress("Starting Copilot SDK..."); - const sdk = await import("@github/copilot-sdk"); - const client = new sdk.CopilotClient({ cliPath }); - - try { - progress("Creating session..."); - const preferredModel = options.model ?? "gpt-4.1"; - const session = await client.createSession({ - model: preferredModel, - streaming: true, - systemMessage: { - content: - "You are an expert codebase analyst. Generate developer-oriented eval cases for this repository. Use tools (glob, view, grep) to inspect the codebase. Output ONLY JSON with keys: instructionFile, cases (array of {id,prompt,expectation})." - }, - infiniteSessions: { enabled: false } - }); - - let content = ""; - session.on((event: { type: string; data?: Record }) => { - if (event.type === "assistant.message_delta") { - const delta = event.data?.deltaContent as string | undefined; - if (delta) { - content += delta; - progress("Generating eval cases..."); - } - } else if (event.type === "tool.execution_start") { - const toolName = event.data?.toolName as string | undefined; - progress(`Using tool: ${toolName ?? "..."}`); - } else if (event.type === "session.error") { - const errorMsg = (event.data?.message as string) ?? "Unknown error"; - if (errorMsg.toLowerCase().includes("auth") || errorMsg.toLowerCase().includes("login")) { - throw new Error("Copilot CLI not logged in. Run `copilot` then `/login` to authenticate."); + return withCwd(repoPath, async () => { + progress("Checking Copilot CLI..."); + const cliPath = await assertCopilotCliReady(); + + progress("Starting Copilot SDK..."); + const sdk = await import("@github/copilot-sdk"); + const client = new sdk.CopilotClient({ cliPath }); + + try { + progress("Creating session..."); + const preferredModel = options.model ?? DEFAULT_MODEL; + const session = await client.createSession({ + model: preferredModel, + streaming: true, + systemMessage: { + content: + "You are an expert codebase analyst. Generate developer-oriented eval cases for this repository. Use tools (glob, view, grep) to inspect the codebase. Output ONLY JSON with keys: instructionFile, cases (array of {id,prompt,expectation})." + }, + infiniteSessions: { enabled: false } + }); + + let content = ""; + session.on((event: { type: string; data?: Record }) => { + if (event.type === "assistant.message_delta") { + const delta = event.data?.deltaContent as string | undefined; + if (delta) { + content += delta; + progress("Generating eval cases..."); + } + } else if (event.type === "tool.execution_start") { + const toolName = event.data?.toolName as string | undefined; + progress(`Using tool: ${toolName ?? "..."}`); + } else if (event.type === "session.error") { + const errorMsg = (event.data?.message as string) ?? "Unknown error"; + if (errorMsg.toLowerCase().includes("auth") || errorMsg.toLowerCase().includes("login")) { + throw new Error("Copilot CLI not logged in. Run `copilot` then `/login` to authenticate."); + } } - } - }); - - const prompt = [ - `Analyze the repository at ${repoPath} and generate ${count} eval cases.`, - "The cases should mirror realistic developer questions about this repo.", - "Use tools to inspect README, package.json, CLI commands, and key files.", - "Ensure cases cover a range of topics: purpose, entrypoints, build/test, configuration, workflows.", - "Include a systemMessage that keeps answers scoped to this repository (avoid generic Copilot CLI details unless asked).", - "Return JSON ONLY (no markdown, no commentary) in this schema:", - "{\n \"instructionFile\": \".github/copilot-instructions.md\",\n \"systemMessage\": \"...\",\n \"cases\": [\n {\"id\": \"case-1\", \"prompt\": \"...\", \"expectation\": \"...\"}\n ]\n}" - ].join("\n"); - - progress("Analyzing codebase..."); - await session.sendAndWait({ prompt }, 180000); - await session.destroy(); - - const parsed = parseEvalConfig(content); - const normalized = normalizeEvalConfig(parsed, count); - return normalized; - } finally { - await client.stop(); - process.chdir(originalCwd); - } + }); + + const prompt = [ + `Analyze the repository at ${repoPath} and generate ${count} eval cases.`, + "The cases should mirror realistic developer questions about this repo.", + "Use tools to inspect README, package.json, CLI commands, and key files.", + "Ensure cases cover a range of topics: purpose, entrypoints, build/test, configuration, workflows.", + "Include a systemMessage that keeps answers scoped to this repository (avoid generic Copilot CLI details unless asked).", + "Return JSON ONLY (no markdown, no commentary) in this schema:", + "{\n \"instructionFile\": \".github/copilot-instructions.md\",\n \"systemMessage\": \"...\",\n \"cases\": [\n {\"id\": \"case-1\", \"prompt\": \"...\", \"expectation\": \"...\"}\n ]\n}" + ].join("\n"); + + progress("Analyzing codebase..."); + await session.sendAndWait({ prompt }, 180000); + await session.destroy(); + + const parsed = parseEvalConfig(content); + const normalized = normalizeEvalConfig(parsed, count); + return normalized; + } finally { + await client.stop(); + } + }); } function parseEvalConfig(raw: string): EvalConfig { diff --git a/src/services/evaluator.ts b/src/services/evaluator.ts index 1a137cd..a4d5271 100644 --- a/src/services/evaluator.ts +++ b/src/services/evaluator.ts @@ -2,22 +2,12 @@ import fs from "fs/promises"; import path from "path"; import { execFile } from "node:child_process"; import { promisify } from "node:util"; +import { assertCopilotCliReady } from "./copilot"; +import { buildTimestampedName } from "../utils/fs"; +import type { EvalCase, EvalConfig } from "./evalScaffold"; const execFileAsync = promisify(execFile); -type EvalCase = { - prompt: string; - expectation: string; - id?: string; -}; - -type EvalConfig = { - instructionFile?: string; - cases: EvalCase[]; - systemMessage?: string; - outputPath?: string; -}; - const DEFAULT_SYSTEM_MESSAGE = "You are answering questions about this repository. Use tools to inspect the repo and cite its files. Avoid generic Copilot CLI details unless the prompt explicitly asks for them."; @@ -94,7 +84,7 @@ export async function runEval(options: EvalRunOptions): Promise<{ summary: strin const runStartedAt = Date.now(); progress("Starting Copilot SDK..."); - const cliPath = await findCopilotCliPath(); + const cliPath = await assertCopilotCliReady(); const sdk = await import("@github/copilot-sdk"); const client = new sdk.CopilotClient({ cliPath }); @@ -328,37 +318,11 @@ function parseJudge(content: string): JudgeResult { async function loadConfig(configPath: string): Promise { const raw = await fs.readFile(configPath, "utf8"); - return JSON.parse(raw) as EvalConfig; -} - -async function findCopilotCliPath(): Promise { - // Try standard PATH first - try { - const { stdout } = await execFileAsync("which", ["copilot"], { timeout: 5000 }); - return stdout.trim(); - } catch { - // Ignore - will try VS Code location - } - - // VS Code Copilot Chat extension location - const home = process.env.HOME ?? ""; - const vscodeLocations = [ - `${home}/Library/Application Support/Code - Insiders/User/globalStorage/github.copilot-chat/copilotCli/copilot`, - `${home}/Library/Application Support/Code/User/globalStorage/github.copilot-chat/copilotCli/copilot`, - `${home}/.vscode-insiders/extensions/github.copilot-chat-*/copilotCli/copilot`, - `${home}/.vscode/extensions/github.copilot-chat-*/copilotCli/copilot`, - ]; - - for (const location of vscodeLocations) { - try { - await fs.access(location); - return location; - } catch { - // Try next location - } + const parsed = JSON.parse(raw) as EvalConfig; + if (!parsed || !Array.isArray(parsed.cases)) { + throw new Error("Eval config must have a 'cases' array."); } - - throw new Error("Copilot CLI not found. Install GitHub Copilot Chat extension in VS Code."); + return parsed; } async function readOptionalFile(filePath: string): Promise { @@ -563,6 +527,8 @@ function getNumber(value: unknown): number | null { return null; } +// The SDK reports cumulative token counts per session, so we keep the peak (max) value +// rather than summing incremental deltas. function mergeTokenUsage(existing: TokenUsage, next: TokenUsage): TokenUsage { return { promptTokens: Math.max(existing.promptTokens ?? 0, next.promptTokens ?? 0) || undefined, @@ -622,11 +588,6 @@ function resolveOutputPath(repoPath: string, override?: string, configValue?: st return path.isAbsolute(chosen) ? chosen : path.resolve(repoPath, chosen); } -function buildTimestampedName(baseName: string): string { - const stamp = new Date().toISOString().replace(/[:.]/gu, "-"); - return `${baseName}-${stamp}.json`; -} - function buildViewerPath(outputPath: string): string { if (outputPath.endsWith(".json")) { return outputPath.replace(/\.json$/u, ".html"); @@ -766,7 +727,7 @@ function buildTrajectoryViewerHtml(data: Record): string {