feat(coding-agent/cleanse): updated ty parser regex and test cases

- Update the ty parser regex to correctly match file path and position before the severity and error code.
- Adjust discovery prompt documentation and test cases to match the revised ty output format.
This commit is contained in:
can1357
2026-08-12 01:16:11 +02:00
parent 78ef4f6bb9
commit bc4404203c
3 changed files with 67 additions and 53 deletions
+6 -6
View File
@@ -488,14 +488,14 @@ function parseTy(input: CleanseParserInput): CleanseDiagnostic[] {
const diagnostics: CleanseDiagnostic[] = [];
const text = sanitizeText(`${input.stdout}\n${input.stderr}`);
for (const line of text.split("\n")) {
const match = /^(error|warning|info)\[([^\]]+)\]\s+(.+?):(\d+):(\d+):\s+(.*)$/.exec(line.trim());
const match = /^(.+?):(\d+):(\d+):\s+(error|warning|info)\[([^\]]+)\]\s+(.*)$/.exec(line.trim());
if (!match) continue;
addDiagnostic(diagnostics, input, {
file: match[3],
line: Number.parseInt(match[4], 10),
column: Number.parseInt(match[5], 10),
code: match[2],
severity: match[1],
file: match[1],
line: Number.parseInt(match[2], 10),
column: Number.parseInt(match[3], 10),
code: match[5],
severity: match[4],
message: match[6],
});
}
@@ -1,56 +1,56 @@
<critical>
- You NEVER edit project files; this is a read-and-verify discovery task.
- You MUST verify every command you propose by running it once.
- Your final message MUST be exactly one JSON object matching the schema below — no prose, no code fences.
- NEVER edit project files — read-and-verify discovery only.
- MUST run each proposed command once.
- Final: exactly one JSON object matching the schema below; no prose or code fences.
</critical>
# Checker Discovery
The user asked `omp cleanse` to detect and repair: **{{request}}**
User requested `omp cleanse` detect and repair: **{{request}}**
Determine which project command(s) surface exactly those diagnostics so the orchestrator can run them, parse their output, and dispatch repair agents.
Identify project command(s) surfacing exactly these diagnostics for orchestrator execution, output parsing, and repair-agent dispatch.
<workflow>
1. Inspect the project (manifests, configs, lockfiles, scripts) to identify the relevant tooling.
2. Determine the exact command and working directory. Prefer project-local binaries (`node_modules/.bin`, `.venv/bin`, wrappers like `gradlew`) over global tools.
3. Prefer a machine-readable output flag matching a known parser below. Otherwise pick a format that prints gcc-style `file:line:col: severity: message` lines and use parser `generic`.
4. Run the command once to verify it executes and its output matches the chosen parser. A non-zero exit with parseable diagnostics is fine; a crash or usage error is not.
5. If several commands are needed to cover the request, return one entry per command.
1. Inspect manifests, configs, lockfiles, and scripts for relevant tooling.
2. Determine exact command and working directory. Prefer project-local binaries (`node_modules/.bin`, `.venv/bin`, wrappers like `gradlew`) over global tools.
3. Prefer machine-readable output matching a known parser below. Otherwise use gcc-style `file:line:col: severity: message` output and parser `generic`.
4. Run once: verify execution and output matches the chosen parser. Non-zero exit with parseable diagnostics: fine; crash or usage error: not.
5. If multiple commands cover the request, return one entry per command.
</workflow>
## Known parsers
| id | expected output |
|id|expected output|
|---|---|
| `rust` | `cargo … --message-format=json` |
| `rust-test` | `cargo test … --message-format=json` |
| `go` | `go vet -json` |
| `go-test` | `go test -json` |
| `staticcheck` | `staticcheck -f json` |
| `golangci` | golangci-lint default text output |
| `ruff` | `ruff check --output-format=json` |
| `pyright` | `pyright`/`basedpyright` `--outputjson` |
| `mypy` | mypy default text output |
| `pylint` | `pylint --output-format=json` |
| `flake8` | flake8 default text output |
| `ty` | `ty check --output-format concise` |
| `eslint` | `eslint --format=json` |
| `biome` | `biome check --reporter=json` |
| `oxlint` | unix-format lines `file:line:col: message [Error/rule]` (`--format=unix`) |
| `deno-lint` | `deno lint --json` |
| `stylelint` | `stylelint --formatter json` |
| `rubocop` | `rubocop --format json` |
| `phpstan` | `phpstan analyse --error-format=json` |
| `psalm` | `psalm --output-format=json` |
| `swiftlint` | `swiftlint lint --reporter json` |
| `dart` | `dart analyze --format machine` |
| `credo` | `mix credo --format=json` |
| `shellcheck` | `shellcheck --format=json1` |
| `hlint` | `hlint --json` |
| `terraform` | `terraform validate -json` |
| `tflint` | `tflint --format=json` |
| `actionlint` | actionlint with its JSON `-format` template |
| `generic` | gcc-style `file:line:col: severity: message` lines (tsc/tsgo `--pretty false`, mypy, clang, zig, MSVC-style) |
|`rust`|`cargo … --message-format=json`|
|`rust-test`|`cargo test … --message-format=json`|
|`go`|`go vet -json`|
|`go-test`|`go test -json`|
|`staticcheck`|`staticcheck -f json`|
|`golangci`|golangci-lint default text output|
|`ruff`|`ruff check --output-format=json`|
|`pyright`|`pyright`/`basedpyright` `--outputjson`|
|`mypy`|mypy default text output|
|`pylint`|`pylint --output-format=json`|
|`flake8`|flake8 default text output|
|`ty`|`ty check --output-format concise`|
|`eslint`|`eslint --format=json`|
|`biome`|`biome check --reporter=json`|
|`oxlint`|unix-format lines `file:line:col: message [Error/rule]` (`--format=unix`)|
|`deno-lint`|`deno lint --json`|
|`stylelint`|`stylelint --formatter json`|
|`rubocop`|`rubocop --format json`|
|`phpstan`|`phpstan analyse --error-format=json`|
|`psalm`|`psalm --output-format=json`|
|`swiftlint`|`swiftlint lint --reporter json`|
|`dart`|`dart analyze --format machine`|
|`credo`|`mix credo --format=json`|
|`shellcheck`|`shellcheck --format=json1`|
|`hlint`|`hlint --json`|
|`terraform`|`terraform validate -json`|
|`tflint`|`tflint --format=json`|
|`actionlint`|actionlint with its JSON `-format` template|
|`generic`|gcc-style `file:line:col: severity: message` lines (tsc/tsgo `--pretty false`, mypy, clang, zig, MSVC-style)|
## Output schema
@@ -68,7 +68,7 @@ Determine which project command(s) surface exactly those diagnostics so the orch
}
```
- `command`: argv array; the first element is a binary name or project-relative path. Never wrap in a shell.
- `cwd`: project-relative working directory; omit for the project root.
- `parser`: one of the known parser ids; omit for `generic`.
- Return `"checkers": []` only when nothing in this project can produce the requested diagnostics.
- `command`: argv array; first element: binary name or project-relative path. NEVER shell-wrap.
- `cwd`: project-relative working directory; omit for project root.
- `parser`: known parser id; omit for `generic`.
- Return `"checkers": []` only if nothing in this project produces the requested diagnostics.
+17 -3
View File
@@ -362,9 +362,23 @@ describe("cleanse alternative-tooling parsers", () => {
});
test("parses ty concise output", () => {
const diagnostics = parse("ty", "error[unresolved-import] src/main.py:1:8: Cannot resolve imported module\n");
expect(diagnostics).toMatchObject([
{ file: "src/main.py", line: 1, column: 8, code: "unresolved-import", severity: "error" },
const diagnostics = parse(
"ty",
"src/main.py:1:8: error[unresolved-import] Cannot resolve imported module `foo`\nFound 1 diagnostic\n",
);
expect(diagnostics).toEqual([
{
checker: "checker",
file: "src/main.py",
line: 1,
column: 8,
endLine: undefined,
endColumn: undefined,
code: "unresolved-import",
severity: "error",
message: "Cannot resolve imported module `foo`",
suggestion: undefined,
},
]);
});