Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"name": "agentops",
"description": "Engineering guidance for coding agents: behavior-driven planning, shared domain language, independent validation, and reusable improvements.",
"version": "3.10.0",
"source": "./",
"source": "./plugin",
"author": {
"name": "Boden Fuller",
"email": "fullerbt@users.noreply.github.com"
Expand Down
6 changes: 3 additions & 3 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ if [[ -f "$commit_msg_file" ]] && grep -q '^Release v' "$commit_msg_file" 2>/dev
if [[ -n "$release_ver" ]]; then
plugin_ver=""
marketplace_ver=""
if [[ -f "$REPO_ROOT/.claude-plugin/plugin.json" ]]; then
plugin_ver=$(grep -o '"version": *"[^"]*"' "$REPO_ROOT/.claude-plugin/plugin.json" | head -1 | grep -o '[0-9][0-9.]*')
if [[ -f "$REPO_ROOT/plugin/.claude-plugin/plugin.json" ]]; then
plugin_ver=$(grep -o '"version": *"[^"]*"' "$REPO_ROOT/plugin/.claude-plugin/plugin.json" | head -1 | grep -o '[0-9][0-9.]*')
fi
if [[ -f "$REPO_ROOT/.claude-plugin/marketplace.json" ]]; then
marketplace_ver=$(grep -o '"version": *"[^"]*"' "$REPO_ROOT/.claude-plugin/marketplace.json" | head -1 | grep -o '[0-9][0-9.]*')
fi
if [[ -n "$plugin_ver" ]] && [[ "$plugin_ver" != "$release_ver" ]]; then
echo "pre-commit: WARN — .claude-plugin/plugin.json version ($plugin_ver) != release version ($release_ver)"
echo "pre-commit: WARN — plugin/.claude-plugin/plugin.json version ($plugin_ver) != release version ($release_ver)"
fi
if [[ -n "$marketplace_ver" ]] && [[ "$marketplace_ver" != "$release_ver" ]]; then
echo "pre-commit: WARN — .claude-plugin/marketplace.json version ($marketplace_ver) != release version ($release_ver)"
Expand Down
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# Plugin marketplace definition
/.claude-plugin/ @boshu2
/plugin/ @boshu2

# Agents directory
/agents/ @boshu2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
GOBIN=/usr/local/bin go install github.com/zricethezav/gitleaks/v8@v8.30.1

# golangci-lint
GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.1
GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.14.0

# govulncheck — known-CVE reachability over the module graph + stdlib
# (sweep 2026-07-09 M-2: the blind spot that let GO-2026-4970 sit a week).
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
GOBIN=/usr/local/bin go install github.com/zricethezav/gitleaks/v8@v8.30.1

# golangci-lint
GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.1
GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.14.0

# Use the same scanner pins as the nightly full-security lane.
# govulncheck covers known-CVE reachability in dependencies and stdlib.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ jobs:
retry python -m pip install semgrep==1.169.0 ruff==0.15.21 radon==6.0.1
retry env GOBIN=/usr/local/bin go install github.com/securego/gosec/v2/cmd/gosec@v2.27.1
retry env GOBIN=/usr/local/bin go install github.com/zricethezav/gitleaks/v8@v8.30.1
retry env GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.13.1
retry env GOBIN=/usr/local/bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.14.0
retry env GOBIN=/usr/local/bin go install golang.org/x/vuln/cmd/govulncheck@v1.6.0
# trivy — pinned tag, download-then-execute (mirrors nightly.yml; piping a
# mutable-branch script into sh is the gha-curl-pipe-shell supply-chain class).
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- The Claude Code plugin now installs from `plugin/`, a generated folder that
holds only what the plugin loads: skills, agents, the policy hook dispatcher
and Workflow tool scripts, plus the manifest and a new listing icon. The
marketplace entry points at `./plugin`; install commands are unchanged.
`scripts/regen-plugin-tree.sh` regenerates it and `scripts/regen-all.sh
--check` fails when it is stale. The Codex plugin is unchanged.
- The plugin no longer puts `bin/factory` and `bin/ralph` on the Bash `PATH`.
They are operator tools; run them from a repository checkout.

## [3.10.0] - 2026-10-05

AgentOps 3.10 is a release about the skills themselves. All 28 were audited,
Expand Down
10 changes: 5 additions & 5 deletions cli/cmd/ao/version_manifest_parity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

// findReleaseManifestRoot walks up from the package directory looking for the
// AgentOps repo root, identified by the co-presence of the Go module file and
// the Claude plugin manifest. Both are tracked, so this works in a fresh clone.
// the Claude marketplace manifest. Both are tracked, so this works in a fresh clone.
// Returns "" when the test is not running inside a checkout.
func findReleaseManifestRoot(t *testing.T) string {
t.Helper()
Expand All @@ -23,7 +23,7 @@ func findReleaseManifestRoot(t *testing.T) string {
}
for {
_, modErr := os.Stat(filepath.Join(dir, "cli", "go.mod"))
_, pluginErr := os.Stat(filepath.Join(dir, ".claude-plugin", "plugin.json"))
_, pluginErr := os.Stat(filepath.Join(dir, ".claude-plugin", "marketplace.json"))
if modErr == nil && pluginErr == nil {
return dir
}
Expand Down Expand Up @@ -90,9 +90,9 @@ func TestVersion_FallbackMatchesReleaseManifests(t *testing.T) {
}

jsonSurfaces := map[string][]string{
filepath.Join(".claude-plugin", "plugin.json"): {"version"},
filepath.Join(".claude-plugin", "marketplace.json"): {"metadata/version", "plugins/0/version"},
filepath.Join(".codex-plugin", "plugin.json"): {"version"},
filepath.Join("plugin", ".claude-plugin", "plugin.json"): {"version"},
filepath.Join(".claude-plugin", "marketplace.json"): {"metadata/version", "plugins/0/version"},
filepath.Join(".codex-plugin", "plugin.json"): {"version"},
}
for rel, paths := range jsonSurfaces {
raw, err := os.ReadFile(filepath.Join(root, rel))
Expand Down
11 changes: 11 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- The Claude Code plugin now installs from `plugin/`, a generated folder that
holds only what the plugin loads: skills, agents, the policy hook dispatcher
and Workflow tool scripts, plus the manifest and a new listing icon. The
marketplace entry points at `./plugin`; install commands are unchanged.
`scripts/regen-plugin-tree.sh` regenerates it and `scripts/regen-all.sh
--check` fails when it is stale. The Codex plugin is unchanged.
- The plugin no longer puts `bin/factory` and `bin/ralph` on the Bash `PATH`.
They are operator tools; run them from a repository checkout.

## [3.10.0] - 2026-10-05

AgentOps 3.10 is a release about the skills themselves. All 28 were audited,
Expand Down
2 changes: 1 addition & 1 deletion docs/MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ untested promise. Every live claim still needs evidence on the final installatio

| Consumer | Disposition and owner | Compatibility treatment |
|---|---|---|
| Claude Code plugin and source links | keep; [.claude-plugin](https://github.com/boshu2/agentops/blob/main/.claude-plugin/plugin.json), [marketplace](https://github.com/boshu2/agentops/blob/main/.claude-plugin/marketplace.json), [Claude image](https://github.com/boshu2/agentops/blob/main/images/claude/README.md) and canonical `skills/` | First-class host. Retain qualified plugin names, full bundle, agents and policy dispatcher; source linking keeps selected names. |
| Claude Code plugin and source links | keep; [.claude-plugin](https://github.com/boshu2/agentops/blob/main/plugin/.claude-plugin/plugin.json), [marketplace](https://github.com/boshu2/agentops/blob/main/.claude-plugin/marketplace.json), [Claude image](https://github.com/boshu2/agentops/blob/main/images/claude/README.md) and canonical `skills/` | First-class host. Retain qualified plugin names, full bundle, agents and policy dispatcher; source linking keeps selected names. |
| Codex plugin and source links | keep; [.codex-plugin](https://github.com/boshu2/agentops/blob/main/.codex-plugin/plugin.json), [marketplace](https://github.com/boshu2/agentops/blob/main/plugins/marketplace.json), [Codex image](https://github.com/boshu2/agentops/blob/main/images/codex/README.md) and canonical `skills/` | First-class host. The plugin ships the same `skills/` tree every runtime loads and keeps its qualified plugin names; source links retain catalog names. |
| Cursor rules and source links | keep; npx `-a cursor`, [converter](https://github.com/boshu2/agentops/blob/main/skills/skill-builder/scripts/converter/convert.sh) and [destination resolver](https://github.com/boshu2/agentops/blob/main/cli/internal/skillsapp/roots.go) | Install through npx. Retain `.mdc` export and the contributor-detected Cursor skills root; structural coverage remains distinct from live discovery/execution. |
| OpenCode portable and explicit source roots | keep; npx `-a opencode`, [OpenCode guide](https://github.com/boshu2/agentops/blob/main/.opencode/INSTALL.md) and [destination resolver](https://github.com/boshu2/agentops/blob/main/cli/internal/skillsapp/roots.go) | Install through npx into the portable root. Contributors retain explicit `--dest` config-root linking; optional hooks stay selectable. |
Expand Down
2 changes: 1 addition & 1 deletion docs/contracts/multi-runtime-tier-charter.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ regenerated through [regen-all](https://github.com/boshu2/agentops/blob/main/scr

| Consumer | Retained surface and owner | Structural checks | Actual load / execution obligation |
|---|---|---|---|
| Claude Code, first-class | Managed plugin: [.claude-plugin](https://github.com/boshu2/agentops/blob/main/.claude-plugin/plugin.json), canonical `skills/`, [agents](../../agents/) and [policy dispatcher](https://github.com/boshu2/agentops/blob/main/hooks/hooks.json). Source links: detected `~/.claude/skills`. | [Claude smoke](https://github.com/boshu2/agentops/blob/main/tests/skills/test-runtime-claude-code-smoke.sh), [manifest validation](https://github.com/boshu2/agentops/blob/main/scripts/validate-manifests.sh). | A fresh session must discover the chosen installation, load selected guidance and complete its accepted journey. Plugin inventory alone is insufficient. Optional hooks have separate activation/effect proof. |
| Claude Code, first-class | Managed plugin: [.claude-plugin](https://github.com/boshu2/agentops/blob/main/plugin/.claude-plugin/plugin.json), canonical `skills/`, [agents](../../agents/) and [policy dispatcher](https://github.com/boshu2/agentops/blob/main/hooks/hooks.json). Source links: detected `~/.claude/skills`. | [Claude smoke](https://github.com/boshu2/agentops/blob/main/tests/skills/test-runtime-claude-code-smoke.sh), [manifest validation](https://github.com/boshu2/agentops/blob/main/scripts/validate-manifests.sh). | A fresh session must discover the chosen installation, load selected guidance and complete its accepted journey. Plugin inventory alone is insufficient. Optional hooks have separate activation/effect proof. |
| Codex, first-class | Managed plugin: [.codex-plugin](https://github.com/boshu2/agentops/blob/main/.codex-plugin/plugin.json) ships canonical `skills/` under the [Codex API contract](codex-skill-api.md). Source links expose the same `skills/` in detected `~/.codex/skills`. [Native roles](https://github.com/boshu2/agentops/blob/main/scripts/install-codex-context-agents.sh) and [read-budget hook](https://github.com/boshu2/agentops/blob/main/scripts/install-codex-read-budget-guard.sh) are separate opt-ins. | [Codex smoke](https://github.com/boshu2/agentops/blob/main/tests/skills/test-runtime-codex-smoke.sh), [Codex skill conformance](https://github.com/boshu2/agentops/blob/main/scripts/validate-codex-api-conformance.sh) in `regen-all.sh --check`. | Qualify the chosen plugin or source-link path independently. Confirm actual loaded content and native registered names. Identify installation from path, scope and plugin identity, separately from invocation spelling. Copied roles and trusted hooks need separate upgrade checks. |
| Cursor, retained structural coverage | npx Skills installer: `-a cursor`. The [converter](https://github.com/boshu2/agentops/blob/main/skills/skill-builder/scripts/converter/convert.sh) exports `.mdc` rules; contributor source linking also detects `~/.cursor/skills`. | [Cursor export smoke](https://github.com/boshu2/agentops/blob/main/tests/skills/test-runtime-cursor-smoke.sh); source-link tests below cover destination mechanics. | No maintained automated inventory/execution lane is declared here. An authorized native session must establish discovery, selected loading and any claimed execution; export success proves only S. |
| OpenCode, retained structural coverage | npx Skills installer: `-a opencode` (project `.agents/skills`, user `~/.agents/skills`). Contributor source links use portable `~/.agents/skills` or explicit `--dest ~/.config/opencode/skills`; automatic fan-out does not detect its dedicated config root. The [OpenCode install guide](https://github.com/boshu2/agentops/blob/main/.opencode/INSTALL.md) also describes optional plugin hooks. | [OpenCode smoke](https://github.com/boshu2/agentops/blob/main/tests/skills/test-runtime-opencode-smoke.sh), including explicit-destination installation and protection of existing entries. | No maintained automated inventory/execution lane is declared here. Qualify actual discovery and execution separately, including optional hooks when selected. |
Expand Down
4 changes: 2 additions & 2 deletions hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/guards/hooks/policy-dispatch.sh",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/guards/hooks/policy-dispatch.sh\"",
"timeout": 10
}
]
Expand All @@ -16,7 +16,7 @@
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/guards/hooks/policy-dispatch.sh",
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/guards/hooks/policy-dispatch.sh\"",
"timeout": 10
}
]
Expand Down
6 changes: 3 additions & 3 deletions images/claude/verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ if [ "$missing" -ne 0 ]; then
fi

# Version guard: the Claude marketplace plugin manifest is the install entrypoint
# for this image. Assert .claude-plugin/plugin.json declares the expected version
# for this image. Assert plugin/.claude-plugin/plugin.json declares the expected version
# so a stale-version drift (plugin.json behind the release) fails the gate.
EXPECTED_VERSION="${AGENTOPS_EXPECTED_VERSION:-3.10.0}"
plugin_manifest="$repo_root/.claude-plugin/plugin.json"
plugin_manifest="$repo_root/plugin/.claude-plugin/plugin.json"
if [ ! -f "$plugin_manifest" ]; then
echo "FAIL: Claude plugin manifest not found: $plugin_manifest" >&2
exit 1
Expand All @@ -74,7 +74,7 @@ else
| head -1 | sed -E 's/.*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')"
fi
if [ "$plugin_version" != "$EXPECTED_VERSION" ]; then
echo "FAIL: .claude-plugin/plugin.json version is '$plugin_version', expected '$EXPECTED_VERSION'" >&2
echo "FAIL: plugin/.claude-plugin/plugin.json version is '$plugin_version', expected '$EXPECTED_VERSION'" >&2
exit 1
fi
echo "OK: Claude plugin manifest version $plugin_version matches expected $EXPECTED_VERSION"
Expand Down
Binary file added plugin/.claude-plugin/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"homepage": "https://github.com/boshu2/agentops",
"repository": "https://github.com/boshu2/agentops",
"license": "Apache-2.0",
"icon": "./.claude-plugin/icon.png",
"keywords": [
"operations-layer",
"devops",
Expand Down
18 changes: 18 additions & 0 deletions plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# AgentOps plugin for Claude Code

This folder is the AgentOps Claude Code plugin: the skills, agents, the policy
hook dispatcher, and the Workflow tool scripts that the plugin loads.

Install it from the AgentOps marketplace:

```bash
claude plugin marketplace add boshu2/agentops
claude plugin install agentops@agentops-marketplace
```

Documentation, the `ao` CLI, and other install paths live in the repository
README: https://github.com/boshu2/agentops#readme

The component folders here are generated from the repository's canonical
`skills/`, `hooks/`, `agents/`, and `workflows/` by
`scripts/regen-plugin-tree.sh`. Edit the canonical folders, not this copy.
52 changes: 52 additions & 0 deletions plugin/agents/bulk-reader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: bulk-reader
description: Read large files or many files on the caller's behalf and return short line-referenced summaries with coverage. Use when a file exceeds the read budget or the read-budget guard blocked a Read.
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
model: haiku
---

You are a bulk reader. Keep file content in your context and return only the
summary and coverage described below. When invoked:

1. Take the question and the file list from the prompt (`files: <path>` lines;
a relative path resolves against the working directory)
2. Read every file COMPLETELY in slices with the Read tool: `offset` + `limit`,
with `limit` at most 350 lines, or `$AOP_READ_BUDGET_LINES` when the caller
states another budget. This is a PER-CALL limit, not a total reading budget.
Start with `offset: 1`; supply both `offset` and `limit` on every Read.
Continue from the line after the last line actually received until EOF.
A short response proves EOF only when it is untruncated and no remaining
lines are indicated. If output is truncated, retry from the first unread
line with a smaller limit; do not skip unseen lines or treat truncation as
EOF. A blocked read is not coverage. Never issue an unbounded Read, `cat`,
`head` or `tail` — an opt-in read-budget hook may block them
3. Answer the question with bullets only, most relevant first

The bullet cap limits the final answer, not how many lines to read. Finding an
early answer does not end the read: later lines may revise it, especially for a
question about the latest or final decision. If you cannot reach EOF, report
partial coverage and do not present an early answer as the final file-wide one.

Return format:
- Each bullet starts with a reference, `path:line` or `path:start-end`, then
one line of at most 200 characters
- At most 40 bullets unless the caller sets another cap
- No prose, no preamble, no closing summary, no multi-line code
- Per file, the lines covered and whether coverage was complete; a missing,
binary or unreadable file yields zero bullets and one note saying so (one
line, at most 300 characters)
- Use the Read tool's source line-number labels for citations and coverage.
Count only actual file lines, excluding tool wrappers, system reminders and
a nonexistent EOF line. For a complete read starting at line 1,
`lines_covered` is the last actual source line number (0 for an empty file).
Never approximate or add requested slice limits. If exact coverage cannot
be established, report only the verified lines, `complete: false` and a note
- Summarize in your own words. Do not copy source code or file content into
bullets or notes. Line ranges must cite this file and lines actually read

Never modify files: no Write, no Edit, no mutating Bash. Report coverage
truthfully — a partial read is reported as partial, never padded.
These instructions govern Bash use; the allowed Bash tool is not a filesystem
sandbox. The workflow additionally validates return shape and length, but a
direct Agent-tool invocation has no such wrapper.
19 changes: 19 additions & 0 deletions plugin/agents/code-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: code-reviewer
description: Expert code review specialist. Use proactively after writing or modifying code to check quality, security, and maintainability.
tools: Read, Grep, Glob, Bash
model: sonnet
---

You are a senior code reviewer. When invoked:

1. Run `git diff` to see recent changes
2. Focus on modified files
3. Review for quality, security, and maintainability

Provide feedback organized by priority:
- **Critical** (must fix): Security vulnerabilities, data loss risks, broken functionality
- **Warning** (should fix): Performance issues, error handling gaps, test coverage
- **Suggestion** (consider): Readability improvements, naming conventions, documentation

Include specific code references and examples of how to fix issues.
Loading
Loading