@jabworks/condux 0.28.0 → 0.29.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jabworks/condux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "OpenCode plugin for the condux workflow toolkit — bundles the condux skills and injects the specialist agents (coder, explorer, planner, researcher) plus an opt-in plan-review listener.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,7 +20,7 @@ between "the pipeline passed" and "I watched it do the thing".
|
|
|
20
20
|
|
|
21
21
|
| Change touches | Run this? |
|
|
22
22
|
|---|---|
|
|
23
|
-
| A rendered surface — page, component, story, dialog | **Yes** |
|
|
23
|
+
| A rendered surface — page, component, story, dialog, a mobile app screen | **Yes** |
|
|
24
24
|
| An endpoint, procedure, or CLI a human will call | **Yes** |
|
|
25
25
|
| Behaviour behind a flag or a state the tests don't reach | **Yes** |
|
|
26
26
|
| Types, docs, comments, config with no runtime effect | No — say so and skip |
|
|
@@ -43,6 +43,14 @@ Do not assume a dev server. In order:
|
|
|
43
43
|
Start it in the background, wait for it to actually serve (poll the URL — do
|
|
44
44
|
not `sleep` and hope), and note the URL in the report.
|
|
45
45
|
|
|
46
|
+
**Mobile app: load the native recipe.** If the project is a mobile app —
|
|
47
|
+
finalize's native-change test: an `expo` or `react-native` dependency, or a
|
|
48
|
+
committed `android/` or `ios/` — read `references/native-app.md` now. Its
|
|
49
|
+
target order replaces the list above; it picks the driving rung once (adb,
|
|
50
|
+
`agent-device`, mobile-mcp, Expo's skills — recommended, never installed) and
|
|
51
|
+
resolves `adb` to an absolute path. The claims, verdicts and report below are
|
|
52
|
+
unchanged.
|
|
53
|
+
|
|
46
54
|
**Mobile app: rebuild first when the change is native.** If finalize's
|
|
47
55
|
`Native` line said *native rebuild* (or the diff touches the native layer —
|
|
48
56
|
see finalize's native-change check), the installed app does not contain the
|
|
@@ -81,6 +89,12 @@ Order of checks, because this is where the defects were:
|
|
|
81
89
|
4. **Keyboard.** Tab to it, Escape out of it, confirm focus lands somewhere
|
|
82
90
|
sensible.
|
|
83
91
|
|
|
92
|
+
**Mobile app:** the same four checks, translated — both themes via
|
|
93
|
+
`cmd uimode night`; pressed, disabled and in-flight states in place of hover;
|
|
94
|
+
the failure path in airplane mode; the system back (`keyevent 4`) in place of
|
|
95
|
+
Tab and Escape, which must close what it opened. Every tap follows
|
|
96
|
+
`native-app.md`'s stale-UI rules.
|
|
97
|
+
|
|
84
98
|
### Step 4 — Capture evidence
|
|
85
99
|
|
|
86
100
|
One artifact per claim that has a visual or observable outcome — screenshot,
|
|
@@ -91,6 +105,12 @@ evidence file for the claim it supports and reference it from the report's
|
|
|
91
105
|
claim table. Console errors and failed network requests seen along the way
|
|
92
106
|
get reported even when they belong to another feature.
|
|
93
107
|
|
|
108
|
+
**Mobile app:** evidence is a screenshot you have read back, or a recording
|
|
109
|
+
for motion, and `native-app.md`'s log sweep stands in for console and network.
|
|
110
|
+
A claim the emulator cannot settle — haptics, camera, push, feel — gets the
|
|
111
|
+
`device-only` verdict and a line under the report's `For the phone:`, never ✓.
|
|
112
|
+
The report adds the `Device` and `Build` header keys.
|
|
113
|
+
|
|
94
114
|
Then write `report.md` into the same dir, in the shape of
|
|
95
115
|
`references/report-template.md` — every run writes one, including runs where
|
|
96
116
|
nothing could be driven (the template carries the fallback shape).
|
|
@@ -127,11 +147,16 @@ Wait timed out
|
|
|
127
147
|
|
|
128
148
|
Two failed attempts on the same claim is the ceiling. Report and move on.
|
|
129
149
|
|
|
150
|
+
On a mobile app, the device-side failures — an offline device, an emulator
|
|
151
|
+
that won't boot, a stale binary — are in `native-app.md`'s part 8, under the
|
|
152
|
+
same ceiling.
|
|
153
|
+
|
|
130
154
|
## Output Format
|
|
131
155
|
|
|
132
|
-
The report shape — the fixed header table (Date / Target / Diff / Themes
|
|
133
|
-
the claim table (Claim | Evidence |
|
|
134
|
-
|
|
156
|
+
The report shape — the fixed header table (Date / Target / Diff / Themes,
|
|
157
|
+
plus Device / Build on a native app run), the claim table (Claim | Evidence |
|
|
158
|
+
Verdict), the phone checklist for `device-only` claims, "Also seen", and the
|
|
159
|
+
outcome line — lives in `references/report-template.md`, the canonical home. It also
|
|
135
160
|
carries the fallback shape for when nothing could be driven; that run still
|
|
136
161
|
writes `report.md`, because an absent report is indistinguishable from a run
|
|
137
162
|
that never happened. Fixed header keys and a fixed claim-table shape are what
|
|
@@ -142,7 +167,8 @@ make two runs of the same surface comparable.
|
|
|
142
167
|
```
|
|
143
168
|
✗ Reporting a claim as verified because the code looks right
|
|
144
169
|
✗ Inventing a screenshot, a response, or a result that wasn't observed
|
|
145
|
-
✗ Installing a browser driver or scaffolding a test harness to get a result
|
|
170
|
+
✗ Installing a browser or device driver, or scaffolding a test harness to get a result
|
|
171
|
+
✗ Reporting a device-only claim as ✓
|
|
146
172
|
✗ sleep-then-check instead of polling for the condition
|
|
147
173
|
✗ Retrying the same selector more than twice
|
|
148
174
|
✗ Killing processes the run didn't start
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Native app verification (Android)
|
|
2
|
+
|
|
3
|
+
Loaded from Step 1 when the project is a mobile app — the same test as
|
|
4
|
+
finalize's native-change check: an `expo` or `react-native` dependency in
|
|
5
|
+
`package.json`, or a committed `android/` or `ios/` directory. A web project
|
|
6
|
+
never reads this file.
|
|
7
|
+
|
|
8
|
+
The claim/verdict/report contract in SKILL.md does not change. This file only
|
|
9
|
+
says how to reach the app, drive it, and read its errors — and which claims an
|
|
10
|
+
emulator cannot settle.
|
|
11
|
+
|
|
12
|
+
## 1. Pick the rung
|
|
13
|
+
|
|
14
|
+
Decide once, at the start of the run, and name the choice in the report's
|
|
15
|
+
`Target` row. Three rungs, each optional, none ever installed by you:
|
|
16
|
+
|
|
17
|
+
| Concern | Use, first match wins |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Build and install | the `expo` plugin's `expo-dev-client` / `eas-simulator` skills, when they are in your skill list → the project's own build script → `npx expo run:android` |
|
|
20
|
+
| Drive and read logs | `agent-device` on PATH (`command -v agent-device`) → mobile-mcp's `mobile_*` tools, when you have them → the core adb recipe below |
|
|
21
|
+
|
|
22
|
+
When a driver rung is in use, follow **its** documentation for the commands
|
|
23
|
+
(`agent-device help`, its bundled skills, the MCP tools' own descriptions) —
|
|
24
|
+
this file deliberately does not restate them. Parts 5–7 below apply on every
|
|
25
|
+
rung: they are about what counts as evidence, not about which tool taps.
|
|
26
|
+
|
|
27
|
+
No driver installed is the normal case, not a gap — never install one, and
|
|
28
|
+
never stop the run to ask.
|
|
29
|
+
|
|
30
|
+
## 2. Target
|
|
31
|
+
|
|
32
|
+
In order, before booting or building anything:
|
|
33
|
+
|
|
34
|
+
1. **The project's own setup wins.** `AGENTS.md`, `README.md`, a
|
|
35
|
+
project-local skill for running the app, `package.json` scripts
|
|
36
|
+
(`android`, `start`, a dev-client script), and anything under `scripts/`
|
|
37
|
+
that boots an emulator or installs a build. Use them as written. When they
|
|
38
|
+
disagree, the prose that is newest wins over a script name — a script can
|
|
39
|
+
outlive the emulator it boots.
|
|
40
|
+
2. **Is a device already attached?** `adb devices` (with the resolved path,
|
|
41
|
+
part 3). One device in the `device` state → use it. `offline` or
|
|
42
|
+
`unauthorized` → part 8.
|
|
43
|
+
3. **No device** → boot the emulator the project's script names, or
|
|
44
|
+
`emulator -list-avds` and the first one. Poll until
|
|
45
|
+
`adb shell getprop sys.boot_completed` prints `1` — never a fixed sleep.
|
|
46
|
+
4. **Metro.** A dev client loads JS from Metro: check port 8081 before
|
|
47
|
+
starting it, and run `adb reverse tcp:8081 tcp:8081` once per boot.
|
|
48
|
+
5. **Package and scheme.** Read `android.package` and `scheme` from the app
|
|
49
|
+
config (`app.json` / `app.config.*`), or `applicationId` from
|
|
50
|
+
`android/app/build.gradle*`. Every launch and log filter below needs them.
|
|
51
|
+
An `app.config.*` can change both per build variant (a dev client often
|
|
52
|
+
carries a `.dev` suffix and its own scheme) — confirm the installed one
|
|
53
|
+
with `adb shell pm list packages <name>` before launching.
|
|
54
|
+
|
|
55
|
+
## 3. Resolve adb once
|
|
56
|
+
|
|
57
|
+
`adb` is often on the user's interactive PATH only, and an agent's shell keeps
|
|
58
|
+
no state between calls — an `export PATH=…` or an `ADB=…` variable lasts one
|
|
59
|
+
command.
|
|
60
|
+
|
|
61
|
+
**A project-provided adb wins.** Some setups run the emulators on another
|
|
62
|
+
host or OS and reach them through a wrapper script or a non-default adb
|
|
63
|
+
server; the project's docs (part 2) name it. Use that, by absolute path.
|
|
64
|
+
Otherwise resolve the absolute path once:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
command -v adb || ls "$ANDROID_HOME/platform-tools/adb" "$ANDROID_SDK_ROOT/platform-tools/adb" 2>/dev/null | head -1
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then **write that literal path into every later command**. An adb that lists
|
|
71
|
+
no devices while the project documents a running one is the wrong adb, not an
|
|
72
|
+
empty machine — go back to the project's docs. Nothing found →
|
|
73
|
+
stop and report the blocker with the exact next command to try (set
|
|
74
|
+
`ANDROID_HOME`, or install platform-tools). Never install the SDK yourself.
|
|
75
|
+
|
|
76
|
+
## 4. Drive
|
|
77
|
+
|
|
78
|
+
The core recipe, written with `adb` for brevity — use the resolved path.
|
|
79
|
+
|
|
80
|
+
| Need | Command |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Launch at a screen | `adb shell am start -W -a android.intent.action.VIEW -d "<scheme>://<path>" <package>` |
|
|
83
|
+
| Tap / swipe | `adb shell input tap <x> <y>` · `adb shell input swipe <x1> <y1> <x2> <y2> <ms>` |
|
|
84
|
+
| Long-press | `adb shell input swipe <x> <y> <x> <y> 800` (a swipe that does not move) |
|
|
85
|
+
| Drag, multi-step gestures | `adb shell input motionevent DOWN/MOVE/UP <x> <y>`, where the device's `input` lists it |
|
|
86
|
+
| Type / keys | `adb shell input text '<text>'` · `adb shell input keyevent 4` (back) |
|
|
87
|
+
| Screenshot | `adb exec-out screencap -p > <claim>.png` — then Read the PNG; an unread screenshot proves nothing |
|
|
88
|
+
| Motion | `adb shell screenrecord --time-limit <s> /sdcard/<claim>.mp4`, then `adb pull` — a still cannot prove an animation |
|
|
89
|
+
| UI tree | `adb exec-out uiautomator dump /dev/tty` — element text, ids and `bounds` |
|
|
90
|
+
| Theme | `adb shell cmd uimode night yes` / `no` — both themes still gate a themed change |
|
|
91
|
+
| Offline | `adb shell cmd connectivity airplane-mode enable` / `disable` |
|
|
92
|
+
| Fresh state | `adb shell pm clear <package>` — only when the claim needs it; it wipes the user's app data |
|
|
93
|
+
|
|
94
|
+
## 5. Stale UI
|
|
95
|
+
|
|
96
|
+
Most wrong taps in the field came from acting on a picture of a screen that
|
|
97
|
+
had already changed.
|
|
98
|
+
|
|
99
|
+
- **Take a fresh screenshot before any tap that changes state**, and look at it.
|
|
100
|
+
- **A `uiautomator dump` is true only for the moment it ran.** Re-dump after
|
|
101
|
+
every navigation, dialog, or list change.
|
|
102
|
+
- **Coordinates come from a dump's `bounds`**, never estimated from an image.
|
|
103
|
+
- **"could not get idle state"** means an animation is running. Poll the dump
|
|
104
|
+
again; a screen that never goes idle is a finding, not a reason to guess.
|
|
105
|
+
|
|
106
|
+
## 6. Log sweep
|
|
107
|
+
|
|
108
|
+
Runtime errors are part of the evidence — the same rule as the browser
|
|
109
|
+
console.
|
|
110
|
+
|
|
111
|
+
1. Before driving: `adb logcat -c`.
|
|
112
|
+
2. After driving, the app's errors: `adb logcat -d -v time --pid=$(adb shell pidof -s <package>) '*:E'`.
|
|
113
|
+
3. The JS layer: `adb logcat -d -v time -s ReactNativeJS:V`, plus Metro's own output.
|
|
114
|
+
4. The app is gone (no pid) → it crashed: `adb logcat -d -b crash`. A crash on a
|
|
115
|
+
claim's path fails that claim.
|
|
116
|
+
|
|
117
|
+
A LogBox or RedBox overlay is a finding: read it, record its message, then
|
|
118
|
+
dismiss it. A RedBox on a claim's path fails that claim. Everything found here
|
|
119
|
+
goes in the report's "Also seen", even when it belongs to another feature.
|
|
120
|
+
|
|
121
|
+
## 7. What the emulator can't prove
|
|
122
|
+
|
|
123
|
+
These claims get the **`device-only`** verdict, with the reason, and go on the
|
|
124
|
+
report's phone checklist. Never ✓, whatever the emulator showed:
|
|
125
|
+
|
|
126
|
+
| Claim touches | Why the emulator can't settle it |
|
|
127
|
+
|---|---|
|
|
128
|
+
| Haptics | no vibration hardware |
|
|
129
|
+
| Camera, QR scanning, biometrics | simulated sources, not the real sensor path |
|
|
130
|
+
| Push notification delivery | needs real FCM delivery on a signed-in device |
|
|
131
|
+
| Feel — scroll, animation smoothness, startup time | judged on the slowest device you support, on a release build |
|
|
132
|
+
| Sensors — GPS movement, motion, NFC, Bluetooth | mocked or absent |
|
|
133
|
+
|
|
134
|
+
The emulator can still verify the *surrounding* behaviour — the button that
|
|
135
|
+
triggers the haptic, the screen the scan result lands on. Split such a claim
|
|
136
|
+
in two rather than giving the whole thing one verdict.
|
|
137
|
+
|
|
138
|
+
## 8. When it goes wrong
|
|
139
|
+
|
|
140
|
+
Environmental failures are results, not things to retry into the ground. The
|
|
141
|
+
two-attempt ceiling from SKILL.md applies.
|
|
142
|
+
|
|
143
|
+
| Failure | Response |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `device offline` / `unauthorized` | one `adb reconnect`; still failing → report it |
|
|
146
|
+
| Emulator won't boot, or no AVD exists | report it with the next command to try; never kill an emulator you did not start |
|
|
147
|
+
| Metro port taken | report it; do not kill the process holding it |
|
|
148
|
+
| The app shows old behaviour | the binary is stale — Step 1's rebuild-first rule; record what you drove in the `Build` key |
|
|
149
|
+
| A tap does nothing | re-dump (part 5) and retry once; second miss → claim unchecked |
|
|
150
|
+
|
|
151
|
+
## 9. iOS
|
|
152
|
+
|
|
153
|
+
The core recipe is Android-only. It has not been verified against the iOS
|
|
154
|
+
simulator, so this file does not pretend to cover it. For an iOS claim: use
|
|
155
|
+
the driver rung (agent-device and mobile-mcp both drive the simulator) when
|
|
156
|
+
one is present; otherwise report the claim **unchecked** with the blocker
|
|
157
|
+
named — "no iOS driver; the core recipe is Android-only".
|
|
@@ -27,6 +27,37 @@ Also seen: <console errors, failed requests, off-feature breakage — or "nothin
|
|
|
27
27
|
<n> claims failed. <fix + re-verify note, or "all green">
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
A **native app run** (SKILL.md Step 1 detected a mobile app) adds two header
|
|
31
|
+
keys and one block, and has a fourth verdict:
|
|
32
|
+
|
|
33
|
+
```markdown
|
|
34
|
+
# Live verification: <change>
|
|
35
|
+
|
|
36
|
+
| | |
|
|
37
|
+
|---|---|
|
|
38
|
+
| Date | YYYY-MM-DD |
|
|
39
|
+
| Target | <package> on <device> via <rung: adb / agent-device / mobile-mcp> |
|
|
40
|
+
| Device | <emulator AVD + API level, or the physical model> |
|
|
41
|
+
| Build | JS only / rebuilt at <commit> (from finalize's Native line) |
|
|
42
|
+
| Diff | <branch or commit under test> |
|
|
43
|
+
| Themes | light ✓ dark ✓ |
|
|
44
|
+
|
|
45
|
+
| Claim | Evidence | Verdict |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| <behavior asserted, one line> | <file in this dir, or —> | ✓ / ✗ <what actually happened> |
|
|
48
|
+
| <hardware-bound behavior> | <file, or —> | device-only — <why the emulator can't show it> |
|
|
49
|
+
|
|
50
|
+
For the phone:
|
|
51
|
+
- [ ] <claim> — <what to do on the device> — passes when <what you observe>
|
|
52
|
+
|
|
53
|
+
Also seen: <logcat errors, LogBox/RedBox messages, Metro errors — or "nothing">
|
|
54
|
+
|
|
55
|
+
<n> failed · <m> device-only (on the phone list) · <k> verified. <fix + re-verify note>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`For the phone:` carries one checkbox per `device-only` row and is omitted
|
|
59
|
+
when there are none. A web run never shows `Device`, `Build`, or this block.
|
|
60
|
+
|
|
30
61
|
When nothing could be driven, the report is still written — an absent
|
|
31
62
|
`report.md` is indistinguishable from a run that never happened:
|
|
32
63
|
|
|
@@ -50,5 +81,6 @@ When nothing could be driven, the report is still written — an absent
|
|
|
50
81
|
|---|---|
|
|
51
82
|
| Everything a run produces lives inside its run dir — nothing at the verification root | Root-level orphans belonging to no run were observed in the wild; the dir is the unit of a run |
|
|
52
83
|
| Evidence files are named for the claim they support and referenced from the claim table | The table is the index — an evidence file it doesn't reference is uncontextualized in a week |
|
|
53
|
-
| Header keys are fixed: Date, Target, Diff, Themes (Themes only for UI surfaces) | Two runs of the same surface are diffable only when their headers line up |
|
|
84
|
+
| Header keys are fixed: Date, Target, Diff, Themes (Themes only for UI surfaces); a native app run adds Device and Build | Two runs of the same surface are diffable only when their headers line up |
|
|
85
|
+
| `device-only` is a verdict, not a pass — it never counts toward verified, and every one lands on the phone checklist | "Never report hardware validation that was not performed": a deferred check written as ✓ is read as done |
|
|
54
86
|
| Every run writes `report.md`, including runs where nothing could be driven | Absence of a report must mean absence of a run, nothing else |
|
package/skills/workflow/SKILL.md
CHANGED
|
@@ -151,7 +151,7 @@ UIs), the combined menu must still carry the full CP-1 option set.
|
|
|
151
151
|
|
|
152
152
|
| Option | What it does |
|
|
153
153
|
|---|---|
|
|
154
|
-
| **Verify it live** *(recommended when the change has a runnable surface)* | Load `live-verification` — drive the real UI or
|
|
154
|
+
| **Verify it live** *(recommended when the change has a runnable surface — an app on an emulator counts)* | Load the `live-verification` skill and follow it — including on a mobile app: drive the real UI, endpoint or emulator, check each claim against observed behaviour, and write its report |
|
|
155
155
|
| **Code review** *(recommended)* | `/code-review` the diff before merging |
|
|
156
156
|
| **Commit** | Load the `git-commit` skill if installed (conventional message from the diff, safe staging); otherwise follow the repo's commit conventions |
|
|
157
157
|
| **Cut a release** | Load the `release` skill if installed — machinery detection, dry-run plan, then tag → push → GitHub release; otherwise follow the repo's release conventions |
|
|
@@ -269,6 +269,7 @@ Stop if you catch yourself doing any of these:
|
|
|
269
269
|
| Silently skipping discovery on a LARGE task | Ask — it's a soft gate, not a free pass |
|
|
270
270
|
| Rewriting a test spec to make it pass | Stop and ask — never silently edit specs |
|
|
271
271
|
| Auto-running code-review, commits, or agents | They're checkpoint choices; run only when picked |
|
|
272
|
+
| Verifying live without loading `live-verification` | Load it — its `report.md` is the evidence (9 of 11 ad-hoc runs in a mobile eval left none) |
|
|
272
273
|
| Auto-advancing past a checkpoint on MEDIUM/LARGE | The user owns every transition |
|
|
273
274
|
| Expanding scope past the confirmed tier | Stop, report, re-confirm |
|
|
274
275
|
|