hacklab 0.22.3 → 26.921.2
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 +39 -415
- package/dist/index.js +317 -23
- package/package.json +22 -40
- package/LICENSE +0 -21
- package/dist/agent-handoff.d.ts +0 -51
- package/dist/agent-handoff.d.ts.map +0 -1
- package/dist/agent-handoff.js +0 -91
- package/dist/agent-handoff.js.map +0 -1
- package/dist/api-client.d.ts +0 -18
- package/dist/api-client.d.ts.map +0 -1
- package/dist/api-client.js +0 -40
- package/dist/api-client.js.map +0 -1
- package/dist/belt.d.ts +0 -25
- package/dist/belt.d.ts.map +0 -1
- package/dist/belt.js +0 -113
- package/dist/belt.js.map +0 -1
- package/dist/card.d.ts +0 -66
- package/dist/card.d.ts.map +0 -1
- package/dist/card.js +0 -151
- package/dist/card.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -238
- package/dist/cli.js.map +0 -1
- package/dist/commands/book.d.ts +0 -14
- package/dist/commands/book.d.ts.map +0 -1
- package/dist/commands/book.js +0 -90
- package/dist/commands/book.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -36
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/chat.js +0 -642
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/config.d.ts +0 -2
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js +0 -84
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/daemon.d.ts +0 -19
- package/dist/commands/daemon.d.ts.map +0 -1
- package/dist/commands/daemon.js +0 -72
- package/dist/commands/daemon.js.map +0 -1
- package/dist/commands/drop.d.ts +0 -12
- package/dist/commands/drop.d.ts.map +0 -1
- package/dist/commands/drop.js +0 -103
- package/dist/commands/drop.js.map +0 -1
- package/dist/commands/drops.d.ts +0 -9
- package/dist/commands/drops.d.ts.map +0 -1
- package/dist/commands/drops.js +0 -96
- package/dist/commands/drops.js.map +0 -1
- package/dist/commands/essay.d.ts +0 -40
- package/dist/commands/essay.d.ts.map +0 -1
- package/dist/commands/essay.js +0 -651
- package/dist/commands/essay.js.map +0 -1
- package/dist/commands/hackathon.d.ts +0 -2
- package/dist/commands/hackathon.d.ts.map +0 -1
- package/dist/commands/hackathon.js +0 -893
- package/dist/commands/hackathon.js.map +0 -1
- package/dist/commands/hacker.d.ts +0 -2
- package/dist/commands/hacker.d.ts.map +0 -1
- package/dist/commands/hacker.js +0 -87
- package/dist/commands/hacker.js.map +0 -1
- package/dist/commands/jobs.d.ts +0 -18
- package/dist/commands/jobs.d.ts.map +0 -1
- package/dist/commands/jobs.js +0 -138
- package/dist/commands/jobs.js.map +0 -1
- package/dist/commands/keys.d.ts +0 -2
- package/dist/commands/keys.d.ts.map +0 -1
- package/dist/commands/keys.js +0 -138
- package/dist/commands/keys.js.map +0 -1
- package/dist/commands/login.d.ts +0 -83
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -236
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -2
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js +0 -22
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/org-jobs.d.ts +0 -50
- package/dist/commands/org-jobs.d.ts.map +0 -1
- package/dist/commands/org-jobs.js +0 -383
- package/dist/commands/org-jobs.js.map +0 -1
- package/dist/commands/org.d.ts +0 -67
- package/dist/commands/org.d.ts.map +0 -1
- package/dist/commands/org.js +0 -1244
- package/dist/commands/org.js.map +0 -1
- package/dist/commands/ping.d.ts +0 -2
- package/dist/commands/ping.d.ts.map +0 -1
- package/dist/commands/ping.js +0 -50
- package/dist/commands/ping.js.map +0 -1
- package/dist/commands/profile.d.ts +0 -72
- package/dist/commands/profile.d.ts.map +0 -1
- package/dist/commands/profile.js +0 -672
- package/dist/commands/profile.js.map +0 -1
- package/dist/commands/project.d.ts +0 -2
- package/dist/commands/project.d.ts.map +0 -1
- package/dist/commands/project.js +0 -583
- package/dist/commands/project.js.map +0 -1
- package/dist/commands/referral.d.ts +0 -6
- package/dist/commands/referral.d.ts.map +0 -1
- package/dist/commands/referral.js +0 -93
- package/dist/commands/referral.js.map +0 -1
- package/dist/commands/rtfm.d.ts +0 -9
- package/dist/commands/rtfm.d.ts.map +0 -1
- package/dist/commands/rtfm.js +0 -114
- package/dist/commands/rtfm.js.map +0 -1
- package/dist/commands/scan.d.ts +0 -13
- package/dist/commands/scan.d.ts.map +0 -1
- package/dist/commands/scan.js +0 -286
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/scout.d.ts +0 -18
- package/dist/commands/scout.d.ts.map +0 -1
- package/dist/commands/scout.js +0 -232
- package/dist/commands/scout.js.map +0 -1
- package/dist/commands/setup-rail.d.ts +0 -58
- package/dist/commands/setup-rail.d.ts.map +0 -1
- package/dist/commands/setup-rail.js +0 -135
- package/dist/commands/setup-rail.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -29
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -442
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/sync.d.ts +0 -9
- package/dist/commands/sync.d.ts.map +0 -1
- package/dist/commands/sync.js +0 -345
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/update.d.ts +0 -2
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/commands/update.js +0 -92
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/whoami.d.ts +0 -2
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js +0 -41
- package/dist/commands/whoami.js.map +0 -1
- package/dist/config.d.ts +0 -78
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -93
- package/dist/config.js.map +0 -1
- package/dist/daily-sync.d.ts +0 -150
- package/dist/daily-sync.d.ts.map +0 -1
- package/dist/daily-sync.js +0 -665
- package/dist/daily-sync.js.map +0 -1
- package/dist/dossier.d.ts +0 -73
- package/dist/dossier.d.ts.map +0 -1
- package/dist/dossier.js +0 -141
- package/dist/dossier.js.map +0 -1
- package/dist/field-normalize.d.ts +0 -4
- package/dist/field-normalize.d.ts.map +0 -1
- package/dist/field-normalize.js +0 -8
- package/dist/field-normalize.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/job-fields.d.ts +0 -47
- package/dist/job-fields.d.ts.map +0 -1
- package/dist/job-fields.js +0 -148
- package/dist/job-fields.js.map +0 -1
- package/dist/machine.d.ts +0 -15
- package/dist/machine.d.ts.map +0 -1
- package/dist/machine.js +0 -64
- package/dist/machine.js.map +0 -1
- package/dist/org-fields.d.ts +0 -57
- package/dist/org-fields.d.ts.map +0 -1
- package/dist/org-fields.js +0 -167
- package/dist/org-fields.js.map +0 -1
- package/dist/posthog.d.ts +0 -38
- package/dist/posthog.d.ts.map +0 -1
- package/dist/posthog.js +0 -224
- package/dist/posthog.js.map +0 -1
- package/dist/project-fields.d.ts +0 -40
- package/dist/project-fields.d.ts.map +0 -1
- package/dist/project-fields.js +0 -79
- package/dist/project-fields.js.map +0 -1
- package/dist/prompt-consent.d.ts +0 -73
- package/dist/prompt-consent.d.ts.map +0 -1
- package/dist/prompt-consent.js +0 -191
- package/dist/prompt-consent.js.map +0 -1
- package/dist/prompt-stats.d.ts +0 -226
- package/dist/prompt-stats.d.ts.map +0 -1
- package/dist/prompt-stats.js +0 -561
- package/dist/prompt-stats.js.map +0 -1
- package/dist/referral.d.ts +0 -14
- package/dist/referral.d.ts.map +0 -1
- package/dist/referral.js +0 -28
- package/dist/referral.js.map +0 -1
- package/dist/registry.d.ts +0 -15
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -180
- package/dist/registry.js.map +0 -1
- package/dist/resolve-command.d.ts +0 -20
- package/dist/resolve-command.d.ts.map +0 -1
- package/dist/resolve-command.js +0 -21
- package/dist/resolve-command.js.map +0 -1
- package/dist/scanners/antigravity.d.ts +0 -41
- package/dist/scanners/antigravity.d.ts.map +0 -1
- package/dist/scanners/antigravity.js +0 -210
- package/dist/scanners/antigravity.js.map +0 -1
- package/dist/scanners/github-copilot-telemetry.d.ts +0 -23
- package/dist/scanners/github-copilot-telemetry.d.ts.map +0 -1
- package/dist/scanners/github-copilot-telemetry.js +0 -220
- package/dist/scanners/github-copilot-telemetry.js.map +0 -1
- package/dist/scanners/github-copilot.d.ts +0 -68
- package/dist/scanners/github-copilot.d.ts.map +0 -1
- package/dist/scanners/github-copilot.js +0 -262
- package/dist/scanners/github-copilot.js.map +0 -1
- package/dist/scanners/incremental.d.ts +0 -282
- package/dist/scanners/incremental.d.ts.map +0 -1
- package/dist/scanners/incremental.js +0 -788
- package/dist/scanners/incremental.js.map +0 -1
- package/dist/scanners/index.d.ts +0 -116
- package/dist/scanners/index.d.ts.map +0 -1
- package/dist/scanners/index.js +0 -726
- package/dist/scanners/index.js.map +0 -1
- package/dist/scanners/sqlite.d.ts +0 -18
- package/dist/scanners/sqlite.d.ts.map +0 -1
- package/dist/scanners/sqlite.js +0 -63
- package/dist/scanners/sqlite.js.map +0 -1
- package/dist/scanners/util.d.ts +0 -112
- package/dist/scanners/util.d.ts.map +0 -1
- package/dist/scanners/util.js +0 -167
- package/dist/scanners/util.js.map +0 -1
- package/dist/session.d.ts +0 -106
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -191
- package/dist/session.js.map +0 -1
- package/dist/share-card-colors.d.ts +0 -19
- package/dist/share-card-colors.d.ts.map +0 -1
- package/dist/share-card-colors.js +0 -36
- package/dist/share-card-colors.js.map +0 -1
- package/dist/share-card.d.ts +0 -31
- package/dist/share-card.d.ts.map +0 -1
- package/dist/share-card.js +0 -380
- package/dist/share-card.js.map +0 -1
- package/dist/share.d.ts +0 -17
- package/dist/share.d.ts.map +0 -1
- package/dist/share.js +0 -75
- package/dist/share.js.map +0 -1
- package/dist/sync.d.ts +0 -100
- package/dist/sync.d.ts.map +0 -1
- package/dist/sync.js +0 -304
- package/dist/sync.js.map +0 -1
- package/dist/ui.d.ts +0 -33
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js +0 -127
- package/dist/ui.js.map +0 -1
- package/dist/utils/npmGlobal.d.ts +0 -30
- package/dist/utils/npmGlobal.d.ts.map +0 -1
- package/dist/utils/npmGlobal.js +0 -69
- package/dist/utils/npmGlobal.js.map +0 -1
- package/dist/utils/openBrowser.d.ts +0 -14
- package/dist/utils/openBrowser.d.ts.map +0 -1
- package/dist/utils/openBrowser.js +0 -47
- package/dist/utils/openBrowser.js.map +0 -1
- package/dist/utils/updateCheck.d.ts +0 -16
- package/dist/utils/updateCheck.d.ts.map +0 -1
- package/dist/utils/updateCheck.js +0 -111
- package/dist/utils/updateCheck.js.map +0 -1
- package/dist/utils/waitForEnter.d.ts +0 -12
- package/dist/utils/waitForEnter.d.ts.map +0 -1
- package/dist/utils/waitForEnter.js +0 -43
- package/dist/utils/waitForEnter.js.map +0 -1
package/dist/api-client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE1C,+EAA+E;AAC/E,uEAAuE;AACvE,8EAA8E;AAE9E,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IACzD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAa;IAChD,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,IAAI;YAAE,aAAa,CAAC,cAAc,EAAE,eAAe,CAAC,CAAA;QACxD,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,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,IAA6C,EAC7C,OAAgB;IAEhB,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,mCAAmC,CAAA;IAC9D,OAAO,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,mBAAmB,MAAM,GAAG,CAAA;AAC7D,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAa,EACb,OAAgB;IAEhB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAExC,CAAA;IACR,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACnD,CAAC"}
|
package/dist/belt.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export type BeltColor = 'white' | 'orange' | 'red' | 'blue' | 'cyan' | 'yellow' | 'lime' | 'green' | 'pink' | 'purple' | 'black';
|
|
2
|
-
export type Title = 'gaijin' | 'deshi' | 'ronin' | 'shinobi' | 'samurai' | 'senpai' | 'tatsujin' | 'kensei' | 'oni' | 'ryujin';
|
|
3
|
-
export type DanTitle = 'shodan' | 'nidan' | 'sandan' | 'yondan' | 'godan' | 'rokudan' | 'nanadan' | 'hachidan' | 'kudan' | 'judan';
|
|
4
|
-
export type GrandMasterTitle = 'shihan' | 'hanshi' | 'meijin' | 'oyama';
|
|
5
|
-
/** Convert raw token count to Pyro XP. 1,000 tokens = 1 XP. */
|
|
6
|
-
export declare function tokensToXp(tokens: number): number;
|
|
7
|
-
/** Convert total XP to level (fractional). */
|
|
8
|
-
export declare function xpToLevel(xp: number): number;
|
|
9
|
-
/** Convert level to minimum XP required. */
|
|
10
|
-
export declare function levelToMinXp(level: number): number;
|
|
11
|
-
/** Get the integer level (floor of fractional level). */
|
|
12
|
-
export declare function getLevel(xp: number): number;
|
|
13
|
-
/** Get belt color for a given level. */
|
|
14
|
-
export declare function getBeltColor(level: number): BeltColor;
|
|
15
|
-
/** Get title for a given level. */
|
|
16
|
-
export declare function getTitle(level: number): Title | DanTitle | GrandMasterTitle;
|
|
17
|
-
export type BeltProgress = {
|
|
18
|
-
level: number;
|
|
19
|
-
title: Title | DanTitle | GrandMasterTitle;
|
|
20
|
-
beltColor: BeltColor;
|
|
21
|
-
progressPercent: number;
|
|
22
|
-
};
|
|
23
|
-
/** Belt info for a raw token total (pyro-only — correct for a fresh account). */
|
|
24
|
-
export declare function beltForTokens(tokensTotal: number): BeltProgress;
|
|
25
|
-
//# sourceMappingURL=belt.d.ts.map
|
package/dist/belt.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"belt.d.ts","sourceRoot":"","sources":["../src/belt.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,QAAQ,GACR,OAAO,CAAA;AAEX,MAAM,MAAM,KAAK,GACb,QAAQ,GACR,OAAO,GACP,OAAO,GACP,SAAS,GACT,SAAS,GACT,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,KAAK,GACL,QAAQ,CAAA;AAEZ,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,SAAS,GACT,SAAS,GACT,UAAU,GACV,OAAO,GACP,OAAO,CAAA;AAEX,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAqCvE,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,yDAAyD;AACzD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAMrD;AAED,mCAAmC;AACnC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,gBAAgB,CAkB3E;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,gBAAgB,CAAA;IAC1C,SAAS,EAAE,SAAS,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAgB/D"}
|
package/dist/belt.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
// Belt / level math — ported verbatim from @hacklab/db `levels.ts` so the CLI
|
|
2
|
-
// can render the share card instantly (locally) without waiting on the server.
|
|
3
|
-
// The CLI is a standalone published package and must not pull in @hacklab/db
|
|
4
|
-
// (drizzle/pg/etc.), so we copy the small, stable curve here.
|
|
5
|
-
//
|
|
6
|
-
// One curve: xp(level) = 23 × level^3.32 up to level 100, exponential above.
|
|
7
|
-
// Pyro XP = tokens / 1000. For a brand-new account, hacker + mason XP are 0, so
|
|
8
|
-
// belt XP == pyro XP — which is exactly what the server computes right after
|
|
9
|
-
// the first sync. Kept in sync via belt.test.ts (anchored to the known points).
|
|
10
|
-
const K = 3.32;
|
|
11
|
-
const A = 23;
|
|
12
|
-
const LEVEL_100_XP = 100_000_000; // 100M XP
|
|
13
|
-
const BELT_TIERS = [
|
|
14
|
-
{ minLevel: 0, color: 'white', title: 'gaijin' },
|
|
15
|
-
{ minLevel: 10, color: 'orange', title: 'deshi' },
|
|
16
|
-
{ minLevel: 20, color: 'red', title: 'ronin' },
|
|
17
|
-
{ minLevel: 30, color: 'blue', title: 'shinobi' },
|
|
18
|
-
{ minLevel: 40, color: 'cyan', title: 'samurai' },
|
|
19
|
-
{ minLevel: 50, color: 'yellow', title: 'senpai' },
|
|
20
|
-
{ minLevel: 60, color: 'lime', title: 'tatsujin' },
|
|
21
|
-
{ minLevel: 70, color: 'green', title: 'kensei' },
|
|
22
|
-
{ minLevel: 80, color: 'pink', title: 'oni' },
|
|
23
|
-
{ minLevel: 90, color: 'purple', title: 'ryujin' },
|
|
24
|
-
];
|
|
25
|
-
const DAN_TITLES = [
|
|
26
|
-
'shodan',
|
|
27
|
-
'nidan',
|
|
28
|
-
'sandan',
|
|
29
|
-
'yondan',
|
|
30
|
-
'godan',
|
|
31
|
-
'rokudan',
|
|
32
|
-
'nanadan',
|
|
33
|
-
'hachidan',
|
|
34
|
-
'kudan',
|
|
35
|
-
'judan',
|
|
36
|
-
];
|
|
37
|
-
const GRAND_MASTER_TIERS = [
|
|
38
|
-
{ minLevel: 200, title: 'shihan' },
|
|
39
|
-
{ minLevel: 300, title: 'hanshi' },
|
|
40
|
-
{ minLevel: 400, title: 'meijin' },
|
|
41
|
-
{ minLevel: 500, title: 'oyama' },
|
|
42
|
-
];
|
|
43
|
-
/** Convert raw token count to Pyro XP. 1,000 tokens = 1 XP. */
|
|
44
|
-
export function tokensToXp(tokens) {
|
|
45
|
-
return Math.floor(tokens / 1_000);
|
|
46
|
-
}
|
|
47
|
-
/** Convert total XP to level (fractional). */
|
|
48
|
-
export function xpToLevel(xp) {
|
|
49
|
-
if (xp <= 0)
|
|
50
|
-
return 0;
|
|
51
|
-
if (xp >= LEVEL_100_XP) {
|
|
52
|
-
return 100 + 100 * Math.log10(xp / LEVEL_100_XP);
|
|
53
|
-
}
|
|
54
|
-
return (xp / A) ** (1 / K);
|
|
55
|
-
}
|
|
56
|
-
/** Convert level to minimum XP required. */
|
|
57
|
-
export function levelToMinXp(level) {
|
|
58
|
-
if (level <= 0)
|
|
59
|
-
return 0;
|
|
60
|
-
if (level >= 100) {
|
|
61
|
-
return Math.round(LEVEL_100_XP * 10 ** ((level - 100) / 100));
|
|
62
|
-
}
|
|
63
|
-
return Math.round(A * level ** K);
|
|
64
|
-
}
|
|
65
|
-
/** Get the integer level (floor of fractional level). */
|
|
66
|
-
export function getLevel(xp) {
|
|
67
|
-
return Math.floor(xpToLevel(xp));
|
|
68
|
-
}
|
|
69
|
-
/** Get belt color for a given level. */
|
|
70
|
-
export function getBeltColor(level) {
|
|
71
|
-
if (level >= 100)
|
|
72
|
-
return 'black';
|
|
73
|
-
for (let i = BELT_TIERS.length - 1; i >= 0; i--) {
|
|
74
|
-
if (level >= BELT_TIERS[i].minLevel)
|
|
75
|
-
return BELT_TIERS[i].color;
|
|
76
|
-
}
|
|
77
|
-
return 'white';
|
|
78
|
-
}
|
|
79
|
-
/** Get title for a given level. */
|
|
80
|
-
export function getTitle(level) {
|
|
81
|
-
if (level >= 200) {
|
|
82
|
-
for (let i = GRAND_MASTER_TIERS.length - 1; i >= 0; i--) {
|
|
83
|
-
if (level >= GRAND_MASTER_TIERS[i].minLevel)
|
|
84
|
-
return GRAND_MASTER_TIERS[i].title;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (level >= 100) {
|
|
88
|
-
const danIndex = Math.min(Math.floor((level - 100) / 10), DAN_TITLES.length - 1);
|
|
89
|
-
return DAN_TITLES[danIndex];
|
|
90
|
-
}
|
|
91
|
-
for (let i = BELT_TIERS.length - 1; i >= 0; i--) {
|
|
92
|
-
if (level >= BELT_TIERS[i].minLevel)
|
|
93
|
-
return BELT_TIERS[i].title;
|
|
94
|
-
}
|
|
95
|
-
return 'gaijin';
|
|
96
|
-
}
|
|
97
|
-
/** Belt info for a raw token total (pyro-only — correct for a fresh account). */
|
|
98
|
-
export function beltForTokens(tokensTotal) {
|
|
99
|
-
const xp = tokensToXp(tokensTotal);
|
|
100
|
-
const level = getLevel(xp);
|
|
101
|
-
const currentLevelXp = levelToMinXp(level);
|
|
102
|
-
const nextLevelXp = levelToMinXp(level + 1);
|
|
103
|
-
const xpIntoLevel = xp - currentLevelXp;
|
|
104
|
-
const xpNeeded = nextLevelXp - currentLevelXp;
|
|
105
|
-
const progressPercent = xpNeeded > 0 ? Math.min(Math.round((xpIntoLevel / xpNeeded) * 100), 100) : 0;
|
|
106
|
-
return {
|
|
107
|
-
level,
|
|
108
|
-
title: getTitle(level),
|
|
109
|
-
beltColor: getBeltColor(level),
|
|
110
|
-
progressPercent,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=belt.js.map
|
package/dist/belt.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"belt.js","sourceRoot":"","sources":["../src/belt.ts"],"names":[],"mappings":"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"}
|
package/dist/card.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export type HackerCardData = {
|
|
2
|
-
handle: string;
|
|
3
|
-
displayName: string | null;
|
|
4
|
-
bio: string | null;
|
|
5
|
-
joinedAt: string;
|
|
6
|
-
claimedAt: string | null;
|
|
7
|
-
level: number;
|
|
8
|
-
tokensTotal: number;
|
|
9
|
-
tokens30d: number;
|
|
10
|
-
estimatedCost: number;
|
|
11
|
-
rank: number | null;
|
|
12
|
-
topModels30d: {
|
|
13
|
-
model: string;
|
|
14
|
-
tokens: number;
|
|
15
|
-
pct: number;
|
|
16
|
-
}[];
|
|
17
|
-
currentStreak: number;
|
|
18
|
-
longestStreak: number;
|
|
19
|
-
activeDays30: number;
|
|
20
|
-
activity30: number[];
|
|
21
|
-
counts: {
|
|
22
|
-
projects: number;
|
|
23
|
-
essays: number;
|
|
24
|
-
drops: number;
|
|
25
|
-
followers: number;
|
|
26
|
-
};
|
|
27
|
-
recent: {
|
|
28
|
-
projects: {
|
|
29
|
-
title: string;
|
|
30
|
-
description: string | null;
|
|
31
|
-
}[];
|
|
32
|
-
essays: {
|
|
33
|
-
title: string;
|
|
34
|
-
publishedAt: string | null;
|
|
35
|
-
}[];
|
|
36
|
-
drops: {
|
|
37
|
-
text: string;
|
|
38
|
-
createdAt: string;
|
|
39
|
-
}[];
|
|
40
|
-
};
|
|
41
|
-
links: {
|
|
42
|
-
profile: string;
|
|
43
|
-
website: string | null;
|
|
44
|
-
github: string | null;
|
|
45
|
-
x: string | null;
|
|
46
|
-
};
|
|
47
|
-
openToWork: boolean;
|
|
48
|
-
};
|
|
49
|
-
export type RenderCardOptions = {
|
|
50
|
-
/** Terminal columns. Clamped to [MIN_WIDTH, DESIGN_WIDTH]. */
|
|
51
|
-
columns?: number;
|
|
52
|
-
now?: Date;
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* Render the full one-screen card as an array of lines (caller joins with \n).
|
|
56
|
-
* Pure: no I/O, deterministic given `now`. Every user-supplied string is passed
|
|
57
|
-
* through stripControl before it reaches the terminal.
|
|
58
|
-
*/
|
|
59
|
-
export declare function renderCard(card: HackerCardData, opts?: RenderCardOptions): string[];
|
|
60
|
-
/**
|
|
61
|
-
* The compact in-chat card (`/who`): 4 lines, no rules, no sparkline. Same
|
|
62
|
-
* strip discipline. Returned as separate lines so the chat renderer can push
|
|
63
|
-
* them as one Entry per row (preserving the one-row-per-entry invariant).
|
|
64
|
-
*/
|
|
65
|
-
export declare function renderCompact(card: HackerCardData): string[];
|
|
66
|
-
//# sourceMappingURL=card.d.ts.map
|
package/dist/card.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC9D,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9E,MAAM,EAAE;QACN,QAAQ,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,EAAE,CAAA;QACzD,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,EAAE,CAAA;QACvD,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC7C,CAAA;IACD,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACjB,CAAA;IACD,UAAU,EAAE,OAAO,CAAA;CACpB,CAAA;AAQD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,IAAI,CAAA;CACX,CAAA;AAyFD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE,iBAAsB,GAC3B,MAAM,EAAE,CAiHV;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAY5D"}
|
package/dist/card.js
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { getTitle } from './belt.js';
|
|
2
|
-
import { formatTokens } from './scanners/util.js';
|
|
3
|
-
import { dim, displayWidth, mint, padEndTo, rankColor, stripControl, truncateToWidth, white, } from './ui.js';
|
|
4
|
-
const DESIGN_WIDTH = 68;
|
|
5
|
-
const MIN_WIDTH = 45; // below this the fixed 30d row can't fit; wrapping is accepted
|
|
6
|
-
/** 8 log-scaled buckets for the 30-day sparkline. Zero renders dim, lit cells mint. */
|
|
7
|
-
const SPARK = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
8
|
-
function resolveWidth(columns) {
|
|
9
|
-
const cols = columns ?? DESIGN_WIDTH;
|
|
10
|
-
return Math.max(MIN_WIDTH, Math.min(DESIGN_WIDTH, cols));
|
|
11
|
-
}
|
|
12
|
-
/** ISO string → `YYYY-MM-DD`. */
|
|
13
|
-
function ymd(iso) {
|
|
14
|
-
return iso.slice(0, 10);
|
|
15
|
-
}
|
|
16
|
-
function ageDays(iso, now) {
|
|
17
|
-
return Math.max(0, Math.floor((now.getTime() - Date.parse(iso)) / 86_400_000));
|
|
18
|
-
}
|
|
19
|
-
/** A left segment and a right segment on one line, right-aligned to `width`. */
|
|
20
|
-
function justify(width, leftColored, rightColored) {
|
|
21
|
-
const gap = Math.max(1, width - displayWidth(leftColored) - displayWidth(rightColored));
|
|
22
|
-
return leftColored + ' '.repeat(gap) + rightColored;
|
|
23
|
-
}
|
|
24
|
-
function rule(width) {
|
|
25
|
-
return dim('─'.repeat(width));
|
|
26
|
-
}
|
|
27
|
-
/** `████ L32 SHINOBI` — coloured band + dim romaji rank. Belt derived from level. */
|
|
28
|
-
function beltBadge(level) {
|
|
29
|
-
const band = rankColor(level, '████');
|
|
30
|
-
const label = dim(` L${level} ${getTitle(level).toUpperCase()}`);
|
|
31
|
-
return band + label;
|
|
32
|
-
}
|
|
33
|
-
function sparkline(values) {
|
|
34
|
-
const max = Math.max(0, ...values);
|
|
35
|
-
const denom = Math.log2(max + 1);
|
|
36
|
-
return values
|
|
37
|
-
.map((v) => {
|
|
38
|
-
if (v <= 0)
|
|
39
|
-
return dim('▁');
|
|
40
|
-
const frac = denom > 0 ? Math.log2(v + 1) / denom : 0;
|
|
41
|
-
const idx = Math.min(SPARK.length - 1, Math.max(0, Math.round(frac * (SPARK.length - 1))));
|
|
42
|
-
return mint(SPARK[idx] ?? '█');
|
|
43
|
-
})
|
|
44
|
-
.join('');
|
|
45
|
-
}
|
|
46
|
-
/** A `label value` row; the label is dim, the value plain, truncated to width. */
|
|
47
|
-
function labelled(width, label, value) {
|
|
48
|
-
const head = dim(padEndTo(label, 8)); // "joined ", "streak ", …
|
|
49
|
-
const budget = width - displayWidth(head);
|
|
50
|
-
return head + truncateToWidth(value, budget);
|
|
51
|
-
}
|
|
52
|
-
/** A recent-list section: `HEADER N` then rows, or `HEADER 0 nothing yet`. */
|
|
53
|
-
function section(width, label, total, rows) {
|
|
54
|
-
if (total === 0)
|
|
55
|
-
return [dim(`${label} 0 nothing yet`)];
|
|
56
|
-
return [`${label} ${total}`, ...rows.map((r) => truncateToWidth(r, width))];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Projects/essays row-budget rule: ≤3 rows below the header. When more than 3
|
|
60
|
-
* exist, show 2 items + `+N more`; otherwise show them all.
|
|
61
|
-
*/
|
|
62
|
-
function recentRows(total, items, row) {
|
|
63
|
-
if (total > 3) {
|
|
64
|
-
return [...items.slice(0, 2).map(row), ` +${total - 2} more`];
|
|
65
|
-
}
|
|
66
|
-
return items.map(row);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Render the full one-screen card as an array of lines (caller joins with \n).
|
|
70
|
-
* Pure: no I/O, deterministic given `now`. Every user-supplied string is passed
|
|
71
|
-
* through stripControl before it reaches the terminal.
|
|
72
|
-
*/
|
|
73
|
-
export function renderCard(card, opts = {}) {
|
|
74
|
-
const width = resolveWidth(opts.columns);
|
|
75
|
-
const now = opts.now ?? new Date();
|
|
76
|
-
const lines = [];
|
|
77
|
-
// Line 1 — identity + belt.
|
|
78
|
-
const name = card.displayName ? ` · ${stripControl(card.displayName)}` : '';
|
|
79
|
-
const identity = white(truncateToWidth(`${stripControl(card.handle)}${name}`, width - displayWidth(beltBadge(card.level)) - 1));
|
|
80
|
-
lines.push(justify(width, identity, beltBadge(card.level)));
|
|
81
|
-
// Line 2 — bio (left) + open-to-work dot (right). Skipped when both absent.
|
|
82
|
-
const bio = card.bio
|
|
83
|
-
? truncateToWidth(stripControl(card.bio), width - 16)
|
|
84
|
-
: '';
|
|
85
|
-
const otw = card.openToWork ? `${mint('●')} open to work` : '';
|
|
86
|
-
if (bio || otw)
|
|
87
|
-
lines.push(justify(width, bio, otw));
|
|
88
|
-
lines.push(rule(width));
|
|
89
|
-
// Identity block.
|
|
90
|
-
const claimed = card.claimedAt
|
|
91
|
-
? `claimed ${ymd(card.claimedAt)}`
|
|
92
|
-
: 'not claimed yet';
|
|
93
|
-
const rank = card.rank != null ? ` rank #${card.rank}` : '';
|
|
94
|
-
lines.push(labelled(width, 'joined', `${ymd(card.joinedAt)} (${ageDays(card.joinedAt, now)}d) ${claimed}${rank}`));
|
|
95
|
-
// Activity block, with the two null-state collapses.
|
|
96
|
-
if (card.tokensTotal === 0) {
|
|
97
|
-
lines.push(dim('no activity yet. run hacklab sync to bank the proof.'));
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
lines.push(labelled(width, 'streak', `${card.currentStreak}d current · ${card.longestStreak}d longest active ${card.activeDays30}/30d`));
|
|
101
|
-
const cost = `$${Math.round(card.estimatedCost).toLocaleString('en-US')} est. cost`;
|
|
102
|
-
lines.push(labelled(width, 'tokens', `${formatTokens(card.tokensTotal)} burned · ${formatTokens(card.tokens30d)} last 30d · ${cost}`));
|
|
103
|
-
// Models + sparkline collapse when there's no 30-day activity.
|
|
104
|
-
if (card.tokens30d > 0) {
|
|
105
|
-
const models = card.topModels30d
|
|
106
|
-
.slice(0, 2)
|
|
107
|
-
.map((m) => `${m.model} ${m.pct}%`)
|
|
108
|
-
.join(' · ');
|
|
109
|
-
if (models)
|
|
110
|
-
lines.push(labelled(width, 'models', models));
|
|
111
|
-
lines.push(dim(padEndTo('30d', 8)) + sparkline(card.activity30));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
lines.push(rule(width));
|
|
115
|
-
// Recent work.
|
|
116
|
-
lines.push(...section(width, 'PROJECTS', card.counts.projects, recentRows(card.counts.projects, card.recent.projects, (p) => ` ${padEndTo(truncateToWidth(stripControl(p.title), 16), 16)} ${stripControl(p.description ?? '')}`)));
|
|
117
|
-
lines.push(...section(width, 'ESSAYS', card.counts.essays, recentRows(card.counts.essays, card.recent.essays, (e) => ` ${e.publishedAt ? ymd(e.publishedAt) : ' '} ${stripControl(e.title)}`)));
|
|
118
|
-
// Drops: 1 item, no "+N more"; the count lives in the header.
|
|
119
|
-
if (card.counts.drops === 0) {
|
|
120
|
-
lines.push(dim('DROPS 0 nothing yet'));
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
const last = card.recent.drops[0];
|
|
124
|
-
lines.push(`DROPS ${card.counts.drops}${last ? ` · last ${ymd(last.createdAt)}` : ''}`);
|
|
125
|
-
if (last) {
|
|
126
|
-
lines.push(truncateToWidth(` "${stripControl(last.text)}"`, width));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
lines.push(rule(width));
|
|
130
|
-
lines.push(dim(`--json for the full payload · hacklab.so/${card.handle}`));
|
|
131
|
-
return lines;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* The compact in-chat card (`/who`): 4 lines, no rules, no sparkline. Same
|
|
135
|
-
* strip discipline. Returned as separate lines so the chat renderer can push
|
|
136
|
-
* them as one Entry per row (preserving the one-row-per-entry invariant).
|
|
137
|
-
*/
|
|
138
|
-
export function renderCompact(card) {
|
|
139
|
-
const name = card.displayName ? ` · ${stripControl(card.displayName)}` : '';
|
|
140
|
-
const otw = card.openToWork ? ` · ${mint('●')} open to work` : '';
|
|
141
|
-
const joined = card.claimedAt
|
|
142
|
-
? `joined ${ageDays(card.claimedAt, new Date())}d ago`
|
|
143
|
-
: 'not claimed yet';
|
|
144
|
-
return [
|
|
145
|
-
`${white(stripControl(card.handle))}${name} · ${beltBadge(card.level)}${otw}`,
|
|
146
|
-
`${formatTokens(card.tokensTotal)} tokens · ${formatTokens(card.tokens30d)}/30d · ${card.currentStreak}d streak · ${joined}`,
|
|
147
|
-
`${card.counts.projects} projects · ${card.counts.essays} essays · ${card.counts.drops} drops`,
|
|
148
|
-
dim(`hacklab.so/${card.handle}`),
|
|
149
|
-
];
|
|
150
|
-
}
|
|
151
|
-
//# sourceMappingURL=card.js.map
|
package/dist/card.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
DELETED
package/dist/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
// The real CLI. Loaded via a dynamic import from index.ts *after* its Node
|
|
2
|
-
// version guard passes — so the Node 20+ APIs these imports reach (e.g.
|
|
3
|
-
// @clack/core's `styleText` from node:util) never link on an unsupported Node.
|
|
4
|
-
import { createRequire } from 'node:module';
|
|
5
|
-
import { clearSyncPaused, readSyncPaused } from './daily-sync.js';
|
|
6
|
-
import { captureException, maybePrintTelemetryNotice, shutdownTelemetry, } from './posthog.js';
|
|
7
|
-
import { findCommand } from './registry.js';
|
|
8
|
-
import { resolveCommand } from './resolve-command.js';
|
|
9
|
-
import { HACKLAB_ENVIRONMENTS, loadSession, resolveHacklabEnv, } from './session.js';
|
|
10
|
-
import { banner, bold, dim } from './ui.js';
|
|
11
|
-
import { notifyIfOutdated } from './utils/updateCheck.js';
|
|
12
|
-
// Single source of the published version: read it from package.json (one level
|
|
13
|
-
// up from this module in both `dist/` and `src/`) instead of hardcoding a string
|
|
14
|
-
// that silently drifts from the real package version. `createRequire` resolves
|
|
15
|
-
// JSON the same way under tsx (dev) and the compiled bin.
|
|
16
|
-
const require = createRequire(import.meta.url);
|
|
17
|
-
const { version: VERSION } = require('../package.json');
|
|
18
|
-
/**
|
|
19
|
-
* The global flags, each mapping onto the env var the rest of the CLI already
|
|
20
|
-
* reads. Going through the env is what makes precedence fall out for free: the
|
|
21
|
-
* flag overwrites any inherited value, and the readers (getAppUrl,
|
|
22
|
-
* resolveCursorAuth) prefer the env over the config file. It also means a value
|
|
23
|
-
* passed once on the command line reaches anything the command shells out to.
|
|
24
|
-
*/
|
|
25
|
-
const GLOBAL_FLAGS = {
|
|
26
|
-
'--env': (value) => {
|
|
27
|
-
const env = resolveHacklabEnv(value);
|
|
28
|
-
if (!env) {
|
|
29
|
-
console.error(`--env must be one of: ${Object.keys(HACKLAB_ENVIRONMENTS).join(', ')} (abbreviations like dev/prod/stag work)`);
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
process.env.HACKLAB_APP_URL = HACKLAB_ENVIRONMENTS[env];
|
|
33
|
-
},
|
|
34
|
-
'--cursor-api-key': (value) => {
|
|
35
|
-
process.env.CURSOR_API_KEY = value;
|
|
36
|
-
},
|
|
37
|
-
'--cursor-email': (value) => {
|
|
38
|
-
process.env.CURSOR_EMAIL = value;
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Pull the global flags out of argv and apply them, returning the remaining args
|
|
43
|
-
* so per-command parsing never sees them. Both `--flag value` and `--flag=value`
|
|
44
|
-
* spellings work.
|
|
45
|
-
*/
|
|
46
|
-
function applyGlobalFlags(argv) {
|
|
47
|
-
const rest = [];
|
|
48
|
-
for (let i = 0; i < argv.length; i++) {
|
|
49
|
-
const arg = argv[i];
|
|
50
|
-
const eq = arg.indexOf('=');
|
|
51
|
-
const name = eq === -1 ? arg : arg.slice(0, eq);
|
|
52
|
-
const apply = GLOBAL_FLAGS[name];
|
|
53
|
-
if (!apply) {
|
|
54
|
-
rest.push(arg);
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const value = eq === -1 ? argv[++i] : arg.slice(eq + 1);
|
|
58
|
-
if (!value) {
|
|
59
|
-
console.error(`${name} requires a value`);
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
62
|
-
apply(value);
|
|
63
|
-
}
|
|
64
|
-
return rest;
|
|
65
|
-
}
|
|
66
|
-
const [cmd, ...args] = applyGlobalFlags(process.argv.slice(2));
|
|
67
|
-
// The help page is a curated, hand-grouped tour of the CLI — not a dump of the
|
|
68
|
-
// registry. That's deliberate: the registry stays the source of truth for
|
|
69
|
-
// dispatch, while this listing groups commands by what the user is trying to do
|
|
70
|
-
// and leaves out the niche ones (book, jobs, keys, scout) that would drown the
|
|
71
|
-
// core flow. Adding a command to the registry does NOT add it here — decide
|
|
72
|
-
// whether it belongs on the front page.
|
|
73
|
-
const HELP_GROUPS = [
|
|
74
|
-
{
|
|
75
|
-
title: 'start here',
|
|
76
|
-
rows: [
|
|
77
|
-
{
|
|
78
|
-
label: 'setup',
|
|
79
|
-
summary: 'first run: scan, sign in, start the background sync',
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
title: 'auth',
|
|
85
|
-
rows: [
|
|
86
|
-
{ label: 'login', summary: 'sign in to hacklab' },
|
|
87
|
-
{ label: 'logout', summary: "clear this machine's session" },
|
|
88
|
-
{ label: 'whoami', summary: "who you're logged in as" },
|
|
89
|
-
],
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
title: 'you',
|
|
93
|
-
rows: [
|
|
94
|
-
{ label: 'profile', summary: 'view and edit your profile' },
|
|
95
|
-
{ label: 'referral', summary: 'your invite link' },
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
title: 'game',
|
|
100
|
-
rows: [
|
|
101
|
-
{ label: 'rules', summary: 'understand how the ranking works' },
|
|
102
|
-
{ label: 'scan', summary: 'scan this machine and share the card' },
|
|
103
|
-
{ label: 'sync', summary: 'upload local AI usage to your profile' },
|
|
104
|
-
],
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
title: 'posting',
|
|
108
|
-
rows: [
|
|
109
|
-
{ label: 'drop <message>', summary: 'post a drop' },
|
|
110
|
-
{ label: 'drops', summary: 'your drops' },
|
|
111
|
-
{ label: 'project', summary: 'add, list, and edit your projects' },
|
|
112
|
-
{ label: 'essay', summary: 'post, list, and update your essays' },
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
title: 'people',
|
|
117
|
-
rows: [
|
|
118
|
-
{ label: 'chat', summary: 'the live public chat channel' },
|
|
119
|
-
{ label: 'hacker', summary: 'view hacker profiles' },
|
|
120
|
-
],
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
title: 'organisations',
|
|
124
|
-
rows: [{ label: 'org', summary: 'create and edit your organisations' }],
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
title: 'hackathons',
|
|
128
|
-
rows: [{ label: 'hackathon', summary: 'RSVP, team up, and submit' }],
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
title: 'manuals',
|
|
132
|
-
rows: [
|
|
133
|
-
{ label: 'rtfm', summary: 'list all manuals' },
|
|
134
|
-
{
|
|
135
|
-
label: 'rtfm <topic>',
|
|
136
|
-
summary: 'print the manual: exact commands, prereqs, done-when criteria',
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
title: 'settings',
|
|
142
|
-
rows: [
|
|
143
|
-
{ label: 'update', summary: 'update this CLI' },
|
|
144
|
-
{
|
|
145
|
-
label: 'daemon [off]',
|
|
146
|
-
summary: 'summon the background sync (off tears it down)',
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
label: 'config <key> <val>',
|
|
150
|
-
summary: 'cursor key, email, prompt-sync',
|
|
151
|
-
},
|
|
152
|
-
],
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
title: 'flags',
|
|
156
|
-
rows: [
|
|
157
|
-
{
|
|
158
|
-
label: '--json',
|
|
159
|
-
summary: 'machine-readable output (agents: always use this)',
|
|
160
|
-
},
|
|
161
|
-
{ label: '--help / -h', summary: 'show help for a command' },
|
|
162
|
-
{ label: '--version / -v', summary: 'show CLI version' },
|
|
163
|
-
],
|
|
164
|
-
},
|
|
165
|
-
];
|
|
166
|
-
function printHelp() {
|
|
167
|
-
banner();
|
|
168
|
-
// Align the summaries: pad every label to the widest one across all groups so
|
|
169
|
-
// the whole page reads as one table.
|
|
170
|
-
const width = Math.max(...HELP_GROUPS.flatMap((g) => g.rows.map((r) => r.label.length)));
|
|
171
|
-
for (const { title, rows } of HELP_GROUPS) {
|
|
172
|
-
console.log('');
|
|
173
|
-
console.log(bold(` ${title}`));
|
|
174
|
-
for (const { label, summary } of rows) {
|
|
175
|
-
console.log(` ${dim(label.padEnd(width))} ${summary}`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
console.log('');
|
|
179
|
-
}
|
|
180
|
-
// Node-version guard (T9). The CLI uses modern Node APIs (global fetch,
|
|
181
|
-
// AbortSignal.timeout). Fail fast with a clear message instead of a cryptic
|
|
182
|
-
// runtime error on an old runtime. The nvm hint matters because a piped
|
|
183
|
-
async function main() {
|
|
184
|
-
// Bare `hacklab` (no command) prints help, same as `--help`/`-h`. Runs before
|
|
185
|
-
// the update nudge so it reads as plain help, matching the `--help` path.
|
|
186
|
-
if (!cmd || cmd === '--help' || cmd === '-h') {
|
|
187
|
-
printHelp();
|
|
188
|
-
process.exit(0);
|
|
189
|
-
}
|
|
190
|
-
if (cmd === '--version' || cmd === '-v') {
|
|
191
|
-
console.log(VERSION);
|
|
192
|
-
process.exit(0);
|
|
193
|
-
}
|
|
194
|
-
// One-time anonymous-telemetry notice (interactive only, shown once). Before
|
|
195
|
-
// the update nudge so, on the very first run, consent is disclosed above any
|
|
196
|
-
// other output.
|
|
197
|
-
await maybePrintTelemetryNotice();
|
|
198
|
-
// One-line nudge if a newer hacklab is published (interactive only, cached
|
|
199
|
-
// daily, timeout-guarded). Must run before any command output so it reads as
|
|
200
|
-
// a header, not buried in results.
|
|
201
|
-
await notifyIfOutdated(VERSION);
|
|
202
|
-
// Resolve a possibly-abbreviated command to its full name (e.g. `sy` -> sync,
|
|
203
|
-
// `or` -> org). Exact matches always win; an ambiguous prefix is
|
|
204
|
-
// rejected with the candidates so the user can disambiguate.
|
|
205
|
-
const resolution = resolveCommand(cmd);
|
|
206
|
-
if (resolution.kind === 'ambiguous') {
|
|
207
|
-
console.error(`ambiguous command "${cmd}": ${resolution.matches.join(' or ')}?`);
|
|
208
|
-
process.exit(1);
|
|
209
|
-
}
|
|
210
|
-
const command = resolution.kind === 'match' ? findCommand(resolution.name) : undefined;
|
|
211
|
-
if (!command) {
|
|
212
|
-
console.error(`unknown command: ${cmd}`);
|
|
213
|
-
console.error('run hacklab --help for usage');
|
|
214
|
-
process.exit(1);
|
|
215
|
-
}
|
|
216
|
-
// Surface a paused daily background sync (e.g. the session expired while the
|
|
217
|
-
// machine was off) once, then clear the marker. Skipped for the auth commands
|
|
218
|
-
// that fix it (login), so we never nag mid-fix.
|
|
219
|
-
if (process.stdout.isTTY && command.name !== 'login') {
|
|
220
|
-
const paused = await readSyncPaused();
|
|
221
|
-
if (paused) {
|
|
222
|
-
console.error(dim(`paused: daily background sync — ${paused}`));
|
|
223
|
-
await clearSyncPaused();
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
await command.run(args);
|
|
227
|
-
// Best-effort final flush for the happy path. Per-event captures already flush
|
|
228
|
-
// eagerly (flushAt: 1), so this mainly drains any autocaptured exception.
|
|
229
|
-
await shutdownTelemetry();
|
|
230
|
-
}
|
|
231
|
-
main().catch(async (err) => {
|
|
232
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
233
|
-
const session = await loadSession().catch(() => null);
|
|
234
|
-
await captureException(err, session?.handle);
|
|
235
|
-
await shutdownTelemetry();
|
|
236
|
-
process.exit(1);
|
|
237
|
-
});
|
|
238
|
-
//# sourceMappingURL=cli.js.map
|