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,55 @@
1
+ import * as clack from '@clack/prompts';
2
+ import { loadSessionState } from '../session.js';
3
+ import { checkSession, formatTokens, runSync } from '../sync.js';
4
+ import { bold, dim, error, info, success } from '../ui.js';
5
+ export async function sync() {
6
+ const sessionState = await loadSessionState();
7
+ const session = sessionState.session;
8
+ if (!session) {
9
+ error(sessionState.status === 'expired' ? 'login expired' : 'not logged in');
10
+ info(`run ${dim('hacklab login')} first`);
11
+ process.exit(1);
12
+ }
13
+ const sessionCheck = await checkSession(session);
14
+ if (sessionCheck.status === 'unauthorized') {
15
+ error('login expired');
16
+ info(`run ${dim('hacklab login')} again`);
17
+ process.exit(1);
18
+ }
19
+ if (sessionCheck.status === 'failed') {
20
+ error(sessionCheck.message);
21
+ process.exit(1);
22
+ }
23
+ console.log('');
24
+ console.log(bold(' hacklab sync'));
25
+ console.log(dim(' scanning local AI tool usage...'));
26
+ console.log('');
27
+ let result;
28
+ try {
29
+ result = await runSync(session);
30
+ }
31
+ catch (e) {
32
+ error(e instanceof Error ? e.message : 'sync failed');
33
+ process.exit(1);
34
+ }
35
+ const { claudeTotal, codexTotal, cursorTotal, openclawTotal, hermesTotal, opencodeTotal, result: r, } = result;
36
+ if (claudeTotal > 0)
37
+ info(` Claude Code ${formatTokens(claudeTotal)} tokens`);
38
+ if (codexTotal > 0)
39
+ info(` Codex ${formatTokens(codexTotal)} tokens`);
40
+ if (cursorTotal > 0)
41
+ info(` Cursor ${formatTokens(cursorTotal)} tokens`);
42
+ if (openclawTotal > 0)
43
+ info(` OpenClaw ${formatTokens(openclawTotal)} tokens`);
44
+ if (hermesTotal > 0)
45
+ info(` Hermes ${formatTokens(hermesTotal)} tokens`);
46
+ if (opencodeTotal > 0)
47
+ info(` OpenCode ${formatTokens(opencodeTotal)} tokens`);
48
+ console.log('');
49
+ success(` ${bold(String(r.title))} lv.${r.level} — ${formatTokens(Number(r.tokensTotal))} total`);
50
+ if (Number(r.tokensDelta) > 0) {
51
+ info(` +${formatTokens(Number(r.tokensDelta))} since last sync`);
52
+ }
53
+ clack.outro(dim('synced.'));
54
+ }
55
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAE1D,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,YAAY,GAAG,MAAM,gBAAgB,EAAE,CAAA;IAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAA;IAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,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,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;IAChD,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,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,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IACjC,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,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,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,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;AAC7B,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare function whoamiCommand(): Promise<void>;
1
+ export declare function whoami(): Promise<void>;
2
2
  //# sourceMappingURL=whoami.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBnD"}
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAGA,wBAAsB,MAAM,kBAe3B"}
@@ -1,23 +1,17 @@
1
- import { intro, outro } from '@clack/prompts';
2
- import { fetchCliWhoAmI } from '../api/client.js';
3
1
  import { loadSession } from '../session.js';
4
- import { getAppUrl } from './login.utils.js';
5
- export async function whoamiCommand() {
6
- intro('hacklab cli');
2
+ import { dim, error, info, success } from '../ui.js';
3
+ export async function whoami() {
7
4
  const session = await loadSession();
8
5
  if (!session) {
9
- outro('not logged in. run `hacklab login`.');
10
- process.exitCode = 1;
11
- return;
6
+ error('not logged in');
7
+ info(`run ${dim('hacklab login')} to authenticate`);
8
+ process.exit(1);
12
9
  }
13
- const appUrl = getAppUrl(session.appUrl);
14
- const identity = await fetchCliWhoAmI(appUrl, session.token);
15
- if (!identity) {
16
- outro('your cli session is invalid or expired. run `hacklab login`.');
17
- process.exitCode = 1;
18
- return;
10
+ success(session.handle ?? session.email);
11
+ info(`email: ${session.email}`);
12
+ if (session.handle) {
13
+ info(`handle: ${session.handle}`);
19
14
  }
20
- const nicknameLabel = session.nickname ? ` (${session.nickname})` : '';
21
- outro(`logged in as ${identity.user.email}${nicknameLabel}`);
15
+ info(`server: ${session.appUrl}`);
22
16
  }
23
17
  //# sourceMappingURL=whoami.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,MAAM,CAAC,KAAK,UAAU,aAAa;IAC/B,KAAK,CAAC,aAAa,CAAC,CAAA;IAEpB,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,KAAK,CAAC,qCAAqC,CAAC,CAAA;QAC5C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;QACpB,OAAM;IACV,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACxC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAE5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,KAAK,CAAC,8DAA8D,CAAC,CAAA;QACrE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;QACpB,OAAM;IACV,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACtE,KAAK,CAAC,gBAAgB,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,aAAa,EAAE,CAAC,CAAA;AAChE,CAAC"}
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEpD,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,KAAK,CAAC,eAAe,CAAC,CAAA;QACtB,IAAI,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAA;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,CAAA;IACxC,IAAI,CAAC,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;IAC/B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACnC,CAAC;IACD,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AACnC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type HacklabConfig = {
2
+ cursorApiKey?: string;
3
+ cursorEmail?: string;
4
+ };
5
+ export declare function loadConfig(): Promise<HacklabConfig>;
6
+ export declare function saveConfig(config: HacklabConfig): Promise<void>;
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +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;CACrB,CAAA;AAID,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 ADDED
@@ -0,0 +1,18 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ const CONFIG_PATH = join(homedir(), '.hacklab', 'config.json');
5
+ export async function loadConfig() {
6
+ try {
7
+ const raw = await readFile(CONFIG_PATH, 'utf8');
8
+ return JSON.parse(raw);
9
+ }
10
+ catch {
11
+ return {};
12
+ }
13
+ }
14
+ export async function saveConfig(config) {
15
+ await mkdir(dirname(CONFIG_PATH), { recursive: true });
16
+ await writeFile(CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
17
+ }
18
+ //# sourceMappingURL=config.js.map
@@ -0,0 +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;AAOzC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAA;AAE9D,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"}
package/dist/dd.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=dd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dd.d.ts","sourceRoot":"","sources":["../src/dd.ts"],"names":[],"mappings":""}
package/dist/dd.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ import { drop } from './commands/drop.js';
3
+ import { error } from './ui.js';
4
+ const args = process.argv.slice(2);
5
+ if (args.length === 0) {
6
+ error('nothing to drop');
7
+ console.error('usage: dd your message here');
8
+ process.exit(1);
9
+ }
10
+ // Check for -u/--url flag
11
+ let url;
12
+ const filtered = [];
13
+ for (let i = 0; i < args.length; i++) {
14
+ const arg = args[i];
15
+ if ((arg === '-u' || arg === '--url') && args[i + 1]) {
16
+ url = args[i + 1];
17
+ i++;
18
+ }
19
+ else {
20
+ filtered.push(arg);
21
+ }
22
+ }
23
+ const content = filtered.join(' ');
24
+ drop(content, url).catch((err) => {
25
+ console.error(err instanceof Error ? err.message : String(err));
26
+ process.exit(1);
27
+ });
28
+ //# sourceMappingURL=dd.js.map
package/dist/dd.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dd.js","sourceRoot":"","sources":["../src/dd.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAElC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACtB,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACxB,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,0BAA0B;AAC1B,IAAI,GAAuB,CAAA;AAC3B,MAAM,QAAQ,GAAa,EAAE,CAAA;AAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAA;IACpB,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACjB,CAAC,EAAE,CAAA;IACL,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACpB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAElC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACxC,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
package/dist/index.js CHANGED
@@ -1,138 +1,129 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from "commander";
3
- import { bragCommand } from "./commands/brag.js";
4
- import { essayCommand } from "./commands/essay.js";
5
- import { initCommand } from "./commands/init.js";
6
- import { joinCommand } from "./commands/join.js";
7
- import { linkCommand } from "./commands/link.js";
8
- import { loginCommand } from "./commands/login.js";
9
- import { newCommand } from "./commands/new.js";
10
- import { onboardCommand } from "./commands/onboard.js";
11
- import { tuiCommand } from "./commands/tui.js";
12
- import { whoamiCommand } from "./commands/whoami.js";
13
- import { createGreenHelpConfig, HELP_BANNER } from "./help-format.js";
14
- const program = new Command();
15
- program
16
- .name("hacklab")
17
- .description("hacklab command line tool")
18
- .version("0.0.1")
19
- .addHelpText("beforeAll", HELP_BANNER);
20
- program.configureHelp(createGreenHelpConfig());
21
- program
22
- .command("join")
23
- .description("authenticate account and optionally set up your hq")
24
- .option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
25
- .action(async (options) => {
26
- await joinCommand({
27
- appUrl: options.appUrl,
28
- });
29
- });
30
- program
31
- .command("brag")
32
- .description("add current github project repo to your hacklab hq as draft")
33
- .option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
34
- .option("--as <account>", "account email or nickname to use")
35
- .option("--hq <path>", "path to your hq repository")
36
- .action(async (options) => {
37
- await bragCommand({
38
- appUrl: options.appUrl,
39
- as: options.as,
40
- hq: options.hq,
41
- });
42
- });
43
- program
44
- .command("essay")
45
- .description("add an essay to your studio lab")
46
- .option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
47
- .option("-l, --lab <slug>", "lab slug (defaults to local .hacklab config)")
48
- .option("-t, --title <title>", "essay title")
49
- .option("-s, --summary <summary>", "essay summary")
50
- .option("-b, --body <markdown>", "essay body markdown")
51
- .option("-f, --file <path>", "read essay body markdown from file")
52
- .option("-p, --publish", "publish immediately")
53
- .action(async (options) => {
54
- await essayCommand({
55
- appUrl: options.appUrl,
56
- lab: options.lab,
57
- title: options.title,
58
- summary: options.summary,
59
- body: options.body,
60
- file: options.file,
61
- publish: options.publish,
62
- });
63
- });
64
- program
65
- .command("onboard")
66
- .description("run cli onboarding (profile + lab)")
67
- .option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
68
- .option("-u, --username <username>", "profile username")
69
- .option("-b, --bio <bio>", "profile bio")
70
- .option("-l, --lab-name <name>", "lab name")
71
- .action(async (options) => {
72
- await onboardCommand({
73
- appUrl: options.appUrl,
74
- username: options.username,
75
- bio: options.bio,
76
- labName: options.labName,
77
- });
78
- });
79
- program
80
- .command("login")
81
- .description("login with your browser and store session locally")
82
- .option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
83
- .action(async (options) => {
84
- await loginCommand({
85
- appUrl: options.appUrl,
86
- });
87
- });
88
- program
89
- .command("whoami")
90
- .description("print current logged in account")
91
- .action(async () => {
92
- await whoamiCommand();
93
- });
94
- program
95
- .command("init")
96
- .description("initialize this repository as a hacklab repo")
97
- .option("-n, --name <name>", "lab display name")
98
- .option("-f, --force", "overwrite existing .hacklab/config.json")
99
- .action(async (options) => {
100
- await initCommand({
101
- name: options.name,
102
- force: options.force,
103
- });
104
- });
105
- program
106
- .command("new")
107
- .description("create new hacklab content")
108
- .argument("[type]", "project | guide | course | essay | research-paper")
109
- .argument("[slug]", "content slug, e.g. my-first-project")
110
- .option("-t, --title <title>", "custom title")
111
- .action(async (type, slug, options) => {
112
- await newCommand(type, slug, {
113
- title: options.title,
114
- });
115
- });
116
- program
117
- .command("link")
118
- .description("link an existing repository to hacklab without scaffolding")
119
- .option("-n, --name <name>", "lab display name")
120
- .option("-f, --force", "overwrite existing .hacklab/config.json")
121
- .action(async (options) => {
122
- await linkCommand({
123
- name: options.name,
124
- force: options.force,
125
- });
126
- });
127
- program
128
- .command("tui")
129
- .alias("/tui")
130
- .description("open hacklab tui entrypoint")
131
- .action(async () => {
132
- await tuiCommand();
133
- });
134
- program.parseAsync(process.argv).catch((error) => {
135
- console.error(error instanceof Error ? error.message : String(error));
2
+ import { brag, parseBragArgs } from './commands/brag.js';
3
+ import { configCommand } from './commands/config.js';
4
+ import { drop } from './commands/drop.js';
5
+ import { exam } from './commands/exam.js';
6
+ import { login } from './commands/login.js';
7
+ import { scanProfile } from './commands/scan-profile.js';
8
+ import { signup } from './commands/signup.js';
9
+ import { sync } from './commands/sync.js';
10
+ import { whoami } from './commands/whoami.js';
11
+ import { loadSession } from './session.js';
12
+ import { banner, bold, dim } from './ui.js';
13
+ const [cmd, ...args] = process.argv.slice(2);
14
+ function printHelp() {
15
+ banner();
16
+ console.log('');
17
+ console.log(bold('usage:'));
18
+ console.log(` hacklab ${dim('signup')} join hacklab from your terminal`);
19
+ console.log(` hacklab ${dim('sync')} sync AI token usage to your profile`);
20
+ console.log(` hacklab ${dim('whoami')} check who you're logged in as`);
21
+ console.log(` hacklab ${dim('drop')} ${dim('"message"')} post a drop to your feed`);
22
+ console.log(` hacklab ${dim('login')} re-authenticate with github`);
23
+ console.log(` hacklab ${dim('exam')} run your belt exam (pyro + hacker)`);
24
+ console.log(` hacklab ${dim('scan')} build your full profile (skills, repos, blog)`);
25
+ console.log(` hacklab ${dim('config')} ${dim('<key> <val>')} set config (cursor-api-key, cursor-email)`);
26
+ console.log(` hacklab ${dim('brag')} ${dim('[path]')} sync .hacklab/project.yaml`);
27
+ console.log('');
28
+ }
29
+ // Node-version guard (T9). The CLI uses modern Node APIs (global fetch,
30
+ // AbortSignal.timeout). Fail fast with a clear message instead of a cryptic
31
+ // runtime error on an old runtime. The nvm hint matters because a piped
32
+ // `curl | sh` install runs in a non-interactive shell where nvm isn't sourced,
33
+ // so version-manager users are told to run npx directly in their own shell.
34
+ function enforceNodeVersion() {
35
+ const major = Number(process.versions.node.split('.')[0]);
36
+ if (Number.isFinite(major) && major < 20) {
37
+ console.error(`hacklab requires Node 20 or newer (you have ${process.versions.node}).`);
38
+ console.error('Using a version manager (nvm/fnm/volta)? Run `npx hacklab@latest` in your shell.');
39
+ process.exit(1);
40
+ }
41
+ }
42
+ async function main() {
43
+ enforceNodeVersion();
44
+ if (cmd === '--help' || cmd === '-h') {
45
+ printHelp();
46
+ process.exit(0);
47
+ }
48
+ if (cmd === '--version' || cmd === '-v') {
49
+ console.log('0.3.0');
50
+ process.exit(0);
51
+ }
52
+ // Bare invocation (e.g. `npx hacklab@latest`): signup for newcomers, sync for
53
+ // a returning, already-authenticated user.
54
+ if (!cmd) {
55
+ const session = await loadSession();
56
+ if (session) {
57
+ await sync();
58
+ }
59
+ else {
60
+ await signup();
61
+ }
62
+ return;
63
+ }
64
+ if (cmd === 'signup') {
65
+ await signup();
66
+ }
67
+ else if (cmd === 'login') {
68
+ await login();
69
+ }
70
+ else if (cmd === 'whoami') {
71
+ await whoami();
72
+ }
73
+ else if (cmd === 'sync') {
74
+ await sync();
75
+ }
76
+ else if (cmd === 'drop') {
77
+ const content = parseDropArgs(args);
78
+ await drop(content.text, content.url);
79
+ }
80
+ else if (cmd === 'exam') {
81
+ const pyro = args.includes('--pyro');
82
+ const hacker = args.includes('--hacker');
83
+ await exam({ pyro, hacker });
84
+ }
85
+ else if (cmd === 'scan') {
86
+ await scanProfile();
87
+ }
88
+ else if (cmd === 'config') {
89
+ await configCommand(args);
90
+ }
91
+ else if (cmd === 'brag') {
92
+ const options = parseBragArgs(args);
93
+ await brag(options.manifestPath);
94
+ }
95
+ else {
96
+ console.error(`unknown command: ${cmd}`);
97
+ console.error('run hacklab --help for usage');
98
+ process.exit(1);
99
+ }
100
+ }
101
+ function parseDropArgs(args) {
102
+ let url;
103
+ const words = [];
104
+ for (let i = 0; i < args.length; i++) {
105
+ const arg = args[i];
106
+ if ((arg === '-u' || arg === '--url') && args[i + 1]) {
107
+ url = args[i + 1];
108
+ i++;
109
+ }
110
+ else if (arg.startsWith('-')) {
111
+ console.error(`unknown flag: ${arg}`);
112
+ process.exit(1);
113
+ }
114
+ else {
115
+ words.push(arg);
116
+ }
117
+ }
118
+ const text = words.join(' ');
119
+ if (!text) {
120
+ console.error('usage: hacklab drop your message here');
121
+ process.exit(1);
122
+ }
123
+ return { text, url };
124
+ }
125
+ main().catch((err) => {
126
+ console.error(err instanceof Error ? err.message : String(err));
136
127
  process.exit(1);
137
128
  });
138
129
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { z } from 'zod';
2
+ export declare const DEFAULT_BRAG_MANIFEST_PATH = ".hacklab/project.yaml";
3
+ declare const projectManifestSchema: z.ZodObject<{
4
+ title: z.ZodString;
5
+ slug: z.ZodOptional<z.ZodString>;
6
+ description: z.ZodOptional<z.ZodString>;
7
+ tags: z.ZodDefault<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodArray<z.ZodString>>>>;
8
+ repoUrl: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
9
+ liveUrl: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
10
+ screenshots: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
11
+ path: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
12
+ url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
13
+ caption: z.ZodDefault<z.ZodOptional<z.ZodString>>;
14
+ }, z.core.$strip>]>>>>;
15
+ content: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
16
+ contentFile: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
17
+ publishedAt: z.ZodPipe<z.ZodTransform<string | Date | undefined, unknown>, z.ZodOptional<z.ZodCoercedDate<unknown>>>;
18
+ }, z.core.$strip>;
19
+ export type BragManifest = z.infer<typeof projectManifestSchema>;
20
+ export type LoadedBragManifest = {
21
+ cwd: string;
22
+ manifestPath: string;
23
+ manifest: BragManifest & {
24
+ slug: string;
25
+ };
26
+ rawYaml: string;
27
+ };
28
+ export type BragScreenshot = {
29
+ url: string;
30
+ caption: string;
31
+ };
32
+ export type BragProjectPayload = {
33
+ title: string;
34
+ slug: string;
35
+ description?: string;
36
+ tags: string[];
37
+ repoUrl?: string;
38
+ liveUrl?: string;
39
+ screenshots: BragScreenshot[];
40
+ content?: string;
41
+ sourceYaml: string;
42
+ publishedAt?: string;
43
+ };
44
+ export type ScreenshotUploadInput = {
45
+ absolutePath: string;
46
+ base64: string;
47
+ contentType: 'image/png' | 'image/jpeg';
48
+ filename: string;
49
+ caption: string;
50
+ };
51
+ export type ScreenshotUploader = (input: ScreenshotUploadInput) => Promise<string>;
52
+ export declare function loadBragManifest(options?: {
53
+ cwd?: string;
54
+ manifestPath?: string;
55
+ }): Promise<LoadedBragManifest>;
56
+ export declare function buildBragProjectPayload(manifest: LoadedBragManifest, uploadScreenshot: ScreenshotUploader): Promise<BragProjectPayload>;
57
+ export {};
58
+ //# sourceMappingURL=project-brag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-brag.d.ts","sourceRoot":"","sources":["../src/project-brag.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,0BAA0B,0BAA0B,CAAA;AAoDjE,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;iBA0CzB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAEhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,YAAY,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,cAAc,EAAE,CAAA;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,WAAW,GAAG,YAAY,CAAA;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,CAC/B,KAAK,EAAE,qBAAqB,KACzB,OAAO,CAAC,MAAM,CAAC,CAAA;AA+DpB,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmD9B;AAkED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,kBAAkB,EAC5B,gBAAgB,EAAE,kBAAkB,GACnC,OAAO,CAAC,kBAAkB,CAAC,CA+D7B"}