Skip to content

Latest commit

 

History

History
344 lines (282 loc) · 16.3 KB

File metadata and controls

344 lines (282 loc) · 16.3 KB

Experimental TypeScript/JavaScript Provider

Agent Maintainer includes an experimental TypeScript/JavaScript ecosystem provider. It is disabled by default and only runs commands that the repository configures explicitly.

The provider exists to validate the ecosystem-provider architecture without weakening Python behavior or pretending every JavaScript repository uses the same package manager, linter, test runner, or build layout.

Configuration

Enable the provider by supplying explicit commands:

[tool.agent_maintainer]
enable_typescript = true
typescript_lint_command = ["npm", "run", "lint"]
typescript_typecheck_command = ["npm", "run", "typecheck"]
typescript_test_command = ["npm", "test", "--", "--runInBand"]
typescript_package_manager_audit_manager = "npm"
typescript_package_manager_audit_command = ["npm", "audit", "--json"]

For pnpm projects, keep the same explicit-command shape:

[tool.agent_maintainer]
enable_typescript = true
typescript_lint_command = ["pnpm", "run", "lint"]
typescript_typecheck_command = ["pnpm", "run", "typecheck"]
typescript_test_command = ["pnpm", "run", "test"]
typescript_knip_command = ["pnpm", "exec", "knip", "--reporter", "json"]
typescript_dependency_cruiser_command = [
  "pnpm", "exec", "depcruise", "--output-type", "json", "src",
]
typescript_package_manager_audit_manager = "pnpm"
typescript_package_manager_audit_command = ["pnpm", "audit", "--json"]

For Vite/Vitest projects, prefer repository scripts over inferred commands:

[tool.agent_maintainer]
enable_typescript = true
typescript_lint_command = ["npm", "run", "lint"]
typescript_typecheck_command = ["npm", "run", "typecheck"]
typescript_test_command = ["npm", "run", "test", "--", "--run"]

Command arrays are passed directly to subprocess execution. They are not shell strings.

Profile membership is configurable:

[tool.agent_maintainer]
typescript_lint_profiles = ["precommit", "full", "ci"]
typescript_typecheck_profiles = ["full", "ci"]
typescript_test_profiles = ["full", "ci"]
typescript_knip_profiles = ["full", "ci"]
typescript_dependency_cruiser_profiles = ["full", "ci"]
typescript_package_manager_audit_profiles = ["full", "ci"]

Default profiles are:

Check Default Profiles
typescript-lint precommit, full, ci
typescript-typecheck full, ci
typescript-test full, ci
typescript-knip full, ci
typescript-dependency-cruiser full, ci
typescript-package-manager-audit full, ci

typescript_knip_profiles defaults to full and ci. Knip stays out of precommit by default because it normally analyzes the whole repository. typescript_dependency_cruiser_profiles also defaults to full and ci; architecture cruising is repository-wide and stays out of precommit by default.

typescript_package_manager_audit_manager is required whenever the audit command is configured. It must be one of npm, pnpm, yarn, or bun; the provider never infers the manager from a lockfile, packageManager, or command text. Workspace audit commands remain explicit under the workspace's configuration and use the root audit profile selection.

If enable_typescript = true but a command is empty, the corresponding check is reported as an optional skip. Agent Maintainer will not guess the package manager or invent a command.

doctor stays silent when the provider is disabled. When the provider is enabled, doctor reports whether TypeScript commands are configured and whether configured command executables are available on PATH, including repo-local node_modules/.bin. Empty-command doctor hints point to stable output formats that improve repair facts: ESLint JSON, tsc --pretty false, Jest/Vitest JSON, and existing coverage-summary.json or lcov.info artifacts. After commands are configured, doctor may emit a non-blocking PASS advisory row when command text does not visibly mention those parser-friendly outputs; the row is guidance only and still does not infer package managers or invent commands.

Structured Output

Agent Maintainer can extract compact summaries and exact repair facts from configured-command output:

  • typescript-typecheck: tsc --pretty false style diagnostics such as src/app.ts(4,9): error TS2322: ...;
  • typescript-lint: ESLint JSON formatter output;
  • typescript-test: Jest-compatible JSON output with testResults and assertionResults, Vitest task-style JSON fixtures, Istanbul coverage-summary.json, and LCOV lcov.info artifacts;
  • typescript-knip: Knip --reporter json output for unused files, exports, types, dependencies, binaries, unlisted dependencies, and unresolved imports or binaries;
  • typescript-dependency-cruiser: dependency-cruiser cruise-result JSON from the configured command's summary.violations array;
  • typescript-package-manager-audit: explicit npm, pnpm, Yarn, or Bun JSON or NDJSON audit output normalized into bounded advisory vulnerability facts;
  • osv-scanner: OSV Scanner v2 output from the existing ecosystem-neutral manual gate.

Knip findings are sorted before Agent Maintainer retains at most 500 normalized findings. Compact failed-check summaries contain at most 50 total lines, including an omission marker when needed; exact context packs keep their existing 5-fact-per-check bound. Line and column values are preserved exactly as Knip reports them. Cycles, duplicates, catalogs, enum members, and namespace/class member categories are ignored in this phase.

Only repository-relative paths are emitted. Absolute and parent-traversal paths are rejected so local machine paths cannot enter summaries or repair context.

Phase 192 Package-Manager Audit Boundary

Phase 192 adds explicit package-manager audit facts without selecting or executing a package manager on the repository's behalf. A configured root or workspace check supplies both typescript_package_manager_audit_manager and the exact typescript_package_manager_audit_command; the command's exit status is preserved. npm, pnpm, Yarn, and Bun report shapes are accepted only when the manager is declared, and malformed neighboring records are skipped without discarding valid findings.

The shared parser emits deterministic, bounded advisory facts with the manager, workspace, package, severity, advisory identifiers, vulnerable ranges, fixed versions, dependency scope/directness, and safe repository-relative path provenance when present. It retains at most 500 findings, 25 values per list, 200-character scalar fields, 500-character display paths, and 50 summary lines; unsafe paths remain display-only. Clean reports with no findings pass, while vulnerability findings stay advisory and do not create a blocking gate or change the configured process exit status.

Synthetic npm, pnpm, Yarn, and Bun fixtures cover the normalized contract and malformed-input behavior. Pinned public npm and pnpm projections replay offline with canonical report hashes; Yarn and Bun remain fixture-only until equivalent public evidence is collected. TypeScript/JavaScript remains experimental.

Advisory LCOV Changed-Line Coverage

When a repository already produces LCOV, report executable changed-line coverage without running a JavaScript tool:

python -m agent_maintainer test-intel typescript-coverage \
  --lcov coverage/lcov.info \
  --base-ref origin/main

For workspace-relative records such as SF:src/app.ts, supply the workspace root explicitly:

python -m agent_maintainer test-intel typescript-coverage \
  --lcov packages/web/coverage/lcov.info \
  --source-root packages/web \
  --staged \
  --format json

The report classifies non-deleted TypeScript/JavaScript source paths from the Git diff, intersects them with executable LCOV DA lines, and calculates one weighted percentage from total covered executable changed lines. Changed comments and other non-executable lines do not enter the denominator. Changed source missing from LCOV is listed separately instead of being silently counted as uncovered.

The LCOV file and source root must resolve inside the repository. Unsafe or ambiguous paths never match source. Input, retained file facts, and text details are bounded. A valid report exits successfully regardless of its percentage; there is no threshold, ratchet, configured provider check, or verifier profile. The command never runs Jest, Vitest, Istanbul, V8, npm, pnpm, Yarn, Bun, or diff-cover.

Agent Maintainer honors the configured Knip command's exit status. Exit 0 passes, while exits 1 and 2 fail through the normal check runner. It does not add --no-exit-code, thresholds, reporter flags, or version enforcement. Pin Knip through the repository's exact dependency or lockfile and include --reporter json in the explicit command when structured facts are wanted.

These parsers are repair-loop helpers. They do not require new config fields, and malformed output falls back to the normal bounded raw-log summary.

Phase 181 Dependency-Cruiser Boundary

Phase 181 dependency-cruiser architecture facts are complete. For this provider, dependency-cruiser is the TypeScript/JavaScript architecture-boundary counterpart to Tach. It does not replace Python Tach, Archguard decision notes, or declared Nx boundary policy.

Agent Maintainer runs only the exact root or workspace typescript_dependency_cruiser_command array and preserves its exit status. It never appends --output-type json, installs dependency-cruiser, generates a configuration, chooses a package manager, or invents boundary rules. Include a repository-owned JSON reporter argument when structured facts are wanted. Cruise-result output has a five-million-character capture limit so realistic module graphs are not cut at the generic command limit. Exit-zero findings are reported as non-blocking warning summaries; the process still passes.

The parser reads only summary.violations. It preserves supported error, warn, and info severities, documented violation types, rule names, and safe source and target labels. Findings are sorted before retaining at most 500 normalized findings. Compact summaries contain at most 50 total lines, and context packs retain five facts per failed check.

Only safe repository-relative sources become context targets. Absolute, drive-qualified, traversal, control-bearing, dot, empty, and overlong paths are non-targetable. Safe basenames can remain visible; violation targets are always display-only. Malformed neighbors and unsupported severity or type values are skipped independently.

Pinned npm decentralized-identity/dwn-sdk-js and pnpm-workspace hicommonwealth/commonwealth projections replay offline with dependency-cruiser 17.0.2. They record exact public revisions, Node and tool versions, config and lockfile hashes, raw-report hashes and byte counts, commands, exit status, and bounded normalized violations. Phase 192 package-manager audit facts are complete; declared Nx boundaries and blocking architecture policy remain later work. TypeScript/JavaScript remains experimental.

Phase 180 OSV Boundary

Phase 180 OSV dependency facts are complete. TypeScript support uses the existing ecosystem-neutral osv-scanner gate; it does not add a provider command or infer npm, pnpm, Yarn, or Bun behavior. The global gate remains explicitly enabled and runs in the manual profile by default.

The shared OSV Scanner v2 parser emits one fact per OSV alias group. Facts include the package ecosystem, name, version, advisory aliases, safe lockfile provenance, and fixed versions when OSV range events provide them. Valid repository-relative paths can become context targets. Absolute paths, parent traversal, and Windows drive paths are redacted to a safe filename label.

The parser retains at most 500 normalized findings, failed-check summaries contain at most 50 total lines, and context packs keep the existing five facts per check. Individual scalars are capped at 200 characters, alias and fix lists at 25 values each, and rendered messages at 1,000 characters. Synthetic tests cover partial groups, malformed neighbors, control characters, and unsafe paths. Bounded projections from pinned pnpm eslint-plugin-vitest and npm node-typescript-boilerplate revisions provide public compatibility evidence; they do not promote the provider or add a default check.

Phase 182 advisory LCOV changed-line coverage facts are complete. Phase 192 package-manager audit facts are complete. Coverage commands or gates, mutation, and blocking reviewability remain unsupported. TypeScript/JavaScript remains experimental.

For current maturation evidence and promotion criteria, see TypeScript Provider Maturation Notes.

Classification

The provider classifies common TypeScript and JavaScript paths:

  • source files: .ts, .tsx, .js, .jsx, .mjs, .cjs;
  • test files: .test.*, .spec.*, __tests__, tests, and specs;
  • ignored or generated paths: node_modules, build outputs, coverage outputs, __generated__, and generated folders;
  • dependency and config files: package.json, lockfiles, tsconfig.json, ESLint, Biome, Vite, Vitest, Jest, and Next config files.

Classification prepares later policy adapters without changing existing Python-backed reviewability behavior.

Unsupported Surface

The provider is intentionally explicit-command first. npm, pnpm, yarn, and bun are supported only when the repository supplies exact command arrays. Agent Maintainer does not infer package manager behavior from lockfiles, packageManager, Corepack settings, workspace manifests, or local scripts.

Test runners are not auto-detected. Jest, Vitest, Playwright, Cypress, Mocha, and other runners must be wired through typescript_test_command. Structured repair facts currently expect stable JSON, TypeScript compiler-style output, stable Jest/Vitest test JSON, or explicit Istanbul/LCOV coverage artifacts; arbitrary human-oriented transcripts stay bounded raw logs.

Frameworks are classified conservatively. Next.js, Vite, Astro, SvelteKit, and monorepo workspace layouts are not inferred into framework specific default checks, generated-file rules, coverage commands, or dependency policies. Configure the repository's own scripts first, then use assess reviewability to inspect advisory changed-file evidence.

Workspace command ownership is explicit. Configure root TypeScript commands only when they intentionally cover packages you want Agent Maintainer to verify. For package-specific checks, add commands under [tool.agent_maintainer.workspaces.<name>]; Agent Maintainer will run only the workspace TypeScript commands you configure and will not infer nested package commands. Workspace Knip commands use the root typescript_knip_profiles selection and stable names such as typescript-knip:web. Workspace dependency-cruiser commands use the root typescript_dependency_cruiser_profiles selection and stable names such as typescript-dependency-cruiser:web.

Coverage summaries and LCOV files can improve typescript-test repair facts when a repository already produces those artifacts. Existing LCOV can also feed the advisory test-intel typescript-coverage report. Knip can improve unused-code and dependency repair facts, the ecosystem-neutral OSV gate can provide dependency vulnerability facts, and explicit dependency-cruiser JSON can provide advisory architecture facts. The package-manager audit adapter accepts only an explicitly declared manager and command, and remains advisory; Yarn and Bun have fixture coverage but no pinned public projection yet. TypeScript coverage command execution or enforcement, mutation, and blocking reviewability adapters are not implemented yet. The provider should remain experimental until these surfaces have fixture and real-repo evidence.

Limitations

  • No package-manager autodetection.
  • No generated starter files yet.
  • No structured parser for arbitrary human-oriented test or coverage transcripts.
  • No TypeScript coverage command or gate or mutation adapter.
  • No public plugin API.
  • No TypeScript reviewability gate is blocking by default.

Python remains the core/reference provider. TypeScript support starts smaller on purpose so the provider seam can prove itself before deeper ecosystem features are added.

Read the Provider Contribution Guide before adding or promoting provider capabilities.