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
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Force LF line endings for test fixtures — tree-sitter grammars
# expect Unix line endings and produce wrong parse trees with CRLF.
tests/fixtures/** text eol=lf
# Force LF for bundled plugin skill docs; the skill hygiene tests assert the
# canonical source files are LF-only, and Windows checkout otherwise rewrites
# them before the lint runs.
codex-plugin/skills/** text eol=lf
cursor-plugin/skills/** text eol=lf
# Force LF for embedded Hermes plugin template assets — they are pulled into
# the binary via include_str! and the generated-plugin snapshot test asserts
# their exact bytes.
Expand Down
108 changes: 108 additions & 0 deletions .github/workflows/plugin-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Schema/lint layer for the shipped agent plugin bundles. Mirrors the official
# Cursor marketplace validation workflow:
# https://github.com/cursor/plugins/blob/main/.github/workflows/validate-plugins.yml
# (ajv + ajv-formats against the plugin/marketplace JSON schemas; the schemas
# are vendored in tests/fixtures/cursor-schemas/).
#
# The Rust contract tests for the bundles already run in ci.yml — do not add
# plain cargo test jobs here. The MCP conformance smoke below is the one
# exception: it needs a built binary plus npx, which cargo test can't provide.
name: Plugin Validation

on:
pull_request:
paths:
- "cursor-plugin/**"
- "codex-plugin/**"
- "tests/fixtures/cursor-schemas/**"
# Plugin/skill test modules (e.g. plugin_manifest_schema_test.rs,
# plugin_skill_contract_test.rs, the skill lint tests).
- "tests/agent_suite/*plugin*"
- "tests/agent_suite/*skill*"
- "scripts/mcp-conformance-smoke.sh"
# The Inspector smoke is the workflow's SDK-backed coverage for
# `tracedecay serve` protocol and tool-schema compatibility.
- "src/serve.rs"
- "src/main.rs"
- "src/lib.rs"
- "src/mcp/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/plugin-validation.yml"
Comment thread
ScriptedAlchemy marked this conversation as resolved.

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
manifest-schema:
name: Manifest schema
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v4
with:
node-version: 22

# Pinned, unlike upstream's floating `npm install ajv ajv-formats`.
- name: Install ajv-cli
run: npm install --no-save ajv-cli@5.0.0 ajv-formats@2.1.1

- name: Compile vendored schemas
run: |
npx --no-install ajv compile --spec=draft7 -c ajv-formats \
-s tests/fixtures/cursor-schemas/plugin.schema.json \
-s tests/fixtures/cursor-schemas/marketplace.schema.json \
-s tests/fixtures/cursor-schemas/mcp.schema.json \
-s tests/fixtures/cursor-schemas/hooks.schema.json

- name: Validate Cursor plugin manifest
run: |
npx --no-install ajv validate --spec=draft7 -c ajv-formats --errors=text \
-s tests/fixtures/cursor-schemas/plugin.schema.json \
-d cursor-plugin/.cursor-plugin/plugin.json

# The Codex manifest follows Codex's own layout (e.g. its `interface`
# block), so the Cursor schema does not apply; keep it to a strict JSON
# well-formedness check alongside the other bundle JSON files.
- name: Check bundle JSON files parse
run: |
set -euo pipefail
find cursor-plugin codex-plugin -name '*.json' -print0 |
while IFS= read -r -d '' f; do
python3 -c "import json,sys; json.load(open(sys.argv[1]))" "$f" \
|| { echo "invalid JSON: $f" >&2; exit 1; }
echo "ok: $f"
done

# Drives a real `tracedecay serve` stdio server through the MCP Inspector
# CLI (pinned version), which embeds the official TypeScript MCP SDK client
# — covering protocol-version negotiation and SDK-side schema validation
# that the in-repo Rust MCP tests cannot. See scripts/mcp-conformance-smoke.sh.
mcp-conformance-smoke:
name: MCP conformance smoke
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v4
with:
node-version: 22

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2

- name: Build tracedecay
run: cargo build --bin tracedecay --locked

- name: Run MCP conformance smoke
run: scripts/mcp-conformance-smoke.sh
env:
TRACEDECAY_BIN: target/debug/tracedecay
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ section so the contributor command and blocking/advisory split still match CI.
4. Add a fixture file `tests/fixtures/sample.{ext}` and a test module `tests/extraction_suite/{lang}.rs`, then register it with a `mod {lang};` declaration in `tests/extraction_suite/main.rs`.
5. Update the feature flag tables in `Cargo.toml` and this document.

## Validating Plugins and Skills

Changes under `cursor-plugin/`, `codex-plugin/`, or `src/agents/` are covered
by a layered validation system: vendored JSON-schema checks, per-host skill
frontmatter contracts, cross-bundle sync/parity tests, and a CI
schema-validation workflow. `cursor-plugin/` is the source of truth — never
hand-edit mirrored Codex skills. Before submitting, run:

```bash
cargo nextest run -E 'binary(=agent_suite)'
```

See [`docs/PLUGIN-VALIDATION.md`](docs/PLUGIN-VALIDATION.md) for the full
layer breakdown, schema refresh procedure, and how to add a skill or a new
ecosystem bundle correctly.

## Running Specific Tests

```bash
Expand Down
Loading
Loading