@hayasaka7/haya-pet 0.2.4 → 0.2.6

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/CHANGELOG.md CHANGED
@@ -1,12 +1,29 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to Haya Pet are documented here. This project adheres to
3
+ All notable changes to HAYA Pet are documented here. This project adheres to
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
6
  > Note: some entries originally drafted under 0.2.0 actually landed *after* the
7
7
  > 0.2.0 npm publish; they are listed under 0.2.1, which is the first version that
8
8
  > ships them.
9
9
 
10
+ ## [0.2.6]
11
+
12
+ ### Fixed
13
+ - **Codex "Approve for me" no longer shows a false *waiting for approval*.**
14
+ With `approvals_reviewer = auto_review` (the TUI's "Approve for me"; legacy
15
+ config alias `guardian_subagent`), Codex routes approval requests to a
16
+ guardian subagent and never prompts the user — but its `PermissionRequest`
17
+ hook still fires when the request is created, so the pet sat on *waiting for
18
+ approval* for the entire auto-review (and the approved command's run). A new
19
+ guardian-review watcher tails the guardian's own session rollout (the only
20
+ persisted trace of the review) and reports event-backed states instead:
21
+ *reviewing* while the guardian assesses, *running tools* on an `allow`
22
+ verdict, *thinking* on a `deny` (the rejection goes back to the model — no
23
+ human decision is pending). When the reviewer is the user (`approvals_reviewer
24
+ = "user"`, "Ask for approval"), nothing changes: *waiting for approval* still
25
+ shows until the user decides.
26
+
10
27
  ## [0.2.4]
11
28
 
12
29
  ### Fixed
package/README.md CHANGED
@@ -1,294 +1,298 @@
1
1
  <div align="center">
2
2
 
3
- # 🐾 Haya Pet
3
+ # HAYA Pet
4
4
 
5
- ### One desktop companion for all your AI terminal agents
5
+ ### Let your Codex Desktop pets follow you into every AI terminal
6
6
 
7
- A transparent, draggable desktop pet that reflects what your AI CLIs are doing —
8
- Codex, Claude Code, Antigravity, Aider, or any command through one shared
9
- runtime with client adapters.
7
+ HAYA Pet is a local desktop companion for Codex, Claude Code, Antigravity,
8
+ Aider, Gemini CLI, and almost any command-line AI client. It was inspired by
9
+ Codex Desktop pets, but fixes the part that hurts: pets generated for Codex
10
+ Desktop should not be trapped inside Codex Desktop.
10
11
 
11
- <!-- HERO SCREENSHOT: drop a wide shot at docs/screenshots/hero.png
12
- (the pet on the desktop with a couple of session bubbles) -->
12
+ Drop in a Codex-compatible pet, wrap your AI CLI with `haya-pet run`, and the
13
+ same little character can watch all your agent sessions from one always-on-top
14
+ overlay.
13
15
 
14
- ![Haya Pet on the desktop](docs/screenshots/hero.png)
16
+ ![HAYA Pet on the desktop](docs/screenshots/hero.png)
15
17
 
16
18
  </div>
17
19
 
18
20
  ---
19
21
 
20
- ## What is this?
22
+ ## Why HAYA Pet Exists
21
23
 
22
- Most "desktop pet for an AI tool" projects build one pet per tool. Haya Pet does
23
- the opposite: it is **one AI Terminal Pet Runtime** that many AI clients plug
24
- into through adapters.
24
+ Codex Desktop made AI pets feel personal. The problem is portability: once a pet
25
+ is generated there, it is useful only there.
25
26
 
26
- You might be running several agents at once:
27
+ HAYA Pet turns those pet assets into a shared runtime for the AI tools you
28
+ actually use day to day:
27
29
 
28
30
  ```text
29
- Codex CLI backend repo
30
- Claude Code frontend repo
31
- Antigravity CLI → infra repo
32
- Aider docs repo
31
+ Codex CLI -> backend work
32
+ Claude Code -> frontend work
33
+ Antigravity -> infra work
34
+ Aider / Gemini -> docs, scripts, experiments
35
+ Any command -> still gets a session bubble
33
36
  ```
34
37
 
35
- Haya Pet watches all of them and presents one ambient interface:
36
-
37
- - **One global pet** — reflects the selected or most urgent AI session; clickable,
38
- draggable, and position-persistent like a real desktop companion.
39
- - **Session bubbles** — one compact bubble per active session showing client,
40
- project, the latest activity, and a status icon (a spinning *working* circle, a
41
- green *done* check, a yellow *needs you*, or a red *failed* cross). Bubbles stack
42
- by connect time — the newest session on top — so the stack never reshuffles while
43
- work is in progress. A folder button beside the pet folds them away.
44
-
45
- ## Features
46
-
47
- - 🪟 **Transparent, frameless, always-on-top overlay** that doesn't steal focus and
48
- stays click-through outside the pet and bubbles.
49
- - 🖱️ **Click / double-click / drag** — click folds/unfolds the bubbles, double-click
50
- expands them, drag moves the pet (position persists; bubbles stay on-screen).
51
- - 📏 **Resizable pet** — hover the pet and drag the corner grip to scale it
52
- 0.5×–2× for your screen; double-click the grip to reset. The size persists.
53
- - 🟢 **Live session bubbles** with per-session status icons and a folder toggle.
54
- - 🧠 **Normalized state model** — every client maps to a shared state vocabulary
55
- (`thinking`, `running_tool`, `waiting_approval`, `reviewing`, `failed`, …).
56
- - 🧩 **Client adapters** with tiered support (process wrapper → PTY observer →
57
- client hooks) so the daemon never bakes in client-specific logic. Default is
58
- lifecycle status; richer status is opt-in (Claude Code / Codex hooks via
59
- `haya-pet hooks on`, or PTY `--observe` for any client).
60
- - 🚀 **Zero-setup launch** — `haya-pet run …` auto-starts the overlay; no separate
61
- daemon to manage.
62
- - 🖼️ **Codex-compatible pet assets** (1536×1872 sprite atlas, 9 actions).
63
- - 🔒 **Local-only & private** — no prompts, files, or screenshots leave your machine.
64
- - 🪟🍎🐧 **Cross-platform** core with per-OS adapters for IPC and windowing.
38
+ Instead of one pet per app, you get **one pet for your whole AI workspace**. It
39
+ reacts to the selected or most urgent session, while compact bubbles show what
40
+ each running client is doing.
65
41
 
66
- ## Screenshots
42
+ ## The Candy
67
43
 
68
- <!-- Drop each PNG into docs/screenshots/ with the filename shown (~800px wide).
69
- Delete any row you don't have a shot for. -->
44
+ - **Bring your Codex Desktop pets with you.** HAYA Pet scans `~/.codex/pets`, so
45
+ Codex-compatible pet folders can be reused without rebuilding the character.
46
+ - **Use one pet across many AI clients.** Codex and Claude Code get richer
47
+ live-status hooks; everything else can connect through the generic wrapper.
48
+ - **See all active agents at a glance.** Session bubbles show client, project,
49
+ latest activity, and status: working, done, needs attention, or failed.
50
+ - **Keep your terminal native.** The default wrapper preserves normal terminal
51
+ input. No broken Shift+Tab just to make the pet move.
52
+ - **Stay local.** HAYA Pet does not upload prompts, files, screenshots, or logs.
70
53
 
71
- | | |
72
- |---|---|
73
- | **The global pet** — reacting to the highest-priority session.<br>![Pet overlay](docs/screenshots/pet-overlay.png) | **Session bubbles** — one per active session, with status icons.<br>![Session bubbles](docs/screenshots/session-bubbles.png) |
74
- | **Folder collapsed** — bubbles tucked away beside the pet.<br>![Folder collapsed](docs/screenshots/folder-collapsed.png) | **Tray menu** — show/hide, pets, reset position, Quit.<br>![Tray menu](docs/screenshots/tray-menu.png) |
54
+ ## Quick Start
75
55
 
76
- ## Documentation
56
+ ### 1. Install
77
57
 
78
- | Doc | What's in it |
79
- |---|---|
80
- | **This README** | Install + users' guide |
81
- | [docs/architecture.md](docs/architecture.md) | How it works, components, project structure, adapter tiers, platform matrix, native helpers, roadmap |
82
- | [docs/publishing.md](docs/publishing.md) | Releasing to npm (the tag → publish workflow) |
83
- | [docs/troubleshooting.md](docs/troubleshooting.md) | Common fixes, incl. repairing a broken Electron install |
84
- | [docs/known-issues.md](docs/known-issues.md) | Deferred issues with known root causes |
85
- | [docs/cross-os-qa.md](docs/cross-os-qa.md) | Cross-OS test matrix |
86
- | [apps/companion/README.md](apps/companion/README.md) | Companion (Electron) internals |
87
- | [PROGRESS.md](PROGRESS.md) | Detailed development log |
58
+ From npm, when available:
88
59
 
89
- ---
60
+ ```bash
61
+ npm install -g @hayasaka7/haya-pet
62
+ ```
90
63
 
91
- # Users' Guide
64
+ From source:
92
65
 
93
- ## Requirements
66
+ ```bash
67
+ git clone <repo-url> haya-pet
68
+ cd haya-pet
69
+ npm install
70
+ npm link
71
+ ```
94
72
 
95
- | Requirement | Why |
96
- |---|---|
97
- | **Node ≥ 18** | Runtime + companion (Electron) |
98
- | **npm** | Install + scripts |
73
+ Prefer not to link globally? Use the CLI directly:
99
74
 
100
- > Default status is lifecycle-only and needs no extra modules. Opt-in Claude Code /
101
- > Codex hooks (`haya-pet hooks on`) also need none. The opt-in `--observe` PTY mode uses
102
- > `node-pty` (installed automatically when it can build; without it, `--observe`
103
- > degrades to lifecycle-only tracking).
75
+ ```bash
76
+ node <repo>/apps/cli/src/haya-pet.js
77
+ ```
104
78
 
105
- ## Install
79
+ ### 2. Add A Pet
106
80
 
107
- **From npm** *(once published recommended for users):*
81
+ Put a Codex-compatible pet folder in `~/.codex/pets` or `~/.haya-pet/pets`.
108
82
 
109
- ```bash
110
- npm install -g @hayasaka7/haya-pet # exposes the `haya-pet` command globally
83
+ On Windows, HAYA Pet also checks `%USERPROFILE%\.codex\pets` and
84
+ `%LOCALAPPDATA%\haya-pet\pets`.
85
+
86
+ ```text
87
+ ~/.codex/pets/my-pet/
88
+ pet.json
89
+ spritesheet.webp
111
90
  ```
112
91
 
113
- **From source** *(current):*
92
+ Minimal `pet.json`:
93
+
94
+ ```json
95
+ {
96
+ "id": "my-pet",
97
+ "name": "My Pet",
98
+ "spritesheet": "spritesheet.webp"
99
+ }
100
+ ```
101
+
102
+ The spritesheet format is the Codex-compatible atlas used by this project:
103
+ 1536 x 1872 pixels, 8 columns x 9 rows, 192 x 208 per frame.
104
+
105
+ Choose the pet:
114
106
 
115
107
  ```bash
116
- git clone <repo-url> haya-pet
117
- cd haya-pet
118
- npm install
119
- npm link # makes `haya-pet` available everywhere
108
+ haya-pet pets
109
+ haya-pet pets use my-pet
120
110
  ```
121
111
 
122
- Prefer not to link globally? Call it directly anywhere you'd type `haya-pet`:
123
- `node <repo>/apps/cli/src/haya-pet.js`.
112
+ You can also switch pets from the tray menu.
124
113
 
125
- ## Run an AI session
114
+ ### 3. Run Your AI Client Through HAYA Pet
126
115
 
127
- Just wrap any command. **The first `haya-pet run` auto-starts the pet overlay**
128
- there's nothing to launch first:
116
+ The first `haya-pet run` starts the overlay automatically.
129
117
 
130
118
  ```bash
131
- haya-pet run --client codex -- codex
132
- haya-pet run --client claude-code -- claude
133
- haya-pet run --client generic -- aider
134
- # Windows / PowerShell example:
135
- haya-pet run --client generic -- powershell -Command "Start-Sleep 10"
119
+ haya-pet run --client codex
120
+ haya-pet run --client claude-code
121
+ haya-pet run --client antigravity
122
+
123
+ # Any other CLI:
124
+ haya-pet run --client generic -- aider
125
+ haya-pet run --client generic -- gemini
126
+ haya-pet run --client generic -- your-ai-command --with --args
136
127
  ```
137
128
 
138
- A **session bubble** appears while the command runs (client · project · status),
139
- and the pet reflects the highest-priority session. On exit the bubble briefly
140
- shows success (a green check) or failure (a red cross), then fades.
129
+ A bubble appears for the session. When the command exits, the bubble shows
130
+ success or failure briefly, then fades.
131
+
132
+ ## What You Get On Screen
133
+
134
+ | Surface | What it does |
135
+ |---|---|
136
+ | Global pet | Reacts to the highest-priority session and can be dragged anywhere. |
137
+ | Session bubbles | One bubble per running AI session, ordered by connect time. |
138
+ | Folder button | Folds the bubbles away when you want a cleaner desktop. |
139
+ | Tray menu | Show/hide, display mode, installed pets, reset position, and quit. |
140
+ | Resize grip | Hover the pet, drag the corner, and keep the size you like. |
141
+
142
+ ## Screenshots
143
+
144
+ | | |
145
+ |---|---|
146
+ | **The global pet** - reacting to the highest-priority session.<br>![Pet overlay](docs/screenshots/pet-overlay.png) | **Session bubbles** - one per active session, with status icons.<br>![Session bubbles](docs/screenshots/session-bubbles.png) |
147
+ | **Folder collapsed** - bubbles tucked away beside the pet.<br>![Folder collapsed](docs/screenshots/folder-collapsed.png) | **Tray menu** - show/hide, pets, reset position, quit.<br>![Tray menu](docs/screenshots/tray-menu.png) |
141
148
 
142
- > If the overlay can't be started (e.g. Electron is missing), your command still
143
- > runs normally and keeps its exit code — you just won't see the pet. Disable
144
- > auto-start with `HAYA_PET_NO_AUTOSTART=1`, or launch it yourself with `haya-pet start`.
149
+ ## Supported Clients
145
150
 
146
- ### Live activity status
151
+ HAYA Pet has two ideas of support:
147
152
 
148
- `haya-pet run` uses **native passthrough by default** the CLI talks directly to
149
- your terminal, so every input mode (Shift+Tab, mouse wheel, word-edit) works
150
- exactly as it does without the wrapper. Out of the box, every client shows
151
- **lifecycle status** (a session bubble while it runs; success/failure from the
152
- real exit code, never from scraping "error" out of output).
153
+ - **Connection support:** the client can be wrapped and shown as a session.
154
+ - **Live-status support:** the pet can react to in-session states like thinking,
155
+ editing files, running tools, or waiting for approval.
153
156
 
154
- ```bash
155
- haya-pet run --client claude-code -- claude # full fidelity, lifecycle status
156
- haya-pet run --client codex -- codex # full fidelity, lifecycle status
157
- ```
157
+ | Client | Works today | Best mode |
158
+ |---|---:|---|
159
+ | Codex CLI | Yes | Wrapper + opt-in hooks, with transcript-based tool activity |
160
+ | Claude Code | Yes | Wrapper + opt-in hooks |
161
+ | Antigravity | Yes | Wrapper lifecycle |
162
+ | Aider | Yes | Generic wrapper |
163
+ | Gemini CLI | Yes | Generic wrapper |
164
+ | Any other command | Yes | Generic wrapper, optional `--observe` |
158
165
 
159
- Two **opt-in** ways to get richer *in-session* status (thinking / running tools /
160
- editing files / waiting for approval):
166
+ Default behavior is intentionally conservative: HAYA Pet shows lifecycle status
167
+ without changing how the terminal behaves. Richer live status is opt-in.
168
+
169
+ ## Live Status
170
+
171
+ For Codex and Claude Code, enable hooks once:
161
172
 
162
173
  ```bash
163
- # Claude Code AND Codex — live status via per-session hooks, NO terminal-fidelity
164
- # tradeoff. Enable once (persisted, global); the first run for each client shows a
165
- # one-time "review hooks" prompt you approve once.
166
174
  haya-pet hooks on
167
- haya-pet run --client claude-code -- claude
168
- haya-pet run --client codex -- codex
169
- # (per-run override without persisting: HAYA_PET_HOOKS=1 …, or $env:HAYA_PET_HOOKS=1 in PowerShell)
170
- # (turn back off: haya-pet hooks off · check: haya-pet hooks status)
171
-
172
- # Any client — coarse live status by watching output through a PTY.
173
- haya-pet run --observe --client codex -- codex
175
+ haya-pet run --client codex
176
+ haya-pet run --client claude-code
174
177
  ```
175
178
 
176
- > **Codex coverage.** Codex shows `thinking` (working) and `idle` (done) via hooks,
177
- > plus `running_tool` / `editing_files` via a session-transcript watcher.
178
- > *Waiting for approval* doesn't arrive yet because of an upstream gap where
179
- > Codex's `PermissionRequest` hook doesn't fire
180
- > ([openai/codex#16732](https://github.com/openai/codex/issues/16732)); it'll start
181
- > working automatically once Codex fixes it. Also: if you pass your own
182
- > `-p/--profile` to codex, haya-pet skips hook injection (Codex allows one
183
- > profile) and tells you. Claude Code has full coverage.
184
-
185
- > **Approval prompts resolve correctly** (Claude Code): deny → the pet returns to
186
- > idle the moment the denial lands in the session transcript; accept a command →
187
- > the pet flips to *working* a couple of seconds after the approved command
188
- > actually starts running (detected from the client's process tree — a real
189
- > event, never a timeout, so an unanswered prompt keeps warning until you decide).
190
-
191
- > **Why opt-in?**
192
- > - **Hooks (Claude Code / Codex):** injecting hooks makes the client show a
193
- > one-time *review hooks* trust prompt. We don't disrupt your session by default;
194
- > turn it on once with `haya-pet hooks on` when you're happy to approve the hooks.
195
- > - **`--observe` (any client):** PTY observation infers status from output, but on
196
- > Windows it routes input through ConPTY, which can break **Shift+Tab**, mouse
197
- > scroll, and word-edit. Use it only for non-interactive runs. See
198
- > [docs/known-issues.md](docs/known-issues.md).
199
-
200
- ## Add and choose a pet
201
-
202
- A pet is a folder with `pet.json` and a 1536×1872 sprite atlas (8×9 cells of
203
- 192×208). Drop it into a search path:
179
+ Check or disable the setting:
204
180
 
205
- ```text
206
- ~/.codex/pets/my-pet/ (Windows: %USERPROFILE%\.codex\pets\my-pet\)
207
- pet.json { "id": "my-pet", "name": "My Pet", "spritesheet": "spritesheet.webp" }
208
- spritesheet.webp
181
+ ```bash
182
+ haya-pet hooks status
183
+ haya-pet hooks off
209
184
  ```
210
185
 
211
- Pets are discovered from `~/.codex/pets` and `~/.haya-pet/pets`. Then choose one:
186
+ Why opt in? Both clients show a one-time trust prompt when hooks are added. HAYA
187
+ Pet lets you decide when to approve that instead of surprising you in the middle
188
+ of work.
189
+
190
+ Codex live status combines three sources: hooks report `thinking`/`idle` and
191
+ approval requests, a transcript watcher reports tool/file activity, and a
192
+ guardian-review watcher tracks Codex's **"Approve for me"** auto-reviewer — the
193
+ pet shows *reviewing* while the guardian assesses a request and only shows
194
+ *waiting for approval* when Codex actually asks you ("Ask for approval" mode).
195
+ Per-tool `PreToolUse` hooks still depend on an upstream Codex gap
196
+ ([openai/codex#16732](https://github.com/openai/codex/issues/16732)); the
197
+ transcript watcher covers that in the meantime.
198
+
199
+ For any client, you can ask HAYA Pet to infer rough activity from terminal
200
+ output:
212
201
 
213
202
  ```bash
214
- haya-pet pets # list installed pets (* = selected)
215
- haya-pet pets use my-pet # select; remembered on every launch
203
+ haya-pet run --observe --client generic -- aider
216
204
  ```
217
205
 
218
- Your choice is stored and reused every time. You can also pick from the tray menu
219
- **Installed Pets**. Without a spritesheet, the pet renders labelled placeholder
220
- frames so everything still works.
206
+ Use `--observe` only when you accept the PTY tradeoff. On Windows, ConPTY can
207
+ break special input such as Shift+Tab, mouse scroll, and word-edit. The default
208
+ non-observe mode keeps terminal input native.
221
209
 
222
- ## Interact with the pet
210
+ ## Pet Controls
223
211
 
224
212
  | Action | Result |
225
213
  |---|---|
226
- | Single click | waves + folds/unfolds the session bubbles |
227
- | Double click | jumps + expands the bubbles |
228
- | Drag | moves the pet; position is saved (bubbles follow, always on-screen) |
229
- | Drag corner grip | resizes the pet 0.5×–2× (grip appears on hover); size is saved |
230
- | Double-click grip | resets the pet to its normal size |
231
- | Tray icon menu | show/hide, display mode, sessions, pets, **reset position**, **Quit** |
214
+ | Single click | Wave and fold or unfold session bubbles. |
215
+ | Double click | Jump and expand session bubbles. |
216
+ | Drag | Move the pet; position is saved. |
217
+ | Drag corner grip | Resize from 0.5x to 2x; size is saved. |
218
+ | Double-click grip | Reset to normal size. |
219
+ | Tray icon | Open menu for display, sessions, pets, reset, and quit. |
232
220
 
233
- ## Stop / exit the pet
221
+ ## Commands
234
222
 
235
223
  ```bash
236
- haya-pet stop # ask the running overlay to quit
237
- ```
224
+ haya-pet run --client codex # launch Codex with a pet session
225
+ haya-pet run --client claude-code # launch Claude Code with a pet session
226
+ haya-pet run --client generic -- aider # wrap any other command
238
227
 
239
- …or **right-click the tray icon → Quit**. `haya-pet stop` is a no-op if nothing is
240
- running, so it's always safe to call.
228
+ haya-pet pets # list installed pets
229
+ haya-pet pets use my-pet # select a pet
241
230
 
242
- ## Manage the overlay
231
+ haya-pet hooks on # enable live-status hooks where supported
232
+ haya-pet hooks status
233
+ haya-pet hooks off
243
234
 
244
- ```bash
245
- haya-pet start # start the overlay explicitly (usually unnecessary — run auto-starts it)
246
- haya-pet stop # quit it
235
+ haya-pet start # start the overlay explicitly
236
+ haya-pet stop # stop the overlay
247
237
  ```
248
238
 
249
- ## Troubleshooting
239
+ If the overlay cannot start, the wrapped command still runs and keeps its real
240
+ exit code. Disable auto-start with `HAYA_PET_NO_AUTOSTART=1`.
250
241
 
251
- Common fixes:
242
+ ## Requirements
252
243
 
253
- | Symptom | Fix |
244
+ | Requirement | Why |
254
245
  |---|---|
255
- | `haya-pet: command not found` | Install globally, or `npm link` in a source checkout. |
256
- | Pet doesn't react to a session | Launch via `haya-pet run …`; check `HAYA_PET_NO_AUTOSTART` isn't set. |
257
- | Pet shows a blue placeholder box | No spritesheet — add a pet (above). |
258
- | Pet is off-screen | Tray menu **Reset Position**. |
259
- | Can't exit | `haya-pet stop` or tray → **Quit**. |
246
+ | Node 18 or newer | Runtime and Electron companion. |
247
+ | npm | Install, link, and test scripts. |
248
+ | Electron | Installed as a runtime dependency. |
249
+ | node-pty | Optional; used only for `--observe`. |
260
250
 
261
- Full list (incl. repairing a broken Electron install): [docs/troubleshooting.md](docs/troubleshooting.md).
251
+ ## Troubleshooting
262
252
 
263
- ---
253
+ | Symptom | Fix |
254
+ |---|---|
255
+ | `haya-pet: command not found` | Install globally, or run `npm link` from this repo. |
256
+ | No pet appears for a session | Start the AI client through `haya-pet run ...`. |
257
+ | Pet shows a placeholder | Add a pet folder with both `pet.json` and `spritesheet.webp`. |
258
+ | Pet is off-screen | Use tray menu -> **Reset Position**. |
259
+ | Overlay will not exit | Run `haya-pet stop` or tray menu -> **Quit**. |
264
260
 
265
- ## Supported clients
261
+ More fixes are in [docs/troubleshooting.md](docs/troubleshooting.md), including
262
+ repairing a broken Electron install.
266
263
 
267
- | Client | Status | Support level |
268
- |---|---|---|
269
- | Generic CLI | ✅ | L1 process wrapper (+ L2 PTY via `--observe`) |
270
- | Codex | ✅ | L1 wrapper + **L4 live-status hooks** (opt-in `haya-pet hooks on`; partial — see note) |
271
- | Claude Code | ✅ | L1 wrapper + **L4 live-status hooks** (opt-in `haya-pet hooks on`) |
272
- | Antigravity | ✅ | L1 wrapper (+ L2 PTY via `--observe`) |
273
- | Gemini CLI / Aider / others | 🔜 | via the generic adapter |
264
+ ## Privacy
274
265
 
275
- (See [docs/architecture.md](docs/architecture.md) for the support tiers and the
276
- platform matrix, and [CHANGELOG.md](CHANGELOG.md) for release notes.)
266
+ HAYA Pet is local-only by default. It does not upload prompts, files,
267
+ screenshots, or session logs. The overlay stores only local state needed for
268
+ pet selection, position, size, and short derived status summaries.
277
269
 
278
- ## Privacy
270
+ ## Documentation
271
+
272
+ | Doc | What it covers |
273
+ |---|---|
274
+ | [docs/architecture.md](docs/architecture.md) | Runtime design, adapter tiers, platform matrix, roadmap. |
275
+ | [docs/publishing.md](docs/publishing.md) | Release and npm publishing flow. |
276
+ | [docs/troubleshooting.md](docs/troubleshooting.md) | Common failures and repair steps. |
277
+ | [docs/known-issues.md](docs/known-issues.md) | Current limitations and upstream gaps. |
278
+ | [docs/cross-os-qa.md](docs/cross-os-qa.md) | Cross-OS QA checklist. |
279
+ | [apps/companion/README.md](apps/companion/README.md) | Electron companion internals. |
280
+ | [assets/fallback-pet/README.md](assets/fallback-pet/README.md) | Bundled fallback pet details. |
281
+ | [PROGRESS.md](PROGRESS.md) | Development log. |
279
282
 
280
- Haya Pet is local-only by default. It does **not** upload prompts, files,
281
- screenshots, or session logs; it stores only short derived status summaries.
282
- Approvals always require explicit user action.
283
+ ## Contributing
283
284
 
284
- ## Contributing & tests
285
+ Run the full test suite:
285
286
 
286
287
  ```bash
287
- npm test # runs the full suite (TDD; tests live in **/test/*.test.mjs)
288
+ npm test
288
289
  ```
289
290
 
290
- See [docs/architecture.md](docs/architecture.md) to find your way around the code.
291
+ The codebase is organized as one npm package with internal packages under
292
+ `packages/` and apps under `apps/`. Start with
293
+ [docs/architecture.md](docs/architecture.md) if you want to add a client adapter,
294
+ touch the overlay, or work on pet rendering.
291
295
 
292
296
  ## License
293
297
 
294
- See [`LICENSE`](LICENSE).
298
+ MIT. See [LICENSE](LICENSE).
@@ -9,6 +9,7 @@ import { injectClaudeHooks as defaultInjectClaudeHooks } from "../../../packages
9
9
  import { injectCodexHooks as defaultInjectCodexHooks } from "../../../packages/cli-core/src/codex-hook-injection.js";
10
10
  import { watchClaudeTranscript as defaultWatchClaudeTranscript } from "../../../packages/cli-core/src/claude-transcript-watcher.js";
11
11
  import { watchCodexTranscript as defaultWatchCodexTranscript } from "../../../packages/cli-core/src/codex-transcript-watcher.js";
12
+ import { watchCodexGuardianReviews as defaultWatchCodexGuardianReviews } from "../../../packages/cli-core/src/codex-guardian-watcher.js";
12
13
  import { ensureCompanionConnection } from "../../../packages/cli-core/src/companion-launcher.js";
13
14
  import { createIpcClient as defaultCreateIpcClient } from "../../../packages/daemon-core/src/ipc-server.js";
14
15
  import { getDefaultPaths } from "../../../packages/platform-core/src/paths.js";
@@ -128,6 +129,8 @@ async function runRunCommand(parsed, dependencies) {
128
129
  const injectCodexHooks = dependencies.injectCodexHooks ?? defaultInjectCodexHooks;
129
130
  const watchClaudeTranscript = dependencies.watchClaudeTranscript ?? defaultWatchClaudeTranscript;
130
131
  const watchCodexTranscript = dependencies.watchCodexTranscript ?? defaultWatchCodexTranscript;
132
+ const watchCodexGuardianReviews =
133
+ dependencies.watchCodexGuardianReviews ?? defaultWatchCodexGuardianReviews;
131
134
  const print = dependencies.print ?? defaultPrint;
132
135
  const env = dependencies.env ?? process.env;
133
136
  const now = dependencies.now ?? Date.now;
@@ -251,6 +254,50 @@ async function runRunCommand(parsed, dependencies) {
251
254
  watcher.stop();
252
255
  previousStopWatcher();
253
256
  };
257
+
258
+ // With "Approve for me" (approvals_reviewer=auto_review, legacy alias
259
+ // guardian_subagent), Codex routes approval requests to a guardian
260
+ // subagent and never shows the human approval UI — yet the
261
+ // PermissionRequest hook still fires at request creation, which used to
262
+ // pin the pet on a false "waiting for approval" for the whole review.
263
+ // The guardian's own rollout is the only observable record of the
264
+ // review, so tail it: a review turn starting proves the agent is
265
+ // reviewing; an "allow" verdict proves the action proceeds; a "deny"
266
+ // verdict goes back to the model, which keeps working. An unreadable
267
+ // verdict reports nothing — a pending cue is never cleared on a guess.
268
+ const guardianWatcher = watchCodexGuardianReviews({
269
+ homeDir: dependencies.homeDir,
270
+ sessionsRoot: dependencies.codexSessionsRoot,
271
+ startedAt: now(),
272
+ onReviewEvent: (event) => {
273
+ hookDebugLog(env, now, {
274
+ source: "codex_guardian",
275
+ event: event.type,
276
+ outcome: event.outcome
277
+ });
278
+
279
+ const report = resolveGuardianStateReport(event);
280
+ if (!report) {
281
+ return;
282
+ }
283
+ messageSender
284
+ .send({
285
+ type: "state",
286
+ sessionId,
287
+ state: report.state,
288
+ summary: report.summary,
289
+ confidence: 0.85,
290
+ source: "client_log",
291
+ updatedAt: now()
292
+ })
293
+ .catch(() => {});
294
+ }
295
+ });
296
+ const stopWithoutGuardian = stopWatcher;
297
+ stopWatcher = () => {
298
+ guardianWatcher.stop();
299
+ stopWithoutGuardian();
300
+ };
254
301
  }
255
302
  }
256
303
 
@@ -276,6 +323,23 @@ async function runRunCommand(parsed, dependencies) {
276
323
  }
277
324
  }
278
325
 
326
+ // Map a guardian review event to the pet state it proves. waiting_approval is
327
+ // deliberately NOT among these: with the guardian reviewing, the user is not
328
+ // being asked anything, and after a deny the request is resolved (the model
329
+ // receives the rejection and continues) — there is no pending human decision.
330
+ function resolveGuardianStateReport(event) {
331
+ if (event.type === "review_started") {
332
+ return { state: "reviewing", summary: "agent reviewing approval" };
333
+ }
334
+ if (event.type === "review_finished" && event.outcome === "allow") {
335
+ return { state: "running_tool", summary: "reviewer approved" };
336
+ }
337
+ if (event.type === "review_finished" && event.outcome === "deny") {
338
+ return { state: "thinking", summary: "reviewer denied" };
339
+ }
340
+ return undefined;
341
+ }
342
+
279
343
  // Resolve whether live-status hooks should be injected for this run (any
280
344
  // hook-capable client). Precedence: HAYA_PET_NO_HOOKS forces off, HAYA_PET_HOOKS
281
345
  // forces on (per-run overrides), otherwise the persisted `haya-pet hooks on/off`