clauddy 1.1.0 → 1.3.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/README.md +34 -20
- package/bin/clauddy.js +55 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,21 +46,21 @@ The token is saved locally (see [Data & privacy](#data--privacy)) and refreshed
|
|
|
46
46
|
</tr>
|
|
47
47
|
</table>
|
|
48
48
|
|
|
49
|
-
Plus a welcome **wave** on launch. You can
|
|
49
|
+
Plus a welcome **wave** on launch. You can [poke the pet from the terminal](#play-with-the-pet) too.
|
|
50
50
|
|
|
51
51
|
## Install
|
|
52
52
|
|
|
53
53
|
macOS (Apple Silicon). Two ways, depending on what you want:
|
|
54
54
|
|
|
55
|
-
### 1.
|
|
55
|
+
### 1. Install as an app — opens at login (recommended)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
One command — it downloads the latest release and drops it in `/Applications`:
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
```bash
|
|
60
|
+
curl -fsSL https://raw.githubusercontent.com/renatoaug/claude-usage-monitor/main/install.sh | bash
|
|
61
|
+
```
|
|
62
62
|
|
|
63
|
-
It registers itself in **Login Items**, so it **starts automatically** with your Mac — set it and forget it.
|
|
63
|
+
No Gatekeeper warning: files fetched with `curl` aren't quarantined like browser downloads, so the (unsigned) app just opens. It registers itself in **Login Items**, so it **starts automatically** with your Mac — set it and forget it.
|
|
64
64
|
|
|
65
65
|
### 2. Run it via `bunx` (no install)
|
|
66
66
|
|
|
@@ -74,6 +74,19 @@ The first run downloads Electron, so give it a moment. Handy for a quick run, bu
|
|
|
74
74
|
|
|
75
75
|
> The app keeps its data in `~/.claude-usage-monitor`, regardless of how you run it.
|
|
76
76
|
|
|
77
|
+
<details>
|
|
78
|
+
<summary>Prefer to download the app by hand?</summary>
|
|
79
|
+
|
|
80
|
+
Grab the **`…-mac.zip`** from [Releases](https://github.com/renatoaug/claude-usage-monitor/releases/latest), unzip, and drag the app to `/Applications`. The browser quarantines it, so macOS will call it *"damaged"* — clear the flag once (Terminal needs **Full Disk Access**):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
xattr -dr com.apple.quarantine "/Applications/Claude Usage Monitor.app"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The `curl` installer above avoids all of this.
|
|
87
|
+
|
|
88
|
+
</details>
|
|
89
|
+
|
|
77
90
|
## Controls
|
|
78
91
|
|
|
79
92
|
- **Drag** the widget anywhere on screen
|
|
@@ -100,22 +113,25 @@ Settings saved from the UI live in `~/.claude-usage-monitor/config.json`, so you
|
|
|
100
113
|
}
|
|
101
114
|
```
|
|
102
115
|
|
|
103
|
-
##
|
|
116
|
+
## Play with the pet
|
|
104
117
|
|
|
105
|
-
|
|
118
|
+
With the widget running, poke it from the terminal — just for fun:
|
|
106
119
|
|
|
107
120
|
```bash
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
./pet auto # ↩️ release control, back to real usage data
|
|
121
|
+
bunx clauddy poke # 💕 squish + hearts
|
|
122
|
+
bunx clauddy celebrate # 🎉 jump + confetti
|
|
123
|
+
bunx clauddy fire # 🔥 on fire
|
|
124
|
+
bunx clauddy sleeping # 😴 blue zzz
|
|
125
|
+
bunx clauddy working # 🍴 eats token coins
|
|
126
|
+
bunx clauddy tired # 🥵 maxed out
|
|
127
|
+
bunx clauddy idle # 🙂 calm
|
|
128
|
+
bunx clauddy auto # ↩️ back to your real usage
|
|
117
129
|
```
|
|
118
130
|
|
|
131
|
+
Each state is written to the data dir the running widget watches, so it reacts
|
|
132
|
+
live. (Installed globally? Drop the `bunx`: `clauddy poke`. Working on the repo?
|
|
133
|
+
`./pet <state>` does the same.)
|
|
134
|
+
|
|
119
135
|
## How it works
|
|
120
136
|
|
|
121
137
|
- **`main.js`** — Electron main process: frameless, transparent, always-on-top window; polls usage; fires macOS notifications; watches `config.json` and `debug.json`.
|
|
@@ -150,5 +166,3 @@ your PRs.
|
|
|
150
166
|
|
|
151
167
|
- `feat:` → minor, `fix:` → patch, `feat!:`/`BREAKING CHANGE` → major.
|
|
152
168
|
- `docs:`/`chore:`/`ci:` etc. don't trigger a release.
|
|
153
|
-
- Needs an **`NPM_TOKEN`** repo secret (an npm automation token); `GITHUB_TOKEN`
|
|
154
|
-
is automatic.
|
package/bin/clauddy.js
CHANGED
|
@@ -1,12 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
3
|
+
// `clauddy` → launch the widget (spawns Electron on main.js)
|
|
4
|
+
// `clauddy <state>` → poke the running widget for fun/demo (writes the state
|
|
5
|
+
// to the data dir the app watches; the app reacts live)
|
|
6
6
|
const path = require('node:path')
|
|
7
|
-
const
|
|
7
|
+
const fs = require('node:fs')
|
|
8
|
+
const os = require('node:os')
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
// same data dir the app uses (respects CLAUDE_CONFIG_DIR for multi-account)
|
|
11
|
+
const dataDir = process.env.CLAUDE_CONFIG_DIR
|
|
12
|
+
? path.join(process.env.CLAUDE_CONFIG_DIR, 'usage-monitor')
|
|
13
|
+
: path.join(os.homedir(), '.claude-usage-monitor')
|
|
14
|
+
|
|
15
|
+
const STATES = [
|
|
16
|
+
'fire',
|
|
17
|
+
'sleeping',
|
|
18
|
+
'working',
|
|
19
|
+
'tired',
|
|
20
|
+
'idle',
|
|
21
|
+
'poke',
|
|
22
|
+
'celebrate',
|
|
23
|
+
'auto',
|
|
24
|
+
'clear',
|
|
25
|
+
]
|
|
26
|
+
const arg = process.argv[2]
|
|
27
|
+
|
|
28
|
+
if (!arg) {
|
|
29
|
+
// no argument → launch the app
|
|
30
|
+
const { spawn } = require('node:child_process')
|
|
31
|
+
const electron = require('electron')
|
|
32
|
+
const child = spawn(electron, [path.join(__dirname, '..', 'main.js')], { stdio: 'inherit' })
|
|
33
|
+
child.on('close', (code) => process.exit(code ?? 0))
|
|
34
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
35
|
+
console.log(
|
|
36
|
+
[
|
|
37
|
+
'clauddy — a cute desktop pet that tracks your Claude Code usage',
|
|
38
|
+
'',
|
|
39
|
+
'Usage:',
|
|
40
|
+
' clauddy launch the widget',
|
|
41
|
+
' clauddy <state> poke the running widget (just for fun)',
|
|
42
|
+
'',
|
|
43
|
+
'States: fire, sleeping, working, tired, idle, poke, celebrate, auto',
|
|
44
|
+
'(the widget must be running for a state to show)',
|
|
45
|
+
].join('\n'),
|
|
46
|
+
)
|
|
47
|
+
} else if (STATES.includes(arg)) {
|
|
48
|
+
// write the state for the running app to pick up
|
|
49
|
+
fs.mkdirSync(dataDir, { recursive: true })
|
|
50
|
+
fs.writeFileSync(
|
|
51
|
+
path.join(dataDir, 'debug.json'),
|
|
52
|
+
`${JSON.stringify({ state: arg, t: Date.now() })}\n`,
|
|
53
|
+
)
|
|
54
|
+
console.log(`clauddy → ${arg} (the running widget will react)`)
|
|
55
|
+
} else {
|
|
56
|
+
console.error(`clauddy: unknown command "${arg}"`)
|
|
57
|
+
console.error('try: fire, sleeping, working, tired, idle, poke, celebrate, auto — or --help')
|
|
58
|
+
process.exit(1)
|
|
59
|
+
}
|