From cd3e6638a182bc2a93304ca23152deea1f7869ad Mon Sep 17 00:00:00 2001 From: Shashwat Jha Date: Thu, 30 Jul 2026 21:46:58 +0530 Subject: [PATCH 1/6] Add support for .mts and .cts file types --- src/agentguard/scanner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/agentguard/scanner.py b/src/agentguard/scanner.py index 8d2868f..52d25de 100644 --- a/src/agentguard/scanner.py +++ b/src/agentguard/scanner.py @@ -23,6 +23,8 @@ ".cjs": "javascript", ".ts": "typescript", ".tsx": "typescript", + ".mts": "typescript", + ".cts": "typescript", ".json": "manifest", ".txt": "manifest", ".toml": "manifest", From 952d9f1d43d82ba29f1320271591f6e685da5c1f Mon Sep 17 00:00:00 2001 From: Shashwat Jha Date: Thu, 30 Jul 2026 21:47:49 +0530 Subject: [PATCH 2/6] Add tests for modern TypeScript source discovery --- tests/test_discovery.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/test_discovery.py diff --git a/tests/test_discovery.py b/tests/test_discovery.py new file mode 100644 index 0000000..ce35719 --- /dev/null +++ b/tests/test_discovery.py @@ -0,0 +1,40 @@ +"""Source discovery and language mapping tests.""" + +from __future__ import annotations + +from pathlib import Path + +import pytest + +from agentguard.config import Config +from agentguard.scanner import LANGUAGES, Scanner + + +@pytest.mark.parametrize("extension", [".mts", ".cts"]) +def test_discovers_modern_typescript_extension(project: Path, extension: str) -> None: + (project / f"agent{extension}").write_text("execSync(command)", encoding="utf-8") + result = Scanner().scan(project) + assert result.files_scanned == 1 + assert "AG002" in {finding.rule_id for finding in result.findings} + + +@pytest.mark.parametrize("extension", [".mts", ".cts"]) +def test_modern_typescript_extension_maps_to_typescript(extension: str) -> None: + assert LANGUAGES[extension] == "typescript" + + +@pytest.mark.parametrize("extension", [".mts", ".cts"]) +def test_excludes_vendor_directory_for_modern_typescript(project: Path, extension: str) -> None: + vendor = project / "node_modules" + vendor.mkdir() + (vendor / f"bad{extension}").write_text("execSync(command)", encoding="utf-8") + result = Scanner().scan(project) + assert result.files_scanned == 0 + assert result.findings == [] + + +@pytest.mark.parametrize("extension", [".mts", ".cts"]) +def test_skips_oversized_modern_typescript_file(project: Path, extension: str) -> None: + (project / f"large{extension}").write_text("x" * 2000, encoding="utf-8") + result = Scanner(Config(max_file_size_kb=1)).scan(project) + assert result.skipped_files == 1 From 6792edbb6328493895efcd566250c0a97629a2e0 Mon Sep 17 00:00:00 2001 From: Shashwat Jha Date: Thu, 30 Jul 2026 21:48:35 +0530 Subject: [PATCH 3/6] Add agent_prompt.mts for web content summarization --- tests/corpus/true_positives/agent_prompt.mts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/corpus/true_positives/agent_prompt.mts diff --git a/tests/corpus/true_positives/agent_prompt.mts b/tests/corpus/true_positives/agent_prompt.mts new file mode 100644 index 0000000..2d5504f --- /dev/null +++ b/tests/corpus/true_positives/agent_prompt.mts @@ -0,0 +1,7 @@ +// ESM TypeScript module (.mts) - web content interpolated directly into a prompt. +import { callModel } from "./model.js"; + +export async function summarize(web_content: string): Promise { + const prompt = `Summarize the following page for the user: ${web_content}`; + return callModel(prompt); +} From 2e9cc705cb9d8e48ca699acba775045de9a36529 Mon Sep 17 00:00:00 2001 From: Shashwat Jha Date: Thu, 30 Jul 2026 21:49:55 +0530 Subject: [PATCH 4/6] Add agent_prompt.mts to TypeScript rule manifest Added agent_prompt.mts to the manifest with expectations and reasoning for TypeScript rules. --- tests/corpus/manifest.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/corpus/manifest.yml b/tests/corpus/manifest.yml index dbdc749..ffdfd64 100644 --- a/tests/corpus/manifest.yml +++ b/tests/corpus/manifest.yml @@ -77,6 +77,17 @@ true_positives: expect: [AG002] why: execSync on a caller-supplied command in TypeScript. + agent_prompt.mts: + origin: written + expect: [AG004] + why: >- + web_content interpolated into a template-literal prompt in a `.mts` (ESM TypeScript) + module. `.mts`/`.cts` map to the `typescript` language in LANGUAGES, and every + TypeScript-aware rule must declare `typescript` in RuleMetadata.languages to see + these files at all - this pins that AG004 specifically stays wired up, not just + AG002 (already covered by agent_tools.ts), so a rule that forgets to list + `typescript` fails the benchmark instead of silently skipping .mts/.cts files. + .env: origin: written expect: [AG001] From 739a98c6dcf557c6440e60f13f3e0e744716f01c Mon Sep 17 00:00:00 2001 From: Shashwat Jha Date: Thu, 30 Jul 2026 21:51:32 +0530 Subject: [PATCH 5/6] Add TypeScript source discovery mapping details Updated changelog to include TypeScript source discovery mapping. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62298e5..15b766e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -116,6 +116,9 @@ All notable changes follow [Keep a Changelog](https://keepachangelog.com/en/1.1. - Terminal, JSON, Markdown, and SARIF 2.1.0 reporting. - Configurable severity thresholds, rule suppression, severity overrides, and module/entry-point plugins. - Docker image, typed Python package, tests, CI, CodeQL, dependency review, release workflow, and open-source governance files. +- `.mts`/`.cts` source discovery: these now map to the `typescript` language, so existing + TypeScript-aware rules (AG002, AG004, AG006, AG007, etc.) run against them with no + rule-level changes. [Unreleased]: https://github.com/amic25/agentguard/commits/main [0.1.0]: # (never published - no tag exists) From ed55508ea6521281d0e836f592249ba703c8fdcf Mon Sep 17 00:00:00 2001 From: Shashwat Jha Date: Thu, 30 Jul 2026 21:52:34 +0530 Subject: [PATCH 6/6] Remove section on '.mts' and '.cts' recognition Removed the section about recognizing '.mts' and '.cts' extensions from the GOOD_FIRST_ISSUES document. --- docs/GOOD_FIRST_ISSUES.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/GOOD_FIRST_ISSUES.md b/docs/GOOD_FIRST_ISSUES.md index 36cecd6..e10e0d3 100644 --- a/docs/GOOD_FIRST_ISSUES.md +++ b/docs/GOOD_FIRST_ISSUES.md @@ -21,8 +21,3 @@ Create a dependency-free plain reporter for CI logs that disable color. Preserve **Labels:** `good first issue`, `documentation` Add a tested GitLab CI example under `docs/integrations/`. Explain exit thresholds and artifact retention without claiming native features AgentGuard does not provide. - -## Recognize `.mts` and `.cts` - -**Labels:** `good first issue`, `javascript`, `scanner` -Treat modern TypeScript module extensions as TypeScript sources. Add discovery tests and update the supported file list.