@jabworks/condux 0.25.1 → 0.26.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.25.1",
3
+ "version": "0.26.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": {
@@ -77,7 +77,7 @@ Tests fail
77
77
 
78
78
  ## Output Format
79
79
 
80
- The `Plan` line below only appears when no matching plan doc was found for the inferred feature slug — it's omitted entirely otherwise.
80
+ The `Plan` line below only appears when no matching plan doc was found for the inferred feature slug — it's omitted entirely otherwise. In a mobile app project a `Native` line joins `Env` (see Companion Files); the example below is a web project, so it has none.
81
81
 
82
82
  ```
83
83
  ## Finalize: [task or feature name]
@@ -119,6 +119,13 @@ until it breaks someone else's checkout.
119
119
  example file (`.env.example`, `.env.sample`, or whatever it uses) gains the
120
120
  same key in the same change — placeholder value only, never a real secret.
121
121
  - Report `Env ✓ n/a` when the diff adds none, so the check is visibly running.
122
+ - **Native (mobile app projects only).** None of the gates above compiles the
123
+ native layer, so a diff that touches it passes everything and still is not
124
+ in the app until it is rebuilt and reinstalled. Classify the diff as
125
+ `JS only` or `native rebuild` and report it as a `Native` line; on a native
126
+ rebuild, end "Ready to commit — native rebuild needed before it can run" and
127
+ name the project's rebuild command. The path list, the fingerprint check and
128
+ when to omit the line are in `references/native-change.md`.
122
129
 
123
130
  ## What Does NOT Happen
124
131
 
@@ -134,3 +141,4 @@ until it breaks someone else's checkout.
134
141
  ## See Also
135
142
 
136
143
  - `references/rationalization-table.md` — common rationalizations for skipping finalize and why they're wrong
144
+ - `references/native-change.md` — mobile apps: when a diff needs a native rebuild, the fingerprint check, the `Native` line
@@ -0,0 +1,106 @@
1
+ # Native-change check
2
+
3
+ A mobile app has two layers. JavaScript reloads in seconds; the native binary
4
+ (Kotlin/Swift, native modules, the compiled app config) only changes when the
5
+ app is **rebuilt and reinstalled**. None of the JS gates — typecheck, lint,
6
+ format, tests — compile the native layer, so a change that touches it can pass
7
+ every gate and still not exist in the app on the device. This check makes that
8
+ visible. It never blocks.
9
+
10
+ Its verdict is used in three places: finalize reports it, workflow mentions it
11
+ at tier confirmation, and live-verification acts on it before driving the app.
12
+
13
+ ## When it applies
14
+
15
+ Only in an app project: an `expo` or `react-native` dependency in
16
+ `package.json`, or a committed `android/` or `ios/` directory. Anywhere else,
17
+ omit the `Native` line entirely — a web repo gets no noise from it.
18
+
19
+ ## The verdict
20
+
21
+ Two outcomes. Name the escalation, lightest first:
22
+
23
+ | Verdict | Means | To see the change |
24
+ |---|---|---|
25
+ | **JS only** | Nothing in the diff reaches the binary | Fast Refresh or a JS reload; restart the app process if a native module is left in a bad state |
26
+ | **Native rebuild** | The diff touches something compiled into the binary | Rebuild the app (dev client or release build) and reinstall it; clear the app's data too when the change touches native state that persists across installs (notification channels, permissions, keychain entries, database schema created natively) |
27
+
28
+ ## How to decide
29
+
30
+ **Precise — when a recorded fingerprint exists.** Expo projects can hash
31
+ their native layer. If `.condux/native/fingerprint-<platform>.json` exists
32
+ (recorded after the last native build — see below), generate a fresh one the
33
+ same way and compare the two JSONs' `hash` fields:
34
+
35
+ ```bash
36
+ # with expo-updates installed — per platform, the same hash EAS uses:
37
+ npx expo-updates fingerprint:generate --platform android > .condux/native/now-android.json
38
+ # without it — covers both platforms at once:
39
+ npx @expo/fingerprint fingerprint:generate > .condux/native/now-all.json
40
+ ```
41
+
42
+ Equal hashes are **JS only**. Different hashes are **Native rebuild** — then
43
+ name what moved with
44
+ `npx @expo/fingerprint fingerprint:diff <recorded> <now>`. The `now-*` file is
45
+ overwritten on every check. Compare against the recording for the platform
46
+ you are building; a both-platforms fingerprint also moves on iOS-only changes,
47
+ so say which one you used. The fingerprint covers what a path list cannot
48
+ see — autolinked native modules inside `node_modules`, config-plugin output,
49
+ patches to native packages.
50
+
51
+ **Core — always available.** Otherwise, read the task's diff. Any of these
52
+ means **Native rebuild**:
53
+
54
+ - local native code: `modules/**` (Expo modules), any `.kt`, `.java`, `.swift`,
55
+ `.m`, `.mm`, `.cpp`, `.h` file, `*.podspec`, `build.gradle*`
56
+ - committed native projects: `android/**`, `ios/**` (if they are generated by
57
+ prebuild, the real change is upstream of them — find it)
58
+ - app config compiled into the binary: in `app.json` / `app.config.*`, the
59
+ `plugins`, `permissions`, `android`/`ios` blocks, `name`, `scheme`, `version`,
60
+ `runtimeVersion`, splash and icon assets; any config-plugin source file
61
+ - dependencies: a package added, removed or version-changed in `package.json`
62
+ that ships native code (it has an `android/` or `ios/` directory, or an
63
+ `expo-module.config.json`), and every Expo SDK or React Native upgrade
64
+ - patches: `patches/**` touching a native package, `cng-patches/**`
65
+ - `eas.json` build-profile changes that alter what is compiled
66
+
67
+ When a file's effect is unclear, say **Native rebuild** and name the file —
68
+ a wasted rebuild costs minutes; a verification against a stale binary costs
69
+ the whole verification.
70
+
71
+ **Project override.** If `AGENTS.md` lists the project's native paths or its
72
+ rebuild command, those win over the lists above.
73
+
74
+ ## Recording the fingerprint
75
+
76
+ The precise check needs a baseline, so whoever rebuilds and installs the app
77
+ records one straight after the install succeeds:
78
+
79
+ ```bash
80
+ mkdir -p .condux/native
81
+ npx expo-updates fingerprint:generate --platform android > .condux/native/fingerprint-android.json
82
+ # or, without expo-updates:
83
+ npx @expo/fingerprint fingerprint:generate > .condux/native/fingerprint-all.json
84
+ ```
85
+
86
+ It lives in `.condux/` (working state, gitignored) because it describes the
87
+ build installed on *this* machine's device or emulator, not the repository.
88
+ Only Expo projects record one — the fingerprint reads the Expo config, and
89
+ `npx` fetches the tool if it isn't installed. Bare React Native and native-only
90
+ projects use the core check alone.
91
+
92
+ ## Reporting
93
+
94
+ In finalize's output, beside `Env`:
95
+
96
+ ```
97
+ Native ✓ JS only (android fingerprint unchanged) — a reload shows it
98
+ Native ⚠ native rebuild — modules/app-lock/android/…/AppLockModule.kt, app.json plugins
99
+ not compiled by any gate; rebuild with `npx expo run:android` and reinstall before verifying
100
+ ```
101
+
102
+ Take the rebuild command from `AGENTS.md` or `package.json` scripts; if
103
+ neither names one, say "rebuild the app" and stop — never guess a build
104
+ command. On **Native rebuild**, finalize ends "Ready to commit — native rebuild
105
+ needed before it can run": the code is clean; the app just does not contain it
106
+ yet.
@@ -43,6 +43,15 @@ 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: rebuild first when the change is native.** If finalize's
47
+ `Native` line said *native rebuild* (or the diff touches the native layer —
48
+ see finalize's native-change check), the installed app does not contain the
49
+ change. Rebuild and reinstall it before driving anything, and clear the app's
50
+ data when the change touches native state that persists across installs. On
51
+ an Expo project, record the new fingerprint as that check describes. A verdict
52
+ driven on the old binary is a verdict on code that isn't there — if the
53
+ rebuild can't run here, stop and report that instead.
54
+
46
55
  ### Step 2 — Enumerate the claims
47
56
 
48
57
  Before touching the UI, write down what the change claims to do — one line
@@ -18,8 +18,8 @@ No under-planning for a cross-cutting feature.
18
18
  ## Live Context
19
19
 
20
20
  ```!
21
- git status --short
22
- git log --oneline -5
21
+ git status --short 2>/dev/null || echo "(not a git repository yet)"
22
+ git log --oneline -5 2>/dev/null || echo "(no commits yet)"
23
23
  ```
24
24
 
25
25
  ## Operating Rules
@@ -70,7 +70,11 @@ Every tier ends with `preflight` then `finalize` — no exceptions.
70
70
  ## The Router
71
71
 
72
72
  1. **Infer the tier.** How many files? Requirement clear or needs design? Crosses
73
- service/package boundaries? Unknowns needing exploration first?
73
+ service/package boundaries? Unknowns needing exploration first? In a mobile
74
+ app, also: does it touch the native layer (finalize's native-change check
75
+ lists what does)? That doesn't change the tier — a one-line Kotlin fix is
76
+ still SMALL — but say so when confirming, because nothing can verify it
77
+ until the app is rebuilt and reinstalled.
74
78
  2. **Spec lookup.** Detect the package root (walk up from CWD to git root, find the
75
79
  nearest `package.json` / `Cargo.toml` / `go.mod` / `pyproject.toml`). Check both
76
80
  scopes (deduplicate if identical):
@@ -106,6 +110,15 @@ Every tier ends with `preflight` then `finalize` — no exceptions.
106
110
  After the user picks, load **only** that skill, run it, then return to the nearest
107
111
  checkpoint and re-present the menu until the user chooses Done.
108
112
 
113
+ **When the question tool caps the options.** CP-1 and CP-3 have five rows, and
114
+ some hosts' question tools take four (Claude Code's AskUserQuestion does). The
115
+ first four rows go on buttons, recommended first. The fifth row rides in the
116
+ free-text slot the tool adds ("Other"), and the question text names it:
117
+ "Plan ready — how do we proceed? (or type 'revise' to rework the plan)" for
118
+ CP-1, "(or say done)" for CP-3. Never merge two rows into one button to make
119
+ room — "Use agents" for the two agent rows is exactly the erosion this rule
120
+ prevents. A host with no cap, or a plain-text menu, shows every row.
121
+
109
122
  ### CP-1 — Plan ready
110
123
 
111
124
  *After draft-plan sign-off (LARGE) or the inline plan (MEDIUM). Plan review already
@@ -248,6 +261,7 @@ Stop if you catch yourself doing any of these:
248
261
  | Tests / lint / typecheck mid-implementation | Save it all for `finalize` |
249
262
  | Spawning agents for a task you can just do | Default is to implement yourself |
250
263
  | Omitting the subagent options from a checkpoint menu | The default shapes the recommendation, never the menu — present every CP-1 row |
264
+ | Merging or dropping rows to fit a four-option question tool | Four rows on buttons, the fifth named in the question text and taken through "Other" |
251
265
  | Silently skipping discovery on a LARGE task | Ask — it's a soft gate, not a free pass |
252
266
  | Rewriting a test spec to make it pass | Stop and ask — never silently edit specs |
253
267
  | Auto-running code-review, commits, or agents | They're checkpoint choices; run only when picked |