@isummation/kasauti-cli 0.2.0 → 0.3.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/README.md +5 -2
- package/kasauti.mjs +35 -0
- package/package.json +7 -3
- package/plugin/.claude-plugin/marketplace.json +15 -0
- package/plugin/kasauti/.claude-plugin/plugin.json +8 -0
- package/plugin/kasauti/.mcp.json +9 -0
- package/plugin/kasauti/AGENTS.md +19 -0
- package/plugin/kasauti/skills/explore-screen/SKILL.md +53 -0
- package/plugin/kasauti/skills/fix-defects/SKILL.md +37 -0
- package/plugin/kasauti/skills/run-tests/SKILL.md +41 -0
package/README.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# @isummation/kasauti-cli
|
|
2
2
|
|
|
3
|
-
Command line for
|
|
3
|
+
Command line for Kasauti test management: explore, author, run, and report and fix defects. Used by people, CI and AI agents. Output is Markdown; add `--json` for scripts. Node 20+, no dependencies. Also carries the Kasauti plugin for Claude Code.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install -g @isummation/kasauti-cli
|
|
6
|
+
npm install -g @isummation/kasauti-cli
|
|
7
7
|
kasauti login https://<kasauti-api> --token <token>
|
|
8
8
|
kasauti map SHOP
|
|
9
|
+
kasauti plugin install # Claude Code plugin: Kasauti MCP tools + explore / run / fix playbooks
|
|
9
10
|
kasauti --help
|
|
10
11
|
```
|
|
11
12
|
|
|
13
|
+
After `npm update -g @isummation/kasauti-cli`, run `kasauti plugin update`.
|
|
14
|
+
|
|
12
15
|
`KASAUTI_URL` and `KASAUTI_TOKEN` override the saved login (that is how CI uses it). Full guide: `docs/using-kasauti-in-your-project.md` in the Kasauti repository.
|
package/kasauti.mjs
CHANGED
|
@@ -5,6 +5,8 @@ import { parseArgs } from 'node:util';
|
|
|
5
5
|
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
6
6
|
import { homedir } from 'node:os';
|
|
7
7
|
import { basename, join, extname } from 'node:path';
|
|
8
|
+
import { spawnSync } from 'node:child_process';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
8
10
|
|
|
9
11
|
const CONFIG = process.env.KASAUTI_CONFIG ?? join(homedir(), '.kasauti.json');
|
|
10
12
|
const HELP = `kasauti <command> [args] [--json]
|
|
@@ -13,6 +15,8 @@ Setup
|
|
|
13
15
|
login <url> --token T save URL + a personal token (Settings → API tokens) to ~/.kasauti.json
|
|
14
16
|
token <name> [--agent NAME] create a personal (or agent) API token
|
|
15
17
|
whoami | projects | mcp-config
|
|
18
|
+
plugin install|update [--scope user|local] add the bundled Claude Code plugin (skills + MCP) to Claude Code
|
|
19
|
+
plugin path where the bundled plugin is, for manual setup
|
|
16
20
|
|
|
17
21
|
Explore
|
|
18
22
|
map <PROJECT> area tree with coverage and open defects
|
|
@@ -58,6 +62,7 @@ const { values: o, positionals: args } = parseArgs({
|
|
|
58
62
|
env: { type: 'string' }, message: { type: 'string', short: 'm' }, attach: { type: 'string', multiple: true }, duration: { type: 'string' },
|
|
59
63
|
case: { type: 'string' }, run: { type: 'string' }, url: { type: 'string' }, actual: { type: 'string' }, expected: { type: 'string' },
|
|
60
64
|
steps: { type: 'string' }, severity: { type: 'string' }, commit: { type: 'string' }, pr: { type: 'string' }, mine: { type: 'boolean' }, force: { type: 'boolean' },
|
|
65
|
+
scope: { type: 'string' },
|
|
61
66
|
},
|
|
62
67
|
});
|
|
63
68
|
|
|
@@ -133,6 +138,36 @@ switch (cmd) {
|
|
|
133
138
|
print(`claude mcp add --transport http kasauti ${url}/mcp --header "Authorization: Bearer <agent token>"\n\nCreate an agent token with: kasauti token claude-code --agent claude-code`);
|
|
134
139
|
break;
|
|
135
140
|
}
|
|
141
|
+
case 'plugin': {
|
|
142
|
+
// The npm package ships the plugin as a one-plugin marketplace (see bundle-plugin.mjs), so installing it
|
|
143
|
+
// needs no access to the Kasauti git repository.
|
|
144
|
+
const dir = fileURLToPath(new URL('./plugin', import.meta.url));
|
|
145
|
+
if (!existsSync(join(dir, '.claude-plugin', 'marketplace.json'))) die('No bundled plugin here (running from a git checkout?). Install the CLI from npm: npm install -g @isummation/kasauti-cli');
|
|
146
|
+
if (sub === 'path') { print(dir); break; }
|
|
147
|
+
if (sub !== 'install' && sub !== 'update') die('Usage: kasauti plugin install|update|path [--scope user|local]');
|
|
148
|
+
// Not 'project': that would commit this machine's npm path into the repo's .claude/settings.json.
|
|
149
|
+
const scope = o.scope ?? 'user';
|
|
150
|
+
if (!['user', 'local'].includes(scope)) die('--scope must be user (all your projects) or local (this project, not committed)');
|
|
151
|
+
const steps = sub === 'install'
|
|
152
|
+
? [['plugin', 'marketplace', 'add', dir, '--scope', scope], ['plugin', 'install', 'kasauti@kasauti', '--scope', scope]]
|
|
153
|
+
: [['plugin', 'marketplace', 'update', 'kasauti'], ['plugin', 'update', 'kasauti@kasauti']];
|
|
154
|
+
const quote = (x) => (/\s/.test(x) ? `"${x}"` : x);
|
|
155
|
+
const show = (a) => `claude ${a.map(quote).join(' ')}`;
|
|
156
|
+
// claude is a .cmd shim on Windows, which only runs through a shell (so paths with spaces get quoted)
|
|
157
|
+
const win = process.platform === 'win32';
|
|
158
|
+
const claude = (a) => spawnSync('claude', win ? a.map(quote) : a, { stdio: 'inherit', shell: win });
|
|
159
|
+
const probe = spawnSync('claude', ['--version'], { stdio: 'ignore', shell: win });
|
|
160
|
+
if (probe.error || probe.status) die(`Claude Code isn't on the PATH. Install it, or run these yourself:\n${steps.map(show).join('\n')}`);
|
|
161
|
+
for (const [i, a] of steps.entries()) {
|
|
162
|
+
console.log(`$ ${show(a)}`);
|
|
163
|
+
let r = claude(a);
|
|
164
|
+
// already added (e.g. a reinstall): refresh it from the folder instead
|
|
165
|
+
if (r.status && i === 0 && sub === 'install') r = claude(['plugin', 'marketplace', 'update', 'kasauti']);
|
|
166
|
+
if (r.status) die(`Failed: ${show(a)}`);
|
|
167
|
+
}
|
|
168
|
+
print(`\nDone. Restart Claude Code, then check /mcp lists kasauti. It reads KASAUTI_URL and KASAUTI_TOKEN (an agent token) from your environment.\nAfter upgrading the CLI (npm update -g @isummation/kasauti-cli), run: kasauti plugin update`);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
136
171
|
case 'map': print(await api('GET', `/projects/${need(sub, '<PROJECT>')}/map`)); break;
|
|
137
172
|
case 'get': print(await api('GET', `/k/${need(sub, '<KEY>')}`)); break;
|
|
138
173
|
case 'activity': print(await api('GET', `/projects/${need(sub, '<PROJECT>')}/activity`)); break;
|
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isummation/kasauti-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Kasauti test management CLI for humans, CI and AI agents",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Kasauti test management CLI for humans, CI and AI agents, with the Claude Code plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"kasauti": "./kasauti.mjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"kasauti.mjs",
|
|
11
|
+
"plugin",
|
|
11
12
|
"README.md"
|
|
12
13
|
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"prepack": "node bundle-plugin.mjs"
|
|
16
|
+
},
|
|
13
17
|
"engines": {
|
|
14
18
|
"node": ">=20"
|
|
15
19
|
},
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
"directory": "packages/cli"
|
|
20
24
|
},
|
|
21
25
|
"publishConfig": {
|
|
22
|
-
"access": "
|
|
26
|
+
"access": "public",
|
|
23
27
|
"registry": "https://registry.npmjs.org/"
|
|
24
28
|
}
|
|
25
29
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kasauti",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "iSummation"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "kasauti",
|
|
9
|
+
"source": "./kasauti",
|
|
10
|
+
"description": "Kasauti test management for AI agents",
|
|
11
|
+
"version": "0.3.0"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"description": "Kasauti test management plugin for Claude Code"
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Kasauti (test management) — instructions for AI agents
|
|
2
|
+
|
|
3
|
+
Copy this section into a product repo's `AGENTS.md` / `CLAUDE.md` / Cursor rules so any agent harness can use Kasauti.
|
|
4
|
+
|
|
5
|
+
Kasauti tracks this project's test cases, runs and defects. Use the `kasauti` MCP server (`$KASAUTI_URL/mcp`, bearer `$KASAUTI_TOKEN`)
|
|
6
|
+
or the `kasauti` CLI (`npm install -g @isummation/kasauti-cli`, then `kasauti --help`; output is Markdown, add `--json` for JSON). The project code is **DEMO** <!-- change me -->.
|
|
7
|
+
|
|
8
|
+
Keys: `DEMO-12` case · `DEMO-A3` area (screen/endpoint) · `DEMO-SC4` scenario · `DEMO-R5` run · `DEMO-D7` defect.
|
|
9
|
+
|
|
10
|
+
- **Start** with `kasauti map DEMO` (MCP `project_map`), then `kasauti get <KEY>`.
|
|
11
|
+
- **Fixing bugs:** `kasauti defects DEMO` → `kasauti defect claim DEMO-D7` → `kasauti get DEMO-D7` (repro steps, evidence, linked case)
|
|
12
|
+
→ reproduce → fix + test → commit mentioning the key → `kasauti defect resolve DEMO-D7 -m "<root cause and change>" --commit <sha>`.
|
|
13
|
+
Reopened defects first; read their comments. Can't reproduce? Comment and `kasauti defect release DEMO-D7`.
|
|
14
|
+
- **Testing a screen:** create or update the area (`kasauti area DEMO --title … --route /path`), scenarios and cases (use stable `ref`s),
|
|
15
|
+
`kasauti run start DEMO --title … --area DEMO-A3`, then `kasauti run next DEMO-R5` / `kasauti result DEMO-R5 DEMO-12 failed -m "…" --attach shot.png`,
|
|
16
|
+
and `kasauti defect report DEMO --title … --case DEMO-12 --run DEMO-R5` for failures.
|
|
17
|
+
- Long text fields are **Markdown**: numbered repro steps, `code` for values, fenced blocks for logs and stack traces. Raw HTML is not rendered. Screenshots testers paste appear as ``: download them with your token to see what they saw.
|
|
18
|
+
- **Never** mark results you didn't observe. You can't verify fixes or approve draft cases; humans do that.
|
|
19
|
+
- Your token carries its owner's role. A developer's token can claim, resolve and comment on defects; exploring and running tests needs a tester's token.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explore-screen
|
|
3
|
+
description: Explore a web app screen in a browser, record its scenarios and test cases in Kasauti, execute them, and report results and defects with evidence. Use when asked to "explore", "test", "find scenarios for" or "write test cases for" a page/screen/URL, or to run exploratory testing on a frontend project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Explore a screen into Kasauti
|
|
7
|
+
|
|
8
|
+
You need two tools: a **browser** (Claude in Chrome, Playwright MCP, or `playwright-cli`) and **Kasauti** (the `kasauti` MCP tools, or the `kasauti` CLI with the same verbs). Keys look like `DEMO-A3` (area), `DEMO-SC4` (scenario), `DEMO-12` (case), `DEMO-R5` (run), `DEMO-D7` (defect).
|
|
9
|
+
|
|
10
|
+
## 1. Orient
|
|
11
|
+
1. `project_map` for the project. It returns the base URL and the areas that already exist, with their coverage. Don't re-create what's there.
|
|
12
|
+
2. If the target screen is already an area, `get` it. Read the **Agent notes** (login, test data, selectors) and the existing scenarios and cases.
|
|
13
|
+
|
|
14
|
+
## 2. Map the screen
|
|
15
|
+
3. Open the screen in the browser. If you're redirected to login, follow the area notes or ask the user.
|
|
16
|
+
4. `upsert_area` with:
|
|
17
|
+
- `title`: a human name.
|
|
18
|
+
- `route`: the URL pattern with params generalized, e.g. `/orders/:id`.
|
|
19
|
+
- `kind: screen`.
|
|
20
|
+
- `parent`: set it for nested screens.
|
|
21
|
+
- `notes`: anything the next agent needs (how to get there, required data, flaky bits).
|
|
22
|
+
5. Identify the **user goals** the screen supports, not individual widgets. Typical set: the happy path, validation and errors, empty and loading states, permissions, and navigation out. `upsert_scenario` once per goal, with a short Given/When/Then `narrative`.
|
|
23
|
+
|
|
24
|
+
## 3. Write concrete cases
|
|
25
|
+
6. `upsert_cases` in one batch per scenario. Each case should have:
|
|
26
|
+
- a `ref` that's stable across sessions, e.g. `orders-detail/cancel-confirm`;
|
|
27
|
+
- a specific `title` that states the expected behaviour;
|
|
28
|
+
- `steps` with `action`, optional `data`, and an `expected` on every step that checks something;
|
|
29
|
+
- `behavior` (positive/negative), `severity` and `layer: e2e`.
|
|
30
|
+
|
|
31
|
+
Keep cases independent and repeatable. Put setup in `preconditions`.
|
|
32
|
+
7. Your cases land as **drafts**. That's expected: a human approves them. Don't try to set `status: actual`.
|
|
33
|
+
|
|
34
|
+
## 4. Execute
|
|
35
|
+
8. `start_run` with `area` set to this screen (or `scenario`) and a descriptive title, e.g. "Exploratory: Orders detail (Chrome)".
|
|
36
|
+
9. Loop: `next_case` → do the steps in the browser → `report_result` with:
|
|
37
|
+
- `status`: passed / failed / blocked (blocked when you can't reach the precondition);
|
|
38
|
+
- `steps`: the 1-based step results, at least for the failing step;
|
|
39
|
+
- `comment`: actual vs expected, the exact error text, the URL;
|
|
40
|
+
- `attachments`: for failures, a screenshot (base64 PNG) plus console errors and failing network calls as text files.
|
|
41
|
+
10. For each failure, `report_defect` with:
|
|
42
|
+
- `case` and `run`, so the failing result and its evidence are linked;
|
|
43
|
+
- a symptom-style `title`;
|
|
44
|
+
- `actualResult`, `expected`, numbered `reproSteps`, `url`, and `environment` (browser and build).
|
|
45
|
+
|
|
46
|
+
Re-reporting the same problem is safe: it adds an occurrence, and it reopens the defect if it had been marked fixed.
|
|
47
|
+
11. Bugs you notice outside any case (console errors, broken links): file them as defects with `area` set.
|
|
48
|
+
12. `complete_run`, then summarise for the user: the area key, the scenarios and cases created, pass/fail counts, the defect keys, and anything you couldn't test.
|
|
49
|
+
|
|
50
|
+
## Rules
|
|
51
|
+
- Never guess results. If you didn't observe it, mark the case `blocked` and explain why.
|
|
52
|
+
- Don't create accounts, payments or other irreversible actions on shared environments unless the area notes say it's safe.
|
|
53
|
+
- Prefer updating existing areas, scenarios and cases (same `ref` or `key`) over creating near-duplicates.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fix-defects
|
|
3
|
+
description: Pick up open defects from Kasauti, reproduce them, fix the code in this repository, and mark them fixed for tester verification. Use when asked to "fix open bugs/defects/issues", "work the Kasauti queue", fix a specific defect key like DEMO-D7, or handle reopened defects.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fix Kasauti defects
|
|
7
|
+
|
|
8
|
+
Kasauti holds the bug; this repo holds the code. You move a defect from `open` to `in_progress` (claimed), then to `fixed`. A **human tester** moves it to `verified`, or reopens it. You can't verify.
|
|
9
|
+
|
|
10
|
+
## 1. Choose work
|
|
11
|
+
1. `list_defects` for the project (the default is unresolved). If the user named a key, use that one.
|
|
12
|
+
- Do reopened defects first (`reopened > 0`). Their comments say why the last fix wasn't enough.
|
|
13
|
+
- Then go by severity (blocker → critical → major).
|
|
14
|
+
2. `claim_defect` before you touch code. If it says someone else is working on it, pick another. Don't use `force` unless the user tells you to.
|
|
15
|
+
|
|
16
|
+
## 2. Understand
|
|
17
|
+
3. `get <defect key>` returns the full bundle: actual vs expected, repro steps, URL, environment, the linked case's steps, failing results with stack traces, evidence links (screenshots and logs, fetch them with the same token), and the comment thread.
|
|
18
|
+
4. Find the code behind the area/route: `get <area key>` gives the route or endpoint. Search the repo for it.
|
|
19
|
+
|
|
20
|
+
## 3. Reproduce, then fix
|
|
21
|
+
5. Reproduce first. Use a browser (Playwright MCP / `playwright-cli`) for UI bugs, or a request or failing test for APIs. If it doesn't reproduce, `comment` with what you tried and `release_defect` it. Don't mark it fixed.
|
|
22
|
+
6. Fix the root cause. Add or adjust an automated test that fails before the fix and passes after.
|
|
23
|
+
- If the project uses the Kasauti Playwright reporter, tag the test with the case key, e.g. `test('… @DEMO-12')`.
|
|
24
|
+
7. Run the relevant tests. Commit with the defect key in the message, e.g. `fix(profile): persist display name (DEMO-D7)`.
|
|
25
|
+
|
|
26
|
+
## 4. Hand back
|
|
27
|
+
8. `resolve_defect` with:
|
|
28
|
+
- `notes`: the root cause, what changed, and how to check it (one short paragraph a tester can follow);
|
|
29
|
+
- `commit`: the SHA; `prUrl` if you opened a PR.
|
|
30
|
+
|
|
31
|
+
This queues a retest of the linked case in the project's **Defect verification** run.
|
|
32
|
+
9. Tell the user which defects you moved to fixed and which you released, and why.
|
|
33
|
+
|
|
34
|
+
## Rules
|
|
35
|
+
- One defect, one focused change. Don't bundle unrelated fixes under one defect.
|
|
36
|
+
- If the "defect" is actually expected behaviour, `comment` your reasoning and leave the status for a human (they can mark it invalid).
|
|
37
|
+
- Never mark a defect fixed without running the code path.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: run-tests
|
|
3
|
+
description: Report automated test results (Playwright, or any framework, or API checks) into Kasauti, and design API test cases from endpoints. Use for backend/API projects, CI reporting, importing an OpenAPI spec, or "run the suite and record results in Kasauti".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Automated and API testing with Kasauti
|
|
7
|
+
|
|
8
|
+
## Playwright projects
|
|
9
|
+
Add the reporter once:
|
|
10
|
+
```ts
|
|
11
|
+
// playwright.config.ts
|
|
12
|
+
reporter: [['list'], ['@isummation/kasauti-playwright-reporter', { project: 'DEMO' }]],
|
|
13
|
+
```
|
|
14
|
+
Then run with `KASAUTI_URL` and `KASAUTI_TOKEN` set (in CI, use an agent token stored as a secret).
|
|
15
|
+
- Tests tagged with a case key (`test('login works @DEMO-12', …)`) report into that case.
|
|
16
|
+
- Untagged tests are matched by file/describe path + title. The first time they run, they're created as **draft automated cases**.
|
|
17
|
+
- Each run creates a run (`source: automation`) and completes it. Set `KASAUTI_RUN=DEMO-R5` to report into an existing run instead.
|
|
18
|
+
|
|
19
|
+
## Other frameworks
|
|
20
|
+
Post results directly, in batches of up to 1000:
|
|
21
|
+
```
|
|
22
|
+
POST /runs {"project":"DEMO","title":"CI #123","source":"automation"}
|
|
23
|
+
POST /k/DEMO-R5/results/bulk {"results":[{"case":"DEMO-12","status":"passed","durationMs":120},
|
|
24
|
+
{"title":"refund > partial","suite":"API/Refunds","status":"failed","stacktrace":"..."}]}
|
|
25
|
+
POST /k/DEMO-R5/complete
|
|
26
|
+
```
|
|
27
|
+
Statuses: passed, failed, blocked, skipped, invalid.
|
|
28
|
+
|
|
29
|
+
## Backend / API projects
|
|
30
|
+
1. Import the API surface once, and re-import when it changes (it's idempotent):
|
|
31
|
+
- `kasauti import openapi DEMO openapi.yaml`
|
|
32
|
+
|
|
33
|
+
This creates one **endpoint area** per operation (`route: "POST /orders"`), grouped under a module area per tag.
|
|
34
|
+
2. `project_map` to see the endpoints with no cases.
|
|
35
|
+
3. Per endpoint, `upsert_scenario` for the behaviours (create succeeds, validation, auth, not found, idempotency, pagination…). Then `upsert_cases` with `layer: api`. Steps are the request (`action: "POST /orders"`, `data`: the body) and `expected` is the status and key fields.
|
|
36
|
+
4. Execute with an agent run:
|
|
37
|
+
- `start_run` with `area` set to the module area;
|
|
38
|
+
- for each case, call the API (curl/fetch against the project base URL);
|
|
39
|
+
- `report_result` with the response status/body excerpt in `comment`;
|
|
40
|
+
- `report_defect` on failure (put the request/response in `actualResult`).
|
|
41
|
+
5. If you write automated tests for these cases, tag them with the case keys so CI results land on the same cases.
|