@vpxa/aikit 0.1.112 → 0.1.114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/package.json +1 -1
- package/packages/cli/dist/index.js +2 -2
- package/packages/cli/dist/{init-BfmAvMGq.js → init-C4Rr0k00.js} +1 -1
- package/packages/cli/dist/{templates-BRWMrqFI.js → templates-DRfiihP4.js} +3 -3
- package/packages/cli/dist/{user-D4p6n-Q5.js → user-HCdUUwXe.js} +1 -1
- package/packages/indexer/dist/index.js +1 -1
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{server-BzPxuGzZ.js → server-qD-mw6RP.js} +1 -1
- package/packages/store/dist/index.d.ts +19 -0
- package/packages/store/dist/index.js +2 -2
- package/packages/store/dist/{sqlite-vec-store-DQE-A0rY.js → sqlite-vec-store-DuGaWATy.js} +2 -2
- package/scaffold/dist/definitions/bodies.mjs +5 -2
- package/scaffold/dist/definitions/plugins.mjs +1 -1
- package/scaffold/dist/definitions/skills.mjs +446 -8
|
@@ -1704,7 +1704,7 @@ Notes:
|
|
|
1704
1704
|
- Scripts auto-detect ADR directory and filename strategy.
|
|
1705
1705
|
- Use \`--dir\` and \`--strategy\` to override.
|
|
1706
1706
|
- Use \`--json\` to emit machine-readable output.
|
|
1707
|
-
`}],aikit:[{file:`SKILL.md`,content:'---\nname: aikit\ndescription: "Use the @vpxa/aikit AI Kit MCP server for codebase search, analysis, and persistent memory. Load this skill when using aikit_search, aikit_analyze, aikit_knowledge, or any aikit_* tool. Covers all 61 MCP tools: search (hybrid/semantic/keyword), code analysis (analyze aspects for structure, dependencies, symbols, patterns, entry points, diagrams, plus blast radius), knowledge graph (auto-populated module/symbol/import graph with traversal), context management (worksets, stash, checkpoints, restore, lanes), code manipulation (rename, codemod, eval), execution and validation (check, test_run, audit), knowledge management (knowledge actions: remember/read/update/forget/list), web access (fetch, search, http), FORGE protocol (ground, classify, evidence map, stratum cards, digest), flow management (list, start, navigate steps, read instructions, inspect runs, add/remove/update flows), presentation (rich dashboards via present tool), onboarding (full codebase analysis in one call), meta-tools (tool discovery and descriptions), and developer utilities (regex, encode, measure, changelog, schema-validate, env, time)."\nmetadata:\n category: cross-cutting\n domain: general\n applicability: always\n inputs: [codebase]\n outputs: [search-results, analysis, knowledge]\n relatedSkills: [present]\n---\n\n# @vpxa/aikit — AI Kit\n\nLocal-first AI developer toolkit — 61 MCP tools for search, analysis, context compression, FORGE quality gates, knowledge management, code manipulation, execution, web access, flow management, presentation, meta-tool discovery, and developer utilities.\n\n## When to Use\n\n- You need long-term memory across coding sessions\n- You want to search a codebase semantically (by meaning, not just keywords)\n- You need to compress large contexts to focus on what matters\n- You want structured output from build tools (tsc, vitest, biome, git)\n- You need to plan which files to read for a task\n- You want to safely explore refactors in isolated lanes\n- You need to rename symbols, apply codemods, or run code transformations\n- You want to fetch and read web pages or search the web\n- You need to make HTTP requests, test APIs, or debug endpoints\n- You want to test regex patterns, encode/decode data, or validate JSON schemas\n- You need code complexity metrics or a git changelog\n\n## Skills Reference\n\n| Context | Skill | Load when |\n|---------|-------|----------|\n| Repository access recovery | `repo-access` | When encountering git auth failures, accessing private/enterprise repos, or when `web_fetch`/`http` returns auth errors on repository URLs. |\n\n## Architecture\n\n10-package monorepo published as a single npm package:\n\n```\ncore → store → embeddings → chunker → indexer → analyzers → tools → server → cli → tui\n```\n\n- **MCP server**: 61 tools + 2 resources (via `@modelcontextprotocol/sdk`)\n- **CLI**: 45 commands (thin dispatcher + 10 command groups)\n- **Search**: Hybrid vector + keyword + RRF fusion\n- **Embeddings**: ONNX local (mxbai-embed-large-v1, 1024 dimensions)\n- **Vector store**: LanceDB (embedded, zero infrastructure)\n- **Chunking**: Tree-sitter AST (TS/JS/Python/Go/Rust/Java) + regex fallback\n- **TUI**: Ink/React dashboard for human monitoring (search, status, curated, activity log)\n\n## Session Protocol (MANDATORY)\n\n### Start (do ALL)\n```\nflow({ action: \'status\' }) # Check/resume active flow FIRST\n# If flow active → flow({ action: \'read\', step }) → follow step instructions\nstatus({}) # Check AI Kit health + onboard state\n# If onboard not run → onboard({ path: "." }) # First-time codebase analysis\nflow({ action: \'list\' }) # See available flows\n# Select flow based on task → flow({ action: \'start\', name: "<name>", topic: "<task>" }) # Start — creates .flows/{topic}/\nknowledge({ action: "list" }) # See stored knowledge\nsearch({ query: "SESSION CHECKPOINT", origin: "curated" }) # Resume prior work\n```\n\n### During Session\n```\nsearch → scope_map → symbol → trace (orient)\ncheck → test_run (validate changes)\nknowledge({ action: "remember", ... }) (capture insights)\n```\n\n### End of Session\n```\nsession_digest({ persist: true }) # Auto-capture session activity\nknowledge({ action: "remember", title: "Session checkpoint: <topic>", content: "<what was done, decisions made, next steps>", category: "conventions" })\n```\n\n## Tool Catalog\n\n### Search & Discovery (8)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `search` | `aikit search` | Hybrid/semantic/keyword search with `search_mode` param |\n| `find` | `aikit find` | Federated search: vector + FTS + glob + regex in one call. Use `mode: \'examples\'` to find usage examples. |\n| `symbol` | `aikit symbol` | Resolve symbol definition, imports, and references |\n| `lookup` | `aikit lookup` | Full-file retrieval by path or record ID |\n| `scope_map` | `aikit scope-map` | Task-scoped reading plan with token estimates |\n| `trace` | `aikit trace` | Forward/backward flow tracing through call chains |\n| `dead_symbols` | `aikit dead-symbols` | Find exported symbols never imported — separates source (actionable) from docs (informational). Accepts `path` to scope the search. |\n| `file_summary` | `aikit summarize` | Structural overview of a file (exports, imports, functions) |\n\n### Code Analysis (2)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `analyze` | `aikit analyze <aspect>` | Unified analyzer for structure, dependencies, symbols, patterns, entry_points, and diagram aspects |\n| `blast_radius` | `aikit analyze blast-radius` | Change impact analysis |\n\n### Context Management (6)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `compact` | `aikit compact` | Compress text to relevant sections using embeddings (no LLM). Accepts `path` for server-side file read. |\n| `workset` | `aikit workset` | Named file set management (save/load/add/remove) |\n| `stash` | `aikit stash` | Named key-value store for session data |\n| `checkpoint` | `aikit checkpoint` | Save/restore session checkpoints |\n| `restore` | `aikit restore` | Restore a previously saved checkpoint |\n| `parse_output` | `aikit parse-output` | Parse tsc/vitest/biome/git output → structured JSON |\n\n### Code Manipulation (4)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `rename` | `aikit rename` | Smart whole-word symbol rename across files (dry-run supported) |\n| `codemod` | `aikit codemod` | Regex-based code transformations with rules (dry-run supported) |\n| `diff_parse` | `aikit diff` | Parse unified diff → structured changes |\n| `data_transform` | `aikit transform` | JQ-like JSON transformations |\n\n### Execution & Validation (4)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `eval` | `aikit eval` | Sandboxed JavaScript/TypeScript execution |\n| `check` | `aikit check` | Incremental typecheck + lint. `detail` param: efficient (default, minimal), normal (parsed errors), full (includes raw) |\n| `test_run` | `aikit test` | Run tests with structured pass/fail results |\n| `audit` | `aikit audit` | Unified project audit: structure, deps, patterns, health, dead symbols, check, entry points → synthesized report with score and recommendations. 6 round-trips → 1. |\n\n### Knowledge Management (2)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `knowledge` | `aikit knowledge <action>` | Unified knowledge tool for remember, read, update, forget, and list actions |\n| `produce_knowledge` | — | Auto-generate knowledge from analysis |\n\n### Auto-Knowledge (automatic)\n\nTool outputs are automatically analyzed after every call. Useful facts (conventions, test patterns, build commands, errors) are extracted and stored as curated entries. Quality gate (score >= 0.3), deduplication, TTL for transient facts, max 50/session.\n\nSearch auto-knowledge with: `search({ query: "...", origin: "curated" })` or `knowledge({ action: "list", category: "conventions" })`\n\n### Verified Lanes (1 tool, 6 actions)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `lane` | `aikit lane` | Manage isolated file copies for parallel exploration |\n\nLane actions: `create` (copy files to lane), `list`, `status` (modified/added/deleted), `diff` (line-level diff), `merge` (apply back to originals), `discard`.\n\n### Git & Environment (4)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `git_context` | `aikit git` | Branch, status, recent commits |\n| `process` | `aikit proc` | Process supervisor (start/stop/logs) |\n| `watch` | `aikit watch` | Filesystem watcher |\n| `delegate` | `aikit delegate` | Delegate subtask to local Ollama model |\n\n### Web & Network (3)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `web_fetch` | — | Fetch web page → markdown/raw/links/outline for LLM consumption |\n| `web_search` | — | Multi-provider web search (DuckDuckGo + Bing-HTML + Mojeek fan-out, no API key needed) |\n| `http` | — | Make HTTP requests for API testing/debugging |\n\n### Developer Utilities (7)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `regex_test` | — | Test regex patterns with match/replace/split modes |\n| `encode` | — | Base64, URL, SHA-256, MD5, hex encode/decode, JWT decode |\n| `measure` | — | Code complexity metrics (cyclomatic, cognitive complexity, lines, functions) |\n| `changelog` | — | Generate changelog from git history (conventional commits) |\n| `schema_validate` | — | Validate JSON data against JSON Schema |\n| `env` | — | System and runtime environment info (sensitive values redacted) |\n| `time` | — | Date parsing, timezone conversion, duration math |\n\n### FORGE Quality Gates (5)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `forge_ground` | — | Full Ground phase: classify tier, scope map, unknowns, constraints |\n| `forge_classify` | — | Quick tier classification (Floor/Standard/Critical) |\n| `evidence_map` | — | CRUD + Gate evaluation for verified/assumed/unknown claims. Safety gate tags (`provenance`/`commitment`/`coverage`) enable mandatory pre-YIELD checks |\n| `stratum_card` | — | Generate T1/T2 compressed context cards from files (10-100x token reduction) |\n| `digest` | — | Compress N text sources into token-budgeted summary |\n\n### System (9)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `config` | `aikit config` | View or update project configuration (kb.config.json) |\n| `status` | `aikit status` | Index statistics |\n| `reindex` | `aikit reindex` | Rebuild index |\n| `health` | `aikit health` | Project health checks (package.json, tsconfig, lockfile, circular deps) |\n| `guide` | `aikit guide` | Tool discovery — given a goal, recommends tools and workflow order |\n| `onboard` | `aikit onboard` | Full codebase onboarding in one call (structure + deps + patterns + knowledge) |\n| `graph` | `aikit graph` | Query the auto-populated knowledge graph (modules, symbols, imports) |\n| `queue` | `aikit queue` | Task queue for sequential agent operations (create/push/next/done/fail) |\n| `replay` | `aikit replay` | View or clear the audit trail of tool invocations (action: list/clear) |\n\n### Flows (1)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `flow` | `aikit flow` | Manage flows — list, start, navigate steps, read instructions, inspect runs, add/remove/update. |\n\n### Presentation (1)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `present` | — | Rich dashboards, charts, tables, timelines. Use `format: "browser"` then `openBrowserPage` to display. **In CLI mode (no VS Code chat), always use `format: "browser"`** — `html` UIResource is invisible in terminal. |\n\n### Meta-Tools — Tool Discovery (3)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `list_tools` | — | List all active AI Kit tools with names, titles, and categories. Accepts optional `category` filter. Use for initial tool discovery. |\n| `describe_tool` | — | Get detailed metadata for a specific tool (title, categories, annotations). Use after `list_tools` to understand a tool before calling it. |\n| `search_tools` | — | Search active tools by keyword across names, titles, and categories. Use when you know what you need but not the tool name. |\n\n### Session Management (1)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `session_digest` | — | Generate a compressed digest of session activity (replay log, stash, checkpoints). Options: `scope` (tools/stash/all), `since`, `last`, `focus`, `mode` (deterministic/sampling), `tokenBudget`, `persist`. Use at session end for handoff or mid-session to review what happened. |\n\n## Execution & Data Tools\n\n### `eval` — Execute Code in Sandbox\n\nRun JavaScript or TypeScript snippets in a constrained VM. Captures console output and return values.\n\n**Parameters:**\n| Param | Type | Default | Description |\n|-------|------|---------|-------------|\n| `code` | string | — | Code to execute |\n| `lang` | `"js"` \\| `"ts"` | `"js"` | Language mode (ts strips type syntax first) |\n| `timeout` | number | 5000 | Execution timeout in ms (max 60000) |\n\n**Examples:**\n```\n// Quick calculation\neval({ code: "return [1,2,3].reduce((a,b) => a+b, 0)" })\n\n// Process data\neval({ code: "const data = [1,2,3,4,5]; return { sum: data.reduce((a,b)=>a+b), avg: data.reduce((a,b)=>a+b)/data.length }" })\n\n// TypeScript\neval({ code: "interface Point { x: number; y: number }; const p: Point = {x: 1, y: 2}; return p.x + p.y", lang: "ts" })\n```\n\n---\n\n### `data_transform` — jq-like JSON Transforms\n\nApply jq-inspired expressions to JSON input for filtering, projection, grouping, and extraction.\n\n**Parameters:**\n| Param | Type | Description |\n|-------|------|-------------|\n| `input` | string | JSON string to transform |\n| `expression` | string | Transform expression (see syntax below) |\n\n**Supported Expressions:**\n\n| Expression | Description | Example |\n|------------|-------------|---------|\n| `.` | Identity (return input as-is) | `.` |\n| `.field` | Access object field | `.name` |\n| `.[N]` | Array index access | `.[0]` |\n| `.field1.field2` | Nested field access | `.user.name` |\n| `| filter(condition)` | Filter array items | `| filter(.age > 18)` |\n| `| map(expr)` | Transform each item | `| map(.name)` |\n| `| sort_by(.field)` | Sort by field | `| sort_by(.date)` |\n| `| group_by(.field)` | Group items by field | `| group_by(.category)` |\n| `| select(cond)` | Keep items matching condition | `| select(.active == true)` |\n| `| flatten` | Flatten nested arrays | `| flatten` |\n| `| unique` | Remove duplicates | `| unique` |\n| `| keys` | Get object keys | `| keys` |\n| `| values` | Get object values | `| values` |\n| `| length` | Array/string length | `| length` |\n| `| join(sep)` | Join array with separator | `| join(", ")` |\n| `| first` | First element | `| first` |\n| `| last` | Last element | `| last` |\n| `| sum` | Sum numeric array | `| sum` |\n| `| avg` | Average of numeric array | `| avg` |\n| `| min` / `| max` | Min/max value | `| min` |\n\n**Comparisons:** `==`, `!=`, `>`, `<`, `>=`, `<=`\n**Logical:** `and`, `or`, `not`\n\n**Examples:**\n```\n// Filter and project\ndata_transform({ input: \'[{"name":"Alice","age":30},{"name":"Bob","age":17}]\', expression: \'| filter(.age >= 18) | map(.name)\' })\n// → ["Alice"]\n\n// Group and count\ndata_transform({ input: \'[{"type":"bug"},{"type":"feat"},{"type":"bug"}]\', expression: \'| group_by(.type)\' })\n// → {"bug":[...], "feat":[...]}\n\n// Sort and take first\ndata_transform({ input: \'[{"score":3},{"score":1},{"score":5}]\', expression: \'| sort_by(.score) | first\' })\n// → {"score":1}\n```\n\n---\n\n### `time` — Date & Time Operations\n\nParse dates, convert timezones, calculate durations, add time. Supports ISO 8601, unix timestamps, and human-readable formats.\n\n**Parameters:**\n| Param | Type | Description |\n|-------|------|-------------|\n| `operation` | string | `now`, `parse`, `convert`, `diff`, `add` |\n| `input` | string | Date input (ISO, unix, or parseable string). For `diff`: two comma-separated dates |\n| `timezone` | string | Target timezone (e.g., "America/New_York") |\n| `duration` | string | Duration to add (e.g., "2h30m", "1d", "30s") — for `add` |\n\n**Operations:**\n| Op | Purpose | Example |\n|----|---------|---------|\n| `now` | Current time in all formats | `time({ operation: "now" })` |\n| `parse` | Parse any date string | `time({ operation: "parse", input: "2024-03-15T10:30:00Z" })` |\n| `convert` | Convert to timezone | `time({ operation: "convert", input: "2024-03-15T10:30:00Z", timezone: "Asia/Tokyo" })` |\n| `diff` | Duration between dates | `time({ operation: "diff", input: "2024-01-01,2024-12-31" })` |\n| `add` | Add duration to date | `time({ operation: "add", input: "2024-03-15", duration: "2h30m" })` |\n\n**Duration format:** Combine: `Nd` (days), `Nh` (hours), `Nm` (minutes), `Ns` (seconds)\nExample: `"1d2h30m"` = 1 day, 2 hours, 30 minutes\n\n## Flow System\n\nFlows are multi-step guided workflows that structure complex tasks. Each step has a skill file with detailed instructions, required artifacts, and agent assignments.\n\n### Built-in Flows\n\n| Flow | Steps | Use When |\n|------|-------|----------|\n| `aikit:basic` | assess → implement → verify | Bug fixes, config changes, small features |\n| `aikit:advanced` | spec → plan → task → execute → verify | New modules, cross-service changes, architectural work |\n\n### Flow Lifecycle\n\n```text\nflow({ action: \'list\' }) # See available flows\nflow({ action: \'info\', name: \'aikit:basic\' }) # View steps, skills, agents\nflow({ action: \'start\', name: \'aikit:basic\', topic: \'Fix login bug\' }) # Start — creates .flows/fix-login-bug/\nflow({ action: \'read\' }) # Read current step\'s instructions ({{artifacts_path}} resolved)\n# ... do the work described in the instruction ...\nflow({ action: \'step\', advance: \'next\' }) # Advance to next step\nflow({ action: \'step\', advance: \'skip\' }) # Skip current step\nflow({ action: \'step\', advance: \'redo\' }) # Redo current step\nflow({ action: \'status\' }) # Check progress (includes slug, runDir, artifactsPath, phase, isEpilogue)\nflow({ action: \'reset\' }) # Abandon active flow\nflow({ action: \'runs\' }) # List all runs (current + past)\n# Epilogue steps (mandatory, injected after every flow):\n# After last flow step → _docs-sync epilogue runs automatically\n# flow({ action: \'status\' }) shows phase: \'after\', isEpilogue: true during epilogue\n```\n\nCustom flow lifecycle management:\n\n```text\nflow({ action: \'add\', source: \'.github/flows/my-flow\' })\nflow({ action: \'update\', name: \'my-flow\' })\nflow({ action: \'remove\', name: \'my-flow\' })\n```\n\n## CRITICAL: Use AI Kit Tools Instead of Native IDE Tools\n\nAI Kit tools provide **10x richer output** than native IDE tools — with AST-analyzed call graphs, scope context, import classification, and cognitive complexity. **You MUST use AI Kit tools instead of native read/search tools.**\n\n### ⛔ PROHIBITED: Native File Reading\n\n**`read_file` / `read_file_raw` MUST NOT be used to understand code.** They waste tokens and miss structural information.\n\nThe **ONLY** acceptable use of `read_file`: getting exact lines immediately before an edit (to verify the `old_str` for replacement). Even then, use `file_summary` first to identify which lines to read.\n\n### Tool Replacement Table\n\n| ❌ NEVER do this | ✅ Use AI Kit Tool | Why |\n|---|---|---|\n| `read_file` (full file) | `file_summary` | Exports, imports, call edges — **10x fewer tokens** |\n| `read_file` (specific section) | `compact({ path, query })` | Server-side read + extract — **5-20x reduction** |\n| `grep_search` / `textSearch` | `search` | Semantic + keyword hybrid across all indexed content |\n| `grep_search` for a symbol | `symbol` | Definition + references **with scope context** |\n| Multiple `read_file` calls | `digest` | Compresses multiple sources into token-budgeted summary |\n| `listDirectory` + `read_file` | `scope_map` | Identifies relevant files for a task automatically |\n| Manual code tracing | `trace` | AST call-graph traversal with scope context |\n| Line counting / `wc` | `measure` | Lines, complexity, **cognitive complexity**, functions |\n| Grep for unused exports | `dead_symbols` | AST-powered export detection with regex fallback |\n| Repeated file reads | `stratum_card` | Reusable compressed context — **10-100x reduction** |\n| `fetch_webpage` | `web_fetch` | Readability extract + token budget — richer output |\n| Web research / browsing | `web_search` | Multi-provider web search without browser — **unique to AI Kit** |\n\n### Decision Tree — How to Read Code\n\n```\nNeed to understand a file?\n├─ Just structure? → file_summary (exports, imports, call edges — ~50 tokens)\n├─ Specific section? → compact({ path, query }) — 5-20x reduction\n├─ Multiple files? → digest (multi-source compression — token-budgeted)\n├─ Repeated reference? → stratum_card (T1/T2 card — 10-100x reduction)\n├─ Need exact lines to EDIT? → read_file (the ONLY acceptable use)\n└─ "I want to read the whole file" → ⛔ STOP. Use file_summary or compact instead.\n```\n\n### Decision Tree — Need Structural Relationships?\n\nWhen vector search and file reads don\'t answer the question (e.g. "who imports this?",\n"what does this depend on?", "how are these files connected?"), use `graph`:\n\n```\nNeed to understand relationships between code?\n├─ Who imports / calls this? → graph({action:\'find_nodes\', name_pattern}) → graph({action:\'neighbors\', node_id, direction:\'incoming\'})\n├─ What does this depend on? → graph({action:\'neighbors\', node_id, direction:\'outgoing\'})\n├─ Full context for a symbol? → graph({action:\'symbol360\', name})\n├─ Related files within N hops? → graph({action:\'traverse\', node_id, max_depth:2})\n├─ Layer/module isolation check? → graph({action:\'depth_traverse\', node_id, max_depth:3})\n└─ Graph size/health? → graph({action:\'stats\'})\n```\n\n**Use this BEFORE** reaching for `analyze({ aspect: "dependencies", ... })` (slower, less precise) or manually\ntracing via `symbol` + `trace` chains. The graph is auto-populated during indexing.\n\n### What AI Kit Tools Return (AST-Enhanced)\n\nThese tools use Tree-sitter WASM to analyze source code at the AST level, providing structured data that raw file reads cannot:\n\n| Tool | Rich Output |\n|------|-------------|\n| `file_summary` | Imports classified as **external vs internal** (`isExternal` flag). **Call edges** between functions (e.g., `handleRequest() → validateInput() @ line 42`). `exported` flag on interfaces and types. Import count breakdown. |\n| `symbol` | References include **scope** — which function/class/method contains each usage (e.g., `referenced in processOrder() at auth-service.ts:55`). |\n| `trace` | **Call-graph edges** discovered via AST syntax tree, not text matching. Supports forward (who does X call?) and backward (who calls X?) tracing. Scope context on each node. |\n| `measure` | **Cognitive complexity** — weights nesting depth (nested `if` inside `for` inside `try` scores higher). More useful than cyclomatic complexity for understanding code difficulty. |\n| `dead_symbols` | **AST export enumeration** — catches `export default`, barrel re-exports (`export { x } from`), `export =`, and `export type`. Regex fallback for non-AST-supported languages. |\n\n### Example: `file_summary` Output\n\n```\nsrc/auth-service.ts\nLanguage: typescript | Lines: 180 | Estimated tokens: ~1400\n\nImports (6): 3 external, 3 internal\n - import { hash } from \'bcrypt\' [external]\n - import { UserRepo } from \'./user-repo\' [internal]\n\nFunctions (4):\n - authenticate @ line 22 [exported]\n - validateToken @ line 55 [exported]\n - hashPassword @ line 90\n - generateJwt @ line 110\n\nCall edges (12 intra-file):\n - authenticate() → hashPassword() @ line 35\n - authenticate() → generateJwt() @ line 42\n - validateToken() → UserRepo.findById() @ line 68\n\nInterfaces (2):\n - AuthResult @ line 8 [exported]\n - TokenPayload @ line 14\n```\n\nCompare: `read_file` would cost ~1400 tokens for raw text. `file_summary` gives structured data in ~120 tokens — **12x reduction** with richer information.\n\n## Token Efficiency\n\n`config.tokenBudget` controls output verbosity globally:\n\n| Level | Output | Compression | Context Strategy |\n|-------|--------|-------------|------------------|\n| `efficient` (default) | Minimal output, score + top issues only | threshold 2000, budget 1000 | `stratum_card(T1)` |\n| `normal` | Standard output with parsed errors/pattern names | threshold 4000, budget 2000 | `compact()` |\n| `full` | Maximum detail with raw output/full tables | No compression | `digest()` |\n\nSet via: `config({ action: \'update\', updates: { tokenBudget: \'normal\' } })`\n\nTools with `detail` param inherit from `config.tokenBudget` when not explicitly set.\nCompression middleware applies to ALL tool responses automatically.\n\n## Search Strategy\n\n1. **Start broad**: `search({ query: "topic", search_mode: "hybrid" })`\n2. **Narrow**: Add `content_type`, `origin`, or `category` filters\n3. **Exact match**: Use `search_mode: "keyword"` for identifiers\n4. **Federated**: Use `find` to combine vector + glob + regex\n\n## Workflow Chains\n\n### Codebase Onboarding\n```\nanalyze({ aspect: "structure", path: "src/" })\n→ analyze({ aspect: "dependencies", path: "src/" })\n→ analyze({ aspect: "entry_points", path: "src/" })\n→ produce_knowledge({ path: "src/" })\n→ knowledge({ action: "remember", title: "Codebase onboarding complete", ... })\n```\n\n### Planning a Task\n```\nscope_map({ task: "implement user auth" })\n→ compact({ path: "src/auth.ts", query: "auth flow" })\n→ workset({ action: "save", name: "auth-task", files: [...] })\n```\n\n### Bug Investigation\n```\nparse_output({ output: <error> }) → symbol({ name: "failingFn" })\n→ trace({ symbol: "failingFn", direction: "backward" })\n→ blast_radius({ changed_files: ["suspect.ts"] })\n→ eval({ code: "hypothesis test" }) → check({ files: ["suspect.ts"] })\n```\n\n### Multi-Task Orchestration (DAG Queue)\n```\nqueue({ action: "create", name: "my-tasks" })\n→ queue({ action: "push", name: "my-tasks", title: "Task 1", data: { deps: [] } })\n→ queue({ action: "push", name: "my-tasks", title: "Task 2", data: { deps: ["task-1-id"] } })\n→ queue({ action: "next", name: "my-tasks" }) # Gets next ready task\n→ [do work]\n→ queue({ action: "done", name: "my-tasks", id: "<id>" })\n```\n\n### Safe Refactor with Lanes\n```\nscope_map({ task: "rename UserService" })\n→ lane({ action: "create", name: "refactor", files: [...] })\n→ [make changes in lane files]\n→ lane({ action: "diff", name: "refactor" })\n→ check({}) → test_run({})\n→ lane({ action: "merge", name: "refactor" })\n```\n\n### Lane — isolated read-only exploration\n\n`lane({ action:\'create\', name })` creates an isolated copy of the workspace. Use to try approach A vs B WITHOUT touching canonical source. Other actions: `list`, `diff`, `delete`. Compare with `lane({ action:\'diff\', names:[\'a\',\'b\'] })`. Do NOT use `lane` for actual refactors — use `checkpoint` instead (`checkpoint` = reversible on canonical source; `lane` = isolated copies for comparison).\n\n### After Making Changes\n```\nblast_radius({ changed_files: ["src/auth.ts"] })\n→ check({}) → test_run({ grep: "auth" })\n→ reindex()\n→ knowledge({ action: "remember", title: "Implemented auth", content: "..." })\n```\n\n### Pre-Commit Validation\n```\ngit_context({ diff: true })\n→ diff_parse({ diff: <staged diff> })\n→ blast_radius({ changed_files: [...] })\n→ check({}) → test_run({})\n```\n\n---\n\n## Persistent Memory\n\n| Action | Tool | Category |\n|--------|------|----------|\n| Store | `knowledge({ action: "remember", title, content, category })` | conventions, decisions, patterns, context, session |\n| Search | `search({ query, origin: "curated" })` | — |\n| Browse | `knowledge({ action: "list" })` or `knowledge({ action: "list", category })` | — |\n| Read | `knowledge({ action: "read", id })` | — |\n| Update | `knowledge({ action: "update", id, content })` | — |\n| Remove | `knowledge({ action: "forget", id })` | — |\n\n**Session checkpoint** (end of session): `knowledge({ action: "remember", title: "Session checkpoint: <topic>", content: "Done/Decisions/Next/Blockers", category: "session" })`\n\n## CLI Quick Reference\n\n```bash\naikit init # Scaffold AI Kit in current directory\naikit init --force # Overwrite all scaffold/skill files\naikit init --guide # JSON report of stale files for LLM-driven updates\naikit serve # Start MCP server (stdio or HTTP)\naikit search <q> # Hybrid search\naikit find <q> # Federated search\naikit symbol <name> # Resolve symbol\naikit scope-map <t> # Task reading plan\naikit compact <q> # Context compression (--path file or stdin)\naikit check # Typecheck + lint (--detail efficient|normal|full)\naikit test # Run tests\naikit rename <old> <new> <path> # Rename symbol\naikit lane create <name> --files f1,f2 # Create lane\naikit lane diff <name> # View lane changes\naikit lane merge <name> # Merge lane back\naikit status # Index stats\naikit reindex # Rebuild index\n```\n\n## Configuration\n\n`kb.config.json` in project root:\n```json\n{\n "sources": [{ "path": ".", "excludePatterns": ["node_modules/**", "**/node_modules/**", "dist/**", "coverage/**", ".aikit-data/**"] }],\n "indexing": { "chunkSize": 1500, "chunkOverlap": 200, "minChunkSize": 100, "concurrency": 5 },\n "embedding": { "model": "mixedbread-ai/mxbai-embed-large-v1", "dimensions": 1024 },\n "store": { "backend": "lancedb", "path": ".aikit-data" },\n "curated": { "path": "curated", "adapter": "filesystem" }\n}\n```\n\n## Tool Profiles\n\nTool profiles control which subset of the 61 tools are active. Profiles reduce token overhead by exposing only relevant tools for a given task.\n\n### Built-in Profiles\n\n| Profile | Description | Use When |\n|---------|-------------|----------|\n| `full` | All tools enabled (default) | General development, orchestration |\n| `safe` | Read-only tools — no file/state modifications | Code review, analysis, research |\n| `research` | Search, analysis, knowledge, web access | Investigation, documentation |\n| `minimal` | Essential tools only — search, check, test | Simple tasks, low-token budgets |\n| `discovery` | Full toolset + meta-tools for guided exploration | New users, onboarding, tool learning |\n\n### Activating a Profile\n\nSet `toolProfile` in `kb.config.json`:\n\n```json\n{\n "toolProfile": "research"\n}\n```\n\nBase tools (`status`, `config`, `guide`, `health`) are **always available** regardless of profile.\n\n## Development (Self-Dogfooding)\n\nWhen developing @vpxa/aikit itself: always `pnpm build` before using CLI/server (runs from `dist/`), always `reindex` after structural code changes, and don\'t run CLI and HTTP server simultaneously (LanceDB is single-process).\n\n---\n\n## Flows\n\nFlows are structured multi-step workflows that guide agents through complex tasks. They are the **primary workflow system** — use them instead of ad-hoc planning when a matching flow exists.\n\n### Flow Tools\n\n| Tool | Purpose |\n|------|---------|\n| `flow` | Check if a flow is active + current step + phase (before/flow/after) + isEpilogue |\n\nDifferent `action` values handle listing, starting, reading steps, advancing, resets, run inspection, and add/update/remove flow management.\n\n### Flow Selection\n\n| Task Type | Flow | Why |\n|-----------|------|-----|\n| Bug fix, config change, small refactor | `aikit:basic` | Known scope, low risk |\n| New feature in existing module | `aikit:basic` | Clear boundaries |\n| New system/service/module | `aikit:advanced` | Needs spec + planning |\n| Cross-service changes | `aikit:advanced` | Multiple boundaries |\n| Architectural change | `aikit:advanced` | High impact |\n| Unclear scope or exploratory | No flow | Use agent\'s native workflow |\n\n### Flow Lifecycle\n\n1. **Start**: `flow({ action: \'list\' })` → choose flow → `flow({ action: \'start\', name: "<name>", topic: "<task>" })`\n2. **Each step**: `flow({ action: \'read\', step: "<name>" })` → follow step instructions → complete work\n3. **Advance**: `flow({ action: \'step\', advance: \'next\' })` → repeat from step 2\n4. **Epilogue**: After last flow step, mandatory epilogue steps run (e.g., `_docs-sync` updates `docs/`)\n5. **Resume**: `flow({ action: \'status\' })` → if active, `flow({ action: \'read\' })` for current step → continue\n6. **Reset**: `flow({ action: \'reset\' })` if you need to start over\n\n---\n\n## Reference Documentation\n\nFor detailed patterns on specific topics, load these reference files:\n\n| Topic | File | When to load |\n|-------|------|-------------|\n| Multi-task orchestration | `references/coordination.md` | Queue, DAG, lanes, worksets, stash, checkpoints |\n| Quality gates (FORGE) | `references/forge-protocol.md` | Complex tasks, evidence maps, tier classification |\n| Search & relationships | `references/search-patterns.md` | Finding code, tracing data flow, graph traversal |\n'},{file:`references/coordination.md`,content:`# Coordination & Multi-Task Orchestration
|
|
1707
|
+
`}],aikit:[{file:`SKILL.md`,content:'---\nname: aikit\ndescription: "Use the @vpxa/aikit AI Kit MCP server for codebase search, analysis, and persistent memory. Load this skill when using aikit_search, aikit_analyze, aikit_knowledge, or any aikit_* tool. Covers all 61 MCP tools: search (hybrid/semantic/keyword), code analysis (analyze aspects for structure, dependencies, symbols, patterns, entry points, diagrams, plus blast radius), knowledge graph (auto-populated module/symbol/import graph with traversal), context management (worksets, stash, checkpoints, restore, lanes), code manipulation (rename, codemod, eval), execution and validation (check, test_run, audit), knowledge management (knowledge actions: remember/read/update/forget/list), web access (fetch, search, http), FORGE protocol (ground, classify, evidence map, stratum cards, digest), flow management (list, start, navigate steps, read instructions, inspect runs, add/remove/update flows), presentation (rich dashboards via present tool), onboarding (full codebase analysis in one call), meta-tools (tool discovery and descriptions), and developer utilities (regex, encode, measure, changelog, schema-validate, env, time)."\nmetadata:\n category: cross-cutting\n domain: general\n applicability: always\n inputs: [codebase]\n outputs: [search-results, analysis, knowledge]\n relatedSkills: [present]\n---\n\n# @vpxa/aikit — AI Kit\n\nLocal-first AI developer toolkit — 61 MCP tools for search, analysis, context compression, FORGE quality gates, knowledge management, code manipulation, execution, web access, flow management, presentation, meta-tool discovery, and developer utilities.\n\n## When to Use\n\n- You need long-term memory across coding sessions\n- You want to search a codebase semantically (by meaning, not just keywords)\n- You need to compress large contexts to focus on what matters\n- You want structured output from build tools (tsc, vitest, biome, git)\n- You need to plan which files to read for a task\n- You want to safely explore refactors in isolated lanes\n- You need to rename symbols, apply codemods, or run code transformations\n- You want to fetch and read web pages or search the web\n- You need to make HTTP requests, test APIs, or debug endpoints\n- You want to test regex patterns, encode/decode data, or validate JSON schemas\n- You need code complexity metrics or a git changelog\n\n## Skills Reference\n\n| Context | Skill | Load when |\n|---------|-------|----------|\n| AI Kit search, analysis, memory | `aikit` | **Always load at session start.** Tool signatures, workflows, session protocol. |\n| Brainstorming & design | `brainstorming` | Before any creative/design work — new features, components, behavior changes. |\n| Session context preservation | `session-handoff` | Context window filling up, session ending, or major milestone completed. |\n| Requirements scoring | `requirements-clarity` | Before planning vague or complex features — score 0-100 until ≥ 90. |\n| Engineering lessons | `lesson-learned` | After completing work — extract principles from git diffs. |\n| Architecture diagrams | `c4-architecture` | When documenting or reviewing architecture — C4 Mermaid diagrams. |\n| Architecture decisions | `adr-skill` | When making non-trivial technical decisions — executable ADRs. |\n| Rich presentation | `present` | When presenting dashboards, charts, tables, or complex visual content to users. |\n| TypeScript patterns | `typescript` | Before TypeScript implementation — type system, compiler config, advanced types. |\n| React patterns | `react` | Before React work — component architecture, React 19 APIs, Server Components. |\n| Frontend design | `frontend-design` | Before UI/UX work — visual design, typography, color, layout, accessibility. |\n| Multi-agent orchestration | `multi-agents-development` | Before delegating to multiple agents — task decomposition, dispatch, review pipelines. |\n| Living documentation | `docs` | When creating or updating project documentation — Diátaxis framework, staleness detection. |\n| Repository access recovery | `repo-access` | When encountering git auth failures, accessing private/enterprise repos, or when `web_fetch`/`http` returns auth errors on repository URLs. |\n| Browser automation & auth | `browser-use` | When needing browser interaction — login flows, SAML SSO bypass, cookie extraction, form filling, web scraping, or authenticated browsing. Pairs with `repo-access` for auth recovery via browser. |\n\n## Architecture\n\n16-package monorepo published as a single npm package:\n\n```\ncore → store → embeddings → chunker → indexer → analyzers → tools → server → cli\n ↕\n dashboard, elicitation, enterprise-bridge, flows, present, settings-ui, aikit-client\n```\n\n- **MCP server**: 61 tools + 2 resources (via `@modelcontextprotocol/sdk`)\n- **CLI**: 49 commands (thin dispatcher + 11 command groups)\n- **Search**: Hybrid vector + keyword + RRF fusion\n- **Embeddings**: ONNX local (mxbai-embed-large-v1, 512 dimensions, int8 quantized)\n- **Vector store**: SQLite-vec (embedded, zero infrastructure)\n- **Chunking**: Tree-sitter AST (TS/JS/Python/Go/Rust/Java) + regex fallback\n- **Dashboard**: Web-based dashboard for knowledge graph visualization and settings management\n\n## Session Protocol (MANDATORY)\n\n### Start (do ALL)\n```\nflow({ action: \'status\' }) # Check/resume active flow FIRST\n# If flow active → flow({ action: \'read\', step }) → follow step instructions\nstatus({}) # Check AI Kit health + onboard state\n# If onboard not run → onboard({ path: "." }) # First-time codebase analysis\nflow({ action: \'list\' }) # See available flows\n# Select flow based on task → flow({ action: \'start\', name: "<name>", topic: "<task>" }) # Start — creates .flows/{topic}/\nknowledge({ action: "list" }) # See stored knowledge\nsearch({ query: "SESSION CHECKPOINT", origin: "curated" }) # Resume prior work\n```\n\n### During Session\n```\nsearch → scope_map → symbol → trace (orient)\ncheck → test_run (validate changes)\nknowledge({ action: "remember", ... }) (capture insights)\n```\n\n### End of Session\n```\nsession_digest({ persist: true }) # Auto-capture session activity\nknowledge({ action: "remember", title: "Session checkpoint: <topic>", content: "<what was done, decisions made, next steps>", category: "conventions" })\n```\n\n## Tool Catalog\n\n### Search & Discovery (8)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `search` | `aikit search` | Hybrid/semantic/keyword search with `search_mode` param |\n| `find` | `aikit find` | Federated search: vector + FTS + glob + regex in one call. Use `mode: \'examples\'` to find usage examples. |\n| `symbol` | `aikit symbol` | Resolve symbol definition, imports, and references |\n| `lookup` | `aikit lookup` | Full-file retrieval by path or record ID |\n| `scope_map` | `aikit scope-map` | Task-scoped reading plan with token estimates |\n| `trace` | `aikit trace` | Forward/backward flow tracing through call chains |\n| `dead_symbols` | `aikit dead-symbols` | Find exported symbols never imported — separates source (actionable) from docs (informational). Accepts `path` to scope the search. |\n| `file_summary` | `aikit summarize` | Structural overview of a file (exports, imports, functions) |\n\n### Code Analysis (2)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `analyze` | `aikit analyze <aspect>` | Unified analyzer for structure, dependencies, symbols, patterns, entry_points, and diagram aspects |\n| `blast_radius` | `aikit analyze blast-radius` | Change impact analysis |\n\n### Context Management (6)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `compact` | `aikit compact` | Compress text to relevant sections using embeddings (no LLM). Accepts `path` for server-side file read. |\n| `workset` | `aikit workset` | Named file set management (save/load/add/remove) |\n| `stash` | `aikit stash` | Named key-value store for session data |\n| `checkpoint` | `aikit checkpoint` | Save/restore session checkpoints |\n| `restore` | `aikit restore` | Restore a previously saved checkpoint |\n| `parse_output` | `aikit parse-output` | Parse tsc/vitest/biome/git output → structured JSON |\n\n### Code Manipulation (4)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `rename` | `aikit rename` | Smart whole-word symbol rename across files (dry-run supported) |\n| `codemod` | `aikit codemod` | Regex-based code transformations with rules (dry-run supported) |\n| `diff_parse` | `aikit diff` | Parse unified diff → structured changes |\n| `data_transform` | `aikit transform` | JQ-like JSON transformations |\n\n### Execution & Validation (4)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `eval` | `aikit eval` | Sandboxed JavaScript/TypeScript execution |\n| `check` | `aikit check` | Incremental typecheck + lint. `detail` param: efficient (default, minimal), normal (parsed errors), full (includes raw) |\n| `test_run` | `aikit test` | Run tests with structured pass/fail results |\n| `audit` | `aikit audit` | Unified project audit: structure, deps, patterns, health, dead symbols, check, entry points → synthesized report with score and recommendations. 6 round-trips → 1. |\n\n### Knowledge Management (2)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `knowledge` | `aikit knowledge <action>` | Unified knowledge tool for remember, read, update, forget, and list actions |\n| `produce_knowledge` | — | Auto-generate knowledge from analysis |\n\n### Auto-Knowledge (automatic)\n\nTool outputs are automatically analyzed after every call. Useful facts (conventions, test patterns, build commands, errors) are extracted and stored as curated entries. Quality gate (score >= 0.3), deduplication, TTL for transient facts, max 50/session.\n\nSearch auto-knowledge with: `search({ query: "...", origin: "curated" })` or `knowledge({ action: "list", category: "conventions" })`\n\n### Verified Lanes (1 tool, 6 actions)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `lane` | `aikit lane` | Manage isolated file copies for parallel exploration |\n\nLane actions: `create` (copy files to lane), `list`, `status` (modified/added/deleted), `diff` (line-level diff), `merge` (apply back to originals), `discard`.\n\n### Git & Environment (4)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `git_context` | `aikit git` | Branch, status, recent commits |\n| `process` | `aikit proc` | Process supervisor (start/stop/logs) |\n| `watch` | `aikit watch` | Filesystem watcher |\n| `delegate` | `aikit delegate` | Delegate subtask to local Ollama model |\n\n### Web & Network (3)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `web_fetch` | — | Fetch web page → markdown/raw/links/outline for LLM consumption |\n| `web_search` | — | Multi-provider web search (DuckDuckGo + Bing-HTML + Mojeek fan-out, no API key needed) |\n| `http` | — | Make HTTP requests for API testing/debugging |\n\n### Developer Utilities (7)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `regex_test` | — | Test regex patterns with match/replace/split modes |\n| `encode` | — | Base64, URL, SHA-256, MD5, hex encode/decode, JWT decode |\n| `measure` | — | Code complexity metrics (cyclomatic, cognitive complexity, lines, functions) |\n| `changelog` | — | Generate changelog from git history (conventional commits) |\n| `schema_validate` | — | Validate JSON data against JSON Schema |\n| `env` | — | System and runtime environment info (sensitive values redacted) |\n| `time` | — | Date parsing, timezone conversion, duration math |\n\n### FORGE Quality Gates (5)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `forge_ground` | — | Full Ground phase: classify tier, scope map, unknowns, constraints |\n| `forge_classify` | — | Quick tier classification (Floor/Standard/Critical) |\n| `evidence_map` | — | CRUD + Gate evaluation for verified/assumed/unknown claims. Safety gate tags (`provenance`/`commitment`/`coverage`) enable mandatory pre-YIELD checks |\n| `stratum_card` | — | Generate T1/T2 compressed context cards from files (10-100x token reduction) |\n| `digest` | — | Compress N text sources into token-budgeted summary |\n\n### System (9)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `config` | `aikit config` | View or update project configuration (aikit.config.json) |\n| `status` | `aikit status` | Index statistics |\n| `reindex` | `aikit reindex` | Rebuild index |\n| `health` | `aikit health` | Project health checks (package.json, tsconfig, lockfile, circular deps) |\n| `guide` | `aikit guide` | Tool discovery — given a goal, recommends tools and workflow order |\n| `onboard` | `aikit onboard` | Full codebase onboarding in one call (structure + deps + patterns + knowledge) |\n| `graph` | `aikit graph` | Query the auto-populated knowledge graph (modules, symbols, imports) |\n| `queue` | `aikit queue` | Task queue for sequential agent operations (create/push/next/done/fail) |\n| `replay` | `aikit replay` | View or clear the audit trail of tool invocations (action: list/clear) |\n\n### Flows (1)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `flow` | `aikit flow` | Manage flows — list, start, navigate steps, read instructions, inspect runs, add/remove/update. |\n\n### Presentation (1)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `present` | — | Rich dashboards, charts, tables, timelines. Use `format: "browser"` then `openBrowserPage` to display. **In CLI mode (no IDE chat panel), always use `format: "browser"`** — `html` UIResource is invisible in terminal. |\n\n### Meta-Tools — Tool Discovery (3)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `list_tools` | — | List all active AI Kit tools with names, titles, and categories. Accepts optional `category` filter. Use for initial tool discovery. |\n| `describe_tool` | — | Get detailed metadata for a specific tool (title, categories, annotations). Use after `list_tools` to understand a tool before calling it. |\n| `search_tools` | — | Search active tools by keyword across names, titles, and categories. Use when you know what you need but not the tool name. |\n\n### Session Management (1)\n| Tool | CLI | Purpose |\n|------|-----|---------|\n| `session_digest` | — | Generate a compressed digest of session activity (replay log, stash, checkpoints). Options: `scope` (tools/stash/all), `since`, `last`, `focus`, `mode` (deterministic/sampling), `tokenBudget`, `persist`. Use at session end for handoff or mid-session to review what happened. |\n\n## Execution & Data Tools\n\n### `eval` — Execute Code in Sandbox\n\nRun JavaScript or TypeScript snippets in a constrained VM. Captures console output and return values.\n\n**Parameters:**\n| Param | Type | Default | Description |\n|-------|------|---------|-------------|\n| `code` | string | — | Code to execute |\n| `lang` | `"js"` \\| `"ts"` | `"js"` | Language mode (ts strips type syntax first) |\n| `timeout` | number | 5000 | Execution timeout in ms (max 60000) |\n\n**Examples:**\n```\n// Quick calculation\neval({ code: "return [1,2,3].reduce((a,b) => a+b, 0)" })\n\n// Process data\neval({ code: "const data = [1,2,3,4,5]; return { sum: data.reduce((a,b)=>a+b), avg: data.reduce((a,b)=>a+b)/data.length }" })\n\n// TypeScript\neval({ code: "interface Point { x: number; y: number }; const p: Point = {x: 1, y: 2}; return p.x + p.y", lang: "ts" })\n```\n\n---\n\n### `data_transform` — jq-like JSON Transforms\n\nApply jq-inspired expressions to JSON input for filtering, projection, grouping, and extraction.\n\n**Parameters:**\n| Param | Type | Description |\n|-------|------|-------------|\n| `input` | string | JSON string to transform |\n| `expression` | string | Transform expression (see syntax below) |\n\n**Supported Expressions:**\n\n| Expression | Description | Example |\n|------------|-------------|---------|\n| `.` | Identity (return input as-is) | `.` |\n| `.field` | Access object field | `.name` |\n| `.[N]` | Array index access | `.[0]` |\n| `.field1.field2` | Nested field access | `.user.name` |\n| `| filter(condition)` | Filter array items | `| filter(.age > 18)` |\n| `| map(expr)` | Transform each item | `| map(.name)` |\n| `| sort_by(.field)` | Sort by field | `| sort_by(.date)` |\n| `| group_by(.field)` | Group items by field | `| group_by(.category)` |\n| `| select(cond)` | Keep items matching condition | `| select(.active == true)` |\n| `| flatten` | Flatten nested arrays | `| flatten` |\n| `| unique` | Remove duplicates | `| unique` |\n| `| keys` | Get object keys | `| keys` |\n| `| values` | Get object values | `| values` |\n| `| length` | Array/string length | `| length` |\n| `| join(sep)` | Join array with separator | `| join(", ")` |\n| `| first` | First element | `| first` |\n| `| last` | Last element | `| last` |\n| `| sum` | Sum numeric array | `| sum` |\n| `| avg` | Average of numeric array | `| avg` |\n| `| min` / `| max` | Min/max value | `| min` |\n\n**Comparisons:** `==`, `!=`, `>`, `<`, `>=`, `<=`\n**Logical:** `and`, `or`, `not`\n\n**Examples:**\n```\n// Filter and project\ndata_transform({ input: \'[{"name":"Alice","age":30},{"name":"Bob","age":17}]\', expression: \'| filter(.age >= 18) | map(.name)\' })\n// → ["Alice"]\n\n// Group and count\ndata_transform({ input: \'[{"type":"bug"},{"type":"feat"},{"type":"bug"}]\', expression: \'| group_by(.type)\' })\n// → {"bug":[...], "feat":[...]}\n\n// Sort and take first\ndata_transform({ input: \'[{"score":3},{"score":1},{"score":5}]\', expression: \'| sort_by(.score) | first\' })\n// → {"score":1}\n```\n\n---\n\n### `time` — Date & Time Operations\n\nParse dates, convert timezones, calculate durations, add time. Supports ISO 8601, unix timestamps, and human-readable formats.\n\n**Parameters:**\n| Param | Type | Description |\n|-------|------|-------------|\n| `operation` | string | `now`, `parse`, `convert`, `diff`, `add` |\n| `input` | string | Date input (ISO, unix, or parseable string). For `diff`: two comma-separated dates |\n| `timezone` | string | Target timezone (e.g., "America/New_York") |\n| `duration` | string | Duration to add (e.g., "2h30m", "1d", "30s") — for `add` |\n\n**Operations:**\n| Op | Purpose | Example |\n|----|---------|---------|\n| `now` | Current time in all formats | `time({ operation: "now" })` |\n| `parse` | Parse any date string | `time({ operation: "parse", input: "2024-03-15T10:30:00Z" })` |\n| `convert` | Convert to timezone | `time({ operation: "convert", input: "2024-03-15T10:30:00Z", timezone: "Asia/Tokyo" })` |\n| `diff` | Duration between dates | `time({ operation: "diff", input: "2024-01-01,2024-12-31" })` |\n| `add` | Add duration to date | `time({ operation: "add", input: "2024-03-15", duration: "2h30m" })` |\n\n**Duration format:** Combine: `Nd` (days), `Nh` (hours), `Nm` (minutes), `Ns` (seconds)\nExample: `"1d2h30m"` = 1 day, 2 hours, 30 minutes\n\n## Flow System\n\nFlows are multi-step guided workflows that structure complex tasks. Each step has a skill file with detailed instructions, required artifacts, and agent assignments.\n\n### Built-in Flows\n\n| Flow | Steps | Use When |\n|------|-------|----------|\n| `aikit:basic` | assess → implement → verify | Bug fixes, config changes, small features |\n| `aikit:advanced` | spec → plan → task → execute → verify | New modules, cross-service changes, architectural work |\n\n### Flow Lifecycle\n\n```text\nflow({ action: \'list\' }) # See available flows\nflow({ action: \'info\', name: \'aikit:basic\' }) # View steps, skills, agents\nflow({ action: \'start\', name: \'aikit:basic\', topic: \'Fix login bug\' }) # Start — creates .flows/fix-login-bug/\nflow({ action: \'read\' }) # Read current step\'s instructions ({{artifacts_path}} resolved)\n# ... do the work described in the instruction ...\nflow({ action: \'step\', advance: \'next\' }) # Advance to next step\nflow({ action: \'step\', advance: \'skip\' }) # Skip current step\nflow({ action: \'step\', advance: \'redo\' }) # Redo current step\nflow({ action: \'status\' }) # Check progress (includes slug, runDir, artifactsPath, phase, isEpilogue)\nflow({ action: \'reset\' }) # Abandon active flow\nflow({ action: \'runs\' }) # List all runs (current + past)\n# Epilogue steps (mandatory, injected after every flow):\n# After last flow step → _docs-sync epilogue runs automatically\n# flow({ action: \'status\' }) shows phase: \'after\', isEpilogue: true during epilogue\n```\n\nCustom flow lifecycle management:\n\n```text\nflow({ action: \'add\', source: \'.github/flows/my-flow\' })\nflow({ action: \'update\', name: \'my-flow\' })\nflow({ action: \'remove\', name: \'my-flow\' })\n```\n\n## CRITICAL: Use AI Kit Tools Instead of Native IDE Tools\n\nAI Kit tools provide **10x richer output** than native IDE tools — with AST-analyzed call graphs, scope context, import classification, and cognitive complexity. **You MUST use AI Kit tools instead of native read/search tools.**\n\n### ⛔ PROHIBITED: Native File Reading\n\n**`read_file` / `read_file_raw` MUST NOT be used to understand code.** They waste tokens and miss structural information.\n\nThe **ONLY** acceptable use of `read_file`: getting exact lines immediately before an edit (to verify the `old_str` for replacement). Even then, use `file_summary` first to identify which lines to read.\n\n### Tool Replacement Table\n\n| ❌ NEVER do this | ✅ Use AI Kit Tool | Why |\n|---|---|---|\n| `read_file` (full file) | `file_summary` | Exports, imports, call edges — **10x fewer tokens** |\n| `read_file` (specific section) | `compact({ path, query })` | Server-side read + extract — **5-20x reduction** |\n| `grep_search` / `textSearch` | `search` | Semantic + keyword hybrid across all indexed content |\n| `grep_search` for a symbol | `symbol` | Definition + references **with scope context** |\n| Multiple `read_file` calls | `digest` | Compresses multiple sources into token-budgeted summary |\n| `listDirectory` + `read_file` | `scope_map` | Identifies relevant files for a task automatically |\n| Manual code tracing | `trace` | AST call-graph traversal with scope context |\n| Line counting / `wc` | `measure` | Lines, complexity, **cognitive complexity**, functions |\n| Grep for unused exports | `dead_symbols` | AST-powered export detection with regex fallback |\n| Repeated file reads | `stratum_card` | Reusable compressed context — **10-100x reduction** |\n| `fetch_webpage` | `web_fetch` | Readability extract + token budget — richer output |\n| Web research / browsing | `web_search` | Multi-provider web search without browser — **unique to AI Kit** |\n\n### Decision Tree — How to Read Code\n\n```\nNeed to understand a file?\n├─ Just structure? → file_summary (exports, imports, call edges — ~50 tokens)\n├─ Specific section? → compact({ path, query }) — 5-20x reduction\n├─ Multiple files? → digest (multi-source compression — token-budgeted)\n├─ Repeated reference? → stratum_card (T1/T2 card — 10-100x reduction)\n├─ Need exact lines to EDIT? → read_file (the ONLY acceptable use)\n└─ "I want to read the whole file" → ⛔ STOP. Use file_summary or compact instead.\n```\n\n### Decision Tree — Need Structural Relationships?\n\nWhen vector search and file reads don\'t answer the question (e.g. "who imports this?",\n"what does this depend on?", "how are these files connected?"), use `graph`:\n\n```\nNeed to understand relationships between code?\n├─ Who imports / calls this? → graph({action:\'find_nodes\', name_pattern}) → graph({action:\'neighbors\', node_id, direction:\'incoming\'})\n├─ What does this depend on? → graph({action:\'neighbors\', node_id, direction:\'outgoing\'})\n├─ Full context for a symbol? → graph({action:\'symbol360\', name})\n├─ Related files within N hops? → graph({action:\'traverse\', node_id, max_depth:2})\n├─ Layer/module isolation check? → graph({action:\'depth_traverse\', node_id, max_depth:3})\n└─ Graph size/health? → graph({action:\'stats\'})\n```\n\n**Use this BEFORE** reaching for `analyze({ aspect: "dependencies", ... })` (slower, less precise) or manually\ntracing via `symbol` + `trace` chains. The graph is auto-populated during indexing.\n\n### What AI Kit Tools Return (AST-Enhanced)\n\nThese tools use Tree-sitter WASM to analyze source code at the AST level, providing structured data that raw file reads cannot:\n\n| Tool | Rich Output |\n|------|-------------|\n| `file_summary` | Imports classified as **external vs internal** (`isExternal` flag). **Call edges** between functions (e.g., `handleRequest() → validateInput() @ line 42`). `exported` flag on interfaces and types. Import count breakdown. |\n| `symbol` | References include **scope** — which function/class/method contains each usage (e.g., `referenced in processOrder() at auth-service.ts:55`). |\n| `trace` | **Call-graph edges** discovered via AST syntax tree, not text matching. Supports forward (who does X call?) and backward (who calls X?) tracing. Scope context on each node. |\n| `measure` | **Cognitive complexity** — weights nesting depth (nested `if` inside `for` inside `try` scores higher). More useful than cyclomatic complexity for understanding code difficulty. |\n| `dead_symbols` | **AST export enumeration** — catches `export default`, barrel re-exports (`export { x } from`), `export =`, and `export type`. Regex fallback for non-AST-supported languages. |\n\n### Example: `file_summary` Output\n\n```\nsrc/auth-service.ts\nLanguage: typescript | Lines: 180 | Estimated tokens: ~1400\n\nImports (6): 3 external, 3 internal\n - import { hash } from \'bcrypt\' [external]\n - import { UserRepo } from \'./user-repo\' [internal]\n\nFunctions (4):\n - authenticate @ line 22 [exported]\n - validateToken @ line 55 [exported]\n - hashPassword @ line 90\n - generateJwt @ line 110\n\nCall edges (12 intra-file):\n - authenticate() → hashPassword() @ line 35\n - authenticate() → generateJwt() @ line 42\n - validateToken() → UserRepo.findById() @ line 68\n\nInterfaces (2):\n - AuthResult @ line 8 [exported]\n - TokenPayload @ line 14\n```\n\nCompare: `read_file` would cost ~1400 tokens for raw text. `file_summary` gives structured data in ~120 tokens — **12x reduction** with richer information.\n\n## Token Efficiency\n\n`config.tokenBudget` controls output verbosity globally:\n\n| Level | Output | Compression | Context Strategy |\n|-------|--------|-------------|------------------|\n| `efficient` (default) | Minimal output, score + top issues only | threshold 2000, budget 1000 | `stratum_card(T1)` |\n| `normal` | Standard output with parsed errors/pattern names | threshold 4000, budget 2000 | `compact()` |\n| `full` | Maximum detail with raw output/full tables | No compression | `digest()` |\n\nSet via: `config({ action: \'update\', updates: { tokenBudget: \'normal\' } })`\n\nTools with `detail` param inherit from `config.tokenBudget` when not explicitly set.\nCompression middleware applies to ALL tool responses automatically.\n\n## Search Strategy\n\n1. **Start broad**: `search({ query: "topic", search_mode: "hybrid" })`\n2. **Narrow**: Add `content_type`, `origin`, or `category` filters\n3. **Exact match**: Use `search_mode: "keyword"` for identifiers\n4. **Federated**: Use `find` to combine vector + glob + regex\n\n## Workflow Chains\n\n### Codebase Onboarding\n```\nanalyze({ aspect: "structure", path: "src/" })\n→ analyze({ aspect: "dependencies", path: "src/" })\n→ analyze({ aspect: "entry_points", path: "src/" })\n→ produce_knowledge({ path: "src/" })\n→ knowledge({ action: "remember", title: "Codebase onboarding complete", ... })\n```\n\n### Planning a Task\n```\nscope_map({ task: "implement user auth" })\n→ compact({ path: "src/auth.ts", query: "auth flow" })\n→ workset({ action: "save", name: "auth-task", files: [...] })\n```\n\n### Bug Investigation\n```\nparse_output({ output: <error> }) → symbol({ name: "failingFn" })\n→ trace({ symbol: "failingFn", direction: "backward" })\n→ blast_radius({ changed_files: ["suspect.ts"] })\n→ eval({ code: "hypothesis test" }) → check({ files: ["suspect.ts"] })\n```\n\n### Multi-Task Orchestration (DAG Queue)\n```\nqueue({ action: "create", name: "my-tasks" })\n→ queue({ action: "push", name: "my-tasks", title: "Task 1", data: { deps: [] } })\n→ queue({ action: "push", name: "my-tasks", title: "Task 2", data: { deps: ["task-1-id"] } })\n→ queue({ action: "next", name: "my-tasks" }) # Gets next ready task\n→ [do work]\n→ queue({ action: "done", name: "my-tasks", id: "<id>" })\n```\n\n### Safe Refactor with Lanes\n```\nscope_map({ task: "rename UserService" })\n→ lane({ action: "create", name: "refactor", files: [...] })\n→ [make changes in lane files]\n→ lane({ action: "diff", name: "refactor" })\n→ check({}) → test_run({})\n→ lane({ action: "merge", name: "refactor" })\n```\n\n### Lane — isolated read-only exploration\n\n`lane({ action:\'create\', name })` creates an isolated copy of the workspace. Use to try approach A vs B WITHOUT touching canonical source. Other actions: `list`, `diff`, `delete`. Compare with `lane({ action:\'diff\', names:[\'a\',\'b\'] })`. Do NOT use `lane` for actual refactors — use `checkpoint` instead (`checkpoint` = reversible on canonical source; `lane` = isolated copies for comparison).\n\n### After Making Changes\n```\nblast_radius({ changed_files: ["src/auth.ts"] })\n→ check({}) → test_run({ grep: "auth" })\n→ reindex()\n→ knowledge({ action: "remember", title: "Implemented auth", content: "..." })\n```\n\n### Pre-Commit Validation\n```\ngit_context({ diff: true })\n→ diff_parse({ diff: <staged diff> })\n→ blast_radius({ changed_files: [...] })\n→ check({}) → test_run({})\n```\n\n---\n\n## Persistent Memory\n\n| Action | Tool | Category |\n|--------|------|----------|\n| Store | `knowledge({ action: "remember", title, content, category })` | conventions, decisions, patterns, context, session |\n| Search | `search({ query, origin: "curated" })` | — |\n| Browse | `knowledge({ action: "list" })` or `knowledge({ action: "list", category })` | — |\n| Read | `knowledge({ action: "read", id })` | — |\n| Update | `knowledge({ action: "update", id, content })` | — |\n| Remove | `knowledge({ action: "forget", id })` | — |\n\n**Session checkpoint** (end of session): `knowledge({ action: "remember", title: "Session checkpoint: <topic>", content: "Done/Decisions/Next/Blockers", category: "session" })`\n\n## CLI Quick Reference\n\n```bash\naikit init # Scaffold AI Kit in current directory\naikit init --force # Overwrite all scaffold/skill files\naikit init --guide # JSON report of stale files for LLM-driven updates\naikit serve # Start MCP server (stdio or HTTP)\naikit search <q> # Hybrid search\naikit find <q> # Federated search\naikit symbol <name> # Resolve symbol\naikit scope-map <t> # Task reading plan\naikit compact <q> # Context compression (--path file or stdin)\naikit check # Typecheck + lint (--detail efficient|normal|full)\naikit test # Run tests\naikit rename <old> <new> <path> # Rename symbol\naikit lane create <name> --files f1,f2 # Create lane\naikit lane diff <name> # View lane changes\naikit lane merge <name> # Merge lane back\naikit status # Index stats\naikit reindex # Rebuild index\n```\n\n## Configuration\n\n`aikit.config.json` in project root:\n```json\n{\n "sources": [{ "path": ".", "excludePatterns": ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.git/**", "**/.aikit-data/**", "**/coverage/**"] }],\n "indexing": { "chunkSize": 1500, "chunkOverlap": 200, "minChunkSize": 100 },\n "embedding": { "model": "mixedbread-ai/mxbai-embed-large-v1", "dimensions": 1024 },\n "store": { "backend": "sqlite-vec", "path": ".aikit-data" },\n "curated": { "path": ".ai/curated" }\n}\n```\n\n## Tool Profiles\n\nTool profiles control which subset of the 61 tools are active. Profiles reduce token overhead by exposing only relevant tools for a given task.\n\n### Built-in Profiles\n\n| Profile | Description | Use When |\n|---------|-------------|----------|\n| `full` | All tools enabled (default) | General development, orchestration |\n| `safe` | Read-only tools — no file/state modifications | Code review, analysis, research |\n| `research` | Search, analysis, knowledge, web access | Investigation, documentation |\n| `minimal` | Essential tools only — search, check, test | Simple tasks, low-token budgets |\n| `discovery` | Full toolset + meta-tools for guided exploration | New users, onboarding, tool learning |\n\n### Activating a Profile\n\nSet `toolProfile` in `aikit.config.json`:\n\n```json\n{\n "toolProfile": "research"\n}\n```\n\nBase tools (`status`, `config`, `guide`, `health`) are **always available** regardless of profile.\n\n## Development (Self-Dogfooding)\n\nWhen developing @vpxa/aikit itself: always `pnpm build` before using CLI/server (runs from `dist/`), and always `reindex` after structural code changes.\n\n---\n\n## Flows\n\nFlows are structured multi-step workflows that guide agents through complex tasks. They are the **primary workflow system** — use them instead of ad-hoc planning when a matching flow exists.\n\n### Flow Tools\n\n| Tool | Purpose |\n|------|---------|\n| `flow` | Check if a flow is active + current step + phase (before/flow/after) + isEpilogue |\n\nDifferent `action` values handle listing, starting, reading steps, advancing, resets, run inspection, and add/update/remove flow management.\n\n### Flow Selection\n\n| Task Type | Flow | Why |\n|-----------|------|-----|\n| Bug fix, config change, small refactor | `aikit:basic` | Known scope, low risk |\n| New feature in existing module | `aikit:basic` | Clear boundaries |\n| New system/service/module | `aikit:advanced` | Needs spec + planning |\n| Cross-service changes | `aikit:advanced` | Multiple boundaries |\n| Architectural change | `aikit:advanced` | High impact |\n| Unclear scope or exploratory | No flow | Use agent\'s native workflow |\n\n### Flow Lifecycle\n\n1. **Start**: `flow({ action: \'list\' })` → choose flow → `flow({ action: \'start\', name: "<name>", topic: "<task>" })`\n2. **Each step**: `flow({ action: \'read\', step: "<name>" })` → follow step instructions → complete work\n3. **Advance**: `flow({ action: \'step\', advance: \'next\' })` → repeat from step 2\n4. **Epilogue**: After last flow step, mandatory epilogue steps run (e.g., `_docs-sync` updates `docs/`)\n5. **Resume**: `flow({ action: \'status\' })` → if active, `flow({ action: \'read\' })` for current step → continue\n6. **Reset**: `flow({ action: \'reset\' })` if you need to start over\n\n---\n\n## Reference Documentation\n\nFor detailed patterns on specific topics, load these reference files:\n\n| Topic | File | When to load |\n|-------|------|-------------|\n| Multi-task orchestration | `references/coordination.md` | Queue, DAG, lanes, worksets, stash, checkpoints |\n| Quality gates (FORGE) | `references/forge-protocol.md` | Complex tasks, evidence maps, tier classification |\n| Search & relationships | `references/search-patterns.md` | Finding code, tracing data flow, graph traversal |\n'},{file:`references/coordination.md`,content:`# Coordination & Multi-Task Orchestration
|
|
1708
1708
|
|
|
1709
1709
|
Patterns for managing multiple tasks, parallel exploration, and session state.
|
|
1710
1710
|
|
|
@@ -7357,11 +7357,11 @@ The \`present\` tool renders structured content as a professional dark-themed da
|
|
|
7357
7357
|
| Need user input back (confirmations, selections, form data) | **\`browser\`** | Browser supports blocking actions that return data |
|
|
7358
7358
|
| Rich visual dashboards without interaction | **\`html\`** | Prefer in-chat when no response is needed |
|
|
7359
7359
|
| User explicitly asks for browser | **\`browser\`** | Respect explicit preference |
|
|
7360
|
-
| **Running in CLI mode** (no
|
|
7360
|
+
| **Running in CLI mode** (no IDE chat panel) | **\`browser\`** | \`html\` UIResource is invisible in CLI — only plain markdown renders. Use \`browser\` so the system browser opens automatically with full rich visualization. |
|
|
7361
7361
|
|
|
7362
7362
|
**Rule: If no user interaction is needed, use \`format: "html"\`. If you need user interaction, use \`format: "browser"\`.**
|
|
7363
7363
|
|
|
7364
|
-
> **⚠️ CLI Mode Override:** When running in CLI mode (terminal, not
|
|
7364
|
+
> **⚠️ CLI Mode Override:** When running in CLI mode (terminal, not IDE chat), **always use \`format: "browser"\`** regardless of whether interaction is needed. The \`html\` format relies on UIResource rendering in the IDE's chat panel — in CLI, only the markdown fallback text is shown, losing all rich visualizations (charts, tables, dashboards). The \`browser\` format starts a local HTTP server and auto-opens the system browser after 8 seconds, which works reliably in any environment.
|
|
7365
7365
|
|
|
7366
7366
|
---
|
|
7367
7367
|
|
|
@@ -7372,17 +7372,17 @@ When using \`format: "browser"\`, the tool starts a local HTTP server and return
|
|
|
7372
7372
|
### Steps:
|
|
7373
7373
|
1. Call \`present\` with \`format: "browser"\` and \`actions\` — it returns text containing \`🌐 **Dashboard opened in browser:** http://127.0.0.1:{port}\`
|
|
7374
7374
|
2. **Extract the URL from the response**
|
|
7375
|
-
3. **Call \`openBrowserPage({ url: "http://127.0.0.1:{port}" })\` -
|
|
7375
|
+
3. **Call \`openBrowserPage({ url: "http://127.0.0.1:{port}" })\` - Playwright MCP to open it in the integrated browser**
|
|
7376
7376
|
|
|
7377
7377
|
\`\`\`
|
|
7378
7378
|
// Step 1: Call present
|
|
7379
7379
|
result = present({ format: "browser", title: "...", content: [...], actions: [...] })
|
|
7380
7380
|
|
|
7381
|
-
// Step 2: MUST open in
|
|
7382
|
-
openBrowserPage({ url: "http://127.0.0.1:{port}" }) //
|
|
7381
|
+
// Step 2: MUST open in integrated browser
|
|
7382
|
+
openBrowserPage({ url: "http://127.0.0.1:{port}" }) // Playwright MCP - opens URL in the integrated browser
|
|
7383
7383
|
\`\`\`
|
|
7384
7384
|
|
|
7385
|
-
> **Fallback**: The server also auto-opens the system browser as a safety net. But you should ALWAYS call \`openBrowserPage\`
|
|
7385
|
+
> **Fallback**: The server also auto-opens the system browser as a safety net. But you should ALWAYS call \`openBrowserPage\` via Playwright MCP yourself so the user sees it in their environment.
|
|
7386
7386
|
|
|
7387
7387
|
**Note:** The HTTP server auto-closes after 5 minutes. Open the page promptly after receiving the URL.
|
|
7388
7388
|
|
|
@@ -8254,7 +8254,7 @@ When implementing a React feature:
|
|
|
8254
8254
|
5. **Loading?** → \`<Suspense>\` with skeleton fallback.
|
|
8255
8255
|
6. **Performance?** → Try React Compiler first. Then manual memo. Then virtualization. Then code splitting.
|
|
8256
8256
|
7. **Error?** → Error boundaries for rendering errors. try/catch for Server Actions.
|
|
8257
|
-
`}],"repo-access":[{file:`references/error-patterns.md`,content:'# Repo Access Error Patterns\n\nUse this reference to distinguish missing repositories from authentication and policy failures when probing Git hosts.\n\n## HTTP Status Code Matrix\n\n| Platform | No auth (private repo) | Wrong credentials | Rate limited | SSO required |\n|---|---|---|---|---|\n| GitHub REST API | `404` (TRAP!) | `401` -> `403` | `403` + rate limit body | `403` + `X-GitHub-SSO` header |\n| GitHub Web | HTML "Page not found" or login redirect | Login redirect | - | - |\n| GitLab | `401` | `401` | `429` | `401` (PAT mandatory) |\n| Bitbucket | `403` | `403` | `429` | `403` |\n| Azure DevOps | `401` | `401` | - | `401` |\n\n## CRITICAL: The GitHub 404 Trap\n\nGitHub deliberately returns `404`, not `401`, for private repositories accessed without authentication.\nThis is by design to avoid leaking whether a repository exists.\n\n- Never conclude a GitHub repository does not exist from an unauthenticated `404`.\n- `GET https://api.github.com/repos/{owner}/{repo}` without auth returns `404` for both "repo truly missing" and "repo exists but is private".\n- The only reliable disambiguation is an authenticated probe.\n- If the same request still returns `404` with valid auth, the repository is truly missing.\n\nProbe order:\n\n1. Try the authenticated API request first.\n2. If it returns `200`, access works.\n3. If it returns `404` without auth context, treat it as ambiguous and recover.\n4. If it returns `404` with known-good auth, treat the repo as missing.\n\n## Git CLI Stderr Patterns\n\n| Error Text Pattern | Platform | Diagnosis | Action |\n|---|---|---|---|\n| `remote: Repository not found.` | GitHub | Auth failure, not proof the repo is missing | Try auth strategies |\n| `git@github.com: Permission denied (publickey).` | GitHub | SSH key not recognized | Check SSH keys, try HTTPS |\n| `remote: HTTP Basic: Access denied.` | GitLab | Auth failure, 2FA likely | Use PAT; password auth is blocked with 2FA |\n| `error: The requested URL returned error: 403` | Bitbucket | Auth failure | Try app password |\n| `TF401019: The Git repository with name or identifier X does not exist` | Azure DevOps | Auth failure or missing repo | Try PAT with Code:Read scope |\n| `fatal: Authentication failed for \'https://...\'` | Any (HTTPS) | General auth failure | Escalate through the strategy ladder |\n| `Permission denied (publickey).` | Any (SSH) | SSH key not recognized | Check `~/.ssh/`, run `ssh-add`, try HTTPS |\n| `fatal: Could not read from remote repository.` | Any (SSH) | SSH access denied | Verify the SSH key is added to the platform |\n| `unable to access \'...\': SSL certificate problem` | Any | Self-signed or enterprise CA issue | Ask about local cert config; skip to local clone if needed |\n\nTreat these stderr strings as direct signals from tool output. Do not reinterpret GitHub\'s `Repository not found` as a clean existence check.\n\n## web_fetch / http Tool Detection\n\n- `web_fetch` against a private GitHub repo URL often returns HTML with "Page not found" or a login page.\n- GitHub web responses can be `200` with a 404-looking body, so `web_fetch` is unreliable for auth diagnosis.\n- `http` against the platform API gives machine-readable bodies and real status codes, so use it for probes.\n- For `web_fetch` on `github.com`, inspect the body for `Page not found`, `Sign in`, or `/login` links. If present, assume private or auth-gated access and trigger recovery.\n\nRecommended diagnostic probe:\n\n```text\nhttp GET https://api.github.com/repos/{owner}/{repo}\n-> 404 + no auth header -> might be private\n-> 401 -> explicit auth failure\n-> 200 -> repo is public, access works\n```\n\n## Edge Cases\n\n| Edge Case | Signal | Response |\n|---|---|---|\n| GitHub.com SAML SSO | `403` + `X-GitHub-SSO: required; url=...` | PAT needs SSO authorization for the org |\n| GHE SAML SSO (web_fetch) | `200` + body contains `Initiating SAML single sign-on`, redirect to `login.microsoftonline.com` or other IdP | Repo EXISTS and is auth-gated. NOT inaccessible. Use PAT + `http` with auth headers, or `gh auth login --hostname <host>` |\n| GHE SAML SSO (http) | `302` redirect to `/login?return_to=...` or IdP URL | Same — repo exists, needs auth. Walk the Strategy Ladder |\n| GHE SAML SSO (git CLI) | `fatal: Authentication failed` or credential prompt | `gh auth login --hostname <host>` or PAT via credential helper |\n\n## SAML SSO — Detailed Pattern\n\nGitHub Enterprise instances commonly use SAML SSO via Azure AD (Entra ID), Okta, or other IdPs. When `web_fetch` hits a GHE URL without auth:\n\n1. GHE returns `200 OK` (not 401/403!) with an HTML page\n2. The HTML contains `Initiating SAML single sign-on` and a redirect URL to the IdP\n3. The redirect URL includes `SAMLRequest=`, `RelayState=`, and often `login.microsoftonline.com`\n4. The agent sees HTML content and may conclude the repo is "inaccessible" or "behind SSO"\n\n**Detection strings** (check `web_fetch` output for ANY of these):\n```\nInitiating SAML single sign-on\nlogin.microsoftonline.com\nYou are being redirected to your identity provider\n/login?return_to=\nSAMLRequest=\nRelayState=\n```\n\n**Correct response:** The repo exists. The `web_fetch` path will never work for SSO-protected GHE. Switch to:\n- `gh auth login --hostname <ghe-host>` (if `gh` CLI available)\n- PAT + `http` with `Authorization: token <PAT>` against `<ghe-host>/api/v3/repos/{owner}/{repo}/contents/{path}`\n- Ask user for local clone if no token can be obtained\n| GitLab 2FA enabled | `401` on password auth | PAT is mandatory; 2FA blocks password auth |\n| Expired token | `401` after providing a valid-looking PAT | Generate a new token and check expiry |\n| GitHub rate limit | `403` + body contains `rate limit` | Not an auth failure; wait or authenticate for a higher limit |\n| IP allowlisting | `403` + body mentions IP or org policies | Cannot be fixed programmatically; skip to local clone (Step 5) |\n| Fine-grained PAT scope | `403` + `insufficient scope` | Switch to a classic PAT for org repos |\n| SSH key not in agent | `Permission denied (publickey)` + key file exists | Run `ssh-add ~/.ssh/id_ed25519` |\n| Wrong SSH username | `Permission denied` | Use `git@host`, not `username@host` |\n| Deploy key conflict | `key is already in use` | Use a user SSH key or PAT instead |\n\n## Escalation Decision Rules\n\n- Retry the same step for transient failures such as DNS failure, timeout, or `5xx` responses.\n- Escalate to the next strategy step for `401`, `403`, `404`, `Permission denied`, `Authentication failed`, or `Access denied`.\n- Skip directly to Step 5 (local clone) for IP allowlisting, enterprise SSL certificate issues, or org policy blocks.\n\nDefault interpretation order:\n\n1. Prefer API probes over web page fetches.\n2. Treat GitHub `404` as ambiguous until valid auth disproves privacy.\n3. Treat SSH `publickey` errors as key-distribution failures, not repo absence.\n4. Separate rate limits and org policy blocks from authentication failures before escalating.'},{file:`references/platform-matrix.md`,content:"# Platform Matrix\n\nUse this reference when a repository URL reveals the hosting platform and the skill needs platform-specific authentication or cloning guidance. Prefer platform CLI login flows or OS-backed credential helpers over raw PAT handling.\n\n## Platform Detection\n\n| URL Pattern | Platform | CLI Tool (optional) | Auth Command | No-CLI Alternative |\n|---|---|---|---|---|\n| `github.com` | GitHub | `gh` | `gh auth login` | PAT + `http` with `Authorization: token <PAT>` |\n| Any custom domain (e.g. `ghe.corp.com`, `github.corp.com`) | GitHub Enterprise | `gh` | `gh auth login --hostname <host>` | PAT + `http` against `<host>/api/v3` |\n| `gitlab.com` | GitLab | `glab` | `glab auth login` | PAT + `http` with `PRIVATE-TOKEN` header |\n| Self-hosted GitLab | GitLab Self-Managed | `glab` | `glab auth login --hostname <host>` | PAT + `http` with `PRIVATE-TOKEN` header |\n| `bitbucket.org` | Bitbucket Cloud | None | N/A | App password + `http` with `Authorization: Bearer` |\n| `dev.azure.com` or `*.visualstudio.com` | Azure DevOps | `az` + GCM | `az login` | PAT + `http` with Basic auth |\n| Gitea instances | Gitea | `tea` (optional) | `tea login add` | PAT + `http` with `Authorization: token` |\n| Unknown or custom domain | Ask user which platform | N/A | N/A | Probe `http` or ask before assuming generic Git |\n\n> **Note:** Platform CLIs (`gh`, `glab`, `az`, `tea`) are native binaries, not npm packages. Do NOT use `npx` to install them — it will fail or install unrelated/unofficial packages. When the CLI is unavailable, use the No-CLI Alternative column.\n\n## GitHub / GitHub Enterprise\n\n- CLI: `gh auth login` uses a browser or device code flow and can open the browser automatically.\n- GitHub Enterprise CLI: `gh auth login --hostname <host>`.\n- PAT creation: `https://github.com/settings/tokens` for classic tokens.\n- PAT creation: `https://github.com/settings/personal-access-tokens` for fine-grained tokens.\n- Minimum scopes: `repo` for classic PATs (NOTE: `repo` grants read and write — prefer fine-grained PATs with `Contents: Read` for read-only access).\n- Minimum scopes: `Contents: Read` for fine-grained PATs.\n- SSH: `git@github.com:owner/repo.git`.\n- Credential helper: `gh auth setup-git` configures Git to use the GitHub credential flow.\n- Note: Fine-grained PATs may not cover organization-level access or every repo path; classic PATs are still required for some org repos.\n- SAML SSO: PATs often require explicit org authorization from `https://github.com/settings/tokens` after creation.\n- Enterprise note: PAT URLs and token policy can vary by host; reuse the same auth pattern with the enterprise hostname and instance settings pages.\n- Enterprise detection: GHE instances use fully custom domains (e.g. `ghe.coxautoinc.com`, `github.acme.com`). If unsure, probe `https://<host>/api/v3` — a GitHub Enterprise instance returns a JSON response with `installed_version`. Use `gh auth login --hostname <host>` with any custom GHE domain.\n\n## GitLab / GitLab Self-Managed\n\n- CLI: `glab auth login` uses a browser-backed OAuth flow.\n- Self-managed CLI: `glab auth login --hostname <host>`.\n- PAT creation: `https://gitlab.com/-/user_settings/personal_access_tokens`.\n- Minimum scopes: `read_repository`.\n- SSH: `git@gitlab.com:owner/repo.git`.\n- Credential helper: `glab auth setup-git` configures Git credential handling.\n- Note: If 2FA is enabled, username/password Git auth is blocked; a PAT is mandatory for HTTPS auth.\n- Self-managed note: PAT URL is typically `https://<host>/-/user_settings/personal_access_tokens` unless the instance customizes settings paths.\n\n## Bitbucket Cloud\n\n- CLI: No official first-party CLI OAuth flow for repo auth.\n- PAT/App Password creation: `https://bitbucket.org/{workspace}/settings/app-passwords`.\n- Minimum permissions: `Repositories: Read`.\n- SSH: `git@bitbucket.org:owner/repo.git`.\n- Note: Bitbucket Cloud uses App Passwords rather than standard PAT terminology.\n- Note: HTTPS auth requires both the Bitbucket username and the app password, delivered through a credential helper or `GIT_ASKPASS` script — never embedded in the clone URL.\n\n## Azure DevOps\n\n- CLI: `az login` authenticates to Microsoft Entra ID; Git Credential Manager then handles Git credentials automatically.\n- PAT-based auth remains the fallback when Entra ID or GCM is unavailable.\n- PAT creation: `https://dev.azure.com/{org}/_usersSettings/tokens`.\n- Minimum scopes: `Code: Read`.\n- SSH: `git@ssh.dev.azure.com:v3/{org}/{project}/{repo}`.\n- Note: Microsoft Entra ID tokens are generally preferred over PATs in enterprise environments.\n- Credential helper: Git Credential Manager via `git-credential-manager configure`.\n- Legacy host note: Azure DevOps may also appear under `*.visualstudio.com` URLs.\n\n## Gitea / Forgejo\n\n- CLI: `tea login add` is available but optional and not universally installed.\n- PAT creation: `https://{host}/user/settings/applications`.\n- Minimum scopes: `repo`.\n- SSH: `git@{host}:owner/repo.git`.\n- Note: Forgejo commonly mirrors the same applications-token path and PAT model as Gitea.\n- Note: Some self-hosted instances rename scopes or disable API token creation, so confirm the instance policy if `repo` is rejected.\n\n## Generic Git (Self-Hosted)\n\n- Platform CLI: None assumed.\n- Auth path: Prefer SSH keys first, then PAT if the host documents HTTPS token auth.\n- PAT creation: Ask the user for the platform's PAT or application-token settings URL.\n- SSH: Use the host's documented SSH remote format; do not assume GitHub-style shortcuts if the server advertises a different pattern.\n\n## API File-Read Endpoints (for web-based code access)\n\nWhen agents need to read individual files without cloning, use these authenticated API endpoints.\n\n### GitHub / GitHub Enterprise\n\n```text\n# Read file contents (returns JSON with base64 content)\nGET https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={branch}\nAuthorization: token <PAT>\n\n# GHE: replace api.github.com with <ghe-host>/api/v3\nGET https://<ghe-host>/api/v3/repos/{owner}/{repo}/contents/{path}?ref={branch}\n\n# Or use gh CLI (auto-authenticated):\ngh api repos/{owner}/{repo}/contents/{path}?ref={branch} --jq '.content' | base64 -d\n```\n\n### GitLab / GitLab Self-Managed\n\n```text\n# URL-encode the file path (/ becomes %2F)\nGET https://gitlab.com/api/v4/projects/{project-id}/repository/files/{url-encoded-path}/raw?ref={branch}\nPRIVATE-TOKEN: <PAT>\n\n# Or use project path instead of ID:\nGET https://gitlab.com/api/v4/projects/{url-encoded-namespace%2Fproject}/repository/files/{url-encoded-path}/raw?ref={branch}\n```\n\n### Azure DevOps\n\n```text\nGET https://dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items?path={path}&api-version=7.0\nAuthorization: Basic {base64(:PAT)}\n```\n\n### Bitbucket Cloud\n\n```text\nGET https://api.bitbucket.org/2.0/repositories/{workspace}/{repo}/src/{commit-or-branch}/{path}\nAuthorization: Bearer <app-password-or-token>\n```\n- Note: Self-hosted products often customize auth policy, token names, and minimum scopes.\n\n## Safe Credential Delivery Patterns\n\n| Method | Command | Safety |\n|---|---|---|\n| Platform CLI | `gh auth login` / `glab auth login` | Best — handles credential storage |\n| Git Credential Manager | `git credential-manager configure` | Good — OS keychain storage |\n| Environment variable | `GH_TOKEN=xxx gh repo clone ...` | OK — ephemeral; safer than URL tokens but visible to same-user processes |\n| Git askpass | `GIT_ASKPASS=script git clone ...` | OK — no shell history exposure |\n| Inline in URL | `git clone https://token@host/...` | FORBIDDEN — leaks in history/logs |\n\n## Operational Notes\n\n- Prefer SSH when the user already has working keys and the host advertises a stable SSH remote format.\n- Prefer platform CLI login for GitHub and GitLab because it also wires Git credential storage.\n- Prefer Git Credential Manager for Azure DevOps and other HTTPS-heavy enterprise setups.\n- When recommending PAT creation, always suggest setting a short expiry (7-30 days for task-specific work). Prefer fine-grained or short-lived tokens.\n- Never recommend pasting tokens inline into clone URLs, scripts checked into the repo, or long-lived shell profiles."},{file:`SKILL.md`,content:'---\nname: repo-access\ndescription: "Progressive repository access recovery for private and enterprise git repositories. Triggered when: (1) git clone/fetch/pull fails with auth errors (401, 403, 404, Permission denied), (2) web_fetch or http tool returns auth failure on repository URLs, (3) user mentions private repo, enterprise repo, or internal repo, (4) user asks to access code from GitHub Enterprise, GitLab Self-Managed, Bitbucket Server, Azure DevOps. Guides through 5-step progressive strategy: anonymous HTTPS, SSH keys, CLI OAuth, PAT, local clone fallback."\nmetadata:\n category: cross-cutting\n domain: general\n applicability: on-demand\n inputs: [git-error, repository-url, platform-context]\n outputs: [authenticated-access, recovery-instructions]\n requires: []\n relatedSkills: [aikit]\nargument-hint: "Repository URL or error message"\n---\n\n# Repository Access Recovery\n\nProgressively recover repository access for private, enterprise, and internal git hosts without leaking credentials.\n\n## When to Activate\n\n### Reactive triggers\n\n- `git clone`, `git fetch`, or `git pull` fails with `401`, `403`, `404`, `Authentication failed`, or `Permission denied (publickey)`.\n- `http` diagnostics against a repo endpoint show auth failure or ambiguous private-repo responses.\n- `web_fetch` returns login page HTML, SSO redirect, "Sign in", "Page not found", or empty/truncated content for a repo URL.\n- Any tool output contains "behind SSO", "SSO required", "SAML", "requires authentication", or similar auth-gate language about a repository.\n- A repository URL works in a browser for the user but fails from agent tools or terminal commands.\n- **You are about to declare a repo "inaccessible" or "unreachable"** — STOP and activate this skill first.\n\n### Proactive triggers\n\n- The user says the repo is private, enterprise, self-managed, internal, or SSO-protected.\n- The repo is hosted on GitHub Enterprise, GitLab Self-Managed, Bitbucket Server/Data Center, Azure DevOps, Gitea, or another custom git host.\n- The environment may need browser sign-in, SSH agent setup, or token-based recovery before any code access can work.\n\n## When NOT to Activate\n\n- Public repositories that already clone or read successfully over HTTPS.\n- Local-only repositories where no remote auth is involved.\n- Problems caused by branch protection, merge conflicts, or rate limiting rather than repository access.\n\n## Step 0: Platform Detection & Capability Gate\n\nDetect platform from the URL, then decide what recovery options are possible in this environment.\n\n| URL pattern | Platform |\n| --- | --- |\n| `github.com`, or any GHE host (e.g. `ghe.*`, `github.*`, custom domain) | GitHub / GitHub Enterprise |\n| `gitlab.com`, `gitlab.<corp-host>` | GitLab / GitLab Self-Managed |\n| `bitbucket.org`, `bitbucket.<corp-host>` | Bitbucket Cloud / Server |\n| `dev.azure.com`, `visualstudio.com`, `/_git/` | Azure DevOps |\n| anything else with git over HTTPS/SSH | Unknown — ask the user which platform before assuming generic Git |\n\n- Capability gate: has terminal, has browser, or conversation-only.\n- If terminal is unavailable, skip directly to PAT guidance or local clone fallback.\n- If browser is unavailable, prefer SSH or pre-created credentials over CLI OAuth.\n- If only the `http` tool is available (no terminal, no CLI): use PAT + authenticated API reads (see "Web-Based Code Access" below). This is the zero-dependency path — no `gh`, `glab`, or `az` installation needed.\n\nFor platform-specific details, read `references/platform-matrix.md`.\n\n## Strategy Ladder\n\n### Step 1: Try HTTPS Anonymous Access\n\n- Goal: prove the repo is public or already reachable without extra auth.\n- What to do: normalize the remote to an HTTPS URL and run `git ls-remote https://...`. If it succeeds, use HTTPS and stop. If it fails with auth-like errors, continue instead of assuming the repo is missing.\n- Verify: `git ls-remote <url>`; SUCCESS -> stop, FAIL -> Step 2.\n\n### Step 2: Check Existing SSH Keys\n\n- Goal: reuse working SSH credentials before asking for new secrets.\n- What to do: inspect `~/.ssh/` for key files, run `ssh-add -l`, then test host auth with `ssh -T git@{host}`. If SSH works, switch the remote to the SSH URL and continue with that transport.\n- Verify: `git ls-remote <ssh-url>`; SUCCESS -> stop, FAIL -> Step 3.\n\n### Step 3: Platform CLI OAuth\n\n- Goal: use the platform\'s interactive login flow with stored credentials.\n- What to do: check whether the matching CLI exists, for example `which gh`, `which glab`, or `which az` (or platform equivalent). If installed, run `{cli} auth login` and let it complete browser or device OAuth, then retry git access.\n- **If the CLI is not installed**: do NOT try `npx` — platform CLIs (`gh`, `glab`, `az`) are native binaries, not npm packages. Skip straight to Step 4 (PAT). For file-read-only tasks, the `http` tool with a PAT header is a zero-dependency alternative to any CLI.\n- Verify: `git ls-remote <url>`; SUCCESS -> stop, FAIL -> Step 4.\n\n### Step 4: Personal Access Token\n\n- Goal: recover access when SSH and CLI OAuth are unavailable or blocked.\n- What to do: ask the user to create a PAT or app password at the platform-specific URL with minimum read scopes only. Have the user provide it through an env var or credential helper, then configure git credentials without embedding the token in the remote URL.\n- Verify: `git ls-remote <url>`; SUCCESS -> stop, FAIL -> Step 5.\n\n### Step 5: Local Clone Fallback\n\n- Goal: unblock work when remote auth cannot be completed from the current environment.\n- What to do: ask the user to clone the repository on their machine using their normal workflow, then provide the local filesystem path. Use the local checkout as the source of truth for code access.\n- Verify: local repo exists and `git rev-parse --show-toplevel` succeeds; SUCCESS -> stop.\n\n## Security Rules (HARD GATE)\n\n- NEVER include a PAT in a git URL; it leaks into shell history, process lists, logs, and config.\n- NEVER repeat a user\'s token value in chat output, summaries, examples, or when relaying tool output that may contain credentials.\n- Use env vars, credential helpers, or platform login tools for token delivery.\n- Recommend minimum scopes only: read-only repo scopes, not broad write/admin scopes.\n- Prefer ephemeral credentials, OAuth/device flows, or short-lived tokens over long-lived PATs.\n- When guiding PAT creation, recommend the shortest feasible expiry (7–30 days for task-specific work).\n\n## After Access Is Established\n\n- Remind the user to revoke single-use PATs once the task is complete.\n- If credentials were stored via a credential helper, note that they persist until manually removed or the token expires.\n\n## Web-Based Code Access (web_fetch / http)\n\nAgents often use `web_fetch` or `http` to read individual files without a full clone. These requests fail silently on private repos — GitHub returns `404` or login HTML, not an auth error.\n\n### Common URL Patterns That Fail on Private Repos\n\n| URL Pattern | Platform | What Happens |\n|---|---|---|\n| `raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}` | GitHub | `404` — no auth header accepted |\n| `github.com/{owner}/{repo}/blob/{ref}/{path}` | GitHub web view | `200` with login HTML, not code |\n| `api.github.com/repos/{owner}/{repo}/contents/{path}` | GitHub API | `404` (the GitHub 404 trap) |\n| `<ghe-host>/{owner}/{repo}/*` (any GHE URL) | GitHub Enterprise | `200` with SAML SSO redirect page — body contains "Initiating SAML single sign-on" and redirect to `login.microsoftonline.com` or other IdP |\n| `gitlab.com/{owner}/{repo}/-/raw/{ref}/{path}` | GitLab | `401` or login redirect |\n| `dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items` | Azure DevOps | `401` or `203` non-authoritative |\n\n### SAML SSO Detection (CRITICAL)\n\nGHE instances with SAML SSO return `200 OK` with an HTML body that is NOT the requested content. **This is the most common false-"inaccessible" scenario.** Detect it by checking `web_fetch` output for ANY of these strings:\n\n- `Initiating SAML single sign-on`\n- `login.microsoftonline.com` (Azure AD / Entra ID)\n- `You are being redirected to your identity provider`\n- `/login?return_to=`\n- `SAMLRequest=`\n- `RelayState=`\n\nIf ANY of these appear → the repo exists and is accessible, it just needs authentication. This is NOT "inaccessible" — follow the Strategy Ladder.\n\n### Recovery: Authenticated API Reads\n\nWhen `web_fetch` fails on a private repo URL, switch to authenticated `http` calls:\n\n1. **Ensure auth is established first** — walk the Strategy Ladder (Steps 1-4) to get working credentials.\n2. **Use the platform API with auth headers**, not raw/web URLs:\n\n| Platform | Authenticated file-read endpoint | Auth header |\n|---|---|---|\n| GitHub / GHE | `http GET https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={branch}` | `Authorization: token <PAT>` or use `gh api` |\n| GitLab | `http GET https://gitlab.com/api/v4/projects/{id}/repository/files/{path}/raw?ref={branch}` | `PRIVATE-TOKEN: <PAT>` |\n| Azure DevOps | `http GET https://dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items?path={path}&api-version=7.0` | `Authorization: Basic <base64(:PAT)>` |\n| Bitbucket | `http GET https://api.bitbucket.org/2.0/repositories/{owner}/{repo}/src/{ref}/{path}` | `Authorization: Bearer <token>` |\n\n3. **Prefer `http` over `web_fetch`** for private repos — `http` sends proper headers and returns machine-readable JSON; `web_fetch` gets HTML login pages.\n4. **For bulk reads**, prefer `git clone --depth 1` over many individual API calls — it\'s faster and avoids rate limits.\n5. **NEVER embed tokens in URLs** — use auth headers via the `http` tool or `gh api` CLI wrapper.\n\n### Quick Decision: Clone vs API Read\n\n| Situation | Preferred method |\n|---|---|\n| Need 1-3 specific files | Authenticated API via `http` |\n| Need to browse/search the repo | `git clone --depth 1` (shallow) |\n| Need file history or blame | `git clone` |\n| No terminal available | Authenticated API via `http` with PAT |\n| Rate-limited on API | `git clone --depth 1` |\n\n## Tool Routing\n\n| Tool | Use |\n| --- | --- |\n| `git_context` | Check local repo state and confirm a clone or fallback checkout is usable |\n| `http` | Probe platform APIs for auth diagnostics AND read file contents from private repos with auth headers |\n| `web_fetch` | Only for public repos or after confirming access works; unreliable for private repos (returns HTML, not code) |\n| `web_search` | Find current platform-specific auth documentation when the host is unusual or self-managed |\n| Terminal | Run git commands, SSH tests, CLI auth flows, and credential-helper setup |\n\nFor detailed error patterns, read `references/error-patterns.md`.\n\n## CRITICAL: The GitHub 404 Trap\n\nGitHub commonly returns `404 Not Found` for private repositories when the caller is unauthenticated or under-authenticated. NEVER conclude that a GitHub repository does not exist from a `404` alone. Treat that response as an authentication signal first, then walk the ladder before declaring the repo missing.'}],"requirements-clarity":[{file:`SKILL.md`,content:`---
|
|
8257
|
+
`}],"repo-access":[{file:`references/error-patterns.md`,content:'# Repo Access Error Patterns\n\nUse this reference to distinguish missing repositories from authentication and policy failures when probing Git hosts.\n\n## HTTP Status Code Matrix\n\n| Platform | No auth (private repo) | Wrong credentials | Rate limited | SSO required |\n|---|---|---|---|---|\n| GitHub REST API | `404` (TRAP!) | `401` -> `403` | `403` + rate limit body | `403` + `X-GitHub-SSO` header |\n| GitHub Web | HTML "Page not found" or login redirect | Login redirect | - | - |\n| GitLab | `401` | `401` | `429` | `401` (PAT mandatory) |\n| Bitbucket | `403` | `403` | `429` | `403` |\n| Azure DevOps | `401` | `401` | - | `401` |\n\n## CRITICAL: The GitHub 404 Trap\n\nGitHub deliberately returns `404`, not `401`, for private repositories accessed without authentication.\nThis is by design to avoid leaking whether a repository exists.\n\n- Never conclude a GitHub repository does not exist from an unauthenticated `404`.\n- `GET https://api.github.com/repos/{owner}/{repo}` without auth returns `404` for both "repo truly missing" and "repo exists but is private".\n- The only reliable disambiguation is an authenticated probe.\n- If the same request still returns `404` with valid auth, the repository is truly missing.\n\nProbe order:\n\n1. Try the authenticated API request first.\n2. If it returns `200`, access works.\n3. If it returns `404` without auth context, treat it as ambiguous and recover.\n4. If it returns `404` with known-good auth, treat the repo as missing.\n\n## Git CLI Stderr Patterns\n\n| Error Text Pattern | Platform | Diagnosis | Action |\n|---|---|---|---|\n| `remote: Repository not found.` | GitHub | Auth failure, not proof the repo is missing | Try auth strategies |\n| `git@github.com: Permission denied (publickey).` | GitHub | SSH key not recognized | Check SSH keys, try HTTPS |\n| `remote: HTTP Basic: Access denied.` | GitLab | Auth failure, 2FA likely | Use PAT; password auth is blocked with 2FA |\n| `error: The requested URL returned error: 403` | Bitbucket | Auth failure | Try app password |\n| `TF401019: The Git repository with name or identifier X does not exist` | Azure DevOps | Auth failure or missing repo | Try PAT with Code:Read scope |\n| `fatal: Authentication failed for \'https://...\'` | Any (HTTPS) | General auth failure | Escalate through the strategy ladder |\n| `Permission denied (publickey).` | Any (SSH) | SSH key not recognized | Check `~/.ssh/`, run `ssh-add`, try HTTPS |\n| `fatal: Could not read from remote repository.` | Any (SSH) | SSH access denied | Verify the SSH key is added to the platform |\n| `unable to access \'...\': SSL certificate problem` | Any | Self-signed or enterprise CA issue | Ask about local cert config; skip to local clone if needed |\n\nTreat these stderr strings as direct signals from tool output. Do not reinterpret GitHub\'s `Repository not found` as a clean existence check.\n\n## web_fetch / http Tool Detection\n\n- `web_fetch` against a private GitHub repo URL often returns HTML with "Page not found" or a login page.\n- GitHub web responses can be `200` with a 404-looking body, so `web_fetch` is unreliable for auth diagnosis.\n- `http` against the platform API gives machine-readable bodies and real status codes, so use it for probes.\n- For `web_fetch` on `github.com`, inspect the body for `Page not found`, `Sign in`, or `/login` links. If present, assume private or auth-gated access and trigger recovery.\n\nRecommended diagnostic probe:\n\n```text\nhttp GET https://api.github.com/repos/{owner}/{repo}\n-> 404 + no auth header -> might be private\n-> 401 -> explicit auth failure\n-> 200 -> repo is public, access works\n```\n\n## Edge Cases\n\n| Edge Case | Signal | Response |\n|---|---|---|\n| GitHub.com SAML SSO | `403` + `X-GitHub-SSO: required; url=...` | PAT needs SSO authorization for the org |\n| GHE SAML SSO (web_fetch) | `200` + body contains `Initiating SAML single sign-on`, redirect to `login.microsoftonline.com` or other IdP | Repo EXISTS and is auth-gated. NOT inaccessible. Use PAT + `http` with auth headers, or `gh auth login --hostname <host>` |\n| GHE SAML SSO (http) | `302` redirect to `/login?return_to=...` or IdP URL | Same — repo exists, needs auth. Walk the Strategy Ladder |\n| GHE SAML SSO (git CLI) | `fatal: Authentication failed` or credential prompt | `gh auth login --hostname <host>` or PAT via credential helper |\n\n## SAML SSO — Detailed Pattern\n\nGitHub Enterprise instances commonly use SAML SSO via Azure AD (Entra ID), Okta, or other IdPs. When `web_fetch` hits a GHE URL without auth:\n\n1. GHE returns `200 OK` (not 401/403!) with an HTML page\n2. The HTML contains `Initiating SAML single sign-on` and a redirect URL to the IdP\n3. The redirect URL includes `SAMLRequest=`, `RelayState=`, and often `login.microsoftonline.com`\n4. The agent sees HTML content and may conclude the repo is "inaccessible" or "behind SSO"\n\n**Detection strings** (check `web_fetch` output for ANY of these):\n```\nInitiating SAML single sign-on\nlogin.microsoftonline.com\nYou are being redirected to your identity provider\n/login?return_to=\nSAMLRequest=\nRelayState=\n```\n\n**Correct response:** The repo exists. The `web_fetch` path will never work for SSO-protected GHE. Switch to:\n- `gh auth login --hostname <ghe-host>` (if `gh` CLI available)\n- PAT + `http` with `Authorization: token <PAT>` against `<ghe-host>/api/v3/repos/{owner}/{repo}/contents/{path}`\n- Ask user for local clone if no token can be obtained\n| GitLab 2FA enabled | `401` on password auth | PAT is mandatory; 2FA blocks password auth |\n| Expired token | `401` after providing a valid-looking PAT | Generate a new token and check expiry |\n| GitHub rate limit | `403` + body contains `rate limit` | Not an auth failure; wait or authenticate for a higher limit |\n| IP allowlisting | `403` + body mentions IP or org policies | Cannot be fixed programmatically; skip to local clone (Step 5) |\n| Fine-grained PAT scope | `403` + `insufficient scope` | Switch to a classic PAT for org repos |\n| SSH key not in agent | `Permission denied (publickey)` + key file exists | Run `ssh-add ~/.ssh/id_ed25519` |\n| Wrong SSH username | `Permission denied` | Use `git@host`, not `username@host` |\n| Deploy key conflict | `key is already in use` | Use a user SSH key or PAT instead |\n\n## Escalation Decision Rules\n\n- Retry the same step for transient failures such as DNS failure, timeout, or `5xx` responses.\n- Escalate to the next strategy step for `401`, `403`, `404`, `Permission denied`, `Authentication failed`, or `Access denied`.\n- Skip directly to Step 5 (local clone) for IP allowlisting, enterprise SSL certificate issues, or org policy blocks.\n\nDefault interpretation order:\n\n1. Prefer API probes over web page fetches.\n2. Treat GitHub `404` as ambiguous until valid auth disproves privacy.\n3. Treat SSH `publickey` errors as key-distribution failures, not repo absence.\n4. Separate rate limits and org policy blocks from authentication failures before escalating.'},{file:`references/platform-matrix.md`,content:"# Platform Matrix\n\nUse this reference when a repository URL reveals the hosting platform and the skill needs platform-specific authentication or cloning guidance. Prefer platform CLI login flows or OS-backed credential helpers over raw PAT handling.\n\n## Platform Detection\n\n| URL Pattern | Platform | CLI Tool (optional) | Auth Command | No-CLI Alternative |\n|---|---|---|---|---|\n| `github.com` | GitHub | `gh` | `gh auth login` | PAT + `http` with `Authorization: token <PAT>` |\n| Any custom domain (e.g. `ghe.corp.com`, `github.corp.com`) | GitHub Enterprise | `gh` | `gh auth login --hostname <host>` | PAT + `http` against `<host>/api/v3` |\n| `gitlab.com` | GitLab | `glab` | `glab auth login` | PAT + `http` with `PRIVATE-TOKEN` header |\n| Self-hosted GitLab | GitLab Self-Managed | `glab` | `glab auth login --hostname <host>` | PAT + `http` with `PRIVATE-TOKEN` header |\n| `bitbucket.org` | Bitbucket Cloud | None | N/A | App password + `http` with `Authorization: Bearer` |\n| `dev.azure.com` or `*.visualstudio.com` | Azure DevOps | `az` + GCM | `az login` | PAT + `http` with Basic auth |\n| Gitea instances | Gitea | `tea` (optional) | `tea login add` | PAT + `http` with `Authorization: token` |\n| Unknown or custom domain | Ask user which platform | N/A | N/A | Probe `http` or ask before assuming generic Git |\n\n> **Note:** Platform CLIs (`gh`, `glab`, `az`, `tea`) are native binaries, not npm packages. Do NOT use `npx` to install them — it will fail or install unrelated/unofficial packages. When the CLI is unavailable, use the No-CLI Alternative column.\n\n## GitHub / GitHub Enterprise\n\n- CLI: `gh auth login` uses a browser or device code flow and can open the browser automatically.\n- GitHub Enterprise CLI: `gh auth login --hostname <host>`.\n- PAT creation: `https://github.com/settings/tokens` for classic tokens.\n- PAT creation: `https://github.com/settings/personal-access-tokens` for fine-grained tokens.\n- Minimum scopes: `repo` for classic PATs (NOTE: `repo` grants read and write — prefer fine-grained PATs with `Contents: Read` for read-only access).\n- Minimum scopes: `Contents: Read` for fine-grained PATs.\n- SSH: `git@github.com:owner/repo.git`.\n- Credential helper: `gh auth setup-git` configures Git to use the GitHub credential flow.\n- Note: Fine-grained PATs may not cover organization-level access or every repo path; classic PATs are still required for some org repos.\n- SAML SSO: PATs often require explicit org authorization from `https://github.com/settings/tokens` after creation.\n- Enterprise note: PAT URLs and token policy can vary by host; reuse the same auth pattern with the enterprise hostname and instance settings pages.\n- Enterprise detection: GHE instances use fully custom domains (e.g. `ghe.coxautoinc.com`, `github.acme.com`). If unsure, probe `https://<host>/api/v3` — a GitHub Enterprise instance returns a JSON response with `installed_version`. Use `gh auth login --hostname <host>` with any custom GHE domain.\n\n## GitLab / GitLab Self-Managed\n\n- CLI: `glab auth login` uses a browser-backed OAuth flow.\n- Self-managed CLI: `glab auth login --hostname <host>`.\n- PAT creation: `https://gitlab.com/-/user_settings/personal_access_tokens`.\n- Minimum scopes: `read_repository`.\n- SSH: `git@gitlab.com:owner/repo.git`.\n- Credential helper: `glab auth setup-git` configures Git credential handling.\n- Note: If 2FA is enabled, username/password Git auth is blocked; a PAT is mandatory for HTTPS auth.\n- Self-managed note: PAT URL is typically `https://<host>/-/user_settings/personal_access_tokens` unless the instance customizes settings paths.\n\n## Bitbucket Cloud\n\n- CLI: No official first-party CLI OAuth flow for repo auth.\n- PAT/App Password creation: `https://bitbucket.org/{workspace}/settings/app-passwords`.\n- Minimum permissions: `Repositories: Read`.\n- SSH: `git@bitbucket.org:owner/repo.git`.\n- Note: Bitbucket Cloud uses App Passwords rather than standard PAT terminology.\n- Note: HTTPS auth requires both the Bitbucket username and the app password, delivered through a credential helper or `GIT_ASKPASS` script — never embedded in the clone URL.\n\n## Azure DevOps\n\n- CLI: `az login` authenticates to Microsoft Entra ID; Git Credential Manager then handles Git credentials automatically.\n- PAT-based auth remains the fallback when Entra ID or GCM is unavailable.\n- PAT creation: `https://dev.azure.com/{org}/_usersSettings/tokens`.\n- Minimum scopes: `Code: Read`.\n- SSH: `git@ssh.dev.azure.com:v3/{org}/{project}/{repo}`.\n- Note: Microsoft Entra ID tokens are generally preferred over PATs in enterprise environments.\n- Credential helper: Git Credential Manager via `git-credential-manager configure`.\n- Legacy host note: Azure DevOps may also appear under `*.visualstudio.com` URLs.\n\n## Gitea / Forgejo\n\n- CLI: `tea login add` is available but optional and not universally installed.\n- PAT creation: `https://{host}/user/settings/applications`.\n- Minimum scopes: `repo`.\n- SSH: `git@{host}:owner/repo.git`.\n- Note: Forgejo commonly mirrors the same applications-token path and PAT model as Gitea.\n- Note: Some self-hosted instances rename scopes or disable API token creation, so confirm the instance policy if `repo` is rejected.\n\n## Generic Git (Self-Hosted)\n\n- Platform CLI: None assumed.\n- Auth path: Prefer SSH keys first, then PAT if the host documents HTTPS token auth.\n- PAT creation: Ask the user for the platform's PAT or application-token settings URL.\n- SSH: Use the host's documented SSH remote format; do not assume GitHub-style shortcuts if the server advertises a different pattern.\n\n## API File-Read Endpoints (for web-based code access)\n\nWhen agents need to read individual files without cloning, use these authenticated API endpoints.\n\n### GitHub / GitHub Enterprise\n\n```text\n# Read file contents (returns JSON with base64 content)\nGET https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={branch}\nAuthorization: token <PAT>\n\n# GHE: replace api.github.com with <ghe-host>/api/v3\nGET https://<ghe-host>/api/v3/repos/{owner}/{repo}/contents/{path}?ref={branch}\n\n# Or use gh CLI (auto-authenticated):\ngh api repos/{owner}/{repo}/contents/{path}?ref={branch} --jq '.content' | base64 -d\n```\n\n### GitLab / GitLab Self-Managed\n\n```text\n# URL-encode the file path (/ becomes %2F)\nGET https://gitlab.com/api/v4/projects/{project-id}/repository/files/{url-encoded-path}/raw?ref={branch}\nPRIVATE-TOKEN: <PAT>\n\n# Or use project path instead of ID:\nGET https://gitlab.com/api/v4/projects/{url-encoded-namespace%2Fproject}/repository/files/{url-encoded-path}/raw?ref={branch}\n```\n\n### Azure DevOps\n\n```text\nGET https://dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items?path={path}&api-version=7.0\nAuthorization: Basic {base64(:PAT)}\n```\n\n### Bitbucket Cloud\n\n```text\nGET https://api.bitbucket.org/2.0/repositories/{workspace}/{repo}/src/{commit-or-branch}/{path}\nAuthorization: Bearer <app-password-or-token>\n```\n- Note: Self-hosted products often customize auth policy, token names, and minimum scopes.\n\n## Safe Credential Delivery Patterns\n\n| Method | Command | Safety |\n|---|---|---|\n| Platform CLI | `gh auth login` / `glab auth login` | Best — handles credential storage |\n| Git Credential Manager | `git credential-manager configure` | Good — OS keychain storage |\n| Environment variable | `GH_TOKEN=xxx gh repo clone ...` | OK — ephemeral; safer than URL tokens but visible to same-user processes |\n| Git askpass | `GIT_ASKPASS=script git clone ...` | OK — no shell history exposure |\n| Inline in URL | `git clone https://token@host/...` | FORBIDDEN — leaks in history/logs |\n\n## Operational Notes\n\n- Prefer SSH when the user already has working keys and the host advertises a stable SSH remote format.\n- Prefer platform CLI login for GitHub and GitLab because it also wires Git credential storage.\n- Prefer Git Credential Manager for Azure DevOps and other HTTPS-heavy enterprise setups.\n- When recommending PAT creation, always suggest setting a short expiry (7-30 days for task-specific work). Prefer fine-grained or short-lived tokens.\n- Never recommend pasting tokens inline into clone URLs, scripts checked into the repo, or long-lived shell profiles."},{file:`SKILL.md`,content:'---\nname: repo-access\ndescription: "Progressive repository access recovery for private and enterprise git repositories. Triggered when: (1) git clone/fetch/pull fails with auth errors (401, 403, 404, Permission denied), (2) web_fetch or http tool returns auth failure on repository URLs, (3) user mentions private repo, enterprise repo, or internal repo, (4) user asks to access code from GitHub Enterprise, GitLab Self-Managed, Bitbucket Server, Azure DevOps. Guides through 6-step progressive strategy: anonymous HTTPS, SSH keys, CLI OAuth, PAT, local clone fallback, browser-based auth recovery (via browser-use skill)."\nmetadata:\n category: cross-cutting\n domain: general\n applicability: on-demand\n inputs: [git-error, repository-url, platform-context]\n outputs: [authenticated-access, recovery-instructions]\n requires: []\n relatedSkills: [aikit]\nargument-hint: "Repository URL or error message"\n---\n\n# Repository Access Recovery\n\nProgressively recover repository access for private, enterprise, and internal git hosts without leaking credentials.\n\n## When to Activate\n\n### Reactive triggers\n\n- `git clone`, `git fetch`, or `git pull` fails with `401`, `403`, `404`, `Authentication failed`, or `Permission denied (publickey)`.\n- `http` diagnostics against a repo endpoint show auth failure or ambiguous private-repo responses.\n- `web_fetch` returns login page HTML, SSO redirect, "Sign in", "Page not found", or empty/truncated content for a repo URL.\n- Any tool output contains "behind SSO", "SSO required", "SAML", "requires authentication", or similar auth-gate language about a repository.\n- A repository URL works in a browser for the user but fails from agent tools or terminal commands.\n- **You are about to declare a repo "inaccessible" or "unreachable"** — STOP and activate this skill first.\n\n### Proactive triggers\n\n- The user says the repo is private, enterprise, self-managed, internal, or SSO-protected.\n- The repo is hosted on GitHub Enterprise, GitLab Self-Managed, Bitbucket Server/Data Center, Azure DevOps, Gitea, or another custom git host.\n- The environment may need browser sign-in, SSH agent setup, or token-based recovery before any code access can work.\n\n## When NOT to Activate\n\n- Public repositories that already clone or read successfully over HTTPS.\n- Local-only repositories where no remote auth is involved.\n- Problems caused by branch protection, merge conflicts, or rate limiting rather than repository access.\n\n## Step 0: Platform Detection & Capability Gate\n\nDetect platform from the URL, then decide what recovery options are possible in this environment.\n\n| URL pattern | Platform |\n| --- | --- |\n| `github.com`, or any GHE host (e.g. `ghe.*`, `github.*`, custom domain) | GitHub / GitHub Enterprise |\n| `gitlab.com`, `gitlab.<corp-host>` | GitLab / GitLab Self-Managed |\n| `bitbucket.org`, `bitbucket.<corp-host>` | Bitbucket Cloud / Server |\n| `dev.azure.com`, `visualstudio.com`, `/_git/` | Azure DevOps |\n| anything else with git over HTTPS/SSH | Unknown — ask the user which platform before assuming generic Git |\n\n- Capability gate: has terminal, has browser, or conversation-only.\n- If terminal is unavailable, skip directly to PAT guidance or local clone fallback.\n- If browser is unavailable, prefer SSH or pre-created credentials over CLI OAuth.\n- If only the `http` tool is available (no terminal, no CLI): use PAT + authenticated API reads (see "Web-Based Code Access" below). This is the zero-dependency path — no `gh`, `glab`, or `az` installation needed.\n\nFor platform-specific details, read `references/platform-matrix.md`.\n\n## Strategy Ladder\n\n### Step 1: Try HTTPS Anonymous Access\n\n- Goal: prove the repo is public or already reachable without extra auth.\n- What to do: normalize the remote to an HTTPS URL and run `git ls-remote https://...`. If it succeeds, use HTTPS and stop. If it fails with auth-like errors, continue instead of assuming the repo is missing.\n- Verify: `git ls-remote <url>`; SUCCESS -> stop, FAIL -> Step 2.\n\n### Step 2: Check Existing SSH Keys\n\n- Goal: reuse working SSH credentials before asking for new secrets.\n- What to do: inspect `~/.ssh/` for key files, run `ssh-add -l`, then test host auth with `ssh -T git@{host}`. If SSH works, switch the remote to the SSH URL and continue with that transport.\n- Verify: `git ls-remote <ssh-url>`; SUCCESS -> stop, FAIL -> Step 3.\n\n### Step 3: Platform CLI OAuth\n\n- Goal: use the platform\'s interactive login flow with stored credentials.\n- What to do: check whether the matching CLI exists, for example `which gh`, `which glab`, or `which az` (or platform equivalent). If installed, run `{cli} auth login` and let it complete browser or device OAuth, then retry git access.\n- **If the CLI is not installed**: do NOT try `npx` — platform CLIs (`gh`, `glab`, `az`) are native binaries, not npm packages. Skip straight to Step 4 (PAT). For file-read-only tasks, the `http` tool with a PAT header is a zero-dependency alternative to any CLI.\n- Verify: `git ls-remote <url>`; SUCCESS -> stop, FAIL -> Step 4.\n\n### Step 4: Personal Access Token\n\n- Goal: recover access when SSH and CLI OAuth are unavailable or blocked.\n- What to do: ask the user to create a PAT or app password at the platform-specific URL with minimum read scopes only. Have the user provide it through an env var or credential helper, then configure git credentials without embedding the token in the remote URL.\n- Verify: `git ls-remote <url>`; SUCCESS -> stop, FAIL -> Step 5.\n\n### Step 5: Local Clone Fallback\n\n- Goal: unblock work when remote auth cannot be completed from the current environment.\n- What to do: ask the user to clone the repository on their machine using their normal workflow, then provide the local filesystem path. Use the local checkout as the source of truth for code access.\n- Verify: local repo exists and `git rev-parse --show-toplevel` succeeds; SUCCESS -> stop, FAIL -> Step 6.\n\n### Step 6: Browser-Based Auth Recovery\n\n- Goal: use Playwright MCP browser tools to authenticate through login walls, SAML SSO, or OAuth flows that block all CLI paths.\n- Prerequisite: **load the `browser-use` skill** before proceeding.\n- What to do:\n 1. `open_browser_page({ url: repoUrl })` — open the target resource in the browser.\n 2. `read_page({ pageId })` — check if login form, SSO redirect, or content appears.\n 3. If SSO/OAuth login form → interact using `click_element`, `type_in_page` (ask user for credentials, NEVER guess).\n 4. If 2FA prompt → ask user for code via elicitation → `type_in_page` to enter it.\n 5. Once authenticated → extract content via `read_page` or `run_playwright_code`.\n 6. For ongoing CLI access → extract session cookies:\n ```javascript\n const cookies = await page.context().cookies()\n return cookies.filter(c => c.name.includes(\'session\') || c.name.includes(\'auth\'))\n ```\n 7. Use extracted cookies with the `http` tool: `http({ url, headers: { Cookie: \'...\' } })`.\n- Verify: content is accessible via browser tools; SUCCESS -> stop.\n- If browser-based auth also fails → the resource genuinely requires manual user intervention outside the agent workflow. Inform the user.\n\n> **Security:** Never store extracted cookies in code, commits, or logs. Warn the user that cookies are auth tokens that expire.\n\n## Security Rules (HARD GATE)\n\n- NEVER include a PAT in a git URL; it leaks into shell history, process lists, logs, and config.\n- NEVER repeat a user\'s token value in chat output, summaries, examples, or when relaying tool output that may contain credentials.\n- Use env vars, credential helpers, or platform login tools for token delivery.\n- Recommend minimum scopes only: read-only repo scopes, not broad write/admin scopes.\n- Prefer ephemeral credentials, OAuth/device flows, or short-lived tokens over long-lived PATs.\n- When guiding PAT creation, recommend the shortest feasible expiry (7–30 days for task-specific work).\n\n## After Access Is Established\n\n- Remind the user to revoke single-use PATs once the task is complete.\n- If credentials were stored via a credential helper, note that they persist until manually removed or the token expires.\n\n## Web-Based Code Access (web_fetch / http)\n\nAgents often use `web_fetch` or `http` to read individual files without a full clone. These requests fail silently on private repos — GitHub returns `404` or login HTML, not an auth error.\n\n### Common URL Patterns That Fail on Private Repos\n\n| URL Pattern | Platform | What Happens |\n|---|---|---|\n| `raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}` | GitHub | `404` — no auth header accepted |\n| `github.com/{owner}/{repo}/blob/{ref}/{path}` | GitHub web view | `200` with login HTML, not code |\n| `api.github.com/repos/{owner}/{repo}/contents/{path}` | GitHub API | `404` (the GitHub 404 trap) |\n| `<ghe-host>/{owner}/{repo}/*` (any GHE URL) | GitHub Enterprise | `200` with SAML SSO redirect page — body contains "Initiating SAML single sign-on" and redirect to `login.microsoftonline.com` or other IdP |\n| `gitlab.com/{owner}/{repo}/-/raw/{ref}/{path}` | GitLab | `401` or login redirect |\n| `dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items` | Azure DevOps | `401` or `203` non-authoritative |\n\n### SAML SSO Detection (CRITICAL)\n\nGHE instances with SAML SSO return `200 OK` with an HTML body that is NOT the requested content. **This is the most common false-"inaccessible" scenario.** Detect it by checking `web_fetch` output for ANY of these strings:\n\n- `Initiating SAML single sign-on`\n- `login.microsoftonline.com` (Azure AD / Entra ID)\n- `You are being redirected to your identity provider`\n- `/login?return_to=`\n- `SAMLRequest=`\n- `RelayState=`\n\nIf ANY of these appear → the repo exists and is accessible, it just needs authentication. This is NOT "inaccessible" — follow the Strategy Ladder.\n\n### Recovery: Authenticated API Reads\n\nWhen `web_fetch` fails on a private repo URL, switch to authenticated `http` calls:\n\n1. **Ensure auth is established first** — walk the Strategy Ladder (Steps 1-4) to get working credentials.\n2. **Use the platform API with auth headers**, not raw/web URLs:\n\n| Platform | Authenticated file-read endpoint | Auth header |\n|---|---|---|\n| GitHub / GHE | `http GET https://api.github.com/repos/{owner}/{repo}/contents/{path}?ref={branch}` | `Authorization: token <PAT>` or use `gh api` |\n| GitLab | `http GET https://gitlab.com/api/v4/projects/{id}/repository/files/{path}/raw?ref={branch}` | `PRIVATE-TOKEN: <PAT>` |\n| Azure DevOps | `http GET https://dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/items?path={path}&api-version=7.0` | `Authorization: Basic <base64(:PAT)>` |\n| Bitbucket | `http GET https://api.bitbucket.org/2.0/repositories/{owner}/{repo}/src/{ref}/{path}` | `Authorization: Bearer <token>` |\n\n3. **Prefer `http` over `web_fetch`** for private repos — `http` sends proper headers and returns machine-readable JSON; `web_fetch` gets HTML login pages.\n4. **For bulk reads**, prefer `git clone --depth 1` over many individual API calls — it\'s faster and avoids rate limits.\n5. **NEVER embed tokens in URLs** — use auth headers via the `http` tool or `gh api` CLI wrapper.\n\n### Quick Decision: Clone vs API Read\n\n| Situation | Preferred method |\n|---|---|\n| Need 1-3 specific files | Authenticated API via `http` |\n| Need to browse/search the repo | `git clone --depth 1` (shallow) |\n| Need file history or blame | `git clone` |\n| No terminal available | Authenticated API via `http` with PAT |\n| Rate-limited on API | `git clone --depth 1` |\n\n## Tool Routing\n\n| Tool | Use |\n| --- | --- |\n| `git_context` | Check local repo state and confirm a clone or fallback checkout is usable |\n| `http` | Probe platform APIs for auth diagnostics AND read file contents from private repos with auth headers |\n| `web_fetch` | Only for public repos or after confirming access works; unreliable for private repos (returns HTML, not code) |\n| `web_search` | Find current platform-specific auth documentation when the host is unusual or self-managed |\n| Terminal | Run git commands, SSH tests, CLI auth flows, and credential-helper setup |\n\nFor detailed error patterns, read `references/error-patterns.md`.\n\n## CRITICAL: The GitHub 404 Trap\n\nGitHub commonly returns `404 Not Found` for private repositories when the caller is unauthenticated or under-authenticated. NEVER conclude that a GitHub repository does not exist from a `404` alone. Treat that response as an authentication signal first, then walk the ladder before declaring the repo missing.'}],"requirements-clarity":[{file:`SKILL.md`,content:`---
|
|
8258
8258
|
name: requirements-clarity
|
|
8259
8259
|
description: Clarify ambiguous requirements through focused dialogue before implementation. Use when requirements are unclear, features are complex (>2 days), or involve cross-team coordination. Ask two core questions - Why? (YAGNI check) and Simpler? (KISS check) - to ensure clarity before coding.
|
|
8260
8260
|
metadata:
|
|
@@ -10332,4 +10332,442 @@ When writing TypeScript:
|
|
|
10332
10332
|
5. **Import style?** → \`import type\` for types. Direct imports, not barrel files. Named exports, not default.
|
|
10333
10333
|
6. **Error handling?** → Result pattern for expected errors. throw for unexpected/programmer errors.
|
|
10334
10334
|
7. **Async?** → Promise.all for parallel. AbortController for timeouts. AsyncGenerator for streams.
|
|
10335
|
+
`}],"browser-use":[{file:`SKILL.md`,content:`---
|
|
10336
|
+
name: browser-use
|
|
10337
|
+
description: "Browser automation for AI agents using Playwright MCP browser tools. Triggered when: (1) repo-access skill exhausts its Strategy Ladder and auth requires browser interaction, (2) \`web_fetch\` returns login page HTML, SAML redirect, or CAPTCHA instead of content, (3) user needs to interact with web applications (fill forms, click buttons, extract data), (4) a site requires JavaScript rendering that \`web_fetch\` cannot handle, (5) user asks to browse, scrape, test, or automate a website. Zero setup — uses tools available to any MCP client with Playwright MCP server."
|
|
10338
|
+
metadata:
|
|
10339
|
+
category: cross-cutting
|
|
10340
|
+
domain: general
|
|
10341
|
+
applicability: on-demand
|
|
10342
|
+
inputs: [url, auth-error, browser-task, login-wall]
|
|
10343
|
+
outputs: [page-content, screenshots, extracted-data, authenticated-session]
|
|
10344
|
+
requires: []
|
|
10345
|
+
relatedSkills: [repo-access, aikit]
|
|
10346
|
+
argument-hint: "URL or browser task description"
|
|
10347
|
+
---
|
|
10348
|
+
|
|
10349
|
+
# Browser Automation for AI Agents
|
|
10350
|
+
|
|
10351
|
+
Drive the Playwright MCP browser to solve authentication barriers, extract data, fill forms, and interact with web applications. This skill bridges the gap between CLI-based access (which fails on login walls, SAML SSO, CAPTCHAs) and real browser interaction.
|
|
10352
|
+
|
|
10353
|
+
**Zero setup required** — all tools are provided by the Playwright MCP server. No installs, no API keys, no user configuration.
|
|
10354
|
+
|
|
10355
|
+
## When to Activate
|
|
10356
|
+
|
|
10357
|
+
### Reactive Triggers
|
|
10358
|
+
|
|
10359
|
+
- \`repo-access\` skill exhausted its Strategy Ladder — SAML SSO, OAuth, or login walls block all CLI paths.
|
|
10360
|
+
- \`web_fetch\` returns login page HTML, SAML redirect, or CAPTCHA challenge instead of content.
|
|
10361
|
+
- \`http\` returns \`401\`/\`403\` and the user confirms they can access the resource in their browser.
|
|
10362
|
+
- Any tool output contains "CAPTCHA", "bot detection", "Cloudflare", "Please verify you are human", or similar anti-bot language.
|
|
10363
|
+
- User asks to interact with a web application (fill forms, click buttons, navigate, extract data).
|
|
10364
|
+
- User asks to take screenshots, test UI, or debug a web page.
|
|
10365
|
+
- A site requires JavaScript rendering that \`web_fetch\` cannot handle.
|
|
10366
|
+
|
|
10367
|
+
### Proactive Triggers
|
|
10368
|
+
|
|
10369
|
+
- Task involves an internal/enterprise web application with SSO.
|
|
10370
|
+
- User asks to scrape, automate, or interact with a website.
|
|
10371
|
+
- User mentions a site that requires login.
|
|
10372
|
+
|
|
10373
|
+
## When NOT to Activate
|
|
10374
|
+
|
|
10375
|
+
- Public pages that \`web_fetch\` handles fine (no login, no JS rendering needed).
|
|
10376
|
+
- API endpoints accessible via \`http\` tool with proper auth headers.
|
|
10377
|
+
- Static file downloads that work with \`http\`.
|
|
10378
|
+
- Tasks that only need \`read_page\` on an already-open browser tab.
|
|
10379
|
+
|
|
10380
|
+
## Available Browser Tools
|
|
10381
|
+
|
|
10382
|
+
All tools are provided by the Playwright MCP server — zero setup, always available:
|
|
10383
|
+
|
|
10384
|
+
| Tool | Purpose | Key Parameters |
|
|
10385
|
+
|------|---------|----------------|
|
|
10386
|
+
| \`open_browser_page\` | Open URL in the integrated browser | \`url\`, \`forceNew\` |
|
|
10387
|
+
| \`read_page\` | Get accessibility snapshot with element refs | \`pageId\` |
|
|
10388
|
+
| \`click_element\` | Click by ref, selector, or description | \`pageId\`, \`ref\`/\`selector\`, \`element\` |
|
|
10389
|
+
| \`type_in_page\` | Type text or press keys into elements | \`pageId\`, \`text\`/\`key\`, \`ref\`/\`selector\` |
|
|
10390
|
+
| \`navigate_page\` | Navigate by URL, back/forward, reload | \`pageId\`, \`url\`/\`type\` |
|
|
10391
|
+
| \`hover_element\` | Hover over elements (tooltips, menus) | \`pageId\`, \`ref\`/\`selector\` |
|
|
10392
|
+
| \`drag_element\` | Drag and drop between elements | \`pageId\`, \`fromRef\`, \`toRef\` |
|
|
10393
|
+
| \`handle_dialog\` | Respond to alerts, confirms, file choosers | \`pageId\`, \`acceptModal\` |
|
|
10394
|
+
| \`screenshot_page\` | Capture visual screenshot | \`pageId\`, \`ref\`/\`selector\` |
|
|
10395
|
+
| \`run_playwright_code\` | Run custom Playwright scripts for advanced automation | \`pageId\`, \`code\` |
|
|
10396
|
+
|
|
10397
|
+
## Core Workflow
|
|
10398
|
+
|
|
10399
|
+
Every browser interaction follows this pattern:
|
|
10400
|
+
|
|
10401
|
+
\`\`\`
|
|
10402
|
+
1. OPEN → open_browser_page({ url: "<target>" })
|
|
10403
|
+
2. READ → read_page({ pageId }) — get accessibility tree with element refs
|
|
10404
|
+
3. ACT → click_element / type_in_page / navigate_page — interact with elements
|
|
10405
|
+
4. READ → read_page({ pageId }) — verify the result
|
|
10406
|
+
5. LOOP → Repeat steps 3-4 until the task is complete
|
|
10407
|
+
\`\`\`
|
|
10408
|
+
|
|
10409
|
+
### Example: Login to a Web Application
|
|
10410
|
+
|
|
10411
|
+
\`\`\`
|
|
10412
|
+
open_browser_page({ url: "https://example.com/login" })
|
|
10413
|
+
→ Returns pageId
|
|
10414
|
+
|
|
10415
|
+
read_page({ pageId })
|
|
10416
|
+
→ Shows form with refs: @username-input, @password-input, @login-button
|
|
10417
|
+
|
|
10418
|
+
type_in_page({ pageId, ref: "@username-input", text: "user@example.com" })
|
|
10419
|
+
→ Note: ASK the user for credentials, NEVER guess
|
|
10420
|
+
|
|
10421
|
+
type_in_page({ pageId, ref: "@password-input", text: "<user-provided>" })
|
|
10422
|
+
|
|
10423
|
+
click_element({ pageId, ref: "@login-button", element: "Login button" })
|
|
10424
|
+
|
|
10425
|
+
read_page({ pageId })
|
|
10426
|
+
→ Verify: page shows dashboard/welcome content, not login form
|
|
10427
|
+
\`\`\`
|
|
10428
|
+
|
|
10429
|
+
### Example: Extract Content from Authenticated Page
|
|
10430
|
+
|
|
10431
|
+
\`\`\`
|
|
10432
|
+
open_browser_page({ url: "https://internal.company.com/docs" })
|
|
10433
|
+
|
|
10434
|
+
read_page({ pageId })
|
|
10435
|
+
→ If login wall: follow login flow (see auth patterns)
|
|
10436
|
+
→ If content visible: extract what you need
|
|
10437
|
+
|
|
10438
|
+
run_playwright_code({
|
|
10439
|
+
pageId,
|
|
10440
|
+
code: \\\`return page.evaluate(() => document.querySelector('main').innerText)\\\`
|
|
10441
|
+
})
|
|
10442
|
+
→ Returns the page text content
|
|
10443
|
+
\`\`\`
|
|
10444
|
+
|
|
10445
|
+
### Example: Fill a Form
|
|
10446
|
+
|
|
10447
|
+
\`\`\`
|
|
10448
|
+
open_browser_page({ url: "https://example.com/form" })
|
|
10449
|
+
read_page({ pageId }) → identify form fields and their refs
|
|
10450
|
+
|
|
10451
|
+
type_in_page({ pageId, ref: "@name-field", text: "John Doe" })
|
|
10452
|
+
type_in_page({ pageId, ref: "@email-field", text: "john@example.com" })
|
|
10453
|
+
click_element({ pageId, ref: "@country-select", element: "country dropdown" })
|
|
10454
|
+
click_element({ pageId, ref: "@us-option", element: "United States option" })
|
|
10455
|
+
click_element({ pageId, ref: "@submit-button", element: "Submit button" })
|
|
10456
|
+
|
|
10457
|
+
read_page({ pageId }) → verify submission success
|
|
10458
|
+
\`\`\`
|
|
10459
|
+
|
|
10460
|
+
## Advanced: run_playwright_code
|
|
10461
|
+
|
|
10462
|
+
For complex automation that basic tools can't handle, use \`run_playwright_code\`:
|
|
10463
|
+
|
|
10464
|
+
### Extract All Links
|
|
10465
|
+
\`\`\`javascript
|
|
10466
|
+
return page.evaluate(() =>
|
|
10467
|
+
Array.from(document.querySelectorAll('a[href]'))
|
|
10468
|
+
.map(a => ({ text: a.textContent.trim(), href: a.href }))
|
|
10469
|
+
.filter(l => l.text)
|
|
10470
|
+
)
|
|
10471
|
+
\`\`\`
|
|
10472
|
+
|
|
10473
|
+
### Wait for Dynamic Content
|
|
10474
|
+
\`\`\`javascript
|
|
10475
|
+
await page.waitForSelector('.results-loaded', { timeout: 10000 })
|
|
10476
|
+
return page.evaluate(() => document.querySelector('.results').innerText)
|
|
10477
|
+
\`\`\`
|
|
10478
|
+
|
|
10479
|
+
### Extract Table Data
|
|
10480
|
+
\`\`\`javascript
|
|
10481
|
+
return page.evaluate(() => {
|
|
10482
|
+
const rows = document.querySelectorAll('table tbody tr')
|
|
10483
|
+
return Array.from(rows).map(row =>
|
|
10484
|
+
Array.from(row.cells).map(cell => cell.textContent.trim())
|
|
10485
|
+
)
|
|
10486
|
+
})
|
|
10487
|
+
\`\`\`
|
|
10488
|
+
|
|
10489
|
+
### Extract Cookies (for session transfer)
|
|
10490
|
+
\`\`\`javascript
|
|
10491
|
+
const cookies = await page.context().cookies()
|
|
10492
|
+
return cookies.filter(c => c.name.includes('session') || c.name.includes('auth'))
|
|
10493
|
+
\`\`\`
|
|
10494
|
+
|
|
10495
|
+
### Scroll and Load More
|
|
10496
|
+
\`\`\`javascript
|
|
10497
|
+
let previousHeight = 0
|
|
10498
|
+
while (true) {
|
|
10499
|
+
const height = await page.evaluate(() => document.body.scrollHeight)
|
|
10500
|
+
if (height === previousHeight) break
|
|
10501
|
+
previousHeight = height
|
|
10502
|
+
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight))
|
|
10503
|
+
await page.waitForTimeout(1000)
|
|
10504
|
+
}
|
|
10505
|
+
return page.evaluate(() => document.body.innerText)
|
|
10506
|
+
\`\`\`
|
|
10507
|
+
|
|
10508
|
+
## Integration with repo-access Skill
|
|
10509
|
+
|
|
10510
|
+
This skill is the **browser escalation path** for repo-access. When repo-access cannot solve authentication via CLI strategies (Steps 1-5), browser-use provides the final recovery:
|
|
10511
|
+
|
|
10512
|
+
### Scenario: SAML SSO on GitHub Enterprise
|
|
10513
|
+
|
|
10514
|
+
1. \`repo-access\` detects SAML SSO redirect in \`web_fetch\` output
|
|
10515
|
+
2. \`repo-access\` walks Strategy Ladder — all CLI paths fail
|
|
10516
|
+
3. **Escalate to browser-use:**
|
|
10517
|
+
a. \`open_browser_page({ url: repoUrl })\` — open repo page
|
|
10518
|
+
b. \`read_page\` — check if SSO redirect appears
|
|
10519
|
+
c. If SSO login form → interact with it (user may need to provide credentials)
|
|
10520
|
+
d. If SSO auto-completes (IdP session) → page loads with repo content
|
|
10521
|
+
e. Extract content via \`read_page\` or \`run_playwright_code\`
|
|
10522
|
+
f. For git clone access: extract cookies/tokens via \`run_playwright_code\` to use in CLI
|
|
10523
|
+
|
|
10524
|
+
### Scenario: OAuth Login Flow
|
|
10525
|
+
|
|
10526
|
+
1. A service requires OAuth consent screen interaction
|
|
10527
|
+
2. \`open_browser_page({ url: oauthUrl })\` — open OAuth page
|
|
10528
|
+
3. \`read_page\` → find the "Authorize" / "Allow" button
|
|
10529
|
+
4. \`click_element\` → authorize
|
|
10530
|
+
5. \`read_page\` → URL now contains \`?code=abc123\`
|
|
10531
|
+
6. Extract the authorization code → return to CLI workflow for token exchange
|
|
10532
|
+
|
|
10533
|
+
### Scenario: 2FA / MFA Challenge
|
|
10534
|
+
|
|
10535
|
+
1. Open login page, fill credentials
|
|
10536
|
+
2. Page shows 2FA prompt
|
|
10537
|
+
3. **Ask the user** for their 2FA code (NEVER guess or bypass)
|
|
10538
|
+
4. \`type_in_page\` → enter code
|
|
10539
|
+
5. Verify login succeeded via \`read_page\`
|
|
10540
|
+
|
|
10541
|
+
### Scenario: Content Behind Login Wall
|
|
10542
|
+
|
|
10543
|
+
1. \`web_fetch\` returns login HTML instead of content
|
|
10544
|
+
2. \`open_browser_page({ url })\` → open the page
|
|
10545
|
+
3. If login form visible → guide through login (ask user for credentials)
|
|
10546
|
+
4. Once authenticated → \`read_page\` or \`run_playwright_code\` to extract content
|
|
10547
|
+
5. Content is now available without needing \`web_fetch\`
|
|
10548
|
+
|
|
10549
|
+
## Security Rules (HARD GATE)
|
|
10550
|
+
|
|
10551
|
+
- **NEVER** extract, log, or display user passwords or secrets from browser sessions.
|
|
10552
|
+
- **NEVER** screenshot pages containing visible credentials, tokens, or sensitive data.
|
|
10553
|
+
- **NEVER** automate actions the user hasn't explicitly requested (no purchasing, no sending messages, no deleting content).
|
|
10554
|
+
- **NEVER** bypass 2FA/MFA — always ask the user for codes.
|
|
10555
|
+
- **ALWAYS** ask the user for credentials rather than guessing or using stored values.
|
|
10556
|
+
- **ALWAYS** confirm before submitting forms or performing irreversible actions.
|
|
10557
|
+
- When extracting cookies via \`run_playwright_code\`, warn the user they contain auth tokens.
|
|
10558
|
+
- **NEVER** store extracted cookies in code, commits, or logs.
|
|
10559
|
+
- Close browser sessions when done if they contain authenticated state.
|
|
10560
|
+
|
|
10561
|
+
## Troubleshooting
|
|
10562
|
+
|
|
10563
|
+
| Problem | Solution |
|
|
10564
|
+
|---------|----------|
|
|
10565
|
+
| \`open_browser_page\` fails | Check the URL is valid and accessible. Try with \`forceNew: true\` |
|
|
10566
|
+
| Page shows "No active page" | The pageId is stale — re-open with \`open_browser_page\` |
|
|
10567
|
+
| Element not found by ref | Refs change on page re-render — call \`read_page\` again to get fresh refs |
|
|
10568
|
+
| Element not visible | Use \`run_playwright_code\` to scroll: \`await page.evaluate(() => window.scrollBy(0, 500))\` |
|
|
10569
|
+
| Login redirect loop | The site may need cookies from a different domain — check with \`run_playwright_code\` |
|
|
10570
|
+
| CAPTCHA appears | Ask the user to solve it manually in the browser panel, then continue |
|
|
10571
|
+
| Page loads empty/blank | Site may block headless browsers — try \`screenshot_page\` to see what rendered |
|
|
10572
|
+
| Dynamic content not loaded | Use \`run_playwright_code\` with \`page.waitForSelector\` before reading |
|
|
10573
|
+
| Form submission fails | Check for hidden fields or CSRF tokens — use \`run_playwright_code\` to inspect |
|
|
10574
|
+
| Multiple pages needed | Track multiple pageIds — \`open_browser_page\` returns unique IDs per page |
|
|
10575
|
+
|
|
10576
|
+
## Decision Flow
|
|
10577
|
+
|
|
10578
|
+
\`\`\`
|
|
10579
|
+
Need to access a web resource?
|
|
10580
|
+
├─ Public, no JS needed? → web_fetch (don't use browser)
|
|
10581
|
+
├─ Public, needs JS rendering? → open_browser_page → read_page
|
|
10582
|
+
├─ Behind login wall? → open_browser_page → login flow → extract content
|
|
10583
|
+
├─ repo-access exhausted? → browser-use is the final escalation
|
|
10584
|
+
├─ Need to fill forms/click? → open_browser_page → read_page → interact
|
|
10585
|
+
├─ Need screenshots? → open_browser_page → screenshot_page
|
|
10586
|
+
├─ CAPTCHA blocking access? → ask user to solve in browser panel
|
|
10587
|
+
└─ Complex multi-step automation? → run_playwright_code for custom scripts
|
|
10588
|
+
\`\`\`
|
|
10589
|
+
`},{file:`references/auth-patterns.md`,content:`# Browser Auth Patterns
|
|
10590
|
+
|
|
10591
|
+
Patterns for using Playwright MCP browser tools to solve authentication challenges that block CLI-based access.
|
|
10592
|
+
|
|
10593
|
+
## Pattern 1: SAML SSO Recovery
|
|
10594
|
+
|
|
10595
|
+
**Problem:** \`web_fetch\` returns SAML redirect HTML instead of content. \`repo-access\` Strategy Ladder exhausted.
|
|
10596
|
+
|
|
10597
|
+
**Solution:**
|
|
10598
|
+
\`\`\`
|
|
10599
|
+
1. Open the target URL:
|
|
10600
|
+
open_browser_page({ url: targetUrl })
|
|
10601
|
+
|
|
10602
|
+
2. Read page to check state:
|
|
10603
|
+
read_page({ pageId })
|
|
10604
|
+
→ If SSO login form: proceed to step 3
|
|
10605
|
+
→ If content already visible: skip to step 5
|
|
10606
|
+
|
|
10607
|
+
3. SSO login interaction:
|
|
10608
|
+
- Find username/email field → type_in_page({ ref, text: userEmail })
|
|
10609
|
+
- Find password field → type_in_page({ ref, text: userPassword })
|
|
10610
|
+
- Click "Sign In" → click_element({ ref, element: "Sign In button" })
|
|
10611
|
+
- NOTE: ASK the user for credentials first
|
|
10612
|
+
|
|
10613
|
+
4. Handle SSO redirect chain:
|
|
10614
|
+
- The browser will auto-follow redirects through the IdP
|
|
10615
|
+
- read_page({ pageId }) after each redirect to check state
|
|
10616
|
+
- If 2FA prompt appears → ask user for code → type_in_page
|
|
10617
|
+
|
|
10618
|
+
5. Extract content:
|
|
10619
|
+
- read_page({ pageId }) → get accessible text
|
|
10620
|
+
- Or: run_playwright_code → document.querySelector('main').innerText
|
|
10621
|
+
- Or: screenshot_page for visual content
|
|
10622
|
+
\`\`\`
|
|
10623
|
+
|
|
10624
|
+
## Pattern 2: OAuth Consent Flow
|
|
10625
|
+
|
|
10626
|
+
**Problem:** Service requires OAuth consent that can't be completed in CLI.
|
|
10627
|
+
|
|
10628
|
+
**Solution:**
|
|
10629
|
+
\`\`\`
|
|
10630
|
+
1. open_browser_page({ url: oauthAuthorizeUrl })
|
|
10631
|
+
|
|
10632
|
+
2. read_page({ pageId })
|
|
10633
|
+
→ Find the "Authorize" / "Allow" / "Grant access" button
|
|
10634
|
+
|
|
10635
|
+
3. click_element({ pageId, ref: authorizeButtonRef, element: "Authorize button" })
|
|
10636
|
+
|
|
10637
|
+
4. read_page({ pageId })
|
|
10638
|
+
→ URL now contains ?code=abc123 (the authorization code)
|
|
10639
|
+
|
|
10640
|
+
5. Extract the code:
|
|
10641
|
+
run_playwright_code({
|
|
10642
|
+
pageId,
|
|
10643
|
+
code: 'return page.url()'
|
|
10644
|
+
})
|
|
10645
|
+
→ Parse the authorization code from the URL
|
|
10646
|
+
|
|
10647
|
+
6. Return code to CLI workflow for token exchange
|
|
10648
|
+
\`\`\`
|
|
10649
|
+
|
|
10650
|
+
## Pattern 3: 2FA / MFA Challenge
|
|
10651
|
+
|
|
10652
|
+
**Problem:** Login requires 2FA code that only the user can provide.
|
|
10653
|
+
|
|
10654
|
+
**CRITICAL:** NEVER try to bypass 2FA. NEVER guess codes. ALWAYS ask the user.
|
|
10655
|
+
|
|
10656
|
+
**Solution:**
|
|
10657
|
+
\`\`\`
|
|
10658
|
+
1. Complete username/password entry (Pattern 1 steps 1-3)
|
|
10659
|
+
|
|
10660
|
+
2. read_page({ pageId })
|
|
10661
|
+
→ Page shows 2FA input field
|
|
10662
|
+
|
|
10663
|
+
3. Ask the user for their 2FA code via elicitation
|
|
10664
|
+
|
|
10665
|
+
4. type_in_page({ pageId, ref: totpInputRef, text: userProvidedCode })
|
|
10666
|
+
|
|
10667
|
+
5. click_element({ pageId, ref: verifyButtonRef, element: "Verify button" })
|
|
10668
|
+
→ Or: type_in_page({ pageId, key: "Enter" })
|
|
10669
|
+
|
|
10670
|
+
6. read_page({ pageId })
|
|
10671
|
+
→ Verify: page shows authenticated content, not login/2FA form
|
|
10672
|
+
\`\`\`
|
|
10673
|
+
|
|
10674
|
+
## Pattern 4: Cookie/Token Extraction
|
|
10675
|
+
|
|
10676
|
+
**Problem:** Need to extract auth tokens from an authenticated browser session for use in CLI tools.
|
|
10677
|
+
|
|
10678
|
+
**Solution:**
|
|
10679
|
+
\`\`\`
|
|
10680
|
+
1. Complete login flow (Patterns 1-3)
|
|
10681
|
+
|
|
10682
|
+
2. Extract cookies:
|
|
10683
|
+
run_playwright_code({
|
|
10684
|
+
pageId,
|
|
10685
|
+
code: \\\`
|
|
10686
|
+
const cookies = await page.context().cookies()
|
|
10687
|
+
return cookies.filter(c =>
|
|
10688
|
+
c.name.includes('session') ||
|
|
10689
|
+
c.name.includes('auth') ||
|
|
10690
|
+
c.name.includes('token')
|
|
10691
|
+
)
|
|
10692
|
+
\\\`
|
|
10693
|
+
})
|
|
10694
|
+
|
|
10695
|
+
3. Use extracted cookie values in http tool:
|
|
10696
|
+
http({
|
|
10697
|
+
url: apiEndpoint,
|
|
10698
|
+
headers: { "Cookie": "session=<extracted-value>" }
|
|
10699
|
+
})
|
|
10700
|
+
|
|
10701
|
+
4. WARNING: Tell the user these tokens are ephemeral and will expire.
|
|
10702
|
+
NEVER store them in code, commits, or logs.
|
|
10703
|
+
\`\`\`
|
|
10704
|
+
|
|
10705
|
+
## Pattern 5: Content Behind Login Wall
|
|
10706
|
+
|
|
10707
|
+
**Problem:** \`web_fetch\` returns a login page instead of content.
|
|
10708
|
+
|
|
10709
|
+
**Solution:**
|
|
10710
|
+
\`\`\`
|
|
10711
|
+
1. open_browser_page({ url: targetUrl })
|
|
10712
|
+
|
|
10713
|
+
2. read_page({ pageId })
|
|
10714
|
+
→ Login form visible
|
|
10715
|
+
|
|
10716
|
+
3. Ask user for credentials (NEVER guess)
|
|
10717
|
+
|
|
10718
|
+
4. Fill and submit login form:
|
|
10719
|
+
type_in_page({ pageId, ref: usernameRef, text: userEmail })
|
|
10720
|
+
type_in_page({ pageId, ref: passwordRef, text: userPassword })
|
|
10721
|
+
click_element({ pageId, ref: loginButtonRef, element: "Login button" })
|
|
10722
|
+
|
|
10723
|
+
5. Handle post-login challenges:
|
|
10724
|
+
read_page({ pageId })
|
|
10725
|
+
→ 2FA? → Pattern 3
|
|
10726
|
+
→ Consent screen? → Pattern 2
|
|
10727
|
+
→ Content visible? → Continue
|
|
10728
|
+
|
|
10729
|
+
6. Extract the content:
|
|
10730
|
+
read_page({ pageId }) → accessible text
|
|
10731
|
+
run_playwright_code → targeted extraction
|
|
10732
|
+
screenshot_page → visual capture
|
|
10733
|
+
\`\`\`
|
|
10734
|
+
|
|
10735
|
+
## Pattern 6: CAPTCHA Handling
|
|
10736
|
+
|
|
10737
|
+
**Problem:** Target site shows CAPTCHA challenge.
|
|
10738
|
+
|
|
10739
|
+
**Detection signals:**
|
|
10740
|
+
- "Checking your browser..." (Cloudflare)
|
|
10741
|
+
- reCAPTCHA / hCaptcha / Turnstile widget visible
|
|
10742
|
+
- "Please verify you are human"
|
|
10743
|
+
|
|
10744
|
+
**Solution:**
|
|
10745
|
+
\`\`\`
|
|
10746
|
+
1. open_browser_page({ url: targetUrl })
|
|
10747
|
+
|
|
10748
|
+
2. read_page({ pageId }) or screenshot_page({ pageId })
|
|
10749
|
+
→ CAPTCHA visible
|
|
10750
|
+
|
|
10751
|
+
3. ASK THE USER to solve the CAPTCHA:
|
|
10752
|
+
"A CAPTCHA challenge appeared on the page. Please solve it
|
|
10753
|
+
in the browser panel, then let me know when done."
|
|
10754
|
+
|
|
10755
|
+
4. After user confirms:
|
|
10756
|
+
read_page({ pageId })
|
|
10757
|
+
→ Content should now be accessible
|
|
10758
|
+
|
|
10759
|
+
5. If CAPTCHA reappears → the site may be aggressively blocking
|
|
10760
|
+
automation. Report to user and suggest manual access.
|
|
10761
|
+
\`\`\`
|
|
10762
|
+
|
|
10763
|
+
**Key rule:** NEVER attempt to solve CAPTCHAs programmatically. Always ask the user.
|
|
10764
|
+
|
|
10765
|
+
## Security Reminders
|
|
10766
|
+
|
|
10767
|
+
- Always ask the user for credentials — NEVER guess, infer, or reuse
|
|
10768
|
+
- Extracted cookies/tokens are SECRETS — never log, store, or commit them
|
|
10769
|
+
- Tell the user when you extract auth tokens and that they expire
|
|
10770
|
+
- Confirm before submitting forms or performing irreversible actions
|
|
10771
|
+
- Close authenticated sessions when the task is complete
|
|
10772
|
+
- Never bypass security measures (2FA, CAPTCHA, rate limits)
|
|
10335
10773
|
`}]};export{e as SKILLS};
|