@qaping/cli 0.1.5 → 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/bin/qaping +606 -5
- package/docs/COMMANDS.md +122 -0
- package/docs/QA-PLAN-FORMAT.md +53 -2
- package/docs/icon.svg +1 -0
- package/package.json +2 -2
- package/skill/SHIPPED-HASHES.json +19 -0
- package/skill/qaping/SKILL.md +246 -58
package/docs/COMMANDS.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# qaping — CLI commands
|
|
2
|
+
|
|
3
|
+
Everything the `qaping` binary does. Your agent runs most of these for you;
|
|
4
|
+
`setup`, `builds` and `rounds` are the ones you will type yourself.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
qaping setup [claude-code|cursor|codex] [--force]
|
|
8
|
+
qaping remove [--client <c>]
|
|
9
|
+
qaping publish-build <game.zip> --platform windows|macos
|
|
10
|
+
qaping builds
|
|
11
|
+
qaping builds rm <slug>
|
|
12
|
+
qaping publish <built-dir>
|
|
13
|
+
qaping wait <ping_id> [--timeout <seconds>]
|
|
14
|
+
qaping results <ping_id> [--json]
|
|
15
|
+
qaping rounds [--json] [--offline] [--file <path>]
|
|
16
|
+
qaping rounds add <ping_id> [--platform windows|macos|ios] [--build <url>]
|
|
17
|
+
[--minutes N] [--deadline-seconds N]
|
|
18
|
+
[--game <slug>] [--checks a,b,c]
|
|
19
|
+
[--note "<patch>"] [--json]
|
|
20
|
+
qaping rounds rm <ping_id> [--json]
|
|
21
|
+
qaping issues <game> [--json] [--status open|fixed|verified|closed]
|
|
22
|
+
qaping whoami
|
|
23
|
+
qaping version
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Getting in and out
|
|
27
|
+
|
|
28
|
+
### `qaping setup [claude-code|cursor|codex] [--force]`
|
|
29
|
+
|
|
30
|
+
Registers the qaping MCP server with your coding agent, installs the `qaping`
|
|
31
|
+
skill and its rule, and signs you in (a browser window opens once). With no
|
|
32
|
+
client name it detects what is installed. `--force` rewrites an existing
|
|
33
|
+
entry.
|
|
34
|
+
|
|
35
|
+
### `qaping remove [--client <c>]`
|
|
36
|
+
|
|
37
|
+
Removes qaping's MCP entry, skill and rule from the client. It touches only
|
|
38
|
+
qaping's own state — nothing else you have installed, and not your login.
|
|
39
|
+
|
|
40
|
+
### `qaping whoami`
|
|
41
|
+
|
|
42
|
+
Which account this machine is signed in as. Results are scoped to the account
|
|
43
|
+
that filed the round, so check this before deciding a round is gone.
|
|
44
|
+
|
|
45
|
+
### `qaping version`
|
|
46
|
+
|
|
47
|
+
Prints the installed version.
|
|
48
|
+
|
|
49
|
+
## Hosting a build
|
|
50
|
+
|
|
51
|
+
### `qaping publish-build <game.zip> --platform windows|macos`
|
|
52
|
+
|
|
53
|
+
Uploads a zipped native build and prints the `/b/<slug>` URL a round is filed
|
|
54
|
+
against. You hold a small number of hosted builds at a time; the oldest is
|
|
55
|
+
listed first by `qaping builds`.
|
|
56
|
+
|
|
57
|
+
### `qaping builds` / `qaping builds rm <slug>`
|
|
58
|
+
|
|
59
|
+
Lists the hosted builds you hold, or deletes one now to free its slot.
|
|
60
|
+
|
|
61
|
+
### `qaping publish <built-dir>`
|
|
62
|
+
|
|
63
|
+
Hosts a browser-playable game's built output and prints the public URL. Web
|
|
64
|
+
rounds are filed with that URL and no platform.
|
|
65
|
+
|
|
66
|
+
## Rounds
|
|
67
|
+
|
|
68
|
+
### `qaping wait <ping_id> [--timeout <seconds>]`
|
|
69
|
+
|
|
70
|
+
Waits on a filed round, renewing the lease that keeps it visible to new
|
|
71
|
+
playtesters, and prints the results when they land. The agent normally runs
|
|
72
|
+
this in a background task.
|
|
73
|
+
|
|
74
|
+
### `qaping results <ping_id> [--json]`
|
|
75
|
+
|
|
76
|
+
One passive fetch, no waiting. Exit code `0` means results are in, `2` means
|
|
77
|
+
still pending, `1` anything else (expired, not yours, unreachable).
|
|
78
|
+
|
|
79
|
+
### `qaping rounds`
|
|
80
|
+
|
|
81
|
+
The parked rounds this repo is owed, read from `qa-open-rounds.json` at the
|
|
82
|
+
repo root, each with its live status. `--offline` skips the status lookup;
|
|
83
|
+
`--file` points at another ledger.
|
|
84
|
+
|
|
85
|
+
### `qaping rounds add <ping_id> …`
|
|
86
|
+
|
|
87
|
+
Records a round the agent chose to park — an overnight run, a slow native
|
|
88
|
+
claim — so a later session collects it instead of filing a duplicate. Add
|
|
89
|
+
`--build`, `--minutes`, `--deadline-seconds`, `--game`, `--checks` and
|
|
90
|
+
`--note` so the record explains itself; `--game` is the QA plan's
|
|
91
|
+
`game_slug`, so the session that collects the round knows which issue board
|
|
92
|
+
it moved.
|
|
93
|
+
|
|
94
|
+
### `qaping rounds rm <ping_id>`
|
|
95
|
+
|
|
96
|
+
Forgets a parked round once it is collected or expired.
|
|
97
|
+
|
|
98
|
+
## The issue board
|
|
99
|
+
|
|
100
|
+
### `qaping issues <game> [--json]`
|
|
101
|
+
|
|
102
|
+
Prints the game's issue board: every bug that outlived a round, with its
|
|
103
|
+
status — open, fixed (you claim it is fixed), verified (a playtester
|
|
104
|
+
confirmed it is gone), closed. `--status` prints one status only; `--json`
|
|
105
|
+
prints the machine-readable rows.
|
|
106
|
+
|
|
107
|
+
Read-only, on purpose. Your agent files, claims, closes and reopens issues
|
|
108
|
+
through the `qaping_issues` MCP tool while it runs the loop; this is the
|
|
109
|
+
window you read it through. Nothing on the board costs credits — only rounds
|
|
110
|
+
do — and nothing turns *verified* except a playtester answering "Gone" on a
|
|
111
|
+
round filed after the fix was claimed.
|
|
112
|
+
|
|
113
|
+
## Files qaping leaves in your repo
|
|
114
|
+
|
|
115
|
+
| file | what it is | commit it? |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `QA-PLAN.md` | the checks this game must pass; the agent authors, you own | yes — see [the format](QA-PLAN-FORMAT.md) |
|
|
118
|
+
| `qa-rounds.jsonl` | append-only history, one line per finished round | yes |
|
|
119
|
+
| `qa-open-rounds.json` | rounds filed and not yet collected | no — gitignore it |
|
|
120
|
+
|
|
121
|
+
The issue board is not a file: it lives on the service, one board per game,
|
|
122
|
+
and `qaping issues <game>` reads it. The plan's `game_slug` is what names it.
|
package/docs/QA-PLAN-FORMAT.md
CHANGED
|
@@ -11,12 +11,19 @@ YAML at the very top of the file:
|
|
|
11
11
|
```yaml
|
|
12
12
|
---
|
|
13
13
|
game: Solar Drift
|
|
14
|
+
game_slug: solar-drift # the issue board's id — minted ONCE, never renamed
|
|
14
15
|
build_command: ./scripts/package.sh --release # the ONE command that produces a shippable build
|
|
15
16
|
platforms: [windows] # windows | macos | ios | web
|
|
16
17
|
input: XInput gamepad # optional; default keyboard+mouse
|
|
17
18
|
---
|
|
18
19
|
```
|
|
19
20
|
|
|
21
|
+
`game_slug` is minted once from the game name — lowercase, every run of
|
|
22
|
+
non-alphanumerics collapsed to a single `-`, no leading or trailing `-`, ≤64
|
|
23
|
+
characters — and is then permanent, exactly like a check id: it names the
|
|
24
|
+
game's issue board, and renaming it orphans every issue filed under the old
|
|
25
|
+
one. Every playtest round is filed with it as `game`.
|
|
26
|
+
|
|
20
27
|
`build_command` is recorded once at setup so every future run can build without
|
|
21
28
|
asking. `platforms: [web]` means a browser-playable game — its "build" is a
|
|
22
29
|
static directory, not a zip. `input` declares the hardware the
|
|
@@ -88,6 +95,26 @@ setup: "?save=campaign-mid"
|
|
|
88
95
|
anything missing, corrupted, or visually wrong.
|
|
89
96
|
````
|
|
90
97
|
|
|
98
|
+
## Bugs live on the issue board; checks live here
|
|
99
|
+
|
|
100
|
+
A check is what the game must ALWAYS do — it belongs in this file, forever. A
|
|
101
|
+
bug is what the game does wrong right now — it belongs on the game's issue
|
|
102
|
+
board (`qaping issues <game_slug>`, moved by the agent through the
|
|
103
|
+
`qaping_issues` tool), where it is numbered, carried across rounds, and
|
|
104
|
+
retired when it is gone. Do not write bugs into `QA-PLAN.md`: a check written
|
|
105
|
+
to describe one bug ("the shop does not close when you press B twice") ages
|
|
106
|
+
into a puzzle the moment the bug is fixed.
|
|
107
|
+
|
|
108
|
+
The board is what makes a fix provable. The agent may CLAIM a fix (with the
|
|
109
|
+
exact build URL the next round will play); only a playtester answering
|
|
110
|
+
"Gone" on a round filed after that claim turns the issue *verified*, and a
|
|
111
|
+
"Still here" on a claimed fix regresses it. Because every round is filed with
|
|
112
|
+
`game`, the board's open and claimed-fixed issues ride it as the playtester's
|
|
113
|
+
checklist — no step budget spent, no bug forgotten between patches.
|
|
114
|
+
|
|
115
|
+
A check and the bug that came from it stay linked through the issue's
|
|
116
|
+
`check_id`: the same id this file gives the check.
|
|
117
|
+
|
|
91
118
|
## The round ledger — qa-rounds.jsonl
|
|
92
119
|
|
|
93
120
|
Beside the plan, at the game repo root, sits `qa-rounds.jsonl`: one JSON line
|
|
@@ -96,6 +123,8 @@ appended per round, committed alongside the plan updates —
|
|
|
96
123
|
```json
|
|
97
124
|
{"round_id": "…", "report_url": "…", "build": "<sha or hosted url>",
|
|
98
125
|
"evidence_grade": "…", "checks": [{"id": "…", "outcome": "…"}],
|
|
126
|
+
"issues": {"game": "solar-drift", "verified": [3], "regressed": [5],
|
|
127
|
+
"new": [7], "still_open": [2]},
|
|
99
128
|
"verdict": "…", "credits": 20, "follow_ups": ["…"]}
|
|
100
129
|
```
|
|
101
130
|
|
|
@@ -106,8 +135,30 @@ page (what the results tool returns), never a PR or issue link. There is no
|
|
|
106
135
|
evidence-link field, deliberately: signed recording URLs expire in days.
|
|
107
136
|
The ledger is the machine truth of what was asked and answered, per check,
|
|
108
137
|
per round; the plan's `last_verified` and `state` are derived from it and
|
|
109
|
-
stay the dev-readable contract.
|
|
110
|
-
|
|
138
|
+
stay the dev-readable contract. `issues` is what this round did to the issue
|
|
139
|
+
board, by number (omitted when the round carried no `game`). `follow_ups` is
|
|
140
|
+
NON-BUG follow-ups only — a check to add, a build affordance to write, a
|
|
141
|
+
question to settle; bugs go on the board, where they are numbered and
|
|
142
|
+
re-checked. Open `follow_ups` are what the next filing must carry forward.
|
|
143
|
+
|
|
144
|
+
## Rounds still open — qa-open-rounds.json
|
|
145
|
+
|
|
146
|
+
A playtest may run for many hours, so a round the agent cannot sit through is
|
|
147
|
+
PARKED: filed with an explicit long deadline, then recorded in
|
|
148
|
+
`qa-open-rounds.json` (same directory) so a LATER session collects it —
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{"rounds": [{"ping_id": "<uuid>", "filed_at": "<ISO>", "platform": "windows",
|
|
152
|
+
"build": "<the hosted or store URL>", "est_minutes": 10,
|
|
153
|
+
"deadline_seconds": 86400, "game": "solar-drift",
|
|
154
|
+
"checks": ["<check ids>"], "note": "<the patch this round covers>"}]}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`qaping rounds` lists it with each round's live status, `qaping rounds add`
|
|
158
|
+
(with `--game` for the board this round carries) records one,
|
|
159
|
+
`qaping rounds rm` drops it once collected. This file is the
|
|
160
|
+
opposite of the ledger and never merges with it: mutable OPEN state, one entry
|
|
161
|
+
per round still owed, emptied as rounds land. It is not history — gitignore it.
|
|
111
162
|
|
|
112
163
|
## Maintenance rules
|
|
113
164
|
|
package/docs/icon.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64"><rect x="4" y="4" width="56" height="56" rx="14" fill="#FF7A45"/><path d="M20 33.5l8 8 16-17" fill="none" stroke="#fff" stroke-width="6.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qaping/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"homepage": "https://qaping.dev",
|
|
5
5
|
"description": "qaping: automatic QA for your game. Your coding agent authors and maintains the QA plan, ships each patch's build to real human playtesters, and reports what broke.",
|
|
6
6
|
"keywords": [
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"node": "^20.17.0 || ^22.13.0 || >=23.5.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"pingfusi": "^0.
|
|
28
|
+
"pingfusi": "^0.17.1"
|
|
29
29
|
},
|
|
30
30
|
"publishConfig": {
|
|
31
31
|
"access": "public"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"note": "sha256 of every SKILL.md version this package has shipped (LF-normalized). setup refreshes an installed skill whose hash is listed here — it is ours — and preserves anything else as a local edit. APPEND-ONLY; regenerate with: node scripts/gen-skill-hashes.js [<skill-root>...]",
|
|
3
|
+
"skills": {
|
|
4
|
+
"qaping": [
|
|
5
|
+
"184aa97ba0d529eea36be3c6eb4a5f4c1db8e2a65a0230e03814276a18a92354",
|
|
6
|
+
"217ffcc582e068424eefbb69376825ac71433fa92f34e3546bd02d8521ef008c",
|
|
7
|
+
"2fe5cafeef48146d8c9cc263ae1aaef764720027d17c0af3ab879e6853cf4a26",
|
|
8
|
+
"38cdc3289db6a544bc0cc828f4981a3f4ed6b39036ce81eebbaf4cbe9c47a5d0",
|
|
9
|
+
"490ff02895fdc6a2eb3a0b671628a8d4eee3efd906782eb45d99eac40bf59846",
|
|
10
|
+
"5462b858f58d183a020a5b2fa214dd1da6856e71a238316641f13d70eb0f0df4",
|
|
11
|
+
"5d0751c023af0a1cf69f152ba587b10c34087c7d5299f2d4b0e782f1ad0d66b0",
|
|
12
|
+
"6d0a5a1b430a8a0fd1c7c06b726de657e7fe82ac37ce69c9446539065d2ce751",
|
|
13
|
+
"71e64cd2b58996236c7fd3375a324ca2ae7b3e4028f7b358a389c562464c8bf3",
|
|
14
|
+
"8d817af568154734cd893122ce2e40ef2cd20cb725abbf318f134318157e5b6c",
|
|
15
|
+
"966bd642f1ee052691c7974a186e9f8f50644bce0ea010b6f0b444931879dbad",
|
|
16
|
+
"b9d08318e69290759bf31e149d64207b9d186faac9ccd01bc1db3ffcff29506c"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|