hacklab 0.10.4 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -12
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +27 -2
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/daemon.d.ts +6 -2
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +12 -8
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +158 -7
- package/dist/commands/sync.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/daily-sync.d.ts +20 -3
- package/dist/daily-sync.d.ts.map +1 -1
- package/dist/daily-sync.js +154 -44
- package/dist/daily-sync.js.map +1 -1
- package/dist/prompt-consent.d.ts +61 -0
- package/dist/prompt-consent.d.ts.map +1 -0
- package/dist/prompt-consent.js +167 -0
- package/dist/prompt-consent.js.map +1 -0
- package/dist/prompt-stats.d.ts +72 -0
- package/dist/prompt-stats.d.ts.map +1 -0
- package/dist/prompt-stats.js +244 -0
- package/dist/prompt-stats.js.map +1 -0
- package/dist/scanners/incremental.d.ts +144 -0
- package/dist/scanners/incremental.d.ts.map +1 -0
- package/dist/scanners/incremental.js +519 -0
- package/dist/scanners/incremental.js.map +1 -0
- package/dist/scanners/index.d.ts +44 -0
- package/dist/scanners/index.d.ts.map +1 -1
- package/dist/scanners/index.js +160 -126
- package/dist/scanners/index.js.map +1 -1
- package/dist/sync.d.ts +25 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +52 -5
- package/dist/sync.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ hacklab daemon
|
|
|
16
16
|
|
|
17
17
|
The script checks for Node 20+ and installs the CLI globally — that's all it
|
|
18
18
|
does. After it, `hacklab` is a real command on your PATH; `join` claims your
|
|
19
|
-
handle and `daemon` schedules the
|
|
19
|
+
handle and `daemon` schedules the background sync. If you already have Node
|
|
20
20
|
(including through a version manager), you can skip the script:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
@@ -36,7 +36,7 @@ irm https://hacklab.so/install.ps1 | iex
|
|
|
36
36
|
|
|
37
37
|
The CLI reads your agents' usage from your Windows home (`%USERPROFILE%\.claude`,
|
|
38
38
|
`.codex`, and Cursor's native tracking DB), and `hacklab daemon` registers the
|
|
39
|
-
|
|
39
|
+
background sync as two Task Scheduler tasks. If you run Claude Code or Codex
|
|
40
40
|
**inside WSL**, install there instead with the `curl … | sh` command above, run
|
|
41
41
|
from your WSL shell.
|
|
42
42
|
|
|
@@ -77,7 +77,7 @@ scan local AI usage → see your rank → sign in with GitHub → claim a userna
|
|
|
77
77
|
6. **Claim** — saves your usage, syncs pinned GitHub projects, and claims
|
|
78
78
|
`hacklab.so/<username>`. Bio and the first drop finish activation in the web
|
|
79
79
|
onboarding flow. Join never schedules anything behind your back — it points
|
|
80
|
-
you at `hacklab daemon` for the
|
|
80
|
+
you at `hacklab daemon` for the background sync.
|
|
81
81
|
7. **Card** — renders the belt, level, rank, and token breakdown directly in the
|
|
82
82
|
terminal. Terminals without inline images get a text version.
|
|
83
83
|
8. **Share** — one optional X prompt. Saying yes saves the image to
|
|
@@ -90,14 +90,16 @@ scan local AI usage → see your rank → sign in with GitHub → claim a userna
|
|
|
90
90
|
finished profile it stops early and points you at `hacklab logout` +
|
|
91
91
|
`hacklab login` to switch accounts.
|
|
92
92
|
- `hacklab sync` — re-scan local AI usage and sync it to your profile.
|
|
93
|
-
- `hacklab daemon` — summon the daemon:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
- `hacklab daemon` — summon the daemon: two OS-native background jobs (launchd on
|
|
94
|
+
macOS, systemd user timers on Linux, Task Scheduler tasks on Windows) so your
|
|
95
|
+
tokens, rank, and streak stay current without you running anything. A **tick
|
|
96
|
+
every minute** reads only what your tools appended since the last run — no
|
|
97
|
+
network call at all on a minute where nothing happened — and a **full sync once
|
|
98
|
+
a day** re-scans everything and repairs whatever the tick missed. No daemon, no
|
|
99
|
+
streak. Re-running it is idempotent; `hacklab daemon off` tears both down, and
|
|
100
|
+
`hacklab logout` removes them too. On a platform we can't schedule (BSD, a
|
|
101
|
+
locked-down box) it prints the commands to schedule yourself instead of
|
|
102
|
+
pretending it worked. `hacklab sync --install-daily` still forwards here.
|
|
101
103
|
- `hacklab whoami` — show who you're logged in as.
|
|
102
104
|
- `hacklab drop "message"` — post a drop to your feed (`-u <url>` to attach a
|
|
103
105
|
link). Human output prints its profile URL; `--json` returns a stable envelope
|
|
@@ -109,7 +111,8 @@ scan local AI usage → see your rank → sign in with GitHub → claim a userna
|
|
|
109
111
|
machine-readable output an agent can drive.
|
|
110
112
|
- `hacklab login` — re-authenticate with GitHub.
|
|
111
113
|
- `hacklab logout` — clear your saved session on this machine.
|
|
112
|
-
- `hacklab config <key> <value>` — set config (`cursor-api-key`, `cursor-email
|
|
114
|
+
- `hacklab config <key> <value>` — set config (`cursor-api-key`, `cursor-email`,
|
|
115
|
+
`prompt-stats`).
|
|
113
116
|
Bare `hacklab config` prints the effective values and where each came from.
|
|
114
117
|
- `hacklab project` — publish the repo you're standing in as a project. It reads
|
|
115
118
|
the git remote, README, and package.json, shows a preview, and publishes on
|
|
@@ -209,6 +212,45 @@ otherwise, and all of it would land on your profile as your own.
|
|
|
209
212
|
If a key is set but Cursor rejects it, the scan says so and falls back to the
|
|
210
213
|
local estimate — it won't quietly hand you an estimate you think is exact.
|
|
211
214
|
|
|
215
|
+
## Prompt stats
|
|
216
|
+
|
|
217
|
+
`sync` can also chart *how* you prompt, not just how many tokens you burned:
|
|
218
|
+
a histogram of your prompt lengths and a prompt count per project, shown on the
|
|
219
|
+
AI Usage tab of your profile. It reads your local Claude Code transcripts
|
|
220
|
+
(`~/.claude/projects`) on this machine.
|
|
221
|
+
|
|
222
|
+
Nothing conversation-derived is uploaded until you say so. The first
|
|
223
|
+
interactive `sync` asks, remembers the answer, and never asks again. There are
|
|
224
|
+
three tiers:
|
|
225
|
+
|
|
226
|
+
| Tier | What leaves your machine |
|
|
227
|
+
| ------- | ------------------------ |
|
|
228
|
+
| `none` | token counts only — exactly what the CLI did before this existed |
|
|
229
|
+
| `stats` | + prompt-length histogram and per-project counts. Numbers only; no prompt text |
|
|
230
|
+
| `full` | + a sample of your prompt text (≤20k chars), scored for how technical it is and then discarded server-side |
|
|
231
|
+
|
|
232
|
+
Projects are matched by their git `origin` remote, so a prompt count only lands
|
|
233
|
+
on a project you've already added to hacklab (`hacklab brag`). Directories
|
|
234
|
+
without a git remote are skipped entirely.
|
|
235
|
+
|
|
236
|
+
Answer up front, without the prompt — the agent-friendly path:
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
hacklab sync --share-prompt-stats # numbers only
|
|
240
|
+
hacklab sync --share-prompt-stats=full # numbers + text sample
|
|
241
|
+
hacklab sync --no-share-prompt-stats # refuse
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Change or revoke it any time:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
hacklab config prompt-stats none # stop sharing; nothing further is uploaded
|
|
248
|
+
hacklab config # show the current tier
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
The unattended daily sync never asks. A machine that has never answered
|
|
252
|
+
uploads token counts only.
|
|
253
|
+
|
|
212
254
|
## Choosing a backend
|
|
213
255
|
|
|
214
256
|
Every command resolves which backend to talk to by the same precedence:
|
package/dist/cli.js
CHANGED
|
@@ -82,6 +82,7 @@ function printHelp() {
|
|
|
82
82
|
console.log(` ${dim('--env')} ${dim('<production|development>')} pick the backend (default: production)`);
|
|
83
83
|
console.log(` ${dim('--cursor-api-key')} ${dim('<key>')} exact Cursor usage (or ${dim('CURSOR_API_KEY')})`);
|
|
84
84
|
console.log(` ${dim('--cursor-email')} ${dim('<email>')} scope a Cursor team key to you (or ${dim('CURSOR_EMAIL')})`);
|
|
85
|
+
console.log(` ${dim('--share-prompt-stats')}${dim('[=stats|full]')} answer the prompt-stats consent up front`);
|
|
85
86
|
console.log('');
|
|
86
87
|
}
|
|
87
88
|
// Node-version guard (T9). The CLI uses modern Node APIs (global fetch,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AA4BA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,iBA8EjD"}
|
package/dist/commands/config.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { loadConfig, resolveCursorAuth, saveConfig, } from '../config.js';
|
|
2
|
+
import { isPromptConsentTier, PROMPT_CONSENT_TIERS, } from '../prompt-consent.js';
|
|
2
3
|
import { dim, error, info, success } from '../ui.js';
|
|
4
|
+
const PROMPT_CONSENT_DESCRIPTIONS = {
|
|
5
|
+
none: 'token counts only. nothing from your conversations leaves this machine.',
|
|
6
|
+
stats: 'prompt lengths and per-project counts. numbers only, no text.',
|
|
7
|
+
full: 'the above, plus a text sample scored for how technical it is (then discarded).',
|
|
8
|
+
};
|
|
3
9
|
/**
|
|
4
10
|
* Note where a value came from. Printing the *effective* value rather than the
|
|
5
11
|
* file's is the point: with an env var or flag set, the file's value is dead
|
|
@@ -21,13 +27,22 @@ export async function configCommand(args) {
|
|
|
21
27
|
if (auth.email) {
|
|
22
28
|
info(` cursor-email: ${auth.email}${sourceNote(auth.emailSource, 'CURSOR_EMAIL')}`);
|
|
23
29
|
}
|
|
30
|
+
const consent = (await loadConfig()).promptStatsConsent;
|
|
31
|
+
if (isPromptConsentTier(consent)) {
|
|
32
|
+
info(` prompt-stats: ${consent}`);
|
|
33
|
+
info(` ${dim(PROMPT_CONSENT_DESCRIPTIONS[consent])}`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
info(` prompt-stats: ${dim('unset — sync will ask')}`);
|
|
37
|
+
}
|
|
24
38
|
if (!auth.apiKey && !auth.email) {
|
|
25
|
-
info(` ${dim('(empty)')}`);
|
|
39
|
+
info(` ${dim('(cursor: empty)')}`);
|
|
26
40
|
}
|
|
27
41
|
console.log('');
|
|
28
42
|
info('available keys:');
|
|
29
43
|
info(` ${dim('cursor-api-key')} your Cursor API key — exact token counts`);
|
|
30
44
|
info(` ${dim('cursor-email')} your Cursor account email — scopes a team key to you`);
|
|
45
|
+
info(` ${dim('prompt-stats')} ${PROMPT_CONSENT_TIERS.join(' | ')} — what leaves this machine`);
|
|
31
46
|
console.log('');
|
|
32
47
|
info(dim('per-run overrides (both beat this file):'));
|
|
33
48
|
info(dim(' hacklab --cursor-api-key <key> sync'));
|
|
@@ -51,9 +66,19 @@ export async function configCommand(args) {
|
|
|
51
66
|
await saveConfig(config);
|
|
52
67
|
success(`cursor-email set to ${value}`);
|
|
53
68
|
break;
|
|
69
|
+
case 'prompt-stats':
|
|
70
|
+
if (!isPromptConsentTier(value)) {
|
|
71
|
+
error(`prompt-stats must be one of: ${PROMPT_CONSENT_TIERS.join(', ')}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
config.promptStatsConsent = value;
|
|
75
|
+
await saveConfig(config);
|
|
76
|
+
success(`prompt-stats set to ${value}`);
|
|
77
|
+
info(dim(` ${PROMPT_CONSENT_DESCRIPTIONS[value]}`));
|
|
78
|
+
break;
|
|
54
79
|
default:
|
|
55
80
|
error(`unknown config key: ${key}`);
|
|
56
|
-
info(`available: cursor-api-key, cursor-email`);
|
|
81
|
+
info(`available: cursor-api-key, cursor-email, prompt-stats`);
|
|
57
82
|
process.exit(1);
|
|
58
83
|
}
|
|
59
84
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,iBAAiB,EACjB,UAAU,GACX,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEpD;;;;GAIG;AACH,SAAS,UAAU,CAAC,MAAwB,EAAE,OAAe;IAC3D,OAAO,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,OAAO,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc;IAChD,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAA;IACjC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAElC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACvB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CACF,qBAAqB,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAC,EAAE,CAC9G,CAAA;QACH,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CACF,qBAAqB,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,CACjF,CAAA;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `hacklab daemon` — arm the
|
|
2
|
+
* `hacklab daemon` — arm the background sync, as its own explicit step.
|
|
3
3
|
*
|
|
4
|
-
* hacklab daemon summon it (install/refresh the OS-native
|
|
4
|
+
* hacklab daemon summon it (install/refresh the OS-native jobs)
|
|
5
5
|
* hacklab daemon off dismiss it (tear the schedule down)
|
|
6
6
|
*
|
|
7
|
+
* Two cadences, one command: a token tick every minute (incremental — it reads
|
|
8
|
+
* only what your tools appended since the last run) and a full sync once a day
|
|
9
|
+
* that re-scans everything and repairs whatever the tick got wrong.
|
|
10
|
+
*
|
|
7
11
|
* This used to be a side effect of `join` (and a flag on `sync`), which made it
|
|
8
12
|
* invisible: users couldn't tell whether anything was scheduled, and the web
|
|
9
13
|
* onboarding had no step to point at. Now it's a command the onboarding flow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAUA
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/D"}
|
package/dist/commands/daemon.js
CHANGED
|
@@ -3,11 +3,15 @@ import { captureEvent } from '../posthog.js';
|
|
|
3
3
|
import { loadSession } from '../session.js';
|
|
4
4
|
import { dim, error, info, success } from '../ui.js';
|
|
5
5
|
/**
|
|
6
|
-
* `hacklab daemon` — arm the
|
|
6
|
+
* `hacklab daemon` — arm the background sync, as its own explicit step.
|
|
7
7
|
*
|
|
8
|
-
* hacklab daemon summon it (install/refresh the OS-native
|
|
8
|
+
* hacklab daemon summon it (install/refresh the OS-native jobs)
|
|
9
9
|
* hacklab daemon off dismiss it (tear the schedule down)
|
|
10
10
|
*
|
|
11
|
+
* Two cadences, one command: a token tick every minute (incremental — it reads
|
|
12
|
+
* only what your tools appended since the last run) and a full sync once a day
|
|
13
|
+
* that re-scans everything and repairs whatever the tick got wrong.
|
|
14
|
+
*
|
|
11
15
|
* This used to be a side effect of `join` (and a flag on `sync`), which made it
|
|
12
16
|
* invisible: users couldn't tell whether anything was scheduled, and the web
|
|
13
17
|
* onboarding had no step to point at. Now it's a command the onboarding flow
|
|
@@ -20,8 +24,8 @@ export async function daemon(args = []) {
|
|
|
20
24
|
return dismiss();
|
|
21
25
|
return summon();
|
|
22
26
|
}
|
|
23
|
-
/** Install (or refresh) the
|
|
24
|
-
*
|
|
27
|
+
/** Install (or refresh) the background sync jobs. Requires a session — they run
|
|
28
|
+
* as this user and upload to their profile. */
|
|
25
29
|
async function summon() {
|
|
26
30
|
const session = await loadSession();
|
|
27
31
|
if (!session) {
|
|
@@ -31,7 +35,7 @@ async function summon() {
|
|
|
31
35
|
}
|
|
32
36
|
const result = await installDailySync();
|
|
33
37
|
if (result.ok) {
|
|
34
|
-
success(`daemon summoned —
|
|
38
|
+
success(`daemon summoned — token tick every minute, full sync daily, via ${result.mechanism}`);
|
|
35
39
|
info(dim(` ${result.detail}`));
|
|
36
40
|
info(dim(` log: ${syncLogPath()}`));
|
|
37
41
|
info(dim(' dismiss it with `hacklab daemon off` (logout removes it too)'));
|
|
@@ -43,8 +47,8 @@ async function summon() {
|
|
|
43
47
|
}
|
|
44
48
|
// Nothing was scheduled: a platform we don't auto-schedule on (e.g. BSD) or a
|
|
45
49
|
// failed scheduler write. Say so plainly and print the copy-paste cron
|
|
46
|
-
//
|
|
47
|
-
error("couldn't schedule the
|
|
50
|
+
// commands — silently reporting success here would cost the user their streak.
|
|
51
|
+
error("couldn't schedule the background sync on this system");
|
|
48
52
|
info(result.instructions);
|
|
49
53
|
await captureEvent(session.handle, 'cli_daily_sync_manual', {
|
|
50
54
|
mechanism: result.mechanism,
|
|
@@ -56,7 +60,7 @@ async function dismiss() {
|
|
|
56
60
|
const session = await loadSession();
|
|
57
61
|
await uninstallDailySync();
|
|
58
62
|
await clearSyncPaused();
|
|
59
|
-
success('daemon dismissed — no more
|
|
63
|
+
success('daemon dismissed — no more background sync');
|
|
60
64
|
info(dim('run `hacklab daemon` to summon it again'));
|
|
61
65
|
await captureEvent(session?.handle, 'cli_daily_sync_removed');
|
|
62
66
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEpD
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEpD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAiB,EAAE;IAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,EAAE,CAAA;IACpE,OAAO,MAAM,EAAE,CAAA;AACjB,CAAC;AAED;+CAC+C;AAC/C,KAAK,UAAU,MAAM;IACnB,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,KAAK,CAAC,eAAe,CAAC,CAAA;QACtB,IAAI,CACF,OAAO,GAAG,CAAC,cAAc,CAAC,cAAc,GAAG,CAAC,eAAe,CAAC,kCAAkC,CAC/F,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAA;IACvC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,CACL,mEAAmE,MAAM,CAAC,SAAS,EAAE,CACtF,CAAA;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC/B,IAAI,CAAC,GAAG,CAAC,UAAU,WAAW,EAAE,EAAE,CAAC,CAAC,CAAA;QACpC,IAAI,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC,CAAA;QAC3E,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,0BAA0B,EAAE;YAC7D,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAA;QACF,OAAM;IACR,CAAC;IAED,8EAA8E;IAC9E,uEAAuE;IACvE,+EAA+E;IAC/E,KAAK,CAAC,sDAAsD,CAAC,CAAA;IAC7D,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACzB,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,uBAAuB,EAAE;QAC1D,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAA;AACJ,CAAC;AAED;0EAC0E;AAC1E,KAAK,UAAU,OAAO;IACpB,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,MAAM,kBAAkB,EAAE,CAAA;IAC1B,MAAM,eAAe,EAAE,CAAA;IACvB,OAAO,CAAC,4CAA4C,CAAC,CAAA;IACrD,IAAI,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAA;IACpD,MAAM,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAA;AAC/D,CAAC"}
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* `hacklab sync` — dispatch on flags:
|
|
3
3
|
* (none) interactive sync (scan, upload, show stats)
|
|
4
4
|
* --install-daily deprecated alias for `hacklab daemon`
|
|
5
|
+
* --tick the every-minute incremental run (usually a no-op)
|
|
5
6
|
* --quiet the unattended daily run (logs to a file, no output)
|
|
6
7
|
*/
|
|
7
8
|
export declare function sync(args?: string[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA+CA;;;;;;GAMG;AACH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB7D"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as clack from '@clack/prompts';
|
|
2
|
-
import { appendSyncLog, clearSyncPaused, markSyncPaused, } from '../daily-sync.js';
|
|
2
|
+
import { appendSyncLog, clearSyncPaused, markSyncPaused, readSyncPaused, trimSyncLog, } from '../daily-sync.js';
|
|
3
3
|
import { captureEvent } from '../posthog.js';
|
|
4
|
-
import {
|
|
4
|
+
import { loadPromptConsent, parsePromptStatsFlag, resolvePromptConsent, savePromptConsent, } from '../prompt-consent.js';
|
|
5
|
+
import { cumulativeTotals, loadScanState, markUploaded, rebuildScanState, runTick, sameTotals, saveScanState, tickPayload, } from '../scanners/incremental.js';
|
|
6
|
+
import { collectToolScans, mergeToolScans } from '../scanners/index.js';
|
|
5
7
|
import { loadSessionState } from '../session.js';
|
|
6
|
-
import { checkSession, ensureFreshSession, formatTokens, LOGIN_EXPIRED_MESSAGE, refreshSession, runSync, syncGithubRepos, uploadTokenScan, } from '../sync.js';
|
|
8
|
+
import { checkSession, ensureFreshSession, formatTokens, LOGIN_EXPIRED_MESSAGE, refreshSession, runSync, SyncUploadError, scanConsentedPromptStats, syncGithubRepos, uploadTokenScan, } from '../sync.js';
|
|
7
9
|
import { bold, dim, error, info, success } from '../ui.js';
|
|
8
10
|
import { daemon } from './daemon.js';
|
|
9
11
|
const SESSION_EXPIRED_REASON = 'your hacklab session expired — run `hacklab login`';
|
|
@@ -11,9 +13,16 @@ const SESSION_EXPIRED_REASON = 'your hacklab session expired — run `hacklab lo
|
|
|
11
13
|
* `hacklab sync` — dispatch on flags:
|
|
12
14
|
* (none) interactive sync (scan, upload, show stats)
|
|
13
15
|
* --install-daily deprecated alias for `hacklab daemon`
|
|
16
|
+
* --tick the every-minute incremental run (usually a no-op)
|
|
14
17
|
* --quiet the unattended daily run (logs to a file, no output)
|
|
15
18
|
*/
|
|
16
19
|
export async function sync(args = []) {
|
|
20
|
+
// Pull --share-prompt-stats out first so it works alongside every mode
|
|
21
|
+
// below (an agent can set consent on the same run that installs the daemon).
|
|
22
|
+
const { tier: flagTier, rest } = parsePromptStatsFlag(args);
|
|
23
|
+
if (flagTier)
|
|
24
|
+
await savePromptConsent(flagTier);
|
|
25
|
+
args = rest;
|
|
17
26
|
if (args.includes('--install-daily')) {
|
|
18
27
|
// Kept working (it shipped, and installed CLIs / old docs still say it) but
|
|
19
28
|
// no longer advertised: scheduling the daemon is `hacklab daemon` now, which
|
|
@@ -21,6 +30,8 @@ export async function sync(args = []) {
|
|
|
21
30
|
info(dim('`sync --install-daily` is now `hacklab daemon` — running that.'));
|
|
22
31
|
return daemon();
|
|
23
32
|
}
|
|
33
|
+
if (args.includes('--tick'))
|
|
34
|
+
return tickSync();
|
|
24
35
|
if (args.includes('--quiet'))
|
|
25
36
|
return quietSync();
|
|
26
37
|
return interactiveSync();
|
|
@@ -30,6 +41,11 @@ export async function sync(args = []) {
|
|
|
30
41
|
* Silent by design — everything goes to ~/.hacklab/sync.log. Proactively
|
|
31
42
|
* refreshes a near-expiry session; if the session has truly lapsed it drops a
|
|
32
43
|
* paused marker the next interactive run surfaces, then exits cleanly.
|
|
44
|
+
*
|
|
45
|
+
* It's also the repair pass for the minutely tick: a full stateless scan, so
|
|
46
|
+
* whatever the tick's tail-follow missed or double-counted is corrected here and
|
|
47
|
+
* the tick's state is re-based on the result. Incremental drift therefore can't
|
|
48
|
+
* outlive a day.
|
|
33
49
|
*/
|
|
34
50
|
async function quietSync() {
|
|
35
51
|
const state = await loadSessionState();
|
|
@@ -46,12 +62,18 @@ async function quietSync() {
|
|
|
46
62
|
return;
|
|
47
63
|
}
|
|
48
64
|
const session = await ensureFreshSession(state.session);
|
|
49
|
-
const
|
|
65
|
+
const results = await collectToolScans();
|
|
66
|
+
const scan = mergeToolScans(results);
|
|
67
|
+
// Whatever the user already consented to. The unattended run never asks, so
|
|
68
|
+
// a machine that has never answered uploads token counts only.
|
|
69
|
+
const promptStats = await scanConsentedPromptStats((await loadPromptConsent()) ?? 'none');
|
|
50
70
|
// Upload tokens AND mirror pinned repos together, so the after-refresh retry
|
|
51
71
|
// below does the exact same work as the happy path (no silently-skipped repo
|
|
52
|
-
// sync on a day the session had to be refreshed mid-run).
|
|
72
|
+
// sync on a day the session had to be refreshed mid-run). The state rebuild
|
|
73
|
+
// rides along: everything just went out, so nothing is left dirty.
|
|
53
74
|
const push = async (s) => {
|
|
54
|
-
await uploadTokenScan(s, scan);
|
|
75
|
+
await uploadTokenScan(s, scan, { promptStats });
|
|
76
|
+
await rebuildScanState(results);
|
|
55
77
|
await syncGithubRepos(s);
|
|
56
78
|
};
|
|
57
79
|
try {
|
|
@@ -82,6 +104,116 @@ async function quietSync() {
|
|
|
82
104
|
await appendSyncLog('paused: session expired');
|
|
83
105
|
}
|
|
84
106
|
}
|
|
107
|
+
/** How long to sit out after a 429 that came without a Retry-After. */
|
|
108
|
+
const DEFAULT_BACKOFF_MS = 15 * 60 * 1000;
|
|
109
|
+
const MAX_BACKOFF_MS = 6 * 60 * 60 * 1000;
|
|
110
|
+
function backoffMs(retryAfter) {
|
|
111
|
+
const seconds = Number(retryAfter);
|
|
112
|
+
if (!Number.isFinite(seconds) || seconds <= 0)
|
|
113
|
+
return DEFAULT_BACKOFF_MS;
|
|
114
|
+
return Math.min(seconds * 1000, MAX_BACKOFF_MS);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Log a tick failure once. A minutely job that keeps hitting the same wall (no
|
|
118
|
+
* network, server down) would otherwise write 1440 identical lines a day, so the
|
|
119
|
+
* first one goes in and the rest are suppressed until something changes.
|
|
120
|
+
*/
|
|
121
|
+
async function logTickError(state, line) {
|
|
122
|
+
if (state.lastError === line)
|
|
123
|
+
return;
|
|
124
|
+
state.lastError = line;
|
|
125
|
+
await appendSyncLog(line);
|
|
126
|
+
}
|
|
127
|
+
/** Pause the background sync, logging it only the first time. */
|
|
128
|
+
async function pauseTick(reason) {
|
|
129
|
+
const alreadyPaused = await readSyncPaused();
|
|
130
|
+
await markSyncPaused(reason);
|
|
131
|
+
if (!alreadyPaused)
|
|
132
|
+
await appendSyncLog(`tick paused: ${reason}`);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* `hacklab sync --tick` — the every-minute run. Where `--quiet` re-scans every
|
|
136
|
+
* log from scratch (~6s and a few hundred MB for a heavy user), this reads only
|
|
137
|
+
* what the AI tools appended since the last tick, and on the overwhelmingly
|
|
138
|
+
* common minute where nothing was appended it exits after a stat walk, without
|
|
139
|
+
* touching the network. Silent unless it uploaded, failed, or got paused: the
|
|
140
|
+
* log has to survive 1440 runs a day.
|
|
141
|
+
*/
|
|
142
|
+
async function tickSync() {
|
|
143
|
+
const saved = await loadScanState();
|
|
144
|
+
// The server asked us to back off — respect it before doing any work at all.
|
|
145
|
+
if (saved?.nextAllowedAt && Date.now() < saved.nextAllowedAt)
|
|
146
|
+
return;
|
|
147
|
+
await trimSyncLog();
|
|
148
|
+
const sessionState = await loadSessionState();
|
|
149
|
+
if (!sessionState.session) {
|
|
150
|
+
// 'missing' is a logged-out machine: nothing to say, every minute.
|
|
151
|
+
if (sessionState.status === 'expired' ||
|
|
152
|
+
sessionState.status === 'invalid') {
|
|
153
|
+
await pauseTick(sessionState.status === 'invalid'
|
|
154
|
+
? 'your hacklab session file is unreadable — run `hacklab login`'
|
|
155
|
+
: SESSION_EXPIRED_REASON);
|
|
156
|
+
}
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const session = await ensureFreshSession(sessionState.session);
|
|
160
|
+
const { state, changed } = await runTick(saved);
|
|
161
|
+
const totals = cumulativeTotals(state);
|
|
162
|
+
if (state.dirty.length === 0 &&
|
|
163
|
+
sameTotals(totals.toolTotals, state.uploaded.toolTotals) &&
|
|
164
|
+
sameTotals(totals.modelTotals, state.uploaded.modelTotals)) {
|
|
165
|
+
// The common case: nothing new to say. Persist only if the walk actually
|
|
166
|
+
// saw something move (a touched file, a re-read harness).
|
|
167
|
+
if (changed)
|
|
168
|
+
await saveScanState(state);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const scan = tickPayload(state);
|
|
172
|
+
const dates = state.dirty.length;
|
|
173
|
+
// No prompt stats and no GitHub mirror: those are the daily job's work, and a
|
|
174
|
+
// minutely run has no business re-reading transcripts. Not interactive either
|
|
175
|
+
// — a background tick isn't user activity.
|
|
176
|
+
try {
|
|
177
|
+
const result = await uploadTokenScan(session, scan);
|
|
178
|
+
markUploaded(state);
|
|
179
|
+
await saveScanState(state);
|
|
180
|
+
await clearSyncPaused();
|
|
181
|
+
await appendSyncLog(`tick: +${formatTokens(Number(result.tokensDelta ?? 0))} tokens (${dates} date${dates === 1 ? '' : 's'})`);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
185
|
+
const status = e instanceof SyncUploadError ? e.status : 0;
|
|
186
|
+
if (status === 429) {
|
|
187
|
+
const wait = backoffMs(e instanceof SyncUploadError ? e.retryAfter : null);
|
|
188
|
+
state.nextAllowedAt = Date.now() + wait;
|
|
189
|
+
await logTickError(state, `tick: rate limited, pausing ${Math.round(wait / 1000)}s`);
|
|
190
|
+
await saveScanState(state);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (message === LOGIN_EXPIRED_MESSAGE) {
|
|
194
|
+
const refreshed = await refreshSession(session);
|
|
195
|
+
if (refreshed) {
|
|
196
|
+
try {
|
|
197
|
+
const result = await uploadTokenScan(refreshed, scan);
|
|
198
|
+
markUploaded(state);
|
|
199
|
+
await saveScanState(state);
|
|
200
|
+
await clearSyncPaused();
|
|
201
|
+
await appendSyncLog(`tick: +${formatTokens(Number(result.tokensDelta ?? 0))} tokens (${dates} dates, after refresh)`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// fall through to pause
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
await saveScanState(state);
|
|
209
|
+
await pauseTick(SESSION_EXPIRED_REASON);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// Dirty dates stay dirty, so the next tick retries them.
|
|
213
|
+
await logTickError(state, `tick error: ${message}`);
|
|
214
|
+
await saveScanState(state);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
85
217
|
async function interactiveSync() {
|
|
86
218
|
const sessionState = await loadSessionState();
|
|
87
219
|
if (!sessionState.session) {
|
|
@@ -104,6 +236,9 @@ async function interactiveSync() {
|
|
|
104
236
|
// Proactively slide a near-expiry session forward — same behavior as the daily
|
|
105
237
|
// job, so expiry management doesn't differ by entry point.
|
|
106
238
|
const session = await ensureFreshSession(sessionState.session);
|
|
239
|
+
// Ask before scanning anything conversational. Asked once, then remembered;
|
|
240
|
+
// an unanswered or non-TTY run resolves to 'none'.
|
|
241
|
+
const promptConsent = await resolvePromptConsent(null, { interactive: true });
|
|
107
242
|
console.log('');
|
|
108
243
|
console.log(bold(' hacklab sync'));
|
|
109
244
|
console.log(dim(' scanning local AI tool usage...'));
|
|
@@ -112,7 +247,7 @@ async function interactiveSync() {
|
|
|
112
247
|
try {
|
|
113
248
|
// Manual `hacklab sync` — tag the upload as interactive so the backend counts
|
|
114
249
|
// it as user activity (the daily background job and join's upload don't).
|
|
115
|
-
result = await runSync(session, { interactive: true });
|
|
250
|
+
result = await runSync(session, { interactive: true, promptConsent });
|
|
116
251
|
}
|
|
117
252
|
catch (e) {
|
|
118
253
|
error(e instanceof Error ? e.message : 'sync failed');
|
|
@@ -146,6 +281,22 @@ async function interactiveSync() {
|
|
|
146
281
|
if (Number(r.tokensDelta) > 0) {
|
|
147
282
|
info(` +${formatTokens(Number(r.tokensDelta))} since last sync`);
|
|
148
283
|
}
|
|
284
|
+
if (result.promptStats) {
|
|
285
|
+
const { totalPrompts } = result.promptStats;
|
|
286
|
+
info(` prompts ${formatTokens(totalPrompts)} scanned${promptConsent === 'full' ? dim(' (+ text sample)') : ''}`);
|
|
287
|
+
// The backend can only attach a project's count if the repo matches one of
|
|
288
|
+
// this user's own projects. Reporting the match rate keeps a scan that
|
|
289
|
+
// matched nothing from reading as a success.
|
|
290
|
+
const summary = result.result.promptStats;
|
|
291
|
+
const reported = summary?.projectsReported ?? 0;
|
|
292
|
+
const matched = summary?.projectsMatched ?? 0;
|
|
293
|
+
if (reported > 0 && matched === 0) {
|
|
294
|
+
info(dim(` none of your ${reported} local repos matched a hacklab project — run \`hacklab brag\` in one`));
|
|
295
|
+
}
|
|
296
|
+
else if (matched > 0) {
|
|
297
|
+
info(dim(` matched ${matched} of ${reported} local repos to projects`));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
149
300
|
// Mirror pinned GitHub repos into projects (best-effort; never fails sync).
|
|
150
301
|
const repos = await syncGithubRepos(session);
|
|
151
302
|
if (repos && (repos.synced > 0 || repos.removed > 0)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AAEvC,OAAO,EACL,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,GACZ,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,OAAO,EAEP,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAgB,MAAM,eAAe,CAAA;AAC9D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,OAAO,EACP,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,sBAAsB,GAC1B,oDAAoD,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAiB,EAAE;IAC5C,uEAAuE;IACvE,6EAA6E;IAC7E,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAC3D,IAAI,QAAQ;QAAE,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAC/C,IAAI,GAAG,IAAI,CAAA;IAEX,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACrC,4EAA4E;QAC5E,6EAA6E;QAC7E,uDAAuD;QACvD,IAAI,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC,CAAA;QAC3E,OAAO,MAAM,EAAE,CAAA;IACjB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,EAAE,CAAA;IAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,EAAE,CAAA;IAChD,OAAO,eAAe,EAAE,CAAA;AAC1B,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,SAAS;IACtB,MAAM,KAAK,GAAG,MAAM,gBAAgB,EAAE,CAAA;IACtC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,aAAa,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;QAC5C,4EAA4E;QAC5E,2EAA2E;QAC3E,kCAAkC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC7D,MAAM,cAAc,CAClB,KAAK,CAAC,MAAM,KAAK,SAAS;gBACxB,CAAC,CAAC,+DAA+D;gBACjE,CAAC,CAAC,sBAAsB,CAC3B,CAAA;QACH,CAAC;QACD,OAAM;IACR,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACvD,MAAM,OAAO,GAAG,MAAM,gBAAgB,EAAE,CAAA;IACxC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IACpC,4EAA4E;IAC5E,+DAA+D;IAC/D,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAChD,CAAC,MAAM,iBAAiB,EAAE,CAAC,IAAI,MAAM,CACtC,CAAA;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,4EAA4E;IAC5E,mEAAmE;IACnE,MAAM,IAAI,GAAG,KAAK,EAAE,CAAU,EAAE,EAAE;QAChC,MAAM,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;QAC/C,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC/B,MAAM,eAAe,CAAC,CAAC,CAAC,CAAA;IAC1B,CAAC,CAAA;IAED,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,CAAC,CAAA;QACnB,MAAM,eAAe,EAAE,CAAA;QACvB,MAAM,aAAa,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACtD,IAAI,GAAG,KAAK,qBAAqB,EAAE,CAAC;YAClC,MAAM,aAAa,CAAC,UAAU,GAAG,EAAE,CAAC,CAAA;YACpC,OAAM;QACR,CAAC;QACD,2DAA2D;QAC3D,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;QAC/C,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,CAAA;gBACrB,MAAM,eAAe,EAAE,CAAA;gBACvB,MAAM,aAAa,CAAC,oBAAoB,CAAC,CAAA;gBACzC,OAAM;YACR,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;YAC1B,CAAC;QACH,CAAC;QACD,MAAM,cAAc,CAAC,sBAAsB,CAAC,CAAA;QAC5C,MAAM,aAAa,CAAC,yBAAyB,CAAC,CAAA;IAChD,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AACzC,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEzC,SAAS,SAAS,CAAC,UAAyB;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,kBAAkB,CAAA;IACxE,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,EAAE,cAAc,CAAC,CAAA;AACjD,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,YAAY,CAAC,KAAgB,EAAE,IAAY;IACxD,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI;QAAE,OAAM;IACpC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAA;IACtB,MAAM,aAAa,CAAC,IAAI,CAAC,CAAA;AAC3B,CAAC;AAED,iEAAiE;AACjE,KAAK,UAAU,SAAS,CAAC,MAAc;IACrC,MAAM,aAAa,GAAG,MAAM,cAAc,EAAE,CAAA;IAC5C,MAAM,cAAc,CAAC,MAAM,CAAC,CAAA;IAC5B,IAAI,CAAC,aAAa;QAAE,MAAM,aAAa,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAA;AACnE,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,QAAQ;IACrB,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAA;IACnC,6EAA6E;IAC7E,IAAI,KAAK,EAAE,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,aAAa;QAAE,OAAM;IACpE,MAAM,WAAW,EAAE,CAAA;IAEnB,MAAM,YAAY,GAAG,MAAM,gBAAgB,EAAE,CAAA;IAC7C,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,mEAAmE;QACnE,IACE,YAAY,CAAC,MAAM,KAAK,SAAS;YACjC,YAAY,CAAC,MAAM,KAAK,SAAS,EACjC,CAAC;YACD,MAAM,SAAS,CACb,YAAY,CAAC,MAAM,KAAK,SAAS;gBAC/B,CAAC,CAAC,+DAA+D;gBACjE,CAAC,CAAC,sBAAsB,CAC3B,CAAA;QACH,CAAC;QACD,OAAM;IACR,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IAE9D,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACtC,IACE,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QACxB,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QACxD,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAC1D,CAAC;QACD,yEAAyE;QACzE,0DAA0D;QAC1D,IAAI,OAAO;YAAE,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;QACvC,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAA;IAChC,8EAA8E;IAC9E,8EAA8E;IAC9E,2CAA2C;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACnD,YAAY,CAAC,KAAK,CAAC,CAAA;QACnB,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;QAC1B,MAAM,eAAe,EAAE,CAAA;QACvB,MAAM,aAAa,CACjB,UAAU,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAC1G,CAAA;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC1D,MAAM,MAAM,GAAG,CAAC,YAAY,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QAE1D,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,YAAY,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YAC1E,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;YACvC,MAAM,YAAY,CAChB,KAAK,EACL,+BAA+B,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAC1D,CAAA;YACD,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;YAC1B,OAAM;QACR,CAAC;QAED,IAAI,OAAO,KAAK,qBAAqB,EAAE,CAAC;YACtC,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;YAC/C,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;oBACrD,YAAY,CAAC,KAAK,CAAC,CAAA;oBACnB,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;oBAC1B,MAAM,eAAe,EAAE,CAAA;oBACvB,MAAM,aAAa,CACjB,UAAU,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,YAAY,KAAK,wBAAwB,CACjG,CAAA;oBACD,OAAM;gBACR,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;YACD,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;YAC1B,MAAM,SAAS,CAAC,sBAAsB,CAAC,CAAA;YACvC,OAAM;QACR,CAAC;QAED,yDAAyD;QACzD,MAAM,YAAY,CAAC,KAAK,EAAE,eAAe,OAAO,EAAE,CAAC,CAAA;QACnD,MAAM,aAAa,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,YAAY,GAAG,MAAM,gBAAgB,EAAE,CAAA;IAC7C,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAA;QAC5E,IAAI,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,+EAA+E;IAC/E,0BAA0B;IAC1B,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IAC7D,IAAI,YAAY,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QAC3C,KAAK,CAAC,eAAe,CAAC,CAAA;QACtB,IAAI,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACrC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;QAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,+EAA+E;IAC/E,2DAA2D;IAC3D,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;IAE9D,4EAA4E;IAC5E,mDAAmD;IACnD,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IAE7E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAA;IACnC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAA;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEf,IAAI,MAA2C,CAAA;IAC/C,IAAI,CAAC;QACH,8EAA8E;QAC9E,0EAA0E;QAC1E,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAA;IACvE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,KAAK,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,EACJ,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,MAAM,EAAE,CAAC,GACV,GAAG,MAAM,CAAA;IAEV,IAAI,WAAW,GAAG,CAAC;QACjB,IAAI,CAAC,kBAAkB,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;IAC5D,IAAI,UAAU,GAAG,CAAC;QAAE,IAAI,CAAC,kBAAkB,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IAC7E,IAAI,WAAW,GAAG,CAAC;QACjB,IAAI,CAAC,kBAAkB,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;IAC5D,IAAI,aAAa,GAAG,CAAC;QACnB,IAAI,CAAC,kBAAkB,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;IAC9D,IAAI,WAAW,GAAG,CAAC;QACjB,IAAI,CAAC,kBAAkB,YAAY,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;IAC5D,IAAI,aAAa,GAAG,CAAC;QACnB,IAAI,CAAC,kBAAkB,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;IAE9D,6EAA6E;IAC7E,2EAA2E;IAC3E,IAAI,gBAAgB,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QAC7C,KAAK,CAAC,aAAa,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAA;QAC7C,IAAI,CACF,GAAG,CAAC,oEAAoE,CAAC,CAC1E,CAAA;QACD,IAAI,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAA;IAClE,CAAC;SAAM,IAAI,gBAAgB,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,4BAA4B,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IAClE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CACL,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAC1F,CAAA;IACD,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,kBAAkB,CAAC,CAAA;IACnE,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,WAAW,CAAA;QAC3C,IAAI,CACF,kBAAkB,YAAY,CAAC,YAAY,CAAC,WAC1C,aAAa,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,EACvD,EAAE,CACH,CAAA;QACD,2EAA2E;QAC3E,uEAAuE;QACvE,6CAA6C;QAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,WAEjB,CAAA;QACb,MAAM,QAAQ,GAAG,OAAO,EAAE,gBAAgB,IAAI,CAAC,CAAA;QAC/C,MAAM,OAAO,GAAG,OAAO,EAAE,eAAe,IAAI,CAAC,CAAA;QAC7C,IAAI,QAAQ,GAAG,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,CACF,GAAG,CACD,kBAAkB,QAAQ,sEAAsE,CACjG,CACF,CAAA;QACH,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,OAAO,OAAO,QAAQ,0BAA0B,CAAC,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAA;QACzE,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC7D,IAAI,CAAC,aAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC;IAED,MAAM,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,oBAAoB,EAAE;QACvD,aAAa,EAAE,WAAW;QAC1B,YAAY,EAAE,UAAU;QACxB,aAAa,EAAE,WAAW;QAC1B,eAAe,EAAE,aAAa;QAC9B,aAAa,EAAE,WAAW;QAC1B,eAAe,EAAE,aAAa;QAC9B,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC,CAAA;IAEF,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;AAC7B,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export type HacklabConfig = {
|
|
2
2
|
cursorApiKey?: string;
|
|
3
3
|
cursorEmail?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Consent for uploading Claude Code conversation data: 'none' | 'stats' |
|
|
6
|
+
* 'full'. Absent means never asked — see prompt-consent.ts, which owns the
|
|
7
|
+
* tiers and treats an unset value as "ask", never as a yes.
|
|
8
|
+
*/
|
|
9
|
+
promptStatsConsent?: string;
|
|
4
10
|
};
|
|
5
11
|
/** Where a resolved credential came from, so `config` can show what actually wins. */
|
|
6
12
|
export type CursorAuthSource = 'env' | 'config' | 'none';
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAID,sFAAsF;AACtF,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;AAExD,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,gBAAgB,CAAA;IAC9B,WAAW,EAAE,gBAAgB,CAAA;CAC9B,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CAgB7D;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAOzD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrE"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAazC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAA;AAY9D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;IACjC,MAAM,IAAI,GAAG,CACX,OAAe,EACf,WAA+B,EACS,EAAE;QAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAA;QAC7C,IAAI,QAAQ;YAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACtC,IAAI,WAAW;YAAE,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QAC/C,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAC5B,CAAC,CAAA;IAED,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IAC1E,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;IAErE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,CAAA;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAA;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAqB;IACpD,MAAM,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACtD,MAAM,SAAS,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AAC9E,CAAC"}
|