kaloko 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 +119 -0
- package/bin/kaloko.mjs +4 -0
- package/bin/qawalk.mjs +4 -0
- package/package.json +42 -0
- package/schemas/bundle.v1.json +19 -0
- package/schemas/config.v1.json +268 -0
- package/schemas/revision.v1.json +36 -0
- package/schemas/run.v1.json +549 -0
- package/schemas/scenario.v1.json +668 -0
- package/schemas/tokens.v1.json +102 -0
- package/skills/kaloko/SKILL.md +94 -0
- package/skills/kaloko/reference/acceptance.md +208 -0
- package/skills/kaloko/reference/apps.md +161 -0
- package/skills/kaloko/reference/collaboration.md +218 -0
- package/skills/kaloko/reference/design.md +143 -0
- package/skills/kaloko/reference/documentation.md +72 -0
- package/skills/kaloko/reference/environments.md +140 -0
- package/skills/kaloko/reference/evaluation.md +62 -0
- package/skills/kaloko/reference/execution.md +75 -0
- package/skills/kaloko/reference/mcp.md +69 -0
- package/skills/kaloko/reference/stacks.md +122 -0
- package/src/cli.mjs +1344 -0
- package/src/lib/access.mjs +169 -0
- package/src/lib/apps/capture.mjs +59 -0
- package/src/lib/apps/drivers.mjs +284 -0
- package/src/lib/apps/helper.swift +102 -0
- package/src/lib/apps/tree.mjs +222 -0
- package/src/lib/browser-daemon.mjs +41 -0
- package/src/lib/browser.mjs +161 -0
- package/src/lib/build.mjs +149 -0
- package/src/lib/calibrate.mjs +97 -0
- package/src/lib/capture.mjs +233 -0
- package/src/lib/compare.mjs +88 -0
- package/src/lib/config.mjs +117 -0
- package/src/lib/console.mjs +13 -0
- package/src/lib/coverage.mjs +75 -0
- package/src/lib/design-cli.mjs +440 -0
- package/src/lib/design-core.mjs +163 -0
- package/src/lib/design.mjs +164 -0
- package/src/lib/doctor.mjs +149 -0
- package/src/lib/draft.mjs +76 -0
- package/src/lib/drift.mjs +145 -0
- package/src/lib/evaluate.mjs +222 -0
- package/src/lib/git.mjs +70 -0
- package/src/lib/htmlview.mjs +130 -0
- package/src/lib/jev.mjs +95 -0
- package/src/lib/mail.mjs +182 -0
- package/src/lib/manifest-core.mjs +127 -0
- package/src/lib/pack-help.mjs +55 -0
- package/src/lib/packs.mjs +121 -0
- package/src/lib/pr.mjs +78 -0
- package/src/lib/probe.mjs +379 -0
- package/src/lib/recheck.mjs +70 -0
- package/src/lib/run.mjs +85 -0
- package/src/lib/scenario.mjs +98 -0
- package/src/lib/schema.mjs +25 -0
- package/src/lib/secrets.mjs +59 -0
- package/src/lib/service.mjs +52 -0
- package/src/lib/stack.mjs +130 -0
- package/src/lib/tokens.mjs +352 -0
- package/src/lib/util.mjs +97 -0
- package/templates/ACCEPTANCE.md +55 -0
- package/templates/cs/ACCEPTANCE.md +55 -0
- package/templates/kaloko.config.yml +76 -0
- package/templates/mail/letter-opener.mjs +47 -0
- package/templates/scenario.yml +119 -0
- package/templates/steps/consent.mjs +33 -0
- package/viewer/index.html +2772 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Execution
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
kaloko start --scenario docs/tasks/TASK-1/qa/scenario.yml --env local [--locales cs,en]
|
|
5
|
+
kaloko browser start # shared Chromium with CDP for the run's environment (its policy, own profile and port)
|
|
6
|
+
kaloko walk # runs steps with strategy playwright + script
|
|
7
|
+
kaloko open --step <id> --locale cs
|
|
8
|
+
kaloko capture --step <id> --locale cs # all viewports of the run
|
|
9
|
+
kaloko capture --step <id> --crop ".selector" --title "What this shows"
|
|
10
|
+
kaloko mail --step <id> --locale cs # e-mail step from the environment's mailbox
|
|
11
|
+
kaloko mail --step <id> --file message.eml # e-mail you obtained yourself (.eml, .html, .json, .txt)
|
|
12
|
+
kaloko auth save --env staging --account admin # a person signs in once (SSO, MFA); walk reuses it
|
|
13
|
+
kaloko session reset # new visitor: clear cookies and storage in the shared browser
|
|
14
|
+
kaloko status
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Commands act on the current run (`CURRENT` in the output directory). When
|
|
18
|
+
other agents or people may start runs in the same repository, pin yours:
|
|
19
|
+
`--run <id>` on every command or `KALOKO_RUN=<id>` in the environment.
|
|
20
|
+
|
|
21
|
+
`walk` resets the session before the first step of a run; agent-driven steps
|
|
22
|
+
call `kaloko session reset` themselves when the plan starts as a new visitor.
|
|
23
|
+
|
|
24
|
+
`start` prints a unique test e-mail address for the run; use it in forms so
|
|
25
|
+
`mail` can find the message.
|
|
26
|
+
|
|
27
|
+
## Choosing a strategy per step
|
|
28
|
+
|
|
29
|
+
- `playwright` — stable, repeatable steps. The script exports
|
|
30
|
+
`default async ({ page, url, locale, capture, crop, acceptDialogs, env, run, session, node })`
|
|
31
|
+
(`node` is `{ id, title, kind }` of the step being walked, so one script can serve several steps);
|
|
32
|
+
`walk` captures automatically after the script unless it called
|
|
33
|
+
`capture()`. With `sessions` in the scenario, `page` and `context` belong
|
|
34
|
+
to the node's person (`session.key`, `title`, `mailbox`, `account`, and
|
|
35
|
+
`credentials` for that account in the run's environment; see
|
|
36
|
+
[environments.md](environments.md#accounts-and-sign-in)).
|
|
37
|
+
- `agent` — steps that need judgement or change often. Follow
|
|
38
|
+
`execution.instructions`, then `kaloko capture --step <id>`.
|
|
39
|
+
- `manual` — a person does it; you capture afterwards.
|
|
40
|
+
|
|
41
|
+
Prefer turning an agent step into a playwright script once it has worked
|
|
42
|
+
twice the same way.
|
|
43
|
+
|
|
44
|
+
## Driving the shared browser with your capabilities
|
|
45
|
+
|
|
46
|
+
- Browser tool over MCP (e.g. Playwright MCP): connect to the CDP endpoint
|
|
47
|
+
printed by `kaloko browser start`, act, then capture.
|
|
48
|
+
- Computer use: run `kaloko browser start --headed` and operate the window.
|
|
49
|
+
- Shell only: write a short Playwright script (`chromium.connectOverCDP`) or
|
|
50
|
+
a scenario step script and use `walk`.
|
|
51
|
+
|
|
52
|
+
There is one shared browser per environment (`browser.port` + the
|
|
53
|
+
environment's position in the config): a production run never shares a tab
|
|
54
|
+
or a cookie jar with local work, and the CLI refuses a readonly run in a
|
|
55
|
+
browser without the readonly policy. `walk` works in its own tab; agents and
|
|
56
|
+
people keep theirs. Several agents on the same environment share cookies, so
|
|
57
|
+
run one scenario at a time per environment: `walk` takes a lock on the shared
|
|
58
|
+
browser and refuses a second run while one is walking. To walk several runs
|
|
59
|
+
in parallel, give each its own browser with `kaloko walk --ephemeral` (own
|
|
60
|
+
cookies and tabs; sign-in through saved account sessions still works).
|
|
61
|
+
Commands leave the shared browser running: they only disconnect from it.
|
|
62
|
+
|
|
63
|
+
Native dialogs (`confirm()` from Rails `data-confirm` / `data-turbo-confirm`,
|
|
64
|
+
`alert`, `prompt`) are unreliable on the shared browser when more than one
|
|
65
|
+
Playwright client is connected over CDP: a client without a handler can
|
|
66
|
+
dismiss the dialog before yours accepts it, and the action silently does not
|
|
67
|
+
happen. In step scripts call `await acceptDialogs()` before the click (it
|
|
68
|
+
replaces the functions in the page, also after navigations); in your own
|
|
69
|
+
scripts do the same with
|
|
70
|
+
`page.evaluate(() => { window.confirm = () => true })`.
|
|
71
|
+
|
|
72
|
+
The environment policy and gate apply to every context the CLI creates (the
|
|
73
|
+
shared browser, `walk` sessions, one-off captures): blocked paths and, when
|
|
74
|
+
readonly, non-GET requests outside `allowed_post_paths` fail and are listed as
|
|
75
|
+
blocked requests in the capture; the gate's credentials go to its origins only.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# MCP server
|
|
2
|
+
|
|
3
|
+
`https://kaloko.app/mcp` speaks MCP over Streamable HTTP (JSON-RPC 2.0,
|
|
4
|
+
POST only, one message per request). Authenticate with an organization API
|
|
5
|
+
token as `Authorization: Bearer qwk_…`; a read-only token is enough, every
|
|
6
|
+
tool reads. Nothing binary crosses MCP: summaries carry the URLs of
|
|
7
|
+
screenshots and files, which the same token can fetch over HTTPS.
|
|
8
|
+
|
|
9
|
+
## Configure
|
|
10
|
+
|
|
11
|
+
Claude Code:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
claude mcp add --transport http kaloko https://kaloko.app/mcp --header "Authorization: Bearer $KALOKO_TOKEN"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Codex / other clients: an HTTP MCP server with URL `https://kaloko.app/mcp`
|
|
18
|
+
and the same header. Keep the token in the environment, not in a committed
|
|
19
|
+
file.
|
|
20
|
+
|
|
21
|
+
## Tools
|
|
22
|
+
|
|
23
|
+
| Tool | Use it for |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `list_runs` | published runs, newest first; filters `scenario`, `project`, `verdict`, `author`, `environment`, `branch`, `limit` |
|
|
26
|
+
| `get_run_summary` | one run: statuses per step and locale, criteria that need attention with evidence, screenshot URLs, verdict, baseline, canvas URL, open feedback |
|
|
27
|
+
| `get_feedback` | run verdict with note, approved steps, unresolved rejections and comments, failed manual criteria (`run_id`, or `scenario` for its latest run) |
|
|
28
|
+
| `list_notifications` | the token owner's inbox (`unread_only`, `limit`) |
|
|
29
|
+
| `list_projects` | projects of the organization with counts; the slug is the `project` filter of `list_runs` and the value for `project:` in a scenario |
|
|
30
|
+
| `get_criteria_verdicts` | reviewer verdicts on manual or overridden criteria of a run |
|
|
31
|
+
| `get_step_assets` | documentation layer (Business): newest capture of every step of a scenario with stable image, HTML and metadata URLs (`scenario`, `step`, `locale`, `viewport`, `accepted`) |
|
|
32
|
+
| `list_step_changes` | documentation layer: steps whose capture or status changed since the previous accepted run or `since` (`scenario`, `since`, `accepted`); see [documentation.md](documentation.md) |
|
|
33
|
+
|
|
34
|
+
## Comment tools
|
|
35
|
+
|
|
36
|
+
| Tool | Use |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `list_comments` | open threads (or `state: all`) across the organization, filtered by `scenario` or `run_id`, with replies, pins, anchors and who wrote them |
|
|
39
|
+
| `add_comment` | comment on a step (`run_id` + `step`), the whole run (`run_id`) or the whole flow (`scenario`); `parent_id` replies; optional `pin` `{ x, y, viewport }` |
|
|
40
|
+
| `resolve_comment` | close a thread with a `note` that says what changed (it becomes the last reply) |
|
|
41
|
+
| `reopen_comment`, `edit_comment`, `delete_comment` | reopen; edit or delete your own comment |
|
|
42
|
+
|
|
43
|
+
Writes need a token with scope full. Follow *Processing feedback* in
|
|
44
|
+
[collaboration.md](collaboration.md).
|
|
45
|
+
|
|
46
|
+
Typical loop for an agent that owns a task: `list_runs` with the scenario →
|
|
47
|
+
`get_feedback` for the latest run → fix what was returned → new run with the
|
|
48
|
+
CLI (`kaloko start … share`) → post the canvas URL in the issue. Capturing,
|
|
49
|
+
evaluating and uploading stay in the CLI; MCP reads, and for design drafts also
|
|
50
|
+
publishes versions, sets references and step status, and comments (below).
|
|
51
|
+
|
|
52
|
+
Errors come back as tool results with `isError: true` (unknown run, expired
|
|
53
|
+
run, missing argument); an invalid token is HTTP 401.
|
|
54
|
+
|
|
55
|
+
## Design tools (#42)
|
|
56
|
+
|
|
57
|
+
The same data and permissions as the REST API; each tool is its REST route.
|
|
58
|
+
|
|
59
|
+
| Tool | Use |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `get_draft` | which revision each step shows, step status, who changed it (person or agent) |
|
|
62
|
+
| `get_step` | the handoff: live files, signed entry URL, token set, page structure, open comments (`ref`: draft, design, vN, run id) |
|
|
63
|
+
| `get_step_history` | versions, and revisions of a step with authors |
|
|
64
|
+
| `list_step_changes` | steps that differ between two references (default design reference → draft) |
|
|
65
|
+
| `get_references`, `get_tokens` | design reference and baseline; the project's token set |
|
|
66
|
+
| `get_draft_feedback` | draft comments, pinned ones with their element |
|
|
67
|
+
| `publish_version`, `set_reference`, `set_step_status`, `add_draft_comment` | writes: need a token with scope full; ask first where the skill says so |
|
|
68
|
+
|
|
69
|
+
Files are not uploaded over MCP: the CLI (`kaloko sync`) or the REST blob endpoints carry them.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Stack steps: many pages of one template
|
|
2
|
+
|
|
3
|
+
A stack step (`kind: stack`) stands for many pages that share a template: the
|
|
4
|
+
articles of a magazine, product or category pages, an SEO catalogue of
|
|
5
|
+
landing pages, pages after a migration. The walk captures every page with
|
|
6
|
+
the step's criteria and a few index fields; the canvas shows one node drawn
|
|
7
|
+
as a stack. Clicking it opens an index of the pages with search, filters,
|
|
8
|
+
sorting, thumbnails and CSV export, and each page opens in the lightbox.
|
|
9
|
+
|
|
10
|
+
## When to use it
|
|
11
|
+
|
|
12
|
+
- One template, many instances with different content, and the question is
|
|
13
|
+
whether *all of them* hold up. Examples: "every article has one H1, a
|
|
14
|
+
title of 10–70 chars and a cover image", "no product page returns 404",
|
|
15
|
+
"every city landing has a description and a canonical".
|
|
16
|
+
- An SEO audit or design of a page catalogue: list the pages, see the gaps
|
|
17
|
+
per page, and export the failing ones for the content team.
|
|
18
|
+
- A redesign or migration: walk the old URL list against the new site.
|
|
19
|
+
|
|
20
|
+
Not for a flow of different screens: those stay separate steps. A stack
|
|
21
|
+
step does not click through anything. It opens each page by URL. Use a
|
|
22
|
+
step script only to prepare each page, for example to dismiss a dialog
|
|
23
|
+
(see below).
|
|
24
|
+
|
|
25
|
+
## Declaring it
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
- id: articles
|
|
29
|
+
kind: stack
|
|
30
|
+
title: Magazine articles
|
|
31
|
+
purpose: Every article reads well and is findable.
|
|
32
|
+
packs: [seo] # the pack criteria apply to every page
|
|
33
|
+
items:
|
|
34
|
+
sitemap: /sitemap.xml # or urls / file / crawl / script (exactly one)
|
|
35
|
+
match: '^/clanky/' # regex on the path with its query; exclude: '…' drops pages
|
|
36
|
+
limit: 800 # default 500, at most 10000
|
|
37
|
+
semantic_sample: 20 # semantic criteria on the first 20 pages only
|
|
38
|
+
# viewports: [desktop] # default: the first viewport of the scenario
|
|
39
|
+
fields: # index columns (max 12); default title, h1, words, http
|
|
40
|
+
- { id: title, label: Title, from: title }
|
|
41
|
+
- { id: words, label: Words, from: words }
|
|
42
|
+
- { id: http, label: HTTP, from: http }
|
|
43
|
+
- { id: author, label: Author, from: .author }
|
|
44
|
+
- { id: cover, label: Cover, from: "article img@src" }
|
|
45
|
+
- { id: links, label: Links, from: "count:main a" }
|
|
46
|
+
# capture: { full_page: true } # default for stacks is the first screen only
|
|
47
|
+
criteria:
|
|
48
|
+
- { id: AC1, text: Has a cover image, check: { type: deterministic, assert: exists, selector: "article img" } }
|
|
49
|
+
- { id: AC2, text: Reads as an article, check: { type: semantic, question: Does the page read as a complete magazine article? } }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Item sources:
|
|
53
|
+
|
|
54
|
+
- `urls: [/a, /b]` is a short fixed list.
|
|
55
|
+
- `file: qa/data/products.csv` is a list next to the scenario. Accepted
|
|
56
|
+
formats are text with one path per line, CSV (first column), or JSON:
|
|
57
|
+
`["/a"]` or `[{ path, title, key }]`, where `key` gives a stable id.
|
|
58
|
+
- `sitemap: /sitemap.xml` also follows a sitemap index (up to 50 sitemaps).
|
|
59
|
+
- `crawl: { from: /clanky, links: "a.card", next: "a.next", pages: 20 }`
|
|
60
|
+
collects links from a listing and follows its pagination.
|
|
61
|
+
- `script: qa/steps/items.mjs` uses the default export
|
|
62
|
+
`({ page, env, locale, url }) => [paths | { path, title, key }]` for
|
|
63
|
+
anything else, such as an API or a search.
|
|
64
|
+
|
|
65
|
+
Pages are deduplicated. External URLs are allowed (e.g. an old domain).
|
|
66
|
+
`{locale}` in any source string is replaced by the walked locale. This is
|
|
67
|
+
how one sitemap with every language is split:
|
|
68
|
+
`match: '^/guides/.*lang={locale}'`, or `sitemap: /{locale}/sitemap.xml`.
|
|
69
|
+
|
|
70
|
+
Field sources: `title`, `h1`, `description`, `canonical`, `lang`, `url`,
|
|
71
|
+
`path`, `words` (words in main/article/body), `http` (the navigation
|
|
72
|
+
status), `count:<selector>`, `<selector>` (text) and `<selector>@<attr>`.
|
|
73
|
+
|
|
74
|
+
A step `execution.script` still works. It is called with `item` in the
|
|
75
|
+
context, opens `item.url` itself and may call `capture()`. Without a script,
|
|
76
|
+
the walk opens each page and captures it.
|
|
77
|
+
|
|
78
|
+
## Cost and size: choose deliberately
|
|
79
|
+
|
|
80
|
+
- Deterministic criteria and packs run on every page. They are cheap.
|
|
81
|
+
- Semantic criteria go to the evaluator. On a stack they run only on the
|
|
82
|
+
first `semantic_sample` pages (default 20). The other pages show the
|
|
83
|
+
criterion as not evaluated. Raise the sample only when the question
|
|
84
|
+
really differs between pages, and tell the person what it costs
|
|
85
|
+
(one call per page and viewport).
|
|
86
|
+
- Stacks capture the first screen of each page (fast, small). Set
|
|
87
|
+
`capture: { full_page: true }` when the criteria are about the whole page.
|
|
88
|
+
- Walking takes about 1–2 s per page. For a first look, use
|
|
89
|
+
`kaloko walk --limit 50`. Re-walk chosen pages with
|
|
90
|
+
`--items clanek-7,clanek-12` (matches the id or the path).
|
|
91
|
+
- A shared run holds at most 20000 files and 300 MB. Each page stores about
|
|
92
|
+
four files, so a stack of a few thousand first-screen pages fits. Split
|
|
93
|
+
larger catalogues by section (`match`), one stack per section.
|
|
94
|
+
|
|
95
|
+
## Reading the results
|
|
96
|
+
|
|
97
|
+
- `kaloko build` writes `steps/<step>/items.json` (`qawalk.stack.v1`)
|
|
98
|
+
with every page's fields, status, failing criteria and evidence. The
|
|
99
|
+
preview inlines it, so the local `index.html` works offline.
|
|
100
|
+
- The node shows the page count, a pass/fail bar and a few thumbnails, with
|
|
101
|
+
failing pages first. Each criterion carries counts (for example "3/31
|
|
102
|
+
pages" in the report).
|
|
103
|
+
- In the index:
|
|
104
|
+
- status chips, a criterion filter, search over path, title and fields,
|
|
105
|
+
sort by any field, list or grid view;
|
|
106
|
+
- keyboard: `/` searches, arrows move, Enter opens, Esc closes;
|
|
107
|
+
- "Download CSV" exports the filtered rows;
|
|
108
|
+
- a page link (`#step=<stack>~<page>`) opens that page directly.
|
|
109
|
+
- Over MCP: `get_run_summary` includes the stack summary.
|
|
110
|
+
`get_stack_items {run_id, step, status?, criterion?, query?, offset, limit}`
|
|
111
|
+
lists pages with fields, failing criteria, evidence and screenshot URLs.
|
|
112
|
+
This is the way to hand an agent "fix these 37 articles".
|
|
113
|
+
|
|
114
|
+
## Report
|
|
115
|
+
|
|
116
|
+
Say how many pages were walked, how many fail and on which criteria (with
|
|
117
|
+
two or three example paths), whether the limit cut the list, and that
|
|
118
|
+
semantic criteria covered only the sample. Put the full list in the CSV or
|
|
119
|
+
the MCP result rather than in the issue.
|
|
120
|
+
|
|
121
|
+
Not yet supported for stacks: comparison with a baseline run per page and
|
|
122
|
+
the documentation layer (latest captures per step).
|