fix(core): strip a BOM before the adapter import check, and split usage exits
Narrowing has_reference to bool(import_lines) meant a UTF-8 BOM hid the import line, since the BOM is not \s: a CLAUDE.md whose first line is @AGENTS.md failed with 'no reference to AGENTS.md' and was told to add the line already in front of it. Decoding is now strict too, so a non-UTF-8 adapter gets an encoding diagnostic instead of being mangled and then graded on the mangling. Usage errors move to exit 2. They shared exit 1 with real findings, while the skill tells the agent to fix any non-zero exit by editing the provider file. The whole-line import rule is kept deliberately -- accepting an inline @AGENTS.md would also accept one inside backticks, which is the silent-drop failure the validator exists to catch -- and the message now says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJJrm5YmacbwMdzZpXcoti
This commit is contained in:
@@ -23,7 +23,7 @@ Provide the path to the provider-specific file to convert (and the target repo r
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents |
|
||||
| `references/provider-matrix.md` | Loaded at Step 1 before searching, unless the target is already a known root `CLAUDE.md`: known files per provider, which ones resolve a cross-file import, and the validator flag each needs |
|
||||
| `references/provider-matrix.md` | Loaded at Step 1 before searching, unless the target is already a known root `CLAUDE.md`: known files per provider, which ones resolve a cross-file import, the validator flag each needs, and the rule that a standalone run and a run composed into by `agentsmd-author` behave identically |
|
||||
| `references/sources.md` | Provenance record — the in-repo ADR precedent this skill's design is modeled on |
|
||||
| `scripts/validate-adapter.sh` | Self-check gate: reference to AGENTS.md present, no excessive duplication, adapter stays thin |
|
||||
| `scripts/README.md` | Directory documentation for `scripts/` |
|
||||
|
||||
@@ -18,6 +18,8 @@ metadata:
|
||||
|
||||
- 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; do not assume a caller skill exists. Detect the provider file, confirm `AGENTS.md`, and run the closeout validator yourself in both cases (`references/provider-matrix.md`).
|
||||
|
||||
## Step 1 — Detect
|
||||
|
||||
Find the provider instruction file to convert. Before searching, read `references/provider-matrix.md` — skip it only when the target is already a known root `CLAUDE.md`, which is the common case.
|
||||
@@ -28,7 +30,7 @@ Then confirm `AGENTS.md` exists at the repo root. If it does not, stop and tell
|
||||
|
||||
Read the provider file and `AGENTS.md` side by side. Separate the provider file's content into two buckets: lines that restate what `AGENTS.md` already owns (universal rules, conventions, project overview) versus lines that are genuinely provider-specific (tool syntax, IDE behavior, model-specific instructions). Rewrite the provider file:
|
||||
|
||||
- **Providers with import syntax** (Claude Code): replace the redundant bucket with an `@AGENTS.md` (or correct relative path) import line, keep the provider-specific bucket below it.
|
||||
- **Providers with import syntax** (Claude Code): replace the redundant bucket with an `@AGENTS.md` (or correct relative path) import on a line of its own, keep the provider-specific bucket below it. An import folded into a sentence is not the thin-adapter shape and `scripts/validate-adapter.sh` will not credit it.
|
||||
- **Providers without import syntax** (Cursor, Copilot, etc.): replace the redundant bucket with a short pointer sentence mentioning `AGENTS.md`, keep the provider-specific bucket.
|
||||
|
||||
The provider file is the only file this skill ever writes. Never create or edit `AGENTS.md` — not in this step, not in any step, whatever the payoff looks like.
|
||||
@@ -43,7 +45,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`.
|
||||
Fix any `FAIL` by editing the provider file, and re-run until it exits `0`. Exit `2` is not a `FAIL`: it means the invocation or the input is wrong — a bad or missing argument, or a file that is not UTF-8 — so fix that, not the adapter.
|
||||
|
||||
## Step 4 — Report
|
||||
|
||||
|
||||
@@ -21,3 +21,12 @@ silently drops every rule the adapter was supposed to defer to.
|
||||
|
||||
Detection is a search, not a lookup: a repo may hold more than one of these, and each one converts
|
||||
independently against the same `AGENTS.md`.
|
||||
|
||||
## Standalone and composed runs behave identically
|
||||
|
||||
This skill is reached two ways: invoked directly by a user, and composed into by `agentsmd-author`
|
||||
once it has written or updated the repo's `AGENTS.md`. Behave identically either way — do not
|
||||
assume a caller skill exists. Detect the provider file yourself, confirm `AGENTS.md` yourself, and
|
||||
run the closeout validator yourself, rather than treating any step as already done by the caller or
|
||||
as something the caller will do afterwards. There is no handshake to rely on and no state passed
|
||||
in beyond the file paths.
|
||||
|
||||
@@ -31,6 +31,12 @@ Exit codes:
|
||||
0 Adapter file passes all checks
|
||||
1 One or more checks failed (empty file, no reference to AGENTS.md,
|
||||
excessive duplication, or file too long)
|
||||
2 Usage or input error — a bad or missing argument, a path that is not a
|
||||
file, or a file that is not UTF-8. Nothing was graded, so there is no
|
||||
FAIL line and no adapter edit to make: fix the invocation or the file's
|
||||
encoding and re-run. Kept distinct from 1 because the skill's own
|
||||
closeout tells the agent to fix every non-zero exit by editing the
|
||||
provider file, which for a mistyped flag edits the wrong file forever.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -51,12 +57,12 @@ while [[ $# -gt 0 ]]; do
|
||||
--max-lines)
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Error: --max-lines requires a value (a non-negative integer)." >&2
|
||||
exit 1
|
||||
exit 2
|
||||
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
|
||||
exit 2
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
@@ -71,7 +77,7 @@ if [[ ${#ARGS[@]} -lt 2 ]]; then
|
||||
echo "Error: adapter-file and agents-md-file are required." >&2
|
||||
echo "" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
exit 2
|
||||
fi
|
||||
|
||||
python3 -u - "${ARGS[0]}" "${ARGS[1]}" "$NO_IMPORT_SYNTAX" "$MAX_LINES" <<'PYTHON'
|
||||
@@ -85,15 +91,43 @@ max_lines = int(max_lines)
|
||||
|
||||
if not os.path.isfile(adapter_path):
|
||||
print(f"Error: '{adapter_path}' is not a file.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
sys.exit(2)
|
||||
if not os.path.isfile(agents_md_path):
|
||||
print(f"Error: '{agents_md_path}' is not a file.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
sys.exit(2)
|
||||
|
||||
with open(adapter_path, encoding="utf-8", errors="replace") as f:
|
||||
adapter_content = f.read()
|
||||
with open(agents_md_path, encoding="utf-8", errors="replace") as f:
|
||||
agents_md_content = f.read()
|
||||
|
||||
def read_text(path):
|
||||
r"""File contents as text, UTF-8, BOM stripped.
|
||||
|
||||
The BOM strip is not cosmetic. IMPORT_RE anchors on `^\s*@`, and a BOM is
|
||||
not `\s` in Python, so a CLAUDE.md saved by an editor that emits one had
|
||||
its first line — the `@AGENTS.md` import, which is the whole adapter —
|
||||
silently treated as prose. The check then said "no reference to AGENTS.md"
|
||||
told the author to add the line already sitting in front of them. Same
|
||||
class of silent BOM miss recorded in scripts/skill-size-check.sh; strip it
|
||||
at the reader so no later check has to know about it.
|
||||
|
||||
Decoding is strict, not errors="replace". Replacement mangles the file and
|
||||
the checks then grade the mangling: a UTF-16 adapter whose first line is
|
||||
`@AGENTS.md` decoded to interleaved NULs and failed as "no reference",
|
||||
which is a true FAIL for a false reason and points the fix at the wrong
|
||||
thing. A file this gate cannot read gets an encoding diagnostic and exit 2,
|
||||
the same policy the ADR-0020 validators' read_text() uses.
|
||||
"""
|
||||
try:
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
text = fh.read()
|
||||
except UnicodeDecodeError as exc:
|
||||
print(f"Error: '{path}' is not valid UTF-8 ({exc.reason} at byte "
|
||||
f"{exc.start}) — re-save it as UTF-8; this check does not guess "
|
||||
"at other encodings.", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
return text[1:] if text.startswith("\ufeff") else text
|
||||
|
||||
|
||||
adapter_content = read_text(adapter_path)
|
||||
agents_md_content = read_text(agents_md_path)
|
||||
|
||||
has_fail = False
|
||||
|
||||
@@ -124,8 +158,8 @@ if not has_reference:
|
||||
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 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(" Why: A thin adapter must import AGENTS.md with an `@AGENTS.md` line of its own; naming the file mid-sentence or inside backticks is prose this check will not credit, and merely naming it defers nothing.")
|
||||
print(" Fix: Put `@AGENTS.md` (or the equivalent relative path) alone on its own line, or pass --no-import-syntax if this provider resolves no imports.")
|
||||
print()
|
||||
|
||||
# --- Duplication check ---
|
||||
|
||||
@@ -148,7 +148,7 @@ EOF
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
echo "@AGENTS.md" > "$ADAPTER"
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD" --max-lines
|
||||
assert_failure
|
||||
assert_failure 2
|
||||
assert_output --partial "--max-lines requires a value"
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ EOF
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
echo "@AGENTS.md" > "$ADAPTER"
|
||||
run bash "$SCRIPT" --max-lines abc "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure
|
||||
assert_failure 2
|
||||
assert_output --partial "non-negative integer"
|
||||
}
|
||||
|
||||
@@ -168,6 +168,47 @@ EOF
|
||||
|
||||
@test "fails with a clear error when the adapter file argument is missing" {
|
||||
run bash "$SCRIPT"
|
||||
assert_failure
|
||||
assert_failure 2
|
||||
assert_output --partial "required"
|
||||
}
|
||||
|
||||
@test "a UTF-8 BOM before the @import line does not hide it" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
python3 -c "import sys; open(sys.argv[1], 'w', encoding='utf-8-sig').write('@AGENTS.md\n')" "$ADAPTER"
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "a usage error exits 2, a genuine finding exits 1" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
echo "@AGENTS.md" > "$ADAPTER"
|
||||
|
||||
run bash "$SCRIPT" --max-lines -3 "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure 2
|
||||
refute_output --partial "FAIL"
|
||||
|
||||
: > "$ADAPTER"
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure 1
|
||||
assert_output --partial "FAIL"
|
||||
}
|
||||
|
||||
@test "a non-UTF-8 adapter is reported as an encoding error, not as a missing reference" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
python3 -c "import sys; open(sys.argv[1], 'wb').write('@AGENTS.md\n'.encode('utf-16'))" "$ADAPTER"
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure 2
|
||||
assert_output --partial "not valid UTF-8"
|
||||
refute_output --partial "no reference"
|
||||
}
|
||||
|
||||
@test "an @AGENTS.md folded into a sentence fails, and the message says the import needs its own line" {
|
||||
ADAPTER="$TMPDIR/CLAUDE.md"
|
||||
cat > "$ADAPTER" <<'EOF'
|
||||
See @AGENTS.md for shared conventions.
|
||||
EOF
|
||||
run bash "$SCRIPT" "$ADAPTER" "$AGENTS_MD"
|
||||
assert_failure 1
|
||||
assert_output --partial "no reference"
|
||||
assert_output --partial "line of its own"
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Provide the path to the provider-specific file to convert (and the target repo r
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents |
|
||||
| `references/provider-matrix.md` | Loaded at Step 1 before searching, unless the target is already a known root `CLAUDE.md`: known files per provider, which ones resolve a cross-file import, and the validator flag each needs |
|
||||
| `references/provider-matrix.md` | Loaded at Step 1 before searching, unless the target is already a known root `CLAUDE.md`: known files per provider, which ones resolve a cross-file import, the validator flag each needs, and the rule that a standalone run and a run composed into by `agentsmd-author` behave identically |
|
||||
| `references/sources.md` | Provenance record — the in-repo ADR precedent this skill's design is modeled on |
|
||||
| `scripts/validate-adapter.sh` | Self-check gate: reference to AGENTS.md present, no excessive duplication, adapter stays thin |
|
||||
| `scripts/README.md` | Directory documentation for `scripts/` |
|
||||
|
||||
@@ -18,6 +18,8 @@ metadata:
|
||||
|
||||
- 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; do not assume a caller skill exists. Detect the provider file, confirm `AGENTS.md`, and run the closeout validator yourself in both cases (`references/provider-matrix.md`).
|
||||
|
||||
## Step 1 — Detect
|
||||
|
||||
Find the provider instruction file to convert. Before searching, read `references/provider-matrix.md` — skip it only when the target is already a known root `CLAUDE.md`, which is the common case.
|
||||
@@ -28,7 +30,7 @@ Then confirm `AGENTS.md` exists at the repo root. If it does not, stop and tell
|
||||
|
||||
Read the provider file and `AGENTS.md` side by side. Separate the provider file's content into two buckets: lines that restate what `AGENTS.md` already owns (universal rules, conventions, project overview) versus lines that are genuinely provider-specific (tool syntax, IDE behavior, model-specific instructions). Rewrite the provider file:
|
||||
|
||||
- **Providers with import syntax** (Claude Code): replace the redundant bucket with an `@AGENTS.md` (or correct relative path) import line, keep the provider-specific bucket below it.
|
||||
- **Providers with import syntax** (Claude Code): replace the redundant bucket with an `@AGENTS.md` (or correct relative path) import on a line of its own, keep the provider-specific bucket below it. An import folded into a sentence is not the thin-adapter shape and `scripts/validate-adapter.sh` will not credit it.
|
||||
- **Providers without import syntax** (Cursor, Copilot, etc.): replace the redundant bucket with a short pointer sentence mentioning `AGENTS.md`, keep the provider-specific bucket.
|
||||
|
||||
The provider file is the only file this skill ever writes. Never create or edit `AGENTS.md` — not in this step, not in any step, whatever the payoff looks like.
|
||||
@@ -43,7 +45,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`.
|
||||
Fix any `FAIL` by editing the provider file, and re-run until it exits `0`. Exit `2` is not a `FAIL`: it means the invocation or the input is wrong — a bad or missing argument, or a file that is not UTF-8 — so fix that, not the adapter.
|
||||
|
||||
## Step 4 — Report
|
||||
|
||||
|
||||
@@ -21,3 +21,12 @@ silently drops every rule the adapter was supposed to defer to.
|
||||
|
||||
Detection is a search, not a lookup: a repo may hold more than one of these, and each one converts
|
||||
independently against the same `AGENTS.md`.
|
||||
|
||||
## Standalone and composed runs behave identically
|
||||
|
||||
This skill is reached two ways: invoked directly by a user, and composed into by `agentsmd-author`
|
||||
once it has written or updated the repo's `AGENTS.md`. Behave identically either way — do not
|
||||
assume a caller skill exists. Detect the provider file yourself, confirm `AGENTS.md` yourself, and
|
||||
run the closeout validator yourself, rather than treating any step as already done by the caller or
|
||||
as something the caller will do afterwards. There is no handshake to rely on and no state passed
|
||||
in beyond the file paths.
|
||||
|
||||
@@ -31,6 +31,12 @@ Exit codes:
|
||||
0 Adapter file passes all checks
|
||||
1 One or more checks failed (empty file, no reference to AGENTS.md,
|
||||
excessive duplication, or file too long)
|
||||
2 Usage or input error — a bad or missing argument, a path that is not a
|
||||
file, or a file that is not UTF-8. Nothing was graded, so there is no
|
||||
FAIL line and no adapter edit to make: fix the invocation or the file's
|
||||
encoding and re-run. Kept distinct from 1 because the skill's own
|
||||
closeout tells the agent to fix every non-zero exit by editing the
|
||||
provider file, which for a mistyped flag edits the wrong file forever.
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -51,12 +57,12 @@ while [[ $# -gt 0 ]]; do
|
||||
--max-lines)
|
||||
if [[ $# -lt 2 ]]; then
|
||||
echo "Error: --max-lines requires a value (a non-negative integer)." >&2
|
||||
exit 1
|
||||
exit 2
|
||||
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
|
||||
exit 2
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
@@ -71,7 +77,7 @@ if [[ ${#ARGS[@]} -lt 2 ]]; then
|
||||
echo "Error: adapter-file and agents-md-file are required." >&2
|
||||
echo "" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
exit 2
|
||||
fi
|
||||
|
||||
python3 -u - "${ARGS[0]}" "${ARGS[1]}" "$NO_IMPORT_SYNTAX" "$MAX_LINES" <<'PYTHON'
|
||||
@@ -85,15 +91,43 @@ max_lines = int(max_lines)
|
||||
|
||||
if not os.path.isfile(adapter_path):
|
||||
print(f"Error: '{adapter_path}' is not a file.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
sys.exit(2)
|
||||
if not os.path.isfile(agents_md_path):
|
||||
print(f"Error: '{agents_md_path}' is not a file.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
sys.exit(2)
|
||||
|
||||
with open(adapter_path, encoding="utf-8", errors="replace") as f:
|
||||
adapter_content = f.read()
|
||||
with open(agents_md_path, encoding="utf-8", errors="replace") as f:
|
||||
agents_md_content = f.read()
|
||||
|
||||
def read_text(path):
|
||||
r"""File contents as text, UTF-8, BOM stripped.
|
||||
|
||||
The BOM strip is not cosmetic. IMPORT_RE anchors on `^\s*@`, and a BOM is
|
||||
not `\s` in Python, so a CLAUDE.md saved by an editor that emits one had
|
||||
its first line — the `@AGENTS.md` import, which is the whole adapter —
|
||||
silently treated as prose. The check then said "no reference to AGENTS.md"
|
||||
told the author to add the line already sitting in front of them. Same
|
||||
class of silent BOM miss recorded in scripts/skill-size-check.sh; strip it
|
||||
at the reader so no later check has to know about it.
|
||||
|
||||
Decoding is strict, not errors="replace". Replacement mangles the file and
|
||||
the checks then grade the mangling: a UTF-16 adapter whose first line is
|
||||
`@AGENTS.md` decoded to interleaved NULs and failed as "no reference",
|
||||
which is a true FAIL for a false reason and points the fix at the wrong
|
||||
thing. A file this gate cannot read gets an encoding diagnostic and exit 2,
|
||||
the same policy the ADR-0020 validators' read_text() uses.
|
||||
"""
|
||||
try:
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
text = fh.read()
|
||||
except UnicodeDecodeError as exc:
|
||||
print(f"Error: '{path}' is not valid UTF-8 ({exc.reason} at byte "
|
||||
f"{exc.start}) — re-save it as UTF-8; this check does not guess "
|
||||
"at other encodings.", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
return text[1:] if text.startswith("\ufeff") else text
|
||||
|
||||
|
||||
adapter_content = read_text(adapter_path)
|
||||
agents_md_content = read_text(agents_md_path)
|
||||
|
||||
has_fail = False
|
||||
|
||||
@@ -124,8 +158,8 @@ if not has_reference:
|
||||
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 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(" Why: A thin adapter must import AGENTS.md with an `@AGENTS.md` line of its own; naming the file mid-sentence or inside backticks is prose this check will not credit, and merely naming it defers nothing.")
|
||||
print(" Fix: Put `@AGENTS.md` (or the equivalent relative path) alone on its own line, or pass --no-import-syntax if this provider resolves no imports.")
|
||||
print()
|
||||
|
||||
# --- Duplication check ---
|
||||
|
||||
Reference in New Issue
Block a user