superdario 1.6.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eventually Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # Super Dario
2
+
3
+ Claude's pixel mascot in a Super Mario flavoured endless runner for your terminal.
4
+ Stomp bugs, bonk ? blocks, jump the pipes, duck under ghosts, collect gold tokens and
5
+ chase the global high score.
6
+ It plugs into Claude Code: every prompt you send opens Dario in a fresh terminal
7
+ tab so you can play while Claude works, and the HUD tells you when Claude is done
8
+ or needs your input.
9
+
10
+ ```
11
+ DARIO TOKENS 7 SCORE 00412 HI 01230 CLAUDE: working...
12
+
13
+ ▄▄ ▄▄▄▄
14
+ ▄███▄ ▀▀▀ ▄██████▄
15
+ ▐█ ▀ █▌ ▀ █▀▀█ ▀
16
+ ▀█▄█▀ ▀▀ ▀▀
17
+ █ █ ▄▄██▄▄
18
+ ─────────────────────────────────────────────────────────────────────────────
19
+ SPACE / UP jump DOWN / S duck P pause Q quit
20
+ ```
21
+
22
+ ## Requirements
23
+
24
+ - macOS (the "open a new terminal" part uses Warp and iTerm as a new tab in the active window; a new window in Terminal.app, Ghostty, WezTerm, kitty, Alacritty, Tabby and Rio; or the integrated terminal of Cursor, VS Code, VS Code Insiders, VSCodium, Windsurf, Kiro and Trae through a tiny launcher extension)
25
+ - Node.js >= 22.18 (runs TypeScript directly, no build step, no runtime dependencies)
26
+
27
+ ## Install
28
+
29
+ ```sh
30
+ curl -fsSL https://dario-xxx.web.app/install.sh | sh # downloads ~/.dario/app, runs the first-run wizard, wires Claude Code
31
+ dario update # later: fetch the newest release from the site
32
+ ```
33
+
34
+ Or from npm (the package is `superdario`, the command is still `dario`):
35
+
36
+ ```sh
37
+ npm install -g superdario && dario install # stable global install; update with npm install -g superdario@latest
38
+ npx superdario install # one-shot: copies itself to ~/.dario/app first, since the npx cache gets pruned
39
+ ```
40
+
41
+ From a source checkout instead:
42
+
43
+ ```sh
44
+ cd dario
45
+ npm install # only dev tooling for typecheck/tests
46
+ ./bin/dario install # hooks into ~/.claude/settings.json, links ~/.claude/skills/dario and ~/.local/bin/dario
47
+ ```
48
+
49
+ Releases are built with `scripts/build_release.sh` (writes `web/dl/dario-<version>.tgz`, `dario-latest.tgz`, `version.json`) and published with `firebase deploy --only hosting`.
50
+
51
+ `dario install` is idempotent and only adds/removes its own entries.
52
+ `dario uninstall` reverses everything.
53
+
54
+ ## Play
55
+
56
+ ```sh
57
+ dario # play in the current terminal
58
+ dario launch # open a new tab/window and play there
59
+ dario stop # close the running game
60
+ dario scores # high score, token totals, games played
61
+ dario ranking # global leaderboard (Firebase) and your rank
62
+ dario name Bob # change the name shown on the leaderboard (asked once on first play)
63
+ dario mode pro # PRO CODER: play only while the agent works (vibe = any time, the default)
64
+ dario status # running? hooks installed? auto-launch? Claude state?
65
+ ```
66
+
67
+ Controls: hold `RIGHT`/`D` to run and release to stop (a tiny helper reads the physical key state on macOS, so this works in every terminal), `LEFT`/`A` walks back (the camera never scrolls back), `SPACE`/`UP`/`W` jump, `DOWN`/`S` duck (fast-fall in the air), `P` pause, `R` restart, `Q`/`ESC` quit. Nothing moves until you run; enemies still walk toward you.
68
+
69
+ You start with 3 lives (shown as `LIVES ♥♥♥` in the HUD; lost ones turn into dots). Touching an enemy costs one: the mascot hops back and blinks
70
+ for a moment, and the run only ends when the last life goes. Some ? blocks pop a red heart instead of
71
+ their logo; grabbing it adds a life (up to 9), credited to the sponsor when it came out of their block ("+1 LIFE by FIGMA").
72
+
73
+ Score grows with distance; each coin is worth 25 points (there is no separate token counter). Landing on a bug squishes
74
+ it for +100, hitting a blinking ? block from below pops out a mushroom (+200 points) or a sponsor's
75
+ logo (+300 points, +100 more each time, shown as "+300 by FIGMA"), and you can stand on blocks. Pipes must be jumped, mid-height
76
+ ghosts ducked (or jumped with perfect timing), high ghosts run under.
77
+
78
+ ## Modes
79
+
80
+ `dario mode vibe` (default, **VIBE CODER**) lets you play whenever you like. `dario mode pro` (**PRO CODER**) only lets
81
+ the mascot run while Claude / Codex / Grok is actually working on a prompt: the start, resume and restart keys are
82
+ locked otherwise ("PRO CODER: plays only while CLAUDE is working"), the game pauses itself the moment the agent
83
+ finishes or needs you, and resumes on its own with the next prompt. The mode is also in the in-game settings panel (C).
84
+
85
+ ## Characters
86
+
87
+ You play as the agent you launched from: the Claude Code hook starts the game as
88
+ **Claude**, `CODEX_HOME`/`CODEX_SANDBOX` in the environment means **Codex**, `GROK_CLI`
89
+ means **Grok**. The other two agents are the walking enemies you stomp. Force it with
90
+ `dario play --as codex`, `dario launch --as grok` or persistently `dario character grok`
91
+ (`auto` restores detection).
92
+
93
+ ## Claude Code integration
94
+
95
+ | Hook | What happens |
96
+ | ------------------ | -------------------------------------------------------------------------------- |
97
+ | `UserPromptSubmit` | writes `working` to `~/.config/dario/claude_status.json`, opens Dario if not running |
98
+ | `Stop` | writes `done`: the game shows **CLAUDE IS DONE - go check your prompt!** |
99
+ | `Notification` | permission / idle prompts write `attention`: **CLAUDE NEEDS YOUR INPUT** |
100
+ | `PreToolUse` / `PostToolUse` | write the running tool ("Bash · npm test", "Edit · game.ts") so the HUD shows live activity; between tools it cycles Claude-Code-style thinking verbs |
101
+
102
+ The hook scripts return immediately (the work runs in the background) and print
103
+ nothing, so prompts are never delayed and no context is injected.
104
+
105
+ When Claude is done or needs input the game pauses itself, and the hook brings
106
+ the app you prompted from back to the front (captured when the prompt was sent).
107
+ If that app was Warp it also presses Cmd+Shift+[ to return to the previous tab,
108
+ which needs Accessibility permission for the app running the hook.
109
+
110
+ ```sh
111
+ dario focus off # keep playing; do not switch apps when Claude finishes
112
+ dario off # stop opening the game on every prompt (hooks stay installed)
113
+ dario on # resume
114
+ dario terminal iterm # force a terminal app or IDE; `dario terminal --list` shows what is installed here
115
+ dario ide cursor # install the Dario Launcher extension and open the game inside the IDE's integrated terminal
116
+ # (cursor | vscode | vscode_insiders | vscodium | windsurf | kiro | trae)
117
+ ```
118
+
119
+ ## Codex CLI and Grok Build
120
+
121
+ The same hooks exist for OpenAI's Codex CLI and xAI's Grok Build, and the game then plays as
122
+ Codex or Grok with the other agents as enemies. `dario install` writes them automatically when
123
+ it finds `~/.codex` or `~/.grok`; `dario agents` shows the state, `dario agents codex` /
124
+ `dario agents grok` add them later and `dario agents codex off` removes them.
125
+
126
+ | Agent | Where the hooks go | Events |
127
+ | ---------- | ------------------------------- | ---------------------------------------------------------------------- |
128
+ | Codex CLI | `~/.codex/hooks.json` | `UserPromptSubmit`, `Stop`, `PermissionRequest` (attention), `PreToolUse`, `PostToolUse` |
129
+ | Grok Build | `~/.grok/hooks/dario.json` | `UserPromptSubmit`, `Stop`, `Notification` (matcher `permission_prompt\|idle_prompt`), `PreToolUse`, `PostToolUse` |
130
+
131
+ Codex only runs hooks you have trusted: open Codex, type `/hooks` and approve the Dario entries once.
132
+ Grok Build also executes Claude Code's `settings.json` hooks in its compatibility mode; the Dario
133
+ scripts detect that (`GROK_HOOK_EVENT`) and either defer to the Grok hook file or report the event as Grok,
134
+ so the game is never opened twice. `CODEX_HOME` / `GROK_HOME` are honoured when set.
135
+
136
+ The `/dario` skill (linked into `~/.claude/skills/dario`) lets you ask Claude to
137
+ open the game, read scores, or toggle auto-launch from the chat.
138
+
139
+ ## Global ranking
140
+
141
+ Scores are submitted to Firestore (project `dario-xxx`) after every game (VIBE and PRO keep separate boards: `highScore` / `proHighScore`) using an
142
+ anonymous Firebase session stored in `~/.config/dario/auth.json`. No SDK: plain
143
+ `fetch` against the Firestore and Identity Toolkit REST APIs. Security rules
144
+ (`firebase/firestore.rules`) let anyone read the board, let only the owner write
145
+ their own document, and never let a high score go down. Deploy rules with
146
+ `firebase deploy --only firestore:rules`.
147
+
148
+ ## Website and sponsors
149
+
150
+ `web/` is a static site on Firebase Hosting (https://dario-xxx.web.app): landing page,
151
+ live leaderboard (VIBE / PRO tabs), an autoplay demo of the real engine (`web/demo.js`, built from `src/demo` with
152
+ `scripts/build_demo.sh`) and the sponsor flow. Three tiers, all paid through Polar:
153
+
154
+ - **In-game mystery box sponsor** (30 days, pay what you like from $29): the amount paid becomes the sponsor's
155
+ `priority`, so higher amounts rank higher: more ? boxes and always the first box of a run.
156
+ - **Banner sponsor** ($69.90 per day) and **ranking sponsor** ($29.90 per day): booked per UTC day on a 30-day
157
+ calendar (`/api/sponsor/slots` lists free / held / booked days). Checkout holds the chosen days for 30 minutes
158
+ (`sponsor_slots`), `order.paid` confirms them, and the game shows the sponsor whose `days` include today.
159
+
160
+ After paying, sponsors upload an image that is shrunk to the tier grid (token 16×12 drawn with sextant glyphs into the 8×8 block, banner 66×20),
161
+ reduced to 8 colors and editable pixel by pixel with a terminal-accurate preview.
162
+
163
+ `functions/` holds the Cloud Functions (Node 22): `sponsorCheckout` creates the pending sponsor (holding its days)
164
+ and the Polar checkout, `polarWebhook` activates it on `order.paid` (Standard Webhooks verified, idempotent per order,
165
+ stores the amount as `priority`, confirms the days), `sponsorState` and `sponsorLogo` serve the edit page behind a
166
+ per-sponsor key, `sponsorSlots` serves the calendar. Firestore: `sponsors` (public when active), `sponsor_private`,
167
+ `sponsor_slots` (public). `priority` can also be edited in the console; ties go to whoever paid first. Non-secret parameters live in `functions/.env`
168
+ (see `.env.example`); tokens are Secret Manager secrets:
169
+
170
+ ```sh
171
+ firebase functions:secrets:set POLAR_ACCESS_TOKEN
172
+ firebase functions:secrets:set POLAR_WEBHOOK_SECRET
173
+ firebase deploy --only functions,hosting,firestore:rules
174
+ ```
175
+
176
+ In the game, active sponsors are fetched once an hour. A **mystery box** sponsor's logo (or a heart) pops out
177
+ of the ? boxes and pays points when grabbed; they are ranked (priority, then who paid first) and the
178
+ top one owns the most boxes and always the first box of a run. The **ranking** sponsor of the day heads the top-10 panel. The single **banner** sponsor (top of the ranking) gets a 66×20 plate, the size of the SUPER DARIO title, with
179
+ "sponsored by NAME" above it: right of the title on the start screen (below it on narrow terminals) and centered on
180
+ top of the pause and game-over screens. All of them are clickable
181
+ (OSC 8 hyperlinks) in Warp, iTerm2, VS Code, kitty, WezTerm and Ghostty. `dario sponsors` lists them.
182
+
183
+ ## Development
184
+
185
+ ```sh
186
+ npm run typecheck
187
+ npm test
188
+ ```
189
+
190
+ Layout: `src/game` (physics, spawning, loop), `src/render` (half-block pixel
191
+ renderer, sprites, HUD), `src/launcher` (terminal strategies, pid lock),
192
+ `src/claude` (status file, hook service, settings installer), `src/agents` (Codex / Grok hook files), `src/ide` (launcher extension for VS Code-style IDEs), `src/cli`
193
+ (commands), `hooks/` (scripts Claude Code calls), `skills/dario` (the skill).
package/bin/dario ADDED
@@ -0,0 +1,45 @@
1
+ #!/bin/sh
2
+ # Dario launcher: resolves the project root (through symlinks) and runs the TypeScript entry with Node >= 22.18.
3
+ SOURCE="$0"
4
+ while [ -h "$SOURCE" ]; do
5
+ LINK_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
6
+ SOURCE="$(readlink "$SOURCE")"
7
+ case "$SOURCE" in
8
+ /*) ;;
9
+ *) SOURCE="$LINK_DIR/$SOURCE" ;;
10
+ esac
11
+ done
12
+ ROOT="$(cd -P "$(dirname "$SOURCE")/.." && pwd)"
13
+
14
+ find_node() {
15
+ if [ -n "$DARIO_NODE" ] && [ -x "$DARIO_NODE" ]; then
16
+ echo "$DARIO_NODE"
17
+ return 0
18
+ fi
19
+ if command -v node >/dev/null 2>&1; then
20
+ command -v node
21
+ return 0
22
+ fi
23
+ for candidate in /opt/homebrew/bin/node /usr/local/bin/node "$HOME/.volta/bin/node" "$HOME/.local/share/fnm/aliases/default/bin/node"; do
24
+ if [ -x "$candidate" ]; then
25
+ echo "$candidate"
26
+ return 0
27
+ fi
28
+ done
29
+ latest="$(ls -d "$HOME"/.nvm/versions/node/*/bin/node 2>/dev/null | sort -V | tail -n 1)"
30
+ if [ -n "$latest" ]; then
31
+ echo "$latest"
32
+ return 0
33
+ fi
34
+ return 1
35
+ }
36
+
37
+ NODE="$(find_node)" || {
38
+ echo "dario: could not find node (>= 22.18 required). Set DARIO_NODE=/path/to/node." >&2
39
+ exit 1
40
+ }
41
+
42
+ # npm installs ship the bundled dist/main.js (Node will not strip types under node_modules); checkouts run the sources.
43
+ ENTRY="$ROOT/src/main.ts"
44
+ if [ ! -f "$ENTRY" ] && [ -f "$ROOT/dist/main.js" ]; then ENTRY="$ROOT/dist/main.js"; fi
45
+ exec "$NODE" --no-warnings=ExperimentalWarning "$ENTRY" "$@"