getstint 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +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 Ao=Object.create;var{getPrototypeOf:Eo,defineProperty:gt,getOwnPropertyNames:No}=Object;var Ro=Object.prototype.hasOwnProperty;var R=(e,t,o)=>{o=e!=null?Ao(Eo(e)):{};let r=t||!e||!e.__esModule?gt(o,"default",{value:e,enumerable:!0}):o;for(let s of No(e))if(!Ro.call(r,s))gt(r,s,{get:()=>e[s],enumerable:!0});return r};var en=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Bo=(e,t)=>{for(var o in t)gt(e,o,{get:t[o],enumerable:!0,configurable:!0,set:(r)=>t[o]=()=>r})};var B=(e,t)=>()=>(e&&(t=e(e=0)),t);var ht=en((mi,tn)=>{var ut={to(e,t){if(!t)return`\x1B[${e+1}G`;return`\x1B[${t+1};${e+1}H`},move(e,t){let o="";if(e<0)o+=`\x1B[${-e}D`;else if(e>0)o+=`\x1B[${e}C`;if(t<0)o+=`\x1B[${-t}A`;else if(t>0)o+=`\x1B[${t}B`;return o},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"},Mo={up:(e=1)=>"\x1B[S".repeat(e),down:(e=1)=>"\x1B[T".repeat(e)},Lo={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 o=0;o<e;o++)t+=this.line+(o<e-1?ut.up():"");if(e)t+=ut.left;return t}};tn.exports={cursor:ut,scroll:Mo,erase:Lo,beep:"\x07"}});var J=en((di,yt)=>{var ze=process||{},nn=ze.argv||[],Ke=ze.env||{},qo=!(!!Ke.NO_COLOR||nn.includes("--no-color"))&&(!!Ke.FORCE_COLOR||nn.includes("--color")||ze.platform==="win32"||(ze.stdout||{}).isTTY&&Ke.TERM!=="dumb"||!!Ke.CI),Wo=(e,t,o=e)=>(r)=>{let s=""+r,i=s.indexOf(t,e.length);return~i?e+Go(s,t,o,i)+t:e+s+t},Go=(e,t,o,r)=>{let s="",i=0;do s+=e.substring(i,r)+o,i=r+t.length,r=e.indexOf(t,i);while(~r);return s+e.substring(i)},on=(e=qo)=>{let t=e?Wo:()=>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")}};yt.exports=on();yt.exports.createColors=on});import{stdin as fn,stdout as gn}from"node:process";import*as X from"node:readline";import rn from"node:readline";import{Writable as Jo}from"node:stream";function Ko({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 un(e){if(typeof e!="string")throw TypeError(`Expected a \`string\`, got \`${typeof e}\``);return e.replace(zo,"")}function hn(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Te(e,t={}){if(typeof e!="string"||e.length===0||(t={ambiguousIsNarrow:!0,...t},e=un(e),e.length===0))return 0;e=e.replace(Xo()," ");let o=t.ambiguousIsNarrow?1:2,r=0;for(let s of e){let i=s.codePointAt(0);if(i<=31||i>=127&&i<=159||i>=768&&i<=879)continue;switch(Qo.eastAsianWidth(s)){case"F":case"W":r+=2;break;case"A":r+=o;break;default:r+=1}}return r}function Do(){let e=new Map;for(let[t,o]of Object.entries(k)){for(let[r,s]of Object.entries(o))k[r]={open:`\x1B[${s[0]}m`,close:`\x1B[${s[1]}m`},o[r]=k[r],e.set(s[0],s[1]);Object.defineProperty(k,t,{value:o,enumerable:!1})}return Object.defineProperty(k,"codes",{value:e,enumerable:!1}),k.color.close="\x1B[39m",k.bgColor.close="\x1B[49m",k.color.ansi=sn(),k.color.ansi256=an(),k.color.ansi16m=cn(),k.bgColor.ansi=sn(bt),k.bgColor.ansi256=an(bt),k.bgColor.ansi16m=cn(bt),Object.defineProperties(k,{rgbToAnsi256:{value:(t,o,r)=>t===o&&o===r?t<8?16:t>248?231:Math.round((t-8)/247*24)+232:16+36*Math.round(t/255*5)+6*Math.round(o/255*5)+Math.round(r/255*5),enumerable:!1},hexToRgb:{value:(t)=>{let o=/[a-f\d]{6}|[a-f\d]{3}/i.exec(t.toString(16));if(!o)return[0,0,0];let[r]=o;r.length===3&&(r=[...r].map((i)=>i+i).join(""));let s=Number.parseInt(r,16);return[s>>16&255,s>>8&255,s&255]},enumerable:!1},hexToAnsi256:{value:(t)=>k.rgbToAnsi256(...k.hexToRgb(t)),enumerable:!1},ansi256ToAnsi:{value:(t)=>{if(t<8)return 30+t;if(t<16)return 90+(t-8);let o,r,s;if(t>=232)o=((t-232)*10+8)/255,r=o,s=o;else{t-=16;let a=t%36;o=Math.floor(t/36)/5,r=Math.floor(a/6)/5,s=a%6/5}let i=Math.max(o,r,s)*2;if(i===0)return 30;let n=30+(Math.round(s)<<2|Math.round(r)<<1|Math.round(o));return i===2&&(n+=60),n},enumerable:!1},rgbToAnsi:{value:(t,o,r)=>k.ansi256ToAnsi(k.rgbToAnsi256(t,o,r)),enumerable:!1},hexToAnsi:{value:(t)=>k.ansi256ToAnsi(k.hexToAnsi256(t)),enumerable:!1}}),k}function mn(e,t,o){return String(e).normalize().replace(/\r\n/g,`
|
|
3
|
+
`).split(`
|
|
4
|
+
`).map((r)=>sr(r,t,o)).join(`
|
|
5
|
+
`)}function $t(e,t){if(typeof e=="string")return Qe.aliases.get(e)===t;for(let o of e)if(o!==void 0&&$t(o,t))return!0;return!1}function ar(e,t){if(e===t)return;let o=e.split(`
|
|
6
|
+
`),r=t.split(`
|
|
7
|
+
`),s=[];for(let i=0;i<Math.max(o.length,r.length);i++)o[i]!==r[i]&&s.push(i);return s}function Z(e){return e===wt}function Ye(e,t){let o=e;o.isTTY&&o.setRawMode(t)}function xn({input:e=fn,output:t=gn,overwrite:o=!0,hideCursor:r=!0}={}){let s=X.createInterface({input:e,output:t,prompt:"",tabSize:1});X.emitKeypressEvents(e,s),e.isTTY&&e.setRawMode(!0);let i=(n,{name:a,sequence:c})=>{let l=String(n);if($t([l,a,c],"cancel")){r&&t.write(T.cursor.show),process.exit(0);return}if(!o)return;X.moveCursor(t,a==="return"?0:-1,a==="return"?-1:0,()=>{X.clearLine(t,1,()=>{e.once("keypress",i)})})};return r&&t.write(T.cursor.hide),e.once("keypress",i),()=>{e.off("keypress",i),r&&t.write(T.cursor.show),e.isTTY&&!cr&&e.setRawMode(!1),s.terminal=!1,s.close()}}class Ct{constructor(e,t=!0){U(this,"input"),U(this,"output"),U(this,"_abortSignal"),U(this,"rl"),U(this,"opts"),U(this,"_render"),U(this,"_track",!1),U(this,"_prevFrame",""),U(this,"_subscribers",new Map),U(this,"_cursor",0),U(this,"state","initial"),U(this,"error",""),U(this,"value");let{input:o=fn,output:r=gn,render:s,signal:i,...n}=e;this.opts=n,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=i,this.input=o,this.output=r}unsubscribe(){this._subscribers.clear()}setSubscriber(e,t){let o=this._subscribers.get(e)??[];o.push(t),this._subscribers.set(e,o)}on(e,t){this.setSubscriber(e,{cb:t})}once(e,t){this.setSubscriber(e,{cb:t,once:!0})}emit(e,...t){let o=this._subscribers.get(e)??[],r=[];for(let s of o)s.cb(...t),s.once&&r.push(()=>o.splice(o.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(wt);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close()},{once:!0})}let o=new Jo;o._write=(r,s,i)=>{this._track&&(this.value=this.rl?.line.replace(/\t/g,""),this._cursor=this.rl?.cursor??0,this.emit("value",this.value)),i()},this.input.pipe(o),this.rl=rn.createInterface({input:this.input,output:o,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:!0}),rn.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),Ye(this.input,!0),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(T.cursor.show),this.output.off("resize",this.render),Ye(this.input,!1),e(this.value)}),this.once("cancel",()=>{this.output.write(T.cursor.show),this.output.off("resize",this.render),Ye(this.input,!1),e(wt)})})}onKeypress(e,t){if(this.state==="error"&&(this.state="active"),t?.name&&(!this._track&&Qe.aliases.has(t.name)&&this.emit("cursor",Qe.aliases.get(t.name)),Qe.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 o=this.opts.validate(this.value);o&&(this.error=o instanceof Error?o.message:o,this.state="error",this.rl?.write(this.value))}this.state!=="error"&&(this.state="submit")}$t([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
|
+
`),Ye(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let e=mn(this._prevFrame,process.stdout.columns,{hard:!0}).split(`
|
|
9
|
+
`).length-1;this.output.write(T.cursor.move(-999,e*-1))}render(){let e=mn(this._render(this)??"",process.stdout.columns,{hard:!0});if(e!==this._prevFrame){if(this.state==="initial")this.output.write(T.cursor.hide);else{let t=ar(this._prevFrame,e);if(this.restoreCursor(),t&&t?.length===1){let o=t[0];this.output.write(T.cursor.move(0,o)),this.output.write(T.erase.lines(1));let r=e.split(`
|
|
10
|
+
`);this.output.write(r[o]),this._prevFrame=e,this.output.write(T.cursor.move(0,r.length-o-1));return}if(t&&t?.length>1){let o=t[0];this.output.write(T.cursor.move(0,o)),this.output.write(T.erase.down());let r=e.split(`
|
|
11
|
+
`).slice(o);this.output.write(r.join(`
|
|
12
|
+
`)),this._prevFrame=e;return}this.output.write(T.erase.down())}this.output.write(e),this.state==="initial"&&(this.state="active"),this._prevFrame=e}}}var T,zo,yn,Yo,Qo,Vo=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},Xo,bt=10,sn=(e=0)=>(t)=>`\x1B[${t+e}m`,an=(e=0)=>(t)=>`\x1B[${38+e};5;${t}m`,cn=(e=0)=>(t,o,r)=>`\x1B[${38+e};2;${t};${o};${r}m`,k,Zo,Fo,er,Ve,tr=39,St="\x07",bn="[",nr="]",kn="m",_t,pn=(e)=>`${Ve.values().next().value}${bn}${e}${kn}`,ln=(e)=>`${Ve.values().next().value}${_t}${e}${St}`,or=(e)=>e.split(" ").map((t)=>Te(t)),kt=(e,t,o)=>{let r=[...t],s=!1,i=!1,n=Te(un(e[e.length-1]));for(let[a,c]of r.entries()){let l=Te(c);if(n+l<=o?e[e.length-1]+=c:(e.push(c),n=0),Ve.has(c)&&(s=!0,i=r.slice(a+1).join("").startsWith(_t)),s){i?c===St&&(s=!1,i=!1):c===kn&&(s=!1);continue}n+=l,n===o&&a<r.length-1&&(e.push(""),n=0)}!n&&e[e.length-1].length>0&&e.length>1&&(e[e.length-2]+=e.pop())},rr=(e)=>{let t=e.split(" "),o=t.length;for(;o>0&&!(Te(t[o-1])>0);)o--;return o===t.length?e:t.slice(0,o).join(" ")+t.slice(o).join("")},sr=(e,t,o={})=>{if(o.trim!==!1&&e.trim()==="")return"";let r="",s,i,n=or(e),a=[""];for(let[l,m]of e.split(" ").entries()){o.trim!==!1&&(a[a.length-1]=a[a.length-1].trimStart());let d=Te(a[a.length-1]);if(l!==0&&(d>=t&&(o.wordWrap===!1||o.trim===!1)&&(a.push(""),d=0),(d>0||o.trim===!1)&&(a[a.length-1]+=" ",d++)),o.hard&&n[l]>t){let g=t-d,h=1+Math.floor((n[l]-g-1)/t);Math.floor((n[l]-1)/t)<h&&a.push(""),kt(a,m,t);continue}if(d+n[l]>t&&d>0&&n[l]>0){if(o.wordWrap===!1&&d<t){kt(a,m,t);continue}a.push("")}if(d+n[l]>t&&o.wordWrap===!1){kt(a,m,t);continue}a[a.length-1]+=m}o.trim!==!1&&(a=a.map((l)=>rr(l)));let c=[...a.join(`
|
|
13
|
+
`)];for(let[l,m]of c.entries()){if(r+=m,Ve.has(m)){let{groups:g}=new RegExp(`(?:\\${bn}(?<code>\\d+)m|\\${_t}(?<uri>.*)${St})`).exec(c.slice(l).join(""))||{groups:{}};if(g.code!==void 0){let h=Number.parseFloat(g.code);s=h===tr?void 0:h}else g.uri!==void 0&&(i=g.uri.length===0?void 0:g.uri)}let d=er.codes.get(Number(s));c[l+1]===`
|
|
14
|
+
`?(i&&(r+=ln("")),s&&d&&(r+=pn(d))):m===`
|
|
15
|
+
`&&(s&&d&&(r+=pn(s)),i&&(r+=ln(i)))}return r},ir,Qe,cr,wt,pr,lr=(e,t,o)=>(t in e)?pr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,U=(e,t,o)=>(lr(e,typeof t!="symbol"?t+"":t,o),o),vt,mr,dr=(e,t,o)=>(t in e)?mr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o,dn=(e,t,o)=>(dr(e,typeof t!="symbol"?t+"":t,o),o),wn=(e,t,o)=>{if(!t.has(e))throw TypeError("Cannot "+o)},xt=(e,t,o)=>(wn(e,t,"read from private field"),o?o.call(e):t.get(e)),fr=(e,t,o)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,o)},gr=(e,t,o,r)=>(wn(e,t,"write to private field"),r?r.call(e,o):t.set(e,o),o),ge,Sn;var It=B(()=>{T=R(ht(),1);zo=Ko();yn={exports:{}};(function(e){var t={};e.exports=t,t.eastAsianWidth=function(r){var s=r.charCodeAt(0),i=r.length==2?r.charCodeAt(1):0,n=s;return 55296<=s&&s<=56319&&56320<=i&&i<=57343&&(s&=1023,i&=1023,n=s<<10|i,n+=65536),n==12288||65281<=n&&n<=65376||65504<=n&&n<=65510?"F":n==8361||65377<=n&&n<=65470||65474<=n&&n<=65479||65482<=n&&n<=65487||65490<=n&&n<=65495||65498<=n&&n<=65500||65512<=n&&n<=65518?"H":4352<=n&&n<=4447||4515<=n&&n<=4519||4602<=n&&n<=4607||9001<=n&&n<=9002||11904<=n&&n<=11929||11931<=n&&n<=12019||12032<=n&&n<=12245||12272<=n&&n<=12283||12289<=n&&n<=12350||12353<=n&&n<=12438||12441<=n&&n<=12543||12549<=n&&n<=12589||12593<=n&&n<=12686||12688<=n&&n<=12730||12736<=n&&n<=12771||12784<=n&&n<=12830||12832<=n&&n<=12871||12880<=n&&n<=13054||13056<=n&&n<=19903||19968<=n&&n<=42124||42128<=n&&n<=42182||43360<=n&&n<=43388||44032<=n&&n<=55203||55216<=n&&n<=55238||55243<=n&&n<=55291||63744<=n&&n<=64255||65040<=n&&n<=65049||65072<=n&&n<=65106||65108<=n&&n<=65126||65128<=n&&n<=65131||110592<=n&&n<=110593||127488<=n&&n<=127490||127504<=n&&n<=127546||127552<=n&&n<=127560||127568<=n&&n<=127569||131072<=n&&n<=194367||177984<=n&&n<=196605||196608<=n&&n<=262141?"W":32<=n&&n<=126||162<=n&&n<=163||165<=n&&n<=166||n==172||n==175||10214<=n&&n<=10221||10629<=n&&n<=10630?"Na":n==161||n==164||167<=n&&n<=168||n==170||173<=n&&n<=174||176<=n&&n<=180||182<=n&&n<=186||188<=n&&n<=191||n==198||n==208||215<=n&&n<=216||222<=n&&n<=225||n==230||232<=n&&n<=234||236<=n&&n<=237||n==240||242<=n&&n<=243||247<=n&&n<=250||n==252||n==254||n==257||n==273||n==275||n==283||294<=n&&n<=295||n==299||305<=n&&n<=307||n==312||319<=n&&n<=322||n==324||328<=n&&n<=331||n==333||338<=n&&n<=339||358<=n&&n<=359||n==363||n==462||n==464||n==466||n==468||n==470||n==472||n==474||n==476||n==593||n==609||n==708||n==711||713<=n&&n<=715||n==717||n==720||728<=n&&n<=731||n==733||n==735||768<=n&&n<=879||913<=n&&n<=929||931<=n&&n<=937||945<=n&&n<=961||963<=n&&n<=969||n==1025||1040<=n&&n<=1103||n==1105||n==8208||8211<=n&&n<=8214||8216<=n&&n<=8217||8220<=n&&n<=8221||8224<=n&&n<=8226||8228<=n&&n<=8231||n==8240||8242<=n&&n<=8243||n==8245||n==8251||n==8254||n==8308||n==8319||8321<=n&&n<=8324||n==8364||n==8451||n==8453||n==8457||n==8467||n==8470||8481<=n&&n<=8482||n==8486||n==8491||8531<=n&&n<=8532||8539<=n&&n<=8542||8544<=n&&n<=8555||8560<=n&&n<=8569||n==8585||8592<=n&&n<=8601||8632<=n&&n<=8633||n==8658||n==8660||n==8679||n==8704||8706<=n&&n<=8707||8711<=n&&n<=8712||n==8715||n==8719||n==8721||n==8725||n==8730||8733<=n&&n<=8736||n==8739||n==8741||8743<=n&&n<=8748||n==8750||8756<=n&&n<=8759||8764<=n&&n<=8765||n==8776||n==8780||n==8786||8800<=n&&n<=8801||8804<=n&&n<=8807||8810<=n&&n<=8811||8814<=n&&n<=8815||8834<=n&&n<=8835||8838<=n&&n<=8839||n==8853||n==8857||n==8869||n==8895||n==8978||9312<=n&&n<=9449||9451<=n&&n<=9547||9552<=n&&n<=9587||9600<=n&&n<=9615||9618<=n&&n<=9621||9632<=n&&n<=9633||9635<=n&&n<=9641||9650<=n&&n<=9651||9654<=n&&n<=9655||9660<=n&&n<=9661||9664<=n&&n<=9665||9670<=n&&n<=9672||n==9675||9678<=n&&n<=9681||9698<=n&&n<=9701||n==9711||9733<=n&&n<=9734||n==9737||9742<=n&&n<=9743||9748<=n&&n<=9749||n==9756||n==9758||n==9792||n==9794||9824<=n&&n<=9825||9827<=n&&n<=9829||9831<=n&&n<=9834||9836<=n&&n<=9837||n==9839||9886<=n&&n<=9887||9918<=n&&n<=9919||9924<=n&&n<=9933||9935<=n&&n<=9953||n==9955||9960<=n&&n<=9983||n==10045||n==10071||10102<=n&&n<=10111||11093<=n&&n<=11097||12872<=n&&n<=12879||57344<=n&&n<=63743||65024<=n&&n<=65039||n==65533||127232<=n&&n<=127242||127248<=n&&n<=127277||127280<=n&&n<=127337||127344<=n&&n<=127386||917760<=n&&n<=917999||983040<=n&&n<=1048573||1048576<=n&&n<=1114109?"A":"N"},t.characterLength=function(r){var s=this.eastAsianWidth(r);return s=="F"||s=="W"||s=="A"?2:1};function o(r){return r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g)||[]}t.length=function(r){for(var s=o(r),i=0,n=0;n<s.length;n++)i=i+this.characterLength(s[n]);return i},t.slice=function(r,s,i){textLen=t.length(r),s=s||0,i=i||1,s<0&&(s=textLen+s),i<0&&(i=textLen+i);for(var n="",a=0,c=o(r),l=0;l<c.length;l++){var m=c[l],d=t.length(m);if(a>=s-(d==2?1:0))if(a+d<=i)n+=m;else break;a+=d}return n}})(yn);Yo=yn.exports,Qo=hn(Yo),Xo=hn(Vo);k={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(k.modifier);Zo=Object.keys(k.color),Fo=Object.keys(k.bgColor);[...Zo,...Fo];er=Do(),Ve=new Set(["\x1B",""]),_t=`${nr}8;;`;ir=["up","down","left","right","space","enter","cancel"],Qe={actions:new Set(ir),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]])};cr=globalThis.process.platform.startsWith("win"),wt=Symbol("clack:cancel");pr=Object.defineProperty;vt=class vt extends Ct{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(T.cursor.move(0,-1)),this.value=t,this.state="submit",this.close()}),this.on("cursor",()=>{this.value=!this.value})}};mr=Object.defineProperty,Sn=class extends Ct{constructor(e){super(e,!1),dn(this,"options"),dn(this,"cursor",0),fr(this,ge,void 0);let{options:t}=e;gr(this,ge,e.selectableGroups!==!1),this.options=Object.entries(t).flatMap(([o,r])=>[{value:o,group:!0,label:o},...r.map((s)=>({...s,group:o}))]),this.value=[...e.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:o})=>o===e.cursorAt),xt(this,ge)?0:1),this.on("cursor",(o)=>{switch(o){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let r=this.options[this.cursor]?.group===!0;!xt(this,ge)&&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;!xt(this,ge)&&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,o=this.getGroupItems(t);this.isGroupSelected(t)?this.value=this.value.filter((r)=>o.findIndex((s)=>s.value===r)===-1):this.value=[...this.value,...o.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((o)=>o!==e.value):[...this.value,e.value]}}};ge=new WeakMap});import{stripVTControlCharacters as Tt}from"node:util";import M from"node:process";function ur(){return M.platform!=="win32"?M.env.TERM!=="linux":!!M.env.CI||!!M.env.WT_SESSION||!!M.env.TERMINUS_SUBLIME||M.env.ConEmuTask==="{cmd::Cmder}"||M.env.TERM_PROGRAM==="Terminus-Sublime"||M.env.TERM_PROGRAM==="vscode"||M.env.TERM==="xterm-256color"||M.env.TERM==="alacritty"||M.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var p,Xe,Ht,_=(e,t)=>Ht?e:t,hr,In,Tn,Ze,yr,x,ue,_n,$n,Cn,Pt,br,Ii,vn,kr,xr,wr,Sr,_r,$r,Cr,Pn=(e)=>{switch(e){case"initial":case"active":return p.default.cyan(hr);case"cancel":return p.default.red(In);case"error":return p.default.yellow(Tn);case"submit":return p.default.green(Ze)}},Fe=(e)=>{let t=e.active??"Yes",o=e.inactive??"No";return new vt({active:t,inactive:o,initialValue:e.initialValue??!0,render(){let r=`${p.default.gray(x)}
|
|
16
|
+
${Pn(this.state)} ${e.message}
|
|
17
|
+
`,s=this.value?t:o;switch(this.state){case"submit":return`${r}${p.default.gray(x)} ${p.default.dim(s)}`;case"cancel":return`${r}${p.default.gray(x)} ${p.default.strikethrough(p.default.dim(s))}
|
|
18
|
+
${p.default.gray(x)}`;default:return`${r}${p.default.cyan(x)} ${this.value?`${p.default.green(_n)} ${t}`:`${p.default.dim($n)} ${p.default.dim(t)}`} ${p.default.dim("/")} ${this.value?`${p.default.dim($n)} ${p.default.dim(o)}`:`${p.default.green(_n)} ${o}`}
|
|
19
|
+
${p.default.cyan(ue)}
|
|
20
|
+
`}}}).prompt()},Hn=(e)=>{let{selectableGroups:t=!0}=e,o=(r,s,i=[])=>{let n=r.label??String(r.value),a=typeof r.group=="string",c=a&&(i[i.indexOf(r)+1]??{group:!0}),l=a&&c.group===!0,m=a?t?`${l?ue:x} `:" ":"";if(s==="active")return`${p.default.dim(m)}${p.default.cyan(Cn)} ${n} ${r.hint?p.default.dim(`(${r.hint})`):""}`;if(s==="group-active")return`${m}${p.default.cyan(Cn)} ${p.default.dim(n)}`;if(s==="group-active-selected")return`${m}${p.default.green(Pt)} ${p.default.dim(n)}`;if(s==="selected"){let g=a||t?p.default.green(Pt):"";return`${p.default.dim(m)}${g} ${p.default.dim(n)} ${r.hint?p.default.dim(`(${r.hint})`):""}`}if(s==="cancelled")return`${p.default.strikethrough(p.default.dim(n))}`;if(s==="active-selected")return`${p.default.dim(m)}${p.default.green(Pt)} ${n} ${r.hint?p.default.dim(`(${r.hint})`):""}`;if(s==="submitted")return`${p.default.dim(n)}`;let d=a||t?p.default.dim(br):"";return`${p.default.dim(m)}${d} ${p.default.dim(n)}`};return new Sn({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
|
+
${p.default.reset(p.default.dim(`Press ${p.default.gray(p.default.bgWhite(p.default.inverse(" space ")))} to select, ${p.default.gray(p.default.bgWhite(p.default.inverse(" enter ")))} to submit`))}`},render(){let r=`${p.default.gray(x)}
|
|
22
|
+
${Pn(this.state)} ${e.message}
|
|
23
|
+
`;switch(this.state){case"submit":return`${r}${p.default.gray(x)} ${this.options.filter(({value:s})=>this.value.includes(s)).map((s)=>o(s,"submitted")).join(p.default.dim(", "))}`;case"cancel":{let s=this.options.filter(({value:i})=>this.value.includes(i)).map((i)=>o(i,"cancelled")).join(p.default.dim(", "));return`${r}${p.default.gray(x)} ${s.trim()?`${s}
|
|
24
|
+
${p.default.gray(x)}`:""}`}case"error":{let s=this.error.split(`
|
|
25
|
+
`).map((i,n)=>n===0?`${p.default.yellow(ue)} ${p.default.yellow(i)}`:` ${i}`).join(`
|
|
26
|
+
`);return`${r}${p.default.yellow(x)} ${this.options.map((i,n,a)=>{let c=this.value.includes(i.value)||i.group===!0&&this.isGroupSelected(`${i.value}`),l=n===this.cursor;return!l&&typeof i.group=="string"&&this.options[this.cursor].value===i.group?o(i,c?"group-active-selected":"group-active",a):l&&c?o(i,"active-selected",a):c?o(i,"selected",a):o(i,l?"active":"inactive",a)}).join(`
|
|
27
|
+
${p.default.yellow(x)} `)}
|
|
28
|
+
${s}
|
|
29
|
+
`}default:return`${r}${p.default.cyan(x)} ${this.options.map((s,i,n)=>{let a=this.value.includes(s.value)||s.group===!0&&this.isGroupSelected(`${s.value}`),c=i===this.cursor;return!c&&typeof s.group=="string"&&this.options[this.cursor].value===s.group?o(s,a?"group-active-selected":"group-active",n):c&&a?o(s,"active-selected",n):a?o(s,"selected",n):o(s,c?"active":"inactive",n)}).join(`
|
|
30
|
+
${p.default.cyan(x)} `)}
|
|
31
|
+
${p.default.cyan(ue)}
|
|
32
|
+
`}}}).prompt()},De=(e="",t="")=>{let o=`
|
|
33
|
+
${e}
|
|
34
|
+
`.split(`
|
|
35
|
+
`),r=Tt(t).length,s=Math.max(o.reduce((n,a)=>{let c=Tt(a);return c.length>n?c.length:n},0),r)+2,i=o.map((n)=>`${p.default.gray(x)} ${p.default.dim(n)}${" ".repeat(s-Tt(n).length)}${p.default.gray(x)}`).join(`
|
|
36
|
+
`);process.stdout.write(`${p.default.gray(x)}
|
|
37
|
+
${p.default.green(Ze)} ${p.default.reset(t)} ${p.default.gray(vn.repeat(Math.max(s-r-1,1))+kr)}
|
|
38
|
+
${i}
|
|
39
|
+
${p.default.gray(xr+vn.repeat(s+2)+wr)}
|
|
40
|
+
`)},et=(e="")=>{process.stdout.write(`${p.default.gray(ue)} ${p.default.red(e)}
|
|
41
|
+
|
|
42
|
+
`)},Pe=(e="")=>{process.stdout.write(`${p.default.gray(yr)} ${e}
|
|
43
|
+
`)},He=(e="")=>{process.stdout.write(`${p.default.gray(x)}
|
|
44
|
+
${p.default.gray(ue)} ${e}
|
|
45
|
+
|
|
46
|
+
`)},y,Ti,Oe=({indicator:e="dots"}={})=>{let t=Ht?["◒","◐","◓","◑"]:["•","o","O","0"],o=Ht?80:120,r=process.env.CI==="true",s,i,n=!1,a="",c,l=performance.now(),m=(O)=>{let A=O>1?"Something went wrong":"Canceled";n&&Dt(A,O)},d=()=>m(2),g=()=>m(1),h=()=>{process.on("uncaughtExceptionMonitor",d),process.on("unhandledRejection",d),process.on("SIGINT",g),process.on("SIGTERM",g),process.on("exit",m)},u=()=>{process.removeListener("uncaughtExceptionMonitor",d),process.removeListener("unhandledRejection",d),process.removeListener("SIGINT",g),process.removeListener("SIGTERM",g),process.removeListener("exit",m)},H=()=>{if(c===void 0)return;r&&process.stdout.write(`
|
|
47
|
+
`);let O=c.split(`
|
|
48
|
+
`);process.stdout.write(Xe.cursor.move(-999,O.length-1)),process.stdout.write(Xe.erase.down(O.length))},K=(O)=>O.replace(/\.+$/,""),se=(O)=>{let A=(performance.now()-O)/1000,G=Math.floor(A/60),fe=Math.floor(A%60);return G>0?`[${G}m ${fe}s]`:`[${fe}s]`},Uo=(O="")=>{n=!0,s=xn(),a=K(O),l=performance.now(),process.stdout.write(`${p.default.gray(x)}
|
|
49
|
+
`);let A=0,G=0;h(),i=setInterval(()=>{if(r&&a===c)return;H(),c=a;let fe=p.default.magenta(t[A]);if(r)process.stdout.write(`${fe} ${a}...`);else if(e==="timer")process.stdout.write(`${fe} ${a} ${se(l)}`);else{let jo=".".repeat(Math.floor(G)).slice(0,3);process.stdout.write(`${fe} ${a}${jo}`)}A=A+1<t.length?A+1:0,G=G<t.length?G+0.125:0},o)},Dt=(O="",A=0)=>{n=!1,clearInterval(i),H();let G=A===0?p.default.green(Ze):A===1?p.default.red(In):p.default.red(Tn);a=K(O??a),e==="timer"?process.stdout.write(`${G} ${a} ${se(l)}
|
|
50
|
+
`):process.stdout.write(`${G} ${a}
|
|
51
|
+
`),u(),s()};return{start:Uo,stop:Dt,message:(O="")=>{a=K(O??a)}}};var F=B(()=>{It();It();p=R(J(),1),Xe=R(ht(),1);Ht=ur(),hr=_("◆","*"),In=_("■","x"),Tn=_("▲","x"),Ze=_("◇","o"),yr=_("┌","T"),x=_("│","|"),ue=_("└","—"),_n=_("●",">"),$n=_("○"," "),Cn=_("◻","[•]"),Pt=_("◼","[+]"),br=_("◻","[ ]"),Ii=_("▪","•"),vn=_("─","-"),kr=_("╮","+"),xr=_("├","+"),wr=_("╯","+"),Sr=_("●","•"),_r=_("◆","*"),$r=_("▲","!"),Cr=_("■","x"),y={message:(e="",{symbol:t=p.default.gray(x)}={})=>{let o=[`${p.default.gray(x)}`];if(e){let[r,...s]=e.split(`
|
|
52
|
+
`);o.push(`${t} ${r}`,...s.map((i)=>`${p.default.gray(x)} ${i}`))}process.stdout.write(`${o.join(`
|
|
53
|
+
`)}
|
|
54
|
+
`)},info:(e)=>{y.message(e,{symbol:p.default.blue(Sr)})},success:(e)=>{y.message(e,{symbol:p.default.green(_r)})},step:(e)=>{y.message(e,{symbol:p.default.green(Ze)})},warn:(e)=>{y.message(e,{symbol:p.default.yellow($r)})},warning:(e)=>{y.warn(e)},error:(e)=>{y.message(e,{symbol:p.default.red(Cr)})}},Ti=`${p.default.gray(x)} `});import{chmodSync as vr,existsSync as On,mkdirSync as Ir,readFileSync as Un,renameSync as Tr,writeFileSync as jn}from"node:fs";import{dirname as Pr}from"node:path";function he(e){try{return Un(e,"utf8")}catch{return null}}function z(e){let t=he(e);if(t===null)return null;try{return JSON.parse(Hr(t))}catch{return null}}function Ue(e,t,o){Ir(Pr(e),{recursive:!0});let r=`${e}.${process.pid}.tmp`;if(jn(r,t,o===void 0?void 0:{mode:o}),Tr(r,e),o!==void 0&&process.platform!=="win32")vr(e,o)}function ae(e,t,o){Ue(e,`${JSON.stringify(t,null,2)}
|
|
55
|
+
`,o)}function Ot(e,t=".stint-backup"){if(!On(e)||On(e+t))return null;return jn(e+t,Un(e)),e+t}function Hr(e){let t="",o=!1;for(let r=0;r<e.length;r+=1){let s=e[r],i=e[r+1];if(o){if(t+=s,s==="\\")t+=i??"",r+=1;else if(s==='"')o=!1;continue}if(s==='"')o=!0,t+=s;else if(s==="/"&&i==="/"){while(r<e.length&&e[r]!==`
|
|
56
|
+
`)r+=1;t+=`
|
|
57
|
+
`}else if(s==="/"&&i==="*"){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 je=()=>{};import{homedir as Or}from"node:os";import{join as I}from"node:path";var D=()=>process.env.STINT_HOME_OVERRIDE??Or(),ye=()=>process.env.STINT_HOME??I(D(),".stint"),f;var L=B(()=>{f={config:()=>I(ye(),"config.json"),state:()=>I(ye(),"state.json"),queue:()=>I(ye(),"queue.jsonl"),usageQueue:()=>I(ye(),"usage.jsonl"),log:()=>I(ye(),"stint.log"),bin:()=>I(ye(),"bin","stint.mjs"),claudeSettings:()=>I(process.env.CLAUDE_CONFIG_DIR??I(D(),".claude"),"settings.json"),claudeProjects:()=>I(process.env.CLAUDE_CONFIG_DIR??I(D(),".claude"),"projects"),codexHome:()=>process.env.CODEX_HOME??I(D(),".codex"),geminiHome:()=>I(D(),".gemini"),opencodeConfig:()=>I(process.env.XDG_CONFIG_HOME??I(D(),".config"),"opencode"),opencodeData:()=>I(process.env.XDG_DATA_HOME??I(D(),".local","share"),"opencode"),wakatimeConfig:()=>I(process.env.WAKATIME_HOME??D(),".wakatime.cfg")}});import{hostname as Ur}from"node:os";function Ut(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 $(){let e=z(f.config())??{},t=process.env.STINT_API_URL??e.apiUrl??jr;return{apiUrl:Ut(t),apiKey:process.env.STINT_API_KEY??e.apiKey,username:e.username,email:e.email,machine:e.machine??Ur(),installed:Array.isArray(e.installed)?e.installed.filter((o)=>typeof o==="string"):[],hideProjectNames:e.hideProjectNames===!0}}function ce(e){let o={...z(f.config())??{},...e};for(let r of Object.keys(o))if(o[r]===void 0)delete o[r];return ae(f.config(),o,Ar),$()}function jt(e,t){let o=new Set($().installed);if(t)o.add(e);else o.delete(e);ce({installed:[...o].sort()})}var jr="https://getstint.dev",Ar=384;var q=B(()=>{je();L()});var En;var An=B(()=>{En={name:"getstint",version:"0.1.0",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 E,Nn=(e="stint-cli")=>`${e}/${E} (${process.platform}-${process.arch}) node/${process.versions.node}`;var be=B(()=>{An();E=En.version});import{spawn as Nr,spawnSync as Rn}from"node:child_process";import{copyFileSync as Rr,existsSync as Mn,mkdirSync as Br,readFileSync as Mr,realpathSync as Lr,writeFileSync as qr}from"node:fs";import{dirname as Wr,extname as Gr}from"node:path";import{fileURLToPath as Jr}from"node:url";function W(e){return(process.platform==="win32"?Rn("where",[e],{stdio:"ignore",windowsHide:!0}):Rn("sh",["-c",`command -v ${e}`],{stdio:"ignore"})).status===0}function Ln(){try{let e=Lr(Jr(import.meta.url));return Gr(e)===".mjs"?e:null}catch{return null}}function Ae(){try{return Mr(qn(),"utf8").trim()}catch{return null}}function tt(){let e=f.bin(),t=Ln();if(t&&t!==e&&(Ae()!==E||!Mn(e)))Br(Wr(e),{recursive:!0}),Rr(t,e),qr(qn(),E);return e}function ee(){return W("node")?"node":process.execPath}function Wn(e){return`${Bn(ee())} ${Bn(f.bin().replace(/\\/g,"/"))} hook ${e}`}function nt(e){let t=Mn(f.bin())?f.bin():Ln();if(!t)return;try{let o=Nr(ee(),[t,...e],{stdio:"ignore",detached:!0,windowsHide:!0,env:process.env});o.on("error",()=>{return}),o.unref()}catch{}}var qn=()=>`${f.bin()}.version`,Bn=(e)=>/[\s"]/.test(e)?`"${e.replace(/"/g,"\\\"")}"`:e;var te=B(()=>{L();be()});function Et(e,t){if(!e.hooks||typeof e.hooks!=="object")return e;let o={};for(let[i,n]of Object.entries(e.hooks)){if(!Array.isArray(n)){o[i]=n;continue}let a=n.map((c)=>c&&Array.isArray(c.hooks)?{...c,hooks:c.hooks.filter((l)=>!Gn(l,t))}:c).filter((c)=>!c||!Array.isArray(c.hooks)||c.hooks.length>0);if(a.length>0)o[i]=a}if(Object.keys(o).length>0)return{...e,hooks:o};let{hooks:r,...s}=e;return s}function Jn(e,t,o){let r=Et(e,t),s={...r.hooks??{}};for(let i of o){let n=i.matcher===void 0?{hooks:[i.handler]}:{matcher:i.matcher,hooks:[i.handler]};s[i.event]=[...s[i.event]??[],n]}return{...r,hooks:s}}function Kn(e,t){if(!e?.hooks)return!1;return Object.values(e.hooks).some((o)=>Array.isArray(o)&&o.some((r)=>Array.isArray(r?.hooks)&&r.hooks.some((s)=>Gn(s,t))))}var Kr=(e)=>new RegExp(`stint(\\.mjs)?["']?\\s+hook\\s+${e.replace(/[-]/g,"\\-")}(\\s|$)`),Gn=(e,t)=>{let o=e?.command;return typeof o==="string"&&Kr(t).test(o)};function zn(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 zr,readFileSync as Yr}from"node:fs";function Qn(e,t,o,r){let s=e.length?e.replace(/\r\n/g,`
|
|
91
|
+
`).split(`
|
|
92
|
+
`):[],i=`[${t}]`,n=s.findIndex((m)=>m.trim().toLowerCase()===i);if(n===-1){if(s.length&&s[s.length-1].trim()!=="")s.push("");return s.push(i,`${o} = ${r}`),Yn(s)}let a=s.findIndex((m,d)=>d>n&&/^\s*\[.+\]\s*$/.test(m));if(a===-1)a=s.length;let c=new RegExp(`^\\s*${o}\\s*=`,"i"),l=s.findIndex((m,d)=>d>n&&d<a&&c.test(m));if(l!==-1)s[l]=`${o} = ${r}`;else{let m=a;while(m-1>n&&s[m-1].trim()==="")m-=1;s.splice(m,0,`${o} = ${r}`)}return Yn(s)}function Vn(e,t,o){return Qn(Qn(e,"settings","api_url",t),"settings","api_key",o)}function Qr(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 Xn(){let e=`${f.wakatimeConfig()}.stint-backup`;return zr(e)?Yr(e,"utf8"):Qr(ot())}var Nt=(e)=>`${e}/api/compat/wakatime/v1`,ot=()=>he(f.wakatimeConfig())??"",Yn=(e)=>e.join(`
|
|
96
|
+
`).replace(/\n*$/,`
|
|
97
|
+
`);var Zn=B(()=>{je();L()});import{spawnSync as Fn}from"node:child_process";import{existsSync as pe,rmSync as Vr}from"node:fs";import{join as Ne}from"node:path";function Mt(e){return{id:e.id,name:e.name,kind:"agent",hint:e.hint,detected:e.detected,installed:()=>Kn(z(e.file()),e.id),install:()=>{let t=e.file(),r=he(t)===null?{}:z(t);if(r===null)throw Error(`${t} isn't valid JSON, so Stint left it alone. Fix it and run the install again.`);return Ot(t),ae(t,Jn(r,e.id,e.specs())),[`Added Stint hooks to ${t}`,e.after].filter(Boolean).join(". ")},uninstall:()=>{let t=e.file(),o=z(t);if(!o)return`Nothing to remove in ${t}`;return ae(t,Et(o,e.id)),`Removed Stint hooks from ${t}`}}}var Bt=(e)=>({type:"command",command:Wn(e)}),Xr,Zr,Fr,Ee=()=>Ne(f.opencodeConfig(),"plugins","stint.js"),Dr,Rt,Dn="getstint.stint",es,ts,j,Re=(e)=>j.find((t)=>t.id===e);var rt=B(()=>{q();je();L();te();Zn();Xr=Mt({id:"claude-code",name:"Claude Code",hint:"hooks in ~/.claude/settings.json",file:f.claudeSettings,detected:()=>pe(Ne(f.claudeSettings(),".."))||W("claude"),specs:()=>{let e={...Bt("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=Mt({id:"codex",name:"Codex CLI",hint:"hooks in ~/.codex/hooks.json",file:()=>Ne(f.codexHome(),"hooks.json"),detected:()=>pe(f.codexHome())||W("codex"),specs:()=>{let e={...Bt("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"}),Fr=Mt({id:"gemini-cli",name:"Gemini CLI",hint:"hooks in ~/.gemini/settings.json",file:()=>Ne(f.geminiHome(),"settings.json"),detected:()=>pe(f.geminiHome())||W("gemini"),specs:()=>{let e={...Bt("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}]}}),Dr={id:"opencode",name:"OpenCode",kind:"agent",hint:"plugin in ~/.config/opencode/plugins",detected:()=>pe(f.opencodeConfig())||pe(f.opencodeData())||W("opencode"),installed:()=>he(Ee())?.includes("STINT_PLUGIN")??!1,install:()=>{return Ue(Ee(),zn(ee(),f.bin())),`Wrote ${Ee()}`},uninstall:()=>{return Vr(Ee(),{force:!0}),`Removed ${Ee()}`}},Rt=["code","cursor","windsurf","codium","code-insiders"],es={id:"editors",name:"VS Code, Cursor and Windsurf",kind:"editor",hint:"installs the Stint extension",detected:()=>Rt.some(W),installed:()=>!1,install:()=>{return Rt.filter(W).map((t)=>{return Fn(t,["--install-extension",Dn,"--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:()=>{return Rt.filter(W).forEach((e)=>Fn(e,["--uninstall-extension",Dn],{stdio:"ignore",shell:process.platform==="win32",timeout:60000})),"Removed the Stint extension"}},ts={id:"wakatime",name:"WakaTime plugins",kind:"editor",hint:"JetBrains, Neovim, Zed, Xcode, Sublime, Emacs and 50 more, through ~/.wakatime.cfg",detected:()=>pe(f.wakatimeConfig())||pe(Ne(f.wakatimeConfig(),"..",".wakatime")),installed:()=>ot().includes(Nt($().apiUrl)),install:()=>{let e=$();if(!e.apiKey)throw Error("Sign in first so Stint has a key to give your WakaTime plugins.");return Ot(f.wakatimeConfig()),Ue(f.wakatimeConfig(),Vn(ot(),Nt(e.apiUrl),e.apiKey),384),`Pointed ${f.wakatimeConfig()} at Stint (your old file is saved as .wakatime.cfg.stint-backup)`},uninstall:()=>{return Ue(f.wakatimeConfig(),Xn(),384),`Restored ${f.wakatimeConfig()}`}},j=[Xr,Zr,Fr,Dr,es,ts]});var xo={};Bo(xo,{uninstall:()=>Qt,pickIntegrations:()=>lt,install:()=>Yt,describe:()=>zs,applyIntegrations:()=>Le});function zs(e){let t=e.installed()?N.default.green("connected"):e.detected()?N.default.yellow("found"):N.default.dim("not found");return`${e.name} ${N.default.dim(`(${t}${N.default.dim(")")}`)}`}async function lt(){let e=j.filter((r)=>r.kind==="agent"),t=j.filter((r)=>r.kind==="editor"),o=await Hn({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:j.filter((r)=>r.installed()||r.detected()&&r.kind==="agent").map((r)=>r.id),required:!1});if(Z(o))return null;return o.map((r)=>Re(r)).filter((r)=>Boolean(r))}function Le(e){tt();let t=0,o=0;for(let r of e)try{let s=r.install();jt(r.id,!0),y.success(`${N.default.bold(r.name)} ${N.default.dim(s)}`),t+=1}catch(s){y.error(`${N.default.bold(r.name)} ${s instanceof Error?s.message:String(s)}`),o+=1}return{ok:t,failed:o}}async function Yt(e,t){if(e.length===0&&!t){let r=await lt();if(!r)return et("Nothing changed.");Le(r);return}let o=e.filter((r)=>!Re(r));if(o.length)throw Error(`Unknown integration: ${o.join(", ")}. Try: ${j.map((r)=>r.id).join(", ")}`);Le(t?j.filter((r)=>r.detected()):e.map((r)=>Re(r)))}function Qt(e){let t=e.length?e.map((o)=>Re(o)).filter((o)=>Boolean(o)):j.filter((o)=>o.installed());if(t.length===0)return y.info("Nothing is connected.");for(let o of t)try{y.success(`${N.default.bold(o.name)} ${N.default.dim(o.uninstall())}`),jt(o.id,!1)}catch(r){y.error(`${N.default.bold(o.name)} ${r instanceof Error?r.message:String(r)}`)}}var N;var mt=B(()=>{F();N=R(J(),1);rt();q();te()});F();var v=R(J(),1);F();var to=R(J(),1);rt();import{existsSync as eo}from"node:fs";be();class oe extends Error{status;code;constructor(e,t,o){super(e);this.status=t;this.code=o}}var st="stint-cli",ns=1e4;async function ne(e,t,o={}){let r={accept:"application/json","user-agent":o.agent??Nn()},s=o.token??e.apiKey;if(s)r.authorization=`Bearer ${s}`;if(o.body!==void 0)r["content-type"]="application/json";let i;try{i=await fetch(`${e.apiUrl}${t}`,{method:o.method??(o.body===void 0?"GET":"POST"),headers:r,body:o.body===void 0?void 0:JSON.stringify(o.body),signal:AbortSignal.timeout(o.timeoutMs??ns)})}catch(c){let l=c instanceof Error&&c.name==="TimeoutError"?"timed out":"couldn't connect";throw new oe(`Stint ${l} (${e.apiUrl}).`,0,"network")}let n=await i.text(),a=null;try{a=n?JSON.parse(n):null}catch{}if(!i.ok){let c=a??{},l=typeof c.error==="string"&&/^[a-z_]+$/.test(c.error)?c.error:void 0;throw new oe(c.error_description??c.message??c.error??`Stint answered ${i.status}.`,i.status,l)}return a}var P={deviceCode:(e,t=st)=>ne({apiUrl:e.apiUrl},"/api/auth/device/code",{body:{client_id:t,scope:"heartbeats usage"}}),deviceToken:(e,t,o=st)=>ne({apiUrl:e.apiUrl},"/api/auth/device/token",{body:{grant_type:"urn:ietf:params:oauth:grant-type:device_code",device_code:t,client_id:o}}),mintKey:(e,t,o)=>ne({apiUrl:e.apiUrl},"/api/v1/me/api-keys",{token:t,body:{name:o}}),signOutSession:(e,t)=>ne({apiUrl:e.apiUrl},"/api/auth/sign-out",{token:t,body:{}}).catch(()=>{return}),me:(e)=>ne(e,"/api/v1/me"),today:(e)=>ne(e,"/api/compat/wakatime/v1/users/current/statusbar/today"),heartbeats:(e,t,o)=>ne(e,"/api/v1/heartbeats",{body:t,agent:o,timeoutMs:8000}),usage:(e,t)=>ne(e,"/api/v1/usage",{body:{samples:t},timeoutMs:15000})};q();L();te();async function no(){let e=$(),t=[],[o]=process.versions.node.split(".").map(Number);t.push({label:`Node ${process.versions.node}`,ok:o>=18,fix:"Install Node 18 or newer from nodejs.org"}),t.push({label:`Hooks run with ${ee()}`,ok:ee()==="node"||eo(ee()),fix:"Put node on your PATH so agents can run the Stint hook"}),t.push({label:`Hook script at ${f.bin()}`,ok:eo(f.bin()),fix:"Run npx getstint install"});try{await P.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 j.filter((s)=>s.installed()))t.push({label:`${r.name} connected`,ok:!0});if(j.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)y.success(r.label);else y.error(`${r.label}${r.fix?to.default.dim(` ${r.fix}`):""}`);return t.every((r)=>r.ok)}import{readFileSync as ys,statSync as bs}from"node:fs";var w=(e)=>typeof e==="number"&&Number.isFinite(e)&&e>0?Math.round(e):0,Y=(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 it(e){let t=[];for(let o of e.split(`
|
|
98
|
+
`)){if(!o.trim())continue;try{t.push(JSON.parse(o))}catch{}}return t}var S=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{},b=(e)=>typeof e==="string"?e:void 0;function Q(e,t,o,r,s){return{entity:`${e}:${r}`,type:"app",category:"ai coding",time:t,project:o||void 0,agent:e,ai_session:r,ai_model:s}}var le="claude-code";function oo(e,t){let o=new Map,r=[],s=new Set;for(let i of it(e)){let n=S(i);if(n.type!=="assistant")continue;let a=S(n.message),c=S(a.usage),l=b(a.id)??b(n.requestId)??b(n.uuid),m=b(a.model),d=Y(n.timestamp);if(!l||!d||!m||m.startsWith("<"))continue;let g=t.projectOf(b(n.cwd)),h=b(n.sessionId)??"claude",u={source_id:`claude:${l}`,time:d,agent:le,model:m,project:g,input_tokens:w(c.input_tokens),output_tokens:w(c.output_tokens),cache_read_tokens:w(c.cache_read_input_tokens),cache_write_tokens:w(c.cache_creation_input_tokens)},H=o.get(u.source_id);if(!H||u.output_tokens>=H.output_tokens)o.set(u.source_id,H?{...u,time:H.time}:u);let K=`${h}|${Math.floor(d)}`;if(!s.has(K))s.add(K),r.push(Q(le,d,g,h,m))}return{samples:[...o.values()],heartbeats:r,carry:{}}}var V="codex";function ro(e,t){let o=w(e.cached_input_tokens);return{...t,input_tokens:Math.max(0,w(e.input_tokens)-o),output_tokens:w(e.output_tokens),cache_read_tokens:o,cache_write_tokens:w(e.cache_write_input_tokens)}}function so(e,t){let o={...t.carry??{}},r=new Map,s=[],i=[],n=[];for(let c of it(e)){let l=S(c),m=S(l.payload),d=Y(l.timestamp);if(l.type==="session_meta"){if(o.session=b(m.id)??o.session??"",o.cwd=b(m.cwd)??o.cwd??"",S(m.source).subagent)o.subagent="1";continue}if(l.type==="turn_context"){let u=b(m.model);if(u){o.model=u;let H=b(m.turn_id);if(H)r.set(H,u)}o.cwd=b(m.cwd)??o.cwd??"";continue}if(!d)continue;let g=t.projectOf(o.cwd||void 0),h=o.session||"codex";if(l.type==="token_usage_record"){let u=b(m.response_id);if(!u)continue;o.records="1";let H=r.get(b(m.turn_id)??"")??o.model??"unknown";s.push(ro(S(m.usage),{source_id:`codex:${u}`,time:d,agent:V,model:H,project:g})),n.push(Q(V,d,g,h,H));continue}if(l.type==="event_msg"&&m.type==="token_count"){let u=S(m.info),H=S(u.total_token_usage),K=S(u.last_token_usage),se=w(H.total_tokens);if(!se||!Object.keys(K).length||o.lastTotal===String(se))continue;if(o.lastTotal=String(se),i.push(ro(K,{source_id:`codex:${h}:${se}`,time:d,agent:V,model:o.model??"unknown",project:g})),o.records!=="1")n.push(Q(V,d,g,h,o.model))}}return{samples:(o.records==="1"?s:i).filter((c)=>c.input_tokens+c.output_tokens+c.cache_read_tokens>0),heartbeats:n,carry:o}}var me="gemini-cli";function io(e,t){let o;try{o=S(JSON.parse(e))}catch{return{samples:[],heartbeats:[],carry:{}}}let r=b(o.sessionId)??"gemini",s=t.projectOf(t.cwd),i=[],n=[];for(let a of Array.isArray(o.messages)?o.messages:[]){let c=S(a);if(c.type!=="gemini")continue;let l=b(c.id),m=Y(c.timestamp),d=S(c.tokens);if(!l||!m)continue;let g=b(c.model)??"gemini",h=w(d.cached),u={source_id:`gemini:${r}:${l}`,time:m,agent:me,model:g,project:s,input_tokens:Math.max(0,w(d.input)-h),output_tokens:w(d.output)+w(d.thoughts),cache_read_tokens:h,cache_write_tokens:0};if(u.input_tokens+u.output_tokens+u.cache_read_tokens>0)i.push(u);n.push(Q(me,m,s,r,g))}return{samples:i,heartbeats:n,carry:{}}}import{existsSync as rs,readFileSync as ao,statSync as ss}from"node:fs";import{basename as is,dirname as as,isAbsolute as cs,join as Lt,resolve as qt}from"node:path";function ps(e){let t=Lt(e,".git");try{if(ss(t).isDirectory())return t;let o=/^gitdir:\s*(.+)$/m.exec(ao(t,"utf8"))?.[1]?.trim();if(!o)return null;return cs(o)?o:qt(e,o)}catch{return null}}function ls(e){let t=qt(e);for(let o=0;o<64;o+=1){if(rs(Lt(t,".git")))return t;let r=as(t);if(r===t)return null;t=r}return null}function ms(e){let t=ps(e);if(!t)return;try{let o=ao(Lt(t,"HEAD"),"utf8").trim();return/^ref:\s*refs\/heads\/(.+)$/.exec(o)?.[1]??void 0}catch{return}}function ke(e){if(!e)return null;let t=ls(e)??qt(e),o=is(t);if(!o)return null;return{root:t,name:o,branch:ms(t)}}import{closeSync as ds,openSync as fs,readSync as gs,statSync as us}from"node:fs";var hs=33554432;function co(e,t){let o;try{o=us(e).size}catch{return null}let r=t&&t.offset<=o?t.offset:0,s=t&&t.offset<=o?t.carry:void 0;if(r===o)return{content:"",cursor:{offset:r,size:o,carry:s}};let i=Math.min(o-r,hs),n=Buffer.alloc(i),a=fs(e,"r");try{gs(a,n,0,i,r)}finally{ds(a)}let c=n.lastIndexOf(10);if(c===-1)return{content:"",cursor:{offset:r,size:o,carry:s}};return{content:n.subarray(0,c+1).toString("utf8"),cursor:{offset:r+c+1,size:o,carry:s}}}var Wt=new Map;function xe(e){if(!e)return"";if(!Wt.has(e))Wt.set(e,ke(e)?.name??"");return Wt.get(e)}var Be={samples:[],heartbeats:[],carry:{}};function we(e,t,o,r){if(e===me){let a=0;try{a=bs(t).size}catch{return Be}if(o.cursors[t]?.size===a)return Be;o.cursors[t]={offset:a,size:a};try{return io(ys(t,"utf8"),{projectOf:xe,cwd:r})}catch{return Be}}let s=e===le?oo:e===V?so:null;if(!s)return Be;let i=co(t,o.cursors[t]);if(!i||!i.content){if(i)o.cursors[t]=i.cursor;return Be}let n=s(i.content,{projectOf:xe,carry:i.cursor.carry});return o.cursors[t]={...i.cursor,carry:Object.keys(n.carry).length?n.carry:void 0},n}q();import{isAbsolute as po,relative as ks,resolve as xs}from"node:path";var ws=/^(write|edit|multiedit|notebookedit|apply_patch|write_file|replace|edit_file|create_file|str_replace|patch)$/i,Ss=new Set(["stop","subagentstop","sessionend","afteragent","session.idle","session.deleted","agent-turn-complete"]),lo=(e)=>Ss.has((e??"").toLowerCase());function _s(e){let t=e.tool_input??{},o=e.file_path??t.file_path??t.filePath??t.path??t.notebook_path??t.absolute_path;return typeof o==="string"&&o.length<1000?o:void 0}function at(e,t,o,r){let s=(t.session_id||"session").slice(0,120),i={category:"ai coding",time:o,project:r?.name,branch:r?.branch,agent:e,ai_session:s,ai_model:t.model},n=_s(t);if(n&&r){let a=po(n)?n:xs(t.cwd??r.root,n),c=ks(r.root,a);if(c&&!c.startsWith("..")&&!po(c))return{...i,entity:c.replace(/\\/g,"/"),type:"file",is_write:ws.test(t.tool_name??"")||t.hook_event_name==="file.edited"}}return{...i,entity:`${e}:${s}`,type:"app"}}L();import{appendFileSync as $s,mkdirSync as Cs,renameSync as vs,statSync as Is}from"node:fs";import{dirname as Ts}from"node:path";var Ps=1048576;function mo(e){let t=f.log();try{Cs(Ts(t),{recursive:!0});try{if(Is(t).size>Ps)vs(t,`${t}.1`)}catch{}$s(t,`${new Date().toISOString()} ${e.replace(/\s+/g," ").slice(0,2000)}
|
|
99
|
+
`)}catch{}}te();L();import{appendFileSync as go,existsSync as Hs,mkdirSync as Os,readFileSync as Jt,readdirSync as Us,renameSync as js,rmSync as Gt,statSync as As,writeFileSync as Za}from"node:fs";import{basename as Es,dirname as uo,join as Ns}from"node:path";var fo=20000,Rs=600000;function ct(e,t){if(t.length===0)return;Os(uo(e),{recursive:!0}),go(e,t.map((o)=>JSON.stringify(o)).join(`
|
|
100
|
+
`)+`
|
|
101
|
+
`)}function Bs(e){let t=[];for(let o of e.split(`
|
|
102
|
+
`)){if(!o.trim())continue;try{t.push(JSON.parse(o))}catch{}}return t}function Ms(e){let t=uo(e),o=`${Es(e)}.claim-`,r=[];try{r=Us(t).filter((s)=>s.startsWith(o))}catch{return}for(let s of r){let i=Ns(t,s);try{if(Date.now()-As(i).mtimeMs<Rs)continue;go(e,Jt(i,"utf8")),Gt(i,{force:!0})}catch{}}}function ho(e){if(Ms(e),!Hs(e))return null;let t=`${e}.claim-${process.pid}-${Date.now()}`;try{js(e,t)}catch{return null}return{items:Bs(Jt(t,"utf8")).slice(-fo),done:()=>Gt(t,{force:!0}),release:(s)=>{Gt(t,{force:!0}),ct(e,s.slice(-fo))}}}function Kt(e){try{return Jt(e,"utf8").split(`
|
|
103
|
+
`).filter((t)=>t.trim()).length}catch{return 0}}je();L();function re(){let e=z(f.state())??{};return{cursors:e.cursors&&typeof e.cursors==="object"?e.cursors:{},lastFlush:e.lastFlush,lastError:e.lastError,authFailed:e.authFailed}}function Se(e){let t=Object.entries(e.cursors),o=t.length>2000?Object.fromEntries(t.slice(-2000)):e.cursors;ae(f.state(),{...e,cursors:o})}var Ls=500,qs=1000,Ws=(e)=>e instanceof oe&&(e.status===0||e.status===401||e.status===429||e.status>=500);async function yo(e,t,o){let r=ho(e);if(!r)return{sent:0};let s=0;for(let i=0;i<r.items.length;i+=t){let n=r.items.slice(i,i+t);try{await o(n),s+=n.length}catch(a){if(Ws(a))return r.release(r.items.slice(i)),{sent:s,error:a}}}return r.done(),{sent:s}}function _e(e){ct(f.queue(),e)}function Me(e){ct(f.usageQueue(),e)}async function pt(e,t){let o=re();if(!e.apiKey)return{sent:0,samples:0,queued:!0,error:"Not signed in. Run `npx getstint login`."};let r=await yo(f.queue(),Ls,(a)=>P.heartbeats(e,a,t)),s=r.error?{sent:0,error:r.error}:await yo(f.usageQueue(),qs,(a)=>P.usage(e,a)),i=r.error??s.error,n=i instanceof Error?i.message:void 0;return Se({...o,lastFlush:i?o.lastFlush:Date.now(),lastError:n?{at:Date.now(),message:n}:void 0,authFailed:i instanceof oe&&i.status===401}),{sent:r.sent,samples:s.sent,queued:Boolean(i),error:n}}var $e="opencode";function zt(e,t){let o=S(e),r=S(o.time),s=S(o.path),i=S(o.tokens),n=S(i.cache),a=b(o.sessionID)??"opencode",c=t.projectOf(b(s.root)??b(s.cwd)),l=Y(r.completed)??Y(r.created),m=b(o.id),d=b(o.modelID);if(o.role!=="assistant"||!m||!l||!d)return{sample:null,time:l,session:a,project:c,model:d};let g={source_id:`opencode:${m}`,time:l,agent:$e,model:d,project:c,input_tokens:w(i.input),output_tokens:w(i.output)+w(i.reasoning),cache_read_tokens:w(n.read),cache_write_tokens:w(n.write)};return{sample:g.input_tokens+g.output_tokens+g.cache_read_tokens+g.cache_write_tokens===0||!r.completed?null:g,time:l,session:a,project:c,model:d}}function bo(e,t){let o=[],r=[];for(let s of e){let i;try{i=JSON.parse(s)}catch{continue}let{sample:n,time:a,session:c,project:l,model:m}=zt(i,t);if(n)o.push(n);if(a&&m)r.push(Q($e,a,l,c,m))}return{samples:o,heartbeats:r,carry:{}}}var Gs=60000,Js=4194304;async function Ks(e){if(process.stdin.isTTY)return"";return new Promise((t)=>{let o="",r=()=>t(o),s=setTimeout(r,e);process.stdin.setEncoding("utf8"),process.stdin.on("data",(i)=>{if(o.length<Js)o+=i}),process.stdin.on("end",()=>{clearTimeout(s),r()}),process.stdin.on("error",()=>{clearTimeout(s),r()})})}async function ko(e){try{if(!e||!/^[a-z0-9-]{2,40}$/.test(e))return;let t=await Ks(2000),o={};try{o=t.trim()?JSON.parse(t):{}}catch{o={}}let r=$();if(!r.apiKey)return;let s=Date.now()/1000,i=o.cwd??o.workspace_roots?.[0]??process.cwd(),n=ke(i);_e([{...at(e,{...o,cwd:i},s,n),machine:r.machine}]);let a=re(),c=lo(o.hook_event_name);if(e===$e&&o.message){let{sample:l}=zt(o.message,{projectOf:xe});if(l)Me([l])}else if(c&&o.transcript_path){let l=we(e,o.transcript_path,a,i);Me(l.samples)}if(Se(a),c||!a.lastFlush||Date.now()-a.lastFlush>Gs)nt(["flush","--quiet",`--agent=${e}`])}catch(t){mo(`hook ${e}: ${t instanceof Error?t.stack??t.message:String(t)}`)}}mt();F();var de=R(J(),1);import{hostname as Fs}from"node:os";q();te();var qe=R(J(),1);import{spawn as Ys,spawnSync as Qs}from"node:child_process";var Vs=/truecolor|24bit/i.test(process.env.COLORTERM??"")||process.env.TERM_PROGRAM==="vscode"||process.env.WT_SESSION!==void 0,Xs=(e)=>!qe.default.isColorSupported?e:Vs?`\x1B[38;2;255;178;36m${e}\x1B[39m`:qe.default.yellow(e),Zs=()=>Xs("◔"),Ce=()=>`${Zs()} ${qe.default.bold("stint")}`;function wo(e){let t=Math.round(e/60);if(t<1)return"0m";let o=Math.floor(t/60);return o?`${o}h ${t%60}m`:`${t}m`}function ve(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 So(){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 Vt(e,t){try{let o=Ys(e,t,{stdio:"ignore",detached:!0,windowsHide:!0});return o.on("error",()=>{return}),o.unref(),!0}catch{return!1}}function Xt(e){if(!/^https?:\/\//.test(e))return!1;if(process.platform==="win32")return Vt("rundll32",["url.dll,FileProtocolHandler",e]);if(process.platform==="darwin")return Vt("open",[e]);return Vt("xdg-open",[e])}function _o(e){let t=process.platform==="win32"?[["clip",[]]]:process.platform==="darwin"?[["pbcopy",[]]]:[["wl-copy",[]],["xclip",["-selection","clipboard"]],["xsel",["--clipboard","--input"]]];for(let[o,r]of t)try{if(Qs(o,r,{input:e,stdio:["pipe","ignore","ignore"],windowsHide:!0,timeout:2000}).status===0)return!0}catch{}return!1}function Ie(e,t=e){if(!process.stdout.isTTY||process.env.TERM==="dumb")return e;return`\x1B]8;;${e}\x07${qe.default.underline(t)}\x1B]8;;\x07`}var Ds=(e)=>new Promise((t)=>setTimeout(t,e));function ei(e,t){let o=new URL("/device",e.apiUrl);return o.searchParams.set("user_code",t),o.searchParams.set("client",st),o.toString()}var ti=(e)=>e.length===8?`${e.slice(0,4)}-${e.slice(4)}`:e;async function $o(e,t){let o=await P.me({...e,apiKey:t});return tt(),ce({apiUrl:e.apiUrl,apiKey:t,username:o.username,email:o.email})}async function ni(e,t,o,r,s){let i=Math.max(o,2)*1000,n=Date.now()+r*1000;while(Date.now()<n){await Ds(i);try{let{access_token:a}=await P.deviceToken(e,t);return a}catch(a){if(!(a instanceof oe))throw a;if(a.code==="authorization_pending"||a.status===0)continue;if(a.code==="slow_down"){i+=5000;continue}if(a.code==="access_denied")throw Error("Sign-in was denied in the browser.");if(a.code==="expired_token")throw Error("The code expired. Run the command again for a new one.");throw a}}throw s.stop("Timed out"),Error("The code expired before it was approved. Run the command again for a new one.")}async function dt(e={}){let t=$(),o={...t,apiUrl:e.apiUrl?Ut(e.apiUrl):t.apiUrl};if(e.key){let m=Oe();m.start("Checking your key");try{let d=await $o(o,e.key.trim());return m.stop(`Signed in as ${de.default.bold(d.username??"you")}`),d}catch(d){throw m.stop("That key didn’t work",1),d}}let r=await P.deviceCode(o),s=ei(o,r.user_code),i=ti(r.user_code),n=e.browser!==!1&&So(),a=We()&&_o(s);if(De([`${de.default.dim("Your code")} ${de.default.bold(de.default.white(i))}`,"",n?"Approve this sign-in in the browser window that just opened.":"Open this link on any device and approve the sign-in:",Ie(s),a?de.default.dim("The link is on your clipboard."):""].filter((m,d,g)=>m!==""||d>0&&g[d-1]!=="").join(`
|
|
104
|
+
`),"Connect this machine"),n)if(We()){let m=await Fe({message:"Open the browser now?",initialValue:!0});if(Z(m))throw Error("Cancelled.");if(m)Xt(s)}else Xt(s);let c=Oe();c.start("Waiting for you to approve in the browser");let l=await ni(o,r.device_code,r.interval,r.expires_in,c);c.message("Creating a key for this machine");try{let{key:m}=await P.mintKey(o,l,`${Fs()} · CLI`.slice(0,60)),d=await $o(o,m);return c.stop(`Signed in as ${de.default.bold(d.username??"you")}`),d}finally{await P.signOutSession(o,l)}}q();import{spawn as oi}from"node:child_process";te();var ri=60000,si={grok:"grok-cli",copilot:"copilot-cli",amp:"amp",qwen:"qwen-code",kiro:"kiro",cline:"cline"};async function Co(e){let t=e.indexOf("--"),[o,...r]=t===-1?e:[e[0],...e.slice(t+1)];if(!o)throw Error("Usage: stint run <agent> [-- command args] e.g. stint run grok");let s=si[o]??o,i=t===-1?[o,...r]:r,n=$(),a=`${s}-${Date.now().toString(36)}`,c=ke(process.cwd()),l=()=>{if(!n.apiKey)return;_e([{...at(s,{session_id:a,cwd:process.cwd()},Date.now()/1000,c),machine:n.machine}]),nt(["flush","--quiet",`--agent=${s}`])};l();let m=setInterval(l,ri),d=oi(i[0],i.slice(1),{stdio:"inherit",shell:process.platform==="win32"}),g=await new Promise((h)=>{d.on("exit",(u)=>h(u??0)),d.on("error",()=>h(127))});return clearInterval(m),l(),g}F();var Ft=R(J(),1);q();be();mt();F();var Zt=R(J(),1);import{readdirSync as ii,readFileSync as ai,statSync as Io}from"node:fs";import{join as Ge}from"node:path";q();L();var vo=395;function Je(e,t,o,r=0,s=[]){if(r>6)return s;let i;try{i=ii(e,{withFileTypes:!0})}catch{return s}for(let n of i){let a=Ge(e,n.name);if(n.isDirectory())Je(a,t,o,r+1,s);else if(t(n.name))try{if(Io(a).mtimeMs>=o)s.push(a)}catch{}}return s}function ci(e=vo){let t=Date.now()-Math.min(e,vo)*86400000,o=re(),r=[],s=[],i=[],n=(c,l,m)=>{let d=m.samples.filter((h)=>h.time*1000>=t);r.push(...d),s.push(...m.heartbeats.filter((h)=>h.time*1000>=t));let g=i.find((h)=>h.agent===c)??i[i.push({agent:c,files:0,samples:0,tokens:0})-1];g.files+=l,g.samples+=d.length,g.tokens+=d.reduce((h,u)=>h+u.input_tokens+u.output_tokens+u.cache_read_tokens+u.cache_write_tokens,0)};for(let c of Je(f.claudeProjects(),(l)=>l.endsWith(".jsonl"),t))n(le,1,we(le,c,o));for(let c of[Ge(f.codexHome(),"sessions"),Ge(f.codexHome(),"archived_sessions")])for(let l of Je(c,(m)=>m.endsWith(".jsonl"),t))n(V,1,we(V,l,o));for(let c of Je(Ge(f.geminiHome(),"tmp"),(l)=>l.endsWith(".json")&&l.startsWith("session-"),t))n(me,1,we(me,c,o));let a=Je(Ge(f.opencodeData(),"storage","message"),(c)=>c.endsWith(".json"),t).filter((c)=>{try{let l=Io(c).mtimeMs;if(o.cursors[c]?.size===l)return!1;return o.cursors[c]={offset:0,size:l},!0}catch{return!1}});if(a.length){let c=a.map((l)=>{try{return ai(l,"utf8")}catch{return""}});n($e,a.length,bo(c,{projectOf:xe}))}return Se(o),{samples:r,heartbeats:s,totals:i}}async function ft(e={}){let t=$();if(!t.apiKey)throw Error("Sign in first: npx getstint login");let o=e.quiet?null:Oe();o?.start("Reading your agent history");let{samples:r,heartbeats:s,totals:i}=ci(e.days);Me(r),_e(s.map((a)=>({...a,machine:t.machine}))),o?.message(`Sending ${ve(r.length)} usage records`);let n=await pt(t);if(!o)return n;o.stop(n.error?`Saved for later: ${n.error}`:`Synced ${ve(n.samples)} usage records and ${ve(n.sent)} activity events`);for(let a of i.filter((c)=>c.samples>0))y.info(`${Zt.default.bold(a.agent)} ${Zt.default.dim(`${a.files} files · ${ve(a.samples)} records · ${ve(a.tokens)} tokens`)}`);return n}async function To(e){Pe(`${Ce()} ${Ft.default.dim(`v${E}`)}`);let t=$(),o=!1;if(t.apiKey&&!e.key&&!e.apiUrl)try{let r=await P.me(t);y.success(`Signed in as ${Ft.default.bold(r.username)}`),o=!0}catch{y.warn("Your saved key no longer works, so let’s sign in again.")}if(!o)t=await dt(e);if(!We()||e.yes){let{install:r}=await Promise.resolve().then(() => (mt(),xo));await r([],!0)}else{let r=await lt();if(r===null){et("Signed in. Connect tools any time with `npx getstint install`.");return}if(r.length)Le(r);let s=await Fe({message:"Import token usage from your past agent sessions?",initialValue:!0});if(!Z(s)&&s)await ft()}He(`You’re set. Your dashboard: ${Ie(`${t.apiUrl}/dashboard`)}`)}F();var C=R(J(),1);rt();q();L();te();be();async function Po(){let e=$(),t=re(),o=[];if(!e.apiKey)o.push(`${C.default.yellow("●")} Not signed in. Run ${C.default.bold("npx getstint login")}.`);else try{let[s,i]=await Promise.all([P.me(e),P.today(e).catch(()=>null)]);if(s.username!==e.username)ce({username:s.username,email:s.email});if(o.push(`${C.default.green("●")} Signed in as ${C.default.bold(s.username)} ${C.default.dim(s.email)}`),i)o.push(`${C.default.dim("Today")} ${C.default.bold(wo(i.data.grand_total.total_seconds))}`)}catch(s){o.push(`${C.default.red("●")} ${s instanceof Error?s.message:String(s)}`)}o.push("");for(let s of j){let i=s.installed()?C.default.green("✓"):s.detected()?C.default.yellow("○"):C.default.dim("·");o.push(`${i} ${s.name}${s.installed()?"":C.default.dim(s.detected()?" found, not connected":" not found")}`)}o.push("");let r=Kt(f.queue())+Kt(f.usageQueue());if(o.push(`${C.default.dim("Server")} ${e.apiUrl}`),o.push(`${C.default.dim("Version")} ${E}${Ae()&&Ae()!==E?C.default.dim(` (hooks use ${Ae()})`):""}`),o.push(`${C.default.dim("Waiting")} ${r?`${r} events will send when Stint is reachable`:"nothing queued"}`),t.lastFlush)o.push(`${C.default.dim("Last sent")} ${new Date(t.lastFlush).toLocaleString()}`);if(t.lastError)o.push(`${C.default.dim("Last error")} ${C.default.red(t.lastError.message)}`);if(De(o.join(`
|
|
105
|
+
`),"Stint"),e.apiKey)y.message(`Dashboard: ${Ie(`${e.apiUrl}/dashboard`)}`)}function Ho(e){let t=[],o={},r;for(let s=0;s<e.length;s+=1){let i=e[s];if(i==="--"){t.push(...e.slice(s));break}if(i.startsWith("--")){let[n,a]=i.slice(2).split(/=(.*)/s,2);if(n.startsWith("no-"))o[n.slice(3)]=!1;else if(a!==void 0)o[n]=a;else if(["key","api-url","days","agent"].includes(n)&&e[s+1]&&!e[s+1].startsWith("-"))o[n]=e[++s];else o[n]=!0;continue}if(i==="-h")o.help=!0;else if(i==="-v")o.version=!0;else if(i==="-y")o.yes=!0;else if(r===void 0)r=i;else t.push(i)}return{command:r,positionals:t,flags:o}}q();be();var Oo=`${Ce()} ${v.default.dim(`v${E}`)} Coding time and AI agent tracking for getstint.dev
|
|
106
|
+
|
|
107
|
+
${v.default.bold("Usage")} npx getstint [command]
|
|
108
|
+
|
|
109
|
+
${v.default.bold("Commands")}
|
|
110
|
+
${v.default.cyan("(none)")} Sign in, pick what to track, import past agent usage
|
|
111
|
+
${v.default.cyan("login")} Connect this machine ${v.default.dim("--no-browser --key <key> --api-url <url>")}
|
|
112
|
+
${v.default.cyan("logout")} Forget the key on this machine
|
|
113
|
+
${v.default.cyan("status")} Who you are, today's time and what's connected
|
|
114
|
+
${v.default.cyan("install")} [ids] Connect agents and editors ${v.default.dim("--all")}
|
|
115
|
+
${v.default.cyan("uninstall")} [ids] Disconnect them again
|
|
116
|
+
${v.default.cyan("sync")} Import token usage from past agent sessions ${v.default.dim("--days <n>")}
|
|
117
|
+
${v.default.cyan("run")} <agent> Track any CLI agent by wrapping it ${v.default.dim("stint run grok")}
|
|
118
|
+
${v.default.cyan("flush")} Send anything waiting in the offline queue
|
|
119
|
+
${v.default.cyan("doctor")} Check that everything is wired up
|
|
120
|
+
|
|
121
|
+
${v.default.bold("Integrations")} claude-code, codex, gemini-cli, opencode, editors, wakatime
|
|
122
|
+
|
|
123
|
+
Docs: https://github.com/getstint/stint-cli`;async function pi(){let{command:e,positionals:t,flags:o}=Ho(process.argv.slice(2));if(o.version)return console.info(E),0;if(o.help||e==="help")return console.info(Oo),0;let r={key:typeof o.key==="string"?o.key:void 0,apiUrl:typeof o["api-url"]==="string"?o["api-url"]:void 0,browser:o.browser!==!1};switch(e){case void 0:case"setup":return await To({...r,yes:o.yes===!0}),0;case"login":return Pe(Ce()),await dt(r),He("This machine is connected. Run `npx getstint install` to pick what to track."),0;case"logout":return ce({apiKey:void 0,username:void 0,email:void 0}),y.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 Po(),0;case"install":return Pe(Ce()),await Yt(t,o.all===!0),He("Done."),0;case"uninstall":return Qt(t),0;case"sync":return await ft({days:typeof o.days==="string"?Number(o.days):void 0}),0;case"flush":{let s=await pt($(),typeof o.agent==="string"?o.agent:void 0);if(!o.quiet)console.info(s.error?`Queued: ${s.error}`:`Sent ${s.sent} events and ${s.samples} usage records.`);return 0}case"hook":return await ko(t[0]),0;case"run":return Co(t);case"doctor":return await no()?0:1;default:return console.error(`Unknown command "${e}".
|
|
124
|
+
`),console.info(Oo),1}}pi().then((e)=>process.exit(e)).catch((e)=>{let t=e instanceof Error?e.message:String(e);if(process.argv[2]==="hook")process.exit(0);y.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.0",
|
|
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
|
+
}
|