hacklab 0.0.1

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 (94) hide show
  1. package/README.md +67 -0
  2. package/dist/api/client.d.ts +118 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +214 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/commands/brag.d.ts +8 -0
  7. package/dist/commands/brag.d.ts.map +1 -0
  8. package/dist/commands/brag.js +318 -0
  9. package/dist/commands/brag.js.map +1 -0
  10. package/dist/commands/brag.utils.d.ts +12 -0
  11. package/dist/commands/brag.utils.d.ts.map +1 -0
  12. package/dist/commands/brag.utils.js +43 -0
  13. package/dist/commands/brag.utils.js.map +1 -0
  14. package/dist/commands/essay.d.ts +18 -0
  15. package/dist/commands/essay.d.ts.map +1 -0
  16. package/dist/commands/essay.js +117 -0
  17. package/dist/commands/essay.js.map +1 -0
  18. package/dist/commands/init.d.ts +16 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +237 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/join.d.ts +10 -0
  23. package/dist/commands/join.d.ts.map +1 -0
  24. package/dist/commands/join.js +314 -0
  25. package/dist/commands/join.js.map +1 -0
  26. package/dist/commands/link.d.ts +17 -0
  27. package/dist/commands/link.d.ts.map +1 -0
  28. package/dist/commands/link.js +36 -0
  29. package/dist/commands/link.js.map +1 -0
  30. package/dist/commands/login.d.ts +15 -0
  31. package/dist/commands/login.d.ts.map +1 -0
  32. package/dist/commands/login.js +108 -0
  33. package/dist/commands/login.js.map +1 -0
  34. package/dist/commands/login.utils.d.ts +3 -0
  35. package/dist/commands/login.utils.d.ts.map +1 -0
  36. package/dist/commands/login.utils.js +13 -0
  37. package/dist/commands/login.utils.js.map +1 -0
  38. package/dist/commands/new.d.ts +15 -0
  39. package/dist/commands/new.d.ts.map +1 -0
  40. package/dist/commands/new.js +172 -0
  41. package/dist/commands/new.js.map +1 -0
  42. package/dist/commands/new.utils.d.ts +7 -0
  43. package/dist/commands/new.utils.d.ts.map +1 -0
  44. package/dist/commands/new.utils.js +50 -0
  45. package/dist/commands/new.utils.js.map +1 -0
  46. package/dist/commands/onboard.d.ts +10 -0
  47. package/dist/commands/onboard.d.ts.map +1 -0
  48. package/dist/commands/onboard.js +93 -0
  49. package/dist/commands/onboard.js.map +1 -0
  50. package/dist/commands/tui.d.ts +12 -0
  51. package/dist/commands/tui.d.ts.map +1 -0
  52. package/dist/commands/tui.js +112 -0
  53. package/dist/commands/tui.js.map +1 -0
  54. package/dist/commands/whoami.d.ts +2 -0
  55. package/dist/commands/whoami.d.ts.map +1 -0
  56. package/dist/commands/whoami.js +23 -0
  57. package/dist/commands/whoami.js.map +1 -0
  58. package/dist/help-format.d.ts +4 -0
  59. package/dist/help-format.d.ts.map +1 -0
  60. package/dist/help-format.js +30 -0
  61. package/dist/help-format.js.map +1 -0
  62. package/dist/index.d.ts +3 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +138 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/lab/config.d.ts +32 -0
  67. package/dist/lab/config.d.ts.map +1 -0
  68. package/dist/lab/config.js +148 -0
  69. package/dist/lab/config.js.map +1 -0
  70. package/dist/lab/contentStatus.d.ts +6 -0
  71. package/dist/lab/contentStatus.d.ts.map +1 -0
  72. package/dist/lab/contentStatus.js +19 -0
  73. package/dist/lab/contentStatus.js.map +1 -0
  74. package/dist/session.d.ts +18 -0
  75. package/dist/session.d.ts.map +1 -0
  76. package/dist/session.js +158 -0
  77. package/dist/session.js.map +1 -0
  78. package/dist/ui/banner.d.ts +2 -0
  79. package/dist/ui/banner.d.ts.map +1 -0
  80. package/dist/ui/banner.js +22 -0
  81. package/dist/ui/banner.js.map +1 -0
  82. package/dist/utils/findRepoRoot.d.ts +2 -0
  83. package/dist/utils/findRepoRoot.d.ts.map +1 -0
  84. package/dist/utils/findRepoRoot.js +17 -0
  85. package/dist/utils/findRepoRoot.js.map +1 -0
  86. package/dist/utils/openBrowser.d.ts +2 -0
  87. package/dist/utils/openBrowser.d.ts.map +1 -0
  88. package/dist/utils/openBrowser.js +29 -0
  89. package/dist/utils/openBrowser.js.map +1 -0
  90. package/dist/utils/pathExists.d.ts +2 -0
  91. package/dist/utils/pathExists.d.ts.map +1 -0
  92. package/dist/utils/pathExists.js +11 -0
  93. package/dist/utils/pathExists.js.map +1 -0
  94. package/package.json +29 -0
@@ -0,0 +1,158 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
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');
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()) {
38
+ try {
39
+ const raw = await readFile(accountsPath, 'utf8');
40
+ const parsed = JSON.parse(raw);
41
+ return normalizeAccountState(parsed);
42
+ }
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;
55
+ }
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');
64
+ 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
+ });
79
+ }
80
+ catch {
81
+ // Account history is best-effort metadata; keep login functional even if this write fails.
82
+ }
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
+ };
98
+ }
99
+ catch (error) {
100
+ if (error.code === 'ENOENT') {
101
+ return null;
102
+ }
103
+ if (error instanceof SyntaxError) {
104
+ return null;
105
+ }
106
+ throw error;
107
+ }
108
+ }
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
+ ];
124
+ }
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
+ });
157
+ }
158
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function printTuiSplash(): void;
2
+ //# sourceMappingURL=banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAgBA,wBAAgB,cAAc,IAAI,IAAI,CASrC"}
@@ -0,0 +1,22 @@
1
+ const BANNER = String.raw `
2
+ █████ █████ ████ █████
3
+ ░░███ ░░███ ░░███ ░░███
4
+ ░███████ ██████ ██████ ░███ █████ ░███ ██████ ░███████
5
+ ░███░░███ ░░░░░███ ███░░███ ░███░░███ ░███ ░░░░░███ ░███░░███
6
+ ░███ ░███ ███████ ░███ ░░░ ░██████░ ░███ ███████ ░███ ░███
7
+ ░███ ░███ ███░░███ ░███ ███ ░███░░███ ░███ ███░░███ ░███ ░███
8
+ ████ █████░░████████░░██████ ████ █████ █████░░████████ ████████
9
+ ░░░░ ░░░░░ ░░░░░░░░ ░░░░░░ ░░░░ ░░░░░ ░░░░░ ░░░░░░░░ ░░░░░░░░
10
+ `;
11
+ const TUI_TAGLINE = '☠️ 👽 hacklab 2026.2.19 (woz-preview) — we ship features faster than bugs can hide.';
12
+ let printed = false;
13
+ export function printTuiSplash() {
14
+ if (printed) {
15
+ return;
16
+ }
17
+ const GREEN = '\x1b[32m';
18
+ const RESET = '\x1b[0m';
19
+ console.log(`${GREEN}${BANNER}\n${TUI_TAGLINE}${RESET}`);
20
+ printed = true;
21
+ }
22
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;CASxB,CAAA;AAED,MAAM,WAAW,GACb,qFAAqF,CAAA;AAEzF,IAAI,OAAO,GAAG,KAAK,CAAA;AAEnB,MAAM,UAAU,cAAc;IAC1B,IAAI,OAAO,EAAE,CAAC;QACV,OAAM;IACV,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAA;IACxB,MAAM,KAAK,GAAG,SAAS,CAAA;IACvB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,MAAM,KAAK,WAAW,GAAG,KAAK,EAAE,CAAC,CAAA;IACxD,OAAO,GAAG,IAAI,CAAA;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function findRepoRoot(startDir?: string): Promise<string>;
2
+ //# sourceMappingURL=findRepoRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findRepoRoot.d.ts","sourceRoot":"","sources":["../../src/utils/findRepoRoot.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,CAAC,QAAQ,SAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB5E"}
@@ -0,0 +1,17 @@
1
+ import { dirname, resolve } from 'node:path';
2
+ import { pathExists } from './pathExists.js';
3
+ export async function findRepoRoot(startDir = process.cwd()) {
4
+ const initialPath = resolve(startDir);
5
+ let currentPath = initialPath;
6
+ while (true) {
7
+ if (await pathExists(`${currentPath}/.git`)) {
8
+ return currentPath;
9
+ }
10
+ const parentPath = dirname(currentPath);
11
+ if (parentPath === currentPath) {
12
+ return initialPath;
13
+ }
14
+ currentPath = parentPath;
15
+ }
16
+ }
17
+ //# sourceMappingURL=findRepoRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findRepoRoot.js","sourceRoot":"","sources":["../../src/utils/findRepoRoot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACrC,IAAI,WAAW,GAAG,WAAW,CAAA;IAE7B,OAAO,IAAI,EAAE,CAAC;QACV,IAAI,MAAM,UAAU,CAAC,GAAG,WAAW,OAAO,CAAC,EAAE,CAAC;YAC1C,OAAO,WAAW,CAAA;QACtB,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;QAEvC,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;YAC7B,OAAO,WAAW,CAAA;QACtB,CAAC;QAED,WAAW,GAAG,UAAU,CAAA;IAC5B,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function openBrowser(url: string): Promise<boolean>;
2
+ //# sourceMappingURL=openBrowser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openBrowser.d.ts","sourceRoot":"","sources":["../../src/utils/openBrowser.ts"],"names":[],"mappings":"AAEA,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA0B/D"}
@@ -0,0 +1,29 @@
1
+ import { spawn } from 'node:child_process';
2
+ export async function openBrowser(url) {
3
+ let command = '';
4
+ let args = [];
5
+ if (process.platform === 'darwin') {
6
+ command = 'open';
7
+ args = [url];
8
+ }
9
+ else if (process.platform === 'win32') {
10
+ command = 'cmd';
11
+ args = ['/c', 'start', '', url];
12
+ }
13
+ else {
14
+ command = 'xdg-open';
15
+ args = [url];
16
+ }
17
+ try {
18
+ const child = spawn(command, args, {
19
+ detached: true,
20
+ stdio: 'ignore',
21
+ });
22
+ child.unref();
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ //# sourceMappingURL=openBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openBrowser.js","sourceRoot":"","sources":["../../src/utils/openBrowser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IACzC,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,IAAI,GAAa,EAAE,CAAA;IAEvB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,GAAG,MAAM,CAAA;QAChB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACtC,OAAO,GAAG,KAAK,CAAA;QACf,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;IACnC,CAAC;SAAM,CAAC;QACJ,OAAO,GAAG,UAAU,CAAA;QACpB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;IAED,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YAC/B,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;SAClB,CAAC,CAAA;QAEF,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,OAAO,IAAI,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAA;IAChB,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function pathExists(path: string): Promise<boolean>;
2
+ //# sourceMappingURL=pathExists.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathExists.d.ts","sourceRoot":"","sources":["../../src/utils/pathExists.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D"}
@@ -0,0 +1,11 @@
1
+ import { access } from 'node:fs/promises';
2
+ export async function pathExists(path) {
3
+ try {
4
+ await access(path);
5
+ return true;
6
+ }
7
+ catch {
8
+ return false;
9
+ }
10
+ }
11
+ //# sourceMappingURL=pathExists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathExists.js","sourceRoot":"","sources":["../../src/utils/pathExists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IACzC,IAAI,CAAC;QACD,MAAM,MAAM,CAAC,IAAI,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAA;IAChB,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "hacklab",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "bin": {
10
+ "hacklab": "./dist/index.js"
11
+ },
12
+ "files": ["dist"],
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.json",
15
+ "dev": "tsx src/index.ts",
16
+ "test": "vitest run",
17
+ "check": "pnpm run build && pnpm run test"
18
+ },
19
+ "dependencies": {
20
+ "@clack/prompts": "^0.10.1",
21
+ "commander": "^13.1.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^24.7.2",
25
+ "tsx": "^4.20.3",
26
+ "typescript": "^5.9.3",
27
+ "vitest": "^4.0.16"
28
+ }
29
+ }