hacklab 0.0.2 → 0.3.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 (154) hide show
  1. package/README.md +44 -3
  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/config.d.ts +2 -0
  8. package/dist/commands/config.d.ts.map +1 -0
  9. package/dist/commands/config.js +48 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/drop.d.ts +2 -0
  12. package/dist/commands/drop.d.ts.map +1 -0
  13. package/dist/commands/drop.js +29 -0
  14. package/dist/commands/drop.js.map +1 -0
  15. package/dist/commands/exam.d.ts +5 -0
  16. package/dist/commands/exam.d.ts.map +1 -0
  17. package/dist/commands/exam.js +224 -0
  18. package/dist/commands/exam.js.map +1 -0
  19. package/dist/commands/join.d.ts +10 -9
  20. package/dist/commands/join.d.ts.map +1 -1
  21. package/dist/commands/join.js +213 -285
  22. package/dist/commands/join.js.map +1 -1
  23. package/dist/commands/login.d.ts +1 -15
  24. package/dist/commands/login.d.ts.map +1 -1
  25. package/dist/commands/login.js +69 -133
  26. package/dist/commands/login.js.map +1 -1
  27. package/dist/commands/scan-profile.d.ts +33 -0
  28. package/dist/commands/scan-profile.d.ts.map +1 -0
  29. package/dist/commands/scan-profile.js +279 -0
  30. package/dist/commands/scan-profile.js.map +1 -0
  31. package/dist/commands/sync.d.ts +2 -0
  32. package/dist/commands/sync.d.ts.map +1 -0
  33. package/dist/commands/sync.js +55 -0
  34. package/dist/commands/sync.js.map +1 -0
  35. package/dist/commands/whoami.d.ts +1 -3
  36. package/dist/commands/whoami.d.ts.map +1 -1
  37. package/dist/commands/whoami.js +10 -37
  38. package/dist/commands/whoami.js.map +1 -1
  39. package/dist/config.d.ts +7 -0
  40. package/dist/config.d.ts.map +1 -0
  41. package/dist/config.js +18 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/dd.d.ts +3 -0
  44. package/dist/dd.d.ts.map +1 -0
  45. package/dist/dd.js +28 -0
  46. package/dist/dd.js.map +1 -0
  47. package/dist/index.js +117 -112
  48. package/dist/index.js.map +1 -1
  49. package/dist/project-brag.d.ts +58 -0
  50. package/dist/project-brag.d.ts.map +1 -0
  51. package/dist/project-brag.js +270 -0
  52. package/dist/project-brag.js.map +1 -0
  53. package/dist/scanners/index.d.ts +24 -0
  54. package/dist/scanners/index.d.ts.map +1 -0
  55. package/dist/scanners/index.js +543 -0
  56. package/dist/scanners/index.js.map +1 -0
  57. package/dist/scanners/util.d.ts +83 -0
  58. package/dist/scanners/util.d.ts.map +1 -0
  59. package/dist/scanners/util.js +129 -0
  60. package/dist/scanners/util.js.map +1 -0
  61. package/dist/session.d.ts +17 -13
  62. package/dist/session.d.ts.map +1 -1
  63. package/dist/session.js +46 -155
  64. package/dist/session.js.map +1 -1
  65. package/dist/share-card.d.ts +29 -0
  66. package/dist/share-card.d.ts.map +1 -0
  67. package/dist/share-card.js +401 -0
  68. package/dist/share-card.js.map +1 -0
  69. package/dist/sync.d.ts +64 -0
  70. package/dist/sync.d.ts.map +1 -0
  71. package/dist/sync.js +805 -0
  72. package/dist/sync.js.map +1 -0
  73. package/dist/ui.d.ts +10 -0
  74. package/dist/ui.d.ts.map +1 -0
  75. package/dist/ui.js +21 -0
  76. package/dist/ui.js.map +1 -0
  77. package/dist/utils/openBrowser.js.map +1 -1
  78. package/package.json +36 -29
  79. package/dist/api/client.d.ts +0 -150
  80. package/dist/api/client.d.ts.map +0 -1
  81. package/dist/api/client.js +0 -246
  82. package/dist/api/client.js.map +0 -1
  83. package/dist/commands/admin-waitlist.d.ts +0 -12
  84. package/dist/commands/admin-waitlist.d.ts.map +0 -1
  85. package/dist/commands/admin-waitlist.js +0 -96
  86. package/dist/commands/admin-waitlist.js.map +0 -1
  87. package/dist/commands/brag.utils.d.ts +0 -12
  88. package/dist/commands/brag.utils.d.ts.map +0 -1
  89. package/dist/commands/brag.utils.js +0 -43
  90. package/dist/commands/brag.utils.js.map +0 -1
  91. package/dist/commands/essay.d.ts +0 -18
  92. package/dist/commands/essay.d.ts.map +0 -1
  93. package/dist/commands/essay.js +0 -117
  94. package/dist/commands/essay.js.map +0 -1
  95. package/dist/commands/explore.d.ts +0 -9
  96. package/dist/commands/explore.d.ts.map +0 -1
  97. package/dist/commands/explore.js +0 -32
  98. package/dist/commands/explore.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/link.d.ts +0 -17
  104. package/dist/commands/link.d.ts.map +0 -1
  105. package/dist/commands/link.js +0 -36
  106. package/dist/commands/link.js.map +0 -1
  107. package/dist/commands/login.utils.d.ts +0 -3
  108. package/dist/commands/login.utils.d.ts.map +0 -1
  109. package/dist/commands/login.utils.js +0 -13
  110. package/dist/commands/login.utils.js.map +0 -1
  111. package/dist/commands/new.d.ts +0 -15
  112. package/dist/commands/new.d.ts.map +0 -1
  113. package/dist/commands/new.js +0 -172
  114. package/dist/commands/new.js.map +0 -1
  115. package/dist/commands/new.utils.d.ts +0 -7
  116. package/dist/commands/new.utils.d.ts.map +0 -1
  117. package/dist/commands/new.utils.js +0 -50
  118. package/dist/commands/new.utils.js.map +0 -1
  119. package/dist/commands/onboard.d.ts +0 -10
  120. package/dist/commands/onboard.d.ts.map +0 -1
  121. package/dist/commands/onboard.js +0 -93
  122. package/dist/commands/onboard.js.map +0 -1
  123. package/dist/commands/publish.d.ts +0 -8
  124. package/dist/commands/publish.d.ts.map +0 -1
  125. package/dist/commands/publish.js +0 -47
  126. package/dist/commands/publish.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
package/README.md CHANGED
@@ -4,11 +4,12 @@ hacklab cli package.
4
4
 
5
5
  ## commands
6
6
 
7
- - `hacklab login` - authenticate via browser oauth or non-interactive token (`--token`).
7
+ - `hacklab login` - authenticate via browser oauth or non-interactive token (`--token`), with identity selection (`--as human|agent`).
8
8
  - `hacklab whoami` - show current logged in user.
9
- - `hacklab init` - create or initialize current repo as your hq repository.
9
+ - `hacklab init` - create or initialize the current repo as your lab repository.
10
+ - `hacklab brag` - read `.hacklab/project.yaml`, upload local screenshots, and sync the project to Hacklab.
10
11
  - `hacklab new` - interactive content creation (`essay`, `guide`, `course`, `research paper`, `project`).
11
- - `hacklab publish` - push current hq repo to github.
12
+ - `hacklab publish` - push the current lab repo to github.
12
13
  - `hacklab explore` - open hacklab discovery in browser.
13
14
  - `hacklab admin waitlist` - admin-only waitlist inspection (visible only for DEV/GOD accounts).
14
15
 
@@ -50,6 +51,10 @@ from repo root:
50
51
  ```bash
51
52
  pnpm --filter @hacklab/cli build
52
53
  node packages/cli/dist/index.js login --token <cli-access-token>
54
+ node packages/cli/dist/index.js login --as human
55
+ node packages/cli/dist/index.js login --as agent
56
+ node packages/cli/dist/index.js brag
57
+ node packages/cli/dist/index.js brag path/to/project.yaml
53
58
  node packages/cli/dist/index.js init --name matts-lab
54
59
  node packages/cli/dist/index.js new
55
60
  node packages/cli/dist/index.js new guide api-design-primer
@@ -64,3 +69,39 @@ environment variables:
64
69
  - `HACKLAB_SESSION_PATH` - custom path for cli session file
65
70
 
66
71
  credentials are stored at `~/.hacklab/session.json`.
72
+
73
+ ## brag manifest
74
+
75
+ `hacklab brag` looks for `.hacklab/project.yaml` in the current directory by default.
76
+
77
+ Supported fields:
78
+
79
+ - `title` - required
80
+ - `slug` - optional; defaults to the current directory name, slugified
81
+ - `description`
82
+ - `tags` - yaml list or comma-separated string
83
+ - `repoUrl` or `repo`
84
+ - `liveUrl` or `url`
85
+ - `publishedAt`, `published_at`, or `date`
86
+ - `content` - inline markdown
87
+ - `contentFile` - relative path to markdown content
88
+ - `screenshots` - up to 5 entries, each either a URL, a relative file path, or `{ path, caption }` / `{ url, caption }`
89
+
90
+ If neither `content` nor `contentFile` is provided, the CLI falls back to `README.md` or `README.mdx` in the repo root.
91
+
92
+ Example:
93
+
94
+ ```yaml
95
+ title: Shipyard
96
+ description: Fast deployment previews for side projects.
97
+ tags:
98
+ - next.js
99
+ - postgres
100
+ repo: https://github.com/acme/shipyard
101
+ url: https://shipyard.dev
102
+ contentFile: README.md
103
+ screenshots:
104
+ - screenshots/home.png
105
+ - path: screenshots/dashboard.jpg
106
+ caption: Dashboard
107
+ ```
package/bin/ddd ADDED
@@ -0,0 +1,19 @@
1
+ #!/bin/sh
2
+ # Wrapper that invokes the real dd.js entrypoint.
3
+ # When used with a noglob alias (alias ddd='noglob ddd'), zsh won't
4
+ # expand special characters like ? ! * before they reach Node.
5
+ #
6
+ # Resolve symlinks so dist/dd.js is found even when this script is invoked
7
+ # through a bin symlink (e.g. /opt/homebrew/bin/ddd -> .../hacklab/bin/ddd).
8
+ # A plain `dirname "$0"` would point at the symlink's dir, not the package.
9
+ src="$0"
10
+ while [ -L "$src" ]; do
11
+ dir="$(cd -P "$(dirname "$src")" && pwd)"
12
+ src="$(readlink "$src")"
13
+ case "$src" in
14
+ /*) ;;
15
+ *) src="$dir/$src" ;;
16
+ esac
17
+ done
18
+ dir="$(cd -P "$(dirname "$src")" && pwd)"
19
+ exec node "$dir/../dist/dd.js" "$@"
@@ -1,8 +1,5 @@
1
- type BragOptions = {
2
- appUrl?: string;
3
- as?: string;
4
- hq?: string;
1
+ export declare function parseBragArgs(args: string[]): {
2
+ manifestPath?: string;
5
3
  };
6
- export declare function bragCommand(options?: BragOptions): Promise<void>;
7
- export {};
4
+ export declare function brag(manifestPath?: string): Promise<void>;
8
5
  //# sourceMappingURL=brag.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"brag.d.ts","sourceRoot":"","sources":["../../src/commands/brag.ts"],"names":[],"mappings":"AAqBA,KAAK,WAAW,GAAG;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,EAAE,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAgOD,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2L1E"}
1
+ {"version":3,"file":"brag.d.ts","sourceRoot":"","sources":["../../src/commands/brag.ts"],"names":[],"mappings":"AASA,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAgCvE;AA6BD,wBAAsB,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,iBA8C/C"}
@@ -1,318 +1,87 @@
1
- import { execFile } from 'node:child_process';
2
- import { mkdir, writeFile } from 'node:fs/promises';
3
- import { homedir } from 'node:os';
4
- import { basename, join, resolve } from 'node:path';
5
- import { promisify } from 'node:util';
6
- import { cancel, intro, isCancel, note, outro, select, text } from '@clack/prompts';
7
- import { loadHacklabConfig } from '../lab/config.js';
8
- import { DEFAULT_CONTENT_STATUS, DEFAULT_CONTENT_VISIBILITY, } from '../lab/contentStatus.js';
9
- import { linkHqToAccount, loadKnownAccounts } from '../session.js';
10
- import { findRepoRoot } from '../utils/findRepoRoot.js';
11
- import { openBrowser } from '../utils/openBrowser.js';
12
- import { pathExists } from '../utils/pathExists.js';
13
- import { getAppUrl } from './login.utils.js';
14
- import { slugify, titleFromSlug } from './new.utils.js';
15
- import { defaultAccountOwner, parseGitHubRemote } from './brag.utils.js';
16
- const execFileAsync = promisify(execFile);
17
- function currentDate() {
18
- return new Date().toISOString().slice(0, 10);
19
- }
20
- function currentIso() {
21
- return new Date().toISOString();
22
- }
23
- async function readGitRemote(repoRoot) {
24
- try {
25
- const result = await execFileAsync('git', ['config', '--get', 'remote.origin.url'], {
26
- cwd: repoRoot,
27
- });
28
- const value = result.stdout.trim();
29
- return value || null;
30
- }
31
- catch {
32
- return null;
33
- }
34
- }
35
- async function selectAccount(as) {
36
- const accounts = await loadKnownAccounts();
37
- if (accounts.length === 0) {
38
- cancel('not logged in. run `hacklab login` first.');
39
- process.exit(1);
40
- }
41
- if (as) {
42
- const normalized = as.trim().toLowerCase();
43
- const matched = accounts.find((account) => {
44
- return (account.email.toLowerCase() === normalized ||
45
- account.nickname?.toLowerCase() === normalized);
46
- });
47
- if (!matched) {
48
- cancel(`account "${as}" not found on this machine.`);
49
- process.exit(1);
50
- }
51
- return matched;
52
- }
53
- if (accounts.length === 1) {
54
- return accounts[0];
55
- }
56
- const selected = await select({
57
- message: 'you have multiple accounts. brag as:',
58
- options: accounts.map((account) => {
59
- const label = account.nickname
60
- ? `${account.nickname} <${account.email}>`
61
- : account.email;
62
- return {
63
- value: account.email,
64
- label,
65
- };
66
- }),
67
- });
68
- if (isCancel(selected)) {
69
- cancel('brag cancelled.');
70
- process.exit(1);
71
- }
72
- const matched = accounts.find((account) => account.email === String(selected));
73
- if (!matched) {
74
- cancel('selected account is invalid.');
75
- process.exit(1);
76
- }
77
- return matched;
78
- }
79
- async function selectHqPath(account, explicitHq) {
80
- const home = process.env.HOME || homedir();
81
- const knownPaths = [
82
- account.activeHqPath,
83
- ...(account.hqPaths ?? []),
84
- ].filter((path) => Boolean(path));
85
- const normalizedKnownPaths = Array.from(new Set(knownPaths.map((path) => {
86
- if (path.startsWith('~/')) {
87
- return resolve(home, path.slice(2));
1
+ import { buildBragProjectPayload, DEFAULT_BRAG_MANIFEST_PATH, loadBragManifest, } from '../project-brag.js';
2
+ import { loadSession } from '../session.js';
3
+ import { dim, error, info, success } from '../ui.js';
4
+ export function parseBragArgs(args) {
5
+ let manifestPath;
6
+ for (let index = 0; index < args.length; index++) {
7
+ const arg = args[index];
8
+ if ((arg === '-f' || arg === '--file') && args[index + 1]) {
9
+ manifestPath = args[index + 1];
10
+ index++;
11
+ continue;
88
12
  }
89
- return resolve(path);
90
- })));
91
- const fallback = account.nickname ? `~/gh/${account.nickname}-hq` : '~/gh/my-hq';
92
- let candidatePath = explicitHq
93
- ? explicitHq.startsWith('~/')
94
- ? resolve(home, explicitHq.slice(2))
95
- : resolve(explicitHq)
96
- : normalizedKnownPaths[0];
97
- while (true) {
98
- if (candidatePath) {
99
- const confirm = await select({
100
- message: `use hq at ${candidatePath}?`,
101
- options: [
102
- {
103
- value: 'yes',
104
- label: 'yes, continue',
105
- },
106
- {
107
- value: 'change',
108
- label: 'change location',
109
- },
110
- {
111
- value: 'exit',
112
- label: 'exit',
113
- },
114
- ],
115
- });
116
- if (isCancel(confirm) || String(confirm) === 'exit') {
117
- cancel('brag cancelled.');
118
- process.exit(1);
119
- }
120
- if (String(confirm) === 'yes') {
121
- return candidatePath;
122
- }
13
+ if (arg === '-h' || arg === '--help') {
14
+ console.log('usage: hacklab brag [path]');
15
+ console.log(' or: hacklab brag --file .hacklab/project.yaml');
16
+ process.exit(0);
123
17
  }
124
- const input = await text({
125
- message: 'where is your hq repo?',
126
- placeholder: fallback,
127
- });
128
- if (isCancel(input)) {
129
- cancel('brag cancelled.');
18
+ if (arg.startsWith('-')) {
19
+ console.error(`unknown flag: ${arg}`);
130
20
  process.exit(1);
131
21
  }
132
- const value = String(input).trim();
133
- if (!value) {
134
- cancel('hq path is required. run `hacklab join` if you do not have an hq yet.');
22
+ if (manifestPath) {
23
+ console.error('usage: hacklab brag [path]');
135
24
  process.exit(1);
136
25
  }
137
- candidatePath = value.startsWith('~/') ? resolve(home, value.slice(2)) : resolve(value);
26
+ manifestPath = arg;
138
27
  }
28
+ return { manifestPath };
139
29
  }
140
- function buildProjectDraft(options) {
141
- const date = currentDate();
142
- const lines = [
143
- '---',
144
- `title: ${options.title}`,
145
- 'type: project',
146
- `status: ${DEFAULT_CONTENT_STATUS}`,
147
- `visibility: ${DEFAULT_CONTENT_VISIBILITY}`,
148
- 'authors:',
149
- ` - ${options.owner}`,
150
- options.sourceRepo ? `source_repo: ${options.sourceRepo}` : null,
151
- options.sourceUrl ? `source_url: ${options.sourceUrl}` : null,
152
- `created_at: ${date}`,
153
- `updated_at: ${date}`,
154
- '---',
155
- '',
156
- `# ${options.title}`,
157
- '',
158
- options.description,
159
- '',
160
- '## why this project',
161
- '',
162
- options.pitch || 'share why this project matters.',
163
- '',
164
- '## what i learned',
165
- '',
166
- options.lesson || 'write what you learned while building this.',
167
- '',
168
- ].filter((line) => line !== null);
169
- return lines.join('\n');
30
+ async function uploadScreenshot(session, input) {
31
+ const response = await fetch(`${session.appUrl}/api/screenshots`, {
32
+ method: 'POST',
33
+ headers: {
34
+ 'Content-Type': 'application/json',
35
+ Authorization: `Bearer ${session.token}`,
36
+ },
37
+ body: JSON.stringify({
38
+ image: input.base64,
39
+ filename: input.filename,
40
+ contentType: input.contentType,
41
+ }),
42
+ });
43
+ const data = await response.json().catch(() => null);
44
+ if (!response.ok || !data?.url) {
45
+ throw new Error(data?.error ?? `Screenshot upload failed (${response.status})`);
46
+ }
47
+ return data.url;
170
48
  }
171
- export async function bragCommand(options = {}) {
172
- intro('brag your project');
173
- const repoRoot = await findRepoRoot();
174
- if (!(await pathExists(join(repoRoot, '.git')))) {
175
- cancel('this command must be run inside a git repository.');
49
+ export async function brag(manifestPath) {
50
+ const session = await loadSession();
51
+ if (!session) {
52
+ error('not logged in');
53
+ info(`run ${dim('hacklab login')} first`);
176
54
  process.exit(1);
177
55
  }
178
- const account = await selectAccount(options.as);
179
- let hqPath = '';
180
- let hqConfig = null;
181
- while (!hqConfig) {
182
- hqPath = await selectHqPath(account, options.hq);
183
- hqConfig = await loadHacklabConfig(hqPath);
184
- if (!hqConfig) {
185
- note(`could not find a valid hacklab hq at ${hqPath}. run \`hacklab join\` or \`hacklab init\` there first.`, 'hq');
186
- options.hq = undefined;
187
- }
188
- }
189
- await linkHqToAccount(account.email, hqPath);
190
- let remoteUrl = await readGitRemote(repoRoot);
191
- let parsedRemote = remoteUrl ? parseGitHubRemote(remoteUrl) : null;
192
- if (!parsedRemote) {
193
- const remoteInput = await text({
194
- message: 'github repository url',
195
- placeholder: 'https://github.com/owner/repo',
56
+ try {
57
+ const manifest = await loadBragManifest({ manifestPath });
58
+ const manifestLabel = manifestPath ?? DEFAULT_BRAG_MANIFEST_PATH;
59
+ info(`reading ${manifestLabel}`);
60
+ const payload = await buildBragProjectPayload(manifest, async (input) => {
61
+ info(`uploading ${input.filename}`);
62
+ return await uploadScreenshot(session, input);
196
63
  });
197
- if (isCancel(remoteInput)) {
198
- cancel('brag cancelled.');
199
- process.exit(1);
64
+ info(`syncing ${payload.title}`);
65
+ const response = await fetch(`${session.appUrl}/api/projects`, {
66
+ method: 'POST',
67
+ headers: {
68
+ 'Content-Type': 'application/json',
69
+ Authorization: `Bearer ${session.token}`,
70
+ },
71
+ body: JSON.stringify(payload),
72
+ });
73
+ const data = await response.json().catch(() => null);
74
+ if (!response.ok) {
75
+ throw new Error(data?.error ?? `Project sync failed (${response.status})`);
200
76
  }
201
- remoteUrl = String(remoteInput).trim();
202
- parsedRemote = parseGitHubRemote(remoteUrl);
203
- if (!parsedRemote) {
204
- cancel('invalid github repository url.');
205
- process.exit(1);
77
+ success('project synced.');
78
+ if (session.handle) {
79
+ info(`${session.appUrl}/${session.handle}/${payload.slug}`);
206
80
  }
207
81
  }
208
- const repoName = parsedRemote?.repo || basename(repoRoot);
209
- const defaultSlug = slugify(repoName);
210
- const defaultTitle = titleFromSlug(defaultSlug || 'my-project');
211
- const titleInput = await text({
212
- message: 'project title',
213
- placeholder: defaultTitle,
214
- });
215
- if (isCancel(titleInput)) {
216
- cancel('brag cancelled.');
217
- process.exit(1);
218
- }
219
- const title = String(titleInput).trim() || defaultTitle;
220
- const descriptionInput = await text({
221
- message: 'one-line description',
222
- placeholder: 'what did you build?',
223
- });
224
- if (isCancel(descriptionInput)) {
225
- cancel('brag cancelled.');
226
- process.exit(1);
227
- }
228
- const description = String(descriptionInput).trim();
229
- if (!description) {
230
- cancel('description is required.');
82
+ catch (err) {
83
+ error(err instanceof Error ? err.message : String(err));
231
84
  process.exit(1);
232
85
  }
233
- const pitchInput = await text({
234
- message: 'why is this cool? (optional)',
235
- });
236
- if (isCancel(pitchInput)) {
237
- cancel('brag cancelled.');
238
- process.exit(1);
239
- }
240
- const lessonInput = await text({
241
- message: 'what did you learn? (optional)',
242
- });
243
- if (isCancel(lessonInput)) {
244
- cancel('brag cancelled.');
245
- process.exit(1);
246
- }
247
- const owner = defaultAccountOwner(account);
248
- const projectSlug = defaultSlug || slugify(title) || 'project';
249
- const targetPath = join(hqPath, hqConfig.contentDirs.projects, projectSlug, 'README.mdx');
250
- if (await pathExists(targetPath)) {
251
- const action = await select({
252
- message: 'project already exists in hq. what now?',
253
- options: [
254
- { value: 'update', label: 'update existing draft' },
255
- { value: 'cancel', label: 'cancel' },
256
- ],
257
- });
258
- if (isCancel(action) || String(action) === 'cancel') {
259
- cancel('brag cancelled.');
260
- process.exit(1);
261
- }
262
- }
263
- await mkdir(join(repoRoot, '.hacklab'), { recursive: true });
264
- const manifest = {
265
- schemaVersion: 1,
266
- repoType: 'project',
267
- hq: {
268
- ...(hqConfig.labId ? { labId: hqConfig.labId } : {}),
269
- labSlug: hqConfig.labSlug,
270
- path: hqPath,
271
- },
272
- owner,
273
- authors: [owner],
274
- source: {
275
- provider: 'github',
276
- ...(parsedRemote?.fullName ? { repo: parsedRemote.fullName } : {}),
277
- ...(parsedRemote?.httpsUrl
278
- ? { url: parsedRemote.httpsUrl }
279
- : remoteUrl
280
- ? { url: remoteUrl }
281
- : {}),
282
- },
283
- project: {
284
- title,
285
- description,
286
- pitch: String(pitchInput).trim() || undefined,
287
- lesson: String(lessonInput).trim() || undefined,
288
- },
289
- createdAt: currentIso(),
290
- updatedAt: currentIso(),
291
- };
292
- await writeFile(join(repoRoot, '.hacklab', 'repo.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
293
- await mkdir(join(hqPath, hqConfig.contentDirs.projects, projectSlug), {
294
- recursive: true,
295
- });
296
- const draft = buildProjectDraft({
297
- title,
298
- description,
299
- owner,
300
- sourceRepo: parsedRemote?.fullName,
301
- sourceUrl: parsedRemote?.httpsUrl,
302
- pitch: String(pitchInput).trim() || undefined,
303
- lesson: String(lessonInput).trim() || undefined,
304
- });
305
- await writeFile(targetPath, draft, 'utf8');
306
- note(`saved repo manifest at ${join(repoRoot, '.hacklab', 'repo.json')}`, 'manifest');
307
- note(`created draft in hq at ${targetPath}`, 'hq draft');
308
- const previewUrl = `${getAppUrl(options.appUrl)}/cli/draft?title=${encodeURIComponent(title)}&slug=${encodeURIComponent(projectSlug)}&type=project`;
309
- const opened = await openBrowser(previewUrl);
310
- if (opened) {
311
- note('opened project draft on hacklab website.', 'preview');
312
- }
313
- else {
314
- note(`open this url:\n${previewUrl}`, 'preview');
315
- }
316
- outro('project added to hacklab as draft.');
317
86
  }
318
87
  //# sourceMappingURL=brag.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"brag.js","sourceRoot":"","sources":["../../src/commands/brag.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brag.js","sourceRoot":"","sources":["../../src/commands/brag.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function configCommand(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,iBAgDjD"}
@@ -0,0 +1,48 @@
1
+ import { loadConfig, saveConfig } from '../config.js';
2
+ import { dim, error, info, success } from '../ui.js';
3
+ export async function configCommand(args) {
4
+ const [key, ...valueParts] = args;
5
+ const value = valueParts.join(' ');
6
+ if (!key) {
7
+ const config = await loadConfig();
8
+ console.log('');
9
+ info('current config:');
10
+ if (config.cursorApiKey) {
11
+ info(` cursor-api-key: ${dim(`${config.cursorApiKey.slice(0, 8)}...`)}`);
12
+ }
13
+ if (config.cursorEmail) {
14
+ info(` cursor-email: ${config.cursorEmail}`);
15
+ }
16
+ if (!config.cursorApiKey && !config.cursorEmail) {
17
+ info(` ${dim('(empty)')}`);
18
+ }
19
+ console.log('');
20
+ info('available keys:');
21
+ info(` ${dim('cursor-api-key')} your Cursor team API key`);
22
+ info(` ${dim('cursor-email')} your Cursor account email`);
23
+ console.log('');
24
+ return;
25
+ }
26
+ if (!value) {
27
+ error(`usage: hacklab config ${key} <value>`);
28
+ process.exit(1);
29
+ }
30
+ const config = await loadConfig();
31
+ switch (key) {
32
+ case 'cursor-api-key':
33
+ config.cursorApiKey = value;
34
+ await saveConfig(config);
35
+ success(`cursor-api-key saved`);
36
+ break;
37
+ case 'cursor-email':
38
+ config.cursorEmail = value;
39
+ await saveConfig(config);
40
+ success(`cursor-email set to ${value}`);
41
+ break;
42
+ default:
43
+ error(`unknown config key: ${key}`);
44
+ info(`available: cursor-api-key, cursor-email`);
45
+ process.exit(1);
46
+ }
47
+ }
48
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAEpD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc;IAChD,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAA;IACjC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAElC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;QACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACvB,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,IAAI,CAAC,qBAAqB,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3E,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,IAAI,CAAC,qBAAqB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QACjD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAChD,IAAI,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;QAC7B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACvB,IAAI,CAAC,KAAK,GAAG,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAA;QAC5D,IAAI,CAAC,KAAK,GAAG,CAAC,cAAc,CAAC,+BAA+B,CAAC,CAAA;QAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAM;IACR,CAAC;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,CAAC,yBAAyB,GAAG,UAAU,CAAC,CAAA;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;IAEjC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,gBAAgB;YACnB,MAAM,CAAC,YAAY,GAAG,KAAK,CAAA;YAC3B,MAAM,UAAU,CAAC,MAAM,CAAC,CAAA;YACxB,OAAO,CAAC,sBAAsB,CAAC,CAAA;YAC/B,MAAK;QACP,KAAK,cAAc;YACjB,MAAM,CAAC,WAAW,GAAG,KAAK,CAAA;YAC1B,MAAM,UAAU,CAAC,MAAM,CAAC,CAAA;YACxB,OAAO,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAA;YACvC,MAAK;QACP;YACE,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAA;YACnC,IAAI,CAAC,yCAAyC,CAAC,CAAA;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function drop(content: string, url?: string): Promise<void>;
2
+ //# sourceMappingURL=drop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop.d.ts","sourceRoot":"","sources":["../../src/commands/drop.ts"],"names":[],"mappings":"AAGA,wBAAsB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,iBA8BvD"}
@@ -0,0 +1,29 @@
1
+ import { loadSession } from '../session.js';
2
+ import { dim, error, info, success } from '../ui.js';
3
+ export async function drop(content, url) {
4
+ const session = await loadSession();
5
+ if (!session) {
6
+ error('not logged in');
7
+ info(`run ${dim('hacklab login')} first`);
8
+ process.exit(1);
9
+ }
10
+ if (content.length > 280) {
11
+ error(`too long — ${content.length}/280 chars`);
12
+ process.exit(1);
13
+ }
14
+ const res = await fetch(`${session.appUrl}/api/drops`, {
15
+ method: 'POST',
16
+ headers: {
17
+ 'Content-Type': 'application/json',
18
+ Authorization: `Bearer ${session.token}`,
19
+ },
20
+ body: JSON.stringify({ content, url }),
21
+ });
22
+ if (!res.ok) {
23
+ const data = await res.json().catch(() => null);
24
+ error(data?.error ?? `failed (${res.status})`);
25
+ process.exit(1);
26
+ }
27
+ success('dropped.');
28
+ }
29
+ //# sourceMappingURL=drop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop.js","sourceRoot":"","sources":["../../src/commands/drop.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,IAAI,CAAC,OAAe,EAAE,GAAY;IACtD,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,QAAQ,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACzB,KAAK,CAAC,cAAc,OAAO,CAAC,MAAM,YAAY,CAAC,CAAA;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,YAAY,EAAE;QACrD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,OAAO,CAAC,KAAK,EAAE;SACzC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;KACvC,CAAC,CAAA;IAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC/C,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,WAAW,GAAG,CAAC,MAAM,GAAG,CAAC,CAAA;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,CAAC,UAAU,CAAC,CAAA;AACrB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function exam(flags: {
2
+ pyro: boolean;
3
+ hacker: boolean;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=exam.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exam.d.ts","sourceRoot":"","sources":["../../src/commands/exam.ts"],"names":[],"mappings":"AAsCA,wBAAsB,IAAI,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,iBA+PnE"}