hacklab 0.12.1 → 0.12.3

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 (59) hide show
  1. package/README.md +28 -74
  2. package/dist/belt.d.ts +1 -1
  3. package/dist/belt.d.ts.map +1 -1
  4. package/dist/belt.js +2 -2
  5. package/dist/belt.js.map +1 -1
  6. package/dist/cli.js +5 -7
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/daemon.d.ts +1 -1
  9. package/dist/commands/daemon.js +2 -2
  10. package/dist/commands/daemon.js.map +1 -1
  11. package/dist/commands/login.d.ts +3 -16
  12. package/dist/commands/login.d.ts.map +1 -1
  13. package/dist/commands/login.js +78 -157
  14. package/dist/commands/login.js.map +1 -1
  15. package/dist/commands/referral.js +2 -2
  16. package/dist/commands/referral.js.map +1 -1
  17. package/dist/commands/scan.d.ts +7 -0
  18. package/dist/commands/scan.d.ts.map +1 -0
  19. package/dist/commands/scan.js +175 -0
  20. package/dist/commands/scan.js.map +1 -0
  21. package/dist/commands/sync.js +1 -1
  22. package/dist/commands/sync.js.map +1 -1
  23. package/dist/commands/whoami.d.ts.map +1 -1
  24. package/dist/commands/whoami.js +9 -11
  25. package/dist/commands/whoami.js.map +1 -1
  26. package/dist/daily-sync.js +1 -1
  27. package/dist/daily-sync.js.map +1 -1
  28. package/dist/posthog.js +1 -1
  29. package/dist/posthog.js.map +1 -1
  30. package/dist/referral.js +2 -2
  31. package/dist/referral.js.map +1 -1
  32. package/dist/registry.d.ts.map +1 -1
  33. package/dist/registry.js +6 -11
  34. package/dist/registry.js.map +1 -1
  35. package/dist/scanners/index.d.ts +3 -3
  36. package/dist/scanners/index.js +3 -3
  37. package/dist/session.d.ts +4 -4
  38. package/dist/share.d.ts.map +1 -1
  39. package/dist/share.js +4 -4
  40. package/dist/share.js.map +1 -1
  41. package/dist/sync.d.ts +5 -6
  42. package/dist/sync.d.ts.map +1 -1
  43. package/dist/sync.js +7 -13
  44. package/dist/sync.js.map +1 -1
  45. package/dist/ui.d.ts +2 -0
  46. package/dist/ui.d.ts.map +1 -1
  47. package/dist/ui.js +4 -0
  48. package/dist/ui.js.map +1 -1
  49. package/dist/utils/openBrowser.d.ts +1 -1
  50. package/dist/utils/openBrowser.js +1 -1
  51. package/dist/utils/waitForEnter.d.ts +2 -8
  52. package/dist/utils/waitForEnter.d.ts.map +1 -1
  53. package/dist/utils/waitForEnter.js +2 -11
  54. package/dist/utils/waitForEnter.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/commands/join.d.ts +0 -15
  57. package/dist/commands/join.d.ts.map +0 -1
  58. package/dist/commands/join.js +0 -479
  59. package/dist/commands/join.js.map +0 -1
@@ -1,72 +1,54 @@
1
- import { createServer } from 'node:http';
2
- import * as clack from '@clack/prompts';
3
1
  import { clearSyncPaused } from '../daily-sync.js';
4
2
  import { captureEvent, identifyUser } from '../posthog.js';
5
3
  import { getAppUrl, saveSession } from '../session.js';
6
- import { bold, dim, info, linkBlue, success, white } from '../ui.js';
4
+ import { bold, dim, link } from '../ui.js';
7
5
  import { openBrowser } from '../utils/openBrowser.js';
8
6
  import { waitForEnter } from '../utils/waitForEnter.js';
9
7
  /**
10
- * Authenticate and save a session. Two paths to the same result:
11
- * - device-code flow (the default): GitHub's device flow — authorize on
12
- * github.com/login/device (signed into GitHub, not Hacklab), and the backend
13
- * maps your GitHub identity to the linked Hacklab account. No local server,
14
- * no port forwarding, no localhost/app URL. Works the same everywhere.
15
- * - localhost-callback flow (only with `--browser`): opens the browser and
16
- * catches the OAuth redirect on a local server.
17
- *
18
- * `allowSignup` (set by `join`) lets the device flow *create* an account when
19
- * the GitHub identity has none yet; `login` leaves it off, so an unknown GitHub
20
- * is told to run `join`. The callback flow always creates-or-logs-in via real
21
- * OAuth, so it's signup-capable regardless.
8
+ * Authenticate via GitHub's device flow. Unknown GitHub identities get an
9
+ * account. An unclaimed GitHub-derived handle is claimed as-is.
22
10
  */
23
- export async function login(opts = {}) {
24
- clack.intro('hacklab login');
11
+ export async function login() {
25
12
  const appUrl = getAppUrl();
26
- let creds = null;
27
- if (!opts.browser) {
28
- // Device flow is the default. null = this backend has no device routes yet
29
- // (e.g. not deployed) — the only case we fall back to the browser flow,
30
- // since there's no device flow to use there.
31
- creds = await loginViaDevice(appUrl, opts.allowSignup ?? false);
32
- if (!creds) {
33
- info(dim('device login unavailable on this server — using browser sign-in.'));
34
- }
13
+ const creds = await loginViaDevice(appUrl);
14
+ let handle = creds.handle;
15
+ let usernameClaimed = creds.usernameClaimed;
16
+ if (!handle) {
17
+ const me = await fetchMe(appUrl, creds.token);
18
+ handle = me?.handle ?? me?.githubUsername ?? undefined;
19
+ if (me?.claimed != null)
20
+ usernameClaimed = me.claimed;
35
21
  }
36
- if (!creds) {
37
- creds = await loginViaCallback(appUrl);
22
+ if (handle && !usernameClaimed) {
23
+ const claimed = await claimHandle(appUrl, creds.token, handle);
24
+ if (claimed) {
25
+ handle = claimed;
26
+ usernameClaimed = true;
27
+ }
38
28
  }
39
29
  await saveSession({
40
30
  token: creds.token,
41
31
  email: creds.email,
42
- handle: creds.handle,
43
- usernameClaimed: creds.usernameClaimed,
32
+ handle,
33
+ usernameClaimed,
44
34
  appUrl,
45
35
  savedAt: new Date().toISOString(),
46
36
  expiresAt: creds.expiresAt,
47
37
  });
48
- // The session is fresh again — drop any "background sync paused" marker so a
49
- // stale notice doesn't fire after the user just fixed it.
50
38
  await clearSyncPaused();
51
- const label = creds.handle ? `${creds.email} (${creds.handle})` : creds.email;
52
- success(`logged in as ${label}`);
53
- clack.outro(dim('hack the planet.'));
54
- if (creds.handle) {
55
- await identifyUser(creds.handle, {
56
- $set: { email: creds.email, handle: creds.handle, app_url: appUrl },
39
+ console.log('');
40
+ console.log(handle ? `signed in as @${handle}` : `signed in as ${creds.email}`);
41
+ if (handle) {
42
+ await identifyUser(handle, {
43
+ $set: { email: creds.email, handle, app_url: appUrl },
57
44
  });
58
- await captureEvent(creds.handle, 'cli_login_completed', {
59
- login_method: opts.browser ? 'browser_callback' : 'device_flow',
60
- username_claimed: creds.usernameClaimed ?? false,
45
+ await captureEvent(handle, 'cli_login_completed', {
46
+ login_method: 'device_flow',
47
+ username_claimed: usernameClaimed ?? false,
61
48
  });
62
49
  }
63
50
  }
64
- /**
65
- * Device-code flow. Returns the credentials on approval, or null if the backend
66
- * doesn't support it (so the caller can fall back). Throws on an explicit
67
- * denial, expiry, or timeout.
68
- */
69
- async function loginViaDevice(appUrl, allowSignup) {
51
+ async function loginViaDevice(appUrl) {
70
52
  let startRes;
71
53
  try {
72
54
  startRes = await fetch(`${appUrl}/api/cli/device/start`, {
@@ -75,164 +57,103 @@ async function loginViaDevice(appUrl, allowSignup) {
75
57
  });
76
58
  }
77
59
  catch {
78
- // Connection refused / DNS / timeout — the server isn't reachable. Name the
79
- // URL so the cause (e.g. local dev app not running) is obvious.
80
60
  throw new Error(`could not reach ${appUrl} — is the server running?`);
81
61
  }
82
- // Older backend without the device routes — let login fall back to callback.
83
- if (startRes.status === 404)
84
- return null;
62
+ if (startRes.status === 404) {
63
+ throw new Error(`device login is not available on ${appUrl}`);
64
+ }
85
65
  if (!startRes.ok) {
86
66
  throw new Error(`could not start device login (${startRes.status})`);
87
67
  }
88
68
  const start = (await startRes.json());
89
- // GitHub's device flow: the user authorizes on github.com, signed into GitHub
90
- // (not Hacklab). We map the resulting GitHub identity to their linked account.
91
- //
92
- // Order matters here. Show the CODE first and hold the browser until the user
93
- // presses Enter — they need to have read the code *before* a new window steals
94
- // their attention. Opening immediately meant the code scrolled past unread and
95
- // people came back to a GitHub prompt with nothing to type.
96
- // `format` overrides clack's default dim styling: body text white, code bold.
97
- clack.note(` ${bold(start.userCode)}`, 'your github device code', {
98
- format: (line) => white(line),
99
- });
100
- await waitForEnter(` ${white('press Enter to open')} ${linkBlue(start.verificationUri)} ${white('in your browser')} `);
69
+ // Code first, then Enter, then the browser — they have to have read the
70
+ // code before a new window steals focus. The URL is printed in full so it
71
+ // is copyable if Enter doesn't open a browser; OSC-8 makes it clickable.
72
+ console.log(dim('copy code'));
73
+ console.log('');
74
+ console.log(bold(start.userCode));
75
+ console.log('');
76
+ console.log(link(start.verificationUri));
77
+ await waitForEnter('(press enter) ');
101
78
  void openBrowser(start.verificationUriComplete ?? start.verificationUri);
102
- info(dim(`if your browser didn't open, go to ${start.verificationUri} and enter the code above.`));
103
79
  const intervalMs = Math.max(1000, (Number(start.interval) || 5) * 1000);
104
80
  const deadline = Date.now() + (Number(start.expiresIn) || 900) * 1000;
105
- const spin = clack.spinner();
106
- spin.start('waiting for you to authorize on GitHub');
107
81
  while (Date.now() < deadline) {
108
82
  let data = null;
109
83
  try {
110
84
  const res = await fetch(`${appUrl}/api/cli/device/poll`, {
111
85
  method: 'POST',
112
86
  headers: { 'Content-Type': 'application/json' },
113
- body: JSON.stringify({ deviceCode: start.deviceCode, allowSignup }),
87
+ body: JSON.stringify({
88
+ deviceCode: start.deviceCode,
89
+ allowSignup: true,
90
+ }),
114
91
  signal: AbortSignal.timeout(10_000),
115
92
  });
116
- // Back off naturally on a rate-limit; otherwise read the status.
117
93
  if (res.status !== 429)
118
94
  data = await res.json().catch(() => null);
119
95
  }
120
96
  catch {
121
- // Transient network error — keep polling until the deadline.
97
+ // keep polling
122
98
  }
123
99
  const status = data?.status;
124
100
  if (status === 'approved' && data?.token && data.email) {
125
- spin.stop('approved');
126
101
  return {
127
102
  token: data.token,
128
103
  email: data.email,
129
- handle: data.handle,
104
+ handle: data.handle ?? data.login,
130
105
  usernameClaimed: data.usernameClaimed,
131
106
  expiresAt: data.expiresAt,
132
107
  };
133
108
  }
134
109
  if (status === 'denied') {
135
- spin.stop('denied');
136
110
  throw new Error('authorization was denied on GitHub.');
137
111
  }
138
112
  if (status === 'expired') {
139
- spin.stop('code expired');
140
113
  throw new Error('the code expired — run `hacklab login` again.');
141
114
  }
142
115
  if (status === 'no_account') {
143
- spin.stop('no linked account');
144
116
  const who = typeof data?.login === 'string' ? ` (@${data.login})` : '';
145
- throw new Error(`no hacklab account is linked to that GitHub${who}. run \`hacklab join\` to register.`);
117
+ throw new Error(`no hacklab account is linked to that GitHub${who}. run \`hacklab login\` again.`);
146
118
  }
147
119
  await sleep(intervalMs);
148
120
  }
149
- spin.stop('timed out');
150
121
  throw new Error('login timed out — run `hacklab login` again.');
151
122
  }
152
- /** Localhost-callback flow: open the browser, catch the OAuth redirect locally. */
153
- async function loginViaCallback(appUrl) {
154
- return await new Promise((resolve, reject) => {
155
- let timeout;
156
- const server = createServer((req, res) => {
157
- const url = new URL(req.url ?? '/', `http://localhost`);
158
- const token = url.searchParams.get('token');
159
- const email = url.searchParams.get('email');
160
- const handle = url.searchParams.get('handle');
161
- const usernameClaimed = url.searchParams.get('usernameClaimed') === '1';
162
- const expiresAt = normalizeDateParam(url.searchParams.get('expiresAt'));
163
- if (!token || !email) {
164
- res.writeHead(400, { 'Content-Type': 'text/html' });
165
- res.end('<h1>login failed</h1><p>missing token. try again.</p>');
166
- return;
167
- }
168
- res.writeHead(200, { 'Content-Type': 'text/html' });
169
- res.end('<h1>logged in!</h1><p>you can close this tab and go back to your terminal.</p>');
170
- stopServer();
171
- resolve({
172
- token,
173
- email,
174
- handle: handle ?? undefined,
175
- usernameClaimed,
176
- expiresAt,
177
- });
178
- });
179
- // Bind 0 = a random free port. On a headless host you can't open the
180
- // browser locally, so the user opens the URL elsewhere and the OAuth
181
- // redirect must reach this callback server — which means forwarding the
182
- // port (e.g. `ssh -L`). Pin it with HACKLAB_CALLBACK_PORT so the forward is
183
- // deterministic across runs. (Headless usually uses the device flow above,
184
- // so this hint is a fallback for a misdetected display.)
185
- const callbackPort = Number(process.env.HACKLAB_CALLBACK_PORT) || 0;
186
- server.listen(callbackPort, '127.0.0.1', () => {
187
- const addr = server.address();
188
- if (!addr || typeof addr === 'string') {
189
- stopServer();
190
- reject(new Error('failed to start callback server'));
191
- return;
192
- }
193
- const callbackUrl = `http://127.0.0.1:${addr.port}`;
194
- const loginUrl = `${appUrl}/cli/auth?callback=${encodeURIComponent(callbackUrl)}`;
195
- info('to sign in, open this URL in a browser:');
196
- info(` ${loginUrl}`);
197
- if (isLikelyHeadless()) {
198
- info(dim('headless? drop --browser to use the device code, or forward the port:'));
199
- info(dim(` ssh -L ${addr.port}:localhost:${addr.port} <this-host>`));
200
- info(dim(' (pin it with HACKLAB_CALLBACK_PORT to reuse one forward)'));
201
- }
202
- // Best-effort auto-open — crash-safe, and a harmless no-op on headless.
203
- void openBrowser(loginUrl);
204
- });
205
- // Timeout after 2 minutes
206
- timeout = setTimeout(() => {
207
- stopServer();
208
- reject(new Error('login timed out. try again.'));
209
- }, 120_000);
210
- function stopServer() {
211
- if (timeout)
212
- clearTimeout(timeout);
213
- server.close();
214
- }
215
- });
216
- }
217
123
  function sleep(ms) {
218
124
  return new Promise((resolve) => setTimeout(resolve, ms));
219
125
  }
220
- function normalizeDateParam(value) {
221
- if (!value)
222
- return undefined;
223
- const date = new Date(value);
224
- return Number.isNaN(date.getTime()) ? undefined : date.toISOString();
126
+ async function fetchMe(appUrl, token) {
127
+ try {
128
+ const res = await fetch(`${appUrl}/api/hackers/me?src=cli`, {
129
+ headers: { Authorization: `Bearer ${token}` },
130
+ signal: AbortSignal.timeout(10_000),
131
+ });
132
+ if (!res.ok)
133
+ return null;
134
+ return (await res.json());
135
+ }
136
+ catch {
137
+ return null;
138
+ }
225
139
  }
226
- /**
227
- * Heuristic for "this host probably can't pop a browser": a Linux/Unix box with
228
- * no display server. macOS and Windows always have a usable GUI opener. Only
229
- * used inside the `--browser` flow to decide whether to print the port-forward
230
- * hint — it no longer gates device-vs-browser (device is always the default).
231
- */
232
- function isLikelyHeadless() {
233
- if (process.platform === 'darwin' || process.platform === 'win32') {
234
- return false;
140
+ async function claimHandle(appUrl, token, username) {
141
+ try {
142
+ const res = await fetch(`${appUrl}/api/cli/claim`, {
143
+ method: 'POST',
144
+ headers: {
145
+ 'Content-Type': 'application/json',
146
+ Authorization: `Bearer ${token}`,
147
+ },
148
+ body: JSON.stringify({ username }),
149
+ });
150
+ if (!res.ok)
151
+ return null;
152
+ const data = (await res.json());
153
+ return data.handle ?? username;
154
+ }
155
+ catch {
156
+ return null;
235
157
  }
236
- return !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY;
237
158
  }
238
159
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -38,11 +38,11 @@ export async function referral(args) {
38
38
  const session = await requireSession(json);
39
39
  const handle = session.handle;
40
40
  if (!handle) {
41
- const message = 'claim a username first with `hacklab join`';
41
+ const message = 'claim a username first with `hacklab login`';
42
42
  if (json)
43
43
  emitJsonError('no_handle', message);
44
44
  error('no referral link yet — you have not claimed a username');
45
- hint('run `hacklab join` to finish setting up your profile');
45
+ hint('run `hacklab login` to finish setting up your profile');
46
46
  process.exit(1);
47
47
  }
48
48
  const base = resolveAppUrl(session);
@@ -1 +1 @@
1
- {"version":3,"file":"referral.js","sourceRoot":"","sources":["../../src/commands/referral.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"referral.js","sourceRoot":"","sources":["../../src/commands/referral.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Scan local AI usage, render the share card, and optionally post it to X.
3
+ * Local-only unless they choose to share. Login is optional: a handle on the
4
+ * session goes on the card; without one the card still renders.
5
+ */
6
+ export declare function scan(): Promise<void>;
7
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"AAiCA;;;;GAIG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAkE1C"}
@@ -0,0 +1,175 @@
1
+ import * as clack from '@clack/prompts';
2
+ import { beltForTokens } from '../belt.js';
3
+ import { loadConfig, resolveCursorAuth, saveConfig } from '../config.js';
4
+ import { captureEvent } from '../posthog.js';
5
+ import { collectToolScans, computeStreaks, detectCursorUsage, formatTokens, mergeToolScans, rescanCursorWithApi, } from '../scanners/index.js';
6
+ import { loadSession } from '../session.js';
7
+ import { promptShareOnX, renderShareCard, } from '../share.js';
8
+ import { bold, dim } from '../ui.js';
9
+ const TOOL_LABELS = {
10
+ claude_code: 'Claude Code',
11
+ codex: 'Codex',
12
+ cursor: 'Cursor',
13
+ openclaw: 'OpenClaw',
14
+ hermes: 'Hermes',
15
+ opencode: 'OpenCode',
16
+ grok: 'Grok Build',
17
+ };
18
+ /**
19
+ * Scan local AI usage, render the share card, and optionally post it to X.
20
+ * Local-only unless they choose to share. Login is optional: a handle on the
21
+ * session goes on the card; without one the card still renders.
22
+ */
23
+ export async function scan() {
24
+ const spin = clack.spinner();
25
+ spin.start('scanning local AI tool usage');
26
+ let results;
27
+ try {
28
+ results = await collectToolScans();
29
+ }
30
+ catch (err) {
31
+ spin.stop('scan failed');
32
+ clack.cancel(`couldn't read local AI usage: ${err instanceof Error ? err.message : String(err)}`);
33
+ process.exit(1);
34
+ }
35
+ spin.stop('scan complete');
36
+ let scanResult = mergeToolScans(results);
37
+ printToolTotals(scanResult);
38
+ const rescanned = await offerCursorApiKey(results, spin);
39
+ if (rescanned) {
40
+ results = rescanned;
41
+ scanResult = mergeToolScans(results);
42
+ printToolTotals(scanResult);
43
+ }
44
+ const session = await loadSession();
45
+ const handle = session?.handle ?? 'hacker';
46
+ const belt = beltForTokens(scanResult.grandTotal);
47
+ const streaks = computeStreaks(scanResult.dailyTotals.map((entry) => entry.date));
48
+ const card = {
49
+ handle,
50
+ level: belt.level,
51
+ title: belt.title,
52
+ beltColor: belt.beltColor,
53
+ tokensTotal: scanResult.grandTotal,
54
+ rank: 0,
55
+ streak: streaks.current,
56
+ longestStreak: streaks.longest,
57
+ progressPercent: belt.progressPercent,
58
+ estimatedCost: estimateCost(scanResult.toolTotals),
59
+ toolBreakdown: {
60
+ claudeCode: scanResult.toolTotals.claude_code ?? 0,
61
+ codex: scanResult.toolTotals.codex ?? 0,
62
+ cursor: scanResult.toolTotals.cursor ?? 0,
63
+ },
64
+ models: Object.entries(scanResult.modelTotals)
65
+ .map(([name, tokens]) => ({ name, tokens }))
66
+ .sort((a, b) => b.tokens - a.tokens),
67
+ dailyActivity: aggregateDailyActivity(scanResult.dailyTotals),
68
+ };
69
+ const cardPath = await renderShareCard(card);
70
+ if (session?.handle) {
71
+ await promptShareOnX(card, cardPath);
72
+ }
73
+ else {
74
+ clack.log.message(dim('hacklab login to put your name on the card'));
75
+ }
76
+ if (session?.handle) {
77
+ await captureEvent(session.handle, 'cli_scan_completed', {
78
+ tokens_total: scanResult.grandTotal,
79
+ });
80
+ }
81
+ clack.outro(dim('done.'));
82
+ }
83
+ function printToolTotals(scan) {
84
+ for (const [tool, total] of Object.entries(scan.toolTotals)) {
85
+ if (total > 0) {
86
+ clack.log.message(`${(TOOL_LABELS[tool] ?? tool).padEnd(12)} ${formatTokens(total)} tokens`);
87
+ }
88
+ }
89
+ clack.log.message(bold(`total: ${formatTokens(scan.grandTotal)} tokens`));
90
+ }
91
+ async function offerCursorApiKey(results, spin) {
92
+ const { apiKey } = await resolveCursorAuth();
93
+ if (apiKey)
94
+ return null;
95
+ if (!(await detectCursorUsage()))
96
+ return null;
97
+ clack.log.step('cursor detected');
98
+ clack.log.message(dim('a cursor api key gets exact counts. enter to skip.'));
99
+ const entered = await clack.password({
100
+ message: 'cursor api key (enter to skip)',
101
+ });
102
+ if (clack.isCancel(entered))
103
+ return null;
104
+ const key = String(entered ?? '').trim();
105
+ if (!key) {
106
+ clack.log.message(dim('skipped — cursor tokens will stay estimated.'));
107
+ return null;
108
+ }
109
+ const emailValue = await clack.text({
110
+ message: 'cursor account email (optional — scopes a team key to just you)',
111
+ placeholder: 'enter to skip',
112
+ });
113
+ const email = clack.isCancel(emailValue) || !String(emailValue ?? '').trim()
114
+ ? undefined
115
+ : String(emailValue).trim();
116
+ await saveConfig({
117
+ ...(await loadConfig()),
118
+ cursorApiKey: key,
119
+ ...(email ? { cursorEmail: email } : {}),
120
+ });
121
+ spin.start('fetching exact cursor usage');
122
+ let rescanned;
123
+ try {
124
+ rescanned = await rescanCursorWithApi(results);
125
+ }
126
+ catch (err) {
127
+ spin.stop('cursor api scan failed');
128
+ clack.log.message(dim(`keeping the local estimate: ${err instanceof Error ? err.message : String(err)}`));
129
+ return null;
130
+ }
131
+ const status = rescanned.find((r) => r.tool === 'cursor')?.cursorScanStatus;
132
+ switch (status?.source) {
133
+ case 'api':
134
+ spin.stop(`cursor: exact counts from ${status.events} usage events`);
135
+ return rescanned;
136
+ case 'api-partial':
137
+ spin.stop(`cursor: ${status.events} usage events (partial)`);
138
+ clack.log.message(dim(`stopped early: ${status.reason}`));
139
+ return rescanned;
140
+ case 'api-failed':
141
+ spin.stop('cursor api scan failed');
142
+ clack.log.message(dim(`${status.reason} — keeping the local estimate.`));
143
+ return null;
144
+ default:
145
+ spin.stop('cursor api returned no usage events');
146
+ clack.log.message(dim('keeping the local estimate.'));
147
+ return null;
148
+ }
149
+ }
150
+ function estimateCost(toolTotals) {
151
+ const rate = {
152
+ claude_code: 0.6,
153
+ codex: 0.25,
154
+ cursor: 0.4,
155
+ openclaw: 0.5,
156
+ hermes: 0.5,
157
+ opencode: 0.5,
158
+ grok: 0.5,
159
+ };
160
+ let cost = 0;
161
+ for (const [tool, tokens] of Object.entries(toolTotals)) {
162
+ cost += (tokens / 1_000_000) * (rate[tool] ?? 0.4);
163
+ }
164
+ return cost;
165
+ }
166
+ function aggregateDailyActivity(dailyTotals) {
167
+ const byDate = new Map();
168
+ for (const entry of dailyTotals) {
169
+ byDate.set(entry.date, (byDate.get(entry.date) ?? 0) + entry.tokens);
170
+ }
171
+ return Array.from(byDate.entries())
172
+ .map(([date, tokens]) => ({ date, tokens }))
173
+ .sort((a, b) => a.date.localeCompare(b.date));
174
+ }
175
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
@@ -246,7 +246,7 @@ async function interactiveSync() {
246
246
  let result;
247
247
  try {
248
248
  // Manual `hacklab sync` — tag the upload as interactive so the backend counts
249
- // it as user activity (the daily background job and join's upload don't).
249
+ // it as user activity (the daily background job doesn't).
250
250
  result = await runSync(session, { interactive: true, promptConsent });
251
251
  }
252
252
  catch (e) {