@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 +18 -1
- package/README.md +209 -205
- package/apps/cli/src/haya-pet.js +64 -0
- package/apps/cli/test/haya-pet.test.mjs +41 -0
- package/apps/companion/README.md +2 -2
- package/apps/companion/src/main/index.js +2 -2
- package/apps/companion/src/main/tray-menu.js +4 -0
- package/apps/companion/src/renderer/index.html +1 -1
- package/apps/companion/test/tray-menu.test.mjs +5 -1
- package/apps/pet-preview/index.html +2 -2
- package/docs/architecture.md +9 -3
- package/docs/known-issues.md +58 -6
- package/docs/publishing.md +1 -1
- package/docs/troubleshooting.md +2 -1
- package/native/win-window-helper/Program.cs +1 -1
- package/package.json +23 -1
- package/packages/adapters/src/codex-guardian.js +131 -0
- package/packages/adapters/src/codex-hooks.js +11 -2
- package/packages/adapters/test/codex-guardian.test.mjs +174 -0
- package/packages/cli-core/src/codex-guardian-watcher.js +136 -0
- package/packages/cli-core/src/codex-rollout-fs.js +88 -0
- package/packages/cli-core/src/codex-transcript-watcher.js +2 -65
- package/packages/cli-core/test/codex-guardian-watcher.test.mjs +217 -0
- package/.github/workflows/ci.yml +0 -75
- package/.github/workflows/release.yml +0 -61
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes 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
|
-
#
|
|
3
|
+
# HAYA Pet
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Let your Codex Desktop pets follow you into every AI terminal
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
12
|
-
|
|
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
|
-

|
|
15
17
|
|
|
16
18
|
</div>
|
|
17
19
|
|
|
18
20
|
---
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## Why HAYA Pet Exists
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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
|
|
30
|
-
Claude Code
|
|
31
|
-
Antigravity
|
|
32
|
-
Aider
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
##
|
|
42
|
+
## The Candy
|
|
67
43
|
|
|
68
|
-
|
|
69
|
-
|
|
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> | **Session bubbles** — one per active session, with status icons.<br> |
|
|
74
|
-
| **Folder collapsed** — bubbles tucked away beside the pet.<br> | **Tray menu** — show/hide, pets, reset position, Quit.<br> |
|
|
54
|
+
## Quick Start
|
|
75
55
|
|
|
76
|
-
|
|
56
|
+
### 1. Install
|
|
77
57
|
|
|
78
|
-
|
|
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
|
-
|
|
64
|
+
From source:
|
|
92
65
|
|
|
93
|
-
|
|
66
|
+
```bash
|
|
67
|
+
git clone <repo-url> haya-pet
|
|
68
|
+
cd haya-pet
|
|
69
|
+
npm install
|
|
70
|
+
npm link
|
|
71
|
+
```
|
|
94
72
|
|
|
95
|
-
|
|
96
|
-
|---|---|
|
|
97
|
-
| **Node ≥ 18** | Runtime + companion (Electron) |
|
|
98
|
-
| **npm** | Install + scripts |
|
|
73
|
+
Prefer not to link globally? Use the CLI directly:
|
|
99
74
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
> degrades to lifecycle-only tracking).
|
|
75
|
+
```bash
|
|
76
|
+
node <repo>/apps/cli/src/haya-pet.js
|
|
77
|
+
```
|
|
104
78
|
|
|
105
|
-
|
|
79
|
+
### 2. Add A Pet
|
|
106
80
|
|
|
107
|
-
|
|
81
|
+
Put a Codex-compatible pet folder in `~/.codex/pets` or `~/.haya-pet/pets`.
|
|
108
82
|
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
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
|
-
|
|
117
|
-
|
|
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
|
-
|
|
123
|
-
`node <repo>/apps/cli/src/haya-pet.js`.
|
|
112
|
+
You can also switch pets from the tray menu.
|
|
124
113
|
|
|
125
|
-
|
|
114
|
+
### 3. Run Your AI Client Through HAYA Pet
|
|
126
115
|
|
|
127
|
-
|
|
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
|
|
132
|
-
haya-pet run --client claude-code
|
|
133
|
-
haya-pet run --client
|
|
134
|
-
|
|
135
|
-
|
|
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
|
|
139
|
-
|
|
140
|
-
|
|
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> | **Session bubbles** - one per active session, with status icons.<br> |
|
|
147
|
+
| **Folder collapsed** - bubbles tucked away beside the pet.<br> | **Tray menu** - show/hide, pets, reset position, quit.<br> |
|
|
141
148
|
|
|
142
|
-
|
|
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
|
-
|
|
151
|
+
HAYA Pet has two ideas of support:
|
|
147
152
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
160
|
-
|
|
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
|
|
168
|
-
haya-pet run --client
|
|
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
|
-
|
|
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
|
-
```
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
spritesheet.webp
|
|
181
|
+
```bash
|
|
182
|
+
haya-pet hooks status
|
|
183
|
+
haya-pet hooks off
|
|
209
184
|
```
|
|
210
185
|
|
|
211
|
-
|
|
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
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
##
|
|
210
|
+
## Pet Controls
|
|
223
211
|
|
|
224
212
|
| Action | Result |
|
|
225
213
|
|---|---|
|
|
226
|
-
| Single click |
|
|
227
|
-
| Double click |
|
|
228
|
-
| Drag |
|
|
229
|
-
| Drag corner grip |
|
|
230
|
-
| Double-click grip |
|
|
231
|
-
| Tray icon
|
|
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
|
-
##
|
|
221
|
+
## Commands
|
|
234
222
|
|
|
235
223
|
```bash
|
|
236
|
-
haya-pet
|
|
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
|
-
|
|
240
|
-
|
|
228
|
+
haya-pet pets # list installed pets
|
|
229
|
+
haya-pet pets use my-pet # select a pet
|
|
241
230
|
|
|
242
|
-
|
|
231
|
+
haya-pet hooks on # enable live-status hooks where supported
|
|
232
|
+
haya-pet hooks status
|
|
233
|
+
haya-pet hooks off
|
|
243
234
|
|
|
244
|
-
|
|
245
|
-
haya-pet
|
|
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
|
-
|
|
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
|
-
|
|
242
|
+
## Requirements
|
|
252
243
|
|
|
253
|
-
|
|
|
244
|
+
| Requirement | Why |
|
|
254
245
|
|---|---|
|
|
255
|
-
|
|
|
256
|
-
|
|
|
257
|
-
|
|
|
258
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
261
|
+
More fixes are in [docs/troubleshooting.md](docs/troubleshooting.md), including
|
|
262
|
+
repairing a broken Electron install.
|
|
266
263
|
|
|
267
|
-
|
|
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
|
-
|
|
276
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
281
|
-
screenshots, or session logs; it stores only short derived status summaries.
|
|
282
|
-
Approvals always require explicit user action.
|
|
283
|
+
## Contributing
|
|
283
284
|
|
|
284
|
-
|
|
285
|
+
Run the full test suite:
|
|
285
286
|
|
|
286
287
|
```bash
|
|
287
|
-
npm test
|
|
288
|
+
npm test
|
|
288
289
|
```
|
|
289
290
|
|
|
290
|
-
|
|
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 [
|
|
298
|
+
MIT. See [LICENSE](LICENSE).
|
package/apps/cli/src/haya-pet.js
CHANGED
|
@@ -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`
|