Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ guide/*.png
guide/probe.*
guide/tour-v2-raw.mp4
guide/tour-v2.json
guide/take*.mp4
guide/tour-v3-raw.mp4
guide/*.log
guide/tour-v3.json
guide/chapters-take*.json
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**kane-qe** is a [Claude Code](https://claude.com/claude-code) plugin (a mod) that watches [kane-cli](https://github.com/LambdaTest/kane-cli) ([KaneAI](https://www.lambdatest.com/kane-ai)) and shows what it is doing, without being asked.

Claude runs kane-cli; the mod reads what kane-cli leaves on disk and draws it: a band of three rows above the prompt with the kane mascot, and a pane for runs and assurance. When Claude changes code and nothing has tested it, the band says so and offers a test.
Claude runs kane-cli; the mod reads what kane-cli leaves on disk and draws it: a band of three rows above the prompt with the kane mascot, and a pane for runs, assurance and history. When Claude changes code and nothing has tested it, the band says so and offers a test.

![The band while a test runs](guide/v2/band-running.png)

Expand Down Expand Up @@ -50,21 +50,24 @@ The same block works in `~/.claude/settings.json` (every project on one machine)
Nothing to start. Open Claude Code in a project and the band is there.

1. **Ask Claude to test something**: "run `kane-cli run "Search for iPod and assert 4 products are listed" --url https://ecommerce-playground.lambdatest.io --agent --headless`", or "run the login test with kane-cli". Within two seconds the band shows the run, its time and the step it is on. A run started in a terminal in the same folder shows up the same way.
2. **Open the pane** with `/kane` or `[ Open ]`. Press a run for its steps; the current or failing step opens to what the agent thinks, does and checks.
3. **When a test fails**, the band names it and the step; the run's detail gives kane's own verdict (why, what kind, how sure, where) and *Open evidence*.
4. **Several runs or a suite**: one coloured cell per run or test, with counts; a failure takes row 2 while the rest keep going.
5. **After Claude changes code**, the band warns *⚠ 1 file changed, untested* with *Test this change*: saved tests that cover the change (with their last result), or an objective Claude drafts from the diff. `/kane auto` makes Claude test before it finishes; `/kane off` turns it off.
6. **Assurance**: row 3 is requirement coverage from `kane-cli cover gaps --json`; the Assurance tab breaks it down per use case, or offers to set it up.
2. **Read the card**: each test Claude runs leaves a card in the conversation with its result, and *View evidence* opens the evidence in the browser.
3. **Open the pane** with `/kane` or `[ Open ]`. Press a run for its steps; the current or failing step opens to what the agent thinks, does and checks.
4. **When a test fails**, the band names it and the step; the run's detail gives kane's own verdict (why, what kind, how sure, where) and *Open evidence*.
5. **Several runs or a suite**: one coloured cell per run or test, with counts; a failure takes row 2 while the rest keep going. A suite on the remote grid (`--remote`) shows how many tests are on the grid and since when; the pane gives the job and its link, and the tests are counted when the job ends.
6. **After Claude changes code**, the band warns *⚠ 1 file changed, untested* with *Test this change*: saved tests that cover the change (with their last result), or an objective Claude drafts from the diff. `/kane auto` makes Claude test before it finishes; `/kane off` turns it off.
7. **Assurance**: row 3 is requirement coverage from `kane-cli cover gaps --json`; the Assurance tab breaks it down per use case, or offers to set it up. Press a use case to see what it still owes and kane-cli's next command for each; *Close these gaps with Claude* hands it over.
8. **History**: the History tab lists the last 30 finished runs in this project, with where each failed.

| Command | |
|---|---|
| `/kane` | Open the pane |
| `/kane assurance` | Open the Assurance tab |
| `/kane history` | Open the History tab |
| `/kane auto` · `/kane ask` · `/kane off` | What happens after Claude changes code, for this session |

`/config` → kane-qe: **After Claude changes code** (`offer` by default, `auto`, `off`) and **kane-cli command** (default `kane-cli`, used only for the read-only `cover gaps`). Colours follow Claude Code's theme.

What it never does: it never starts a kane-cli run, never reads kane-cli's human output, and never shows what kane-cli did not report. The only commands it runs are `kane-cli cover gaps --json`, `kill -0`, `git check-ignore` and `git diff`.
What it never does: it never starts a kane-cli test, and never shows what kane-cli did not report. The commands it runs are `kane-cli cover gaps --json`, `kill -0`, `ps`, `git check-ignore` and `git diff`, and, only when you press *View evidence*, `kane-cli evidence serve <pack>` and `open`. It reads kane-cli's structured output only, with one exception: the viewer link that `evidence serve` prints.

## How to publish it on Claude

Expand All @@ -73,7 +76,7 @@ What it never does: it never starts a kane-cli run, never reads kane-cli's human
```
claude plugin validate kane-qe --strict # the plugin: manifest, hooks, state contract
claude plugin validate . --strict # the marketplace manifest
claude plugin test kane-qe # 81 tests
claude plugin test kane-qe # 127 tests
```

CI (`.github/workflows/ci.yml`) runs the same on every push to `main` and on pull requests.
Expand Down Expand Up @@ -111,10 +114,10 @@ References: [install plugins](https://code.claude.com/docs/en/plugins/install),
| `kane-qe/hooks/sources.ts` | The live-run pointer and byte offsets into event files |
| `kane-qe/hooks/register.tsx` | Polling, hooks (edits, end of turn, `/kane`, theme) and the drawing |
| `kane-qe/hooks/mascot.ts` | The mascot: a cell grid in terminals, an image elsewhere |
| `kane-qe/tests/` | Adapter table, band states at 60/80/120 columns, recorded kane-cli streams replayed, band and pane on terminal and desktop, change tracking, stale pointers, assurance, theme |
| `kane-qe/tests/` | Adapter table, band states at 60/80/120 columns, recorded kane-cli streams replayed, band and pane on terminal and desktop, change tracking, stale pointers, assurance and use-case detail, remote suites, history, the card in the chat, theme |
| `.claude-plugin/marketplace.json` | The `lambdatest` marketplace: this repository installs with `/plugin marketplace add` |
| `docs/` | The Field Guide and the explainer as standalone HTML, with the walkthrough video and screenshots (`guide/build_docs.sh` rebuilds them) |
| `guide/` | The page sources, screenshots, design coverage, and the script that records the walkthrough (`KANE_DEMO_DIR=<project> guide/run_tour_v2.sh`) |
| `guide/` | The page sources, screenshots, design coverage, and the scripts that record a walkthrough with real runs (`KANE_DEMO_DIR=<project> guide/run_tour_v2.sh`; `run_tour_v3.sh` for a demo shop project, covering the chat card, auto mode, use-case detail and History) and cut a short captioned promo from one (`python3 guide/make_promo.py guide/promo.json`) |

Edit `kane-qe/` and a session that loads it with `--plugin-dir` or `CLAUDE_CODE_PLUGIN_DIRS` reloads it on save. After recording a new kane-cli stream into `kane-qe/tests/fixtures/`, run `node kane-qe/tests/fixtures/build.mjs`.

Expand Down
5 changes: 3 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ <h2 id="video-h">v2 in a real session</h2>
<h2 id="where-h">What it is</h2>
<div class="surfaces">
<div><span class="where">above the prompt</span><h3>The band</h3><p>Three rows, always there: what kane-cli is doing, the step or the failure, and assurance coverage. The mascot's eyes move while a test runs.</p></div>
<div><span class="where">/kane · [ Open ]</span><h3>The pane</h3><p>Runs: a card per run or a row per suite test; press one for its steps. Assurance: coverage bars and a card per use case.</p></div>
<div><span class="where">/kane · [ Open ]</span><h3>The pane</h3><p>Runs: a card per run or a row per suite test; press one for its steps. Assurance: coverage bars and a card per use case; press one for what it still owes. History: the last 30 finished runs in this project.</p></div>
<div><span class="where">nothing to start</span><h3>It watches</h3><p>Any kane-cli run in this project shows up by itself within two seconds: started by Claude, a terminal or a script.</p></div>
<div><span class="where">after an edit</span><h3>Test what changed</h3><p>When Claude changes code and nothing has tested it, the band says so and offers the saved test that covers it, or a drafted one.</p></div>
<div><span class="where">kane's own verdict</span><h3>Why it failed</h3><p>Why, what kind, how sure, and the step it failed on, straight from kane-cli's investigation. Never guessed.</p></div>
Expand Down Expand Up @@ -310,6 +310,7 @@ <h2 id="cmd-h">Commands</h2>
<tbody>
<tr><td><code>/kane</code></td><td>Open the pane</td></tr>
<tr><td><code>/kane assurance</code></td><td>Open the Assurance tab</td></tr>
<tr><td><code>/kane history</code></td><td>Open the History tab</td></tr>
<tr><td><code>/kane auto</code></td><td>Claude tests a change before it finishes (this session)</td></tr>
<tr><td><code>/kane ask</code></td><td>The band offers a test (this session)</td></tr>
<tr><td><code>/kane off</code></td><td>Nothing after a change (this session)</td></tr>
Expand All @@ -333,7 +334,7 @@ <h2>Settings</h2>
<section aria-labelledby="design-h">
<div class="eyebrow">Design coverage</div>
<h2 id="design-h">Built to the design, and checked against it</h2>
<p>v2 was built from the kane-cli mod design: 17 features, 13 screens and a build spec. Every feature and screen was compared in a real terminal with the design's screenshots, and 81 tests cover the rest. The full list, with how each item was checked, is in <a href="https://github.com/LambdaTest/kane-claude-plugin/blob/main/guide/v2/design-coverage.md">design-coverage.md</a>.</p>
<p>v2 was built from the kane-cli mod design: 17 features, 13 screens and a build spec. Every feature and screen was compared in a real terminal with the design's screenshots, and 127 tests cover the rest. The full list, with how each item was checked, is in <a href="https://github.com/LambdaTest/kane-claude-plugin/blob/main/guide/v2/design-coverage.md">design-coverage.md</a>.</p>
<div class="two">
<div class="callout"><h3>Two deliberate differences</h3><p>The design lists a test file's coming steps; kane-cli reports no step total, and the spec says never to show one. The design's cards say “Chrome 154”; kane-cli reports no browser name for desktop runs.</p></div>
<div class="callout warn"><h3>Not checked yet</h3><p>The desktop app: the band and pane are tested on its surface, with the mascot as an image, but were not opened in the app itself.</p></div>
Expand Down
38 changes: 38 additions & 0 deletions guide/cut_tour_v3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Cuts tour-v3-raw.mp4 into kane-qe-v3-tour.mp4: stops at the end of the tour, plays the waiting
stretches the driver marked 6x faster, and writes chapters-v3.json with the chapter times moved to match."""
import json
import subprocess

FAST = 6.0
tour = json.load(open('tour-v3.json'))
end = tour['chapters'][-1]['t'] + 4
waits = sorted([a, b] for a, b in tour['waits'] if b - a > 2 and b <= end)

# Segments of the raw video: (start, end, speed).
segs, t = [], 0.0
for a, b in waits:
if a > t:
segs.append((t, a, 1.0))
segs.append((a, b, FAST))
t = b
segs.append((t, end, 1.0))


def moved(x: float) -> float:
out = 0.0
for a, b, k in segs:
if x <= a:
break
out += (min(x, b) - a) / k
return round(out, 1)


parts = []
for i, (a, b, k) in enumerate(segs):
parts.append(f'[0:v]trim=start={a}:end={b},setpts=(PTS-STARTPTS)/{k}[v{i}]')
filt = ';'.join(parts) + ';' + ''.join(f'[v{i}]' for i in range(len(segs))) + f'concat=n={len(segs)}:v=1:a=0[out]'
subprocess.run(['ffmpeg', '-loglevel', 'error', '-y', '-i', 'tour-v3-raw.mp4', '-filter_complex', filt, '-map', '[out]',
'-c:v', 'libx264', '-crf', '23', '-preset', 'slow', '-pix_fmt', 'yuv420p', '-movflags', '+faststart', 'kane-qe-v3-tour.mp4'], check=True)
chapters = [{**c, 't': moved(c['t'])} for c in tour['chapters']]
json.dump(chapters, open('chapters-v3.json', 'w'), indent=2)
print('cut', len(segs), 'segments; chapters at', [c['t'] for c in chapters])
5 changes: 3 additions & 2 deletions guide/kane-qe-guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ <h2 id="video-h">v2 in a real session</h2>
<h2 id="where-h">What it is</h2>
<div class="surfaces">
<div><span class="where">above the prompt</span><h3>The band</h3><p>Three rows, always there: what kane-cli is doing, the step or the failure, and assurance coverage. The mascot's eyes move while a test runs.</p></div>
<div><span class="where">/kane · [ Open ]</span><h3>The pane</h3><p>Runs: a card per run or a row per suite test; press one for its steps. Assurance: coverage bars and a card per use case.</p></div>
<div><span class="where">/kane · [ Open ]</span><h3>The pane</h3><p>Runs: a card per run or a row per suite test; press one for its steps. Assurance: coverage bars and a card per use case; press one for what it still owes. History: the last 30 finished runs in this project.</p></div>
<div><span class="where">nothing to start</span><h3>It watches</h3><p>Any kane-cli run in this project shows up by itself within two seconds: started by Claude, a terminal or a script.</p></div>
<div><span class="where">after an edit</span><h3>Test what changed</h3><p>When Claude changes code and nothing has tested it, the band says so and offers the saved test that covers it, or a drafted one.</p></div>
<div><span class="where">kane's own verdict</span><h3>Why it failed</h3><p>Why, what kind, how sure, and the step it failed on, straight from kane-cli's investigation. Never guessed.</p></div>
Expand Down Expand Up @@ -306,6 +306,7 @@ <h2 id="cmd-h">Commands</h2>
<tbody>
<tr><td><code>/kane</code></td><td>Open the pane</td></tr>
<tr><td><code>/kane assurance</code></td><td>Open the Assurance tab</td></tr>
<tr><td><code>/kane history</code></td><td>Open the History tab</td></tr>
<tr><td><code>/kane auto</code></td><td>Claude tests a change before it finishes (this session)</td></tr>
<tr><td><code>/kane ask</code></td><td>The band offers a test (this session)</td></tr>
<tr><td><code>/kane off</code></td><td>Nothing after a change (this session)</td></tr>
Expand All @@ -329,7 +330,7 @@ <h2>Settings</h2>
<section aria-labelledby="design-h">
<div class="eyebrow">Design coverage</div>
<h2 id="design-h">Built to the design, and checked against it</h2>
<p>v2 was built from the kane-cli mod design: 17 features, 13 screens and a build spec. Every feature and screen was compared in a real terminal with the design's screenshots, and 81 tests cover the rest. The full list, with how each item was checked, is in <a href="https://github.com/LambdaTest/kane-claude-plugin/blob/main/guide/v2/design-coverage.md">design-coverage.md</a>.</p>
<p>v2 was built from the kane-cli mod design: 17 features, 13 screens and a build spec. Every feature and screen was compared in a real terminal with the design's screenshots, and 127 tests cover the rest. The full list, with how each item was checked, is in <a href="https://github.com/LambdaTest/kane-claude-plugin/blob/main/guide/v2/design-coverage.md">design-coverage.md</a>.</p>
<div class="two">
<div class="callout"><h3>Two deliberate differences</h3><p>The design lists a test file's coming steps; kane-cli reports no step total, and the spec says never to show one. The design's cards say “Chrome 154”; kane-cli reports no browser name for desktop runs.</p></div>
<div class="callout warn"><h3>Not checked yet</h3><p>The desktop app: the band and pane are tested on its surface, with the mascot as an image, but were not opened in the app itself.</p></div>
Expand Down
Loading
Loading