acbridge 1.2.0 → 1.4.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": "acbridge",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Control AC Bridge from any terminal: sign in, run the bridge, and drive smart-home devices and Profiles.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "AC BRIDGE LIMITED",
package/plugin/README.md CHANGED
@@ -23,11 +23,11 @@ Codex's `~/.codex/hooks.json` instead (§ below).
23
23
  | Path (under `plugin/`) | Role |
24
24
  |------------------------|------|
25
25
  | `.claude-plugin/marketplace.json` | Marketplace manifest — declares the marketplace `name: "bridge"` and lists its one plugin, `alexa` (`source: ./plugins/alexa`). |
26
- | `plugins/alexa/.claude-plugin/plugin.json` | Plugin manifest — `name: "alexa"`, `version 0.1.0`; declares a `channels` capability bound to the `alexa` MCP server. |
26
+ | `plugins/alexa/.claude-plugin/plugin.json` | Plugin manifest — `name: "alexa"`, `version 0.4.0`; declares a `channels` capability bound to the `alexa` MCP server. |
27
27
  | `plugins/alexa/.mcp.json` | MCP server definition — spawns the channel as `node ${CLAUDE_PLUGIN_ROOT}/dist/channel.mjs`. |
28
28
  | `plugins/alexa/hooks/hooks.json` | Registers the `PreToolUse` gate (`→ scripts/gate.mjs`) **plus** the Profiles session-state signals on `SessionStart`/`SessionEnd`/`UserPromptSubmit`/`Stop`/`StopFailure`/`Notification`/`PreToolUse[AskUserQuestion\|ExitPlanMode\|Workflow]`/`PostToolUse`/`PostToolUseFailure`/`SubagentStart`/`SubagentStop`/`PreCompact`/`PostCompact`/`PermissionDenied`/`TaskCompleted` (all `→ scripts/signal.mjs`). |
29
29
  | `plugins/alexa/scripts/gate.mjs` | The PreToolUse permission gate (below). |
30
- | `plugins/alexa/scripts/signal.mjs` | The Profiles session-state signal — maps each lifecycle hook → one of the 28 wire states (+ on every POST: a transcript-tail `context` reading and the raw **mode/model ferry** — the last `permission-mode` record + assistant model id, which the hub diffs into the mode/`modelChanged` states) → `POST /local/session/state`; successful tools → a state-less tick on `POST /local/session/context` (below). |
30
+ | `plugins/alexa/scripts/signal.mjs` | The Profiles session-state signal — maps each lifecycle hook → one of the 30 wire states (+ on every POST: a transcript-tail `context` reading and the raw **mode/model ferry** — the last `permission-mode` record + assistant model id, which the hub diffs into the mode/`modelChanged` states) → `POST /local/session/state`; successful tools → a state-less tick on `POST /local/session/context` (below). |
31
31
  | `plugins/alexa/scripts/statusline.mjs` | The statusline TEE — installed as Claude's `statusLine` command by `acbridge` (reversible; chains any existing statusline): POSTs the exact context % + rate-limit % + `model.id`/`display_name` to `/local/session/context` (the `usageHigh` data feed and the freshest `modelChanged` source), then renders. |
32
32
  | `plugins/alexa/scripts/codex-signal.mjs` | The Codex CLI sibling of `signal.mjs` (below) — installed into `~/.codex/hooks.json`, **not** this plugin's `hooks/hooks.json`. |
33
33
  | `plugins/alexa/dist/channel.mjs` | The bundled channel MCP server — **build artifact** copied from `../channel/` (gitignored; absent until built). |
@@ -179,9 +179,12 @@ Claude); the POST is bounded by a 2 s timeout.
179
179
  `scripts/codex-signal.mjs` is the Codex CLI sibling of `signal.mjs` above, for a repo bound to a
180
180
  **Codex** profile. It is installed by `acbridge setup` (`node-core/src/codex-setup/hooks.ts`,
181
181
  merge-safe/reversible — every foreign hook survives verbatim; off-switch `BRIDGE_CODEX_HOOKS=0` /
182
- `"autoCodexHooks": false`) directly into **Codex's own** `~/.codex/hooks.json`, registered against 9
182
+ `"autoCodexHooks": false`) directly into **Codex's own** `~/.codex/hooks.json`, registered against 10
183
183
  lifecycle events: `SessionStart`, `UserPromptSubmit`, `Stop`, `PermissionRequest`, `PreCompact`,
184
- `PostCompact`, `SubagentStart`, `SubagentStop`, `PostToolUse`. Codex requires a one-time in-TUI
184
+ `PostCompact`, `SubagentStart`, `SubagentStop`, `PostToolUse`, `SessionEnd` (the last is the 2026-08
185
+ addition — upstream Codex shipped the hook mid-2026; it is appended LAST so a document written by the
186
+ 9-event installer gains exactly one new key on re-run, and Codex keys hook trust per event, so it
187
+ ships untrusted until the user approves it via `/hooks`). Codex requires a one-time in-TUI
185
188
  `/hooks` review before a third-party hook actually runs — `acbridge setup` prints that reminder when
186
189
  it changes the file, since it can't bypass the gate.
187
190
 
@@ -197,26 +200,32 @@ suffix on a self-derived session. `PermissionRequest` is observe-and-abstain: cl
197
200
  device signal, but this script **never** writes to stdout (Codex reads a permission hook's stdout as
198
201
  an approve/deny decision).
199
202
 
200
- Codex has no `SessionEnd`/`Notification`/`StopFailure`/`PermissionDenied`/`TaskCompleted` hooks and
201
- no rate-limit data; this hook script reaches 17 states directly (the 16 originals plus `error`, from
202
- an error-shaped tool result on `PostToolUse`), and the adapter/voice surface reaches the rest of the
203
- 23-state codex mask — `CODEX_EVENTS` (`contracts/src/profiles.ts`, 23 of the 28 wire states) — which
204
- is exactly what the Codex profile editor offers. Same activation
203
+ Codex has no `Notification`/`StopFailure`/`PermissionDenied`/`TaskCompleted` hooks and no rate-limit
204
+ data; this hook script reaches 18 states directly (the 16 originals, plus `error` from an
205
+ error-shaped tool result on `PostToolUse`, plus `ended` from `SessionEnd`), and the adapter/voice
206
+ surface reaches the rest of the 24-state codex mask — `CODEX_EVENTS` (`contracts/src/profiles.ts`, 24
207
+ of the 30 wire states) — which is exactly what the Codex profile editor offers. Same activation
205
208
  ladder and fail-safes as `signal.mjs` (BRIDGE_* env → per-session handshake → self-derive when a hub
206
209
  is configured on this machine; `BRIDGE_AUTO_PROFILES=0` off-switch; any parse/IO/network error exits
207
- 0) — with one structural difference and one lifecycle gap, both recorded in
208
- [`../docs/reviews/XPLAT-2026-07-28.md`](../docs/reviews/XPLAT-2026-07-28.md):
209
-
210
- - **Local home + fixed port only.** Unlike `signal.mjs`, this script does **not** resolve the
211
- WSL↔Windows bridge home: it pins the local `~/.claude-bridge` (`BRIDGE_SECRET_DIR` aside) and the
212
- env/config `hubPort` — no `resolveBridgeHome()`, no beacon-port pickup, and no
213
- `hooks-last-error.json` breadcrumb on rejection. With the hub on the other side of a WSL↔Windows
214
- split (or bound off 8790 without a matching `config.json`), hook-lane Codex Profiles silently no-op.
215
- - **No `ended`, ever.** No Codex hook can produce the `ended` state (Codex ships no `SessionEnd`),
216
- and the hub keys Profile scene revert + arbiter stand-down on `ended` — so a hook-lane Codex session
217
- that exits leaves its scene applied and its arbiter claim held on a daemon-kept hub until the next
218
- session starts or the hub itself stops. The adapter lane (`acbridge run --agent codex`) does post
219
- `ended` and is unaffected.
210
+ 0), and — since the 2026-07-29 XPLAT-HOME fix — the same **bridge-home resolution** as its Claude
211
+ twins: `resolveBridgeHome()`, beacon-port-before-config ordering, and a `hooks-last-error.json`
212
+ breadcrumb on rejection. A hub on the other side of a WSL↔Windows split, or bound off 8790, is
213
+ therefore found rather than silently missed.
214
+
215
+ Two structural differences remain, and neither is a bug:
216
+
217
+ - **`started` is synthesized in the TUI.** Codex v0.146's TUI dispatches no `SessionStart` (live-
218
+ verified 2026-08-02: a TUI session sat open with zero hook dispatches while the same binary's
219
+ `codex exec` fired it), so the script synthesizes `started` from the first event it ever sees for a
220
+ session — POSTed before that event's own signal, audit-tagged `codex:SessionStart~synthesized`. The
221
+ start scene therefore fires with the first **message**, not at window-open. `exec` (and any future
222
+ TUI that dispatches `SessionStart` again) writes the handshake at start, so the workaround
223
+ self-disables.
224
+ - **The hub's 30-minute idle close is a BACKSTOP, not the close.** `SessionEnd` → `ended` is the real
225
+ close and runs scene revert + arbiter stand-down the moment Codex exits; the synthesized idle close
226
+ (`hub/src/devices/session-idle.ts`) covers abnormal exits, pre-`SessionEnd` Codex builds, and hook
227
+ entries not yet trusted via `/hooks`. The adapter lane (`acbridge run --agent codex`) posts `ended`
228
+ itself and never needed either.
220
229
 
221
230
  Full detail: [`../docs/CLAUDE-SIGNALS.md`](../docs/CLAUDE-SIGNALS.md) §7a.
222
231