Skip to content

feat: agentic-coding transpiler — single-source-of-truth across 15 AI agent platforms#331

Open
awsmadi wants to merge 17 commits into
mainfrom
pr/agent-plugins
Open

feat: agentic-coding transpiler — single-source-of-truth across 15 AI agent platforms#331
awsmadi wants to merge 17 commits into
mainfrom
pr/agent-plugins

Conversation

@awsmadi

@awsmadi awsmadi commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Introduces ash-agent-plugins/agentic-coding/ — a single-source-of-truth transpiler that emits ASH plugin packages for 15 AI agent platforms from a unified Pydantic schema.
  • Class-per-backend architecture with Click CLI, pluggable build phases, smoke_test() coverage on every backend, real CLI validators, version pins, matrix CI.
  • All 152 files live under ash-agent-plugins/; zero collision with the rest of the codebase.

Closes #60.

What's included

  • Data-driven schema refresh + Pydantic codegen (Amazon Q, Continue Zod, Aider, Claude, Cline, Codex, Cursor, Gemini, Goose, Kiro, Microsoft Copilot, OpenCode, Roo, Windsurf, generic-skill)
  • Format abstraction decouples formats × agents
  • pytest regression suite + pinned-CLI workflow + Goose AGENTS.md
  • Generic-skill release + CliTool metadata
  • External schema validation + platform constraints

Why this PR is independent

Path-disjoint from all other refactor work. No imports/exports cross the ash-agent-plugins/ boundary. Reviewers can focus on the transpiler in isolation; this PR can land in any order relative to the scan-decomposition / MCP / scanner-template work in flight on sibling branches.

Test plan

  • CI: matrix-CI runs across all 15 backend smoke tests
  • CI: pytest regression suite passes
  • CI: pinned-CLI workflow validates against external platform schemas
  • Manual: `cd ash-agent-plugins/agentic-coding && python -m transpiler.cli --help`

awsmadi added 17 commits May 8, 2026 11:15
Fixes 80+ documentation bugs and adds source-derived doc generation:

Bug fixes (macro-applied):
- Fix version typo v3.0,1 in README pipx example
- Update all version references from v3.4.0/v3.0.0/v3.2.2 to v3.4.1
- Fix config path .ash/ash.yaml to .ash/.ash.yaml across 3 files
- Fix suppression field name file_path to path in config/quick-start guides
- Update pre-commit rev from v3.0.0 to v3.4.1 across 5 files

New documentation:
- SECURITY.md (vulnerability disclosure policy)
- GitHub issue templates (bug_report.yml, feature_request.yml)
- Pull request template
- docs/concepts.md (domain model with Mermaid diagram)
- docs/glossary.md (28 term definitions)
- docs/supported-languages.md (scanner coverage matrix)
- docs/api-reference.md (mkdocstrings auto-rendered)
- docs/cli-reference-generated.md (auto-generated from source)

Automation:
- scripts/generate_cli_docs.py (introspects Typer + MCP tools)
- scripts/verify_docs_freshness.py (7-check CI gate)
- CI lint job: docs freshness verification step added
…ies bug

Model methods added (19 total, 86 new tests):
- ScannerSeverityCount: total, actionable_count, increment, max_severity
- SummaryStats: set_timing
- ScannerTargetStatusInfo: total_duration
- ScannerStatusInfo: is_dual_layer
- AshSuppression: matches(finding), id, is_expired, days_until_expiry
- IgnorePathWithReason: matches_path
- SarifReport: get_all_results, get_scanner_names, filter_results_by_files
- ScanResultsContainer: for_excluded, for_missing_deps, for_failure, determine_status

Bug fixes:
- to_flat_vulnerabilities() no longer mutates on repeat calls (cached via PrivateAttr)
- scan_phase.py: 9 factory sites + 35-line status cascade replaced with model methods

Documentation:
- Fixed 38 version/path errors across 19 doc files
- Created docs/content/docs/troubleshooting.md
- Created docs/content/docs/architecture.md
- sarif_utils: extract _resolve_result_severity helper, use .increment()
  and .get_all_results() (Pattern 4: -30 lines)
- scan_phase: use sev_count.total instead of destructuring into 6 locals
  (Pattern 3: -8 lines)
- scanner_statistics_calculator: use ScannerSeverityCount instance with
  .increment() for per-scanner counting (Pattern 1: -50 lines), and
  accumulate into model instance for totals (Pattern 2: -6 lines)
- Fix test mock to configure .total property
… factories, PrivateAttr cleanup

Tier 1 (9/9 swarm consensus):
- ScanResultsContainer.severity_counts: Dict[str,int] → ScannerSeverityCount model
  Eliminates 30+ .get() calls and duplicated threshold logic in determine_status()
- ScannerMetrics now inherits ScannerSeverityCount (DRYs 7 field declarations)
  Removed dead status_text field; passed is now @computed_field
- to_flat_vulnerabilities() reduced from 375→66 lines (82% smaller)
  Extracted FlatVulnerability.from_sarif_result() and from_additional_report() classmethods
  Eliminated duplicated tag/scanner extraction blocks

Tier 2 (6-8/9 consensus):
- FlatVulnerability: added location_display property and is_actionable(threshold) method
- AshPluginManager._resolved_plugins → PrivateAttr(default_factory=dict)
- AshConfig._resolution_warnings → PrivateAttr(default_factory=list)
- PluginContext.work_dir: model_post_init → @model_validator(mode="after")
- Deduplicated _populate_summary_stats_from_unified_metrics (removed 50-line model method)
- Removed duplicate format_duration from run_ash_scan.py
- Removed SummaryStats.model_post_init no-op

94 new tests across 3 test files. Full suite: 2174 passed, 0 failed.
Removes ~5,750 lines of unused test utilities (mock_factories, integration_test_utils,
context_managers, coverage_utils, parallel_test_utils, resource_management,
data_factories, external_service_mocks) and the meta-test that asserted their
presence. All 2,157 unit tests still pass.

Type fixes applied to orchestrator.py, unified_metrics.py, run_ash_scan.py,
mocks.py, get_scan_set.py, normalizers.py, and constants.py:
- type: ignore[attr-defined] for runtime-patched logger.verbose calls
- ExecutionStrategy.PARALLEL.value -> ExecutionStrategy.PARALLEL (enum vs str)
- None guards for Optional member access
- str(path) where str | None expected
…ions

Three independent bugs caught by the codebase review:

1. flat_vulnerability.py:317 - replace hash(description) % 10000 with
   hashlib.sha256(description.encode()).hexdigest()[:8]. Python's hash() is
   randomized per-process via PYTHONHASHSEED, so the same finding got different
   IDs across runs, breaking cross-scan dedup.

2. asharp_model.py:_apply_suppression_side_effects - persist the dict-to-model
   conversion back to scanner_results[key]. Local-only mutation discarded
   suppression count increments for dict-typed entries.

3. execution_engine.py:execute_phases - move return self._results out of the
   finally block. Per Python semantics, return inside finally swallows
   exceptions propagating from the try body, hiding phase failures from
   the caller.

Adds tests/unit/test_phase0_critical_bugs.py with regression coverage for
all three. Tests fail before fixes, pass after.
…gent platforms

Adds a config-driven build pipeline that emits plugin packages for Claude Code,
Codex CLI, Kiro IDE, GitHub Copilot, OpenCode, Cursor, Windsurf, Cline, Roo Code,
Continue.dev, Gemini CLI, Block Goose, Amazon Q, Aider, and MCPB / Claude Desktop
from one canonical _base/ source. Wraps the upstream ASH MCP server.

Architecture:
- _base/ (source-of-truth): manifest.json, skill.md, references/, commands/,
  agents/, mcp.json — humans only edit here
- configs.yaml + Pydantic schema: per-platform layout descriptions
- transpile.py: generic dispatcher with section emitters
- templates/: Jinja2 frontmatter + per-platform shape templates
- plugins/: GENERATED outputs committed for browse-by-platform

Verification:
- Pre-commit hook auto-regenerates outputs and verifies no drift
- CI workflow (uv run) runs --check on every PR; drift fails the build
- Deterministic builds — including .mcpb ZIP archives with fixed mtime
- AGENTS.md emitted at plugins root, read natively by 9+ platforms
…constraints

Adds three-tier output validation to the transpiler. Run via
`uv run --project agentic-coding/transpiler transpile --check` (drift +
validation) or `--validate-only` (validation alone).

Tier 1 — official external JSON Schemas (cached under transpiler/schemas/):
  - MCPB manifest.json validated against modelcontextprotocol/mcpb Draft 07
  - OpenCode opencode.json validated against opencode.ai Draft 2020-12

Tier 2 — structural sanity (every generated file):
  - All *.json parse as JSON
  - All *.yaml/*.yml parse as YAML
  - All *.md/*.mdc with `---` headers have parseable YAML frontmatter
  - Every path declared in configs.yaml exists in the output tree

Tier 3 — known platform constraints (from research-confirmed docs):
  - Claude plugin name: kebab-case (^[a-z0-9]+(-[a-z0-9]+)*$)
  - Roo customMode slug: ^[a-zA-Z0-9-]+$
  - Windsurf rule trigger: enum {always_on, model_decision, glob, manual}
  - Copilot copilot-instructions.md <= 4000 chars (Code Review limit)
  - Windsurf rules <= 12000 bytes (per-rule cap)
  - MCPB archive contains manifest.json at root + manifest schema-valid

Verified by deliberately corrupting the Claude plugin name and confirming
the validator catches it before restoring.

Adds jsonschema>=4.0 dependency.
Two follow-ups to the validation feature:

1. Add agentic-coding/transpiler/schemas/refresh.sh to re-fetch the cached
   external JSON Schemas (MCPB manifest, OpenCode config) when upstream
   specs change. Refresh is explicit/reviewable rather than runtime-fetch
   so a network blip can never block CI, and a malicious upstream change
   would land via a reviewed git diff rather than silently.

2. Remove gemini-settings.schema.json — it was speculatively fetched but
   validates ~/.gemini/settings.json (a file we don't generate), not our
   gemini-extension.json. Dead weight.

3. Update README to document the three validation tiers and the refresh
   command.

Verified: --check still passes after refresh + gemini removal.
…ter + Amazon Q + Continue Zod

Schema management overhaul. Replaces the hand-rolled refresh.sh with a
declarative pipeline driven by transpiler/schemas/schemas.json:

  - direct entries (HTTP fetch with User-Agent for hosts that 403 default UA):
      * mcpb-manifest.schema.json  (modelcontextprotocol/mcpb, Draft 07)
      * opencode-config.schema.json (opencode.ai, Draft 2020-12)
      * amazonq-agent.schema.json   (aws/amazon-q-developer-cli, Draft 07)

  - zod-converted entries (clones repo, runs tsc + zod-to-json-schema via Node):
      * continue-config.schema.json (continuedev/continue configYamlSchema)

  Refresh: `uv run --project agentic-coding/transpiler refresh-schemas`
  Codegen: `uv run --project agentic-coding/transpiler --extra refresh generate-models`

Pydantic models generated from 3 of 4 schemas (OpenCode's 31k-line provider
matrix is too large to commit; jsonschema-based runtime validation continues
for that one). Models live at transpiler/generated_models/ and are imported
by validate.py.

Validation upgrades:

  - python-frontmatter library replaces hand-rolled frontmatter parser
    (handles BOM, CRLF, trailing-newline edge cases properly)
  - Amazon Q agent.json now schema-validated (was previously only structural)
  - validate_paths_exist() now uses **values consistently — won't crash on
    future placeholders added to configs.yaml
  - Validation errors annotated with _base/ source-file fix hints

Addresses DA findings #1, #2, #11, #12, #14 from prior reviews. Architectural
class-per-backend refactor (DA finding #15+) is the next commit.
…uild phases

Replaces the monolithic transpile.py + configs.yaml dispatch model with a
class-per-backend plugin pattern. Each of the 15 platforms is now a
BaseBackend subclass that declares its layout via class-level constants
(PLUGIN_MANIFEST, MCP, SKILL, COMMANDS, AGENTS, INSTRUCTION_FILE, etc.).

Architecture:

  transpiler/
    core.py              BaseBackend ABC, section dataclasses, BuildPhase,
                         Manifest, BuildContext, topo-sort for phase deps.
    registry.py          @register_backend decorator + BackendRegistry.
    backends/
      __init__.py        Imports all 15 backend modules → triggers registration.
      claude.py          ClaudeBackend(BaseBackend) — class vars only.
      codex.py, kiro.py, copilot.py, opencode.py, cursor.py, windsurf.py,
      cline.py, roo.py, continue_dev.py, gemini.py, goose.py, amazonq.py,
      aider.py, mcpb.py
    emitters.py          Section emitters (run_section_emitters dispatcher).
    jinja_renderer.py    Shared Jinja2 environment.
    manifest_builders.py JSON manifest dict builders (claude/codex/gemini/amazonq).
    mcp_builders.py      MCP shape variants (mcpServers/servers/opencode_embedded/amazonq).
    install_scripts.py   Bash install scripts for windsurf/cline/gemini/goose/amazonq.
    packagers.py         Deterministic ZIP archive builder for MCPB.
    orchestrator.py      build_one/build_all/release_one/release_all/check_drift.
    cli.py               Click CLI: setup/build/release/check subcommands.

CLI (canonical):
  agentic-plugins build              # build all backends + AGENTS.md
  agentic-plugins build claude       # build a single backend
  agentic-plugins check              # drift + validation
  agentic-plugins setup              # phase 'setup' (refresh-time work)
  agentic-plugins release [--dist]   # phase 'release' (package artifacts)

Backwards-compatible `transpile` shim still works for existing pre-commit
invocations that haven't been retrained.

Pluggable build phases (BuildPhase + PHASES class var) allow backends to
opt into multi-step pipelines (setup/build/release stages with topo-sorted
depends_on). Default behavior is the section-emitter dispatch — most
backends declare zero PHASES.

Verification:
  - Byte-identical output vs. pre-refactor snapshot (`diff -r` empty)
  - `agentic-plugins check` reports OK on both drift and validation passes
  - All 15 backends registered, AGENTS.md emitted at plugins/ root

Removed:
  - configs.yaml — every entry now lives as class vars on a backend module
  - schema.py — Pydantic models for configs.yaml are no longer needed
  - transpile.py — replaced by transpiler/orchestrator.py + transpiler/cli.py

Click added as a runtime dependency.
Closes outstanding gaps from the unification review against the plan.

Architecture changes:

  * Each backend is now a sub-package (backends/<name>/__init__.py) so
    backends can ship per-backend templates, smoke tests, or other
    auxiliary files. Imports updated from ..core/..registry to
    ...core/...registry to reflect the deeper nesting.

  * Jinja2 environment now uses ChoiceLoader to discover per-backend
    templates under backends/<name>/templates/ in addition to the shared
    transpiler/templates/ tree. Per-backend templates take priority.

  * Backwards-compat `transpile` entry point removed. Use `agentic-plugins`.

  * `agentic-plugins check` now runs BOTH drift and validation
    unconditionally and accumulates failures — a single CI run surfaces
    every problem (DA finding #4).

  * New `agentic-plugins smoke-test` subcommand: each backend can override
    smoke_test(ctx) to verify the generated plugin loads under the
    platform's CLI/IDE. AiderBackend ships the first implementation;
    other backends raise NotImplementedError → reported as 'skipped'.

  * Per-backend Click subcommand registration via class-level CLI_GROUP.
    Backends can mount custom commands at `agentic-plugins <name> <cmd>`.

  * MCPBBackend implements release() via a `copy-archive` build phase
    that copies ash.mcpb to dist/ash-{version}.mcpb for GitHub release
    attachment.

  * Manifest enforces kebab-case on `name` and `skill_name` via
    __post_init__ regex check (DA finding #9). Path-traversal is
    structurally impossible because malformed names fail at load time.

  * Generated Pydantic models (mcpb_manifest.Model, amazonq_agent.Agent)
    now run alongside the jsonschema validation in validate.py. Provides
    field-path-aware error reporting in addition to schema-level checks.
    Continue's RootModel is generated; Amazon Q's root class is named
    "Agent", not "Model" — both correctly mapped.

  * pydantic[email] required because MCPB schema validates author.email.

  * GitHub Actions: setup-uv@v3 -> @v6 (DA finding #14). Added
    smoke-test step to CI workflow.

  * README updated to reflect class-per-backend architecture and the
    Click CLI's four-phase shape.

Verification:
  * `agentic-plugins build` produces output byte-identical to snapshot
    taken before this commit
  * `agentic-plugins check` reports OK on both drift and validation
  * `agentic-plugins release mcpb --dist /tmp/test-dist` produces
    ash-1.0.0.mcpb as expected
  * `agentic-plugins smoke-test aider` passes (other 14 skipped)
Implements the CI-time check that platform CLIs/configs can load each
generated plugin. Three concrete behaviors per backend:

  1. Structural validation — JSON/YAML parses, required top-level keys
     present, file-size caps respected (Copilot 4000-char, Windsurf 12000-byte).
  2. CLI invocation when the platform ships a CLI (claude, codex, q,
     gemini, goose, opencode) — `<cli> --version` exits zero.
  3. Archive contents check for MCPB — open ash.mcpb, parse manifest.json,
     confirm name/version/manifest_version present.

BaseBackend._invoke_cli centralizes the subprocess pattern: missing-from-PATH
binaries soft-pass (CLI not installed in this env), broken wrapper installs
(toolbox-style symlinks pointing at deleted targets) also soft-pass, real
process failures hard-fail with stderr tail.

GUI-only platforms (Cursor, Windsurf, Cline, Roo, Kiro) and VS-Code-only
(Continue) hard-pass on structural checks alone — there's no CLI to exercise
beyond the load test the IDE itself does at startup.

Verified locally:

  agentic-plugins smoke-test
    [pass] aider, amazonq, claude, cline, codex, continue, copilot,
           cursor, gemini, goose, kiro, mcpb, opencode, roo, windsurf
    summary: 15 passed, 0 skipped, 0 failed

  agentic-plugins check
    OK: AGENTS.md + 15 platform outputs match _base/ source.
    OK: validation passed for 15 platforms + AGENTS.md.
Upgrades smoke_test() across 6 backends to invoke each platform's
purpose-built validator (no LLM, no auth) instead of `--version`:

  - claude: `claude plugin validate <dir>` (schema check on plugin.json,
    skill/agent/command frontmatter, hooks/hooks.json)
  - codex: `CODEX_HOME=$(mktemp -d) codex plugin marketplace add <dir>`
    (schema-validates marketplace.json + plugin.json; CODEX_HOME isolates
    CI runs)
  - gemini: `gemini extensions validate <dir>` (purpose-built no-LLM
    validator per packages/cli/src/commands/extensions/validate.ts)
  - amazonq: `q agent validate --path <agent.json>` (jsonschema check;
    always exits 0 — caller must scan stderr for WARNING/Error prefixes,
    handled in helper)
  - aider: `aider --exit --yes-always --config <conf>` (de facto config
    validator per aider/main.py — configargparse parses YAML before
    argparse short-circuits help/version)
  - mcpb: `mcpb validate <archive>` upgraded alongside structural check;
    also bumps manifest_version 0.3 -> 0.4 and populates entry_point

Splits BaseBackend._invoke_cli into two semantically distinct helpers
addressing devil's-advocate review findings:

  - _probe_cli_present: liveness probe for `--version`-class commands.
    Soft-skips on missing binary, broken wrappers (toolbox-style symlinks
    pointing at deleted .app bundles).
  - _invoke_validator: substantive validation. Soft-skips ONLY when the
    binary is fully absent; on-disk validator failures (including stderr
    "no such file or directory" — which is a legitimate signal for these
    commands) hard-fail. Falls back to stdout when stderr is empty.
    60s default timeout for filesystem-traversing validators.

Adds CLI version pinning via _base/cli_versions.json + new
BaseBackend._assert_version_pin helper. Each upgraded backend asserts
the installed CLI's major.minor matches the pinned value before running
the validator — catches upstream subcommand-shape changes early.

Adds smoke-test summary [skip] vs [pass] distinction (DA #8): backends
returning {ok:True, skipped:True} appear in a separate column instead
of being lumped with passes, so CI logs distinguish "12 passed, 3
skipped" from "15 passed". Skipped backends still don't fail the build.

Fixes Codex marketplace.json emission path: was at root, must be at
.claude-plugin/marketplace.json or .agents/plugins/marketplace.json
per MARKETPLACE_MANIFEST_RELATIVE_PATHS in
codex-rs/core-plugins/src/marketplace.rs. Without this, `codex plugin
marketplace add` rejected the directory.

Verified locally:

  agentic-plugins check
    OK: AGENTS.md + 15 platform outputs match _base/ source.
    OK: validation passed for 15 platforms + AGENTS.md.

  agentic-plugins smoke-test  (3 CLIs installed locally: claude, codex, mcpb)
    [pass]   claude: claude plugin validate ... OK
    [pass]   codex:  codex plugin marketplace add ... OK
    [pass]   mcpb:   ash.mcpb OK (manifest_version=0.4)
    [skip]   aider/amazonq/gemini/goose/opencode (CLI absent or broken)
    [pass]   the 9 IDE-only platforms (structural-only)
    summary: 10 passed, 5 skipped, 0 failed

In CI with all 5 missing CLIs installed at pinned versions, expect
15/15 pass. The skipped state never blocks the build; only real
validator failures do.
Adds transpiler/formats.py with 14 Format objects (claude-marketplace,
amazonq-agent, agentskills, mcpb-bundle, gemini-extension, continue-config,
opencode-config, vscode-mcp, cursor-rules, windsurf-rules, cline-rules,
roo-rules, goose-config, aider-config) and a `FORMAT` class var on each of
the 14 backends (kiro is left without a Format pending Powers-format work).

This decouples the *output shape* (Format: directory layout + schema URL +
spec URL) from the *consumer* (Agent / BaseBackend subclass: a CLI/IDE that
reads files in this shape). Three formats serve multiple agents today:

  - claude-marketplace -> claude, codex
    (Codex's plugin loader natively searches both .codex-plugin/plugin.json
     AND .claude-plugin/plugin.json per DISCOVERABLE_PLUGIN_MANIFEST_PATHS)
  - amazonq-agent -> amazonq (kiro-cli backend pending)
  - agentskills -> (no backend yet; available for future skill-only emission)

Adds an `agentic-plugins formats` subcommand listing each Format with its
spec/schema URLs and the agents that consume it. Updates smoke-test output
to suffix each line with `(format-name)` so shared-format relationships
are visible in CI logs:

  [pass]   claude (claude-marketplace): claude plugin validate ... OK
  [pass]   codex (claude-marketplace): env CODEX_HOME=... codex plugin
           marketplace add ... OK

This commit is deliberately additive. The section-emitter dispatch still
reads per-backend class vars (PLUGIN_MANIFEST/MCP/SKILL/etc); subsequent
commits can move layout from class vars into Format objects, deduplicating
shared-format backends. All 15 backends still pass build + check + smoke-test.

Also drops the orphan agentic-coding/plugins/codex/.codex-plugin/plugin.json
left over from the path migration to .claude-plugin/.

Verified locally:
  agentic-plugins check     -> 15 platforms + AGENTS.md, drift+validation OK
  agentic-plugins formats   -> 14 formats listed, claude+codex on the same one
  agentic-plugins smoke-test -> 10 passed, 5 skipped, 0 failed
Adds the negative-test suite the devil's-advocate review specifically
requested (DA finding #10): a malformed-validator scenario must hard-fail
through `_invoke_validator`, while a missing CLI must still soft-skip.
Three pytest cases prove the policy holds:

  1. CLI on PATH + non-zero exit + 'no such file or directory' in stderr
     -> ok=False (this would have silently passed under the old _invoke_cli).
  2. CLI absent from PATH -> ok=True with skipped=True.
  3. macOS .app bundle wrapper exec failure (toolbox/nvm-style stale
     symlinks) -> soft-skip with the documented narrow signature
     (.app/Contents/ + 'no such file or directory' + leading absolute path).

Updates .github/workflows/validate.yml to install the 5 platform CLIs
that ship real schema validators, each pinned to the major.minor in
_base/cli_versions.json: claude-code 2.1, codex 0.130, gemini-cli 0.41,
mcpb 2.1, opencode-ai 1.14. Plus aider 0.86.2, goose v1.33.1, kiro-cli
latest. Each backend's smoke_test() asserts the installed CLI's version
matches the pin before invoking the validator, so a drift-from-pin
install hard-fails the assertion rather than silently running against
an unsupported CLI shape.

Migrates Goose backend from .goosehints to AGENTS.md emission. Per
goose-docs.ai/docs/guides/context-engineering/using-goosehints, Goose's
default context-file list is `["AGENTS.md", ".goosehints"]` — AGENTS.md
takes precedence. Switching aligns with the universal instruction-file
already adopted by Codex, Cursor, Windsurf, Roo, Copilot, Kiro, OpenCode,
Aider, and Cline.

Marks Roo Code as deprecated in the README install table — Roo Code
shuts down 2026-05-15 (4 days from this commit on 2026-05-11). The Roo
team recommends Cline as the successor; we keep the backend but flag
it so users don't pick a sunsetting platform for new installs.

Verified locally:
  agentic-plugins check     -> 15 platforms + AGENTS.md, drift+validation OK
  pytest tests/             -> 3/3 pass
  agentic-plugins smoke-test -> 10 passed, 5 skipped, 0 failed
Adds a 16th backend, generic-skill, that ships the agentskills.io SKILL.md
format as a standalone artifact at agentic-coding/plugins/generic-skill/.
Five existing backends are marked SUPPORTS_GENERIC_SKILL = True (claude,
codex, opencode, cline, kiro) — they natively consume the format at
their respective skills directories. The per-platform plugin trees stay
primary; generic-skill ships alongside for custom integrations or for
agents that want the bare skill without the MCP wrapper.

Adds a CliTool dataclass and a CLI_TOOLS class var on every backend,
declaring which CLIs install or validate that backend. Each backend now
declares 1–3 CLI tools:
  - claude: claude, skills-ref
  - codex:  codex, claude (the artifact lives at .claude-plugin/plugin.json
            which both CLIs read), skills-ref
  - amazonq: q, kiro-cli (per the bidirectional Q v1 / kiro-cli compatibility
             documented in transpiler memory file project_format_taxonomy.md)
  - generic-skill: skills-ref (the format-level validator)
  ... etc.

The CliTool registry at transpiler/cli_tools.py is the single source of
truth for install commands and version pins. `_base/cli_versions.json`
drives the smoke-test version-pin assertions.

New CLI subcommands surface the matrix:
  - `agentic-plugins formats` shows agentskills as a format-only release
    with "natively consumed by: claude, cline, codex, kiro, opencode"
  - `agentic-plugins cli-tools` lists each backend's CLI tools with
    install commands + validate argv templates
  - `agentic-plugins matrix --validators-only` emits JSON for CI to
    consume as strategy.matrix.include

CI workflow restructured into three jobs:
  1. drift-and-validate: structural + drift + pytest (single runner, fast)
  2. matrix-config: invokes `agentic-plugins matrix --validators-only`
  3. smoke-test: parallel matrix of (backend, validator-CLI) pairs;
     fail-fast: false; each cell installs only the CLI it needs at the
     pinned version and runs `agentic-plugins smoke-test <backend>`.
     Adding a new backend or CLI declaration auto-expands the CI matrix.

The generic-skill backend's smoke_test() runs `skills-ref validate`
when on PATH, otherwise falls back to a structural check ensuring every
SKILL.md's frontmatter `name` matches its parent directory (per
agentskills.io spec).

Verified locally:
  agentic-plugins check     -> 16 platforms + AGENTS.md, drift+validation OK
  pytest tests/             -> 3/3 pass
  agentic-plugins formats   -> agentskills shows format-only release
  agentic-plugins cli-tools -> 16 backends, 17 CliTool entries
  agentic-plugins matrix    -> JSON matrix for CI consumption
  agentic-plugins smoke-test -> 10 passed, 6 skipped, 0 failed
@awsmadi awsmadi requested a review from a team as a code owner May 12, 2026 00:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(results): adapt standardized JSON output to AWS Security Finding Format (ASFF)

2 participants