getstint 0.0.0-stage → 0.1.1
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 +21 -0
- package/README.md +186 -2
- package/dist/stint.mjs +124 -0
- package/package.json +60 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stint
|
|
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
CHANGED
|
@@ -1,3 +1,187 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="assets/wordmark-dark.png">
|
|
5
|
+
<img src="assets/wordmark-light.png" alt="Stint" height="56">
|
|
6
|
+
</picture>
|
|
7
|
+
|
|
8
|
+
**Know where your hours go.** One command connects your AI agents and editors to [Stint](https://getstint.dev), the free coding time tracker.
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/getstint)
|
|
11
|
+
[](https://nodejs.org)
|
|
12
|
+
[](https://bun.sh)
|
|
13
|
+
[](https://marketplace.visualstudio.com/items?itemName=getstint.stint)
|
|
14
|
+
[](https://github.com/getstint/stint-cli/actions/workflows/ci.yml)
|
|
15
|
+
[](LICENSE)
|
|
16
|
+
|
|
17
|
+
[Quick start](#quick-start) · [Integrations](#integrations) · [Commands](#commands) · [Privacy](#privacy) · [Configuration](#configuration) · [How it works](#how-it-works) · [Development](#development)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx getstint
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
That's the whole setup. It signs you in through your browser, finds the agents and editors on your machine, connects the ones you pick, and imports token usage from your past sessions so your dashboard isn't empty on day one.
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx getstint # or: bunx getstint · pnpm dlx getstint · yarn dlx getstint
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
┌ ◔ stint v0.1.0
|
|
37
|
+
│
|
|
38
|
+
◇ Connect this machine ─────────────────────────────────╮
|
|
39
|
+
│ │
|
|
40
|
+
│ Your code KQ4E-WZGK │
|
|
41
|
+
│ │
|
|
42
|
+
│ Approve this sign-in in the browser window that just │
|
|
43
|
+
│ opened. │
|
|
44
|
+
│ https://getstint.dev/device?user_code=KQ4EWZGK │
|
|
45
|
+
│ The link is on your clipboard. │
|
|
46
|
+
│ │
|
|
47
|
+
├─────────────────────────────────────────────────────────╯
|
|
48
|
+
◇ Signed in as adam
|
|
49
|
+
│
|
|
50
|
+
◆ What should Stint track?
|
|
51
|
+
│ AI agents
|
|
52
|
+
│ ◼ Claude Code hooks in ~/.claude/settings.json
|
|
53
|
+
│ ◼ Codex CLI hooks in ~/.codex/hooks.json
|
|
54
|
+
│ ◻ Gemini CLI not found on this machine
|
|
55
|
+
│ ◼ OpenCode plugin in ~/.config/opencode/plugins
|
|
56
|
+
│ Editors
|
|
57
|
+
│ ◼ VS Code, Cursor and Windsurf
|
|
58
|
+
│ ◻ WakaTime plugins JetBrains, Neovim, Zed, Xcode and more
|
|
59
|
+
└
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
No browser on this machine (SSH, a container, a server)? The CLI notices and prints the link instead. Open it on your phone or laptop, approve, and the terminal carries on. For CI or scripts, skip the browser entirely with a key from **Settings › API key**:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx getstint login --key 3f2b8c1e-9a4d-4e7f-b1c2-5d6e7f8a9b0c
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Prefer a global install? `npm i -g getstint` gives you `stint` on your `PATH`.
|
|
69
|
+
|
|
70
|
+
## Integrations
|
|
71
|
+
|
|
72
|
+
| Tool | How Stint connects | What you get |
|
|
73
|
+
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
74
|
+
| **Claude Code** | `SessionStart`, `UserPromptSubmit`, `PostToolUse`, `Stop`, `SubagentStop` and `SessionEnd` hooks in `~/.claude/settings.json`, or the [plugin](#claude-code-plugin) | Agent time per project, files it edits, tokens and cost per model from the session transcript |
|
|
75
|
+
| **Codex CLI** | Lifecycle hooks in `~/.codex/hooks.json` | Agent time, edits, per-response token usage from the rollout log |
|
|
76
|
+
| **Gemini CLI** | Hooks in `~/.gemini/settings.json` | Agent time, edits, token usage from the chat log |
|
|
77
|
+
| **OpenCode** | A plugin in `~/.config/opencode/plugins/stint.js` | Agent time, edits, token usage for every completed message |
|
|
78
|
+
| **Grok CLI, Copilot CLI, Amp, Qwen Code, anything else** | `stint run <agent>` wraps the command | Agent time per project |
|
|
79
|
+
| **VS Code, Cursor, Windsurf, VSCodium** | Installs the Stint extension from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=getstint.stint) | Your own coding time, languages, files and branches |
|
|
80
|
+
| **JetBrains, Neovim, Vim, Zed, Xcode, Sublime, Emacs and 50+ more** | Points your existing [WakaTime plugin](https://wakatime.com/plugins) at Stint through `~/.wakatime.cfg` | Everything those plugins already track |
|
|
81
|
+
|
|
82
|
+
Agent time is always counted **separately** from your own coding time, so a long agent session never inflates your hours.
|
|
83
|
+
|
|
84
|
+
Codex asks you to trust new hooks once. After installing, open Codex, run `/hooks` and approve the Stint entries.
|
|
85
|
+
|
|
86
|
+
### Claude Code plugin
|
|
87
|
+
|
|
88
|
+
If you'd rather manage it as a plugin:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
claude plugin marketplace add getstint/stint-cli
|
|
92
|
+
claude plugin install stint@stint
|
|
93
|
+
npx getstint login
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The plugin uses the same hook as `npx getstint install claude-code`, so pick one or the other.
|
|
97
|
+
|
|
98
|
+
### Backfilling history
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx getstint sync # everything from the last 13 months
|
|
102
|
+
npx getstint sync --days 30
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`sync` reads the session logs Claude Code, Codex, Gemini CLI and OpenCode already keep on your disk, and sends token counts and agent time. Running it again only sends what's new, and Stint ignores anything it has already seen.
|
|
106
|
+
|
|
107
|
+
## Commands
|
|
108
|
+
|
|
109
|
+
| Command | What it does |
|
|
110
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
111
|
+
| `npx getstint` | Sign in, pick what to track, import past usage |
|
|
112
|
+
| `login` | Connect this machine. `--no-browser` prints the link only, `--key <key>` skips the browser, `--api-url <url>` targets another server |
|
|
113
|
+
| `logout` | Forget the key on this machine |
|
|
114
|
+
| `status` | Who you're signed in as, today's time, what's connected, anything waiting to send |
|
|
115
|
+
| `install [ids…]` | Connect integrations. With no ids you get the picker, `--all` connects everything detected |
|
|
116
|
+
| `uninstall [ids…]` | Remove Stint's hooks and plugins, leaving everything else in those files alone |
|
|
117
|
+
| `sync` | Import token usage and agent time from past sessions |
|
|
118
|
+
| `run <agent> [-- cmd…]` | Track any CLI agent by wrapping it: `stint run grok`, `stint run my-agent -- ./bin/agent --flag` |
|
|
119
|
+
| `flush` | Send anything waiting in the offline queue now |
|
|
120
|
+
| `doctor` | Check Node, the hook script, the connection and your key |
|
|
121
|
+
|
|
122
|
+
Integration ids: `claude-code`, `codex`, `gemini-cli`, `opencode`, `editors`, `wakatime`.
|
|
123
|
+
|
|
124
|
+
## Privacy
|
|
125
|
+
|
|
126
|
+
Stint is a time tracker, not a code collector.
|
|
127
|
+
|
|
128
|
+
- **Never sent**: file contents, prompts, model responses, tool output, terminal commands, environment variables.
|
|
129
|
+
- **Sent**: timestamps, project name (the folder name of the git repository), branch, the file path **relative to the project root** (so your home directory and username never leave the machine), whether the event was an edit, the agent and model names, and token counts.
|
|
130
|
+
- Files outside the project, such as `~/.ssh/config`, are reported as a plain session event with no path at all.
|
|
131
|
+
- Your key lives in `~/.stint/config.json`, readable only by you (`0600` on macOS and Linux). Revoke it any time in **Settings › API key**.
|
|
132
|
+
- Hide project names from your public profile in **Settings › Privacy**.
|
|
133
|
+
|
|
134
|
+
## Configuration
|
|
135
|
+
|
|
136
|
+
Everything lives in `~/.stint/`:
|
|
137
|
+
|
|
138
|
+
| File | Purpose |
|
|
139
|
+
| ---------------------------- | ------------------------------------------------------------------- |
|
|
140
|
+
| `config.json` | Server URL, your key, username and connected integrations |
|
|
141
|
+
| `bin/stint.mjs` | The copy of the CLI that hooks run, so a hook never waits on `npx` |
|
|
142
|
+
| `queue.jsonl`, `usage.jsonl` | Events waiting to send while you're offline (capped at 20 000 each) |
|
|
143
|
+
| `state.json` | How far each session log has been read |
|
|
144
|
+
| `stint.log` | Hook errors, capped at 1 MB |
|
|
145
|
+
|
|
146
|
+
Environment variables:
|
|
147
|
+
|
|
148
|
+
| Variable | Default | Description |
|
|
149
|
+
| -------------------------------------------------------------------------------------- | ---------------------- | --------------------------------------------------- |
|
|
150
|
+
| `STINT_API_URL` | `https://getstint.dev` | Use another Stint server, such as a self-hosted one |
|
|
151
|
+
| `STINT_API_KEY` | from `config.json` | Use this key instead of the saved one |
|
|
152
|
+
| `STINT_HOME` | `~/.stint` | Where Stint keeps its files |
|
|
153
|
+
| `STINT_NO_BROWSER` | unset | Never open a browser during login |
|
|
154
|
+
| `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `WAKATIME_HOME` | the tools' defaults | Respected when finding each tool's files |
|
|
155
|
+
|
|
156
|
+
## How it works
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
agent hook ──▶ stint hook <agent> ──▶ ~/.stint/queue.jsonl ──▶ stint flush (detached) ──▶ getstint.dev
|
|
160
|
+
reads stdin JSON append-only, offline-safe batches of 500
|
|
161
|
+
reads new log lines never blocks the agent retries next time if offline
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- **Hooks never slow your agent down.** `stint hook` reads the event, appends to a local queue and exits in milliseconds without touching the network. Sending happens in a detached `stint flush`, at most once a minute and at the end of each turn.
|
|
165
|
+
- **Nothing is lost offline.** If Stint can't be reached, events stay queued and go out with the next flush.
|
|
166
|
+
- **Nothing is counted twice.** Token usage is keyed by the provider's message or response id, heartbeats by time and file, and the server drops duplicates.
|
|
167
|
+
- **Your settings files are safe.** Installing merges Stint's entries next to your own hooks, keeps a one-time `.stint-backup` of the original, and uninstalling removes only Stint's lines. Installing twice changes nothing.
|
|
168
|
+
|
|
169
|
+
The HTTP API the CLI and editor extensions use is documented in [`docs/api.md`](docs/api.md).
|
|
170
|
+
|
|
171
|
+
## Development
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
bun install
|
|
175
|
+
bun test # unit tests
|
|
176
|
+
bun run typecheck
|
|
177
|
+
bun run build # dist/stint.mjs, a single file with no runtime dependencies
|
|
178
|
+
bun run dev -- status
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Run against a local Stint server with `STINT_API_URL=http://localhost:3210`. `bun scripts/e2e.ts` runs the full login, install, hook, sync and uninstall flow against a local server inside a throwaway home directory, so it never touches your real agent settings.
|
|
182
|
+
|
|
183
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for conventions and [docs/publishing.md](docs/publishing.md) for how releases reach npm, the Claude Code marketplace and the editor stores.
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
[MIT](LICENSE)
|
package/dist/stint.mjs
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var Pn=Object.create;var{getPrototypeOf:jn,defineProperty:Xt,getOwnPropertyNames:On}=Object;var eu=Object.prototype.hasOwnProperty;function Mn(e){return this[e]}var Un,Hn,M=(e,t,n)=>{var r=e!=null&&typeof e==="object";if(r){var s=t?Un??=new WeakMap:Hn??=new WeakMap,o=s.get(e);if(o)return o}n=e!=null?Pn(jn(e)):{};let u=t||!e||!e.__esModule||!eu.call(e,"default")?Xt(n,"default",{value:e,enumerable:!0}):n;if(e&&typeof e==="object"||typeof e==="function"){for(let i of On(e))if(!eu.call(u,i))Xt(u,i,{get:Mn.bind(e,i),enumerable:!0})}if(r)s.set(e,u);return u};var tu=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var U=(e,t,n)=>()=>{if(e)try{t=e(e=0)}catch(r){n=[r]}if(n)throw n[0];return t};var gt=tu(function(lo,uu){var ht={to(e,t){if(!t)return`\x1B[${e+1}G`;return`\x1B[${t+1};${e+1}H`},move(e,t){let n="";if(e<0)n+=`\x1B[${-e}D`;else if(e>0)n+=`\x1B[${e}C`;if(t<0)n+=`\x1B[${-t}A`;else if(t>0)n+=`\x1B[${t}B`;return n},up:(e=1)=>`\x1B[${e}A`,down:(e=1)=>`\x1B[${e}B`,forward:(e=1)=>`\x1B[${e}C`,backward:(e=1)=>`\x1B[${e}D`,nextLine:(e=1)=>"\x1B[E".repeat(e),prevLine:(e=1)=>"\x1B[F".repeat(e),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},Rn={up:(e=1)=>"\x1B[S".repeat(e),down:(e=1)=>"\x1B[T".repeat(e)},Nn={screen:"\x1B[2J",up:(e=1)=>"\x1B[1J".repeat(e),down:(e=1)=>"\x1B[J".repeat(e),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(e){let t="";for(let n=0;n<e;n++)t+=this.line+(n<e-1?ht.up():"");if(e)t+=ht.left;return t}};uu.exports={cursor:ht,scroll:Rn,erase:Nn,beep:"\x07"}});var G=tu(function(po,ft){var Ve=process||{},nu=Ve.argv||[],qe=Ve.env||{},Wn=!(!!qe.NO_COLOR||nu.includes("--no-color"))&&(!!qe.FORCE_COLOR||nu.includes("--color")||Ve.platform==="win32"||(Ve.stdout||{}).isTTY&&qe.TERM!=="dumb"||!!qe.CI),Ln=(e,t,n=e)=>(r)=>{let s=""+r,o=s.indexOf(t,e.length);return~o?e+Gn(s,t,n,o)+t:e+s+t},Gn=(e,t,n,r)=>{let s="",o=0;do s+=e.substring(o,r)+n,o=r+t.length,r=e.indexOf(t,o);while(~r);return s+e.substring(o)},ru=(e=Wn)=>{let t=e?Ln:()=>String;return{isColorSupported:e,reset:t("\x1B[0m","\x1B[0m"),bold:t("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:t("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:t("\x1B[3m","\x1B[23m"),underline:t("\x1B[4m","\x1B[24m"),inverse:t("\x1B[7m","\x1B[27m"),hidden:t("\x1B[8m","\x1B[28m"),strikethrough:t("\x1B[9m","\x1B[29m"),black:t("\x1B[30m","\x1B[39m"),red:t("\x1B[31m","\x1B[39m"),green:t("\x1B[32m","\x1B[39m"),yellow:t("\x1B[33m","\x1B[39m"),blue:t("\x1B[34m","\x1B[39m"),magenta:t("\x1B[35m","\x1B[39m"),cyan:t("\x1B[36m","\x1B[39m"),white:t("\x1B[37m","\x1B[39m"),gray:t("\x1B[90m","\x1B[39m"),bgBlack:t("\x1B[40m","\x1B[49m"),bgRed:t("\x1B[41m","\x1B[49m"),bgGreen:t("\x1B[42m","\x1B[49m"),bgYellow:t("\x1B[43m","\x1B[49m"),bgBlue:t("\x1B[44m","\x1B[49m"),bgMagenta:t("\x1B[45m","\x1B[49m"),bgCyan:t("\x1B[46m","\x1B[49m"),bgWhite:t("\x1B[47m","\x1B[49m"),blackBright:t("\x1B[90m","\x1B[39m"),redBright:t("\x1B[91m","\x1B[39m"),greenBright:t("\x1B[92m","\x1B[39m"),yellowBright:t("\x1B[93m","\x1B[39m"),blueBright:t("\x1B[94m","\x1B[39m"),magentaBright:t("\x1B[95m","\x1B[39m"),cyanBright:t("\x1B[96m","\x1B[39m"),whiteBright:t("\x1B[97m","\x1B[39m"),bgBlackBright:t("\x1B[100m","\x1B[49m"),bgRedBright:t("\x1B[101m","\x1B[49m"),bgGreenBright:t("\x1B[102m","\x1B[49m"),bgYellowBright:t("\x1B[103m","\x1B[49m"),bgBlueBright:t("\x1B[104m","\x1B[49m"),bgMagentaBright:t("\x1B[105m","\x1B[49m"),bgCyanBright:t("\x1B[106m","\x1B[49m"),bgWhiteBright:t("\x1B[107m","\x1B[49m")}};ft.exports=ru();ft.exports.createColors=ru});import{stdin as mu,stdout as du}from"node:process";import*as Y from"node:readline";import su from"node:readline";import{Writable as qn}from"node:stream";function Vn({onlyFirst:e=!1}={}){let t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");return new RegExp(t,e?void 0:"g")}function hu(e){if(typeof e!="string")throw TypeError(`Expected a \`string\`, got \`${typeof e}\``);return e.replace(Kn,"")}function gu(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Ae(e,t={}){if(typeof e!="string"||e.length===0||(t={ambiguousIsNarrow:!0,...t},e=hu(e),e.length===0))return 0;e=e.replace(Qn()," ");let n=t.ambiguousIsNarrow?1:2,r=0;for(let s of e){let o=s.codePointAt(0);if(o<=31||o>=127&&o<=159||o>=768&&o<=879)continue;switch(zn.eastAsianWidth(s)){case"F":case"W":r+=2;break;case"A":r+=n;break;default:r+=1}}return r}function er(){let e=new Map;for(let[t,n]of Object.entries(C)){for(let[r,s]of Object.entries(n))C[r]={open:`\x1B[${s[0]}m`,close:`\x1B[${s[1]}m`},n[r]=C[r],e.set(s[0],s[1]);Object.defineProperty(C,t,{value:n,enumerable:!1})}return Object.defineProperty(C,"codes",{value:e,enumerable:!1}),C.color.close="\x1B[39m",C.bgColor.close="\x1B[49m",C.color.ansi=ou(),C.color.ansi256=iu(),C.color.ansi16m=Du(),C.bgColor.ansi=ou(Ft),C.bgColor.ansi256=iu(Ft),C.bgColor.ansi16m=Du(Ft),Object.defineProperties(C,{rgbToAnsi256:{value:(t,n,r)=>t===n&&n===r?t<8?16:t>248?231:Math.round((t-8)/247*24)+232:16+36*Math.round(t/255*5)+6*Math.round(n/255*5)+Math.round(r/255*5),enumerable:!1},hexToRgb:{value:(t)=>{let n=/[a-f\d]{6}|[a-f\d]{3}/i.exec(t.toString(16));if(!n)return[0,0,0];let[r]=n;r.length===3&&(r=[...r].map((o)=>o+o).join(""));let s=Number.parseInt(r,16);return[s>>16&255,s>>8&255,s&255]},enumerable:!1},hexToAnsi256:{value:(t)=>C.rgbToAnsi256(...C.hexToRgb(t)),enumerable:!1},ansi256ToAnsi:{value:(t)=>{if(t<8)return 30+t;if(t<16)return 90+(t-8);let n,r,s;if(t>=232)n=((t-232)*10+8)/255,r=n,s=n;else{t-=16;let i=t%36;n=Math.floor(t/36)/5,r=Math.floor(i/6)/5,s=i%6/5}let o=Math.max(n,r,s)*2;if(o===0)return 30;let u=30+(Math.round(s)<<2|Math.round(r)<<1|Math.round(n));return o===2&&(u+=60),u},enumerable:!1},rgbToAnsi:{value:(t,n,r)=>C.ansi256ToAnsi(C.rgbToAnsi256(t,n,r)),enumerable:!1},hexToAnsi:{value:(t)=>C.ansi256ToAnsi(C.hexToAnsi256(t)),enumerable:!1}}),C}function lu(e,t,n){return String(e).normalize().replace(/\r\n/g,`
|
|
3
|
+
`).split(`
|
|
4
|
+
`).map((r)=>or(r,t,n)).join(`
|
|
5
|
+
`)}function wt(e,t){if(typeof e=="string")return Je.aliases.get(e)===t;for(let n of e)if(n!==void 0&&wt(n,t))return!0;return!1}function Dr(e,t){if(e===t)return;let n=e.split(`
|
|
6
|
+
`),r=t.split(`
|
|
7
|
+
`),s=[];for(let o=0;o<Math.max(n.length,r.length);o++)n[o]!==r[o]&&s.push(o);return s}function Q(e){return e===yt}function Ke(e,t){let n=e;n.isTTY&&n.setRawMode(t)}function Eu({input:e=mu,output:t=du,overwrite:n=!0,hideCursor:r=!0}={}){let s=Y.createInterface({input:e,output:t,prompt:"",tabSize:1});Y.emitKeypressEvents(e,s),e.isTTY&&e.setRawMode(!0);let o=(u,{name:i,sequence:D})=>{let c=String(u);if(wt([c,i,D],"cancel")){r&&t.write(A.cursor.show),process.exit(0);return}if(!n)return;Y.moveCursor(t,i==="return"?0:-1,i==="return"?-1:0,()=>{Y.clearLine(t,1,()=>{e.once("keypress",o)})})};return r&&t.write(A.cursor.hide),e.once("keypress",o),()=>{e.off("keypress",o),r&&t.write(A.cursor.show),e.isTTY&&!ar&&e.setRawMode(!1),s.terminal=!1,s.close()}}class kt{constructor(e,t=!0){T(this,"input"),T(this,"output"),T(this,"_abortSignal"),T(this,"rl"),T(this,"opts"),T(this,"_render"),T(this,"_track",!1),T(this,"_prevFrame",""),T(this,"_subscribers",new Map),T(this,"_cursor",0),T(this,"state","initial"),T(this,"error",""),T(this,"value");let{input:n=mu,output:r=du,render:s,signal:o,...u}=e;this.opts=u,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=s.bind(this),this._track=t,this._abortSignal=o,this.input=n,this.output=r}unsubscribe(){this._subscribers.clear()}setSubscriber(e,t){let n=this._subscribers.get(e)??[];n.push(t),this._subscribers.set(e,n)}on(e,t){this.setSubscriber(e,{cb:t})}once(e,t){this.setSubscriber(e,{cb:t,once:!0})}emit(e,...t){let n=this._subscribers.get(e)??[],r=[];for(let s of n)s.cb(...t),s.once&&r.push(()=>n.splice(n.indexOf(s),1));for(let s of r)s()}prompt(){return new Promise((e,t)=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state="cancel",this.close(),e(yt);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close()},{once:!0})}let n=new qn;n._write=(r,s,o)=>{this._track&&(this.value=this.rl?.line.replace(/\t/g,""),this._cursor=this.rl?.cursor??0,this.emit("value",this.value)),o()},this.input.pipe(n),this.rl=su.createInterface({input:this.input,output:n,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:!0}),su.emitKeypressEvents(this.input,this.rl),this.rl.prompt(),this.opts.initialValue!==void 0&&this._track&&this.rl.write(this.opts.initialValue),this.input.on("keypress",this.onKeypress),Ke(this.input,!0),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(A.cursor.show),this.output.off("resize",this.render),Ke(this.input,!1),e(this.value)}),this.once("cancel",()=>{this.output.write(A.cursor.show),this.output.off("resize",this.render),Ke(this.input,!1),e(yt)})})}onKeypress(e,t){if(this.state==="error"&&(this.state="active"),t?.name&&(!this._track&&Je.aliases.has(t.name)&&this.emit("cursor",Je.aliases.get(t.name)),Je.actions.has(t.name)&&this.emit("cursor",t.name)),e&&(e.toLowerCase()==="y"||e.toLowerCase()==="n")&&this.emit("confirm",e.toLowerCase()==="y"),e==="\t"&&this.opts.placeholder&&(this.value||(this.rl?.write(this.opts.placeholder),this.emit("value",this.opts.placeholder))),e&&this.emit("key",e.toLowerCase()),t?.name==="return"){if(this.opts.validate){let n=this.opts.validate(this.value);n&&(this.error=n instanceof Error?n.message:n,this.state="error",this.rl?.write(this.value))}this.state!=="error"&&(this.state="submit")}wt([e,t?.name,t?.sequence],"cancel")&&(this.state="cancel"),(this.state==="submit"||this.state==="cancel")&&this.emit("finalize"),this.render(),(this.state==="submit"||this.state==="cancel")&&this.close()}close(){this.input.unpipe(),this.input.removeListener("keypress",this.onKeypress),this.output.write(`
|
|
8
|
+
`),Ke(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let e=lu(this._prevFrame,process.stdout.columns,{hard:!0}).split(`
|
|
9
|
+
`).length-1;this.output.write(A.cursor.move(-999,e*-1))}render(){let e=lu(this._render(this)??"",process.stdout.columns,{hard:!0});if(e!==this._prevFrame){if(this.state==="initial")this.output.write(A.cursor.hide);else{let t=Dr(this._prevFrame,e);if(this.restoreCursor(),t&&t?.length===1){let n=t[0];this.output.write(A.cursor.move(0,n)),this.output.write(A.erase.lines(1));let r=e.split(`
|
|
10
|
+
`);this.output.write(r[n]),this._prevFrame=e,this.output.write(A.cursor.move(0,r.length-n-1));return}if(t&&t?.length>1){let n=t[0];this.output.write(A.cursor.move(0,n)),this.output.write(A.erase.down());let r=e.split(`
|
|
11
|
+
`).slice(n);this.output.write(r.join(`
|
|
12
|
+
`)),this._prevFrame=e;return}this.output.write(A.erase.down())}this.output.write(e),this.state==="initial"&&(this.state="active"),this._prevFrame=e}}}var A,Kn,fu,Jn,zn,Yn=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g},Qn,Ft=10,ou=(e=0)=>(t)=>`\x1B[${t+e}m`,iu=(e=0)=>(t)=>`\x1B[${38+e};5;${t}m`,Du=(e=0)=>(t,n,r)=>`\x1B[${38+e};2;${t};${n};${r}m`,C,Zn,Xn,tr,ze,ur=39,bt="\x07",Fu="[",nr="]",Cu="m",$t,au=(e)=>`${ze.values().next().value}${Fu}${e}${Cu}`,cu=(e)=>`${ze.values().next().value}${$t}${e}${bt}`,rr=(e)=>e.split(" ").map((t)=>Ae(t)),Ct=(e,t,n)=>{let r=[...t],s=!1,o=!1,u=Ae(hu(e[e.length-1]));for(let[i,D]of r.entries()){let c=Ae(D);if(u+c<=n?e[e.length-1]+=D:(e.push(D),u=0),ze.has(D)&&(s=!0,o=r.slice(i+1).join("").startsWith($t)),s){o?D===bt&&(s=!1,o=!1):D===Cu&&(s=!1);continue}u+=c,u===n&&i<r.length-1&&(e.push(""),u=0)}!u&&e[e.length-1].length>0&&e.length>1&&(e[e.length-2]+=e.pop())},sr=(e)=>{let t=e.split(" "),n=t.length;for(;n>0&&!(Ae(t[n-1])>0);)n--;return n===t.length?e:t.slice(0,n).join(" ")+t.slice(n).join("")},or=(e,t,n={})=>{if(n.trim!==!1&&e.trim()==="")return"";let r="",s,o,u=rr(e),i=[""];for(let[c,l]of e.split(" ").entries()){n.trim!==!1&&(i[i.length-1]=i[i.length-1].trimStart());let p=Ae(i[i.length-1]);if(c!==0&&(p>=t&&(n.wordWrap===!1||n.trim===!1)&&(i.push(""),p=0),(p>0||n.trim===!1)&&(i[i.length-1]+=" ",p++)),n.hard&&u[c]>t){let d=t-p,g=1+Math.floor((u[c]-d-1)/t);Math.floor((u[c]-1)/t)<g&&i.push(""),Ct(i,l,t);continue}if(p+u[c]>t&&p>0&&u[c]>0){if(n.wordWrap===!1&&p<t){Ct(i,l,t);continue}i.push("")}if(p+u[c]>t&&n.wordWrap===!1){Ct(i,l,t);continue}i[i.length-1]+=l}n.trim!==!1&&(i=i.map((c)=>sr(c)));let D=[...i.join(`
|
|
13
|
+
`)];for(let[c,l]of D.entries()){if(r+=l,ze.has(l)){let{groups:d}=new RegExp(`(?:\\${Fu}(?<code>\\d+)m|\\${$t}(?<uri>.*)${bt})`).exec(D.slice(c).join(""))||{groups:{}};if(d.code!==void 0){let g=Number.parseFloat(d.code);s=g===ur?void 0:g}else d.uri!==void 0&&(o=d.uri.length===0?void 0:d.uri)}let p=tr.codes.get(Number(s));D[c+1]===`
|
|
14
|
+
`?(o&&(r+=cu("")),s&&p&&(r+=au(p))):l===`
|
|
15
|
+
`&&(s&&p&&(r+=au(s)),o&&(r+=cu(o)))}return r},ir,Je,ar,yt,cr,lr=(e,t,n)=>(t in e)?cr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,T=(e,t,n)=>(lr(e,typeof t!="symbol"?t+"":t,n),n),Bt,pr,mr=(e,t,n)=>(t in e)?pr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,pu=(e,t,n)=>(mr(e,typeof t!="symbol"?t+"":t,n),n),yu=(e,t,n)=>{if(!t.has(e))throw TypeError("Cannot "+n)},Et=(e,t,n)=>(yu(e,t,"read from private field"),n?n.call(e):t.get(e)),dr=(e,t,n)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,n)},hr=(e,t,n,r)=>(yu(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),he,bu;var xt=U(()=>{A=M(gt(),1);Kn=Vn();fu={exports:{}};(function(e){var t={};e.exports=t,t.eastAsianWidth=function(r){var s=r.charCodeAt(0),o=r.length==2?r.charCodeAt(1):0,u=s;return 55296<=s&&s<=56319&&56320<=o&&o<=57343&&(s&=1023,o&=1023,u=s<<10|o,u+=65536),u==12288||65281<=u&&u<=65376||65504<=u&&u<=65510?"F":u==8361||65377<=u&&u<=65470||65474<=u&&u<=65479||65482<=u&&u<=65487||65490<=u&&u<=65495||65498<=u&&u<=65500||65512<=u&&u<=65518?"H":4352<=u&&u<=4447||4515<=u&&u<=4519||4602<=u&&u<=4607||9001<=u&&u<=9002||11904<=u&&u<=11929||11931<=u&&u<=12019||12032<=u&&u<=12245||12272<=u&&u<=12283||12289<=u&&u<=12350||12353<=u&&u<=12438||12441<=u&&u<=12543||12549<=u&&u<=12589||12593<=u&&u<=12686||12688<=u&&u<=12730||12736<=u&&u<=12771||12784<=u&&u<=12830||12832<=u&&u<=12871||12880<=u&&u<=13054||13056<=u&&u<=19903||19968<=u&&u<=42124||42128<=u&&u<=42182||43360<=u&&u<=43388||44032<=u&&u<=55203||55216<=u&&u<=55238||55243<=u&&u<=55291||63744<=u&&u<=64255||65040<=u&&u<=65049||65072<=u&&u<=65106||65108<=u&&u<=65126||65128<=u&&u<=65131||110592<=u&&u<=110593||127488<=u&&u<=127490||127504<=u&&u<=127546||127552<=u&&u<=127560||127568<=u&&u<=127569||131072<=u&&u<=194367||177984<=u&&u<=196605||196608<=u&&u<=262141?"W":32<=u&&u<=126||162<=u&&u<=163||165<=u&&u<=166||u==172||u==175||10214<=u&&u<=10221||10629<=u&&u<=10630?"Na":u==161||u==164||167<=u&&u<=168||u==170||173<=u&&u<=174||176<=u&&u<=180||182<=u&&u<=186||188<=u&&u<=191||u==198||u==208||215<=u&&u<=216||222<=u&&u<=225||u==230||232<=u&&u<=234||236<=u&&u<=237||u==240||242<=u&&u<=243||247<=u&&u<=250||u==252||u==254||u==257||u==273||u==275||u==283||294<=u&&u<=295||u==299||305<=u&&u<=307||u==312||319<=u&&u<=322||u==324||328<=u&&u<=331||u==333||338<=u&&u<=339||358<=u&&u<=359||u==363||u==462||u==464||u==466||u==468||u==470||u==472||u==474||u==476||u==593||u==609||u==708||u==711||713<=u&&u<=715||u==717||u==720||728<=u&&u<=731||u==733||u==735||768<=u&&u<=879||913<=u&&u<=929||931<=u&&u<=937||945<=u&&u<=961||963<=u&&u<=969||u==1025||1040<=u&&u<=1103||u==1105||u==8208||8211<=u&&u<=8214||8216<=u&&u<=8217||8220<=u&&u<=8221||8224<=u&&u<=8226||8228<=u&&u<=8231||u==8240||8242<=u&&u<=8243||u==8245||u==8251||u==8254||u==8308||u==8319||8321<=u&&u<=8324||u==8364||u==8451||u==8453||u==8457||u==8467||u==8470||8481<=u&&u<=8482||u==8486||u==8491||8531<=u&&u<=8532||8539<=u&&u<=8542||8544<=u&&u<=8555||8560<=u&&u<=8569||u==8585||8592<=u&&u<=8601||8632<=u&&u<=8633||u==8658||u==8660||u==8679||u==8704||8706<=u&&u<=8707||8711<=u&&u<=8712||u==8715||u==8719||u==8721||u==8725||u==8730||8733<=u&&u<=8736||u==8739||u==8741||8743<=u&&u<=8748||u==8750||8756<=u&&u<=8759||8764<=u&&u<=8765||u==8776||u==8780||u==8786||8800<=u&&u<=8801||8804<=u&&u<=8807||8810<=u&&u<=8811||8814<=u&&u<=8815||8834<=u&&u<=8835||8838<=u&&u<=8839||u==8853||u==8857||u==8869||u==8895||u==8978||9312<=u&&u<=9449||9451<=u&&u<=9547||9552<=u&&u<=9587||9600<=u&&u<=9615||9618<=u&&u<=9621||9632<=u&&u<=9633||9635<=u&&u<=9641||9650<=u&&u<=9651||9654<=u&&u<=9655||9660<=u&&u<=9661||9664<=u&&u<=9665||9670<=u&&u<=9672||u==9675||9678<=u&&u<=9681||9698<=u&&u<=9701||u==9711||9733<=u&&u<=9734||u==9737||9742<=u&&u<=9743||9748<=u&&u<=9749||u==9756||u==9758||u==9792||u==9794||9824<=u&&u<=9825||9827<=u&&u<=9829||9831<=u&&u<=9834||9836<=u&&u<=9837||u==9839||9886<=u&&u<=9887||9918<=u&&u<=9919||9924<=u&&u<=9933||9935<=u&&u<=9953||u==9955||9960<=u&&u<=9983||u==10045||u==10071||10102<=u&&u<=10111||11093<=u&&u<=11097||12872<=u&&u<=12879||57344<=u&&u<=63743||65024<=u&&u<=65039||u==65533||127232<=u&&u<=127242||127248<=u&&u<=127277||127280<=u&&u<=127337||127344<=u&&u<=127386||917760<=u&&u<=917999||983040<=u&&u<=1048573||1048576<=u&&u<=1114109?"A":"N"},t.characterLength=function(r){var s=this.eastAsianWidth(r);return s=="F"||s=="W"||s=="A"?2:1};function n(r){return r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g)||[]}t.length=function(r){for(var s=n(r),o=0,u=0;u<s.length;u++)o=o+this.characterLength(s[u]);return o},t.slice=function(r,s,o){textLen=t.length(r),s=s||0,o=o||1,s<0&&(s=textLen+s),o<0&&(o=textLen+o);for(var u="",i=0,D=n(r),c=0;c<D.length;c++){var l=D[c],p=t.length(l);if(i>=s-(p==2?1:0))if(i+p<=o)u+=l;else break;i+=p}return u}})(fu);Jn=fu.exports,zn=gu(Jn),Qn=gu(Yn);C={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],overline:[53,55],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],gray:[90,39],grey:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgGray:[100,49],bgGrey:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};Object.keys(C.modifier);Zn=Object.keys(C.color),Xn=Object.keys(C.bgColor);[...Zn,...Xn];tr=er(),ze=new Set(["\x1B",""]),$t=`${nr}8;;`;ir=["up","down","left","right","space","enter","cancel"],Je={actions:new Set(ir),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]])};ar=globalThis.process.platform.startsWith("win"),yt=Symbol("clack:cancel");cr=Object.defineProperty;Bt=class Bt extends kt{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(e){super(e,!1),this.value=!!e.initialValue,this.on("value",()=>{this.value=this._value}),this.on("confirm",(t)=>{this.output.write(A.cursor.move(0,-1)),this.value=t,this.state="submit",this.close()}),this.on("cursor",()=>{this.value=!this.value})}};pr=Object.defineProperty,bu=class extends kt{constructor(e){super(e,!1),pu(this,"options"),pu(this,"cursor",0),dr(this,he,void 0);let{options:t}=e;hr(this,he,e.selectableGroups!==!1),this.options=Object.entries(t).flatMap(([n,r])=>[{value:n,group:!0,label:n},...r.map((s)=>({...s,group:n}))]),this.value=[...e.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:n})=>n===e.cursorAt),Et(this,he)?0:1),this.on("cursor",(n)=>{switch(n){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let r=this.options[this.cursor]?.group===!0;!Et(this,he)&&r&&(this.cursor=this.cursor===0?this.options.length-1:this.cursor-1);break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let r=this.options[this.cursor]?.group===!0;!Et(this,he)&&r&&(this.cursor=this.cursor===this.options.length-1?0:this.cursor+1);break}case"space":this.toggleValue();break}})}getGroupItems(e){return this.options.filter((t)=>t.group===e)}isGroupSelected(e){return this.getGroupItems(e).every((t)=>this.value.includes(t.value))}toggleValue(){let e=this.options[this.cursor];if(e.group===!0){let t=e.value,n=this.getGroupItems(t);this.isGroupSelected(t)?this.value=this.value.filter((r)=>n.findIndex((s)=>s.value===r)===-1):this.value=[...this.value,...n.map((r)=>r.value)],this.value=Array.from(new Set(this.value))}else{let t=this.value.includes(e.value);this.value=t?this.value.filter((n)=>n!==e.value):[...this.value,e.value]}}};he=new WeakMap});import{stripVTControlCharacters as vt}from"node:util";import H from"node:process";function gr(){return H.platform!=="win32"?H.env.TERM!=="linux":!!H.env.CI||!!H.env.WT_SESSION||!!H.env.TERMINUS_SUBLIME||H.env.ConEmuTask==="{cmd::Cmder}"||H.env.TERM_PROGRAM==="Terminus-Sublime"||H.env.TERM_PROGRAM==="vscode"||H.env.TERM==="xterm-256color"||H.env.TERM==="alacritty"||H.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var a,Ye,St,w=(e,t)=>St?e:t,fr,xu,vu,Qe,Fr,E,ge,$u,wu,ku,At,Cr,vo,Bu,Er,yr,br,$r,wr,kr,Br,Au=(e)=>{switch(e){case"initial":case"active":return a.default.cyan(fr);case"cancel":return a.default.red(xu);case"error":return a.default.yellow(vu);case"submit":return a.default.green(Qe)}},Ze=(e)=>{let t=e.active??"Yes",n=e.inactive??"No";return new Bt({active:t,inactive:n,initialValue:e.initialValue??!0,render(){let r=`${a.default.gray(E)}
|
|
16
|
+
${Au(this.state)} ${e.message}
|
|
17
|
+
`,s=this.value?t:n;switch(this.state){case"submit":return`${r}${a.default.gray(E)} ${a.default.dim(s)}`;case"cancel":return`${r}${a.default.gray(E)} ${a.default.strikethrough(a.default.dim(s))}
|
|
18
|
+
${a.default.gray(E)}`;default:return`${r}${a.default.cyan(E)} ${this.value?`${a.default.green($u)} ${t}`:`${a.default.dim(wu)} ${a.default.dim(t)}`} ${a.default.dim("/")} ${this.value?`${a.default.dim(wu)} ${a.default.dim(n)}`:`${a.default.green($u)} ${n}`}
|
|
19
|
+
${a.default.cyan(ge)}
|
|
20
|
+
`}}}).prompt()},Su=(e)=>{let{selectableGroups:t=!0}=e,n=(r,s,o=[])=>{let u=r.label??String(r.value),i=typeof r.group=="string",D=i&&(o[o.indexOf(r)+1]??{group:!0}),c=i&&D.group===!0,l=i?t?`${c?ge:E} `:" ":"";if(s==="active")return`${a.default.dim(l)}${a.default.cyan(ku)} ${u} ${r.hint?a.default.dim(`(${r.hint})`):""}`;if(s==="group-active")return`${l}${a.default.cyan(ku)} ${a.default.dim(u)}`;if(s==="group-active-selected")return`${l}${a.default.green(At)} ${a.default.dim(u)}`;if(s==="selected"){let d=i||t?a.default.green(At):"";return`${a.default.dim(l)}${d} ${a.default.dim(u)} ${r.hint?a.default.dim(`(${r.hint})`):""}`}if(s==="cancelled")return`${a.default.strikethrough(a.default.dim(u))}`;if(s==="active-selected")return`${a.default.dim(l)}${a.default.green(At)} ${u} ${r.hint?a.default.dim(`(${r.hint})`):""}`;if(s==="submitted")return`${a.default.dim(u)}`;let p=i||t?a.default.dim(Cr):"";return`${a.default.dim(l)}${p} ${a.default.dim(u)}`};return new bu({options:e.options,initialValues:e.initialValues,required:e.required??!0,cursorAt:e.cursorAt,selectableGroups:t,validate(r){if(this.required&&r.length===0)return`Please select at least one option.
|
|
21
|
+
${a.default.reset(a.default.dim(`Press ${a.default.gray(a.default.bgWhite(a.default.inverse(" space ")))} to select, ${a.default.gray(a.default.bgWhite(a.default.inverse(" enter ")))} to submit`))}`},render(){let r=`${a.default.gray(E)}
|
|
22
|
+
${Au(this.state)} ${e.message}
|
|
23
|
+
`;switch(this.state){case"submit":return`${r}${a.default.gray(E)} ${this.options.filter(({value:s})=>this.value.includes(s)).map((s)=>n(s,"submitted")).join(a.default.dim(", "))}`;case"cancel":{let s=this.options.filter(({value:o})=>this.value.includes(o)).map((o)=>n(o,"cancelled")).join(a.default.dim(", "));return`${r}${a.default.gray(E)} ${s.trim()?`${s}
|
|
24
|
+
${a.default.gray(E)}`:""}`}case"error":{let s=this.error.split(`
|
|
25
|
+
`).map((o,u)=>u===0?`${a.default.yellow(ge)} ${a.default.yellow(o)}`:` ${o}`).join(`
|
|
26
|
+
`);return`${r}${a.default.yellow(E)} ${this.options.map((o,u,i)=>{let D=this.value.includes(o.value)||o.group===!0&&this.isGroupSelected(`${o.value}`),c=u===this.cursor;return!c&&typeof o.group=="string"&&this.options[this.cursor].value===o.group?n(o,D?"group-active-selected":"group-active",i):c&&D?n(o,"active-selected",i):D?n(o,"selected",i):n(o,c?"active":"inactive",i)}).join(`
|
|
27
|
+
${a.default.yellow(E)} `)}
|
|
28
|
+
${s}
|
|
29
|
+
`}default:return`${r}${a.default.cyan(E)} ${this.options.map((s,o,u)=>{let i=this.value.includes(s.value)||s.group===!0&&this.isGroupSelected(`${s.value}`),D=o===this.cursor;return!D&&typeof s.group=="string"&&this.options[this.cursor].value===s.group?n(s,i?"group-active-selected":"group-active",u):D&&i?n(s,"active-selected",u):i?n(s,"selected",u):n(s,D?"active":"inactive",u)}).join(`
|
|
30
|
+
${a.default.cyan(E)} `)}
|
|
31
|
+
${a.default.cyan(ge)}
|
|
32
|
+
`}}}).prompt()},Xe=(e="",t="")=>{let n=`
|
|
33
|
+
${e}
|
|
34
|
+
`.split(`
|
|
35
|
+
`),r=vt(t).length,s=Math.max(n.reduce((u,i)=>{let D=vt(i);return D.length>u?D.length:u},0),r)+2,o=n.map((u)=>`${a.default.gray(E)} ${a.default.dim(u)}${" ".repeat(s-vt(u).length)}${a.default.gray(E)}`).join(`
|
|
36
|
+
`);process.stdout.write(`${a.default.gray(E)}
|
|
37
|
+
${a.default.green(Qe)} ${a.default.reset(t)} ${a.default.gray(Bu.repeat(Math.max(s-r-1,1))+Er)}
|
|
38
|
+
${o}
|
|
39
|
+
${a.default.gray(yr+Bu.repeat(s+2)+br)}
|
|
40
|
+
`)},et=(e="")=>{process.stdout.write(`${a.default.gray(ge)} ${a.default.red(e)}
|
|
41
|
+
|
|
42
|
+
`)},Se=(e="")=>{process.stdout.write(`${a.default.gray(Fr)} ${e}
|
|
43
|
+
`)},_e=(e="")=>{process.stdout.write(`${a.default.gray(E)}
|
|
44
|
+
${a.default.gray(ge)} ${e}
|
|
45
|
+
|
|
46
|
+
`)},f,Ao,Ie=({indicator:e="dots"}={})=>{let t=St?["◒","◐","◓","◑"]:["•","o","O","0"],n=St?80:120,r=process.env.CI==="true",s,o,u=!1,i="",D,c=performance.now(),l=(I)=>{let j=I>1?"Something went wrong":"Canceled";u&&Zt(j,I)},p=()=>l(2),d=()=>l(1),g=()=>{process.on("uncaughtExceptionMonitor",p),process.on("unhandledRejection",p),process.on("SIGINT",d),process.on("SIGTERM",d),process.on("exit",l)},h=()=>{process.removeListener("uncaughtExceptionMonitor",p),process.removeListener("unhandledRejection",p),process.removeListener("SIGINT",d),process.removeListener("SIGTERM",d),process.removeListener("exit",l)},_=()=>{if(D===void 0)return;r&&process.stdout.write(`
|
|
47
|
+
`);let I=D.split(`
|
|
48
|
+
`);process.stdout.write(Ye.cursor.move(-999,I.length-1)),process.stdout.write(Ye.erase.down(I.length))},q=(I)=>I.replace(/\.+$/,""),se=(I)=>{let j=(performance.now()-I)/1000,L=Math.floor(j/60),de=Math.floor(j%60);return L>0?`[${L}m ${de}s]`:`[${de}s]`},In=(I="")=>{u=!0,s=Eu(),i=q(I),c=performance.now(),process.stdout.write(`${a.default.gray(E)}
|
|
49
|
+
`);let j=0,L=0;g(),o=setInterval(()=>{if(r&&i===D)return;_(),D=i;let de=a.default.magenta(t[j]);if(r)process.stdout.write(`${de} ${i}...`);else if(e==="timer")process.stdout.write(`${de} ${i} ${se(c)}`);else{let Tn=".".repeat(Math.floor(L)).slice(0,3);process.stdout.write(`${de} ${i}${Tn}`)}j=j+1<t.length?j+1:0,L=L<t.length?L+0.125:0},n)},Zt=(I="",j=0)=>{u=!1,clearInterval(o),_();let L=j===0?a.default.green(Qe):j===1?a.default.red(xu):a.default.red(vu);i=q(I??i),e==="timer"?process.stdout.write(`${L} ${i} ${se(c)}
|
|
50
|
+
`):process.stdout.write(`${L} ${i}
|
|
51
|
+
`),h(),s()};return{start:In,stop:Zt,message:(I="")=>{i=q(I??i)}}};var Z=U(()=>{xt();xt();a=M(G(),1),Ye=M(gt(),1);St=gr(),fr=w("◆","*"),xu=w("■","x"),vu=w("▲","x"),Qe=w("◇","o"),Fr=w("┌","T"),E=w("│","|"),ge=w("└","—"),$u=w("●",">"),wu=w("○"," "),ku=w("◻","[•]"),At=w("◼","[+]"),Cr=w("◻","[ ]"),vo=w("▪","•"),Bu=w("─","-"),Er=w("╮","+"),yr=w("├","+"),br=w("╯","+"),$r=w("●","•"),wr=w("◆","*"),kr=w("▲","!"),Br=w("■","x"),f={message:(e="",{symbol:t=a.default.gray(E)}={})=>{let n=[`${a.default.gray(E)}`];if(e){let[r,...s]=e.split(`
|
|
52
|
+
`);n.push(`${t} ${r}`,...s.map((o)=>`${a.default.gray(E)} ${o}`))}process.stdout.write(`${n.join(`
|
|
53
|
+
`)}
|
|
54
|
+
`)},info:(e)=>{f.message(e,{symbol:a.default.blue($r)})},success:(e)=>{f.message(e,{symbol:a.default.green(wr)})},step:(e)=>{f.message(e,{symbol:a.default.green(Qe)})},warn:(e)=>{f.message(e,{symbol:a.default.yellow(kr)})},warning:(e)=>{f.warn(e)},error:(e)=>{f.message(e,{symbol:a.default.red(Br)})}},Ao=`${a.default.gray(E)} `});import{chmodSync as xr,existsSync as _u,mkdirSync as vr,readFileSync as Iu,renameSync as Ar,writeFileSync as Tu}from"node:fs";import{dirname as Sr}from"node:path";function fe(e){try{return Iu(e,"utf8")}catch{return null}}function V(e){let t=fe(e);if(t===null)return null;try{return JSON.parse(_r(t))}catch{return null}}function Te(e,t,n){vr(Sr(e),{recursive:!0});let r=`${e}.${process.pid}.tmp`;if(Tu(r,t,n===void 0?void 0:{mode:n}),Ar(r,e),n!==void 0&&process.platform!=="win32")xr(e,n)}function ie(e,t,n){Te(e,`${JSON.stringify(t,null,2)}
|
|
55
|
+
`,n)}function _t(e,t=".stint-backup"){if(!_u(e)||_u(e+t))return null;return Tu(e+t,Iu(e)),e+t}function _r(e){let t="",n=!1;for(let r=0;r<e.length;r+=1){let s=e[r],o=e[r+1];if(n){if(t+=s,s==="\\")t+=o??"",r+=1;else if(s==='"')n=!1;continue}if(s==='"')n=!0,t+=s;else if(s==="/"&&o==="/"){while(r<e.length&&e[r]!==`
|
|
56
|
+
`)r+=1;t+=`
|
|
57
|
+
`}else if(s==="/"&&o==="*"){r+=2;while(r<e.length&&!(e[r]==="*"&&e[r+1]==="/"))r+=1;r+=1}else t+=s}return t.replace(/,(\s*[}\]])/g,"$1")}var Pe=()=>{};import{homedir as Ir}from"node:os";import{join as v}from"node:path";var X=()=>process.env.STINT_HOME_OVERRIDE??Ir(),Fe=()=>process.env.STINT_HOME??v(X(),".stint"),m;var R=U(()=>{m={config:()=>v(Fe(),"config.json"),state:()=>v(Fe(),"state.json"),queue:()=>v(Fe(),"queue.jsonl"),usageQueue:()=>v(Fe(),"usage.jsonl"),log:()=>v(Fe(),"stint.log"),bin:()=>v(Fe(),"bin","stint.mjs"),claudeSettings:()=>v(process.env.CLAUDE_CONFIG_DIR??v(X(),".claude"),"settings.json"),claudeProjects:()=>v(process.env.CLAUDE_CONFIG_DIR??v(X(),".claude"),"projects"),codexHome:()=>process.env.CODEX_HOME??v(X(),".codex"),geminiHome:()=>v(X(),".gemini"),opencodeConfig:()=>v(process.env.XDG_CONFIG_HOME??v(X(),".config"),"opencode"),opencodeData:()=>v(process.env.XDG_DATA_HOME??v(X(),".local","share"),"opencode"),wakatimeConfig:()=>v(process.env.WAKATIME_HOME??X(),".wakatime.cfg")}});import{hostname as Tr}from"node:os";function It(e){let t=new URL(e.includes("://")?e:`https://${e}`);if(t.protocol!=="https:"&&!["localhost","127.0.0.1","[::1]"].includes(t.hostname))throw Error("Stint only talks to servers over HTTPS (http is allowed for localhost).");return t.origin}function k(){let e=V(m.config())??{},t=process.env.STINT_API_URL??e.apiUrl??Pr;return{apiUrl:It(t),apiKey:process.env.STINT_API_KEY??e.apiKey,username:e.username,email:e.email,machine:e.machine??Tr(),installed:Array.isArray(e.installed)?e.installed.filter((n)=>typeof n==="string"):[],hideProjectNames:e.hideProjectNames===!0}}function De(e){let n={...V(m.config())??{},...e};for(let r of Object.keys(n))if(n[r]===void 0)delete n[r];return ie(m.config(),n,jr),k()}function Tt(e,t){let n=new Set(k().installed);if(t)n.add(e);else n.delete(e);De({installed:[...n].sort()})}var Pr="https://getstint.dev",jr=384;var N=U(()=>{Pe();R()});var ju;var Pu=U(()=>{ju={name:"getstint",version:"0.1.1",description:"Track your coding time and AI agents with Stint: one command connects Claude Code, Codex, Gemini CLI, OpenCode and your editors.",keywords:["stint","time-tracking","wakatime","wakatime-alternative","claude-code","codex","gemini-cli","opencode","ai-agents","cli","developer-tools"],homepage:"https://getstint.dev",bugs:{url:"https://github.com/getstint/stint-cli/issues"},repository:{type:"git",url:"git+https://github.com/getstint/stint-cli.git"},license:"MIT",author:"Stint <hello@getstint.dev> (https://getstint.dev)",type:"module",bin:{stint:"dist/stint.mjs",getstint:"dist/stint.mjs"},files:["dist/stint.mjs","README.md","LICENSE"],engines:{node:">=18.17"},scripts:{build:"bun scripts/build.ts",dev:"bun src/cli.ts",test:"bun test",typecheck:"tsc --noEmit",check:"bun run format:check && bun run typecheck && bun test && bun run build",prepublishOnly:"bun run check",format:"prettier --write .","format:check":"prettier --check ."},devDependencies:{"@clack/prompts":"^0.11.0","@types/bun":"^1.2.22","@types/node":"^22.15.0",picocolors:"^1.1.1",prettier:"3.6.2",typescript:"^5.9.3"},publishConfig:{access:"public"}}});var O,Ou=(e="stint-cli")=>`${e}/${O} (${process.platform}-${process.arch}) node/${process.versions.node}`;var Ce=U(()=>{Pu();O=ju.version});import{spawn as Mr,spawnSync as Mu}from"node:child_process";import{copyFileSync as Ur,existsSync as Hu,mkdirSync as Hr,readFileSync as Rr,realpathSync as Nr,writeFileSync as Wr}from"node:fs";import{dirname as Lr,extname as Gr}from"node:path";import{fileURLToPath as qr}from"node:url";function W(e){return(process.platform==="win32"?Mu("where",[e],{stdio:"ignore",windowsHide:!0}):Mu("sh",["-c",`command -v ${e}`],{stdio:"ignore"})).status===0}function Ru(){try{let e=Nr(qr(import.meta.url));return Gr(e)===".mjs"?e:null}catch{return null}}function je(){try{return Rr(Nu(),"utf8").trim()}catch{return null}}function tt(){let e=m.bin(),t=Ru();if(t&&t!==e&&(je()!==O||!Hu(e)))Hr(Lr(e),{recursive:!0}),Ur(t,e),Wr(Nu(),O);return e}function ee(){return W("node")?"node":process.execPath}function Wu(e){return`${Uu(ee())} ${Uu(m.bin().replace(/\\/g,"/"))} hook ${e}`}function ut(e){let t=Hu(m.bin())?m.bin():Ru();if(!t)return;try{let n=Mr(ee(),[t,...e],{stdio:"ignore",detached:!0,windowsHide:!0,env:process.env});n.on("error",()=>{return}),n.unref()}catch{}}var Nu=()=>`${m.bin()}.version`,Uu=(e)=>/[\s"]/.test(e)?`"${e.replace(/"/g,"\\\"")}"`:e;var te=U(()=>{R();Ce()});function jt(e,t){if(!e.hooks||typeof e.hooks!=="object")return e;let n={};for(let[o,u]of Object.entries(e.hooks)){if(!Array.isArray(u)){n[o]=u;continue}let i=u.map((D)=>D&&Array.isArray(D.hooks)?{...D,hooks:D.hooks.filter((c)=>!Lu(c,t))}:D).filter((D)=>!D||!Array.isArray(D.hooks)||D.hooks.length>0);if(i.length>0)n[o]=i}if(Object.keys(n).length>0)return{...e,hooks:n};let{hooks:r,...s}=e;return s}function Gu(e,t,n){let r=jt(e,t),s={...r.hooks??{}};for(let o of n){let u=o.matcher===void 0?{hooks:[o.handler]}:{matcher:o.matcher,hooks:[o.handler]};s[o.event]=[...s[o.event]??[],u]}return{...r,hooks:s}}function qu(e,t){if(!e?.hooks)return!1;return Object.values(e.hooks).some((n)=>Array.isArray(n)&&n.some((r)=>Array.isArray(r?.hooks)&&r.hooks.some((s)=>Lu(s,t))))}var Vr=(e)=>new RegExp(`stint(\\.mjs)?["']?\\s+hook\\s+${e.replace(/[-]/g,"\\-")}(\\s|$)`),Lu=(e,t)=>{let n=e?.command;return typeof n==="string"&&Vr(t).test(n)};function Vu(e,t){return`import { spawn } from "node:child_process";
|
|
58
|
+
|
|
59
|
+
const NODE = ${JSON.stringify(e)};
|
|
60
|
+
const BIN = ${JSON.stringify(t)};
|
|
61
|
+
const STINT_PLUGIN = "getstint";
|
|
62
|
+
const WATCHED = new Set(["session.created", "session.idle", "session.deleted", "message.updated", "file.edited"]);
|
|
63
|
+
|
|
64
|
+
function send(payload) {
|
|
65
|
+
try {
|
|
66
|
+
const child = spawn(NODE, [BIN, "hook", "opencode"], { stdio: ["pipe", "ignore", "ignore"], detached: true, windowsHide: true });
|
|
67
|
+
child.on("error", () => {});
|
|
68
|
+
child.stdin.on("error", () => {});
|
|
69
|
+
child.stdin.end(JSON.stringify(payload));
|
|
70
|
+
child.unref();
|
|
71
|
+
} catch {}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const StintPlugin = async ({ directory, worktree }) => {
|
|
75
|
+
const cwd = worktree || directory;
|
|
76
|
+
return {
|
|
77
|
+
event: async ({ event }) => {
|
|
78
|
+
if (!event || !WATCHED.has(event.type)) return;
|
|
79
|
+
const props = event.properties || {};
|
|
80
|
+
const info = props.info || {};
|
|
81
|
+
if (event.type === "message.updated" && (info.role !== "assistant" || !info.time || !info.time.completed)) return;
|
|
82
|
+
send({ source: STINT_PLUGIN, hook_event_name: event.type, cwd, session_id: info.sessionID || props.sessionID || info.id || "", file_path: props.file, message: event.type === "message.updated" ? info : undefined });
|
|
83
|
+
},
|
|
84
|
+
"tool.execute.after": async (input, output) => {
|
|
85
|
+
const args = (output && output.metadata && output.metadata.args) || (input && input.args) || {};
|
|
86
|
+
send({ source: STINT_PLUGIN, hook_event_name: "tool.execute.after", cwd, session_id: (input && input.sessionID) || "", tool_name: input && input.tool, file_path: args.filePath || args.path });
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
`}import{existsSync as Kr,readFileSync as Jr}from"node:fs";function Ju(e,t,n,r){let s=e.length?e.replace(/\r\n/g,`
|
|
91
|
+
`).split(`
|
|
92
|
+
`):[],o=`[${t}]`,u=s.findIndex((l)=>l.trim().toLowerCase()===o);if(u===-1){if(s.length&&s[s.length-1].trim()!=="")s.push("");return s.push(o,`${n} = ${r}`),Ku(s)}let i=s.findIndex((l,p)=>p>u&&/^\s*\[.+\]\s*$/.test(l));if(i===-1)i=s.length;let D=new RegExp(`^\\s*${n}\\s*=`,"i"),c=s.findIndex((l,p)=>p>u&&p<i&&D.test(l));if(c!==-1)s[c]=`${n} = ${r}`;else{let l=i;while(l-1>u&&s[l-1].trim()==="")l-=1;s.splice(l,0,`${n} = ${r}`)}return Ku(s)}function zu(e,t,n){return Ju(Ju(e,"settings","api_url",t),"settings","api_key",n)}function zr(e){let t=e.replace(/\r\n/g,`
|
|
93
|
+
`).split(`
|
|
94
|
+
`);if(!t.some((r)=>/^\s*api_url\s*=.*\/api\/compat\/wakatime\/v1\s*$/.test(r)))return e;return t.filter((r)=>!/^\s*api_(url|key)\s*=/.test(r)).join(`
|
|
95
|
+
`)}function Yu(){let e=`${m.wakatimeConfig()}.stint-backup`;return Kr(e)?Jr(e,"utf8"):zr(nt())}var Ot=(e)=>`${e}/api/compat/wakatime/v1`,nt=()=>fe(m.wakatimeConfig())??"",Ku=(e)=>e.join(`
|
|
96
|
+
`).replace(/\n*$/,`
|
|
97
|
+
`);var Qu=U(()=>{Pe();R()});import{spawnSync as Zu}from"node:child_process";import{existsSync as ae,rmSync as Yr}from"node:fs";import{join as Me}from"node:path";function Ht(e){return{id:e.id,name:e.name,kind:"agent",hint:e.hint,detected:e.detected,installed:()=>qu(V(e.file()),e.id),install:()=>{let t=e.file(),r=fe(t)===null?{}:V(t);if(r===null)throw Error(`${t} isn't valid JSON, so Stint left it alone. Fix it and run the install again.`);return _t(t),ie(t,Gu(r,e.id,e.specs())),[`Added Stint hooks to ${t}`,e.after].filter(Boolean).join(". ")},uninstall:()=>{let t=e.file(),n=V(t);if(!n)return`Nothing to remove in ${t}`;return ie(t,jt(n,e.id)),`Removed Stint hooks from ${t}`}}}var Ut=(e)=>({type:"command",command:Wu(e)}),Qr,Zr,Xr,Oe=()=>Me(m.opencodeConfig(),"plugins","stint.js"),es,Mt,Xu="getstint.stint",ts,us,P,Ue=(e)=>P.find((t)=>t.id===e);var rt=U(()=>{N();Pe();R();te();Qu();Qr=Ht({id:"claude-code",name:"Claude Code",hint:"hooks in ~/.claude/settings.json",file:m.claudeSettings,detected:()=>ae(Me(m.claudeSettings(),".."))||W("claude"),specs:()=>{let e={...Ut("claude-code"),async:!0,timeout:30};return[{event:"SessionStart",handler:e},{event:"UserPromptSubmit",handler:e},{event:"PostToolUse",matcher:"*",handler:e},{event:"Stop",handler:e},{event:"SubagentStop",handler:e},{event:"SessionEnd",handler:e}]}}),Zr=Ht({id:"codex",name:"Codex CLI",hint:"hooks in ~/.codex/hooks.json",file:()=>Me(m.codexHome(),"hooks.json"),detected:()=>ae(m.codexHome())||W("codex"),specs:()=>{let e={...Ut("codex"),async:!0,statusMessage:"Stint"};return[{event:"SessionStart",handler:e},{event:"UserPromptSubmit",handler:e},{event:"PostToolUse",matcher:"*",handler:e},{event:"Stop",handler:e}]},after:"Codex asks you to trust new hooks once: run /hooks in Codex and approve the Stint entries"}),Xr=Ht({id:"gemini-cli",name:"Gemini CLI",hint:"hooks in ~/.gemini/settings.json",file:()=>Me(m.geminiHome(),"settings.json"),detected:()=>ae(m.geminiHome())||W("gemini"),specs:()=>{let e={...Ut("gemini-cli"),name:"stint",timeout:5000};return[{event:"SessionStart",handler:e},{event:"BeforeAgent",handler:e},{event:"AfterTool",matcher:".*",handler:e},{event:"AfterAgent",handler:e},{event:"SessionEnd",handler:e}]}}),es={id:"opencode",name:"OpenCode",kind:"agent",hint:"plugin in ~/.config/opencode/plugins",detected:()=>ae(m.opencodeConfig())||ae(m.opencodeData())||W("opencode"),installed:()=>fe(Oe())?.includes("STINT_PLUGIN")??!1,install:()=>(Te(Oe(),Vu(ee(),m.bin())),`Wrote ${Oe()}`),uninstall:()=>(Yr(Oe(),{force:!0}),`Removed ${Oe()}`)},Mt=["code","cursor","windsurf","codium","code-insiders"],ts={id:"editors",name:"VS Code, Cursor and Windsurf",kind:"editor",hint:"installs the Stint extension",detected:()=>Mt.some(W),installed:()=>!1,install:()=>Mt.filter(W).map((t)=>Zu(t,["--install-extension",Xu,"--force"],{stdio:"ignore",shell:process.platform==="win32",timeout:120000}).status===0?`${t}: installed`:`${t}: couldn't install, get it at https://marketplace.visualstudio.com/items?itemName=getstint.stint`).join(", ")||"No editor command line found",uninstall:()=>(Mt.filter(W).forEach((e)=>Zu(e,["--uninstall-extension",Xu],{stdio:"ignore",shell:process.platform==="win32",timeout:60000})),"Removed the Stint extension")},us={id:"wakatime",name:"WakaTime plugins",kind:"editor",hint:"JetBrains, Neovim, Zed, Xcode, Sublime, Emacs and 50 more, through ~/.wakatime.cfg",detected:()=>ae(m.wakatimeConfig())||ae(Me(m.wakatimeConfig(),"..",".wakatime")),installed:()=>nt().includes(Ot(k().apiUrl)),install:()=>{let e=k();if(!e.apiKey)throw Error("Sign in first so Stint has a key to give your WakaTime plugins.");return _t(m.wakatimeConfig()),Te(m.wakatimeConfig(),zu(nt(),Ot(e.apiUrl),e.apiKey),384),`Pointed ${m.wakatimeConfig()} at Stint (your old file is saved as .wakatime.cfg.stint-backup)`},uninstall:()=>(Te(m.wakatimeConfig(),Yu(),384),`Restored ${m.wakatimeConfig()}`)},P=[Qr,Zr,Xr,es,ts,us]});async function Kt(){let e=P.filter((r)=>r.kind==="agent"),t=P.filter((r)=>r.kind==="editor"),n=await Su({message:"What should Stint track?",options:{"AI agents":e.map((r)=>({value:r.id,label:r.name,hint:r.installed()?"connected":r.detected()?r.hint:"not found on this machine"})),Editors:t.map((r)=>({value:r.id,label:r.name,hint:r.installed()?"connected":r.hint}))},initialValues:P.filter((r)=>r.installed()||r.detected()&&r.kind==="agent").map((r)=>r.id),required:!1});if(Q(n))return null;return n.map((r)=>Ue(r)).filter((r)=>Boolean(r))}function ct(e){tt();let t=0,n=0;for(let r of e)try{let s=r.install();Tt(r.id,!0),f.success(`${pe.default.bold(r.name)} ${pe.default.dim(s)}`),t+=1}catch(s){f.error(`${pe.default.bold(r.name)} ${s instanceof Error?s.message:String(s)}`),n+=1}return{ok:t,failed:n}}async function lt(e,t){if(e.length===0&&!t){let r=await Kt();if(!r)return et("Nothing changed.");ct(r);return}let n=e.filter((r)=>!Ue(r));if(n.length)throw Error(`Unknown integration: ${n.join(", ")}. Try: ${P.map((r)=>r.id).join(", ")}`);ct(t?P.filter((r)=>r.detected()):e.map((r)=>Ue(r)))}function En(e){let t=e.length?e.map((n)=>Ue(n)).filter((n)=>Boolean(n)):P.filter((n)=>n.installed());if(t.length===0)return f.info("Nothing is connected.");for(let n of t)try{f.success(`${pe.default.bold(n.name)} ${pe.default.dim(n.uninstall())}`),Tt(n.id,!1)}catch(r){f.error(`${pe.default.bold(n.name)} ${r instanceof Error?r.message:String(r)}`)}}var pe;var pt=U(()=>{Z();rt();N();te();pe=M(G(),1)});Z();var x=M(G(),1);Z();rt();var tn=M(G(),1);import{existsSync as en}from"node:fs";Ce();class ne extends Error{status;code;constructor(e,t,n){super(e);this.status=t;this.code=n}}var st="stint-cli",ns=1e4;async function ue(e,t,n={}){let r={accept:"application/json","user-agent":n.agent??Ou()},s=n.token??e.apiKey;if(s)r.authorization=`Bearer ${s}`;if(n.body!==void 0)r["content-type"]="application/json";let o;try{o=await fetch(`${e.apiUrl}${t}`,{method:n.method??(n.body===void 0?"GET":"POST"),headers:r,body:n.body===void 0?void 0:JSON.stringify(n.body),signal:AbortSignal.timeout(n.timeoutMs??ns)})}catch(D){let c=D instanceof Error&&D.name==="TimeoutError"?"timed out":"couldn't connect";throw new ne(`Stint ${c} (${e.apiUrl}).`,0,"network")}let u=await o.text(),i=null;try{i=u?JSON.parse(u):null}catch{}if(!o.ok){let D=i??{},c=typeof D.error==="string"&&/^[a-z_]+$/.test(D.error)?D.error:void 0;throw new ne(D.error_description??D.message??D.error??`Stint answered ${o.status}.`,o.status,c)}return i}var S={deviceCode:(e,t=st)=>ue({apiUrl:e.apiUrl},"/api/auth/device/code",{body:{client_id:t,scope:"heartbeats usage"}}),deviceToken:(e,t,n=st)=>ue({apiUrl:e.apiUrl},"/api/auth/device/token",{body:{grant_type:"urn:ietf:params:oauth:grant-type:device_code",device_code:t,client_id:n}}),mintKey:(e,t,n)=>ue({apiUrl:e.apiUrl},"/api/v1/me/api-keys",{token:t,body:{name:n}}),signOutSession:(e,t)=>ue({apiUrl:e.apiUrl},"/api/auth/sign-out",{token:t,body:{}}).catch(()=>{return}),me:(e)=>ue(e,"/api/v1/me"),today:(e)=>ue(e,"/api/compat/wakatime/v1/users/current/statusbar/today"),heartbeats:(e,t,n)=>ue(e,"/api/v1/heartbeats",{body:t,agent:n,timeoutMs:8000}),usage:(e,t)=>ue(e,"/api/v1/usage",{body:{samples:t},timeoutMs:15000})};N();R();te();async function un(){let e=k(),t=[],[n]=process.versions.node.split(".").map(Number);t.push({label:`Node ${process.versions.node}`,ok:n>=18,fix:"Install Node 18 or newer from nodejs.org"}),t.push({label:`Hooks run with ${ee()}`,ok:ee()==="node"||en(ee()),fix:"Put node on your PATH so agents can run the Stint hook"}),t.push({label:`Hook script at ${m.bin()}`,ok:en(m.bin()),fix:"Run npx getstint install"});try{await S.me(e),t.push({label:`Reached ${e.apiUrl} and the key works`,ok:!0})}catch(r){t.push({label:`Reaching ${e.apiUrl}`,ok:!1,fix:r instanceof Error?r.message:String(r)})}for(let r of P.filter((s)=>s.installed()))t.push({label:`${r.name} connected`,ok:!0});if(P.find((r)=>r.id==="codex")?.installed())t.push({label:"Codex hooks need one approval",ok:W("codex"),fix:"Open Codex, run /hooks and trust the Stint entries"});for(let r of t)if(r.ok)f.success(r.label);else f.error(`${r.label}${r.fix?tn.default.dim(` ${r.fix}`):""}`);return t.every((r)=>r.ok)}import{readFileSync as Fs,statSync as Cs}from"node:fs";var y=(e)=>typeof e==="number"&&Number.isFinite(e)&&e>0?Math.round(e):0,K=(e)=>{if(typeof e==="number"&&Number.isFinite(e))return e>1000000000000?e/1000:e;if(typeof e==="string"){let t=Date.parse(e);return Number.isFinite(t)?t/1000:null}return null};function ot(e){let t=[];for(let n of e.split(`
|
|
98
|
+
`)){if(!n.trim())continue;try{t.push(JSON.parse(n))}catch{}}return t}var b=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{},F=(e)=>typeof e==="string"?e:void 0;function J(e,t,n,r,s){return{entity:`${e}:${r}`,type:"app",category:"ai coding",time:t,project:n||void 0,agent:e,ai_session:r,ai_model:s}}var ce="claude-code";function nn(e,t){let n=new Map,r=[],s=new Set;for(let o of ot(e)){let u=b(o);if(u.type!=="assistant")continue;let i=b(u.message),D=b(i.usage),c=F(i.id)??F(u.requestId)??F(u.uuid),l=F(i.model),p=K(u.timestamp);if(!c||!p||!l||l.startsWith("<"))continue;let d=t.projectOf(F(u.cwd)),g=F(u.sessionId)??"claude",h={source_id:`claude:${c}`,time:p,agent:ce,model:l,project:d,input_tokens:y(D.input_tokens),output_tokens:y(D.output_tokens),cache_read_tokens:y(D.cache_read_input_tokens),cache_write_tokens:y(D.cache_creation_input_tokens)},_=n.get(h.source_id);if(!_||h.output_tokens>=_.output_tokens)n.set(h.source_id,_?{...h,time:_.time}:h);let q=`${g}|${Math.floor(p)}`;if(!s.has(q))s.add(q),r.push(J(ce,p,d,g,l))}return{samples:[...n.values()],heartbeats:r,carry:{}}}var z="codex";function rn(e,t){let n=y(e.cached_input_tokens);return{...t,input_tokens:Math.max(0,y(e.input_tokens)-n),output_tokens:y(e.output_tokens),cache_read_tokens:n,cache_write_tokens:y(e.cache_write_input_tokens)}}function sn(e,t){let n={...t.carry??{}},r=new Map,s=[],o=[],u=[];for(let D of ot(e)){let c=b(D),l=b(c.payload),p=K(c.timestamp);if(c.type==="session_meta"){if(n.session=F(l.id)??n.session??"",n.cwd=F(l.cwd)??n.cwd??"",b(l.source).subagent)n.subagent="1";continue}if(c.type==="turn_context"){let h=F(l.model);if(h){n.model=h;let _=F(l.turn_id);if(_)r.set(_,h)}n.cwd=F(l.cwd)??n.cwd??"";continue}if(!p)continue;let d=t.projectOf(n.cwd||void 0),g=n.session||"codex";if(c.type==="token_usage_record"){let h=F(l.response_id);if(!h)continue;n.records="1";let _=r.get(F(l.turn_id)??"")??n.model??"unknown";s.push(rn(b(l.usage),{source_id:`codex:${h}`,time:p,agent:z,model:_,project:d})),u.push(J(z,p,d,g,_));continue}if(c.type==="event_msg"&&l.type==="token_count"){let h=b(l.info),_=b(h.total_token_usage),q=b(h.last_token_usage),se=y(_.total_tokens);if(!se||!Object.keys(q).length||n.lastTotal===String(se))continue;if(n.lastTotal=String(se),o.push(rn(q,{source_id:`codex:${g}:${se}`,time:p,agent:z,model:n.model??"unknown",project:d})),n.records!=="1")u.push(J(z,p,d,g,n.model))}}return{samples:(n.records==="1"?s:o).filter((D)=>D.input_tokens+D.output_tokens+D.cache_read_tokens>0),heartbeats:u,carry:n}}var le="gemini-cli";function on(e,t){let n;try{n=b(JSON.parse(e))}catch{return{samples:[],heartbeats:[],carry:{}}}let r=F(n.sessionId)??"gemini",s=t.projectOf(t.cwd),o=[],u=[];for(let i of Array.isArray(n.messages)?n.messages:[]){let D=b(i);if(D.type!=="gemini")continue;let c=F(D.id),l=K(D.timestamp),p=b(D.tokens);if(!c||!l)continue;let d=F(D.model)??"gemini",g=y(p.cached),h={source_id:`gemini:${r}:${c}`,time:l,agent:le,model:d,project:s,input_tokens:Math.max(0,y(p.input)-g),output_tokens:y(p.output)+y(p.thoughts),cache_read_tokens:g,cache_write_tokens:0};if(h.input_tokens+h.output_tokens+h.cache_read_tokens>0)o.push(h);u.push(J(le,l,s,r,d))}return{samples:o,heartbeats:u,carry:{}}}import{existsSync as ss,readFileSync as Dn,statSync as os}from"node:fs";import{basename as is,dirname as Ds,isAbsolute as as,join as Rt,resolve as Nt}from"node:path";function cs(e){let t=Rt(e,".git");try{if(os(t).isDirectory())return t;let n=/^gitdir:\s*(.+)$/m.exec(Dn(t,"utf8"))?.[1]?.trim();if(!n)return null;return as(n)?n:Nt(e,n)}catch{return null}}function ls(e){let t=Nt(e);for(let n=0;n<64;n+=1){if(ss(Rt(t,".git")))return t;let r=Ds(t);if(r===t)return null;t=r}return null}function ps(e){let t=cs(e);if(!t)return;try{let n=Dn(Rt(t,"HEAD"),"utf8").trim();return/^ref:\s*refs\/heads\/(.+)$/.exec(n)?.[1]??void 0}catch{return}}function Ee(e){if(!e)return null;let t=ls(e)??Nt(e),n=is(t);if(!n)return null;return{root:t,name:n,branch:ps(t)}}import{closeSync as ms,openSync as ds,readSync as hs,statSync as gs}from"node:fs";var fs=33554432;function an(e,t){let n;try{n=gs(e).size}catch{return null}let r=t&&t.offset<=n?t.offset:0,s=t&&t.offset<=n?t.carry:void 0;if(r===n)return{content:"",cursor:{offset:r,size:n,carry:s}};let o=Math.min(n-r,fs),u=Buffer.alloc(o),i=ds(e,"r");try{hs(i,u,0,o,r)}finally{ms(i)}let D=u.lastIndexOf(10);if(D===-1)return{content:"",cursor:{offset:r,size:n,carry:s}};return{content:u.subarray(0,D+1).toString("utf8"),cursor:{offset:r+D+1,size:n,carry:s}}}var Wt=new Map;function ye(e){if(!e)return"";if(!Wt.has(e))Wt.set(e,Ee(e)?.name??"");return Wt.get(e)}var He={samples:[],heartbeats:[],carry:{}};function be(e,t,n,r){if(e===le){let i=0;try{i=Cs(t).size}catch{return He}if(n.cursors[t]?.size===i)return He;n.cursors[t]={offset:i,size:i};try{return on(Fs(t,"utf8"),{projectOf:ye,cwd:r})}catch{return He}}let s=e===ce?nn:e===z?sn:null;if(!s)return He;let o=an(t,n.cursors[t]);if(!o||!o.content){if(o)n.cursors[t]=o.cursor;return He}let u=s(o.content,{projectOf:ye,carry:o.cursor.carry});return n.cursors[t]={...o.cursor,carry:Object.keys(u.carry).length?u.carry:void 0},u}N();import{isAbsolute as cn,relative as Es,resolve as ys}from"node:path";var bs=/^(write|edit|multiedit|notebookedit|apply_patch|write_file|replace|edit_file|create_file|str_replace|patch)$/i,$s=new Set(["stop","subagentstop","sessionend","afteragent","session.idle","session.deleted","agent-turn-complete"]),ln=(e)=>$s.has((e??"").toLowerCase());function ws(e){let t=e.tool_input??{},n=e.file_path??t.file_path??t.filePath??t.path??t.notebook_path??t.absolute_path;return typeof n==="string"&&n.length<1000?n:void 0}function it(e,t,n,r){let s=(t.session_id||"session").slice(0,120),o={category:"ai coding",time:n,project:r?.name,branch:r?.branch,agent:e,ai_session:s,ai_model:t.model},u=ws(t);if(u&&r){let i=cn(u)?u:ys(t.cwd??r.root,u),D=Es(r.root,i);if(D&&!D.startsWith("..")&&!cn(D))return{...o,entity:D.replace(/\\/g,"/"),type:"file",is_write:bs.test(t.tool_name??"")||t.hook_event_name==="file.edited"}}return{...o,entity:`${e}:${s}`,type:"app"}}R();import{appendFileSync as ks,mkdirSync as Bs,renameSync as xs,statSync as vs}from"node:fs";import{dirname as As}from"node:path";var Ss=1048576;function pn(e){let t=m.log();try{Bs(As(t),{recursive:!0});try{if(vs(t).size>Ss)xs(t,`${t}.1`)}catch{}ks(t,`${new Date().toISOString()} ${e.replace(/\s+/g," ").slice(0,2000)}
|
|
99
|
+
`)}catch{}}te();R();import{appendFileSync as dn,existsSync as _s,mkdirSync as Is,readFileSync as Gt,readdirSync as Ts,renameSync as Ps,rmSync as Lt,statSync as js,writeFileSync as Zi}from"node:fs";import{basename as Os,dirname as hn,join as Ms}from"node:path";var mn=20000,Us=600000;function Dt(e,t){if(t.length===0)return;Is(hn(e),{recursive:!0}),dn(e,t.map((n)=>JSON.stringify(n)).join(`
|
|
100
|
+
`)+`
|
|
101
|
+
`)}function Hs(e){let t=[];for(let n of e.split(`
|
|
102
|
+
`)){if(!n.trim())continue;try{t.push(JSON.parse(n))}catch{}}return t}function Rs(e){let t=hn(e),n=`${Os(e)}.claim-`,r=[];try{r=Ts(t).filter((s)=>s.startsWith(n))}catch{return}for(let s of r){let o=Ms(t,s);try{if(Date.now()-js(o).mtimeMs<Us)continue;dn(e,Gt(o,"utf8")),Lt(o,{force:!0})}catch{}}}function gn(e){if(Rs(e),!_s(e))return null;let t=`${e}.claim-${process.pid}-${Date.now()}`;try{Ps(e,t)}catch{return null}return{items:Hs(Gt(t,"utf8")).slice(-mn),done:()=>Lt(t,{force:!0}),release:(s)=>{Lt(t,{force:!0}),Dt(e,s.slice(-mn))}}}function qt(e){try{return Gt(e,"utf8").split(`
|
|
103
|
+
`).filter((t)=>t.trim()).length}catch{return 0}}Pe();R();function re(){let e=V(m.state())??{};return{cursors:e.cursors&&typeof e.cursors==="object"?e.cursors:{},lastFlush:e.lastFlush,lastError:e.lastError,authFailed:e.authFailed}}function $e(e){let t=Object.entries(e.cursors),n=t.length>2000?Object.fromEntries(t.slice(-2000)):e.cursors;ie(m.state(),{...e,cursors:n})}var Ns=500,Ws=1000,Ls=(e)=>e instanceof ne&&(e.status===0||e.status===401||e.status===429||e.status>=500);async function fn(e,t,n){let r=gn(e);if(!r)return{sent:0};let s=0;for(let o=0;o<r.items.length;o+=t){let u=r.items.slice(o,o+t);try{await n(u),s+=u.length}catch(i){if(Ls(i))return r.release(r.items.slice(o)),{sent:s,error:i}}}return r.done(),{sent:s}}function we(e){Dt(m.queue(),e)}function Re(e){Dt(m.usageQueue(),e)}async function at(e,t){let n=re();if(!e.apiKey)return{sent:0,samples:0,queued:!0,error:"Not signed in. Run `npx getstint login`."};let r=await fn(m.queue(),Ns,(i)=>S.heartbeats(e,i,t)),s=r.error?{sent:0,error:r.error}:await fn(m.usageQueue(),Ws,(i)=>S.usage(e,i)),o=r.error??s.error,u=o instanceof Error?o.message:void 0;return $e({...n,lastFlush:o?n.lastFlush:Date.now(),lastError:u?{at:Date.now(),message:u}:void 0,authFailed:o instanceof ne&&o.status===401}),{sent:r.sent,samples:s.sent,queued:Boolean(o),error:u}}var ke="opencode";function Vt(e,t){let n=b(e),r=b(n.time),s=b(n.path),o=b(n.tokens),u=b(o.cache),i=F(n.sessionID)??"opencode",D=t.projectOf(F(s.root)??F(s.cwd)),c=K(r.completed)??K(r.created),l=F(n.id),p=F(n.modelID);if(n.role!=="assistant"||!l||!c||!p)return{sample:null,time:c,session:i,project:D,model:p};let d={source_id:`opencode:${l}`,time:c,agent:ke,model:p,project:D,input_tokens:y(o.input),output_tokens:y(o.output)+y(o.reasoning),cache_read_tokens:y(u.read),cache_write_tokens:y(u.write)};return{sample:d.input_tokens+d.output_tokens+d.cache_read_tokens+d.cache_write_tokens===0||!r.completed?null:d,time:c,session:i,project:D,model:p}}function Fn(e,t){let n=[],r=[];for(let s of e){let o;try{o=JSON.parse(s)}catch{continue}let{sample:u,time:i,session:D,project:c,model:l}=Vt(o,t);if(u)n.push(u);if(i&&l)r.push(J(ke,i,c,D,l))}return{samples:n,heartbeats:r,carry:{}}}var Gs=60000,qs=4194304;async function Vs(e){if(process.stdin.isTTY)return"";return new Promise((t)=>{let n="",r=()=>t(n),s=setTimeout(r,e);process.stdin.setEncoding("utf8"),process.stdin.on("data",(o)=>{if(n.length<qs)n+=o}),process.stdin.on("end",()=>{clearTimeout(s),r()}),process.stdin.on("error",()=>{clearTimeout(s),r()})})}async function Cn(e){try{if(!e||!/^[a-z0-9-]{2,40}$/.test(e))return;let t=await Vs(2000),n={};try{n=t.trim()?JSON.parse(t):{}}catch{n={}}let r=k();if(!r.apiKey)return;let s=Date.now()/1000,o=n.cwd??n.workspace_roots?.[0]??process.cwd(),u=Ee(o);we([{...it(e,{...n,cwd:o},s,u),machine:r.machine}]);let i=re(),D=ln(n.hook_event_name);if(e===ke&&n.message){let{sample:c}=Vt(n.message,{projectOf:ye});if(c)Re([c])}else if(D&&n.transcript_path){let c=be(e,n.transcript_path,i,o);Re(c.samples)}if($e(i),D||!i.lastFlush||Date.now()-i.lastFlush>Gs)ut(["flush","--quiet",`--agent=${e}`])}catch(t){pn(`hook ${e}: ${t instanceof Error?t.stack??t.message:String(t)}`)}}pt();Z();var me=M(G(),1);import{hostname as Zs}from"node:os";N();te();var Ne=M(G(),1);import{spawn as Ks,spawnSync as Js}from"node:child_process";var zs=/truecolor|24bit/i.test(process.env.COLORTERM??"")||process.env.TERM_PROGRAM==="vscode"||process.env.WT_SESSION!==void 0,Ys=(e)=>!Ne.default.isColorSupported?e:zs?`\x1B[38;2;255;178;36m${e}\x1B[39m`:Ne.default.yellow(e),Qs=()=>Ys("◔"),Be=()=>`${Qs()} ${Ne.default.bold("stint")}`;function yn(e){let t=Math.round(e/60);if(t<1)return"0m";let n=Math.floor(t/60);return n?`${n}h ${t%60}m`:`${t}m`}function xe(e){if(e>=1e9)return`${(e/1e9).toFixed(1)}B`;if(e>=1e6)return`${(e/1e6).toFixed(1)}M`;if(e>=1000)return`${(e/1000).toFixed(1)}K`;return String(e)}var We=()=>Boolean(process.stdin.isTTY&&process.stdout.isTTY)&&process.env.CI===void 0;function bn(){if(process.env.STINT_NO_BROWSER||process.env.CI||process.env.SSH_CONNECTION||process.env.SSH_TTY)return!1;if(process.platform==="linux")return Boolean(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)&&!process.env.WSL_DISTRO_NAME;return!0}function Jt(e,t){try{let n=Ks(e,t,{stdio:"ignore",detached:!0,windowsHide:!0});return n.on("error",()=>{return}),n.unref(),!0}catch{return!1}}function zt(e){if(!/^https?:\/\//.test(e))return!1;if(process.platform==="win32")return Jt("rundll32",["url.dll,FileProtocolHandler",e]);if(process.platform==="darwin")return Jt("open",[e]);return Jt("xdg-open",[e])}function $n(e){let t=process.platform==="win32"?[["clip",[]]]:process.platform==="darwin"?[["pbcopy",[]]]:[["wl-copy",[]],["xclip",["-selection","clipboard"]],["xsel",["--clipboard","--input"]]];for(let[n,r]of t)try{if(Js(n,r,{input:e,stdio:["pipe","ignore","ignore"],windowsHide:!0,timeout:2000}).status===0)return!0}catch{}return!1}function ve(e,t=e){if(!process.stdout.isTTY||process.env.TERM==="dumb")return e;return`\x1B]8;;${e}\x07${Ne.default.underline(t)}\x1B]8;;\x07`}var Xs=(e)=>new Promise((t)=>setTimeout(t,e));function eo(e,t){let n=new URL("/device",e.apiUrl);return n.searchParams.set("user_code",t),n.searchParams.set("client",st),n.toString()}var to=(e)=>e.length===8?`${e.slice(0,4)}-${e.slice(4)}`:e;async function wn(e,t){let n=await S.me({...e,apiKey:t});return tt(),De({apiUrl:e.apiUrl,apiKey:t,username:n.username,email:n.email})}async function uo(e,t,n,r,s){let o=Math.max(n,2)*1000,u=Date.now()+r*1000;while(Date.now()<u){await Xs(o);try{let{access_token:i}=await S.deviceToken(e,t);return i}catch(i){if(!(i instanceof ne))throw i;if(i.code==="authorization_pending"||i.status===0)continue;if(i.code==="slow_down"){o+=5000;continue}if(i.code==="access_denied")throw Error("Sign-in was denied in the browser.");if(i.code==="expired_token")throw Error("The code expired. Run the command again for a new one.");throw i}}throw s.stop("Timed out"),Error("The code expired before it was approved. Run the command again for a new one.")}async function mt(e={}){let t=k(),n={...t,apiUrl:e.apiUrl?It(e.apiUrl):t.apiUrl};if(e.key){let l=Ie();l.start("Checking your key");try{let p=await wn(n,e.key.trim());return l.stop(`Signed in as ${me.default.bold(p.username??"you")}`),p}catch(p){throw l.stop("That key didn’t work",1),p}}let r=await S.deviceCode(n),s=eo(n,r.user_code),o=to(r.user_code),u=e.browser!==!1&&bn(),i=We()&&$n(s);if(Xe([`${me.default.dim("Your code")} ${me.default.bold(me.default.white(o))}`,"",u?"Approve this sign-in in the browser window that just opened.":"Open this link on any device and approve the sign-in:",ve(s),i?me.default.dim("The link is on your clipboard."):""].filter((l,p,d)=>l!==""||p>0&&d[p-1]!=="").join(`
|
|
104
|
+
`),"Connect this machine"),u)if(We()){let l=await Ze({message:"Open the browser now?",initialValue:!0});if(Q(l))throw Error("Cancelled.");if(l)zt(s)}else zt(s);let D=Ie();D.start("Waiting for you to approve in the browser");let c=await uo(n,r.device_code,r.interval,r.expires_in,D);D.message("Creating a key for this machine");try{let{key:l}=await S.mintKey(n,c,`${Zs()} · CLI`.slice(0,60)),p=await wn(n,l);return D.stop(`Signed in as ${me.default.bold(p.username??"you")}`),p}finally{await S.signOutSession(n,c)}}N();import{spawn as no}from"node:child_process";te();var ro=60000,so={grok:"grok-cli",copilot:"copilot-cli",amp:"amp",qwen:"qwen-code",kiro:"kiro",cline:"cline"};async function kn(e){let t=e.indexOf("--"),[n,...r]=t===-1?e:[e[0],...e.slice(t+1)];if(!n)throw Error("Usage: stint run <agent> [-- command args] e.g. stint run grok");let s=so[n]??n,o=t===-1?[n,...r]:r,u=k(),i=`${s}-${Date.now().toString(36)}`,D=Ee(process.cwd()),c=()=>{if(!u.apiKey)return;we([{...it(s,{session_id:i,cwd:process.cwd()},Date.now()/1000,D),machine:u.machine}]),ut(["flush","--quiet",`--agent=${s}`])};c();let l=setInterval(c,ro),p=no(o[0],o.slice(1),{stdio:"inherit",shell:process.platform==="win32"}),d=await new Promise((g)=>{p.on("exit",(h)=>g(h??0)),p.on("error",()=>g(127))});return clearInterval(l),c(),d}Z();var Qt=M(G(),1);N();Ce();pt();Z();var Yt=M(G(),1);import{readdirSync as oo,readFileSync as io,statSync as xn}from"node:fs";import{join as Le}from"node:path";N();R();var Bn=395;function Ge(e,t,n,r=0,s=[]){if(r>6)return s;let o;try{o=oo(e,{withFileTypes:!0})}catch{return s}for(let u of o){let i=Le(e,u.name);if(u.isDirectory())Ge(i,t,n,r+1,s);else if(t(u.name))try{if(xn(i).mtimeMs>=n)s.push(i)}catch{}}return s}function Do(e=Bn){let t=Date.now()-Math.min(e,Bn)*86400000,n=re(),r=[],s=[],o=[],u=(D,c,l)=>{let p=l.samples.filter((g)=>g.time*1000>=t);r.push(...p),s.push(...l.heartbeats.filter((g)=>g.time*1000>=t));let d=o.find((g)=>g.agent===D)??o[o.push({agent:D,files:0,samples:0,tokens:0})-1];d.files+=c,d.samples+=p.length,d.tokens+=p.reduce((g,h)=>g+h.input_tokens+h.output_tokens+h.cache_read_tokens+h.cache_write_tokens,0)};for(let D of Ge(m.claudeProjects(),(c)=>c.endsWith(".jsonl"),t))u(ce,1,be(ce,D,n));for(let D of[Le(m.codexHome(),"sessions"),Le(m.codexHome(),"archived_sessions")])for(let c of Ge(D,(l)=>l.endsWith(".jsonl"),t))u(z,1,be(z,c,n));for(let D of Ge(Le(m.geminiHome(),"tmp"),(c)=>c.endsWith(".json")&&c.startsWith("session-"),t))u(le,1,be(le,D,n));let i=Ge(Le(m.opencodeData(),"storage","message"),(D)=>D.endsWith(".json"),t).filter((D)=>{try{let c=xn(D).mtimeMs;if(n.cursors[D]?.size===c)return!1;return n.cursors[D]={offset:0,size:c},!0}catch{return!1}});if(i.length){let D=i.map((c)=>{try{return io(c,"utf8")}catch{return""}});u(ke,i.length,Fn(D,{projectOf:ye}))}return $e(n),{samples:r,heartbeats:s,totals:o}}async function dt(e={}){let t=k();if(!t.apiKey)throw Error("Sign in first: npx getstint login");let n=e.quiet?null:Ie();n?.start("Reading your agent history");let{samples:r,heartbeats:s,totals:o}=Do(e.days);Re(r),we(s.map((i)=>({...i,machine:t.machine}))),n?.message(`Sending ${xe(r.length)} usage records`);let u=await at(t);if(!n)return u;n.stop(u.error?`Saved for later: ${u.error}`:`Synced ${xe(u.samples)} usage records and ${xe(u.sent)} activity events`);for(let i of o.filter((D)=>D.samples>0))f.info(`${Yt.default.bold(i.agent)} ${Yt.default.dim(`${i.files} files · ${xe(i.samples)} records · ${xe(i.tokens)} tokens`)}`);return u}async function vn(e){Se(`${Be()} ${Qt.default.dim(`v${O}`)}`);let t=k(),n=!1;if(t.apiKey&&!e.key&&!e.apiUrl)try{let r=await S.me(t);f.success(`Signed in as ${Qt.default.bold(r.username)}`),n=!0}catch{f.warn("Your saved key no longer works, so let’s sign in again.")}if(!n)t=await mt(e);if(!We()||e.yes){await Promise.resolve().then(() => pt());await lt([],!0)}else{let r=await Kt();if(r===null){et("Signed in. Connect tools any time with `npx getstint install`.");return}if(r.length)ct(r);let s=await Ze({message:"Import token usage from your past agent sessions?",initialValue:!0});if(!Q(s)&&s)await dt()}_e(`You’re set. Your dashboard: ${ve(`${t.apiUrl}/dashboard`)}`)}Z();rt();var B=M(G(),1);N();R();te();Ce();async function An(){let e=k(),t=re(),n=[];if(!e.apiKey)n.push(`${B.default.yellow("●")} Not signed in. Run ${B.default.bold("npx getstint login")}.`);else try{let[s,o]=await Promise.all([S.me(e),S.today(e).catch(()=>null)]);if(s.username!==e.username)De({username:s.username,email:s.email});if(n.push(`${B.default.green("●")} Signed in as ${B.default.bold(s.username)} ${B.default.dim(s.email)}`),o)n.push(`${B.default.dim("Today")} ${B.default.bold(yn(o.data.grand_total.total_seconds))}`)}catch(s){n.push(`${B.default.red("●")} ${s instanceof Error?s.message:String(s)}`)}n.push("");for(let s of P){let o=s.installed()?B.default.green("✓"):s.detected()?B.default.yellow("○"):B.default.dim("·");n.push(`${o} ${s.name}${s.installed()?"":B.default.dim(s.detected()?" found, not connected":" not found")}`)}n.push("");let r=qt(m.queue())+qt(m.usageQueue());if(n.push(`${B.default.dim("Server")} ${e.apiUrl}`),n.push(`${B.default.dim("Version")} ${O}${je()&&je()!==O?B.default.dim(` (hooks use ${je()})`):""}`),n.push(`${B.default.dim("Waiting")} ${r?`${r} events will send when Stint is reachable`:"nothing queued"}`),t.lastFlush)n.push(`${B.default.dim("Last sent")} ${new Date(t.lastFlush).toLocaleString()}`);if(t.lastError)n.push(`${B.default.dim("Last error")} ${B.default.red(t.lastError.message)}`);if(Xe(n.join(`
|
|
105
|
+
`),"Stint"),e.apiKey)f.message(`Dashboard: ${ve(`${e.apiUrl}/dashboard`)}`)}function Sn(e){let t=[],n={},r;for(let s=0;s<e.length;s+=1){let o=e[s];if(o==="--"){t.push(...e.slice(s));break}if(o.startsWith("--")){let[u,i]=o.slice(2).split(/=(.*)/s,2);if(u.startsWith("no-"))n[u.slice(3)]=!1;else if(i!==void 0)n[u]=i;else if(["key","api-url","days","agent"].includes(u)&&e[s+1]&&!e[s+1].startsWith("-"))n[u]=e[++s];else n[u]=!0;continue}if(o==="-h")n.help=!0;else if(o==="-v")n.version=!0;else if(o==="-y")n.yes=!0;else if(r===void 0)r=o;else t.push(o)}return{command:r,positionals:t,flags:n}}N();Ce();var _n=`${Be()} ${x.default.dim(`v${O}`)} Coding time and AI agent tracking for getstint.dev
|
|
106
|
+
|
|
107
|
+
${x.default.bold("Usage")} npx getstint [command]
|
|
108
|
+
|
|
109
|
+
${x.default.bold("Commands")}
|
|
110
|
+
${x.default.cyan("(none)")} Sign in, pick what to track, import past agent usage
|
|
111
|
+
${x.default.cyan("login")} Connect this machine ${x.default.dim("--no-browser --key <key> --api-url <url>")}
|
|
112
|
+
${x.default.cyan("logout")} Forget the key on this machine
|
|
113
|
+
${x.default.cyan("status")} Who you are, today's time and what's connected
|
|
114
|
+
${x.default.cyan("install")} [ids] Connect agents and editors ${x.default.dim("--all")}
|
|
115
|
+
${x.default.cyan("uninstall")} [ids] Disconnect them again
|
|
116
|
+
${x.default.cyan("sync")} Import token usage from past agent sessions ${x.default.dim("--days <n>")}
|
|
117
|
+
${x.default.cyan("run")} <agent> Track any CLI agent by wrapping it ${x.default.dim("stint run grok")}
|
|
118
|
+
${x.default.cyan("flush")} Send anything waiting in the offline queue
|
|
119
|
+
${x.default.cyan("doctor")} Check that everything is wired up
|
|
120
|
+
|
|
121
|
+
${x.default.bold("Integrations")} claude-code, codex, gemini-cli, opencode, editors, wakatime
|
|
122
|
+
|
|
123
|
+
Docs: https://github.com/getstint/stint-cli`;async function ao(){let{command:e,positionals:t,flags:n}=Sn(process.argv.slice(2));if(n.version)return console.info(O),0;if(n.help||e==="help")return console.info(_n),0;let r={key:typeof n.key==="string"?n.key:void 0,apiUrl:typeof n["api-url"]==="string"?n["api-url"]:void 0,browser:n.browser!==!1};switch(e){case void 0:case"setup":return await vn({...r,yes:n.yes===!0}),0;case"login":return Se(Be()),await mt(r),_e("This machine is connected. Run `npx getstint install` to pick what to track."),0;case"logout":return De({apiKey:void 0,username:void 0,email:void 0}),f.success("Signed out on this machine. Revoke the key at getstint.dev/dashboard/settings?tab=api if you want it gone for good."),0;case"status":case"whoami":return await An(),0;case"install":return Se(Be()),await lt(t,n.all===!0),_e("Done."),0;case"uninstall":return En(t),0;case"sync":return await dt({days:typeof n.days==="string"?Number(n.days):void 0}),0;case"flush":{let s=await at(k(),typeof n.agent==="string"?n.agent:void 0);if(!n.quiet)console.info(s.error?`Queued: ${s.error}`:`Sent ${s.sent} events and ${s.samples} usage records.`);return 0}case"hook":return await Cn(t[0]),0;case"run":return kn(t);case"doctor":return await un()?0:1;default:return console.error(`Unknown command "${e}".
|
|
124
|
+
`),console.info(_n),1}}ao().then((e)=>process.exit(e)).catch((e)=>{let t=e instanceof Error?e.message:String(e);if(process.argv[2]==="hook")process.exit(0);f.error(t),process.exit(1)});
|
package/package.json
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "getstint",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Track your coding time and AI agents with Stint: one command connects Claude Code, Codex, Gemini CLI, OpenCode and your editors.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"stint",
|
|
7
|
+
"time-tracking",
|
|
8
|
+
"wakatime",
|
|
9
|
+
"wakatime-alternative",
|
|
10
|
+
"claude-code",
|
|
11
|
+
"codex",
|
|
12
|
+
"gemini-cli",
|
|
13
|
+
"opencode",
|
|
14
|
+
"ai-agents",
|
|
15
|
+
"cli",
|
|
16
|
+
"developer-tools"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://getstint.dev",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/getstint/stint-cli/issues"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/getstint/stint-cli.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": "Stint <hello@getstint.dev> (https://getstint.dev)",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"bin": {
|
|
30
|
+
"stint": "dist/stint.mjs",
|
|
31
|
+
"getstint": "dist/stint.mjs"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist/stint.mjs",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.17"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "bun scripts/build.ts",
|
|
43
|
+
"dev": "bun src/cli.ts",
|
|
44
|
+
"test": "bun test",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"check": "bun run format:check && bun run typecheck && bun test && bun run build",
|
|
47
|
+
"prepublishOnly": "bun run check",
|
|
48
|
+
"format": "prettier --write .",
|
|
49
|
+
"format:check": "prettier --check ."
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@clack/prompts": "^0.11.0",
|
|
53
|
+
"@types/bun": "^1.2.22",
|
|
54
|
+
"@types/node": "^22.15.0",
|
|
55
|
+
"picocolors": "^1.1.1",
|
|
56
|
+
"prettier": "3.6.2",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
}
|
|
62
|
+
}
|