@kirrosh/zond 0.26.0 → 0.27.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 +59 -0
- package/README.md +22 -21
- package/bin/zond.mjs +23 -0
- package/package.json +13 -16
- package/scripts/npm/postinstall.mjs +76 -0
- package/src/CLAUDE.md +0 -112
- package/src/bun-types.d.ts +0 -5
- package/src/cli/argv.ts +0 -122
- package/src/cli/commands/add-api.ts +0 -146
- package/src/cli/commands/api/annotate/idempotency.ts +0 -59
- package/src/cli/commands/api/annotate/index.ts +0 -880
- package/src/cli/commands/api/annotate/lifecycle.ts +0 -74
- package/src/cli/commands/api/annotate/overlay.ts +0 -206
- package/src/cli/commands/api/annotate/pagination.ts +0 -64
- package/src/cli/commands/api/annotate/prompts.ts +0 -220
- package/src/cli/commands/api/annotate/readback.ts +0 -58
- package/src/cli/commands/api/annotate/resources.ts +0 -91
- package/src/cli/commands/api/annotate/seed-bodies.ts +0 -61
- package/src/cli/commands/audit.ts +0 -786
- package/src/cli/commands/catalog.ts +0 -97
- package/src/cli/commands/check.ts +0 -361
- package/src/cli/commands/checks.ts +0 -1072
- package/src/cli/commands/ci-init.ts +0 -223
- package/src/cli/commands/clean.ts +0 -212
- package/src/cli/commands/cleanup.ts +0 -236
- package/src/cli/commands/completions.ts +0 -192
- package/src/cli/commands/coverage.ts +0 -872
- package/src/cli/commands/db.ts +0 -611
- package/src/cli/commands/describe.ts +0 -120
- package/src/cli/commands/discover.ts +0 -1356
- package/src/cli/commands/doctor.ts +0 -661
- package/src/cli/commands/fixtures.ts +0 -402
- package/src/cli/commands/generate.ts +0 -577
- package/src/cli/commands/init/agents-md.ts +0 -61
- package/src/cli/commands/init/bootstrap.ts +0 -111
- package/src/cli/commands/init/index.ts +0 -244
- package/src/cli/commands/init/skills.ts +0 -141
- package/src/cli/commands/init/templates/agents.md +0 -86
- package/src/cli/commands/init/templates/markdown.d.ts +0 -4
- package/src/cli/commands/init/templates/skills/warm-up-target.md +0 -122
- package/src/cli/commands/init/templates/skills/zond-checks.md +0 -621
- package/src/cli/commands/init/templates/skills/zond-seed.md +0 -114
- package/src/cli/commands/init/templates/skills/zond-triage.md +0 -272
- package/src/cli/commands/init/templates/skills/zond.md +0 -861
- package/src/cli/commands/init/templates/zond-config.yml +0 -14
- package/src/cli/commands/prepare-fixtures.ts +0 -97
- package/src/cli/commands/probe/_seed-bodies.ts +0 -52
- package/src/cli/commands/probe/mass-assignment.ts +0 -594
- package/src/cli/commands/probe/security.ts +0 -537
- package/src/cli/commands/probe/static.ts +0 -255
- package/src/cli/commands/probe/webhooks.ts +0 -163
- package/src/cli/commands/probe.ts +0 -535
- package/src/cli/commands/reference.ts +0 -87
- package/src/cli/commands/refresh-api.ts +0 -227
- package/src/cli/commands/remove-api.ts +0 -150
- package/src/cli/commands/report-bundle.ts +0 -310
- package/src/cli/commands/report.ts +0 -241
- package/src/cli/commands/request.ts +0 -548
- package/src/cli/commands/run.ts +0 -1142
- package/src/cli/commands/schema-from-runs.ts +0 -128
- package/src/cli/commands/secrets.ts +0 -133
- package/src/cli/commands/session.ts +0 -244
- package/src/cli/commands/use.ts +0 -74
- package/src/cli/index.ts +0 -55
- package/src/cli/json-envelope.ts +0 -108
- package/src/cli/json-schemas.ts +0 -314
- package/src/cli/output.ts +0 -40
- package/src/cli/program.ts +0 -219
- package/src/cli/resolve.ts +0 -105
- package/src/cli/runtime.ts +0 -7
- package/src/cli/safe-live.ts +0 -24
- package/src/cli/status-filter.ts +0 -114
- package/src/cli/util/api-context.ts +0 -85
- package/src/cli/version.ts +0 -8
- package/src/core/audit/persist.ts +0 -183
- package/src/core/checks/budget.ts +0 -59
- package/src/core/checks/checks/_crud-helpers.ts +0 -133
- package/src/core/checks/checks/_negative_mutator.ts +0 -133
- package/src/core/checks/checks/_readback-helpers.ts +0 -133
- package/src/core/checks/checks/content_type_conformance.ts +0 -39
- package/src/core/checks/checks/cross_call_references.ts +0 -147
- package/src/core/checks/checks/cursor_boundary_fuzzing.ts +0 -219
- package/src/core/checks/checks/ensure_resource_availability.ts +0 -62
- package/src/core/checks/checks/idempotency_replay.ts +0 -242
- package/src/core/checks/checks/ignored_auth.ts +0 -254
- package/src/core/checks/checks/index.ts +0 -68
- package/src/core/checks/checks/lifecycle_transitions.ts +0 -416
- package/src/core/checks/checks/missing_required_header.ts +0 -40
- package/src/core/checks/checks/negative_data_rejection.ts +0 -148
- package/src/core/checks/checks/not_a_server_error.ts +0 -35
- package/src/core/checks/checks/open_cors_on_sensitive.ts +0 -160
- package/src/core/checks/checks/pagination_invariants.ts +0 -419
- package/src/core/checks/checks/positive_data_acceptance.ts +0 -33
- package/src/core/checks/checks/rate_limit_headers_absent.ts +0 -77
- package/src/core/checks/checks/response_headers_conformance.ts +0 -74
- package/src/core/checks/checks/response_schema_conformance.ts +0 -30
- package/src/core/checks/checks/status_code_conformance.ts +0 -132
- package/src/core/checks/checks/unsupported_method.ts +0 -63
- package/src/core/checks/checks/use_after_free.ts +0 -78
- package/src/core/checks/index.ts +0 -30
- package/src/core/checks/mode.ts +0 -82
- package/src/core/checks/recommended-action.ts +0 -68
- package/src/core/checks/registry.ts +0 -78
- package/src/core/checks/runner.ts +0 -1461
- package/src/core/checks/sarif.ts +0 -230
- package/src/core/checks/spec-findings.ts +0 -308
- package/src/core/checks/stateful.ts +0 -121
- package/src/core/checks/types.ts +0 -305
- package/src/core/checks/zond-extensions.ts +0 -73
- package/src/core/classifier/recommended-action.ts +0 -251
- package/src/core/context/current.ts +0 -51
- package/src/core/context/session.ts +0 -78
- package/src/core/coverage/loader.ts +0 -216
- package/src/core/coverage/reasons.ts +0 -300
- package/src/core/diagnostics/db-analysis.ts +0 -666
- package/src/core/diagnostics/failure-class.ts +0 -140
- package/src/core/diagnostics/failure-hints.ts +0 -112
- package/src/core/diagnostics/spec-pointer.ts +0 -99
- package/src/core/diagnostics/suggested-fixes.ts +0 -155
- package/src/core/exporter/case-study/index.ts +0 -270
- package/src/core/exporter/curl.ts +0 -40
- package/src/core/exporter/exporter.ts +0 -48
- package/src/core/exporter/html-report/escape.ts +0 -24
- package/src/core/exporter/html-report/index.ts +0 -479
- package/src/core/exporter/html-report/script.ts +0 -100
- package/src/core/exporter/html-report/styles.ts +0 -408
- package/src/core/generator/catalog-builder.ts +0 -179
- package/src/core/generator/chunker.ts +0 -78
- package/src/core/generator/coverage-phase.ts +0 -0
- package/src/core/generator/coverage-scanner.ts +0 -87
- package/src/core/generator/data-factory.ts +0 -759
- package/src/core/generator/describe.ts +0 -302
- package/src/core/generator/endpoint-warnings.ts +0 -52
- package/src/core/generator/fixtures-builder.ts +0 -332
- package/src/core/generator/index.ts +0 -14
- package/src/core/generator/openapi-reader.ts +0 -297
- package/src/core/generator/path-param-disambig.ts +0 -140
- package/src/core/generator/resources-builder.ts +0 -898
- package/src/core/generator/schema-utils.ts +0 -112
- package/src/core/generator/serializer.ts +0 -343
- package/src/core/generator/suite-generator.ts +0 -1301
- package/src/core/generator/types.ts +0 -63
- package/src/core/identity/identity-file.ts +0 -0
- package/src/core/lint/affects.ts +0 -28
- package/src/core/lint/config.ts +0 -96
- package/src/core/lint/format.ts +0 -42
- package/src/core/lint/index.ts +0 -94
- package/src/core/lint/reporter.ts +0 -128
- package/src/core/lint/rules/consistency.ts +0 -158
- package/src/core/lint/rules/heuristics.ts +0 -97
- package/src/core/lint/rules/strictness.ts +0 -109
- package/src/core/lint/types.ts +0 -96
- package/src/core/lint/walker.ts +0 -248
- package/src/core/meta/meta-store.ts +0 -11
- package/src/core/output/README.md +0 -73
- package/src/core/output/index.ts +0 -13
- package/src/core/output/run.ts +0 -91
- package/src/core/output/types.ts +0 -122
- package/src/core/parser/dynamic-values.ts +0 -160
- package/src/core/parser/env-interpolation.ts +0 -104
- package/src/core/parser/filter.ts +0 -97
- package/src/core/parser/schema.ts +0 -359
- package/src/core/parser/types.ts +0 -117
- package/src/core/parser/variables.ts +0 -0
- package/src/core/parser/yaml-parser.ts +0 -181
- package/src/core/probe/bootstrap.ts +0 -34
- package/src/core/probe/dry-run-envelope.ts +0 -61
- package/src/core/probe/mass-assignment/classify.ts +0 -175
- package/src/core/probe/mass-assignment/cleanup.ts +0 -52
- package/src/core/probe/mass-assignment/digest.ts +0 -114
- package/src/core/probe/mass-assignment/orchestrator.ts +0 -459
- package/src/core/probe/mass-assignment/regression.ts +0 -141
- package/src/core/probe/mass-assignment/suspects.ts +0 -92
- package/src/core/probe/mass-assignment/types.ts +0 -135
- package/src/core/probe/mass-assignment-probe-class.ts +0 -198
- package/src/core/probe/mass-assignment-probe.ts +0 -27
- package/src/core/probe/mass-assignment-template.ts +0 -240
- package/src/core/probe/method-probe.ts +0 -164
- package/src/core/probe/method-shared.ts +0 -69
- package/src/core/probe/negative-probe.ts +0 -691
- package/src/core/probe/orphan-tracker.ts +0 -188
- package/src/core/probe/path-discovery.ts +0 -439
- package/src/core/probe/probe-harness.ts +0 -119
- package/src/core/probe/registry.ts +0 -89
- package/src/core/probe/runner.ts +0 -136
- package/src/core/probe/security/baseline.ts +0 -174
- package/src/core/probe/security/classify.ts +0 -341
- package/src/core/probe/security/cleanup.ts +0 -125
- package/src/core/probe/security/detectors.ts +0 -71
- package/src/core/probe/security/digest.ts +0 -104
- package/src/core/probe/security/orchestrator.ts +0 -398
- package/src/core/probe/security/regression.ts +0 -103
- package/src/core/probe/security/types.ts +0 -151
- package/src/core/probe/security-probe-class.ts +0 -207
- package/src/core/probe/security-probe.ts +0 -32
- package/src/core/probe/shared.ts +0 -531
- package/src/core/probe/static-probe-class.ts +0 -125
- package/src/core/probe/types.ts +0 -165
- package/src/core/probe/verdict-aggregator.ts +0 -33
- package/src/core/probe/webhooks-probe.ts +0 -282
- package/src/core/reporter/console.ts +0 -240
- package/src/core/reporter/index.ts +0 -22
- package/src/core/reporter/json.ts +0 -22
- package/src/core/reporter/junit.ts +0 -93
- package/src/core/reporter/ndjson.ts +0 -37
- package/src/core/reporter/types.ts +0 -15
- package/src/core/runner/assertions.ts +0 -383
- package/src/core/runner/async-pool.ts +0 -108
- package/src/core/runner/auth-path.ts +0 -8
- package/src/core/runner/ci-context.ts +0 -72
- package/src/core/runner/executor.ts +0 -652
- package/src/core/runner/expr-eval.ts +0 -41
- package/src/core/runner/form-encode.ts +0 -41
- package/src/core/runner/http-client.ts +0 -224
- package/src/core/runner/learn-drift.ts +0 -293
- package/src/core/runner/preflight-vars.ts +0 -153
- package/src/core/runner/progress-tracker.ts +0 -73
- package/src/core/runner/rate-limiter.ts +0 -185
- package/src/core/runner/run-kind.ts +0 -45
- package/src/core/runner/schema-validator.ts +0 -308
- package/src/core/runner/send-request.ts +0 -232
- package/src/core/runner/transforms.ts +0 -65
- package/src/core/runner/types.ts +0 -94
- package/src/core/secrets/registry.ts +0 -164
- package/src/core/secrets/secrets-file.ts +0 -115
- package/src/core/selectors/operation-filter.ts +0 -144
- package/src/core/setup-api.ts +0 -590
- package/src/core/severity/category.ts +0 -94
- package/src/core/severity/index.ts +0 -58
- package/src/core/spec/infer-schema.ts +0 -102
- package/src/core/spec/layers.ts +0 -154
- package/src/core/spec/merge-specs.ts +0 -156
- package/src/core/spec/schema-from-runs.ts +0 -117
- package/src/core/spec/schema-overlay.ts +0 -130
- package/src/core/util/ajv.ts +0 -13
- package/src/core/util/format-eta.ts +0 -21
- package/src/core/util/headers.ts +0 -9
- package/src/core/util/url.ts +0 -24
- package/src/core/utils.ts +0 -13
- package/src/core/workspace/config.ts +0 -129
- package/src/core/workspace/fixture-gap-report.ts +0 -84
- package/src/core/workspace/fixture-gaps.ts +0 -71
- package/src/core/workspace/manifest.ts +0 -283
- package/src/core/workspace/output-rotation.ts +0 -62
- package/src/core/workspace/root.ts +0 -96
- package/src/core/workspace/triage-path.ts +0 -87
- package/src/db/lint-runs.ts +0 -47
- package/src/db/migrate.ts +0 -128
- package/src/db/migrations/0001_run_kind.sql +0 -25
- package/src/db/migrations/0002_run_kind_request.sql +0 -59
- package/src/db/migrations/sql.d.ts +0 -4
- package/src/db/queries/collections.ts +0 -133
- package/src/db/queries/coverage.ts +0 -9
- package/src/db/queries/dashboard.ts +0 -59
- package/src/db/queries/results.ts +0 -216
- package/src/db/queries/runs.ts +0 -289
- package/src/db/queries/sessions.ts +0 -42
- package/src/db/queries/settings.ts +0 -28
- package/src/db/queries/types.ts +0 -172
- package/src/db/queries.ts +0 -75
- package/src/db/schema.ts +0 -298
package/src/cli/json-envelope.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single source of truth for `--json` output across all CLI commands.
|
|
3
|
-
*
|
|
4
|
-
* Every `--json` response carries the same envelope:
|
|
5
|
-
*
|
|
6
|
-
* { ok, command, data, warnings, errors, exit_code? }
|
|
7
|
-
*
|
|
8
|
-
* Commands construct the payload (`data`) and ask one of the helpers
|
|
9
|
-
* below to render it. Don't `console.log(JSON.stringify(...))` ad-hoc
|
|
10
|
-
* for `--json` paths — go through `printJson` / `writeEnvelope` so the
|
|
11
|
-
* shape stays uniform (TASK-73, TASK-74, closed by TASK-184).
|
|
12
|
-
*
|
|
13
|
-
* TASK-296: errors[] is a list of `{code, message, details?}` so an
|
|
14
|
-
* agent can route on `code` without parsing the human message. Helpers
|
|
15
|
-
* accept either a bare `string` (auto-wrapped with code `unknown_error`)
|
|
16
|
-
* or a structured `ZondError` to keep call sites short.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
// TASK-295: types are derived from the zod schemas in `./json-schemas.ts`
|
|
20
|
-
// so the published JSON Schema (docs/json-schema/) and the runtime types
|
|
21
|
-
// can never drift. Edit the enum/object there, run `bun run schemas`,
|
|
22
|
-
// commit the regenerated docs.
|
|
23
|
-
import type { z } from "zod";
|
|
24
|
-
import {
|
|
25
|
-
ZondErrorCodeSchema,
|
|
26
|
-
ZondErrorSchema,
|
|
27
|
-
} from "./json-schemas.ts";
|
|
28
|
-
|
|
29
|
-
export type ZondErrorCode = z.infer<typeof ZondErrorCodeSchema>;
|
|
30
|
-
export type ZondError = z.infer<typeof ZondErrorSchema>;
|
|
31
|
-
|
|
32
|
-
export interface JsonEnvelope<T = unknown> {
|
|
33
|
-
ok: boolean;
|
|
34
|
-
command: string;
|
|
35
|
-
data: T;
|
|
36
|
-
warnings: string[];
|
|
37
|
-
errors: ZondError[];
|
|
38
|
-
/** Exit code the process will return. Present on error envelopes so a
|
|
39
|
-
* caller can read the taxonomy class without re-parsing $? from a shell
|
|
40
|
-
* (see ZOND.md → "Exit codes"). */
|
|
41
|
-
exit_code?: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Accept either a bare string (auto-coded `unknown_error`) or a fully-
|
|
45
|
-
* structured `ZondError`. Lets us migrate ~100 call sites incrementally
|
|
46
|
-
* without breaking the schema. */
|
|
47
|
-
export type ErrorInput = string | ZondError;
|
|
48
|
-
|
|
49
|
-
function normalizeErrors(errs: readonly ErrorInput[]): ZondError[] {
|
|
50
|
-
return errs.map(e =>
|
|
51
|
-
typeof e === "string" ? { code: "unknown_error" as const, message: e } : e,
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function jsonOk<T>(command: string, data: T, warnings?: string[]): JsonEnvelope<T> {
|
|
56
|
-
return { ok: true, command, data, warnings: warnings ?? [], errors: [] };
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function jsonError(
|
|
60
|
-
command: string,
|
|
61
|
-
errors: readonly ErrorInput[],
|
|
62
|
-
warnings?: string[],
|
|
63
|
-
exitCode = 2,
|
|
64
|
-
): JsonEnvelope<null> {
|
|
65
|
-
return {
|
|
66
|
-
ok: false,
|
|
67
|
-
command,
|
|
68
|
-
data: null,
|
|
69
|
-
warnings: warnings ?? [],
|
|
70
|
-
errors: normalizeErrors(errors),
|
|
71
|
-
exit_code: exitCode,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function printJson(envelope: JsonEnvelope): void {
|
|
76
|
-
process.stdout.write(JSON.stringify(envelope, null, 2) + "\n");
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Convenience constructor: `zerr("env_missing", "base_url not set", { var: "base_url" })`. */
|
|
80
|
-
export function zerr(code: ZondErrorCode, message: string, details?: Record<string, unknown>): ZondError {
|
|
81
|
-
return details ? { code, message, details } : { code, message };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Discriminated-union result an action can hand back to {@link writeEnvelope}. */
|
|
85
|
-
export type EnvelopeResult<T> =
|
|
86
|
-
| { ok: true; data: T; warnings?: string[] }
|
|
87
|
-
| { ok: false; errors: readonly ErrorInput[]; warnings?: string[]; exitCode?: number };
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Render a typed `EnvelopeResult` to stdout as a JSON envelope and return
|
|
91
|
-
* the process exit code (0 on ok, `result.exitCode ?? 2` on error). This
|
|
92
|
-
* is the recommended wrapper for new commands — it lets the handler
|
|
93
|
-
* focus on producing a payload and surfaces the right exit code in one
|
|
94
|
-
* call:
|
|
95
|
-
*
|
|
96
|
-
* const result = await doWork();
|
|
97
|
-
* if (options.json) return writeEnvelope("my-cmd", result);
|
|
98
|
-
* // …human path…
|
|
99
|
-
*/
|
|
100
|
-
export function writeEnvelope<T>(command: string, result: EnvelopeResult<T>): number {
|
|
101
|
-
if (result.ok) {
|
|
102
|
-
printJson(jsonOk(command, result.data, result.warnings));
|
|
103
|
-
return 0;
|
|
104
|
-
}
|
|
105
|
-
const exit = result.exitCode ?? 2;
|
|
106
|
-
printJson(jsonError(command, result.errors, result.warnings, exit));
|
|
107
|
-
return exit;
|
|
108
|
-
}
|
package/src/cli/json-schemas.ts
DELETED
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TASK-295: zod sources of truth for the `--json` envelope shape and its
|
|
3
|
-
* sub-types. Run `bun run scripts/emit-json-schemas.ts` after changing
|
|
4
|
-
* any of these to regenerate `docs/json-schema/*.schema.json`.
|
|
5
|
-
*
|
|
6
|
-
* Why zod first, JSON Schema second: zod is the type AND the validator
|
|
7
|
-
* we already ship; emitting JSON Schema from it keeps the published
|
|
8
|
-
* schema and the runtime checks in lock-step. New fields land here and
|
|
9
|
-
* propagate, instead of drifting between two hand-maintained shapes.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { z } from "zod";
|
|
13
|
-
|
|
14
|
-
/** TASK-296 closed enum — must stay in sync with `ZondErrorCode` in
|
|
15
|
-
* `src/cli/json-envelope.ts`. */
|
|
16
|
-
export const ZondErrorCodeSchema = z.enum([
|
|
17
|
-
"unknown_error",
|
|
18
|
-
"env_missing",
|
|
19
|
-
"fixture_missing",
|
|
20
|
-
"network_timeout",
|
|
21
|
-
"network_error",
|
|
22
|
-
"sandbox_blocked",
|
|
23
|
-
"spec_load_failure",
|
|
24
|
-
"yaml_parse_error",
|
|
25
|
-
"workspace_not_found",
|
|
26
|
-
"file_not_found",
|
|
27
|
-
"permission_denied",
|
|
28
|
-
"argument_invalid",
|
|
29
|
-
"api_not_registered",
|
|
30
|
-
"db_error",
|
|
31
|
-
"auth_config_error",
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
export const ZondErrorSchema = z.object({
|
|
35
|
-
code: ZondErrorCodeSchema,
|
|
36
|
-
message: z.string(),
|
|
37
|
-
details: z.record(z.string(), z.unknown()).optional(),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
/** TASK-294 closed enum — must stay in sync with `RecommendedAction` in
|
|
41
|
-
* `src/core/diagnostics/failure-hints.ts` and the per-check mapping in
|
|
42
|
-
* `src/core/checks/recommended-action.ts` (ARV-11).
|
|
43
|
-
* ARV-11 added three values for the depth-checks framework:
|
|
44
|
-
* - `tighten_validation` — server accepted invalid input.
|
|
45
|
-
* - `add_required_header` — server didn't enforce a required header.
|
|
46
|
-
* - `wontfix_known_limitation` — known/accepted gap; agent should
|
|
47
|
-
* not retry or report. */
|
|
48
|
-
export const RecommendedActionSchema = z.enum([
|
|
49
|
-
"report_backend_bug",
|
|
50
|
-
"fix_auth_config",
|
|
51
|
-
"fix_test_logic",
|
|
52
|
-
"fix_network_config",
|
|
53
|
-
"fix_env",
|
|
54
|
-
"fix_spec",
|
|
55
|
-
"fix_fixture",
|
|
56
|
-
// ARV-42 — re-run `zond generate` for failures rooted in generator-emitted
|
|
57
|
-
// bodies; editing the YAML directly is overwritten by the next regenerate.
|
|
58
|
-
"regenerate_suite",
|
|
59
|
-
"tighten_validation",
|
|
60
|
-
"add_required_header",
|
|
61
|
-
"wontfix_known_limitation",
|
|
62
|
-
]);
|
|
63
|
-
|
|
64
|
-
/** Envelope body. `data` is open (`unknown`) so this schema covers every
|
|
65
|
-
* command without enumerating each payload — command-specific schemas
|
|
66
|
-
* can refine `data` per-command in a follow-up. */
|
|
67
|
-
export const JsonEnvelopeSchema = z.object({
|
|
68
|
-
ok: z.boolean(),
|
|
69
|
-
command: z.string(),
|
|
70
|
-
data: z.unknown(),
|
|
71
|
-
warnings: z.array(z.string()),
|
|
72
|
-
errors: z.array(ZondErrorSchema),
|
|
73
|
-
exit_code: z.number().int().optional(),
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
/** ARV-1 (m-15): shape of `data` for `zond checks run --json`. The
|
|
77
|
-
* envelope itself stays the generic JsonEnvelopeSchema; this schema
|
|
78
|
-
* pins the per-command payload so agents can validate findings without
|
|
79
|
-
* parsing them by-hand. ARV-11 adds `recommended_action` as a closed
|
|
80
|
-
* enum on each finding. */
|
|
81
|
-
export const SeveritySchema = z.enum(["critical", "high", "medium", "low", "info"]);
|
|
82
|
-
export const CategorySchema = z.enum(["security", "reliability", "contract", "hygiene"]);
|
|
83
|
-
|
|
84
|
-
export const CheckFindingSchema = z.object({
|
|
85
|
-
check: z.string(),
|
|
86
|
-
severity: SeveritySchema,
|
|
87
|
-
// ARV-251: category drives per-section roll-up. Optional on the wire
|
|
88
|
-
// for backwards compat with older NDJSON streams — derived by reader
|
|
89
|
-
// from check id if absent.
|
|
90
|
-
category: CategorySchema.optional(),
|
|
91
|
-
operation: z.object({
|
|
92
|
-
path: z.string(),
|
|
93
|
-
method: z.string(),
|
|
94
|
-
operationId: z.string().optional(),
|
|
95
|
-
}),
|
|
96
|
-
request_signature: z.string(),
|
|
97
|
-
response_summary: z.object({
|
|
98
|
-
status: z.number().int(),
|
|
99
|
-
content_type: z.string().optional(),
|
|
100
|
-
}),
|
|
101
|
-
message: z.string(),
|
|
102
|
-
evidence: z.record(z.string(), z.unknown()).optional(),
|
|
103
|
-
// ARV-11: recommended_action is now a closed enum so agents can
|
|
104
|
-
// route on it without parsing free-form strings. Same enum used by
|
|
105
|
-
// `db diagnose` (TASK-294) plus three depth-check additions.
|
|
106
|
-
recommended_action: RecommendedActionSchema.optional(),
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
export const CheckRunSummarySchema = z.object({
|
|
110
|
-
operations: z.number().int().nonnegative(),
|
|
111
|
-
cases: z.number().int().nonnegative(),
|
|
112
|
-
checks_run: z.number().int().nonnegative(),
|
|
113
|
-
findings: z.number().int().nonnegative(),
|
|
114
|
-
by_severity: z.object({
|
|
115
|
-
critical: z.number().int().nonnegative(),
|
|
116
|
-
high: z.number().int().nonnegative(),
|
|
117
|
-
medium: z.number().int().nonnegative(),
|
|
118
|
-
low: z.number().int().nonnegative(),
|
|
119
|
-
info: z.number().int().nonnegative(),
|
|
120
|
-
}),
|
|
121
|
-
by_category: z.object({
|
|
122
|
-
security: z.number().int().nonnegative(),
|
|
123
|
-
reliability: z.number().int().nonnegative(),
|
|
124
|
-
contract: z.number().int().nonnegative(),
|
|
125
|
-
hygiene: z.number().int().nonnegative(),
|
|
126
|
-
}),
|
|
127
|
-
// ARV-26: per-(check, reason) skip tally — surfaces probe outcomes that
|
|
128
|
-
// never produced a checkable response (e.g. probe got 4xx, schema only on
|
|
129
|
-
// 200) so "0 findings" doesn't read as "all green".
|
|
130
|
-
skipped_outcomes: z.record(z.string(), z.number().int().nonnegative()),
|
|
131
|
-
// ARV-83: structured counterpart to skipped_outcomes — split into
|
|
132
|
-
// {check, reason, count} so consumers don't have to colon-tokenise a
|
|
133
|
-
// reason that may itself contain colons. Sorted by count desc.
|
|
134
|
-
skipped_outcomes_grouped: z.array(z.object({
|
|
135
|
-
check: z.string(),
|
|
136
|
-
reason: z.string(),
|
|
137
|
-
count: z.number().int().nonnegative(),
|
|
138
|
-
})),
|
|
139
|
-
// ARV-283 / ARV-68: count of findings the severity matrix demoted to
|
|
140
|
-
// `info-suppressed`. Excluded from `findings` / `by_severity` so CI
|
|
141
|
-
// gates ignore them, but exposed here so consumers (ajv validators
|
|
142
|
-
// included) accept the field — the runner emits it unconditionally.
|
|
143
|
-
suppressed: z.number().int().nonnegative().optional(),
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
/** ARV-60: spec-level rollup row. Emitted when ≥80% of a check's
|
|
147
|
-
* applicable operations share the same root cause (status drift,
|
|
148
|
-
* missing-declaration skip cluster, or no-detector zero-case). Lives in
|
|
149
|
-
* `data.spec_findings` and as its own `spec_finding` NDJSON event. */
|
|
150
|
-
export const SpecFindingSchema = z.object({
|
|
151
|
-
check: z.string(),
|
|
152
|
-
kind: z.enum(["status_drift", "missing_declaration", "no_detector", "broken_baseline", "other"]),
|
|
153
|
-
severity: SeveritySchema,
|
|
154
|
-
category: CategorySchema.optional(),
|
|
155
|
-
reason: z.string(),
|
|
156
|
-
fix_hint: z.string(),
|
|
157
|
-
affected_operations: z.array(z.object({
|
|
158
|
-
path: z.string(),
|
|
159
|
-
method: z.string(),
|
|
160
|
-
operationId: z.string().optional(),
|
|
161
|
-
})),
|
|
162
|
-
count: z.number().int().nonnegative(),
|
|
163
|
-
applicable: z.number().int().nonnegative(),
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
export const ChecksRunDataSchema = z.object({
|
|
167
|
-
findings: z.array(CheckFindingSchema),
|
|
168
|
-
summary: CheckRunSummarySchema,
|
|
169
|
-
// ARV-60: always present (empty array when no clusters cross 80%).
|
|
170
|
-
spec_findings: z.array(SpecFindingSchema),
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
/** ARV-10 (m-15): NDJSON streaming events emitted by `zond checks run
|
|
174
|
-
* --ndjson`. Each event is a snapshot JSON line on stdout — agents pipe
|
|
175
|
-
* the stream into `jq` / a validator and consume findings as they happen
|
|
176
|
-
* rather than waiting for the run to finish. The discriminated union
|
|
177
|
-
* below is the schema we publish — every emitted line MUST match one
|
|
178
|
-
* branch exactly (verified by ajv in tests). */
|
|
179
|
-
const OperationRefSchema = z.object({
|
|
180
|
-
path: z.string(),
|
|
181
|
-
method: z.string(),
|
|
182
|
-
operationId: z.string().optional(),
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
export const NdjsonCheckStartEventSchema = z.object({
|
|
186
|
-
type: z.literal("check_start"),
|
|
187
|
-
ts: z.string(),
|
|
188
|
-
operation: OperationRefSchema,
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
export const NdjsonCheckResultEventSchema = z.object({
|
|
192
|
-
type: z.literal("check_result"),
|
|
193
|
-
ts: z.string(),
|
|
194
|
-
check: z.string(),
|
|
195
|
-
// ARV-215: severity from the registry (mirrors `zond checks list`
|
|
196
|
-
// [high|medium|low]). Lets consumers group NDJSON by severity without
|
|
197
|
-
// re-joining against the registry.
|
|
198
|
-
severity: z.enum(["info", "low", "medium", "high", "critical"]),
|
|
199
|
-
verdict: z.enum(["pass", "fail"]),
|
|
200
|
-
operation: OperationRefSchema,
|
|
201
|
-
request_signature: z.string(),
|
|
202
|
-
response: z.object({
|
|
203
|
-
status: z.number().int(),
|
|
204
|
-
content_type: z.string().optional(),
|
|
205
|
-
}),
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
export const NdjsonFindingEventSchema = z.object({
|
|
209
|
-
type: z.literal("finding"),
|
|
210
|
-
ts: z.string(),
|
|
211
|
-
// ARV-156: mirror the top-level `check` field carried by check_start /
|
|
212
|
-
// check_result so consumer pipelines can `jq -c '.check'` uniformly
|
|
213
|
-
// across event types without branching on `.type`. The same value lives
|
|
214
|
-
// inside `.finding.check` — existing consumers reading the nested form
|
|
215
|
-
// keep working (back-compat addition, not a rename).
|
|
216
|
-
check: z.string(),
|
|
217
|
-
finding: CheckFindingSchema,
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
export const NdjsonSummaryEventSchema = z.object({
|
|
221
|
-
type: z.literal("summary"),
|
|
222
|
-
ts: z.string(),
|
|
223
|
-
summary: CheckRunSummarySchema,
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
/** ARV-60: rolled-up spec-level finding event. Emitted before the
|
|
227
|
-
* terminal `summary` event so streaming consumers see clusters in the
|
|
228
|
-
* same order the CLI renders them. Per-op `finding` events are NOT
|
|
229
|
-
* removed — both layers coexist. */
|
|
230
|
-
export const NdjsonSpecFindingEventSchema = z.object({
|
|
231
|
-
type: z.literal("spec_finding"),
|
|
232
|
-
ts: z.string(),
|
|
233
|
-
check: z.string(),
|
|
234
|
-
spec_finding: SpecFindingSchema,
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
export const NdjsonEventSchema = z.discriminatedUnion("type", [
|
|
238
|
-
NdjsonCheckStartEventSchema,
|
|
239
|
-
NdjsonCheckResultEventSchema,
|
|
240
|
-
NdjsonFindingEventSchema,
|
|
241
|
-
NdjsonSpecFindingEventSchema,
|
|
242
|
-
NdjsonSummaryEventSchema,
|
|
243
|
-
]);
|
|
244
|
-
|
|
245
|
-
/** m-17 / ARV-50: shape of `data` for `zond probe <class> --dry-run --json`.
|
|
246
|
-
* Severity is intentionally absent — nothing is classified yet, so
|
|
247
|
-
* reusing the run-time bucket would mislead CI gates (F1-15). The
|
|
248
|
-
* `skip_reason` enum is open across probe families (e.g. security has
|
|
249
|
-
* `isolated-protected`, mass-assignment has its own subset); we keep
|
|
250
|
-
* it as a string with documented values rather than a closed enum
|
|
251
|
-
* that needs to be rev'd every time a new class lands. */
|
|
252
|
-
export const ProbeEndpointPlanSchema = z.object({
|
|
253
|
-
path: z.string(),
|
|
254
|
-
method: z.string(),
|
|
255
|
-
planned: z.boolean(),
|
|
256
|
-
classes_planned: z.array(z.string()),
|
|
257
|
-
fields_planned: z.array(z.string()),
|
|
258
|
-
skip_reason: z.string().nullable(),
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
export const ProbeDryRunDataSchema = z.object({
|
|
262
|
-
endpoints: z.array(ProbeEndpointPlanSchema),
|
|
263
|
-
summary: z.object({
|
|
264
|
-
totalEndpoints: z.number().int().nonnegative(),
|
|
265
|
-
planned: z.number().int().nonnegative(),
|
|
266
|
-
skipped: z.number().int().nonnegative(),
|
|
267
|
-
}),
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
/** m-17 / ARV-51: shape of `data` for live probe runs (`zond probe <class>
|
|
271
|
-
* --report json` or the default `--json`). One entry per endpoint with
|
|
272
|
-
* structured findings — no markdown blob. The legacy `data.digest.stdout`
|
|
273
|
-
* field is gone (F3-15 / F4-15). */
|
|
274
|
-
export const ProbeFindingSchema = z.object({
|
|
275
|
-
class: z.string(),
|
|
276
|
-
severity: z.enum(["high", "low", "inconclusive", "ok"]),
|
|
277
|
-
evidence: z.record(z.string(), z.unknown()),
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
export const ProbeEndpointResultSchema = z.object({
|
|
281
|
-
path: z.string(),
|
|
282
|
-
method: z.string(),
|
|
283
|
-
classes_run: z.array(z.string()),
|
|
284
|
-
findings: z.array(ProbeFindingSchema),
|
|
285
|
-
status: z.enum(["ok", "high", "low", "inconclusive", "skipped"]),
|
|
286
|
-
skip_reason: z.string().optional(),
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
export const ProbeRunDataSchema = z.object({
|
|
290
|
-
endpoints: z.array(ProbeEndpointResultSchema),
|
|
291
|
-
summary: z.object({
|
|
292
|
-
totalEndpoints: z.number().int().nonnegative(),
|
|
293
|
-
probed: z.number().int().nonnegative(),
|
|
294
|
-
by_status: z.object({
|
|
295
|
-
ok: z.number().int().nonnegative(),
|
|
296
|
-
high: z.number().int().nonnegative(),
|
|
297
|
-
low: z.number().int().nonnegative(),
|
|
298
|
-
inconclusive: z.number().int().nonnegative(),
|
|
299
|
-
skipped: z.number().int().nonnegative(),
|
|
300
|
-
}),
|
|
301
|
-
}),
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
export const SCHEMAS = {
|
|
305
|
-
envelope: JsonEnvelopeSchema,
|
|
306
|
-
error: ZondErrorSchema,
|
|
307
|
-
errorCode: ZondErrorCodeSchema,
|
|
308
|
-
recommendedAction: RecommendedActionSchema,
|
|
309
|
-
checksRunData: ChecksRunDataSchema,
|
|
310
|
-
checkFinding: CheckFindingSchema,
|
|
311
|
-
"ndjson-events": NdjsonEventSchema,
|
|
312
|
-
probeDryRun: ProbeDryRunDataSchema,
|
|
313
|
-
probeRun: ProbeRunDataSchema,
|
|
314
|
-
} as const;
|
package/src/cli/output.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const RESET = "\x1b[0m";
|
|
2
|
-
const RED = "\x1b[31m";
|
|
3
|
-
const GREEN = "\x1b[32m";
|
|
4
|
-
const YELLOW = "\x1b[33m";
|
|
5
|
-
|
|
6
|
-
function useColor(): boolean {
|
|
7
|
-
return process.stderr.isTTY ?? false;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let debugHintShown = false;
|
|
11
|
-
|
|
12
|
-
// ARV-203: when a command catches an unexpected throw and calls
|
|
13
|
-
// `printError(msg, err)`, gate the stack trace behind ZOND_DEBUG=1.
|
|
14
|
-
// Without the env var, append a one-time hint so the user knows the
|
|
15
|
-
// switch exists — the previous behaviour silently dropped TypeError
|
|
16
|
-
// stacks and forced reverse-engineering from the bare message.
|
|
17
|
-
export function printError(message: string, err?: unknown): void {
|
|
18
|
-
const msg = useColor() ? `${RED}Error: ${message}${RESET}` : `Error: ${message}`;
|
|
19
|
-
process.stderr.write(msg + "\n");
|
|
20
|
-
if (err === undefined) return;
|
|
21
|
-
if (process.env.ZOND_DEBUG === "1" && err instanceof Error && err.stack) {
|
|
22
|
-
process.stderr.write(err.stack + "\n");
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
if (!debugHintShown) {
|
|
26
|
-
debugHintShown = true;
|
|
27
|
-
process.stderr.write(" hint: set ZOND_DEBUG=1 to print the full stack trace.\n");
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function printSuccess(message: string): void {
|
|
32
|
-
const color = process.stdout.isTTY ?? false;
|
|
33
|
-
const msg = color ? `${GREEN}${message}${RESET}` : message;
|
|
34
|
-
process.stdout.write(msg + "\n");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function printWarning(message: string): void {
|
|
38
|
-
const msg = useColor() ? `${YELLOW}Warning: ${message}${RESET}` : `Warning: ${message}`;
|
|
39
|
-
process.stderr.write(msg + "\n");
|
|
40
|
-
}
|
package/src/cli/program.ts
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { Command } from "commander";
|
|
2
|
-
|
|
3
|
-
import { registerRun } from "./commands/run.ts";
|
|
4
|
-
import { registerCheck, registerLint } from "./commands/check.ts";
|
|
5
|
-
import { registerChecks } from "./commands/checks.ts";
|
|
6
|
-
import { registerCoverage } from "./commands/coverage.ts";
|
|
7
|
-
import { registerCi } from "./commands/ci-init.ts";
|
|
8
|
-
import { registerClean } from "./commands/clean.ts";
|
|
9
|
-
import { registerCleanup } from "./commands/cleanup.ts";
|
|
10
|
-
import { registerInit } from "./commands/init/index.ts";
|
|
11
|
-
import { registerDescribe } from "./commands/describe.ts";
|
|
12
|
-
import { registerDb } from "./commands/db.ts";
|
|
13
|
-
import { registerRequest } from "./commands/request.ts";
|
|
14
|
-
import { registerGenerate } from "./commands/generate.ts";
|
|
15
|
-
import { registerPrepareFixtures } from "./commands/prepare-fixtures.ts";
|
|
16
|
-
import { registerFixtures } from "./commands/fixtures.ts";
|
|
17
|
-
import { registerSecrets } from "./commands/secrets.ts";
|
|
18
|
-
import { registerProbes } from "./commands/probe.ts";
|
|
19
|
-
import { bootstrapProbes } from "../core/probe/bootstrap.ts";
|
|
20
|
-
import { registerReport } from "./commands/report.ts";
|
|
21
|
-
import { registerCatalog } from "./commands/catalog.ts";
|
|
22
|
-
import { registerCompletions } from "./commands/completions.ts";
|
|
23
|
-
import { registerUse } from "./commands/use.ts";
|
|
24
|
-
import { registerSession } from "./commands/session.ts";
|
|
25
|
-
import { registerDoctor } from "./commands/doctor.ts";
|
|
26
|
-
import { registerRefreshApi } from "./commands/refresh-api.ts";
|
|
27
|
-
import { registerSchemaFromRuns } from "./commands/schema-from-runs.ts";
|
|
28
|
-
import { registerAdd } from "./commands/add-api.ts";
|
|
29
|
-
import { registerRemove } from "./commands/remove-api.ts";
|
|
30
|
-
import { registerAudit } from "./commands/audit.ts";
|
|
31
|
-
import { registerReference } from "./commands/reference.ts";
|
|
32
|
-
import { registerApiAnnotate } from "./commands/api/annotate/index.ts";
|
|
33
|
-
|
|
34
|
-
import { getSecretRegistry } from "../core/secrets/registry.ts";
|
|
35
|
-
import { getRuntimeInfo } from "./runtime.ts";
|
|
36
|
-
import { VERSION } from "./version.ts";
|
|
37
|
-
import { preprocessArgv } from "./argv.ts";
|
|
38
|
-
|
|
39
|
-
export { preprocessArgv };
|
|
40
|
-
|
|
41
|
-
// ── Program builder ──
|
|
42
|
-
|
|
43
|
-
export function buildProgram(): Command {
|
|
44
|
-
const program = new Command("zond")
|
|
45
|
-
.description("API Testing Platform")
|
|
46
|
-
.version(`${VERSION} (${getRuntimeInfo()})`, "-v, --version", "Show version")
|
|
47
|
-
.helpOption("-h, --help", "Show this help")
|
|
48
|
-
.showHelpAfterError("(run 'zond --help' for usage)")
|
|
49
|
-
.exitOverride()
|
|
50
|
-
// TASK-166 (m-10): global escape hatch for local debugging — disables
|
|
51
|
-
// the secret registry's redaction pass everywhere (DB writes,
|
|
52
|
-
// exporters, stdout). Default is redact-on. Hook is read from the
|
|
53
|
-
// env var so it survives across nested subcommand parsers.
|
|
54
|
-
.option("--no-redact", "Disable auto-redaction of registered secret values (debug only)")
|
|
55
|
-
.option(
|
|
56
|
-
"--api <name>",
|
|
57
|
-
"TASK-290: Select the active API for this invocation. Resolution order: per-command --api > global --api (this flag) > ZOND_API env > .zond/current-api file (set via `zond use <name>`).",
|
|
58
|
-
)
|
|
59
|
-
.hook("preAction", (thisCommand) => {
|
|
60
|
-
const enabled = thisCommand.opts().redact !== false;
|
|
61
|
-
// Mirror the flag into env so deeply-nested code that doesn't have
|
|
62
|
-
// access to `cmd` (e.g. setup-api, exporters) can still consult it.
|
|
63
|
-
process.env.ZOND_REDACT = enabled ? "1" : "0";
|
|
64
|
-
getSecretRegistry().setEnabled(enabled);
|
|
65
|
-
// TASK-290: mirror the global --api flag into env so the resolution
|
|
66
|
-
// chain in core/context/current.ts (which has no `cmd` ref) sees it.
|
|
67
|
-
// Per-command --api still wins because it is passed positionally to
|
|
68
|
-
// resolveSpecArg / resolveApiCollection.
|
|
69
|
-
const apiGlobal = thisCommand.opts().api;
|
|
70
|
-
if (typeof apiGlobal === "string" && apiGlobal.length > 0) {
|
|
71
|
-
process.env.ZOND_API_GLOBAL = apiGlobal;
|
|
72
|
-
} else {
|
|
73
|
-
delete process.env.ZOND_API_GLOBAL;
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
registerRun(program);
|
|
78
|
-
|
|
79
|
-
registerCheck(program);
|
|
80
|
-
registerChecks(program);
|
|
81
|
-
registerLint(program);
|
|
82
|
-
|
|
83
|
-
registerCi(program);
|
|
84
|
-
|
|
85
|
-
registerUse(program);
|
|
86
|
-
registerRefreshApi(program);
|
|
87
|
-
registerSchemaFromRuns(program);
|
|
88
|
-
registerDoctor(program);
|
|
89
|
-
|
|
90
|
-
registerSession(program);
|
|
91
|
-
registerCoverage(program);
|
|
92
|
-
|
|
93
|
-
registerInit(program);
|
|
94
|
-
registerAdd(program);
|
|
95
|
-
registerRemove(program);
|
|
96
|
-
|
|
97
|
-
registerDescribe(program);
|
|
98
|
-
registerDb(program);
|
|
99
|
-
registerRequest(program);
|
|
100
|
-
|
|
101
|
-
registerClean(program);
|
|
102
|
-
registerCleanup(program);
|
|
103
|
-
|
|
104
|
-
registerGenerate(program);
|
|
105
|
-
registerPrepareFixtures(program);
|
|
106
|
-
registerFixtures(program);
|
|
107
|
-
registerSecrets(program);
|
|
108
|
-
registerAudit(program);
|
|
109
|
-
|
|
110
|
-
// m-17 / ARV-49: validate registered probes implement the Probe
|
|
111
|
-
// contract before commander gets to wire them up. Boot-throws on a
|
|
112
|
-
// missing slot, so a regression can't slip past CI.
|
|
113
|
-
bootstrapProbes();
|
|
114
|
-
registerProbes(program);
|
|
115
|
-
|
|
116
|
-
registerCatalog(program);
|
|
117
|
-
registerReport(program);
|
|
118
|
-
|
|
119
|
-
registerCompletions(program);
|
|
120
|
-
registerReference(program);
|
|
121
|
-
registerApiAnnotate(program);
|
|
122
|
-
|
|
123
|
-
// TASK-267: group top-level commands by phase in `zond --help`. Without
|
|
124
|
-
// grouping, the flat 20+ command list buries the workflow shape; with it,
|
|
125
|
-
// a new tester can see "setup → generate → run → analyze → report" at a
|
|
126
|
-
// glance. Commands not listed below stay in the default group.
|
|
127
|
-
const HELP_GROUPS: Record<string, string> = {
|
|
128
|
-
// setup: register an API, prepare workspace
|
|
129
|
-
"init": "Setup:",
|
|
130
|
-
"add": "Setup:",
|
|
131
|
-
"remove": "Setup:",
|
|
132
|
-
"use": "Setup:",
|
|
133
|
-
"secrets": "Setup:",
|
|
134
|
-
"refresh-api": "Setup:",
|
|
135
|
-
"doctor": "Setup:",
|
|
136
|
-
"clean": "Setup:",
|
|
137
|
-
"cleanup": "Setup:",
|
|
138
|
-
// generate: produce suites/probes from the spec
|
|
139
|
-
"generate": "Generate:",
|
|
140
|
-
"prepare-fixtures": "Generate:",
|
|
141
|
-
"probe": "Generate:",
|
|
142
|
-
// run: execute suites against a live API
|
|
143
|
-
"run": "Run:",
|
|
144
|
-
"session": "Run:",
|
|
145
|
-
"request": "Run:",
|
|
146
|
-
// analyze: post-run inspection and triage
|
|
147
|
-
"coverage": "Analyze:",
|
|
148
|
-
"db": "Analyze:",
|
|
149
|
-
"audit": "Analyze:",
|
|
150
|
-
"check": "Analyze:",
|
|
151
|
-
"checks": "Analyze:",
|
|
152
|
-
"describe": "Analyze:",
|
|
153
|
-
// report: outbound artefacts (HTML, bundles, catalog)
|
|
154
|
-
"report": "Report:",
|
|
155
|
-
"catalog": "Report:",
|
|
156
|
-
// other: scaffolding / shell integration
|
|
157
|
-
"ci": "Other:",
|
|
158
|
-
"completions": "Other:",
|
|
159
|
-
"reference": "Other:",
|
|
160
|
-
};
|
|
161
|
-
for (const sub of program.commands) {
|
|
162
|
-
const group = HELP_GROUPS[sub.name()];
|
|
163
|
-
if (group) sub.helpGroup(group);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// TASK-73: previously `--json` was a top-level/global option that propagated
|
|
167
|
-
// to every subcommand, which collided with `run --report json` (and broke
|
|
168
|
-
// `run --json` outright). Now it is per-command. Attach `--json` to every
|
|
169
|
-
// subcommand that previously read it via globalJson(), EXCEPT `run` —
|
|
170
|
-
// run's only JSON output path is `--report json`.
|
|
171
|
-
// Skip by fully-qualified path so `db run` (inner) keeps --json while
|
|
172
|
-
// top-level `run` does not.
|
|
173
|
-
const skipJson = new Set(["run", "completions"]);
|
|
174
|
-
const attachJson = (cmd: Command, parentPath: string): void => {
|
|
175
|
-
const path = parentPath ? `${parentPath} ${cmd.name()}` : cmd.name();
|
|
176
|
-
// Only leaf commands (those with action handlers) get --json — parent
|
|
177
|
-
// namespace commands like `db` and `ci` would otherwise shadow the option
|
|
178
|
-
// on their children and `cmd.opts()` on the leaf would not see --json.
|
|
179
|
-
const hasAction = (cmd as unknown as { _actionHandler?: unknown })._actionHandler != null;
|
|
180
|
-
if (hasAction && !skipJson.has(path)) {
|
|
181
|
-
cmd.option(
|
|
182
|
-
"--json",
|
|
183
|
-
"Emit a `{ok, command, data, warnings, errors}` envelope on stdout. " +
|
|
184
|
-
"Distinct from `zond run --report json` (which is a per-test test-run report).",
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
for (const sub of cmd.commands) attachJson(sub, path);
|
|
188
|
-
};
|
|
189
|
-
for (const sub of program.commands) attachJson(sub, "");
|
|
190
|
-
|
|
191
|
-
// TASK-297: stamp every leaf with a "related skill" footer so `zond <cmd>
|
|
192
|
-
// --help` is a single-stop entry point for an agent: discover the flag
|
|
193
|
-
// surface AND know which skill file to open for the workflow context.
|
|
194
|
-
// Mapped by fully-qualified path; `*` matches any unnamed leaf and is
|
|
195
|
-
// tried last.
|
|
196
|
-
const skillFor: Record<string, string> = {
|
|
197
|
-
// Depth-check & probe commands → checks skill (annotate flow + m-20).
|
|
198
|
-
"checks run": "skills/zond-checks.md",
|
|
199
|
-
"checks list": "skills/zond-checks.md",
|
|
200
|
-
"api annotate": "skills/zond-checks.md",
|
|
201
|
-
"probe security": "skills/zond-checks.md",
|
|
202
|
-
"probe mass-assignment": "skills/zond-checks.md",
|
|
203
|
-
// Triage-class commands.
|
|
204
|
-
"db diagnose": "skills/zond-triage.md",
|
|
205
|
-
"db compare": "skills/zond-triage.md",
|
|
206
|
-
};
|
|
207
|
-
const attachHelp = (cmd: Command, parentPath: string): void => {
|
|
208
|
-
const path = parentPath ? `${parentPath} ${cmd.name()}` : cmd.name();
|
|
209
|
-
const hasAction = (cmd as unknown as { _actionHandler?: unknown })._actionHandler != null;
|
|
210
|
-
if (hasAction) {
|
|
211
|
-
const skill = skillFor[path] ?? "skills/zond.md";
|
|
212
|
-
cmd.addHelpText("after", `\nRelated skill: ${skill}`);
|
|
213
|
-
}
|
|
214
|
-
for (const sub of cmd.commands) attachHelp(sub, path);
|
|
215
|
-
};
|
|
216
|
-
for (const sub of program.commands) attachHelp(sub, "");
|
|
217
|
-
|
|
218
|
-
return program;
|
|
219
|
-
}
|