getstint 0.1.3 → 0.1.4

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.
Files changed (2) hide show
  1. package/dist/stint.mjs +3 -3
  2. package/package.json +1 -1
package/dist/stint.mjs CHANGED
@@ -54,7 +54,7 @@ ${a.default.gray(fe)} ${e}
54
54
  `)},info:(e)=>{f.message(e,{symbol:a.default.blue(br)})},success:(e)=>{f.message(e,{symbol:a.default.green($r)})},step:(e)=>{f.message(e,{symbol:a.default.green(Xe)})},warn:(e)=>{f.message(e,{symbol:a.default.yellow(wr)})},warning:(e)=>{f.warn(e)},error:(e)=>{f.message(e,{symbol:a.default.red(kr)})}},Ao=`${a.default.gray(E)} `});import{chmodSync as Br,existsSync as _u,mkdirSync as xr,readFileSync as Iu,renameSync as vr,writeFileSync as Tu}from"node:fs";import{dirname as Sr}from"node:path";function Fe(e){try{return Iu(e,"utf8")}catch{return null}}function V(e){let t=Fe(e);if(t===null)return null;try{return JSON.parse(Ar(t))}catch{return null}}function Pe(e,t,n){xr(Sr(e),{recursive:!0});let r=`${e}.${process.pid}.tmp`;if(Tu(r,t,n===void 0?void 0:{mode:n}),vr(r,e),n!==void 0&&process.platform!=="win32")Br(e,n)}function ie(e,t,n){Pe(e,`${JSON.stringify(t,null,2)}
55
55
  `,n)}function _t(e,t=".stint-backup"){if(!_u(e)||_u(e+t))return null;return Tu(e+t,Iu(e)),e+t}function Ar(e){let t="",n=!1;for(let r=0;r<e.length;r+=1){let s=e[r],o=e[r+1];if(n){if(t+=s,s==="\\")t+=o??"",r+=1;else if(s==='"')n=!1;continue}if(s==='"')n=!0,t+=s;else if(s==="/"&&o==="/"){while(r<e.length&&e[r]!==`
56
56
  `)r+=1;t+=`
57
- `}else if(s==="/"&&o==="*"){r+=2;while(r<e.length&&!(e[r]==="*"&&e[r+1]==="/"))r+=1;r+=1}else t+=s}return t.replace(/,(\s*[}\]])/g,"$1")}var je=()=>{};import{homedir as _r}from"node:os";import{join as v}from"node:path";var te=()=>process.env.STINT_HOME_OVERRIDE??_r(),Ce=()=>process.env.STINT_HOME??v(te(),".stint"),m;var R=U(()=>{m={config:()=>v(Ce(),"config.json"),state:()=>v(Ce(),"state.json"),queue:()=>v(Ce(),"queue.jsonl"),usageQueue:()=>v(Ce(),"usage.jsonl"),log:()=>v(Ce(),"stint.log"),bin:()=>v(Ce(),"bin","stint.mjs"),claudeSettings:()=>v(process.env.CLAUDE_CONFIG_DIR??v(te(),".claude"),"settings.json"),claudeProjects:()=>v(process.env.CLAUDE_CONFIG_DIR??v(te(),".claude"),"projects"),codexHome:()=>process.env.CODEX_HOME??v(te(),".codex"),geminiHome:()=>v(te(),".gemini"),opencodeConfig:()=>v(process.env.XDG_CONFIG_HOME??v(te(),".config"),"opencode"),opencodeData:()=>v(process.env.XDG_DATA_HOME??v(te(),".local","share"),"opencode"),wakatimeConfig:()=>v(process.env.WAKATIME_HOME??te(),".wakatime.cfg")}});import{hostname as Ir}from"node:os";function It(e){let t=new URL(e.includes("://")?e:`https://${e}`);if(t.protocol!=="https:"&&!["localhost","127.0.0.1","[::1]"].includes(t.hostname))throw Error("Stint only talks to servers over HTTPS (http is allowed for localhost).");return t.origin}function k(){let e=V(m.config())??{},t=process.env.STINT_API_URL??e.apiUrl??Tr;return{apiUrl:It(t),apiKey:process.env.STINT_API_KEY??e.apiKey,username:e.username,email:e.email,machine:e.machine??Ir(),installed:Array.isArray(e.installed)?e.installed.filter((n)=>typeof n==="string"):[],hideProjectNames:e.hideProjectNames===!0}}function De(e){let n={...V(m.config())??{},...e};for(let r of Object.keys(n))if(n[r]===void 0)delete n[r];return ie(m.config(),n,Pr),k()}function Tt(e,t){let n=new Set(k().installed);if(t)n.add(e);else n.delete(e);De({installed:[...n].sort()})}var Tr="https://getstint.dev",Pr=384;var N=U(()=>{je();R()});var ju;var Pu=U(()=>{ju={name:"getstint",version:"0.1.3",description:"Track your coding time and AI agents with Stint: one command connects Claude Code, Codex, Gemini CLI, OpenCode and your editors.",keywords:["stint","time-tracking","wakatime","wakatime-alternative","claude-code","codex","gemini-cli","opencode","ai-agents","cli","developer-tools"],homepage:"https://getstint.dev",bugs:{url:"https://github.com/getstint/stint-cli/issues"},repository:{type:"git",url:"git+https://github.com/getstint/stint-cli.git"},license:"MIT",author:"Stint <hello@getstint.dev> (https://getstint.dev)",type:"module",bin:{stint:"dist/stint.mjs",getstint:"dist/stint.mjs"},files:["dist/stint.mjs","README.md","LICENSE"],engines:{node:">=18.17"},scripts:{build:"bun scripts/build.ts",dev:"bun src/cli.ts",test:"bun test",typecheck:"tsc --noEmit",check:"bun run format:check && bun run typecheck && bun test && bun run build",prepublishOnly:"bun run check",format:"prettier --write .","format:check":"prettier --check ."},devDependencies:{"@clack/prompts":"^0.11.0","@types/bun":"^1.2.22","@types/node":"^22.15.0",picocolors:"^1.1.1",prettier:"3.6.2",typescript:"^5.9.3"},publishConfig:{access:"public"}}});var O,Ou=(e="stint-cli")=>`${e}/${O} (${process.platform}-${process.arch}) node/${process.versions.node}`;var Ee=U(()=>{Pu();O=ju.version});import{spawn as Or,spawnSync as Mu}from"node:child_process";import{copyFileSync as Mr,existsSync as Hu,mkdirSync as Ur,readFileSync as Hr,realpathSync as Rr,writeFileSync as Nr}from"node:fs";import{dirname as Wr,extname as Lr}from"node:path";import{fileURLToPath as Gr}from"node:url";function W(e){return(process.platform==="win32"?Mu("where",[e],{stdio:"ignore",windowsHide:!0}):Mu("sh",["-c",`command -v ${e}`],{stdio:"ignore"})).status===0}function Ru(){try{let e=Rr(Gr(import.meta.url));return Lr(e)===".mjs"?e:null}catch{return null}}function Oe(){try{return Hr(Nu(),"utf8").trim()}catch{return null}}function ye(){let e=m.bin(),t=Ru();if(t&&t!==e&&(Oe()!==O||!Hu(e)))Ur(Wr(e),{recursive:!0}),Mr(t,e),Nr(Nu(),O);return e}function ue(){return W("node")?"node":process.execPath}function Wu(e){return`${Uu(ue())} ${Uu(m.bin().replace(/\\/g,"/"))} hook ${e}`}function Me(e){let t=Hu(m.bin())?m.bin():Ru();if(!t)return;try{let n=Or(ue(),[t,...e],{stdio:"ignore",detached:!0,windowsHide:!0,env:process.env});n.on("error",()=>{return}),n.unref()}catch{}}var Nu=()=>`${m.bin()}.version`,Uu=(e)=>/[\s"]/.test(e)?`"${e.replace(/"/g,"\\\"")}"`:e;var K=U(()=>{R();Ee()});function jt(e,t){if(!e.hooks||typeof e.hooks!=="object")return e;let n={};for(let[o,u]of Object.entries(e.hooks)){if(!Array.isArray(u)){n[o]=u;continue}let i=u.map((D)=>D&&Array.isArray(D.hooks)?{...D,hooks:D.hooks.filter((c)=>!Lu(c,t))}:D).filter((D)=>!D||!Array.isArray(D.hooks)||D.hooks.length>0);if(i.length>0)n[o]=i}if(Object.keys(n).length>0)return{...e,hooks:n};let{hooks:r,...s}=e;return s}function Gu(e,t,n){let r=jt(e,t),s={...r.hooks??{}};for(let o of n){let u=o.matcher===void 0?{hooks:[o.handler]}:{matcher:o.matcher,hooks:[o.handler]};s[o.event]=[...s[o.event]??[],u]}return{...r,hooks:s}}function qu(e,t){if(!e?.hooks)return!1;return Object.values(e.hooks).some((n)=>Array.isArray(n)&&n.some((r)=>Array.isArray(r?.hooks)&&r.hooks.some((s)=>Lu(s,t))))}var qr=(e)=>new RegExp(`stint(\\.mjs)?["']?\\s+hook\\s+${e.replace(/[-]/g,"\\-")}(\\s|$)`),Lu=(e,t)=>{let n=e?.command;return typeof n==="string"&&qr(t).test(n)};function Vu(e,t){return`import { spawn } from "node:child_process";
57
+ `}else if(s==="/"&&o==="*"){r+=2;while(r<e.length&&!(e[r]==="*"&&e[r+1]==="/"))r+=1;r+=1}else t+=s}return t.replace(/,(\s*[}\]])/g,"$1")}var je=()=>{};import{homedir as _r}from"node:os";import{join as v}from"node:path";var te=()=>process.env.STINT_HOME_OVERRIDE??_r(),Ce=()=>process.env.STINT_HOME??v(te(),".stint"),m;var R=U(()=>{m={config:()=>v(Ce(),"config.json"),state:()=>v(Ce(),"state.json"),queue:()=>v(Ce(),"queue.jsonl"),usageQueue:()=>v(Ce(),"usage.jsonl"),log:()=>v(Ce(),"stint.log"),bin:()=>v(Ce(),"bin","stint.mjs"),claudeSettings:()=>v(process.env.CLAUDE_CONFIG_DIR??v(te(),".claude"),"settings.json"),claudeProjects:()=>v(process.env.CLAUDE_CONFIG_DIR??v(te(),".claude"),"projects"),codexHome:()=>process.env.CODEX_HOME??v(te(),".codex"),geminiHome:()=>v(te(),".gemini"),opencodeConfig:()=>v(process.env.XDG_CONFIG_HOME??v(te(),".config"),"opencode"),opencodeData:()=>v(process.env.XDG_DATA_HOME??v(te(),".local","share"),"opencode"),wakatimeConfig:()=>v(process.env.WAKATIME_HOME??te(),".wakatime.cfg")}});import{hostname as Ir}from"node:os";function It(e){let t=new URL(e.includes("://")?e:`https://${e}`);if(t.protocol!=="https:"&&!["localhost","127.0.0.1","[::1]"].includes(t.hostname))throw Error("Stint only talks to servers over HTTPS (http is allowed for localhost).");return t.origin}function k(){let e=V(m.config())??{},t=process.env.STINT_API_URL??e.apiUrl??Tr;return{apiUrl:It(t),apiKey:process.env.STINT_API_KEY??e.apiKey,username:e.username,email:e.email,machine:e.machine??Ir(),installed:Array.isArray(e.installed)?e.installed.filter((n)=>typeof n==="string"):[],hideProjectNames:e.hideProjectNames===!0}}function De(e){let n={...V(m.config())??{},...e};for(let r of Object.keys(n))if(n[r]===void 0)delete n[r];return ie(m.config(),n,Pr),k()}function Tt(e,t){let n=new Set(k().installed);if(t)n.add(e);else n.delete(e);De({installed:[...n].sort()})}var Tr="https://getstint.dev",Pr=384;var N=U(()=>{je();R()});var ju;var Pu=U(()=>{ju={name:"getstint",version:"0.1.4",description:"Track your coding time and AI agents with Stint: one command connects Claude Code, Codex, Gemini CLI, OpenCode and your editors.",keywords:["stint","time-tracking","wakatime","wakatime-alternative","claude-code","codex","gemini-cli","opencode","ai-agents","cli","developer-tools"],homepage:"https://getstint.dev",bugs:{url:"https://github.com/getstint/stint-cli/issues"},repository:{type:"git",url:"git+https://github.com/getstint/stint-cli.git"},license:"MIT",author:"Stint <hello@getstint.dev> (https://getstint.dev)",type:"module",bin:{stint:"dist/stint.mjs",getstint:"dist/stint.mjs"},files:["dist/stint.mjs","README.md","LICENSE"],engines:{node:">=18.17"},scripts:{build:"bun scripts/build.ts",dev:"bun src/cli.ts",test:"bun test",typecheck:"tsc --noEmit",check:"bun run format:check && bun run typecheck && bun test && bun run build",prepublishOnly:"bun run check",format:"prettier --write .","format:check":"prettier --check ."},devDependencies:{"@clack/prompts":"^0.11.0","@types/bun":"^1.2.22","@types/node":"^22.15.0",picocolors:"^1.1.1",prettier:"3.6.2",typescript:"^5.9.3"},publishConfig:{access:"public"}}});var O,Ou=(e="stint-cli")=>`${e}/${O} (${process.platform}-${process.arch}) node/${process.versions.node}`;var Ee=U(()=>{Pu();O=ju.version});import{spawn as Or,spawnSync as Mu}from"node:child_process";import{copyFileSync as Mr,existsSync as Hu,mkdirSync as Ur,readFileSync as Hr,realpathSync as Rr,writeFileSync as Nr}from"node:fs";import{dirname as Wr,extname as Lr}from"node:path";import{fileURLToPath as Gr}from"node:url";function W(e){return(process.platform==="win32"?Mu("where",[e],{stdio:"ignore",windowsHide:!0}):Mu("sh",["-c",`command -v ${e}`],{stdio:"ignore"})).status===0}function Ru(){try{let e=Rr(Gr(import.meta.url));return Lr(e)===".mjs"?e:null}catch{return null}}function Oe(){try{return Hr(Nu(),"utf8").trim()}catch{return null}}function ye(){let e=m.bin(),t=Ru();if(t&&t!==e&&(Oe()!==O||!Hu(e)))Ur(Wr(e),{recursive:!0}),Mr(t,e),Nr(Nu(),O);return e}function ue(){return W("node")?"node":process.execPath}function Wu(e){return`${Uu(ue())} ${Uu(m.bin().replace(/\\/g,"/"))} hook ${e}`}function Me(e){let t=Hu(m.bin())?m.bin():Ru();if(!t)return;try{let n=Or(ue(),[t,...e],{stdio:"ignore",detached:!0,windowsHide:!0,env:process.env});n.on("error",()=>{return}),n.unref()}catch{}}var Nu=()=>`${m.bin()}.version`,Uu=(e)=>/[\s"]/.test(e)?`"${e.replace(/"/g,"\\\"")}"`:e;var K=U(()=>{R();Ee()});function jt(e,t){if(!e.hooks||typeof e.hooks!=="object")return e;let n={};for(let[o,u]of Object.entries(e.hooks)){if(!Array.isArray(u)){n[o]=u;continue}let i=u.map((D)=>D&&Array.isArray(D.hooks)?{...D,hooks:D.hooks.filter((c)=>!Lu(c,t))}:D).filter((D)=>!D||!Array.isArray(D.hooks)||D.hooks.length>0);if(i.length>0)n[o]=i}if(Object.keys(n).length>0)return{...e,hooks:n};let{hooks:r,...s}=e;return s}function Gu(e,t,n){let r=jt(e,t),s={...r.hooks??{}};for(let o of n){let u=o.matcher===void 0?{hooks:[o.handler]}:{matcher:o.matcher,hooks:[o.handler]};s[o.event]=[...s[o.event]??[],u]}return{...r,hooks:s}}function qu(e,t){if(!e?.hooks)return!1;return Object.values(e.hooks).some((n)=>Array.isArray(n)&&n.some((r)=>Array.isArray(r?.hooks)&&r.hooks.some((s)=>Lu(s,t))))}var qr=(e)=>new RegExp(`stint(\\.mjs)?["']?\\s+hook\\s+${e.replace(/[-]/g,"\\-")}(\\s|$)`),Lu=(e,t)=>{let n=e?.command;return typeof n==="string"&&qr(t).test(n)};function Vu(e,t){return`import { spawn } from "node:child_process";
58
58
 
59
59
  const NODE = ${JSON.stringify(e)};
60
60
  const BIN = ${JSON.stringify(t)};
@@ -94,13 +94,13 @@ export const StintPlugin = async ({ directory, worktree }) => {
94
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
95
  `)}function Yu(){let e=`${m.wakatimeConfig()}.stint-backup`;return Vr(e)?Kr(e,"utf8"):Jr(nt())}var Ot=(e)=>`${e}/api/compat/wakatime/v1`,nt=()=>Fe(m.wakatimeConfig())??"",Ku=(e)=>e.join(`
96
96
  `).replace(/\n*$/,`
97
- `);var Qu=U(()=>{je();R()});import{spawnSync as Zu}from"node:child_process";import{existsSync as ae,rmSync as zr}from"node:fs";import{join as He}from"node:path";function Ht(e){return{id:e.id,name:e.name,kind:"agent",hint:e.hint,detected:e.detected,installed:()=>qu(V(e.file()),e.id),install:()=>{let t=e.file(),r=Fe(t)===null?{}:V(t);if(r===null)throw Error(`${t} isn't valid JSON, so Stint left it alone. Fix it and run the install again.`);return _t(t),ie(t,Gu(r,e.id,e.specs())),[`Added Stint hooks to ${t}`,e.after].filter(Boolean).join(". ")},uninstall:()=>{let t=e.file(),n=V(t);if(!n)return`Nothing to remove in ${t}`;return ie(t,jt(n,e.id)),`Removed Stint hooks from ${t}`}}}var Ut=(e)=>({type:"command",command:Wu(e)}),Yr,Qr,Zr,Ue=()=>He(m.opencodeConfig(),"plugins","stint.js"),Xr,Mt,Xu="getstint.stint",es,ts,P,Re=(e)=>P.find((t)=>t.id===e);var rt=U(()=>{N();je();R();K();Qu();Yr=Ht({id:"claude-code",name:"Claude Code",hint:"hooks in ~/.claude/settings.json",file:m.claudeSettings,detected:()=>ae(He(m.claudeSettings(),".."))||W("claude"),specs:()=>{let e={...Ut("claude-code"),async:!0,timeout:30};return[{event:"SessionStart",handler:e},{event:"UserPromptSubmit",handler:e},{event:"PostToolUse",matcher:"*",handler:e},{event:"Stop",handler:e},{event:"SubagentStop",handler:e},{event:"SessionEnd",handler:e}]}}),Qr=Ht({id:"codex",name:"Codex CLI",hint:"hooks in ~/.codex/hooks.json",file:()=>He(m.codexHome(),"hooks.json"),detected:()=>ae(m.codexHome())||W("codex"),specs:()=>{let e={...Ut("codex"),async:!0,statusMessage:"Stint"};return[{event:"SessionStart",handler:e},{event:"UserPromptSubmit",handler:e},{event:"PostToolUse",matcher:"*",handler:e},{event:"Stop",handler:e}]},after:"Codex asks you to trust new hooks once: run /hooks in Codex and approve the Stint entries"}),Zr=Ht({id:"gemini-cli",name:"Gemini CLI",hint:"hooks in ~/.gemini/settings.json",file:()=>He(m.geminiHome(),"settings.json"),detected:()=>ae(m.geminiHome())||W("gemini"),specs:()=>{let e={...Ut("gemini-cli"),name:"stint",timeout:5000};return[{event:"SessionStart",handler:e},{event:"BeforeAgent",handler:e},{event:"AfterTool",matcher:".*",handler:e},{event:"AfterAgent",handler:e},{event:"SessionEnd",handler:e}]}}),Xr={id:"opencode",name:"OpenCode",kind:"agent",hint:"plugin in ~/.config/opencode/plugins",detected:()=>ae(m.opencodeConfig())||ae(m.opencodeData())||W("opencode"),installed:()=>Fe(Ue())?.includes("STINT_PLUGIN")??!1,install:()=>(Pe(Ue(),Vu(ue(),m.bin())),`Wrote ${Ue()}`),uninstall:()=>(zr(Ue(),{force:!0}),`Removed ${Ue()}`)},Mt=["code","cursor","windsurf","codium","code-insiders"],es={id:"editors",name:"VS Code, Cursor and Windsurf",kind:"editor",hint:"installs the Stint extension",detected:()=>Mt.some(W),installed:()=>!1,install:()=>Mt.filter(W).map((t)=>Zu(t,["--install-extension",Xu,"--force"],{stdio:"ignore",shell:process.platform==="win32",timeout:120000}).status===0?`${t}: installed`:`${t}: couldn't install, get it at https://marketplace.visualstudio.com/items?itemName=getstint.stint`).join(", ")||"No editor command line found",uninstall:()=>(Mt.filter(W).forEach((e)=>Zu(e,["--uninstall-extension",Xu],{stdio:"ignore",shell:process.platform==="win32",timeout:60000})),"Removed the Stint extension")},ts={id:"wakatime",name:"WakaTime plugins",kind:"editor",hint:"JetBrains, Neovim, Zed, Xcode, Sublime, Emacs and 50 more, through ~/.wakatime.cfg",detected:()=>ae(m.wakatimeConfig())||ae(He(m.wakatimeConfig(),"..",".wakatime")),installed:()=>nt().includes(Ot(k().apiUrl)),install:()=>{let e=k();if(!e.apiKey)throw Error("Sign in first so Stint has a key to give your WakaTime plugins.");return _t(m.wakatimeConfig()),Pe(m.wakatimeConfig(),zu(nt(),Ot(e.apiUrl),e.apiKey),384),`Pointed ${m.wakatimeConfig()} at Stint (your old file is saved as .wakatime.cfg.stint-backup)`},uninstall:()=>(Pe(m.wakatimeConfig(),Yu(),384),`Restored ${m.wakatimeConfig()}`)},P=[Yr,Qr,Zr,Xr,es,ts]});async function Kt(){let e=P.filter((r)=>r.kind==="agent"),t=P.filter((r)=>r.kind==="editor"),n=await Au({message:"What should Stint track?",options:{"AI agents":e.map((r)=>({value:r.id,label:r.name,hint:r.installed()?"connected":r.detected()?r.hint:"not found on this machine"})),Editors:t.map((r)=>({value:r.id,label:r.name,hint:r.installed()?"connected":r.hint}))},initialValues:P.filter((r)=>r.installed()||r.detected()&&r.kind==="agent").map((r)=>r.id),required:!1});if(X(n))return null;return n.map((r)=>Re(r)).filter((r)=>Boolean(r))}function ct(e){ye();let t=0,n=0;for(let r of e)try{let s=r.install();Tt(r.id,!0),f.success(`${me.default.bold(r.name)} ${me.default.dim(s)}`),t+=1}catch(s){f.error(`${me.default.bold(r.name)} ${s instanceof Error?s.message:String(s)}`),n+=1}return{ok:t,failed:n}}async function lt(e,t){if(e.length===0&&!t){let r=await Kt();if(!r)return ut("Nothing changed.");ct(r);return}let n=e.filter((r)=>!Re(r));if(n.length)throw Error(`Unknown integration: ${n.join(", ")}. Try: ${P.map((r)=>r.id).join(", ")}`);ct(t?P.filter((r)=>r.detected()):e.map((r)=>Re(r)))}function Cn(e){let t=e.length?e.map((n)=>Re(n)).filter((n)=>Boolean(n)):P.filter((n)=>n.installed());if(t.length===0)return f.info("Nothing is connected.");for(let n of t)try{f.success(`${me.default.bold(n.name)} ${me.default.dim(n.uninstall())}`),Tt(n.id,!1)}catch(r){f.error(`${me.default.bold(n.name)} ${r instanceof Error?r.message:String(r)}`)}}var me;var pt=U(()=>{ee();rt();N();K();me=M(G(),1)});ee();var x=M(G(),1);ee();rt();var tn=M(G(),1);import{existsSync as en}from"node:fs";Ee();class re extends Error{status;code;constructor(e,t,n){super(e);this.status=t;this.code=n}}var st="stint-cli",us=1e4;async function ne(e,t,n={}){let r={accept:"application/json","user-agent":n.agent??Ou()},s=n.token??e.apiKey;if(s)r.authorization=`Bearer ${s}`;if(n.body!==void 0)r["content-type"]="application/json";let o;try{o=await fetch(`${e.apiUrl}${t}`,{method:n.method??(n.body===void 0?"GET":"POST"),headers:r,body:n.body===void 0?void 0:JSON.stringify(n.body),signal:AbortSignal.timeout(n.timeoutMs??us)})}catch(D){let c=D instanceof Error&&D.name==="TimeoutError"?"timed out":"couldn't connect";throw new re(`Stint ${c} (${e.apiUrl}).`,0,"network")}let u=await o.text(),i=null;try{i=u?JSON.parse(u):null}catch{}if(!o.ok){let D=i??{},c=typeof D.error==="string"&&/^[a-z_]+$/.test(D.error)?D.error:void 0;throw new re(D.error_description??D.message??D.error??`Stint answered ${o.status}.`,o.status,c)}return i}var A={deviceCode:(e,t=st)=>ne({apiUrl:e.apiUrl},"/api/auth/device/code",{body:{client_id:t,scope:"heartbeats usage"}}),deviceToken:(e,t,n=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:n}}),mintKey:(e,t,n)=>ne({apiUrl:e.apiUrl},"/api/v1/me/api-keys",{token:t,body:{name:n}}),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,n)=>ne(e,"/api/v1/heartbeats",{body:t,agent:n,timeoutMs:8000}),usage:(e,t)=>ne(e,"/api/v1/usage",{body:{samples:t},timeoutMs:15000})};N();R();K();async function un(){let e=k(),t=[],[n]=process.versions.node.split(".").map(Number);t.push({label:`Node ${process.versions.node}`,ok:n>=18,fix:"Install Node 18 or newer from nodejs.org"}),t.push({label:`Hooks run with ${ue()}`,ok:ue()==="node"||en(ue()),fix:"Put node on your PATH so agents can run the Stint hook"}),t.push({label:`Hook script at ${m.bin()}`,ok:en(m.bin()),fix:"Run npx getstint install"});try{await A.me(e),t.push({label:`Reached ${e.apiUrl} and the key works`,ok:!0})}catch(r){t.push({label:`Reaching ${e.apiUrl}`,ok:!1,fix:r instanceof Error?r.message:String(r)})}for(let r of P.filter((s)=>s.installed()))t.push({label:`${r.name} connected`,ok:!0});if(P.find((r)=>r.id==="codex")?.installed())t.push({label:"Codex hooks need one approval",ok:W("codex"),fix:"Open Codex, run /hooks and trust the Stint entries"});for(let r of t)if(r.ok)f.success(r.label);else f.error(`${r.label}${r.fix?tn.default.dim(` ${r.fix}`):""}`);return t.every((r)=>r.ok)}import{readFileSync as fs,statSync as Fs}from"node:fs";var y=(e)=>typeof e==="number"&&Number.isFinite(e)&&e>0?Math.round(e):0,J=(e)=>{if(typeof e==="number"&&Number.isFinite(e))return e>1000000000000?e/1000:e;if(typeof e==="string"){let t=Date.parse(e);return Number.isFinite(t)?t/1000:null}return null};function ot(e){let t=[];for(let n of e.split(`
97
+ `);var Qu=U(()=>{je();R()});import{spawnSync as Zu}from"node:child_process";import{existsSync as ae,rmSync as zr}from"node:fs";import{join as He}from"node:path";function Ht(e){return{id:e.id,name:e.name,kind:"agent",hint:e.hint,detected:e.detected,installed:()=>qu(V(e.file()),e.id),install:()=>{let t=e.file(),r=Fe(t)===null?{}:V(t);if(r===null)throw Error(`${t} isn't valid JSON, so Stint left it alone. Fix it and run the install again.`);return _t(t),ie(t,Gu(r,e.id,e.specs())),[`Added Stint hooks to ${t}`,e.after].filter(Boolean).join(". ")},uninstall:()=>{let t=e.file(),n=V(t);if(!n)return`Nothing to remove in ${t}`;return ie(t,jt(n,e.id)),`Removed Stint hooks from ${t}`}}}var Ut=(e)=>({type:"command",command:Wu(e)}),Yr,Qr,Zr,Ue=()=>He(m.opencodeConfig(),"plugins","stint.js"),Xr,Mt,Xu="getstint.stint",es,ts,P,Re=(e)=>P.find((t)=>t.id===e);var rt=U(()=>{N();je();R();K();Qu();Yr=Ht({id:"claude-code",name:"Claude Code",hint:"hooks in ~/.claude/settings.json",file:m.claudeSettings,detected:()=>ae(He(m.claudeSettings(),".."))||W("claude"),specs:()=>{let e={...Ut("claude-code"),async:!0,timeout:30};return[{event:"SessionStart",handler:e},{event:"UserPromptSubmit",handler:e},{event:"PostToolUse",matcher:"*",handler:e},{event:"Stop",handler:e},{event:"SubagentStop",handler:e},{event:"SessionEnd",handler:e}]}}),Qr=Ht({id:"codex",name:"Codex CLI",hint:"hooks in ~/.codex/hooks.json",file:()=>He(m.codexHome(),"hooks.json"),detected:()=>ae(m.codexHome())||W("codex"),specs:()=>{let e={...Ut("codex"),async:!0,statusMessage:"Stint"};return[{event:"SessionStart",handler:e},{event:"UserPromptSubmit",handler:e},{event:"PostToolUse",matcher:"*",handler:e},{event:"Stop",handler:e}]},after:"Codex asks you to trust new hooks once: run /hooks in Codex and approve the Stint entries"}),Zr=Ht({id:"gemini-cli",name:"Gemini CLI",hint:"hooks in ~/.gemini/settings.json",file:()=>He(m.geminiHome(),"settings.json"),detected:()=>ae(m.geminiHome())||W("gemini"),specs:()=>{let e={...Ut("gemini-cli"),name:"stint",timeout:5000};return[{event:"SessionStart",handler:e},{event:"BeforeAgent",handler:e},{event:"AfterTool",matcher:".*",handler:e},{event:"AfterAgent",handler:e},{event:"SessionEnd",handler:e}]}}),Xr={id:"opencode",name:"OpenCode",kind:"agent",hint:"plugin in ~/.config/opencode/plugins",detected:()=>ae(m.opencodeConfig())||ae(m.opencodeData())||W("opencode"),installed:()=>Fe(Ue())?.includes("STINT_PLUGIN")??!1,install:()=>(Pe(Ue(),Vu(ue(),m.bin())),`Wrote ${Ue()}`),uninstall:()=>(zr(Ue(),{force:!0}),`Removed ${Ue()}`)},Mt=["code","cursor","windsurf","codium","code-insiders"],es={id:"editors",name:"VS Code, Cursor and Windsurf",kind:"editor",hint:"installs the Stint extension",detected:()=>Mt.some(W),installed:()=>!1,install:()=>Mt.filter(W).map((t)=>Zu(t,["--install-extension",Xu,"--force"],{stdio:"ignore",shell:process.platform==="win32",timeout:120000}).status===0?`${t}: installed`:`${t}: couldn't install, get it at https://marketplace.visualstudio.com/items?itemName=getstint.stint`).join(", ")||"No editor command line found",uninstall:()=>(Mt.filter(W).forEach((e)=>Zu(e,["--uninstall-extension",Xu],{stdio:"ignore",shell:process.platform==="win32",timeout:60000})),"Removed the Stint extension")},ts={id:"wakatime",name:"WakaTime plugins",kind:"editor",hint:"JetBrains, Neovim, Zed, Xcode, Sublime, Emacs and 50 more, through ~/.wakatime.cfg",detected:()=>ae(m.wakatimeConfig())||ae(He(m.wakatimeConfig(),"..",".wakatime")),installed:()=>nt().includes(Ot(k().apiUrl)),install:()=>{let e=k();if(!e.apiKey)throw Error("Sign in first so Stint has a key to give your WakaTime plugins.");return _t(m.wakatimeConfig()),Pe(m.wakatimeConfig(),zu(nt(),Ot(e.apiUrl),e.apiKey),384),`Pointed ${m.wakatimeConfig()} at Stint (your old file is saved as .wakatime.cfg.stint-backup)`},uninstall:()=>(Pe(m.wakatimeConfig(),Yu(),384),`Restored ${m.wakatimeConfig()}`)},P=[Yr,Qr,Zr,Xr,es,ts]});async function Kt(){let e=P.filter((r)=>r.kind==="agent"),t=P.filter((r)=>r.kind==="editor"),n=await Au({message:"What should Stint track?",options:{"AI agents":e.map((r)=>({value:r.id,label:r.name,hint:r.installed()?"connected":r.detected()?r.hint:"not found on this machine"})),Editors:t.map((r)=>({value:r.id,label:r.name,hint:r.installed()?"connected":r.hint}))},initialValues:P.filter((r)=>r.installed()||r.detected()&&r.kind==="agent").map((r)=>r.id),required:!1});if(X(n))return null;return n.map((r)=>Re(r)).filter((r)=>Boolean(r))}function ct(e){ye();let t=0,n=0;for(let r of e)try{let s=r.install();Tt(r.id,!0),f.success(`${me.default.bold(r.name)} ${me.default.dim(s)}`),t+=1}catch(s){f.error(`${me.default.bold(r.name)} ${s instanceof Error?s.message:String(s)}`),n+=1}return{ok:t,failed:n}}async function lt(e,t){if(e.length===0&&!t){let r=await Kt();if(!r)return ut("Nothing changed.");ct(r);return}let n=e.filter((r)=>!Re(r));if(n.length)throw Error(`Unknown integration: ${n.join(", ")}. Try: ${P.map((r)=>r.id).join(", ")}`);ct(t?P.filter((r)=>r.detected()):e.map((r)=>Re(r)))}function Cn(e){let t=e.length?e.map((n)=>Re(n)).filter((n)=>Boolean(n)):P.filter((n)=>n.installed());if(t.length===0)return f.info("Nothing is connected.");for(let n of t)try{f.success(`${me.default.bold(n.name)} ${me.default.dim(n.uninstall())}`),Tt(n.id,!1)}catch(r){f.error(`${me.default.bold(n.name)} ${r instanceof Error?r.message:String(r)}`)}}var me;var pt=U(()=>{ee();rt();N();K();me=M(G(),1)});ee();var x=M(G(),1);ee();rt();var tn=M(G(),1);import{existsSync as en}from"node:fs";Ee();class re extends Error{status;code;constructor(e,t,n){super(e);this.status=t;this.code=n}}var st="stint-cli",us=1e4;async function ne(e,t,n={}){let r={accept:"application/json","user-agent":n.agent??Ou()},s=n.token??e.apiKey;if(s)r.authorization=`Bearer ${s}`;if(n.body!==void 0)r["content-type"]="application/json";let o;try{o=await fetch(`${e.apiUrl}${t}`,{method:n.method??(n.body===void 0?"GET":"POST"),headers:r,body:n.body===void 0?void 0:JSON.stringify(n.body),signal:AbortSignal.timeout(n.timeoutMs??us)})}catch(D){let c=D instanceof Error&&D.name==="TimeoutError"?"timed out":"couldn't connect";throw new re(`Stint ${c} (${e.apiUrl}).`,0,"network")}let u=await o.text(),i=null;try{i=u?JSON.parse(u):null}catch{}if(!o.ok){let D=i??{},c=typeof D.error==="string"&&/^[a-z_]+$/.test(D.error)?D.error:void 0;throw new re(D.error_description??D.message??D.error??`Stint answered ${o.status}.`,o.status,c)}return i}var A={deviceCode:(e,t=st)=>ne({apiUrl:e.apiUrl},"/api/auth/device/code",{body:{client_id:t,scope:"heartbeats usage"}}),deviceToken:(e,t,n=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:n}}),mintKey:(e,t,n)=>ne({apiUrl:e.apiUrl},"/api/v1/me/api-keys",{token:t,body:{name:n}}),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,n)=>ne(e,"/api/v1/heartbeats",{body:t,agent:n,timeoutMs:60000}),usage:(e,t)=>ne(e,"/api/v1/usage",{body:{samples:t},timeoutMs:60000})};N();R();K();async function un(){let e=k(),t=[],[n]=process.versions.node.split(".").map(Number);t.push({label:`Node ${process.versions.node}`,ok:n>=18,fix:"Install Node 18 or newer from nodejs.org"}),t.push({label:`Hooks run with ${ue()}`,ok:ue()==="node"||en(ue()),fix:"Put node on your PATH so agents can run the Stint hook"}),t.push({label:`Hook script at ${m.bin()}`,ok:en(m.bin()),fix:"Run npx getstint install"});try{await A.me(e),t.push({label:`Reached ${e.apiUrl} and the key works`,ok:!0})}catch(r){t.push({label:`Reaching ${e.apiUrl}`,ok:!1,fix:r instanceof Error?r.message:String(r)})}for(let r of P.filter((s)=>s.installed()))t.push({label:`${r.name} connected`,ok:!0});if(P.find((r)=>r.id==="codex")?.installed())t.push({label:"Codex hooks need one approval",ok:W("codex"),fix:"Open Codex, run /hooks and trust the Stint entries"});for(let r of t)if(r.ok)f.success(r.label);else f.error(`${r.label}${r.fix?tn.default.dim(` ${r.fix}`):""}`);return t.every((r)=>r.ok)}import{readFileSync as fs,statSync as Fs}from"node:fs";var y=(e)=>typeof e==="number"&&Number.isFinite(e)&&e>0?Math.round(e):0,J=(e)=>{if(typeof e==="number"&&Number.isFinite(e))return e>1000000000000?e/1000:e;if(typeof e==="string"){let t=Date.parse(e);return Number.isFinite(t)?t/1000:null}return null};function ot(e){let t=[];for(let n of e.split(`
98
98
  `)){if(!n.trim())continue;try{t.push(JSON.parse(n))}catch{}}return t}var b=(e)=>e&&typeof e==="object"&&!Array.isArray(e)?e:{},F=(e)=>typeof e==="string"?e:void 0;function z(e,t,n,r,s){return{entity:`${e}:${r}`,type:"app",category:"ai coding",time:t,project:n||void 0,agent:e,ai_session:r,ai_model:s}}var ce="claude-code";function nn(e,t){let n=new Map,r=[],s=new Set;for(let o of ot(e)){let u=b(o);if(u.type!=="assistant")continue;let i=b(u.message),D=b(i.usage),c=F(i.id)??F(u.requestId)??F(u.uuid),l=F(i.model),p=J(u.timestamp);if(!c||!p||!l||l.startsWith("<"))continue;let d=t.projectOf(F(u.cwd)),g=F(u.sessionId)??"claude",h={source_id:`claude:${c}`,time:p,agent:ce,model:l,project:d,input_tokens:y(D.input_tokens),output_tokens:y(D.output_tokens),cache_read_tokens:y(D.cache_read_input_tokens),cache_write_tokens:y(D.cache_creation_input_tokens)},_=n.get(h.source_id);if(!_||h.output_tokens>=_.output_tokens)n.set(h.source_id,_?{...h,time:_.time}:h);let q=`${g}|${Math.floor(p)}`;if(!s.has(q))s.add(q),r.push(z(ce,p,d,g,l))}return{samples:[...n.values()],heartbeats:r,carry:{}}}var Y="codex";function rn(e,t){let n=y(e.cached_input_tokens);return{...t,input_tokens:Math.max(0,y(e.input_tokens)-n),output_tokens:y(e.output_tokens),cache_read_tokens:n,cache_write_tokens:y(e.cache_write_input_tokens)}}function sn(e,t){let n={...t.carry??{}},r=new Map,s=[],o=[],u=[];for(let D of ot(e)){let c=b(D),l=b(c.payload),p=J(c.timestamp);if(c.type==="session_meta"){if(n.session=F(l.id)??n.session??"",n.cwd=F(l.cwd)??n.cwd??"",b(l.source).subagent)n.subagent="1";continue}if(c.type==="turn_context"){let h=F(l.model);if(h){n.model=h;let _=F(l.turn_id);if(_)r.set(_,h)}n.cwd=F(l.cwd)??n.cwd??"";continue}if(!p)continue;let d=t.projectOf(n.cwd||void 0),g=n.session||"codex";if(c.type==="token_usage_record"){let h=F(l.response_id);if(!h)continue;n.records="1";let _=r.get(F(l.turn_id)??"")??n.model??"unknown";s.push(rn(b(l.usage),{source_id:`codex:${h}`,time:p,agent:Y,model:_,project:d})),u.push(z(Y,p,d,g,_));continue}if(c.type==="event_msg"&&l.type==="token_count"){let h=b(l.info),_=b(h.total_token_usage),q=b(h.last_token_usage),se=y(_.total_tokens);if(!se||!Object.keys(q).length||n.lastTotal===String(se))continue;if(n.lastTotal=String(se),o.push(rn(q,{source_id:`codex:${g}:${se}`,time:p,agent:Y,model:n.model??"unknown",project:d})),n.records!=="1")u.push(z(Y,p,d,g,n.model))}}return{samples:(n.records==="1"?s:o).filter((D)=>D.input_tokens+D.output_tokens+D.cache_read_tokens>0),heartbeats:u,carry:n}}var le="gemini-cli";function on(e,t){let n;try{n=b(JSON.parse(e))}catch{return{samples:[],heartbeats:[],carry:{}}}let r=F(n.sessionId)??"gemini",s=t.projectOf(t.cwd),o=[],u=[];for(let i of Array.isArray(n.messages)?n.messages:[]){let D=b(i);if(D.type!=="gemini")continue;let c=F(D.id),l=J(D.timestamp),p=b(D.tokens);if(!c||!l)continue;let d=F(D.model)??"gemini",g=y(p.cached),h={source_id:`gemini:${r}:${c}`,time:l,agent:le,model:d,project:s,input_tokens:Math.max(0,y(p.input)-g),output_tokens:y(p.output)+y(p.thoughts),cache_read_tokens:g,cache_write_tokens:0};if(h.input_tokens+h.output_tokens+h.cache_read_tokens>0)o.push(h);u.push(z(le,l,s,r,d))}return{samples:o,heartbeats:u,carry:{}}}import{existsSync as rs,readFileSync as Dn,statSync as ss}from"node:fs";import{basename as os,dirname as is,isAbsolute as Ds,join as Rt,resolve as Nt}from"node:path";function as(e){let t=Rt(e,".git");try{if(ss(t).isDirectory())return t;let n=/^gitdir:\s*(.+)$/m.exec(Dn(t,"utf8"))?.[1]?.trim();if(!n)return null;return Ds(n)?n:Nt(e,n)}catch{return null}}function cs(e){let t=Nt(e);for(let n=0;n<64;n+=1){if(rs(Rt(t,".git")))return t;let r=is(t);if(r===t)return null;t=r}return null}function ls(e){let t=as(e);if(!t)return;try{let n=Dn(Rt(t,"HEAD"),"utf8").trim();return/^ref:\s*refs\/heads\/(.+)$/.exec(n)?.[1]??void 0}catch{return}}function be(e){if(!e)return null;let t=cs(e)??Nt(e),n=os(t);if(!n)return null;return{root:t,name:n,branch:ls(t)}}import{closeSync as ps,openSync as ms,readSync as ds,statSync as hs}from"node:fs";var gs=33554432;function an(e,t){let n;try{n=hs(e).size}catch{return null}let r=t&&t.offset<=n?t.offset:0,s=t&&t.offset<=n?t.carry:void 0;if(r===n)return{content:"",cursor:{offset:r,size:n,carry:s}};let o=Math.min(n-r,gs),u=Buffer.alloc(o),i=ms(e,"r");try{ds(i,u,0,o,r)}finally{ps(i)}let D=u.lastIndexOf(10);if(D===-1)return{content:"",cursor:{offset:r,size:n,carry:s}};return{content:u.subarray(0,D+1).toString("utf8"),cursor:{offset:r+D+1,size:n,carry:s}}}var Wt=new Map;function $e(e){if(!e)return"";if(!Wt.has(e))Wt.set(e,be(e)?.name??"");return Wt.get(e)}var Ne={samples:[],heartbeats:[],carry:{}};function we(e,t,n,r){if(e===le){let i=0;try{i=Fs(t).size}catch{return Ne}if(n.cursors[t]?.size===i)return Ne;n.cursors[t]={offset:i,size:i};try{return on(fs(t,"utf8"),{projectOf:$e,cwd:r})}catch{return Ne}}let s=e===ce?nn:e===Y?sn:null;if(!s)return Ne;let o=an(t,n.cursors[t]);if(!o||!o.content){if(o)n.cursors[t]=o.cursor;return Ne}let u=s(o.content,{projectOf:$e,carry:o.cursor.carry});return n.cursors[t]={...o.cursor,carry:Object.keys(u.carry).length?u.carry:void 0},u}N();import{isAbsolute as cn,relative as Cs,resolve as Es}from"node:path";var ys=/^(write|edit|multiedit|notebookedit|apply_patch|write_file|replace|edit_file|create_file|str_replace|patch)$/i,bs=new Set(["stop","subagentstop","sessionend","afteragent","session.idle","session.deleted","agent-turn-complete"]),ln=(e)=>bs.has((e??"").toLowerCase());function $s(e){let t=e.tool_input??{},n=e.file_path??t.file_path??t.filePath??t.path??t.notebook_path??t.absolute_path;return typeof n==="string"&&n.length<1000?n:void 0}function it(e,t,n,r){let s=(t.session_id||"session").slice(0,120),o={category:"ai coding",time:n,project:r?.name,branch:r?.branch,agent:e,ai_session:s,ai_model:t.model},u=$s(t);if(u&&r){let i=cn(u)?u:Es(t.cwd??r.root,u),D=Cs(r.root,i);if(D&&!D.startsWith("..")&&!cn(D))return{...o,entity:D.replace(/\\/g,"/"),type:"file",is_write:ys.test(t.tool_name??"")||t.hook_event_name==="file.edited"}}return{...o,entity:`${e}:${s}`,type:"app"}}R();import{appendFileSync as ws,mkdirSync as ks,renameSync as Bs,statSync as xs}from"node:fs";import{dirname as vs}from"node:path";var Ss=1048576;function pn(e){let t=m.log();try{ks(vs(t),{recursive:!0});try{if(xs(t).size>Ss)Bs(t,`${t}.1`)}catch{}ws(t,`${new Date().toISOString()} ${e.replace(/\s+/g," ").slice(0,2000)}
99
99
  `)}catch{}}K();R();import{appendFileSync as mn,existsSync as As,mkdirSync as _s,readFileSync as Gt,readdirSync as Is,renameSync as Ts,rmSync as Lt,statSync as Ps,writeFileSync as Xi}from"node:fs";import{basename as js,dirname as dn,join as Os}from"node:path";var Ms=250000,Us=600000;function Dt(e,t){if(t.length===0)return;_s(dn(e),{recursive:!0}),mn(e,t.map((n)=>JSON.stringify(n)).join(`
100
100
  `)+`
101
101
  `)}function Hs(e){let t=[];for(let n of e.split(`
102
102
  `)){if(!n.trim())continue;try{t.push(JSON.parse(n))}catch{}}return t}function Rs(e){let t=dn(e),n=`${js(e)}.claim-`,r=[];try{r=Is(t).filter((s)=>s.startsWith(n))}catch{return}for(let s of r){let o=Os(t,s);try{if(Date.now()-Ps(o).mtimeMs<Us)continue;mn(e,Gt(o,"utf8")),Lt(o,{force:!0})}catch{}}}function hn(e){if(Rs(e),!As(e))return null;let t=`${e}.claim-${process.pid}-${Date.now()}`;try{Ts(e,t)}catch{return null}return{items:Hs(Gt(t,"utf8")),done:()=>Lt(t,{force:!0}),release:(s)=>{Lt(t,{force:!0}),Dt(e,s.slice(-Ms))}}}function qt(e){try{return Gt(e,"utf8").split(`
103
- `).filter((t)=>t.trim()).length}catch{return 0}}je();R();function Q(){let e=V(m.state())??{};return{cursors:e.cursors&&typeof e.cursors==="object"?e.cursors:{},lastFlush:e.lastFlush,lastSync:e.lastSync,lastError:e.lastError,authFailed:e.authFailed}}function pe(e){let t=Object.entries(e.cursors),n=t.length>2000?Object.fromEntries(t.slice(-2000)):e.cursors;ie(m.state(),{...e,cursors:n})}var Ns=500,Ws=1000,Ls=(e)=>e instanceof re&&(e.status===0||e.status===401||e.status===429||e.status>=500);async function gn(e,t,n){let r=hn(e);if(!r)return{sent:0};let s=0;for(let o=0;o<r.items.length;o+=t){let u=r.items.slice(o,o+t);try{await n(u),s+=u.length}catch(i){if(Ls(i))return r.release(r.items.slice(o)),{sent:s,error:i}}}return r.done(),{sent:s}}function ke(e){Dt(m.queue(),e)}function We(e){Dt(m.usageQueue(),e)}async function at(e,t){let n=Q();if(!e.apiKey)return{sent:0,samples:0,queued:!0,error:"Not signed in. Run `npx getstint login`."};let r=await gn(m.queue(),Ns,(i)=>A.heartbeats(e,i,t)),s=r.error?{sent:0,error:r.error}:await gn(m.usageQueue(),Ws,(i)=>A.usage(e,i)),o=r.error??s.error,u=o instanceof Error?o.message:void 0;return pe({...n,lastFlush:o?n.lastFlush:Date.now(),lastError:u?{at:Date.now(),message:u}:void 0,authFailed:o instanceof re&&o.status===401}),{sent:r.sent,samples:s.sent,queued:Boolean(o),error:u}}var Be="opencode";function Vt(e,t){let n=b(e),r=b(n.time),s=b(n.path),o=b(n.tokens),u=b(o.cache),i=F(n.sessionID)??"opencode",D=t.projectOf(F(s.root)??F(s.cwd)),c=J(r.completed)??J(r.created),l=F(n.id),p=F(n.modelID);if(n.role!=="assistant"||!l||!c||!p)return{sample:null,time:c,session:i,project:D,model:p};let d={source_id:`opencode:${l}`,time:c,agent:Be,model:p,project:D,input_tokens:y(o.input),output_tokens:y(o.output)+y(o.reasoning),cache_read_tokens:y(u.read),cache_write_tokens:y(u.write)};return{sample:d.input_tokens+d.output_tokens+d.cache_read_tokens+d.cache_write_tokens===0||!r.completed?null:d,time:c,session:i,project:D,model:p}}function fn(e,t){let n=[],r=[];for(let s of e){let o;try{o=JSON.parse(s)}catch{continue}let{sample:u,time:i,session:D,project:c,model:l}=Vt(o,t);if(u)n.push(u);if(i&&l)r.push(z(Be,i,c,D,l))}return{samples:n,heartbeats:r,carry:{}}}var Gs=60000,qs=3600000,Vs=4194304;async function Ks(e){if(process.stdin.isTTY)return"";return new Promise((t)=>{let n="",r=()=>t(n),s=setTimeout(r,e);process.stdin.setEncoding("utf8"),process.stdin.on("data",(o)=>{if(n.length<Vs)n+=o}),process.stdin.on("end",()=>{clearTimeout(s),r()}),process.stdin.on("error",()=>{clearTimeout(s),r()})})}async function Fn(e){try{if(!e||!/^[a-z0-9-]{2,40}$/.test(e))return;let t=await Ks(2000),n={};try{n=t.trim()?JSON.parse(t):{}}catch{n={}}let r=k();if(!r.apiKey)return;let s=Date.now()/1000,o=n.cwd??n.workspace_roots?.[0]??process.cwd(),u=be(o);ke([{...it(e,{...n,cwd:o},s,u),machine:r.machine}]);let i=Q(),D=ln(n.hook_event_name);if(e===Be&&n.message){let{sample:l}=Vt(n.message,{projectOf:$e});if(l)We([l])}else if(D&&n.transcript_path){let l=we(e,n.transcript_path,i,o);We(l.samples)}let c=!i.lastSync||Date.now()-i.lastSync>qs;if(c)i.lastSync=Date.now();if(pe(i),c)Me(["sync","--quiet"]);else if(D||!i.lastFlush||Date.now()-i.lastFlush>Gs)Me(["flush","--quiet",`--agent=${e}`])}catch(t){pn(`hook ${e}: ${t instanceof Error?t.stack??t.message:String(t)}`)}}pt();ee();var de=M(G(),1);import{hostname as Xs}from"node:os";N();K();var Le=M(G(),1);import{spawn as Js,spawnSync as zs}from"node:child_process";var Ys=/truecolor|24bit/i.test(process.env.COLORTERM??"")||process.env.TERM_PROGRAM==="vscode"||process.env.WT_SESSION!==void 0,Qs=(e)=>!Le.default.isColorSupported?e:Ys?`\x1B[38;2;255;178;36m${e}\x1B[39m`:Le.default.yellow(e),Zs=()=>Qs("◔"),xe=()=>`${Zs()} ${Le.default.bold("stint")}`;function En(e){let t=Math.round(e/60);if(t<1)return"0m";let n=Math.floor(t/60);return n?`${n}h ${t%60}m`:`${t}m`}function 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 Ge=()=>Boolean(process.stdin.isTTY&&process.stdout.isTTY)&&process.env.CI===void 0;function yn(){if(process.env.STINT_NO_BROWSER||process.env.CI||process.env.SSH_CONNECTION||process.env.SSH_TTY)return!1;if(process.platform==="linux")return Boolean(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)&&!process.env.WSL_DISTRO_NAME;return!0}function Jt(e,t){try{let n=Js(e,t,{stdio:"ignore",detached:!0,windowsHide:!0});return n.on("error",()=>{return}),n.unref(),!0}catch{return!1}}function zt(e){if(!/^https?:\/\//.test(e))return!1;if(process.platform==="win32")return Jt("rundll32",["url.dll,FileProtocolHandler",e]);if(process.platform==="darwin")return Jt("open",[e]);return Jt("xdg-open",[e])}function bn(e){let t=process.platform==="win32"?[["clip",[]]]:process.platform==="darwin"?[["pbcopy",[]]]:[["wl-copy",[]],["xclip",["-selection","clipboard"]],["xsel",["--clipboard","--input"]]];for(let[n,r]of t)try{if(zs(n,r,{input:e,stdio:["pipe","ignore","ignore"],windowsHide:!0,timeout:2000}).status===0)return!0}catch{}return!1}function Se(e,t=e){if(!process.stdout.isTTY||process.env.TERM==="dumb")return e;return`\x1B]8;;${e}\x07${Le.default.underline(t)}\x1B]8;;\x07`}var eo=(e)=>new Promise((t)=>setTimeout(t,e));function to(e,t){let n=new URL("/device",e.apiUrl);return n.searchParams.set("user_code",t),n.searchParams.set("client",st),n.toString()}var uo=(e)=>e.length===8?`${e.slice(0,4)}-${e.slice(4)}`:e;async function $n(e,t){let n=await A.me({...e,apiKey:t});return ye(),De({apiUrl:e.apiUrl,apiKey:t,username:n.username,email:n.email})}async function no(e,t,n,r,s){let o=Math.max(n,2)*1000,u=Date.now()+r*1000;while(Date.now()<u){await eo(o);try{let{access_token:i}=await A.deviceToken(e,t);return i}catch(i){if(!(i instanceof re))throw i;if(i.code==="authorization_pending"||i.status===0)continue;if(i.code==="slow_down"){o+=5000;continue}if(i.code==="access_denied")throw Error("Sign-in was denied in the browser.");if(i.code==="expired_token")throw Error("The code expired. Run the command again for a new one.");throw i}}throw s.stop("Timed out"),Error("The code expired before it was approved. Run the command again for a new one.")}async function mt(e={}){let t=k(),n={...t,apiUrl:e.apiUrl?It(e.apiUrl):t.apiUrl};if(e.key){let l=Te();l.start("Checking your key");try{let p=await $n(n,e.key.trim());return l.stop(`Signed in as ${de.default.bold(p.username??"you")}`),p}catch(p){throw l.stop("That key didn’t work",1),p}}let r=await A.deviceCode(n),s=to(n,r.user_code),o=uo(r.user_code),u=e.browser!==!1&&yn(),i=Ge()&&bn(s);if(tt([`${de.default.dim("Your code")} ${de.default.bold(de.default.white(o))}`,"",u?"Approve this sign-in in the browser window that just opened.":"Open this link on any device and approve the sign-in:",Se(s),i?de.default.dim("The link is on your clipboard."):""].filter((l,p,d)=>l!==""||p>0&&d[p-1]!=="").join(`
103
+ `).filter((t)=>t.trim()).length}catch{return 0}}je();R();function Q(){let e=V(m.state())??{};return{cursors:e.cursors&&typeof e.cursors==="object"?e.cursors:{},lastFlush:e.lastFlush,lastSync:e.lastSync,lastError:e.lastError,authFailed:e.authFailed}}function pe(e){let t=Object.entries(e.cursors),n=t.length>2000?Object.fromEntries(t.slice(-2000)):e.cursors;ie(m.state(),{...e,cursors:n})}var Ns=200,Ws=500,Ls=(e)=>e instanceof re&&(e.status===0||e.status===401||e.status===429||e.status>=500);async function gn(e,t,n){let r=hn(e);if(!r)return{sent:0};let s=0;for(let o=0;o<r.items.length;o+=t){let u=r.items.slice(o,o+t);try{await n(u),s+=u.length}catch(i){if(Ls(i))return r.release(r.items.slice(o)),{sent:s,error:i}}}return r.done(),{sent:s}}function ke(e){Dt(m.queue(),e)}function We(e){Dt(m.usageQueue(),e)}async function at(e,t){let n=Q();if(!e.apiKey)return{sent:0,samples:0,queued:!0,error:"Not signed in. Run `npx getstint login`."};let r=await gn(m.queue(),Ns,(i)=>A.heartbeats(e,i,t)),s=r.error?{sent:0,error:r.error}:await gn(m.usageQueue(),Ws,(i)=>A.usage(e,i)),o=r.error??s.error,u=o instanceof Error?o.message:void 0;return pe({...n,lastFlush:o?n.lastFlush:Date.now(),lastError:u?{at:Date.now(),message:u}:void 0,authFailed:o instanceof re&&o.status===401}),{sent:r.sent,samples:s.sent,queued:Boolean(o),error:u}}var Be="opencode";function Vt(e,t){let n=b(e),r=b(n.time),s=b(n.path),o=b(n.tokens),u=b(o.cache),i=F(n.sessionID)??"opencode",D=t.projectOf(F(s.root)??F(s.cwd)),c=J(r.completed)??J(r.created),l=F(n.id),p=F(n.modelID);if(n.role!=="assistant"||!l||!c||!p)return{sample:null,time:c,session:i,project:D,model:p};let d={source_id:`opencode:${l}`,time:c,agent:Be,model:p,project:D,input_tokens:y(o.input),output_tokens:y(o.output)+y(o.reasoning),cache_read_tokens:y(u.read),cache_write_tokens:y(u.write)};return{sample:d.input_tokens+d.output_tokens+d.cache_read_tokens+d.cache_write_tokens===0||!r.completed?null:d,time:c,session:i,project:D,model:p}}function fn(e,t){let n=[],r=[];for(let s of e){let o;try{o=JSON.parse(s)}catch{continue}let{sample:u,time:i,session:D,project:c,model:l}=Vt(o,t);if(u)n.push(u);if(i&&l)r.push(z(Be,i,c,D,l))}return{samples:n,heartbeats:r,carry:{}}}var Gs=60000,qs=3600000,Vs=4194304;async function Ks(e){if(process.stdin.isTTY)return"";return new Promise((t)=>{let n="",r=()=>t(n),s=setTimeout(r,e);process.stdin.setEncoding("utf8"),process.stdin.on("data",(o)=>{if(n.length<Vs)n+=o}),process.stdin.on("end",()=>{clearTimeout(s),r()}),process.stdin.on("error",()=>{clearTimeout(s),r()})})}async function Fn(e){try{if(!e||!/^[a-z0-9-]{2,40}$/.test(e))return;let t=await Ks(2000),n={};try{n=t.trim()?JSON.parse(t):{}}catch{n={}}let r=k();if(!r.apiKey)return;let s=Date.now()/1000,o=n.cwd??n.workspace_roots?.[0]??process.cwd(),u=be(o);ke([{...it(e,{...n,cwd:o},s,u),machine:r.machine}]);let i=Q(),D=ln(n.hook_event_name);if(e===Be&&n.message){let{sample:l}=Vt(n.message,{projectOf:$e});if(l)We([l])}else if(D&&n.transcript_path){let l=we(e,n.transcript_path,i,o);We(l.samples)}let c=!i.lastSync||Date.now()-i.lastSync>qs;if(c)i.lastSync=Date.now();if(pe(i),c)Me(["sync","--quiet"]);else if(D||!i.lastFlush||Date.now()-i.lastFlush>Gs)Me(["flush","--quiet",`--agent=${e}`])}catch(t){pn(`hook ${e}: ${t instanceof Error?t.stack??t.message:String(t)}`)}}pt();ee();var de=M(G(),1);import{hostname as Xs}from"node:os";N();K();var Le=M(G(),1);import{spawn as Js,spawnSync as zs}from"node:child_process";var Ys=/truecolor|24bit/i.test(process.env.COLORTERM??"")||process.env.TERM_PROGRAM==="vscode"||process.env.WT_SESSION!==void 0,Qs=(e)=>!Le.default.isColorSupported?e:Ys?`\x1B[38;2;255;178;36m${e}\x1B[39m`:Le.default.yellow(e),Zs=()=>Qs("◔"),xe=()=>`${Zs()} ${Le.default.bold("stint")}`;function En(e){let t=Math.round(e/60);if(t<1)return"0m";let n=Math.floor(t/60);return n?`${n}h ${t%60}m`:`${t}m`}function 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 Ge=()=>Boolean(process.stdin.isTTY&&process.stdout.isTTY)&&process.env.CI===void 0;function yn(){if(process.env.STINT_NO_BROWSER||process.env.CI||process.env.SSH_CONNECTION||process.env.SSH_TTY)return!1;if(process.platform==="linux")return Boolean(process.env.DISPLAY||process.env.WAYLAND_DISPLAY)&&!process.env.WSL_DISTRO_NAME;return!0}function Jt(e,t){try{let n=Js(e,t,{stdio:"ignore",detached:!0,windowsHide:!0});return n.on("error",()=>{return}),n.unref(),!0}catch{return!1}}function zt(e){if(!/^https?:\/\//.test(e))return!1;if(process.platform==="win32")return Jt("rundll32",["url.dll,FileProtocolHandler",e]);if(process.platform==="darwin")return Jt("open",[e]);return Jt("xdg-open",[e])}function bn(e){let t=process.platform==="win32"?[["clip",[]]]:process.platform==="darwin"?[["pbcopy",[]]]:[["wl-copy",[]],["xclip",["-selection","clipboard"]],["xsel",["--clipboard","--input"]]];for(let[n,r]of t)try{if(zs(n,r,{input:e,stdio:["pipe","ignore","ignore"],windowsHide:!0,timeout:2000}).status===0)return!0}catch{}return!1}function Se(e,t=e){if(!process.stdout.isTTY||process.env.TERM==="dumb")return e;return`\x1B]8;;${e}\x07${Le.default.underline(t)}\x1B]8;;\x07`}var eo=(e)=>new Promise((t)=>setTimeout(t,e));function to(e,t){let n=new URL("/device",e.apiUrl);return n.searchParams.set("user_code",t),n.searchParams.set("client",st),n.toString()}var uo=(e)=>e.length===8?`${e.slice(0,4)}-${e.slice(4)}`:e;async function $n(e,t){let n=await A.me({...e,apiKey:t});return ye(),De({apiUrl:e.apiUrl,apiKey:t,username:n.username,email:n.email})}async function no(e,t,n,r,s){let o=Math.max(n,2)*1000,u=Date.now()+r*1000;while(Date.now()<u){await eo(o);try{let{access_token:i}=await A.deviceToken(e,t);return i}catch(i){if(!(i instanceof re))throw i;if(i.code==="authorization_pending"||i.status===0)continue;if(i.code==="slow_down"){o+=5000;continue}if(i.code==="access_denied")throw Error("Sign-in was denied in the browser.");if(i.code==="expired_token")throw Error("The code expired. Run the command again for a new one.");throw i}}throw s.stop("Timed out"),Error("The code expired before it was approved. Run the command again for a new one.")}async function mt(e={}){let t=k(),n={...t,apiUrl:e.apiUrl?It(e.apiUrl):t.apiUrl};if(e.key){let l=Te();l.start("Checking your key");try{let p=await $n(n,e.key.trim());return l.stop(`Signed in as ${de.default.bold(p.username??"you")}`),p}catch(p){throw l.stop("That key didn’t work",1),p}}let r=await A.deviceCode(n),s=to(n,r.user_code),o=uo(r.user_code),u=e.browser!==!1&&yn(),i=Ge()&&bn(s);if(tt([`${de.default.dim("Your code")} ${de.default.bold(de.default.white(o))}`,"",u?"Approve this sign-in in the browser window that just opened.":"Open this link on any device and approve the sign-in:",Se(s),i?de.default.dim("The link is on your clipboard."):""].filter((l,p,d)=>l!==""||p>0&&d[p-1]!=="").join(`
104
104
  `),"Connect this machine"),u)if(Ge()){let l=await et({message:"Open the browser now?",initialValue:!0});if(X(l))throw Error("Cancelled.");if(l)zt(s)}else zt(s);let D=Te();D.start("Waiting for you to approve in the browser");let c=await no(n,r.device_code,r.interval,r.expires_in,D);D.message("Creating a key for this machine");try{let{key:l}=await A.mintKey(n,c,`${Xs()} · CLI`.slice(0,60)),p=await $n(n,l);return D.stop(`Signed in as ${de.default.bold(p.username??"you")}`),p}finally{await A.signOutSession(n,c)}}N();import{spawn as ro}from"node:child_process";K();var so=60000,oo={grok:"grok-cli",copilot:"copilot-cli",amp:"amp",qwen:"qwen-code",kiro:"kiro",cline:"cline"};async function wn(e){let t=e.indexOf("--"),[n,...r]=t===-1?e:[e[0],...e.slice(t+1)];if(!n)throw Error("Usage: stint run <agent> [-- command args] e.g. stint run grok");let s=oo[n]??n,o=t===-1?[n,...r]:r,u=k(),i=`${s}-${Date.now().toString(36)}`,D=be(process.cwd()),c=()=>{if(!u.apiKey)return;ke([{...it(s,{session_id:i,cwd:process.cwd()},Date.now()/1000,D),machine:u.machine}]),Me(["flush","--quiet",`--agent=${s}`])};c();let l=setInterval(c,so),p=ro(o[0],o.slice(1),{stdio:"inherit",shell:process.platform==="win32"}),d=await new Promise((g)=>{p.on("exit",(h)=>g(h??0)),p.on("error",()=>g(127))});return clearInterval(l),c(),d}ee();var Qt=M(G(),1);N();Ee();pt();ee();var Yt=M(G(),1);import{readdirSync as io,readFileSync as Do,statSync as Bn}from"node:fs";import{join as qe}from"node:path";N();R();var kn=395;function Ve(e,t,n,r=0,s=[]){if(r>6)return s;let o;try{o=io(e,{withFileTypes:!0})}catch{return s}for(let u of o){let i=qe(e,u.name);if(u.isDirectory())Ve(i,t,n,r+1,s);else if(t(u.name))try{if(Bn(i).mtimeMs>=n)s.push(i)}catch{}}return s}function ao(e=kn){let t=Date.now()-Math.min(e,kn)*86400000,n=Q(),r=[],s=[],o=[],u=(D,c,l)=>{let p=l.samples.filter((g)=>g.time*1000>=t);r.push(...p),s.push(...l.heartbeats.filter((g)=>g.time*1000>=t));let d=o.find((g)=>g.agent===D)??o[o.push({agent:D,files:0,samples:0,tokens:0})-1];d.files+=c,d.samples+=p.length,d.tokens+=p.reduce((g,h)=>g+h.input_tokens+h.output_tokens+h.cache_read_tokens+h.cache_write_tokens,0)};for(let D of Ve(m.claudeProjects(),(c)=>c.endsWith(".jsonl"),t))u(ce,1,we(ce,D,n));for(let D of[qe(m.codexHome(),"sessions"),qe(m.codexHome(),"archived_sessions")])for(let c of Ve(D,(l)=>l.endsWith(".jsonl"),t))u(Y,1,we(Y,c,n));for(let D of Ve(qe(m.geminiHome(),"tmp"),(c)=>c.endsWith(".json")&&c.startsWith("session-"),t))u(le,1,we(le,D,n));let i=Ve(qe(m.opencodeData(),"storage","message"),(D)=>D.endsWith(".json"),t).filter((D)=>{try{let c=Bn(D).mtimeMs;if(n.cursors[D]?.size===c)return!1;return n.cursors[D]={offset:0,size:c},!0}catch{return!1}});if(i.length){let D=i.map((c)=>{try{return Do(c,"utf8")}catch{return""}});u(Be,i.length,fn(D,{projectOf:$e}))}return pe(n),{samples:r,heartbeats:s,totals:o}}async function dt(e={}){let t=k();if(!t.apiKey)throw Error("Sign in first: npx getstint login");let n=e.quiet?null:Te();n?.start("Reading your agent history");let{samples:r,heartbeats:s,totals:o}=ao(e.days);pe({...Q(),lastSync:Date.now()}),We(r),ke(s.map((i)=>({...i,machine:t.machine}))),n?.message(`Sending ${ve(r.length)} usage records`);let u=await at(t);if(!n)return u;n.stop(u.error?`Saved for later: ${u.error}`:`Synced ${ve(u.samples)} usage records and ${ve(u.sent)} activity events`);for(let i of o.filter((D)=>D.samples>0))f.info(`${Yt.default.bold(i.agent)} ${Yt.default.dim(`${i.files} files · ${ve(i.samples)} records · ${ve(i.tokens)} tokens`)}`);return u}async function xn(e){_e(`${xe()} ${Qt.default.dim(`v${O}`)}`);let t=k(),n=!1;if(t.apiKey&&!e.key&&!e.apiUrl)try{let r=await A.me(t);f.success(`Signed in as ${Qt.default.bold(r.username)}`),n=!0}catch{f.warn("Your saved key no longer works, so let’s sign in again.")}if(!n)t=await mt(e);if(!Ge()||e.yes){await Promise.resolve().then(() => pt());await lt([],!0)}else{let r=await Kt();if(r===null){ut("Signed in. Connect tools any time with `npx getstint install`.");return}if(r.length)ct(r);let s=await et({message:"Import token usage from your past agent sessions?",initialValue:!0});if(!X(s)&&s)await dt()}Ie(`You’re set. Your dashboard: ${Se(`${t.apiUrl}/dashboard`)}`)}ee();rt();var B=M(G(),1);N();R();K();Ee();async function vn(){let e=k(),t=Q(),n=[];if(!e.apiKey)n.push(`${B.default.yellow("●")} Not signed in. Run ${B.default.bold("npx getstint login")}.`);else try{let[s,o]=await Promise.all([A.me(e),A.today(e).catch(()=>null)]);if(s.username!==e.username)De({username:s.username,email:s.email});if(n.push(`${B.default.green("●")} Signed in as ${B.default.bold(s.username)} ${B.default.dim(s.email)}`),o)n.push(`${B.default.dim("Today")} ${B.default.bold(En(o.data.grand_total.total_seconds))}`)}catch(s){n.push(`${B.default.red("●")} ${s instanceof Error?s.message:String(s)}`)}n.push("");for(let s of P){let o=s.installed()?B.default.green("✓"):s.detected()?B.default.yellow("○"):B.default.dim("·");n.push(`${o} ${s.name}${s.installed()?"":B.default.dim(s.detected()?" found, not connected":" not found")}`)}n.push("");let r=qt(m.queue())+qt(m.usageQueue());if(n.push(`${B.default.dim("Server")} ${e.apiUrl}`),n.push(`${B.default.dim("Version")} ${O}${Oe()&&Oe()!==O?B.default.dim(` (hooks use ${Oe()})`):""}`),n.push(`${B.default.dim("Waiting")} ${r?`${r} events will send when Stint is reachable`:"nothing queued"}`),t.lastFlush)n.push(`${B.default.dim("Last sent")} ${new Date(t.lastFlush).toLocaleString()}`);if(t.lastError)n.push(`${B.default.dim("Last error")} ${B.default.red(t.lastError.message)}`);if(tt(n.join(`
105
105
  `),"Stint"),e.apiKey)f.message(`Dashboard: ${Se(`${e.apiUrl}/dashboard`)}`)}function Sn(e){let t=[],n={},r;for(let s=0;s<e.length;s+=1){let o=e[s];if(o==="--"){t.push(...e.slice(s));break}if(o.startsWith("--")){let[u,i]=o.slice(2).split(/=(.*)/s,2);if(u.startsWith("no-"))n[u.slice(3)]=!1;else if(i!==void 0)n[u]=i;else if(["key","api-url","days","agent"].includes(u)&&e[s+1]&&!e[s+1].startsWith("-"))n[u]=e[++s];else n[u]=!0;continue}if(o==="-h")n.help=!0;else if(o==="-v")n.version=!0;else if(o==="-y")n.yes=!0;else if(r===void 0)r=o;else t.push(o)}return{command:r,positionals:t,flags:n}}N();K();Ee();var An=`${xe()} ${x.default.dim(`v${O}`)} Coding time and AI agent tracking for getstint.dev
106
106
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getstint",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Track your coding time and AI agents with Stint: one command connects Claude Code, Codex, Gemini CLI, OpenCode and your editors.",
5
5
  "keywords": [
6
6
  "stint",