feat: agentic-coding transpiler — single-source-of-truth across 15 AI agent platforms#331
Open
awsmadi wants to merge 17 commits into
Open
feat: agentic-coding transpiler — single-source-of-truth across 15 AI agent platforms#331awsmadi wants to merge 17 commits into
awsmadi wants to merge 17 commits into
Conversation
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
rafaelpereyra
approved these changes
May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
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.ash-agent-plugins/; zero collision with the rest of the codebase.Closes #60.
What's included
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