diff --git a/scripts/lint-artifact.mjs b/scripts/lint-artifact.mjs index eec5ab0..f8252e6 100644 --- a/scripts/lint-artifact.mjs +++ b/scripts/lint-artifact.mjs @@ -137,6 +137,8 @@ function lintOne(file) { // --- clipboard guard --- if (/navigator\.clipboard\.writeText/.test(html)) { + const hasHelper = /(?:const|function|let|var)\s+writeClipboard\b/.test(html); + if (!hasHelper) fails.push("navigator.clipboard.writeText appears without a writeClipboard helper in the same file"); const guarded = /navigator\.clipboard\s*&&\s*navigator\.clipboard\.writeText|navigator\.clipboard\?\.writeText/.test(html); if (!guarded) fails.push("navigator.clipboard.writeText called without guarding navigator.clipboard first"); } diff --git a/tests/test_linters.py b/tests/test_linters.py index b72fc66..3d40fe9 100644 --- a/tests/test_linters.py +++ b/tests/test_linters.py @@ -417,6 +417,35 @@ def test_lint_artifact_against_dropped_copy_prompt_fails(tmp_path): assert "copy-as-prompt" in r.stdout +def test_lint_artifact_unguarded_clipboard_fails(tmp_path): + bad = tmp_path / "unguarded.html" + bad.write_text( + _META_HEAD + + '