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

@@ -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: