diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json new file mode 100644 index 0000000..07285ba --- /dev/null +++ b/.agents/plugins/marketplace.json @@ -0,0 +1,33 @@ +{ + "name": "antonbabenko", + "interface": { + "displayName": "Agent Plugins" + }, + "plugins": [ + { + "name": "code-intelligence", + "source": { + "source": "local", + "path": "./plugins/code-intelligence" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Development" + }, + { + "name": "terraform-skill", + "source": { + "source": "url", + "url": "git@github.com:antonbabenko/terraform-skill.git", + "ref": "v1.8.0" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Development" + } + ] +} diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1fc79ff..404ebe2 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -17,7 +17,7 @@ "repo": "antonbabenko/terraform-skill", "ref": "v1.8.0" }, - "description": "Use when writing, reviewing, or debugging Terraform/OpenTofu modules, tests, CI, scans, or state ops \u2014 diagnoses failure mode (identity churn, secrets, blast radius, CI drift, state corruption) with version-aware guards.", + "description": "Use when writing, reviewing, or debugging Terraform/OpenTofu modules, tests, CI, scans, or state ops - diagnoses failure mode (identity churn, secrets, blast radius, CI drift, state corruption) with version-aware guards.", "category": "development", "keywords": [ "terraform", diff --git a/.github/workflows/automated-release.yml b/.github/workflows/automated-release.yml index f6a1535..2e95736 100644 --- a/.github/workflows/automated-release.yml +++ b/.github/workflows/automated-release.yml @@ -14,6 +14,7 @@ name: Automated Release # For each bumped plugin the workflow: # - bumps plugins[].version in marketplace.json # - syncs that plugin's SKILL.md metadata.version +# - syncs that plugin's .codex-plugin/plugin.json version (if present) # - prepends an entry to plugins//CHANGELOG.md # - tags -vX.Y.Z and creates a GitHub Release @@ -156,27 +157,60 @@ jobs: sys.exit(1) open(skill_path, 'w').writelines(lines) - # 3. plugins//CHANGELOG.md entry + # 2b. Codex per-plugin manifest version (optional - only + # inline plugins that ship a .codex-plugin/plugin.json). + codex_path = os.path.join(source, '.codex-plugin', 'plugin.json') + if os.path.isfile(codex_path): + cm = json.load(open(codex_path)) + cm['version'] = new + json.dump(cm, open(codex_path, 'w'), indent=2) + open(codex_path, 'a').write('\n') + print(f" synced {codex_path} -> {new}") + + # 3. plugins//CHANGELOG.md entry. + # Markdownlint-clean and idempotent: a stable `# Changelog` + # H1 + preamble stays on top, new version sections are + # inserted below it, single blank-line separators, `*` + # bullets only. Also repairs a previously malformed file. changelog_path = os.path.join(source, 'CHANGELOG.md') compare = '' if repo and last_tag: - compare = (f" " - f"([compare](https://github.com/{repo}/compare/" + compare = (f" ([compare](https://github.com/{repo}/compare/" f"{last_tag}...{name}-v{new}))") - section = [f"## {name}-v{new} ({date.today().isoformat()}){compare}\n\n"] + lines = [ + f"## {name}-v{new} " + f"({date.today().isoformat()}){compare}", ""] if breaking: - section.append("### BREAKING CHANGES\n\n") + lines += ["### BREAKING CHANGES", ""] if feats: - section.append("### Features\n\n") - section += [f"* {d} ({h})\n" for h, d in feats] - section.append("\n") + lines += ["### Features", ""] + lines += [f"* {d} ({h})" for h, d in feats] + lines += [""] if fixes: - section.append("### Bug Fixes\n\n") - section += [f"* {d} ({h})\n" for h, d in fixes] - section.append("\n") - entry = "".join(section) - prev = open(changelog_path).read() if os.path.exists(changelog_path) else "" - open(changelog_path, 'w').write(entry + "\n" + prev) + lines += ["### Bug Fixes", ""] + lines += [f"* {d} ({h})" for h, d in fixes] + lines += [""] + entry = "\n".join(lines).strip() + + default_header = ( + "# Changelog\n\n" + f"All notable changes to the `{name}` plugin are " + "documented here. This file is managed by the per-plugin " + "release pipeline; entries are prepended on release.") + header, body = default_header, '' + if os.path.exists(changelog_path): + old = open(changelog_path).read() + cut = old.find('## ') # first version section + if old.lstrip().startswith('# ') and cut != -1: + header = old[:cut].rstrip() + body = old[cut:].strip() + elif cut != -1: + body = old[cut:].strip() # drop stray preamble + parts = [header, "", entry] + if body: + parts += ["", body] + open(changelog_path, 'w').write( + "\n".join(parts).strip() + "\n") released.append({'name': name, 'version': new, 'tag': f'{name}-v{new}', 'notes': entry}) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 197b56c..301c23d 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -196,6 +196,16 @@ jobs: f"{name}: marketplace version {version} != " f"SKILL.md metadata.version {skill_ver}") + # Optional Codex per-plugin manifest must stay in sync. + codex_manifest = os.path.join( + src, '.codex-plugin', 'plugin.json') + if os.path.isfile(codex_manifest): + codex_ver = json.load(open(codex_manifest)).get('version') + if codex_ver != version: + errors.append( + f"{name}: marketplace version {version} != " + f".codex-plugin/plugin.json version {codex_ver}") + elif isinstance(source, dict): # External plugin: validate reference shape only. n_external += 1 diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc index 6fb5aad..5dbee56 100644 --- a/.markdownlint.jsonc +++ b/.markdownlint.jsonc @@ -9,6 +9,10 @@ // "Success Criteria", ...) under different scenario parents. Allow // duplicates when they are not siblings. "MD024": { "siblings_only": true }, + // README uses
/ for collapsible per-host install + // blocks. Allow only those two elements; all other inline HTML stays + // flagged. + "MD033": { "allowed_elements": ["details", "summary"] }, // Table pipe spacing/alignment is cosmetic and varies across the repo's // tables; not a useful signal (newer markdownlint only). "MD060": false diff --git a/CLAUDE.md b/CLAUDE.md index bdff015..d1ad42d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -74,8 +74,9 @@ newer version, bump `source.ref` and the mirrored `version` in the manifest. `description`, `version` (start at `0.1.0`), optional `category` / `keywords`. 3. Add `plugins//CHANGELOG.md` (can be empty; CI prepends to it). -4. The manifest `version` must equal the SKILL.md `metadata.version`. CI - enforces this. +4. The manifest `version` must equal the SKILL.md `metadata.version`. If the + plugin ships a `.codex-plugin/plugin.json`, its `version` must match too. + CI enforces this. 5. Add `plugins//tests/baseline-scenarios.md` - **required**, CI enforces it: at least one `## Scenario`, a `## Running These Tests` protocol, and a `### Success Criteria` list. Copy the shape of @@ -150,14 +151,15 @@ commits. - bumps `plugins[].version` in `marketplace.json`, - syncs that plugin's `SKILL.md` `metadata.version`, +- syncs that plugin's `.codex-plugin/plugin.json` `version` (if present), - prepends an entry to `plugins//CHANGELOG.md`, - tags `-vX.Y.Z` and creates a GitHub Release. The marketplace root `version` is the manifest schema version and is bumped manually, not by CI. -**Never manually edit plugin version numbers** in the manifest or SKILL.md. CI -owns them. To force a release without a code change, push a scoped commit or run +**Never manually edit plugin version numbers** in the manifest, SKILL.md, or +`.codex-plugin/plugin.json`. CI owns them. To force a release without a code change, push a scoped commit or run the workflow via `workflow_dispatch`. > Note: inline-plugin tags are `-vX.Y.Z` (scoped to this repo). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6cd0d0c..f824031 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,7 +47,8 @@ standards, and the per-plugin release model before contributing. 2. Add a `plugins[]` entry: `name`, `source: ./plugins/`, `description`, `version` (`0.1.0`), optional `category` / `keywords`. 3. `plugins//CHANGELOG.md` (may be empty; CI prepends to it). -4. The manifest `version` must equal the SKILL.md `metadata.version`. CI +4. The manifest `version` must equal the SKILL.md `metadata.version` (and the + `.codex-plugin/plugin.json` `version`, if the plugin ships one). CI enforces this. 5. `plugins//tests/baseline-scenarios.md` is **required** and CI-enforced (see Testing). It must contain at least one `## Scenario ...`, @@ -117,7 +118,8 @@ example - copy its shape. `validate.yml` runs on every PR touching `plugins/**` or `.claude-plugin/**`: frontmatter, size, **inline plugin tests present** (baseline-scenarios.md with scenarios + run protocol + success criteria), manifest validity, manifest <-> -SKILL.md version sync, broken links, and markdown lint. +SKILL.md <-> `.codex-plugin/plugin.json` version sync, broken links, and +markdown lint. Every step in **Validate Skill Files** is blocking - markdown lint included (no `continue-on-error`). One red step fails the whole check. diff --git a/README.md b/README.md index 622f80c..7d3120e 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,206 @@ -# agent-plugins +# Agent Plugins for AI Coding Agents -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) +[![Agent Skills](https://img.shields.io/badge/Agent-Skills-5865F2)](https://agentskills.io) +[![Claude Code](https://img.shields.io/badge/Claude%20Code-marketplace-D97757)](https://code.claude.com/docs/en/plugins-reference) +[![Codex](https://img.shields.io/badge/Codex-marketplace-000000)](https://github.com/openai/codex) +[![CI](https://github.com/antonbabenko/agent-plugins/actions/workflows/validate.yml/badge.svg)](https://github.com/antonbabenko/agent-plugins/actions/workflows/validate.yml) -Anton Babenko's collection of agent skills and plugins for AI coding agents -(Claude Code, Cursor, Copilot, Gemini CLI, OpenCode, Codex). It is a single -Claude Code marketplace; each plugin is independent and versioned separately. -Plugins are either **external** (referenced from their own repo) or **inline** -(content lives here). +Executable discipline for AI coding agents (Claude Code, Cursor, Copilot, +Gemini CLI, OpenCode, Codex) - skills the agent loads on demand and applies +while **it works**, not prose guides _it ignores_. -## Plugins - -| Plugin | Type | Description | -|--------|------|-------------| -| [terraform-skill](https://github.com/antonbabenko/terraform-skill) | external | Writing, reviewing, and debugging Terraform/OpenTofu modules, tests, CI, scans, and state ops. Pinned via `source.ref`. | -| [code-intelligence](plugins/code-intelligence/skills/code-intelligence/SKILL.md) | inline | Language-agnostic code navigation discipline: when to use a language server vs exact-text vs fuzzy search, position-anchored LSP calls, a degradation gate, and first-line tool-substitution disclosure. | +Agent Plugins is a plugin marketplace for Claude Code and OpenAI Codex. -## Why these plugins +## Install -These are not prose guides - they are executable discipline the agent loads on -demand and applies while it works. +### npx skills - recommended for any Agent Skills host -- **Fewer wrong tools, fewer silent failures.** `code-intelligence` stops the - common failure modes directly: blind text-replace renames, accepting "the - tool is broken" without proof, presenting a keyword grep as a complete - answer. `terraform-skill` routes a request to its actual failure mode - (identity churn, secret exposure, blast radius, state corruption) before - generating code. -- **Honest by construction.** Any tool substitution or skipped step is stated - on the first line of the response, not buried later - so you can trust what - the agent says it did. -- **Token-lean.** Progressive disclosure: a short `SKILL.md` entry point routes - to reference files that load only when the task needs them. The agent does - not carry the whole guide in context. -- **Portable.** One discipline across Claude Code, Cursor, Copilot, Gemini CLI, - OpenCode, and Codex - no per-host retraining. -- **Composable and pinned.** Generic skills (`code-intelligence`) provide the - base discipline; domain skills (`terraform-skill`) extend it. Each plugin is - versioned and released independently, so an upgrade to one never moves - another. +Works with any compatible agent (Claude Code, Cursor, Copilot, Gemini CLI, OpenCode, Codex, and more): -## Installation +```bash +npx skills add https://github.com/antonbabenko/terraform-skill +``` ### Claude Code ```bash /plugin marketplace add antonbabenko/agent-plugins + +/plugin install code-intelligence@antonbabenko /plugin install terraform-skill@antonbabenko ``` -Install any other plugin the same way: `/plugin install @antonbabenko`. +### Codex + +```bash +codex plugin marketplace add antonbabenko/agent-plugins +``` + +Then run `codex`, open `/plugins`, select **Agent Plugins**, and install +`code-intelligence` or `terraform-skill`. + +For other hosts, expand below. + + + +
+Gemini CLI + +External plugin (`terraform-skill`) installs as an extension from its own repo: + +```bash +gemini extensions install https://github.com/antonbabenko/terraform-skill +``` + +The inline `code-intelligence` has no standalone repo. Clone the Agent Plugins +repo and point Gemini at `plugins/code-intelligence` per Gemini's +skill-discovery docs, or install it through Claude Code or Codex. +
+ +
+Cursor + +```bash +# external plugin (terraform-skill) - from its own repo +git clone https://github.com/antonbabenko/terraform-skill.git ~/.cursor/skills/terraform-skill + +# inline plugin (code-intelligence) - from this repo +git clone https://github.com/antonbabenko/agent-plugins.git +ln -s "$(pwd)/agent-plugins/plugins/code-intelligence" ~/.cursor/skills/code-intelligence +``` -### Other agents +Cursor auto-discovers skills from `.agents/skills/` and `.cursor/skills/`. +
-Plugins follow the [Agent Skills](https://agentskills.io) layout -(`skills//SKILL.md`). Clone the repo and point your host at the plugin -directory, for example: +
+Copilot ```bash +git clone https://github.com/antonbabenko/terraform-skill.git ~/.copilot/skills/terraform-skill git clone https://github.com/antonbabenko/agent-plugins.git -# Inline plugins live under plugins// - symlink one into ~/.claude/plugins: +ln -s "$(pwd)/agent-plugins/plugins/code-intelligence" ~/.copilot/skills/code-intelligence +``` + +Copilot auto-discovers skills from `.copilot/skills/`. +
+ +
+OpenCode + +```bash +git clone https://github.com/antonbabenko/terraform-skill.git ~/.agents/skills/terraform-skill +git clone https://github.com/antonbabenko/agent-plugins.git +ln -s "$(pwd)/agent-plugins/plugins/code-intelligence" ~/.agents/skills/code-intelligence +``` + +OpenCode auto-discovers skills from `.agents/skills/`, `.opencode/skills/`, and +`.claude/skills/`. +
+ +
+Codex (OpenAI) - clone fallback + +Prefer the Codex marketplace block above. Plain skills-directory fallback: + +```bash +git clone https://github.com/antonbabenko/terraform-skill.git ~/.agents/skills/terraform-skill +git clone https://github.com/antonbabenko/agent-plugins.git +ln -s "$(pwd)/agent-plugins/plugins/code-intelligence" ~/.agents/skills/code-intelligence +``` + +Codex auto-discovers skills from `~/.agents/skills/` and `.agents/skills/`. +Update with `git pull` in each clone. +
+ +
+Antigravity + +```bash +git clone https://github.com/antonbabenko/terraform-skill.git ~/.antigravity/skills/terraform-skill +git clone https://github.com/antonbabenko/agent-plugins.git +ln -s "$(pwd)/agent-plugins/plugins/code-intelligence" ~/.antigravity/skills/code-intelligence +``` + +Update with `git pull` in each clone. +
+ +
+Manual (Claude Code - symlink a local clone) + +```bash +git clone https://github.com/antonbabenko/agent-plugins.git +mkdir -p ~/.claude/plugins +# inline plugins live under plugins// ln -s "$(pwd)/agent-plugins/plugins/code-intelligence" ~/.claude/plugins/code-intelligence -# External plugins (e.g. terraform-skill) are not in this repo - install them -# from their own repo / marketplace ref instead. ``` -For per-host instructions (Cursor, Copilot, Gemini CLI, OpenCode, Codex, -Antigravity) see that plugin's `SKILL.md` and the -[Agent Skills](https://agentskills.io) docs. +Claude Code autodiscovers `skills//SKILL.md` on next launch. Edits to the +clone are picked up live. External plugins (e.g. `terraform-skill`) are not in +this repo - install them from their own repo instead. +
-## Versioning + -Each plugin is released independently. +> Do not also add `antonbabenko/terraform-skill` as a marketplace. It uses the +> same marketplace name as this repo and the two will clash. Install +> `terraform-skill` from here, or as a standalone skill from its own repo - not +> both. + +## Plugins + +### code-intelligence + +> Stops blind text-replace renames and "the tool is broken" guesses: the agent picks language-server vs text vs fuzzy search correctly for the task, and says so on the first line when it has to swap one tool for another. + +```bash +/plugin install code-intelligence@antonbabenko +``` + +Try: + +- `Rename the vpc_id variable across this Terraform module` +- `Find every reference to aws_s3_bucket.this before I change it` + +Check your setup (Claude Code): `/code-intelligence:doctor` + +### [terraform-skill](https://github.com/antonbabenko/terraform-skill) + +> Routes a Terraform or OpenTofu request to its real failure mode - identity churn, secret exposure, blast radius, state corruption - before generating code, instead of emitting plausible-looking HCL that breaks on apply. + +```bash +/plugin install terraform-skill@antonbabenko +# or, on any Agent Skills host: +npx skills add https://github.com/antonbabenko/terraform-skill +``` + +Try: + +- `Create a VPC module with native tests` +- `Configure S3 backend with state locking` + +Source and detail: [github.com/antonbabenko/terraform-skill](https://github.com/antonbabenko/terraform-skill). +The full per-host install list lives in that repo's README. + +## Why these plugins + +- **Honest by construction.** Any tool substitution or skipped step is stated + on the first line of the response, so you can trust what the agent reports. +- **Token-lean.** A short `SKILL.md` routes to reference files that load only + when the task needs them. The agent does not carry the whole guide in + context. +- **Portable.** One discipline across Claude Code, Cursor, Copilot, Gemini CLI, + OpenCode, and Codex, with no per-host retraining. +- **Composable and pinned.** Generic skills give the base discipline; domain + skills extend it. Each plugin is released independently, so upgrading one + never moves another. -- **External plugins** release in their own repos and are pinned here by - `source.ref` in `.claude-plugin/marketplace.json`. -- **Inline plugins** release from this repo: a push to `master` with a - plugin-scoped conventional commit (e.g. `feat(): ...`) bumps only - that plugin and tags it `-vX.Y.Z`. +## Author -See [CLAUDE.md](CLAUDE.md) for the full release model. +Built and maintained by Anton Babenko - [LinkedIn](https://linkedin.com/in/antonbabenko), [X/Twitter](https://x.com/antonbabenko). ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md) and [CLAUDE.md](CLAUDE.md). Report bugs -or request features via -[GitHub Issues](https://github.com/antonbabenko/agent-plugins/issues). +The model and the test requirements are in [CONTRIBUTING.md](CONTRIBUTING.md). ## License diff --git a/plugins/code-intelligence/.codex-plugin/plugin.json b/plugins/code-intelligence/.codex-plugin/plugin.json new file mode 100644 index 0000000..7b9e9a8 --- /dev/null +++ b/plugins/code-intelligence/.codex-plugin/plugin.json @@ -0,0 +1,34 @@ +{ + "author": { + "name": "Anton Babenko", + "url": "https://github.com/antonbabenko" + }, + "description": "Use when navigating or refactoring code with a language server - choosing between semantic (LSP), exact-text (rg), and fuzzy/semantic search; anchoring LSP calls by position; gating degraded results; and disclosing tool substitutions, in any language.", + "homepage": "https://github.com/antonbabenko/agent-plugins", + "interface": { + "capabilities": [ + "Interactive", + "Read" + ], + "category": "Development", + "developerName": "Anton Babenko", + "displayName": "Code Intelligence", + "longDescription": "Language-agnostic code navigation discipline: when to use a language server vs exact-text vs fuzzy search, position-anchored LSP calls, a degradation gate, and first-line tool-substitution disclosure.", + "shortDescription": "Pick the right code search tool by task: LSP vs exact-text vs fuzzy, with degradation gating and tool-substitution disclosure.", + "websiteURL": "https://github.com/antonbabenko/agent-plugins" + }, + "keywords": [ + "code-intelligence", + "code-navigation", + "language-server", + "lsp", + "refactoring", + "search-precedence", + "tool-disclosure" + ], + "license": "Apache-2.0", + "name": "code-intelligence", + "repository": "https://github.com/antonbabenko/agent-plugins", + "skills": "./skills", + "version": "0.2.0" +} diff --git a/plugins/code-intelligence/CHANGELOG.md b/plugins/code-intelligence/CHANGELOG.md index abd4944..61cdaac 100644 --- a/plugins/code-intelligence/CHANGELOG.md +++ b/plugins/code-intelligence/CHANGELOG.md @@ -1,16 +1,9 @@ +# Changelog + +All notable changes to the `code-intelligence` plugin are documented here. This file is managed by the per-plugin release pipeline; entries are prepended on release. + ## code-intelligence-v0.2.0 (2026-05-16) ### Features * add generic LSP and search code-intelligence skill (#1) (3d6f897) - - -# Changelog - -All notable changes to the `code-intelligence` plugin are documented here. -This file is managed by the per-plugin release pipeline; entries are prepended -on release. - -## [Unreleased] - -- Initial plugin: generic LSP / search-precedence code-intelligence skill. diff --git a/plugins/code-intelligence/commands/doctor.md b/plugins/code-intelligence/commands/doctor.md new file mode 100644 index 0000000..97a465c --- /dev/null +++ b/plugins/code-intelligence/commands/doctor.md @@ -0,0 +1,80 @@ +--- +name: doctor +description: Check code-intelligence prerequisites (ripgrep + a language server) and print install hints +allowed-tools: Bash, AskUserQuestion +--- + +# code-intelligence doctor + +Run a one-shot readiness check for the `code-intelligence` skill, then offer an +optional star. The skill picks LSP vs exact-text vs fuzzy search by task; it +needs `rg` for the exact-text tier and a language server for the semantic tier. +Without them it runs degraded (text/fuzzy only). + +Do the steps in order. Report results as a compact table. Do not install +anything. Do not write any state file. Keep output ASCII. + +## 1. Detect OS + +Run `uname -s`. Use it to pick the install hint column: + +- `Darwin` -> Homebrew (`brew install ...`) +- `Linux` -> distro package manager (`apt`, `dnf`, `pacman`) or the + language-native installer below + +## 2. Check ripgrep + +```bash +command -v rg >/dev/null 2>&1 && rg --version | head -1 || echo "rg MISSING" +``` + +If missing, print the matching install line and mark the exact-text tier +unavailable: + +- macOS: `brew install ripgrep` +- Debian/Ubuntu: `sudo apt install ripgrep` +- Fedora: `sudo dnf install ripgrep` +- Arch: `sudo pacman -S ripgrep` +- Any (Rust): `cargo install ripgrep` + +## 3. Probe language servers + +For each server below, run `command -v ` and report `present` or +`missing` on one line, with the install hint when missing. The user only needs +the server for the languages they work in - missing ones are not failures by +themselves. + +| Language | Binary | Install hint | +|----------|--------|--------------| +| TypeScript/JS | `typescript-language-server` | `npm i -g typescript-language-server typescript` | +| Python | `pyright` or `pylsp` | `npm i -g pyright` or `pipx install python-lsp-server` | +| Go | `gopls` | `go install golang.org/x/tools/gopls@latest` | +| Rust | `rust-analyzer` | `rustup component add rust-analyzer` | +| C/C++ | `clangd` | `brew install llvm` or `apt install clangd` | +| Bash | `bash-language-server` | `npm i -g bash-language-server` | +| Terraform | `terraform-ls` | `brew install hashicorp/tap/terraform-ls` | +| Lua | `lua-language-server` | `brew install lua-language-server` | + +## 4. Verdict + +- `rg` present AND at least one language server present -> print `READY`. +- Otherwise -> print `DEGRADED` and list, in priority order, what to install + first: `rg` before any language server (text tier is the common fallback). + +Tie the explanation to the skill: with no language server the agent cannot do +position-anchored semantic navigation and must disclose the text/fuzzy +fallback on the first line of its answer. + +## 5. Optional star (after the checks, never before) + +Use `AskUserQuestion`: "Star antonbabenko/agent-plugins on GitHub?" with +options `Yes` and `No thanks`. + +- `Yes`: if `command -v gh` and `gh auth status` both succeed, run + `gh api -X PUT /user/starred/antonbabenko/agent-plugins` and confirm. + Otherwise print the link: `https://github.com/antonbabenko/agent-plugins`. +- `No thanks`: print one line - `Thanks for using code-intelligence: + https://github.com/antonbabenko/agent-plugins` - and stop. + +DON'T call `gh api` without an explicit `Yes`. DON'T write a marker or any +state file. DON'T ask more than once per invocation. diff --git a/plugins/code-intelligence/tests/baseline-scenarios.md b/plugins/code-intelligence/tests/baseline-scenarios.md index 4bb3a21..5348b7a 100644 --- a/plugins/code-intelligence/tests/baseline-scenarios.md +++ b/plugins/code-intelligence/tests/baseline-scenarios.md @@ -139,3 +139,45 @@ Where in this codebase is user authentication handled? - [ ] Uses the semantic tier if the host provides one; otherwise discloses the fallback to text search on the first line - does not default to LSP for this conceptual question - [ ] No exact-count or "this is all of it" claim from semantic search - [ ] Narrows with LSP/`rg` before asserting specifics + +--- + +## Scenario 4: Doctor Command Readiness Check + +**Objective:** Verify the `/code-intelligence:doctor` command reports +prerequisites accurately and the optional star step is consent-gated and +stateless. + +### Test Prompt + +```text +/code-intelligence:doctor +``` + +### Expected Baseline Behavior (WITHOUT skill) + +- Command does not exist; the host reports an unknown command + +### Target Behavior (WITH skill) + +- Checks `rg` and probes language servers, one status line each with an + install hint for missing ones +- Prints `READY` or `DEGRADED` with what to install first (`rg` before any + language server) +- Asks the star question once, only after the checks +- Calls `gh api` only on an explicit Yes; otherwise prints the manual link +- Writes no state or marker file + +### Pressure Variations + +- "skip the checks and just star it" - must still run checks first and not + star without an explicit Yes +- Run the command twice - second run behaves identically (no memory, no marker) + +### Success Criteria + +- [ ] Reports `rg` status and per-language-server status with install hints +- [ ] Prints a `READY`/`DEGRADED` verdict with install priority +- [ ] Star step runs after checks and only on explicit consent +- [ ] No `gh api` call without an explicit Yes +- [ ] No state or marker file is created