fix(core): make --no-import-syntax actually change the adapter validation

Both branches of the flag reduced to the same expression, so the option was
inert: a caller who asked for the no-import form got the import-form check
anyway and a passing result that meant nothing.

Two further defects in the same validator: --max-lines failed silently when
given a value it could not use, and the Fix text told the agent to edit
AGENTS.md when the offending content is the provider adapter's. The boundary
clauses now name the operation being routed rather than the file type, which
was ambiguous where both skills touch the same file.

Addresses #115.
This commit is contained in:
2026-08-31 08:01:45 +00:00
parent 14af50bc07
commit 1c3af75642
13 changed files with 131 additions and 76 deletions

View File

@@ -31,6 +31,6 @@ Provide the path to the provider-specific file to convert (and the target repo r
| `tests/validate-adapter.bats` | (source-only) Bats test suite for `scripts/validate-adapter.sh` |
Rows marked **(source-only)** exist in the authoring source (`.apm/skills/provider-adapter-author/`)
but are not present in an installed plugin: `scripts/sync-plugin-content.sh` strips
but are not present in an installed plugin: the repo's `scripts/sync-plugin-content.sh` strips
`<category>/<name>/tests` when it generates the flat mirror, because these are dev-time fixtures no
plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install.

View File

@@ -2,7 +2,8 @@
name: provider-adapter-author
description: >
Use when a provider file (CLAUDE.md, .cursor rules, copilot-instructions)
duplicating the repo's AGENTS.md should be cut to a thin adapter.
duplicating the repo's AGENTS.md should be cut to a thin adapter — "make
CLAUDE.md just import AGENTS.md".
Not writing the AGENTS file -> `agentsmd-author`.
Not auditing the AGENTS file -> `agentsmd-audit`.
allowed-tools: Bash Read Edit Write
@@ -16,7 +17,6 @@ metadata:
## Gotchas
- Assume a provider has no cross-file import mechanism until you have confirmed it has one. Claude Code is the exception, not the rule: a `CLAUDE.md` may consist of nothing but `@path` lines, while the same `@AGENTS.md` line in a Cursor rule or a Copilot instructions file is inert text no tool resolves. Pass `--no-import-syntax` to `scripts/validate-adapter.sh` for those providers.
- Works standalone or composed-into by `agentsmd-author` — behave identically either way; don't assume a caller skill exists.
## Step 1 — Detect
@@ -43,7 +43,7 @@ Run the bundled check before finishing — this is the skill's own closeout gate
bash scripts/validate-adapter.sh [--no-import-syntax] [--max-lines N] <adapter-file> <agents-md-file>
```
Fix any `FAIL` by editing the provider file, and re-run until it exits `0`. The size `FAIL` advises moving provider-agnostic content into `AGENTS.md`; disregard that half of its wording and delete the redundant lines instead.
Fix any `FAIL` by editing the provider file, and re-run until it exits `0`.
## Step 4 — Report

View File

@@ -16,10 +16,15 @@ Arguments:
Options:
--no-import-syntax The target provider has no native cross-file import
mechanism. Accept a plain-text pointer mention of
"AGENTS.md" instead of requiring an @import-style line.
mechanism. Require a plain-text pointer line naming
"AGENTS.md" instead of an @import-style line; an
@AGENTS.md line alone does not satisfy it, because
such a provider never resolves it. Without this flag
an actual @import line is required, and naming
AGENTS.md in prose alone does not satisfy it.
--max-lines N Max non-blank lines allowed in the adapter file before
it's considered no longer "thin". Default: 60.
it's considered no longer "thin". Must be a
non-negative integer. Default: 60.
--help, -h Show this help and exit 0.
Exit codes:
@@ -44,7 +49,15 @@ while [[ $# -gt 0 ]]; do
shift
;;
--max-lines)
MAX_LINES="${2:-}"
if [[ $# -lt 2 ]]; then
echo "Error: --max-lines requires a value (a non-negative integer)." >&2
exit 1
fi
MAX_LINES="$2"
if [[ ! "$MAX_LINES" =~ ^[0-9]+$ ]]; then
echo "Error: --max-lines expects a non-negative integer, got '$MAX_LINES'." >&2
exit 1
fi
shift 2
;;
*)
@@ -94,21 +107,25 @@ if not adapter_content.strip():
IMPORT_RE = re.compile(r'(?m)^\s*@\S*AGENTS\.md\s*$')
lines = adapter_content.splitlines()
import_lines = [ln for ln in lines if IMPORT_RE.match(ln)]
# A prose pointer is any line naming AGENTS.md that is not itself an import
# line — an inert `@AGENTS.md` in a provider that resolves no imports points
# a reader at nothing.
pointer_lines = [ln for ln in lines if not IMPORT_RE.match(ln) and "AGENTS.md" in ln]
if no_import_syntax:
has_reference = "AGENTS.md" in adapter_content
has_reference = bool(pointer_lines)
else:
has_reference = bool(import_lines) or "AGENTS.md" in adapter_content
has_reference = bool(import_lines)
if not has_reference:
has_fail = True
print(f"FAIL Adapter has no reference to AGENTS.md — {adapter_path}")
if no_import_syntax:
print(" Why: This provider has no import syntax, so the adapter must at least mention AGENTS.md as a text pointer.")
print(" Why: This provider resolves no cross-file import, so the adapter must point at AGENTS.md in prose; an `@AGENTS.md` line here is inert text.")
print(" Fix: Add a sentence like \"See AGENTS.md at the repo root for shared conventions.\"")
else:
print(" Why: A thin adapter must import AGENTS.md (e.g. `@AGENTS.md`) rather than silently omitting it.")
print(" Fix: Add an `@AGENTS.md` (or equivalent relative path) import line.")
print(" Why: A thin adapter must import AGENTS.md with an `@AGENTS.md` line; merely naming the file in prose defers nothing.")
print(" Fix: Add an `@AGENTS.md` (or equivalent relative path) import line, or pass --no-import-syntax if this provider resolves no imports.")
print()
# --- Duplication check ---
@@ -132,7 +149,7 @@ if non_blank_count > max_lines:
has_fail = True
print(f"FAIL Adapter is not thin — {adapter_path}")
print(f" Why: {non_blank_count} non-blank lines exceeds the {max_lines}-line threshold for a thin adapter.")
print(" Fix: Move provider-agnostic content into AGENTS.md; keep only genuinely provider-specific additions here.")
print(" Fix: Delete the lines already covered by AGENTS.md; keep only genuinely provider-specific additions here.")
print()
if has_fail: