@trolleroof/tui 0.2.3
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/README.md +349 -0
- package/dist/index.js +8404 -0
- package/overlay-release.json +4 -0
- package/package.json +48 -0
- package/scripts/build-overlay-web.ts +34 -0
- package/scripts/dev-harness.sh +81 -0
- package/scripts/dev-harness.test.sh +33 -0
- package/scripts/export-bc.ts +124 -0
- package/scripts/install-adapters.sh +192 -0
- package/scripts/install-adapters.test.sh +69 -0
- package/scripts/manage-hermes-hooks.py +39 -0
- package/scripts/materialize-agents-plugin.sh +85 -0
- package/scripts/overlay.test.ts +106 -0
- package/scripts/overlay.ts +385 -0
- package/scripts/plugin-update.test.ts +318 -0
- package/scripts/plugin-update.ts +378 -0
- package/scripts/preview-overlay.ts +153 -0
- package/scripts/run-plugin-update.test.ts +31 -0
- package/scripts/run-plugin-update.ts +65 -0
- package/scripts/version-bump.test.ts +76 -0
- package/scripts/version-bump.ts +89 -0
package/README.md
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# tui-gamepigeon
|
|
2
|
+
|
|
3
|
+
Play familiar single-player games in a lightweight HTML overlay while your agents work. Game engines are shared between the overlay and the recording pipeline so interaction traces stay game-agnostic when recording is enabled.
|
|
4
|
+
|
|
5
|
+
## Play
|
|
6
|
+
|
|
7
|
+
Build the overlay once, then launch the arcade menu or a specific game:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun install
|
|
11
|
+
bun run build:overlay # web bundle + native Tauri shell (needs Rust)
|
|
12
|
+
bun start # overlay menu
|
|
13
|
+
bun start snake # jump straight into Snake
|
|
14
|
+
# or after `bun run build`: gamepigeon / gamepigeon snake
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
In the overlay: arrow keys or WASD to move, `Enter` to select, `r` to restart, `Esc` or `q` to hide. Drag the top bar to move the window; use the expand control to resize it.
|
|
18
|
+
|
|
19
|
+
## Install: local vs. global
|
|
20
|
+
|
|
21
|
+
There are two ways to run the Arcade overlay. **Local** runs it straight from this
|
|
22
|
+
checkout for development. **Global** installs it once so the plain `claude` command
|
|
23
|
+
opens Arcade in every project.
|
|
24
|
+
|
|
25
|
+
Both need [Bun](https://bun.sh) (`>=1.3`), macOS 11+ or Windows 10+, and Rust only
|
|
26
|
+
when building the overlay binary from source.
|
|
27
|
+
|
|
28
|
+
### Local (from this checkout)
|
|
29
|
+
|
|
30
|
+
Build the overlay and wire the harness adapters to this working copy:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bun install
|
|
34
|
+
bun run build:overlay # overlay web bundle + native Tauri shell (needs Rust)
|
|
35
|
+
bun run install:adapters # installs Codex / Claude / OpenCode adapters -> this checkout
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Restart your harness. The generated adapters live at `~/.codex/skills/arcade`,
|
|
39
|
+
`~/.claude/skills/arcade`, and `~/.config/opencode/commands/arcade.md`; all execute
|
|
40
|
+
`scripts/overlay.ts` from this checkout.
|
|
41
|
+
|
|
42
|
+
For local harness development, one command builds the current checkout, replaces any
|
|
43
|
+
stale overlay, and points at the debug Tauri binary instead of the packaged release:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bun run claude:dev # Claude Code — loads this checkout via --plugin-dir .
|
|
47
|
+
bun run codex:dev # Codex — workspace plugin + $arcade adapter from this checkout
|
|
48
|
+
bun run antigravity:dev # Antigravity — .agents/plugins/ workspace plugin + agy
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Claude appears as `/tui-gamepigeon:arcade`. Codex uses the `$arcade` skill (or `/arcade` picker).
|
|
52
|
+
Antigravity picks up `.agents/plugins/tui-gamepigeon/` from the repo root. All three set
|
|
53
|
+
`GAMEPIGEON_SKIP_UPDATE_CHECK=1` so local dev is not fighting the release auto-updater.
|
|
54
|
+
|
|
55
|
+
To open the overlay directly without a harness:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bun run start # menu
|
|
59
|
+
bun run start 2048 # a specific game
|
|
60
|
+
bun run preview:overlay # browser preview at 470×650 (no Tauri)
|
|
61
|
+
bun run dev:overlay # rebuild web bundle + debug shell, then show
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Browser preview
|
|
65
|
+
|
|
66
|
+
Agents (and humans) can iterate on overlay layout without a Rust build:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bun run preview:overlay
|
|
70
|
+
# → http://127.0.0.1:4173/ (opens your browser)
|
|
71
|
+
bun run preview:overlay -- --game=connect4
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The preview frames the real overlay UI at the production sizes (**470×650** compact, **720×780** expanded). Titlebar **↗ / ↙** toggles the frame; Hide and Shutdown are no-ops in the browser. Open a game from the menu, or pass `--game=<id>` / use `?game=<id>` (optional `&variation=classic`).
|
|
75
|
+
|
|
76
|
+
### Global (installed once, works everywhere)
|
|
77
|
+
|
|
78
|
+
For Codex (or another supported harness), the one-command install is:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx -y bunx @trolleroof/tui@latest install --codex
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Replace `--codex` with `--claude`, `--opencode`, `--hermes`, `--openclaw`, or
|
|
85
|
+
`--all`. This uses npm to fetch Bun for the command, then writes the harness adapter.
|
|
86
|
+
Restart the harness when it finishes.
|
|
87
|
+
|
|
88
|
+
Install the plugin from the GitHub marketplace so the normal `claude` command runs
|
|
89
|
+
the lifecycle hooks in every project:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
claude plugin marketplace add Trolleroof/tui-gamepigeon
|
|
93
|
+
claude plugin install tui-gamepigeon@tui-gamepigeon --scope user
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Optionally enable Claude's marketplace refresh under `/plugin` → **Marketplaces** →
|
|
97
|
+
**tui-gamepigeon**, and point the status line at the Arcade update shim once:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
"statusLine": {
|
|
101
|
+
"type": "command",
|
|
102
|
+
"command": "bun ~/.gamepigeon/status-line.ts"
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The packaged plugin exposes `/tui-gamepigeon:arcade` and `/tui-gamepigeon:arcade-update`;
|
|
107
|
+
the standalone adapter provides Claude's shorter `/arcade`.
|
|
108
|
+
|
|
109
|
+
## Optional account
|
|
110
|
+
|
|
111
|
+
Arcade requires an account. On first launch the plugin opens the shared web login, where a new player can create an account or sign in with email, Google, or GitHub. Later launches reuse the private local session.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
gamepigeon auth signup
|
|
115
|
+
gamepigeon auth login
|
|
116
|
+
gamepigeon auth oauth google
|
|
117
|
+
gamepigeon auth oauth github
|
|
118
|
+
gamepigeon auth status
|
|
119
|
+
gamepigeon auth logout
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Production defaults to `https://runretroarcade.com/login.html`, `https://auth.runretroarcade.com`, and `https://api.runretroarcade.com`. Override them for local development with `GAMEPIGEON_LOGIN_URL`, `GAMEPIGEON_AUTH_URL`, and `GAMEPIGEON_BACKEND_URL`. The browser returns the Better Auth bearer to a localhost callback; it is stored in `auth.json` and atomically mirrored to `backend.conf`, both with user-only permissions. That same bearer authenticates `/v1/me`, trace uploads, and completed-game results. If that validation or an upload fails, Arcade marks the account chip **Sync paused** while keeping gameplay data queued locally. Logout clears both credentials without deleting local games or traces.
|
|
123
|
+
|
|
124
|
+
## Coding harness adapters
|
|
125
|
+
|
|
126
|
+
The bundled adapters give Codex CLI, Claude Code, and OpenCode the same Arcade launcher. GamePigeon opens a centered, borderless HTML overlay above the active desktop. It uses the operating system's installed webview through a small Tauri shell, not Chrome or Electron.
|
|
127
|
+
|
|
128
|
+
Requirements:
|
|
129
|
+
|
|
130
|
+
- Bun
|
|
131
|
+
- macOS 11+ or Windows 10+
|
|
132
|
+
- A packaged overlay binary, or Rust when building it from source
|
|
133
|
+
|
|
134
|
+
The overlay is a single-instance helper with no Dock icon on macOS and no taskbar or console entry on Windows. Hiding it keeps the game state alive; invoking Arcade again restores and centers the existing window. It works from regular terminals and does not require tmux, a browser, a local server, or an extra setup command after plugin installation.
|
|
135
|
+
|
|
136
|
+
Install the dependencies and all three harness adapters from this checkout:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
bun install
|
|
140
|
+
bun run build:overlay
|
|
141
|
+
bun run install:adapters
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Restart the harness after installation. In Claude Code, submitting any prompt opens or restores Arcade while Claude works. In Codex, invoke `$arcade` directly, or type `/arcade` to filter the picker and select **Arcade**. Claude Code and OpenCode receive a bare `/arcade` command. The packaged Claude plugin uses its required namespace: `/tui-gamepigeon:arcade`. Codex does not register custom top-level slash commands; its `/arcade` interaction is picker discovery for the `$arcade` skill, like other Codex skills.
|
|
145
|
+
|
|
146
|
+
For local harness development, one command builds the current checkout, replaces any stale overlay, and loads this repo instead of an installed copy:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
bun run claude:dev # Claude Code
|
|
150
|
+
bun run codex:dev # Codex CLI
|
|
151
|
+
bun run antigravity:dev # Antigravity (agy)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`SessionStart` snaps a still-running overlay back to the menu (without popping the window open) so a new session never resumes mid-game, `UserPromptSubmit` shows the overlay, `Stop` pauses it with an `Enter` shortcut back to the coding prompt, and `SessionEnd` shuts down the helper.
|
|
155
|
+
|
|
156
|
+
To enable the hooks for the normal `claude` command, install the GitHub marketplace once:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
claude plugin marketplace add Trolleroof/tui-gamepigeon
|
|
160
|
+
claude plugin install tui-gamepigeon@tui-gamepigeon --scope user
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Claude Code does not silently install plugin updates. Arcade uses a WOZ-style detect-and-nudge flow instead (see **Auto-updates** below).
|
|
164
|
+
|
|
165
|
+
The generated adapters live at `~/.codex/skills/arcade`, `~/.claude/skills/arcade`, and `~/.config/opencode/commands/arcade.md`; all execute `scripts/overlay.ts` from this checkout. The installer refuses to replace an unrelated command with the same name. Press `Esc` or `q` to hide the game, drag its top bar to move it, and use the expand button to resize it.
|
|
166
|
+
|
|
167
|
+
## Auto-updates
|
|
168
|
+
|
|
169
|
+
Arcade updates in three layers. Claude Code cannot silently install a new plugin package for you — the user still confirms the upgrade — but detection and overlay binaries are automatic.
|
|
170
|
+
|
|
171
|
+
1. **Detect + nudge (plugin scripts/hooks)**
|
|
172
|
+
On every new session, a `SessionStart` hook runs `scripts/plugin-update.ts --check`. It compares the installed plugin's `gitCommitSha` against `main` on GitHub. When they differ, it writes `~/.gamepigeon/update-available.json` and refreshes `~/.gamepigeon/status-line.ts`. The first prompt of the session also runs `--nudge`, which injects a reminder to run `/tui-gamepigeon:arcade-update`. Local directory marketplaces and `bun run claude:dev` (`GAMEPIGEON_SKIP_UPDATE_CHECK=1`) skip the check.
|
|
173
|
+
|
|
174
|
+
2. **Manual plugin upgrade**
|
|
175
|
+
Run `/tui-gamepigeon:arcade-update` (or the equivalent `claude plugin marketplace update tui-gamepigeon` + `claude plugin update tui-gamepigeon@tui-gamepigeon`). Then `/reload-plugins` or restart Claude Code so the new scripts load. The skill clears the update flag on success.
|
|
176
|
+
|
|
177
|
+
3. **Overlay binary download**
|
|
178
|
+
Overlay UI changes ship as new binaries. Pushing anything under `overlay/`, `tauri/`, `scripts/overlay*`, or the shared game code triggers the `Overlay` workflow, which builds and tests macOS and Windows binaries. Publishing is a separate, deliberate step: the workflow cuts a release only when `package.json`'s version names one that does not exist yet (see [Releasing](#releasing)). When it does, it publishes the binaries as `overlay-v<version>` and commits `overlay-release.json` pointing at it. On the next session, `scripts/overlay.ts` compares that manifest against `~/.gamepigeon/bin/current`, downloads the new binary (via `gh` for private repos, plain HTTPS once public), quits any overlay still running the old build, and launches the fresh one. Download failures fall back to the previously installed binary, so offline sessions keep working.
|
|
179
|
+
|
|
180
|
+
One-time status line setup (optional, but closest to the WOZ experience):
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
"statusLine": {
|
|
184
|
+
"type": "command",
|
|
185
|
+
"command": "bun ~/.gamepigeon/status-line.ts"
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Add that under `~/.claude/settings.json`. The shim is rewritten on each session check and does not hardcode a plugin cache path, so it stays valid across upgrades.
|
|
190
|
+
|
|
191
|
+
The repository also includes native plugin manifests for marketplace distribution. Local dev commands build the checkout and load it directly:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
bun run claude:dev # Claude Code — --plugin-dir .
|
|
195
|
+
bun run codex:dev # Codex — workspace plugin + adapter
|
|
196
|
+
bun run antigravity:dev # Antigravity — .agents/plugins/ at repo root
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Claude namespaces plugin-provided skills, so the packaged forms appear as `/tui-gamepigeon:arcade` and `/tui-gamepigeon:arcade-update`. The standalone adapter provides Claude's shorter `/arcade` form.
|
|
200
|
+
|
|
201
|
+
Codex CLI and OpenCode invoke the overlay through their Arcade adapter. Claude Code additionally exposes lifecycle hooks, which is why prompt-start and response-stop behavior is automatic there.
|
|
202
|
+
|
|
203
|
+
To bypass a harness and open the overlay directly:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
bun run start
|
|
207
|
+
bun run start 2048
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Launch games
|
|
211
|
+
|
|
212
|
+
| Game | Status | Controls |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| 2048 | ✅ playable | arrows/wasd slide |
|
|
215
|
+
| Tetris | ✅ playable | arrows move, z/x rotate, space drop |
|
|
216
|
+
| Snake | ✅ playable | arrows/wasd steer |
|
|
217
|
+
| Minesweeper | ✅ playable | arrows move, space reveal, f flag |
|
|
218
|
+
| Sokoban | ✅ playable | arrows push, z undo |
|
|
219
|
+
| Connect Four | ✅ playable | ←/→ aim, space drop |
|
|
220
|
+
| Sudoku | ✅ playable | arrows move, 1-9 place, 0/x clear |
|
|
221
|
+
|
|
222
|
+
## Interaction traces
|
|
223
|
+
|
|
224
|
+
The recording layer under `src/recording/` durably journals episodes under `~/.tui-gamepigeon/recordings/` and splits them into immutable upload chunks. Every schema-v2 event includes `event_id`, `user_id`, `chunk_id`, and `game_id`.
|
|
225
|
+
|
|
226
|
+
- Policy-visible events preserve input impulses, timing, score/reward changes, and episode completion.
|
|
227
|
+
- Privileged engine checkpoints and realized random effects support deterministic replay without leaking hidden state into policy input.
|
|
228
|
+
- Local writes continue when upload is disabled or temporarily unavailable; pending chunks retry on later sessions.
|
|
229
|
+
- Completed games also enter a separate durable score outbox. Quits, restarts, and client shutdowns never submit a score.
|
|
230
|
+
|
|
231
|
+
## Local score history
|
|
232
|
+
|
|
233
|
+
Every naturally completed overlay game appends one JSON object to
|
|
234
|
+
`~/.tui-gamepigeon/scores/history.jsonl`, even without a network connection.
|
|
235
|
+
The directory is user-only (`0700`) and the JSONL file is `0600`. Quits,
|
|
236
|
+
restarts, and shutdowns do not create entries.
|
|
237
|
+
|
|
238
|
+
Each schema-v1 row contains `game_id`, `game_type`, `variation_id`, `score`,
|
|
239
|
+
`success`, `completed_at` (the game-end timestamp), `duration_ms`, and
|
|
240
|
+
`platform`, plus the resulting `personal_best` and `high_score_updated`.
|
|
241
|
+
Personal bests are calculated per `game_type`; duplicate `game_id` writes are
|
|
242
|
+
idempotent.
|
|
243
|
+
|
|
244
|
+
The history is device-only today. A future remote score feature belongs in the
|
|
245
|
+
sync backend, not the auth Worker D1; it should merge records by `game_id` and
|
|
246
|
+
keep local logging independent of account and network availability.
|
|
247
|
+
|
|
248
|
+
Set the opaque per-user bearer token issued by Retro Backend. Requests default
|
|
249
|
+
to the sync backend at `https://api.runretroarcade.com`; set
|
|
250
|
+
`GAMEPIGEON_BACKEND_URL` only when targeting local or staging infrastructure:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
export GAMEPIGEON_BACKEND_TOKEN=retro_...
|
|
254
|
+
# optional override:
|
|
255
|
+
# export GAMEPIGEON_BACKEND_URL=http://127.0.0.1:8787
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The HTML overlay journals each seeded action sequence in local storage, rebuilds replay-safe schema-v2 engine-state traces at episode end, and hands immutable chunks plus completed-game results to Tauri. Tauri validates and durably queues them before any network call, then resolves the canonical `/v1/me` user and drains both outboxes in the background. Chunks live under `~/.tui-gamepigeon/recordings/overlay-pending/` until `/v1/game-event-chunks` accepts them; results live under `~/.tui-gamepigeon/recordings/results/overlay-pending/` until `/v1/game-results` accepts them. Interrupted and offline sessions recover on the next launch, while cloud-acknowledged payloads move to the matching `overlay-completed/` directory.
|
|
259
|
+
|
|
260
|
+
Export policy-visible human demonstrations into leakage-safe BC splits:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
bun run export:bc -- --output ./bc-dataset
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The exporter reads completed terminal and overlay chunks by default, joins each human control to its referenced observation and outcome across chunk boundaries, drops environment actions and no-op controls, and writes `train.jsonl`, `validation.jsonl`, `test.jsonl`, and `manifest.json`. Splits are deterministic by `game_id`, keeping every episode in only one split. Use repeatable `--input <file-or-directory>` arguments for backend downloads or `--include-noops` when those actions are intentionally part of the policy.
|
|
267
|
+
|
|
268
|
+
Before recording, the client finishes local recovery and resolves the token's canonical user through `GET /v1/me`. It uploads only trace chunks and results owned by that user; pending data from another local account is left untouched. If configured identity lookup fails, gameplay starts without recording that episode and retries identity on later games and drains. `GAMEPIGEON_INGEST_URL` and `GAMEPIGEON_INGEST_API_KEY` are deprecated compatibility aliases retained through `0.x` and scheduled for removal in `1.0`. They do not opt into the default backend: a legacy key set without `GAMEPIGEON_INGEST_URL` leaves sync disabled rather than uploading to `https://api.runretroarcade.com`.
|
|
269
|
+
|
|
270
|
+
This repository owns the client-side producer and versioned wire contracts. The ingestion service, score database, queue consumers, and object-storage archive live in the backend repository. The v1 and v2 request fixtures under `contracts/` can be reused by that backend's contract tests.
|
|
271
|
+
|
|
272
|
+
## Analytics
|
|
273
|
+
|
|
274
|
+
Basic product analytics (DAU / feature usage) via PostHog are separate from interaction traces, which are for policy training rather than usage metrics.
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
export POSTHOG_API_KEY=phc_...
|
|
278
|
+
# optional, defaults to https://us.i.posthog.com
|
|
279
|
+
export POSTHOG_HOST=https://us.i.posthog.com
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Without `POSTHOG_API_KEY` set, analytics calls are no-ops — gameplay is never affected. Events currently captured: `app.opened`, `account.signed_up`, `account.signed_in`, `game.started`, `game.ended`. Signed-in events use the account's pseudonymous user ID; guest events use an anonymous per-install ID stored at `~/.tui-gamepigeon/device_id`.
|
|
283
|
+
|
|
284
|
+
The PostHog SDK batches events with its defaults, uses the CloudEvent ID as `$insert_id` for retry deduplication, and flushes during graceful shutdown.
|
|
285
|
+
|
|
286
|
+
Product events use a CloudEvents 1.0 envelope with `specversion`, `id`, `source`, `type`, `time`, `datacontenttype`, optional `subject`, and typed `data`. Client events default to source `/tui-gamepigeon/client`; plugin, website, and backend producers use their own source. Event IDs reuse the recording layer's `evt_` identifier format.
|
|
287
|
+
|
|
288
|
+
| Funnel | Event types | Allowed data |
|
|
289
|
+
| --- | --- | --- |
|
|
290
|
+
| Awareness | `site.visited` | `referrer_host`, `campaign` |
|
|
291
|
+
| Acquisition | `account.signed_up`, `account.signed_in` | `method` |
|
|
292
|
+
| Activation | `game.started`, `game.ended` | `game_type`, `variation_id`, outcome, score, success |
|
|
293
|
+
| Retention | `app.opened`, gameplay events | `app_version`, platform, gameplay data |
|
|
294
|
+
| Revenue | `payment.succeeded` | `plan`, `currency`, `amount_minor` |
|
|
295
|
+
| Referral | `referral.created`, `referral.redeemed` | channel |
|
|
296
|
+
| Plugin lifecycle | `plugin.launched`, `plugin.reattached`, `agent.task_completed` | harness |
|
|
297
|
+
|
|
298
|
+
The website owns `site.visited`; invite and payment services own their corresponding events. Until those producers exist, the names above reserve the shared contract without fabricating client events. Analytics must never include terminal frames, trajectories, prompts, repository contents, credentials, email addresses, or raw provider payloads.
|
|
299
|
+
|
|
300
|
+
The live [GamePigeon AARRR client dashboard](https://us.posthog.com/project/434929/dashboard/1866662) covers the client-owned acquisition, activation, and retention signals. See [`docs/analytics.md`](docs/analytics.md) for event ownership, saved insights, and the CLI verification runbook.
|
|
301
|
+
|
|
302
|
+
## Architecture
|
|
303
|
+
|
|
304
|
+
- `src/index.ts` — thin CLI: `gamepigeon` opens the overlay; `gamepigeon auth` handles accounts.
|
|
305
|
+
- `src/core/game.ts` — gym-style `Game` interface every title implements (`reset(seed)` / `step(action)` / `state()`), shared by the overlay and recorder.
|
|
306
|
+
- `src/core/rng.ts` — seedable PRNG (mulberry32) for reproducible episodes.
|
|
307
|
+
- `src/games/*/` — pure game engines (unit-tested); HTML rendering lives in `overlay/renderers.ts`.
|
|
308
|
+
- `src/recording/` — causal events, durable chunks, recovery, and upload transport.
|
|
309
|
+
- `src/results/` — completed-game result outbox, recovery, and score delivery.
|
|
310
|
+
- `src/sync/` — authoritative backend identity and the single-flight upload coordinator.
|
|
311
|
+
- `src/analytics/posthog.ts` — PostHog Node client wrapper for product analytics.
|
|
312
|
+
- `scripts/overlay.ts` — launcher, release download, and harness hook entry point.
|
|
313
|
+
- `overlay/` — bundled HTML/CSS/TypeScript frontend and deterministic local game session.
|
|
314
|
+
- `tauri/` — single-instance native shell with hidden Dock/taskbar presence.
|
|
315
|
+
|
|
316
|
+
## Development
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
bun run test
|
|
320
|
+
bun run test:adapters
|
|
321
|
+
bun run test:launcher
|
|
322
|
+
bun run typecheck
|
|
323
|
+
bun run build # emits dist/, exposes the `gamepigeon` bin
|
|
324
|
+
bun run build:overlay:web # overlay bundle only
|
|
325
|
+
bun run preview:overlay # browser preview (470×650 / 720×780 frame)
|
|
326
|
+
bun run dev:overlay # debug Tauri shell + show overlay
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Bun runs the TypeScript source directly in development and builds a Bun-targeted executable for distribution.
|
|
330
|
+
|
|
331
|
+
## Releasing
|
|
332
|
+
|
|
333
|
+
Releases are gated on the version, not on commits. Pushing to `main` builds and tests the overlay but publishes nothing; a release appears only when `package.json`'s version names one that has no release yet. This keeps routine pushes from minting a release each time.
|
|
334
|
+
|
|
335
|
+
To cut one, bump the version and push:
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
bun run version:bump # 0.2.1 -> 0.2.2
|
|
339
|
+
bun run version:bump minor # 0.2.1 -> 0.3.0
|
|
340
|
+
bun run version:bump major # 0.2.1 -> 1.0.0
|
|
341
|
+
bun run version:bump 1.4.0 # explicit
|
|
342
|
+
bun run version:bump --no-commit
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
The version lives in four manifests — `package.json`, `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, and `.claude-plugin/marketplace.json` — and the script rewrites all of them together. Bump by hand and they drift, which is why `scripts/version-bump.test.ts` asserts they agree.
|
|
346
|
+
|
|
347
|
+
The script commits but never pushes; publishing stays an explicit action. On the next push to `main`, CI builds the binaries, publishes them as `overlay-v<version>`, and commits an `overlay-release.json` pointing at that tag, which is what installed plugins download on their next session.
|
|
348
|
+
|
|
349
|
+
Adding a new file that carries the version means adding it to `VERSION_FILES` in `scripts/version-bump.ts`, or it silently stops being bumped.
|