@kirrosh/zond 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +758 -3
- package/README.md +78 -15
- package/package.json +17 -10
- package/src/cli/argv.ts +122 -0
- package/src/cli/commands/add-api.ts +134 -0
- package/src/cli/commands/api/annotate/idempotency.ts +59 -0
- package/src/cli/commands/api/annotate/index.ts +525 -0
- package/src/cli/commands/api/annotate/lifecycle.ts +74 -0
- package/src/cli/commands/api/annotate/overlay.ts +206 -0
- package/src/cli/commands/api/annotate/pagination.ts +60 -0
- package/src/cli/commands/api/annotate/prompts.ts +183 -0
- package/src/cli/commands/api/annotate/readback.ts +58 -0
- package/src/cli/commands/api/annotate/resources.ts +91 -0
- package/src/cli/commands/api/annotate/seed-bodies.ts +61 -0
- package/src/cli/commands/audit.ts +480 -0
- package/src/cli/commands/bootstrap.ts +710 -0
- package/src/cli/commands/catalog.ts +35 -0
- package/src/cli/commands/check.ts +348 -0
- package/src/cli/commands/checks.ts +756 -0
- package/src/cli/commands/ci-init.ts +55 -6
- package/src/cli/commands/clean.ts +212 -0
- package/src/cli/commands/cleanup.ts +262 -0
- package/src/cli/commands/completions.ts +192 -0
- package/src/cli/commands/coverage.ts +605 -132
- package/src/cli/commands/db.ts +180 -8
- package/src/cli/commands/describe.ts +37 -2
- package/src/cli/commands/discover.ts +1236 -0
- package/src/cli/commands/doctor.ts +607 -0
- package/src/cli/commands/fixtures.ts +402 -0
- package/src/cli/commands/generate.ts +420 -47
- package/src/cli/commands/init/agents-md.ts +61 -0
- package/src/cli/commands/init/bootstrap.ts +108 -0
- package/src/cli/commands/init/index.ts +244 -0
- package/src/cli/commands/init/skills.ts +98 -0
- package/src/cli/commands/init/templates/agents.md +77 -0
- package/src/cli/commands/init/templates/markdown.d.ts +4 -0
- package/src/cli/commands/init/templates/skills/zond-checks.md +397 -0
- package/src/cli/commands/init/templates/skills/zond-triage.md +210 -0
- package/src/cli/commands/init/templates/skills/zond.md +651 -0
- package/src/cli/commands/init/templates/zond-config.yml +14 -0
- package/src/cli/commands/prepare-fixtures.ts +135 -0
- package/src/cli/commands/probe/mass-assignment.ts +503 -0
- package/src/cli/commands/probe/security.ts +454 -0
- package/src/cli/commands/probe/static.ts +255 -0
- package/src/cli/commands/probe/webhooks.ts +161 -0
- package/src/cli/commands/probe.ts +459 -0
- package/src/cli/commands/reference.ts +87 -0
- package/src/cli/commands/refresh-api.ts +169 -0
- package/src/cli/commands/remove-api.ts +150 -0
- package/src/cli/commands/report-bundle.ts +318 -0
- package/src/cli/commands/report.ts +241 -0
- package/src/cli/commands/request.ts +379 -4
- package/src/cli/commands/run.ts +911 -33
- package/src/cli/commands/session.ts +244 -0
- package/src/cli/commands/use.ts +74 -0
- package/src/cli/index.ts +36 -607
- package/src/cli/json-envelope.ts +112 -3
- package/src/cli/json-schemas.ts +263 -0
- package/src/cli/program.ts +218 -0
- package/src/cli/resolve.ts +105 -0
- package/src/cli/status-filter.ts +124 -0
- package/src/cli/util/api-context.ts +85 -0
- package/src/cli/version.ts +8 -0
- package/src/core/anti-fp/bootstrap.ts +34 -0
- package/src/core/anti-fp/index.ts +33 -0
- package/src/core/anti-fp/registry.ts +44 -0
- package/src/core/anti-fp/rules/baseline-echo.ts +74 -0
- package/src/core/anti-fp/rules/schemathesis/body_negation_becomes_valid.ts +52 -0
- package/src/core/anti-fp/rules/schemathesis/coverage_phase_boundary_positive.ts +38 -0
- package/src/core/anti-fp/rules/schemathesis/has_unverifiable_mutations.ts +35 -0
- package/src/core/anti-fp/rules/schemathesis/index.ts +24 -0
- package/src/core/anti-fp/rules/schemathesis/string_type_mutation_becomes_valid.ts +53 -0
- package/src/core/anti-fp/rules/subscription-gated/index.ts +11 -0
- package/src/core/anti-fp/rules/subscription-gated/paid-plan-403.ts +75 -0
- package/src/core/anti-fp/types.ts +68 -0
- package/src/core/checks/checks/_crud-helpers.ts +133 -0
- package/src/core/checks/checks/_negative_mutator.ts +133 -0
- package/src/core/checks/checks/_readback-helpers.ts +133 -0
- package/src/core/checks/checks/content_type_conformance.ts +39 -0
- package/src/core/checks/checks/cross_call_references.ts +134 -0
- package/src/core/checks/checks/ensure_resource_availability.ts +62 -0
- package/src/core/checks/checks/idempotency_replay.ts +246 -0
- package/src/core/checks/checks/ignored_auth.ts +211 -0
- package/src/core/checks/checks/index.ts +65 -0
- package/src/core/checks/checks/lifecycle_transitions.ts +273 -0
- package/src/core/checks/checks/missing_required_header.ts +40 -0
- package/src/core/checks/checks/negative_data_rejection.ts +45 -0
- package/src/core/checks/checks/not_a_server_error.ts +27 -0
- package/src/core/checks/checks/open_cors_on_sensitive.ts +131 -0
- package/src/core/checks/checks/pagination_invariants.ts +238 -0
- package/src/core/checks/checks/positive_data_acceptance.ts +36 -0
- package/src/core/checks/checks/rate_limit_headers_absent.ts +77 -0
- package/src/core/checks/checks/response_headers_conformance.ts +74 -0
- package/src/core/checks/checks/response_schema_conformance.ts +30 -0
- package/src/core/checks/checks/status_code_conformance.ts +61 -0
- package/src/core/checks/checks/unsupported_method.ts +63 -0
- package/src/core/checks/checks/use_after_free.ts +78 -0
- package/src/core/checks/index.ts +30 -0
- package/src/core/checks/mode.ts +79 -0
- package/src/core/checks/recommended-action.ts +64 -0
- package/src/core/checks/registry.ts +78 -0
- package/src/core/checks/runner.ts +874 -0
- package/src/core/checks/sarif.ts +230 -0
- package/src/core/checks/stateful.ts +121 -0
- package/src/core/checks/types.ts +189 -0
- package/src/core/classifier/recommended-action.ts +222 -0
- package/src/core/context/current.ts +51 -0
- package/src/core/context/session.ts +78 -0
- package/src/core/coverage/loader.ts +185 -0
- package/src/core/coverage/reasons.ts +300 -0
- package/src/core/diagnostics/db-analysis.ts +161 -12
- package/src/core/diagnostics/failure-class.ts +120 -0
- package/src/core/diagnostics/failure-hints.ts +212 -9
- package/src/core/diagnostics/spec-pointer.ts +99 -0
- package/src/core/diagnostics/suggested-fixes.ts +156 -0
- package/src/core/exporter/case-study/index.ts +270 -0
- package/src/core/exporter/curl.ts +40 -0
- package/src/core/exporter/exporter.ts +48 -0
- package/src/core/exporter/html-report/escape.ts +24 -0
- package/src/core/exporter/html-report/index.ts +479 -0
- package/src/core/exporter/html-report/script.ts +100 -0
- package/src/core/exporter/html-report/styles.ts +408 -0
- package/src/core/generator/chunker.ts +53 -15
- package/src/core/generator/coverage-phase.ts +0 -0
- package/src/core/generator/create-body.ts +89 -0
- package/src/core/generator/data-factory.ts +490 -33
- package/src/core/generator/describe.ts +1 -1
- package/src/core/generator/fixtures-builder.ts +325 -0
- package/src/core/generator/index.ts +7 -5
- package/src/core/generator/openapi-reader.ts +55 -3
- package/src/core/generator/path-param-disambig.ts +114 -0
- package/src/core/generator/resources-builder.ts +648 -0
- package/src/core/generator/schema-utils.ts +11 -3
- package/src/core/generator/serializer.ts +114 -15
- package/src/core/generator/suite-generator.ts +484 -77
- package/src/core/generator/types.ts +8 -0
- package/src/core/identity/identity-file.ts +129 -0
- package/src/core/lint/affects.ts +28 -0
- package/src/core/lint/config.ts +96 -0
- package/src/core/lint/format.ts +42 -0
- package/src/core/lint/index.ts +94 -0
- package/src/core/lint/reporter.ts +128 -0
- package/src/core/lint/rules/consistency.ts +158 -0
- package/src/core/lint/rules/heuristics.ts +97 -0
- package/src/core/lint/rules/strictness.ts +109 -0
- package/src/core/lint/types.ts +96 -0
- package/src/core/lint/walker.ts +248 -0
- package/src/core/meta/meta-store.ts +6 -73
- package/src/core/output/README.md +91 -0
- package/src/core/output/index.ts +13 -0
- package/src/core/output/run.ts +126 -0
- package/src/core/output/types.ts +129 -0
- package/src/core/parser/env-interpolation.ts +104 -0
- package/src/core/parser/filter.ts +57 -0
- package/src/core/parser/schema.ts +132 -5
- package/src/core/parser/types.ts +29 -2
- package/src/core/parser/variables.ts +0 -0
- package/src/core/parser/yaml-parser.ts +108 -13
- package/src/core/probe/bootstrap.ts +34 -0
- package/src/core/probe/dry-run-envelope.ts +57 -0
- package/src/core/probe/mass-assignment-probe-class.ts +198 -0
- package/src/core/probe/mass-assignment-probe.ts +1122 -0
- package/src/core/probe/mass-assignment-template.ts +212 -0
- package/src/core/probe/method-probe.ts +164 -0
- package/src/core/probe/method-shared.ts +69 -0
- package/src/core/probe/negative-probe.ts +691 -0
- package/src/core/probe/orphan-tracker.ts +188 -0
- package/src/core/probe/path-discovery.ts +440 -0
- package/src/core/probe/probe-harness.ts +120 -0
- package/src/core/probe/registry.ts +89 -0
- package/src/core/probe/runner.ts +136 -0
- package/src/core/probe/security-probe-class.ts +201 -0
- package/src/core/probe/security-probe.ts +1453 -0
- package/src/core/probe/shared.ts +505 -0
- package/src/core/probe/static-probe-class.ts +125 -0
- package/src/core/probe/types.ts +165 -0
- package/src/core/probe/verdict-aggregator.ts +33 -0
- package/src/core/probe/webhooks-probe.ts +284 -0
- package/src/core/reporter/console.ts +69 -4
- package/src/core/reporter/index.ts +2 -3
- package/src/core/reporter/json.ts +15 -2
- package/src/core/reporter/junit.ts +27 -12
- package/src/core/reporter/ndjson.ts +37 -0
- package/src/core/reporter/types.ts +3 -0
- package/src/core/runner/assertions.ts +62 -2
- package/src/core/runner/async-pool.ts +108 -0
- package/src/core/runner/auth-path.ts +8 -0
- package/src/core/runner/ci-context.ts +72 -0
- package/src/core/runner/executor.ts +391 -52
- package/src/core/runner/form-encode.ts +51 -0
- package/src/core/runner/http-client.ts +115 -7
- package/src/core/runner/learn-drift.ts +293 -0
- package/src/core/runner/preflight-vars.ts +149 -0
- package/src/core/runner/progress-tracker.ts +73 -0
- package/src/core/runner/rate-limiter.ts +203 -0
- package/src/core/runner/run-kind.ts +39 -0
- package/src/core/runner/schema-validator.ts +312 -0
- package/src/core/runner/send-request.ts +153 -20
- package/src/core/runner/types.ts +38 -0
- package/src/core/secrets/registry.ts +164 -0
- package/src/core/secrets/secrets-file.ts +115 -0
- package/src/core/selectors/operation-filter.ts +144 -0
- package/src/core/setup-api.ts +419 -17
- package/src/core/severity/category.ts +94 -0
- package/src/core/severity/index.ts +121 -0
- package/src/core/spec/layers.ts +154 -0
- package/src/core/util/format-eta.ts +21 -0
- package/src/core/utils.ts +5 -1
- package/src/core/workspace/config.ts +129 -0
- package/src/core/workspace/manifest.ts +283 -0
- package/src/core/workspace/output-rotation.ts +62 -0
- package/src/core/workspace/root.ts +94 -0
- package/src/core/workspace/triage-path.ts +87 -0
- package/src/db/lint-runs.ts +47 -0
- package/src/db/migrate.ts +126 -0
- package/src/db/migrations/0001_run_kind.sql +25 -0
- package/src/db/migrations/sql.d.ts +4 -0
- package/src/db/queries/collections.ts +133 -0
- package/src/db/queries/coverage.ts +9 -0
- package/src/db/queries/dashboard.ts +59 -0
- package/src/db/queries/results.ts +128 -0
- package/src/db/queries/runs.ts +235 -0
- package/src/db/queries/sessions.ts +42 -0
- package/src/db/queries/settings.ts +28 -0
- package/src/db/queries/types.ts +172 -0
- package/src/db/queries.ts +72 -802
- package/src/db/schema.ts +179 -48
- package/src/cli/commands/export.ts +0 -144
- package/src/cli/commands/guide.ts +0 -127
- package/src/cli/commands/init.ts +0 -57
- package/src/cli/commands/serve.ts +0 -81
- package/src/cli/commands/sync.ts +0 -269
- package/src/cli/commands/update.ts +0 -189
- package/src/cli/commands/validate.ts +0 -34
- package/src/core/exporter/postman.ts +0 -963
- package/src/core/generator/guide-builder.ts +0 -253
- package/src/core/meta/types.ts +0 -21
- package/src/core/parser/index.ts +0 -21
- package/src/core/runner/execute-run.ts +0 -132
- package/src/core/runner/index.ts +0 -12
- package/src/core/sync/spec-differ.ts +0 -38
- package/src/web/data/collection-state.ts +0 -362
- package/src/web/routes/api.ts +0 -314
- package/src/web/routes/dashboard.ts +0 -350
- package/src/web/routes/runs.ts +0 -64
- package/src/web/schemas.ts +0 -121
- package/src/web/server.ts +0 -134
- package/src/web/static/htmx.min.cjs +0 -1
- package/src/web/static/style.css +0 -1148
- package/src/web/views/endpoints-tab.ts +0 -174
- package/src/web/views/explorer-tab.ts +0 -402
- package/src/web/views/health-strip.ts +0 -92
- package/src/web/views/layout.ts +0 -48
- package/src/web/views/results.ts +0 -210
- package/src/web/views/runs-tab.ts +0 -126
- package/src/web/views/suites-tab.ts +0 -181
package/src/cli/commands/db.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { getCollections, getRuns, getRunDetail, diagnoseRun, compareRuns } from "../../core/diagnostics/db-analysis.ts";
|
|
2
|
-
import { getFilteredResults } from "../../db/queries.ts";
|
|
2
|
+
import { getFilteredResults, getLatestFailingRunId, getLatestRunId } from "../../db/queries.ts";
|
|
3
3
|
import { getDb } from "../../db/schema.ts";
|
|
4
4
|
import { printError } from "../output.ts";
|
|
5
5
|
import { jsonOk, jsonError, printJson } from "../json-envelope.ts";
|
|
6
|
+
import { parseStatusFilter, compileStatusFilterToSql, type StatusMatcher } from "../status-filter.ts";
|
|
6
7
|
|
|
7
8
|
export interface DbOptions {
|
|
8
9
|
subcommand: string;
|
|
@@ -12,7 +13,16 @@ export interface DbOptions {
|
|
|
12
13
|
dbPath?: string;
|
|
13
14
|
json?: boolean;
|
|
14
15
|
method?: string;
|
|
15
|
-
status
|
|
16
|
+
/** Raw `--status` argument (TASK-140). Parsed lazily so help text can show
|
|
17
|
+
* the literal user input in error messages. */
|
|
18
|
+
status?: string;
|
|
19
|
+
/** TASK-266: `db diagnose --latest` — pick the most recent run regardless
|
|
20
|
+
* of failure status (default is most recent failing run). */
|
|
21
|
+
latest?: boolean;
|
|
22
|
+
/** TASK-266: explicit run id override (`--run-id N`). Same effect as
|
|
23
|
+
* passing the id positionally; kept as a flag because the `zond-triage`
|
|
24
|
+
* skill and other agents prefer self-documenting flags. */
|
|
25
|
+
runId?: number;
|
|
16
26
|
}
|
|
17
27
|
|
|
18
28
|
export async function dbCommand(options: DbOptions): Promise<number> {
|
|
@@ -46,7 +56,8 @@ export async function dbCommand(options: DbOptions): Promise<number> {
|
|
|
46
56
|
} else {
|
|
47
57
|
for (const r of runs) {
|
|
48
58
|
const run = r as any;
|
|
49
|
-
const
|
|
59
|
+
const isFail = run.failed > 0 || (run.total > 0 && run.passed === 0);
|
|
60
|
+
const status = isFail ? "FAIL" : "PASS";
|
|
50
61
|
console.log(`#${run.id} ${status} ${run.passed}/${run.total} passed (${run.started_at})`);
|
|
51
62
|
}
|
|
52
63
|
}
|
|
@@ -65,7 +76,21 @@ export async function dbCommand(options: DbOptions): Promise<number> {
|
|
|
65
76
|
// If filtering by method/status, show filtered results instead of full detail
|
|
66
77
|
if (options.method || options.status !== undefined) {
|
|
67
78
|
getDb(options.dbPath);
|
|
68
|
-
|
|
79
|
+
let statusSql: { sql: string; params: number[] } | undefined;
|
|
80
|
+
if (options.status !== undefined) {
|
|
81
|
+
let matcher: StatusMatcher;
|
|
82
|
+
try {
|
|
83
|
+
matcher = parseStatusFilter(options.status);
|
|
84
|
+
} catch (err) {
|
|
85
|
+
const msg = `Invalid --status: ${(err as Error).message}`;
|
|
86
|
+
if (json) printJson(jsonError("db run", [msg]));
|
|
87
|
+
else printError(msg);
|
|
88
|
+
return 2;
|
|
89
|
+
}
|
|
90
|
+
const compiled = compileStatusFilterToSql(matcher, "response_status");
|
|
91
|
+
if (compiled) statusSql = compiled;
|
|
92
|
+
}
|
|
93
|
+
const results = getFilteredResults(id, { method: options.method, statusSql });
|
|
69
94
|
if (json) {
|
|
70
95
|
printJson(jsonOk("db run", { run_id: id, count: results.length, results }));
|
|
71
96
|
} else {
|
|
@@ -83,17 +108,72 @@ export async function dbCommand(options: DbOptions): Promise<number> {
|
|
|
83
108
|
}
|
|
84
109
|
|
|
85
110
|
case "diagnose": {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
111
|
+
// TASK-266: resolve run id with the priority
|
|
112
|
+
// explicit positional > --run-id > --latest > last failing run.
|
|
113
|
+
// The bare `zond db diagnose` is the agent-friendly default the
|
|
114
|
+
// `zond-triage` skill relies on; `--latest` exists for "show me the
|
|
115
|
+
// last run, even if it passed".
|
|
116
|
+
getDb(options.dbPath);
|
|
117
|
+
let id: number | null = null;
|
|
118
|
+
let resolution: "explicit" | "run-id-flag" | "latest" | "latest-failing" = "explicit";
|
|
119
|
+
const positionalRaw = positional[0];
|
|
120
|
+
if (positionalRaw !== undefined && positionalRaw !== "") {
|
|
121
|
+
const n = parseInt(positionalRaw, 10);
|
|
122
|
+
if (isNaN(n)) {
|
|
123
|
+
const msg = `Invalid run id: ${positionalRaw}. Expected a positive integer.`;
|
|
124
|
+
if (json) printJson(jsonError("db diagnose", [msg]));
|
|
125
|
+
else printError(msg);
|
|
126
|
+
return 2;
|
|
127
|
+
}
|
|
128
|
+
id = n;
|
|
129
|
+
} else if (options.runId !== undefined) {
|
|
130
|
+
id = options.runId;
|
|
131
|
+
resolution = "run-id-flag";
|
|
132
|
+
} else if (options.latest) {
|
|
133
|
+
id = getLatestRunId();
|
|
134
|
+
resolution = "latest";
|
|
135
|
+
} else {
|
|
136
|
+
id = getLatestFailingRunId();
|
|
137
|
+
resolution = "latest-failing";
|
|
138
|
+
if (id == null) {
|
|
139
|
+
// No failures — fall back to the latest run so the user still
|
|
140
|
+
// gets a useful payload, with a "no failures" hint.
|
|
141
|
+
const fallback = getLatestRunId();
|
|
142
|
+
if (fallback == null) {
|
|
143
|
+
const msg = "No runs in the database yet. Try `zond run <suite>` first.";
|
|
144
|
+
if (json) printJson(jsonError("db diagnose", [msg]));
|
|
145
|
+
else printError(msg);
|
|
146
|
+
return 1;
|
|
147
|
+
}
|
|
148
|
+
const result = diagnoseRun(fallback, options.verbose, options.dbPath, options.limit);
|
|
149
|
+
const warning = `No failing runs — diagnosing latest run #${fallback} (all passed).`;
|
|
150
|
+
if (json) {
|
|
151
|
+
printJson(jsonOk("db diagnose", { ...result, resolution: "latest-no-failures", run_id: fallback }, [warning]));
|
|
152
|
+
} else {
|
|
153
|
+
process.stderr.write(`zond: ${warning}\n`);
|
|
154
|
+
console.log(JSON.stringify(result, null, 2));
|
|
155
|
+
}
|
|
156
|
+
return 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (id == null) {
|
|
160
|
+
const msg = "Missing run ID. Usage: zond db diagnose [id] (default: last failing run)";
|
|
89
161
|
if (json) printJson(jsonError("db diagnose", [msg]));
|
|
90
162
|
else printError(msg);
|
|
91
163
|
return 2;
|
|
92
164
|
}
|
|
93
165
|
const result = diagnoseRun(id, options.verbose, options.dbPath, options.limit);
|
|
94
166
|
if (json) {
|
|
95
|
-
printJson(jsonOk("db diagnose", result));
|
|
167
|
+
printJson(jsonOk("db diagnose", { ...result, resolution, run_id: id }));
|
|
96
168
|
} else {
|
|
169
|
+
if (resolution !== "explicit") {
|
|
170
|
+
const label = resolution === "latest-failing"
|
|
171
|
+
? `last failing run #${id}`
|
|
172
|
+
: resolution === "latest"
|
|
173
|
+
? `latest run #${id}`
|
|
174
|
+
: `run #${id}`;
|
|
175
|
+
process.stderr.write(`zond: diagnosing ${label}\n`);
|
|
176
|
+
}
|
|
97
177
|
console.log(JSON.stringify(result, null, 2));
|
|
98
178
|
}
|
|
99
179
|
return 0;
|
|
@@ -134,3 +214,95 @@ export async function dbCommand(options: DbOptions): Promise<number> {
|
|
|
134
214
|
return 2;
|
|
135
215
|
}
|
|
136
216
|
}
|
|
217
|
+
|
|
218
|
+
import type { Command } from "commander";
|
|
219
|
+
import { globalJson } from "../resolve.ts";
|
|
220
|
+
import { parsePositiveInt } from "../argv.ts";
|
|
221
|
+
|
|
222
|
+
export function registerDb(program: Command): void {
|
|
223
|
+
const db = program.command("db").description("Query the test database");
|
|
224
|
+
|
|
225
|
+
db
|
|
226
|
+
.command("collections")
|
|
227
|
+
.description("List all API collections")
|
|
228
|
+
.option("--db <path>", "Path to SQLite database file")
|
|
229
|
+
.action(async (opts, cmd: Command) => {
|
|
230
|
+
process.exitCode = await dbCommand({
|
|
231
|
+
subcommand: "collections",
|
|
232
|
+
positional: [],
|
|
233
|
+
dbPath: opts.db,
|
|
234
|
+
json: globalJson(cmd),
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
db
|
|
239
|
+
.command("runs")
|
|
240
|
+
.description("List recent test runs")
|
|
241
|
+
.option("--limit <N>", "Maximum number of runs to display", parsePositiveInt("--limit"))
|
|
242
|
+
.option("--db <path>", "Path to SQLite database file")
|
|
243
|
+
.action(async (opts, cmd: Command) => {
|
|
244
|
+
process.exitCode = await dbCommand({
|
|
245
|
+
subcommand: "runs",
|
|
246
|
+
positional: [],
|
|
247
|
+
limit: opts.limit,
|
|
248
|
+
dbPath: opts.db,
|
|
249
|
+
json: globalJson(cmd),
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
db
|
|
254
|
+
.command("run <id>")
|
|
255
|
+
.description("Show run details")
|
|
256
|
+
.option("--verbose", "Show all results")
|
|
257
|
+
.option("--method <method>", "Filter by HTTP method")
|
|
258
|
+
.option(
|
|
259
|
+
"--status <expr>",
|
|
260
|
+
"Filter by HTTP status. Accepts: exact code (502), class (5xx), range (500-599), comparison (>=500, <400), or comma-separated mix (5xx,429).",
|
|
261
|
+
)
|
|
262
|
+
.option("--db <path>", "Path to SQLite database file")
|
|
263
|
+
.action(async (id: string, opts, cmd: Command) => {
|
|
264
|
+
process.exitCode = await dbCommand({
|
|
265
|
+
subcommand: "run",
|
|
266
|
+
positional: [id],
|
|
267
|
+
verbose: opts.verbose === true,
|
|
268
|
+
method: opts.method,
|
|
269
|
+
status: opts.status,
|
|
270
|
+
dbPath: opts.db,
|
|
271
|
+
json: globalJson(cmd),
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
db
|
|
276
|
+
.command("diagnose [id]")
|
|
277
|
+
.description("Diagnose run failures. Without [id]: defaults to the most recent failing run (TASK-266); falls back to latest run with a 'no failures' note when nothing has failed.")
|
|
278
|
+
.option("--latest", "Diagnose the most recent run regardless of status (TASK-266)")
|
|
279
|
+
.option("--run-id <N>", "Explicit run id override (same as positional [id]; preferred form for agents)", parsePositiveInt("--run-id"))
|
|
280
|
+
.option("--limit <N>", "Examples per failure group", parsePositiveInt("--limit"))
|
|
281
|
+
.option("--verbose", "Show all examples (not grouped)")
|
|
282
|
+
.option("--db <path>", "Path to SQLite database file")
|
|
283
|
+
.action(async (id: string | undefined, opts, cmd: Command) => {
|
|
284
|
+
process.exitCode = await dbCommand({
|
|
285
|
+
subcommand: "diagnose",
|
|
286
|
+
positional: id !== undefined ? [id] : [],
|
|
287
|
+
limit: opts.limit,
|
|
288
|
+
verbose: opts.verbose === true,
|
|
289
|
+
latest: opts.latest === true,
|
|
290
|
+
runId: opts.runId,
|
|
291
|
+
dbPath: opts.db,
|
|
292
|
+
json: globalJson(cmd),
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
db
|
|
297
|
+
.command("compare <idA> <idB>")
|
|
298
|
+
.description("Compare two runs")
|
|
299
|
+
.option("--db <path>", "Path to SQLite database file")
|
|
300
|
+
.action(async (idA: string, idB: string, opts, cmd: Command) => {
|
|
301
|
+
process.exitCode = await dbCommand({
|
|
302
|
+
subcommand: "compare",
|
|
303
|
+
positional: [idA, idB],
|
|
304
|
+
dbPath: opts.db,
|
|
305
|
+
json: globalJson(cmd),
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
}
|
|
@@ -37,7 +37,13 @@ export async function describeCommand(options: DescribeOptions): Promise<number>
|
|
|
37
37
|
return 0;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
// No flags = compact listing. Erroring out (exit 2) on `zond describe`
|
|
41
|
+
// breaks scripts that pipe the listing; the listing IS the only useful
|
|
42
|
+
// default since the spec is the only required arg. Single-endpoint detail
|
|
43
|
+
// remains opt-in via --method/--path.
|
|
44
|
+
const useCompact = options.compact || (!options.method && !options.path);
|
|
45
|
+
|
|
46
|
+
if (useCompact) {
|
|
41
47
|
const endpoints = await describeCompact(options.specPath);
|
|
42
48
|
|
|
43
49
|
if (options.json) {
|
|
@@ -55,8 +61,10 @@ export async function describeCommand(options: DescribeOptions): Promise<number>
|
|
|
55
61
|
return 0;
|
|
56
62
|
}
|
|
57
63
|
|
|
64
|
+
// We get here only when one of --method/--path is set but not both —
|
|
65
|
+
// single-endpoint detail needs both halves of the address.
|
|
58
66
|
if (!options.method || !options.path) {
|
|
59
|
-
const msg = "
|
|
67
|
+
const msg = "--method and --path must be used together for single-endpoint detail. Drop both for the compact listing.";
|
|
60
68
|
if (options.json) {
|
|
61
69
|
printJson(jsonError("describe", [msg]));
|
|
62
70
|
} else {
|
|
@@ -83,3 +91,30 @@ export async function describeCommand(options: DescribeOptions): Promise<number>
|
|
|
83
91
|
return 2;
|
|
84
92
|
}
|
|
85
93
|
}
|
|
94
|
+
|
|
95
|
+
import type { Command } from "commander";
|
|
96
|
+
import { globalJson, resolveSpecArg } from "../resolve.ts";
|
|
97
|
+
|
|
98
|
+
export function registerDescribe(program: Command): void {
|
|
99
|
+
program
|
|
100
|
+
.command("describe [spec]")
|
|
101
|
+
.description("Describe endpoints from OpenAPI spec")
|
|
102
|
+
.option("--api <name>", "Use the registered API's spec (apis/<name>/spec.json)")
|
|
103
|
+
.option("--db <path>", "Path to SQLite database file")
|
|
104
|
+
.option("--compact", "List all endpoints briefly")
|
|
105
|
+
.option("--list-params", "List all unique parameters across all endpoints")
|
|
106
|
+
.option("--method <method>", "HTTP method for single endpoint detail")
|
|
107
|
+
.option("--path <path>", "Endpoint path for single endpoint detail")
|
|
108
|
+
.action(async (specPos: string | undefined, opts, cmd: Command) => {
|
|
109
|
+
const resolved = resolveSpecArg(specPos, opts.api, opts.db);
|
|
110
|
+
if ("error" in resolved) { printError(resolved.error); process.exitCode = 2; return; }
|
|
111
|
+
process.exitCode = await describeCommand({
|
|
112
|
+
specPath: resolved.spec,
|
|
113
|
+
compact: opts.compact === true,
|
|
114
|
+
listParams: opts.listParams === true,
|
|
115
|
+
method: opts.method,
|
|
116
|
+
path: opts.path,
|
|
117
|
+
json: globalJson(cmd),
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|