@kirrosh/zond 0.12.3 → 0.12.5
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/README.md
CHANGED
|
@@ -1,128 +1,83 @@
|
|
|
1
1
|
# zond
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
AI-powered API testing for Claude Code, Cursor, and CI/CD.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Say "test my API" — get working tests, coverage dashboard, and CI config in minutes.
|
|
6
|
+
|
|
7
|
+
<!-- TODO: add demo GIF (15 sec: plugin install → "cover openapi.json with tests" → 42/47 endpoints covered → dashboard) -->
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Zond reads your OpenAPI spec and gives your AI agent everything it needs to test your API: structured tools, safety guardrails, coverage tracking, and run history. You don't need to learn anything new — just describe what you want and the agent handles the rest.
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Quick Start
|
|
10
12
|
|
|
11
13
|
```
|
|
12
14
|
/plugin marketplace add kirrosh/zond
|
|
13
15
|
/plugin install zond@zond-marketplace
|
|
14
16
|
```
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
- **17 MCP tools** for API testing (test generation, execution, diagnostics, coverage)
|
|
18
|
-
- **Skills** for test generation, debugging failures, and CI setup
|
|
19
|
-
- **Slash commands**: `/zond:api-test`, `/zond:api-coverage`
|
|
20
|
-
|
|
21
|
-
After installation, just say: _"Safely cover the API from openapi.json with tests"_ — the agent handles everything.
|
|
22
|
-
|
|
23
|
-
## Install
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# Option 1: via npx (recommended — works everywhere with Node.js)
|
|
27
|
-
npx -y @kirrosh/zond --version
|
|
28
|
-
|
|
29
|
-
# Option 2: Binary (no Node.js required)
|
|
30
|
-
# macOS / Linux
|
|
31
|
-
curl -fsSL https://raw.githubusercontent.com/kirrosh/zond/master/install.sh | sh
|
|
32
|
-
|
|
33
|
-
# Windows
|
|
34
|
-
iwr https://raw.githubusercontent.com/kirrosh/zond/master/install.ps1 | iex
|
|
35
|
-
```
|
|
18
|
+
Then say: _"Safely cover the API from openapi.json with tests"_
|
|
36
19
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
## MCP Setup (Cursor / Claude Code / Windsurf)
|
|
40
|
-
|
|
41
|
-
Click the badge above, or add manually:
|
|
42
|
-
|
|
43
|
-
```json
|
|
44
|
-
{
|
|
45
|
-
"mcpServers": {
|
|
46
|
-
"zond": {
|
|
47
|
-
"command": "npx",
|
|
48
|
-
"args": [
|
|
49
|
-
"-y",
|
|
50
|
-
"@kirrosh/zond@latest",
|
|
51
|
-
"mcp",
|
|
52
|
-
"--dir",
|
|
53
|
-
"${workspaceFolder}"
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
20
|
+
You get skills, slash commands, and 12 MCP tools in one package.
|
|
59
21
|
|
|
60
|
-
>
|
|
22
|
+
<details>
|
|
23
|
+
<summary>Other installation methods (MCP, CLI, binary)</summary>
|
|
61
24
|
|
|
62
|
-
|
|
25
|
+
### MCP Server (Cursor, Windsurf, other editors)
|
|
63
26
|
|
|
64
|
-
|
|
65
|
-
| ----------- | ----------------------------------------------------- |
|
|
66
|
-
| Cursor | Settings > MCP, or `.cursor/mcp.json` in project root |
|
|
67
|
-
| Claude Code | `.mcp.json` in project root |
|
|
68
|
-
| Windsurf | `.windsurfrules/mcp.json` or settings |
|
|
27
|
+
[](https://cursor.com/en/install-mcp?name=zond&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBraXJyb3NoL3pvbmQiLCJtY3AiXX0K)
|
|
69
28
|
|
|
70
|
-
|
|
29
|
+
Or add manually — see [MCP setup guide](docs/mcp-guide.md) for Cursor, Claude Code, and Windsurf config.
|
|
71
30
|
|
|
72
|
-
|
|
31
|
+
### CLI / Binary
|
|
73
32
|
|
|
74
|
-
|
|
33
|
+
```bash
|
|
34
|
+
npx -y @kirrosh/zond --version
|
|
75
35
|
|
|
76
|
-
|
|
77
|
-
|
|
36
|
+
# Standalone binary (no Node.js required)
|
|
37
|
+
curl -fsSL https://raw.githubusercontent.com/kirrosh/zond/master/install.sh | sh # macOS/Linux
|
|
38
|
+
iwr https://raw.githubusercontent.com/kirrosh/zond/master/install.ps1 | iex # Windows
|
|
78
39
|
```
|
|
79
40
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
generate_and_save(specPath: "openapi.json")
|
|
84
|
-
```
|
|
41
|
+
See [ZOND.md](ZOND.md) for full CLI reference.
|
|
85
42
|
|
|
86
|
-
|
|
43
|
+
</details>
|
|
87
44
|
|
|
88
|
-
|
|
45
|
+
## What Happens
|
|
89
46
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
47
|
+
1. **Point** — you give the agent an OpenAPI spec
|
|
48
|
+
2. **Generate** — zond reads the spec, produces YAML test suites (smoke + CRUD)
|
|
49
|
+
3. **Run** — tests execute, failures are diagnosed, coverage is tracked
|
|
93
50
|
|
|
94
|
-
|
|
51
|
+
The agent does all three steps autonomously. It asks you only when it needs an auth token or permission to run write operations.
|
|
95
52
|
|
|
96
|
-
|
|
97
|
-
run_tests(testPath: "apis/myapi/tests/", safe: true)
|
|
98
|
-
```
|
|
53
|
+
## Why Not Just Ask Claude to Write pytest?
|
|
99
54
|
|
|
100
|
-
|
|
55
|
+
Claude Code can write pytest from scratch — but it takes 30-60 minutes per flow, has no safety guardrails, no coverage tracking, and no run history. Zond gives the agent structured tools to do it in 5 minutes with full visibility.
|
|
101
56
|
|
|
102
|
-
|
|
103
|
-
query_db(action: "diagnose_failure", runId: 42)
|
|
104
|
-
```
|
|
57
|
+
## Key Capabilities
|
|
105
58
|
|
|
106
|
-
|
|
59
|
+
| | |
|
|
60
|
+
|---|---|
|
|
61
|
+
| **Safe by Default** | `--safe` runs only GET requests. `--dry-run` previews without sending. The agent never touches production data without your explicit approval. |
|
|
62
|
+
| **Spec-Grounded** | Tests are derived from your OpenAPI schema, not invented from scratch. The spec is the source of truth. |
|
|
63
|
+
| **Full Visibility** | Every run is stored in SQLite. Compare runs, track regressions, see exactly what the server returned. |
|
|
64
|
+
| **Coverage Tracking** | See which endpoints are tested, which aren't, and what broke since last run. |
|
|
65
|
+
| **CI-Ready** | One command generates GitHub Actions or GitLab CI workflow. Tests in YAML, in git, with code review. |
|
|
107
66
|
|
|
108
|
-
##
|
|
67
|
+
## Try It
|
|
109
68
|
|
|
110
69
|
```
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
zond serve Web dashboard with health strip + endpoints/suites/runs tabs (--port 8080)
|
|
116
|
-
zond mcp Start MCP server
|
|
117
|
-
zond chat AI chat agent (--provider ollama|openai|anthropic)
|
|
118
|
-
zond doctor Diagnostics
|
|
70
|
+
"Cover openapi.json with tests"
|
|
71
|
+
"Run only smoke tests against staging"
|
|
72
|
+
"What broke since last run?"
|
|
73
|
+
"Set up CI for API tests"
|
|
119
74
|
```
|
|
120
75
|
|
|
121
76
|
## Documentation
|
|
122
77
|
|
|
123
|
-
- [docs/quickstart.md](docs/quickstart.md) — step-by-step quickstart guide (RU)
|
|
124
78
|
- [ZOND.md](ZOND.md) — full CLI and MCP tools reference
|
|
125
79
|
- [docs/mcp-guide.md](docs/mcp-guide.md) — MCP agent workflow guide
|
|
80
|
+
- [docs/quickstart.md](docs/quickstart.md) — step-by-step quickstart (RU)
|
|
126
81
|
- [docs/ci.md](docs/ci.md) — CI/CD integration
|
|
127
82
|
|
|
128
83
|
## License
|
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@ function escapeRegex(s: string): string {
|
|
|
24
24
|
function getExpectedStatus(ep: EndpointInfo): number {
|
|
25
25
|
const success = ep.responses.find(r => r.statusCode >= 200 && r.statusCode < 300);
|
|
26
26
|
if (success) return success.statusCode;
|
|
27
|
-
if (ep.responses.length > 0) return ep.responses[0]
|
|
27
|
+
if (ep.responses.length > 0) return ep.responses[0]!.statusCode;
|
|
28
28
|
return 200;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -182,10 +182,10 @@ export function detectCrudGroups(endpoints: EndpointInfo[]): CrudGroup[] {
|
|
|
182
182
|
|
|
183
183
|
if (itemEndpoints.length === 0) continue;
|
|
184
184
|
|
|
185
|
-
const itemPath = itemEndpoints[0]
|
|
185
|
+
const itemPath = itemEndpoints[0]!.path;
|
|
186
186
|
const idMatch = itemPath.match(/\{([^}]+)\}$/);
|
|
187
187
|
if (!idMatch) continue;
|
|
188
|
-
const idParam = idMatch[1]
|
|
188
|
+
const idParam = idMatch[1]!;
|
|
189
189
|
|
|
190
190
|
const read = itemEndpoints.find(ep => ep.method.toUpperCase() === "GET");
|
|
191
191
|
if (!read) continue; // Minimum: POST + GET/{id}
|
|
@@ -316,7 +316,7 @@ export function findUnresolvedVars(suite: RawSuite, envKeys?: Set<string>): stri
|
|
|
316
316
|
const scan = (obj: unknown) => {
|
|
317
317
|
if (typeof obj === "string") {
|
|
318
318
|
for (const m of obj.matchAll(/\{\{([^$}][^}]*)\}\}/g)) {
|
|
319
|
-
if (!KNOWN.has(m[1]) && !captured.has(m[1])) vars.add(m[1]);
|
|
319
|
+
if (!KNOWN.has(m[1]!) && !captured.has(m[1]!)) vars.add(m[1]!);
|
|
320
320
|
}
|
|
321
321
|
} else if (obj && typeof obj === "object") {
|
|
322
322
|
for (const v of Object.values(obj)) scan(v);
|
|
@@ -101,7 +101,7 @@ export function registerGenerateAndSaveTool(server: McpServer) {
|
|
|
101
101
|
(effectiveMode === "guide"
|
|
102
102
|
? `Pass includeFormat: false for subsequent chunks to save tokens. `
|
|
103
103
|
: "") +
|
|
104
|
-
`Example: generate_and_save(specPath: '${specPath}', tag: '${plan.chunks[0]
|
|
104
|
+
`Example: generate_and_save(specPath: '${specPath}', tag: '${plan.chunks[0]!.tag}'` +
|
|
105
105
|
(effectiveMode === "guide" ? `, mode: 'guide'` : "") + `)`,
|
|
106
106
|
};
|
|
107
107
|
if (coverageInfo) {
|