hacklab 0.0.1 → 0.3.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.
Files changed (154) hide show
  1. package/README.md +48 -8
  2. package/bin/ddd +19 -0
  3. package/dist/commands/brag.d.ts +3 -6
  4. package/dist/commands/brag.d.ts.map +1 -1
  5. package/dist/commands/brag.js +68 -299
  6. package/dist/commands/brag.js.map +1 -1
  7. package/dist/commands/claim.d.ts +2 -0
  8. package/dist/commands/claim.d.ts.map +1 -0
  9. package/dist/commands/claim.js +534 -0
  10. package/dist/commands/claim.js.map +1 -0
  11. package/dist/commands/config.d.ts +2 -0
  12. package/dist/commands/config.d.ts.map +1 -0
  13. package/dist/commands/config.js +48 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/dojo-init.d.ts +2 -0
  16. package/dist/commands/dojo-init.d.ts.map +1 -0
  17. package/dist/commands/dojo-init.js +75 -0
  18. package/dist/commands/dojo-init.js.map +1 -0
  19. package/dist/commands/drop.d.ts +2 -0
  20. package/dist/commands/drop.d.ts.map +1 -0
  21. package/dist/commands/drop.js +29 -0
  22. package/dist/commands/drop.js.map +1 -0
  23. package/dist/commands/exam.d.ts +5 -0
  24. package/dist/commands/exam.d.ts.map +1 -0
  25. package/dist/commands/exam.js +224 -0
  26. package/dist/commands/exam.js.map +1 -0
  27. package/dist/commands/login.d.ts +1 -14
  28. package/dist/commands/login.d.ts.map +1 -1
  29. package/dist/commands/login.js +70 -102
  30. package/dist/commands/login.js.map +1 -1
  31. package/dist/commands/scan-profile.d.ts +33 -0
  32. package/dist/commands/scan-profile.d.ts.map +1 -0
  33. package/dist/commands/scan-profile.js +279 -0
  34. package/dist/commands/scan-profile.js.map +1 -0
  35. package/dist/commands/signup.d.ts +11 -0
  36. package/dist/commands/signup.d.ts.map +1 -0
  37. package/dist/commands/signup.js +242 -0
  38. package/dist/commands/signup.js.map +1 -0
  39. package/dist/commands/sync.d.ts +2 -0
  40. package/dist/commands/sync.d.ts.map +1 -0
  41. package/dist/commands/sync.js +55 -0
  42. package/dist/commands/sync.js.map +1 -0
  43. package/dist/commands/whoami.d.ts +1 -1
  44. package/dist/commands/whoami.d.ts.map +1 -1
  45. package/dist/commands/whoami.js +10 -16
  46. package/dist/commands/whoami.js.map +1 -1
  47. package/dist/config.d.ts +7 -0
  48. package/dist/config.d.ts.map +1 -0
  49. package/dist/config.js +18 -0
  50. package/dist/config.js.map +1 -0
  51. package/dist/dd.d.ts +3 -0
  52. package/dist/dd.d.ts.map +1 -0
  53. package/dist/dd.js +28 -0
  54. package/dist/dd.js.map +1 -0
  55. package/dist/index.js +125 -134
  56. package/dist/index.js.map +1 -1
  57. package/dist/project-brag.d.ts +58 -0
  58. package/dist/project-brag.d.ts.map +1 -0
  59. package/dist/project-brag.js +270 -0
  60. package/dist/project-brag.js.map +1 -0
  61. package/dist/scanners/index.d.ts +24 -0
  62. package/dist/scanners/index.d.ts.map +1 -0
  63. package/dist/scanners/index.js +543 -0
  64. package/dist/scanners/index.js.map +1 -0
  65. package/dist/scanners/util.d.ts +83 -0
  66. package/dist/scanners/util.d.ts.map +1 -0
  67. package/dist/scanners/util.js +129 -0
  68. package/dist/scanners/util.js.map +1 -0
  69. package/dist/session.d.ts +17 -12
  70. package/dist/session.d.ts.map +1 -1
  71. package/dist/session.js +46 -141
  72. package/dist/session.js.map +1 -1
  73. package/dist/share-card.d.ts +29 -0
  74. package/dist/share-card.d.ts.map +1 -0
  75. package/dist/share-card.js +401 -0
  76. package/dist/share-card.js.map +1 -0
  77. package/dist/sync.d.ts +64 -0
  78. package/dist/sync.d.ts.map +1 -0
  79. package/dist/sync.js +805 -0
  80. package/dist/sync.js.map +1 -0
  81. package/dist/ui.d.ts +10 -0
  82. package/dist/ui.d.ts.map +1 -0
  83. package/dist/ui.js +21 -0
  84. package/dist/ui.js.map +1 -0
  85. package/dist/utils/openBrowser.js.map +1 -1
  86. package/package.json +36 -27
  87. package/dist/api/client.d.ts +0 -118
  88. package/dist/api/client.d.ts.map +0 -1
  89. package/dist/api/client.js +0 -214
  90. package/dist/api/client.js.map +0 -1
  91. package/dist/commands/brag.utils.d.ts +0 -12
  92. package/dist/commands/brag.utils.d.ts.map +0 -1
  93. package/dist/commands/brag.utils.js +0 -43
  94. package/dist/commands/brag.utils.js.map +0 -1
  95. package/dist/commands/essay.d.ts +0 -18
  96. package/dist/commands/essay.d.ts.map +0 -1
  97. package/dist/commands/essay.js +0 -117
  98. package/dist/commands/essay.js.map +0 -1
  99. package/dist/commands/init.d.ts +0 -16
  100. package/dist/commands/init.d.ts.map +0 -1
  101. package/dist/commands/init.js +0 -237
  102. package/dist/commands/init.js.map +0 -1
  103. package/dist/commands/join.d.ts +0 -10
  104. package/dist/commands/join.d.ts.map +0 -1
  105. package/dist/commands/join.js +0 -314
  106. package/dist/commands/join.js.map +0 -1
  107. package/dist/commands/link.d.ts +0 -17
  108. package/dist/commands/link.d.ts.map +0 -1
  109. package/dist/commands/link.js +0 -36
  110. package/dist/commands/link.js.map +0 -1
  111. package/dist/commands/login.utils.d.ts +0 -3
  112. package/dist/commands/login.utils.d.ts.map +0 -1
  113. package/dist/commands/login.utils.js +0 -13
  114. package/dist/commands/login.utils.js.map +0 -1
  115. package/dist/commands/new.d.ts +0 -15
  116. package/dist/commands/new.d.ts.map +0 -1
  117. package/dist/commands/new.js +0 -172
  118. package/dist/commands/new.js.map +0 -1
  119. package/dist/commands/new.utils.d.ts +0 -7
  120. package/dist/commands/new.utils.d.ts.map +0 -1
  121. package/dist/commands/new.utils.js +0 -50
  122. package/dist/commands/new.utils.js.map +0 -1
  123. package/dist/commands/onboard.d.ts +0 -10
  124. package/dist/commands/onboard.d.ts.map +0 -1
  125. package/dist/commands/onboard.js +0 -93
  126. package/dist/commands/onboard.js.map +0 -1
  127. package/dist/commands/tui.d.ts +0 -12
  128. package/dist/commands/tui.d.ts.map +0 -1
  129. package/dist/commands/tui.js +0 -112
  130. package/dist/commands/tui.js.map +0 -1
  131. package/dist/help-format.d.ts +0 -4
  132. package/dist/help-format.d.ts.map +0 -1
  133. package/dist/help-format.js +0 -30
  134. package/dist/help-format.js.map +0 -1
  135. package/dist/lab/config.d.ts +0 -32
  136. package/dist/lab/config.d.ts.map +0 -1
  137. package/dist/lab/config.js +0 -148
  138. package/dist/lab/config.js.map +0 -1
  139. package/dist/lab/contentStatus.d.ts +0 -6
  140. package/dist/lab/contentStatus.d.ts.map +0 -1
  141. package/dist/lab/contentStatus.js +0 -19
  142. package/dist/lab/contentStatus.js.map +0 -1
  143. package/dist/ui/banner.d.ts +0 -2
  144. package/dist/ui/banner.d.ts.map +0 -1
  145. package/dist/ui/banner.js +0 -22
  146. package/dist/ui/banner.js.map +0 -1
  147. package/dist/utils/findRepoRoot.d.ts +0 -2
  148. package/dist/utils/findRepoRoot.d.ts.map +0 -1
  149. package/dist/utils/findRepoRoot.js +0 -17
  150. package/dist/utils/findRepoRoot.js.map +0 -1
  151. package/dist/utils/pathExists.d.ts +0 -2
  152. package/dist/utils/pathExists.d.ts.map +0 -1
  153. package/dist/utils/pathExists.js +0 -11
  154. package/dist/utils/pathExists.js.map +0 -1
@@ -0,0 +1,129 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ export function emptyResult(tool) {
4
+ return { tool, daily: [], hourly: [], models: {} };
5
+ }
6
+ export const HOURLY_WINDOW_DAYS = 90;
7
+ export function toDateStr(ts) {
8
+ const v = typeof ts === 'string' && /^\d+$/.test(ts) ? Number(ts) : ts;
9
+ const d = new Date(v);
10
+ return d.toISOString().slice(0, 10);
11
+ }
12
+ export function hourlyCutoff() {
13
+ const d = new Date();
14
+ d.setUTCDate(d.getUTCDate() - HOURLY_WINDOW_DAYS);
15
+ return d.toISOString().slice(0, 10);
16
+ }
17
+ export function formatTokens(n) {
18
+ if (n >= 1_000_000_000)
19
+ return `${(n / 1_000_000_000).toFixed(1)}B`;
20
+ if (n >= 1_000_000)
21
+ return `${(n / 1_000_000).toFixed(1)}M`;
22
+ if (n >= 1_000)
23
+ return `${(n / 1_000).toFixed(0)}K`;
24
+ return String(n);
25
+ }
26
+ export function formatBytes(n) {
27
+ if (n >= 1_073_741_824)
28
+ return `${(n / 1_073_741_824).toFixed(1)}GB`;
29
+ if (n >= 1_048_576)
30
+ return `${(n / 1_048_576).toFixed(1)}MB`;
31
+ if (n >= 1_024)
32
+ return `${(n / 1_024).toFixed(0)}KB`;
33
+ return `${n}B`;
34
+ }
35
+ /** Recursively collect files with a given extension; unreadable dirs are skipped. */
36
+ export async function findFiles(dir, ext) {
37
+ const results = [];
38
+ async function walk(current) {
39
+ try {
40
+ const entries = await readdir(current, { withFileTypes: true });
41
+ for (const entry of entries) {
42
+ const fullPath = join(current, entry.name);
43
+ if (entry.isDirectory()) {
44
+ await walk(fullPath);
45
+ }
46
+ else if (entry.name.endsWith(ext)) {
47
+ results.push(fullPath);
48
+ }
49
+ }
50
+ }
51
+ catch {
52
+ // skip unreadable directories
53
+ }
54
+ }
55
+ await walk(dir);
56
+ return results;
57
+ }
58
+ /**
59
+ * Per-scanner accumulator. Replaces the old module-level modelAccumulator /
60
+ * hourlyAccumulator globals — each scanner instantiates its own, so there is no
61
+ * cross-scan state to clear and concurrent runs can't clobber each other.
62
+ */
63
+ export class TokenCollector {
64
+ tool;
65
+ dailyByModel = new Map();
66
+ hourly = new Map();
67
+ models = new Map();
68
+ cutoff = hourlyCutoff();
69
+ constructor(tool) {
70
+ this.tool = tool;
71
+ }
72
+ addDaily(date, model, tokens, messages = 1) {
73
+ const key = `${date}|${model}`;
74
+ const existing = this.dailyByModel.get(key);
75
+ if (existing) {
76
+ existing.tokens += tokens;
77
+ existing.messages += messages;
78
+ }
79
+ else {
80
+ this.dailyByModel.set(key, { tokens, messages });
81
+ }
82
+ if (model)
83
+ this.models.set(model, (this.models.get(model) ?? 0) + tokens);
84
+ }
85
+ addHourly(date, hour, model, tokens, messages = 1) {
86
+ if (date < this.cutoff)
87
+ return;
88
+ const key = `${date}|${hour}|${model ?? ''}`;
89
+ const existing = this.hourly.get(key);
90
+ if (existing) {
91
+ existing.tokens += tokens;
92
+ existing.messages += messages;
93
+ }
94
+ else {
95
+ this.hourly.set(key, { tokens, messages });
96
+ }
97
+ }
98
+ result(extra) {
99
+ const daily = Array.from(this.dailyByModel.entries()).map(([key, { tokens, messages }]) => {
100
+ const [date, model] = key.split('|');
101
+ return {
102
+ date: date ?? '',
103
+ tool: this.tool,
104
+ tokens,
105
+ messages,
106
+ model: model || undefined,
107
+ };
108
+ });
109
+ const hourly = Array.from(this.hourly.entries()).map(([key, { tokens, messages }]) => {
110
+ const [date, hourStr, model] = key.split('|');
111
+ return {
112
+ date: date ?? '',
113
+ hour: Number(hourStr),
114
+ tool: this.tool,
115
+ model: model || undefined,
116
+ tokens,
117
+ messages,
118
+ };
119
+ });
120
+ return {
121
+ tool: this.tool,
122
+ daily,
123
+ hourly,
124
+ models: Object.fromEntries(this.models),
125
+ ...extra,
126
+ };
127
+ }
128
+ }
129
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/scanners/util.ts"],"names":[],"mappings":"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"}
package/dist/session.d.ts CHANGED
@@ -1,18 +1,23 @@
1
1
  export type Session = {
2
- email: string;
3
2
  token: string;
4
- loggedInAt: string;
5
- appUrl?: string;
6
- nickname?: string;
3
+ email: string;
4
+ handle?: string;
5
+ appUrl: string;
6
+ savedAt: string;
7
+ expiresAt?: string;
7
8
  };
8
- export type Account = Session & {
9
- hqPaths?: string[];
10
- activeHqPath?: string;
9
+ export type LoadSessionState = {
10
+ status: 'ok';
11
+ session: Session;
12
+ } | {
13
+ status: 'missing' | 'invalid' | 'expired';
14
+ session: null;
11
15
  };
12
16
  export declare function getSessionPath(): string;
13
- export declare function getAccountsPath(): string;
14
- export declare function saveSession(session: Session, sessionPath?: string): Promise<void>;
15
- export declare function loadSession(sessionPath?: string): Promise<Session | null>;
16
- export declare function loadKnownAccounts(): Promise<Account[]>;
17
- export declare function linkHqToAccount(email: string, hqPath: string): Promise<void>;
17
+ export declare function saveSession(session: Session): Promise<void>;
18
+ export declare function getSessionExpiresAt(session: Pick<Session, 'expiresAt' | 'savedAt'>): Date | null;
19
+ export declare function isSessionExpired(session: Pick<Session, 'expiresAt' | 'savedAt'>, now?: Date): boolean;
20
+ export declare function loadSessionState(): Promise<LoadSessionState>;
21
+ export declare function loadSession(): Promise<Session | null>;
22
+ export declare function getAppUrl(): string;
18
23
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAKD,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAOD,wBAAgB,cAAc,IAAI,MAAM,CAMvC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AA2DD,wBAAsB,WAAW,CAC7B,OAAO,EAAE,OAAO,EAChB,WAAW,SAAmB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,WAAW,CAC7B,WAAW,SAAmB,GAC/B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CA2BzB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAmB5D;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuClF"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAKD,MAAM,MAAM,gBAAgB,GACxB;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAClC;IAAE,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,CAAA;AAEhE,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjE;AASD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,GAC9C,IAAI,GAAG,IAAI,CAQb;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAAC,EAC/C,GAAG,OAAa,GACf,OAAO,CAGT;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAyBlE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAE3D;AAED,wBAAgB,SAAS,IAAI,MAAM,CAIlC"}
package/dist/session.js CHANGED
@@ -1,158 +1,63 @@
1
1
  import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import { homedir } from 'node:os';
3
3
  import { dirname, join } from 'node:path';
4
- const DEFAULT_SESSION_PATH = join(homedir(), '.hacklab', 'session.json');
5
- const DEFAULT_ACCOUNTS_PATH = join(homedir(), '.hacklab', 'accounts.json');
4
+ const SESSION_PATH = join(homedir(), '.hacklab', 'session.json');
5
+ const LEGACY_SESSION_TTL_MS = 7 * 24 * 60 * 60 * 1000;
6
6
  export function getSessionPath() {
7
- return (process.env.HACKLAB_SESSION_PATH ??
8
- process.env.HACKLA_SESSION_PATH ??
9
- DEFAULT_SESSION_PATH);
10
- }
11
- export function getAccountsPath() {
12
- return process.env.HACKLAB_ACCOUNTS_PATH ?? DEFAULT_ACCOUNTS_PATH;
13
- }
14
- function normalizeAccountState(raw) {
15
- const accounts = Array.isArray(raw?.accounts)
16
- ? raw.accounts
17
- .filter((account) => {
18
- return Boolean(account?.email && account?.token && account?.loggedInAt);
19
- })
20
- .map((account) => {
21
- return {
22
- email: account.email,
23
- token: account.token,
24
- loggedInAt: account.loggedInAt,
25
- appUrl: account.appUrl,
26
- nickname: account.nickname,
27
- hqPaths: account.hqPaths?.filter(Boolean) ?? [],
28
- activeHqPath: account.activeHqPath,
29
- };
30
- })
31
- : [];
32
- return {
33
- activeEmail: raw?.activeEmail,
34
- accounts,
35
- };
36
- }
37
- async function loadAccountState(accountsPath = getAccountsPath()) {
7
+ return process.env.HACKLAB_SESSION_PATH ?? SESSION_PATH;
8
+ }
9
+ export async function saveSession(session) {
10
+ const path = getSessionPath();
11
+ await mkdir(dirname(path), { recursive: true });
12
+ await writeFile(path, `${JSON.stringify(session, null, 2)}\n`, 'utf8');
13
+ }
14
+ function parseDate(value) {
15
+ if (!value)
16
+ return null;
17
+ const date = new Date(value);
18
+ return Number.isNaN(date.getTime()) ? null : date;
19
+ }
20
+ export function getSessionExpiresAt(session) {
21
+ const explicit = parseDate(session.expiresAt);
22
+ if (explicit)
23
+ return explicit;
24
+ const savedAt = parseDate(session.savedAt);
25
+ if (!savedAt)
26
+ return null;
27
+ return new Date(savedAt.getTime() + LEGACY_SESSION_TTL_MS);
28
+ }
29
+ export function isSessionExpired(session, now = new Date()) {
30
+ const expiresAt = getSessionExpiresAt(session);
31
+ return expiresAt ? expiresAt.getTime() <= now.getTime() : false;
32
+ }
33
+ export async function loadSessionState() {
34
+ let raw;
38
35
  try {
39
- const raw = await readFile(accountsPath, 'utf8');
40
- const parsed = JSON.parse(raw);
41
- return normalizeAccountState(parsed);
36
+ raw = await readFile(getSessionPath(), 'utf8');
42
37
  }
43
- catch (error) {
44
- if (error.code === 'ENOENT') {
45
- return {
46
- accounts: [],
47
- };
48
- }
49
- if (error instanceof SyntaxError) {
50
- return {
51
- accounts: [],
52
- };
53
- }
54
- throw error;
38
+ catch {
39
+ return { status: 'missing', session: null };
55
40
  }
56
- }
57
- async function saveAccountState(state, accountsPath = getAccountsPath()) {
58
- await mkdir(dirname(accountsPath), { recursive: true });
59
- await writeFile(accountsPath, `${JSON.stringify(state, null, 2)}\n`, 'utf8');
60
- }
61
- export async function saveSession(session, sessionPath = getSessionPath()) {
62
- await mkdir(dirname(sessionPath), { recursive: true });
63
- await writeFile(sessionPath, `${JSON.stringify(session, null, 2)}\n`, 'utf8');
41
+ let data;
64
42
  try {
65
- const state = await loadAccountState();
66
- const existing = state.accounts.find((account) => account.email === session.email);
67
- const nextAccount = {
68
- ...existing,
69
- ...session,
70
- hqPaths: existing?.hqPaths ?? [],
71
- activeHqPath: existing?.activeHqPath,
72
- };
73
- const accounts = state.accounts.filter((account) => account.email !== session.email);
74
- accounts.push(nextAccount);
75
- await saveAccountState({
76
- activeEmail: session.email,
77
- accounts,
78
- });
43
+ data = JSON.parse(raw);
79
44
  }
80
45
  catch {
81
- // Account history is best-effort metadata; keep login functional even if this write fails.
46
+ return { status: 'invalid', session: null };
82
47
  }
83
- }
84
- export async function loadSession(sessionPath = getSessionPath()) {
85
- try {
86
- const raw = await readFile(sessionPath, 'utf8');
87
- const parsed = JSON.parse(raw);
88
- if (!parsed.email || !parsed.token || !parsed.loggedInAt) {
89
- return null;
90
- }
91
- return {
92
- email: parsed.email,
93
- token: parsed.token,
94
- loggedInAt: parsed.loggedInAt,
95
- appUrl: parsed.appUrl,
96
- nickname: parsed.nickname,
97
- };
48
+ if (!data.token || !data.email || !data.appUrl) {
49
+ return { status: 'invalid', session: null };
98
50
  }
99
- catch (error) {
100
- if (error.code === 'ENOENT') {
101
- return null;
102
- }
103
- if (error instanceof SyntaxError) {
104
- return null;
105
- }
106
- throw error;
51
+ const session = data;
52
+ if (isSessionExpired(session)) {
53
+ return { status: 'expired', session: null };
107
54
  }
55
+ return { status: 'ok', session };
108
56
  }
109
- export async function loadKnownAccounts() {
110
- const state = await loadAccountState();
111
- if (state.accounts.length > 0) {
112
- return state.accounts;
113
- }
114
- const session = await loadSession();
115
- if (!session) {
116
- return [];
117
- }
118
- return [
119
- {
120
- ...session,
121
- hqPaths: [],
122
- },
123
- ];
57
+ export async function loadSession() {
58
+ return (await loadSessionState()).session;
124
59
  }
125
- export async function linkHqToAccount(email, hqPath) {
126
- const state = await loadAccountState();
127
- let account = state.accounts.find((item) => item.email === email);
128
- if (!account) {
129
- const session = await loadSession();
130
- if (!session || session.email !== email) {
131
- return;
132
- }
133
- account = {
134
- ...session,
135
- hqPaths: [],
136
- };
137
- state.accounts.push(account);
138
- }
139
- const existingPaths = account.hqPaths ?? [];
140
- const nextPaths = existingPaths.includes(hqPath)
141
- ? existingPaths
142
- : [...existingPaths, hqPath];
143
- const nextAccounts = state.accounts.map((item) => {
144
- if (item.email !== email) {
145
- return item;
146
- }
147
- return {
148
- ...item,
149
- hqPaths: nextPaths,
150
- activeHqPath: hqPath,
151
- };
152
- });
153
- await saveAccountState({
154
- activeEmail: state.activeEmail || email,
155
- accounts: nextAccounts,
156
- });
60
+ export function getAppUrl() {
61
+ return (process.env.HACKLAB_APP_URL?.replace(/\/$/, '') ?? 'http://localhost:3000');
157
62
  }
158
63
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type ShareCardData = {
2
+ handle: string;
3
+ level: number;
4
+ title: string;
5
+ beltColor: string;
6
+ tokensTotal: number;
7
+ rank: number;
8
+ streak: number;
9
+ longestStreak: number;
10
+ progressPercent: number;
11
+ estimatedCost: number;
12
+ toolBreakdown: {
13
+ claudeCode: number;
14
+ codex: number;
15
+ cursor: number;
16
+ };
17
+ models: Array<{
18
+ name: string;
19
+ tokens: number;
20
+ }>;
21
+ dailyActivity: Array<{
22
+ date: string;
23
+ tokens: number;
24
+ }>;
25
+ };
26
+ export declare function generateShareCard(data: ShareCardData): Promise<string>;
27
+ export declare function displayInTerminal(pngBuffer: Buffer): boolean;
28
+ export declare function copyToClipboard(imagePath: string): Promise<boolean>;
29
+ //# sourceMappingURL=share-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share-card.d.ts","sourceRoot":"","sources":["../src/share-card.tsx"],"names":[],"mappings":"AA0CA,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE;QACb,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/C,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACvD,CAAA;AAmfD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAoC5E;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CA4C5D;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASzE"}