hacklab 0.7.4 → 0.8.5

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 (87) hide show
  1. package/README.md +16 -1
  2. package/dist/api-client.d.ts +18 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +40 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/commands/book.d.ts +14 -0
  7. package/dist/commands/book.d.ts.map +1 -0
  8. package/dist/commands/book.js +90 -0
  9. package/dist/commands/book.js.map +1 -0
  10. package/dist/commands/chat.d.ts +1 -1
  11. package/dist/commands/chat.d.ts.map +1 -1
  12. package/dist/commands/chat.js +3 -0
  13. package/dist/commands/chat.js.map +1 -1
  14. package/dist/commands/drop.d.ts +1 -1
  15. package/dist/commands/drop.js +1 -1
  16. package/dist/commands/hacker.d.ts.map +1 -1
  17. package/dist/commands/hacker.js +24 -30
  18. package/dist/commands/hacker.js.map +1 -1
  19. package/dist/commands/join.d.ts +4 -2
  20. package/dist/commands/join.d.ts.map +1 -1
  21. package/dist/commands/join.js +78 -45
  22. package/dist/commands/join.js.map +1 -1
  23. package/dist/commands/keys.d.ts +2 -0
  24. package/dist/commands/keys.d.ts.map +1 -0
  25. package/dist/commands/keys.js +138 -0
  26. package/dist/commands/keys.js.map +1 -0
  27. package/dist/commands/login.d.ts.map +1 -1
  28. package/dist/commands/login.js +3 -6
  29. package/dist/commands/login.js.map +1 -1
  30. package/dist/commands/org.d.ts +7 -7
  31. package/dist/commands/org.d.ts.map +1 -1
  32. package/dist/commands/org.js +407 -32
  33. package/dist/commands/org.js.map +1 -1
  34. package/dist/commands/profile.d.ts +60 -0
  35. package/dist/commands/profile.d.ts.map +1 -0
  36. package/dist/commands/profile.js +474 -0
  37. package/dist/commands/profile.js.map +1 -0
  38. package/dist/commands/project.d.ts +5 -0
  39. package/dist/commands/project.d.ts.map +1 -0
  40. package/dist/commands/project.js +387 -0
  41. package/dist/commands/project.js.map +1 -0
  42. package/dist/commands/scout.d.ts +18 -0
  43. package/dist/commands/scout.d.ts.map +1 -0
  44. package/dist/commands/scout.js +232 -0
  45. package/dist/commands/scout.js.map +1 -0
  46. package/dist/field-normalize.d.ts +4 -0
  47. package/dist/field-normalize.d.ts.map +1 -0
  48. package/dist/field-normalize.js +8 -0
  49. package/dist/field-normalize.js.map +1 -0
  50. package/dist/index.js +10 -3
  51. package/dist/index.js.map +1 -1
  52. package/dist/machine.d.ts +15 -0
  53. package/dist/machine.d.ts.map +1 -0
  54. package/dist/machine.js +64 -0
  55. package/dist/machine.js.map +1 -0
  56. package/dist/org-fields.d.ts +57 -0
  57. package/dist/org-fields.d.ts.map +1 -0
  58. package/dist/org-fields.js +167 -0
  59. package/dist/org-fields.js.map +1 -0
  60. package/dist/posthog.d.ts +34 -5
  61. package/dist/posthog.d.ts.map +1 -1
  62. package/dist/posthog.js +217 -13
  63. package/dist/posthog.js.map +1 -1
  64. package/dist/project-infer.d.ts +50 -0
  65. package/dist/project-infer.d.ts.map +1 -0
  66. package/dist/project-infer.js +211 -0
  67. package/dist/project-infer.js.map +1 -0
  68. package/dist/registry.d.ts.map +1 -1
  69. package/dist/registry.js +37 -9
  70. package/dist/registry.js.map +1 -1
  71. package/dist/sync.d.ts +3 -0
  72. package/dist/sync.d.ts.map +1 -1
  73. package/dist/sync.js +7 -0
  74. package/dist/sync.js.map +1 -1
  75. package/dist/ui.d.ts +1 -0
  76. package/dist/ui.d.ts.map +1 -1
  77. package/dist/ui.js +5 -0
  78. package/dist/ui.js.map +1 -1
  79. package/package.json +1 -1
  80. package/dist/commands/brag.d.ts +0 -5
  81. package/dist/commands/brag.d.ts.map +0 -1
  82. package/dist/commands/brag.js +0 -92
  83. package/dist/commands/brag.js.map +0 -1
  84. package/dist/project-brag.d.ts +0 -58
  85. package/dist/project-brag.d.ts.map +0 -1
  86. package/dist/project-brag.js +0 -270
  87. package/dist/project-brag.js.map +0 -1
package/dist/posthog.js CHANGED
@@ -1,20 +1,224 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { promises as fs } from 'node:fs';
3
+ import { createRequire } from 'node:module';
4
+ import { dirname, join } from 'node:path';
1
5
  import { PostHog } from 'posthog-node';
2
- export const posthog = new PostHog(process.env.POSTHOG_API_KEY ??
3
- 'phc_CT4u3J62yYaAHUcnYKjmnpAGXTrWqv7ZbmvYQcUTEACK', {
4
- host: process.env.POSTHOG_HOST ?? 'https://eu.i.posthog.com',
5
- flushAt: 1,
6
- flushInterval: 0,
7
- enableExceptionAutocapture: true,
8
- });
6
+ import { envNameForUrl, getSessionPath, resolveAppUrl } from './session.js';
7
+ import { dim } from './ui.js';
8
+ // Single source of the published version (one level up from this module in both
9
+ // `dist/` and `src/`), tagged onto every event so we can slice by CLI version.
10
+ const require = createRequire(import.meta.url);
11
+ const { version: CLI_VERSION } = require('../package.json');
12
+ // The PostHog *project* API key for the CLI's own project (id 226792, separate
13
+ // from the web app's project 226288). It's a publishable client key (phc_…,
14
+ // write-only) that ships inside the published npm package regardless, so
15
+ // committing it here is fine. `POSTHOG_API_KEY` overrides it for dev/testing.
16
+ // The CLI never reads Vercel env (it runs on users' machines), so its key lives
17
+ // here, not in Vercel.
18
+ const PROJECT_API_KEY = process.env.POSTHOG_API_KEY ??
19
+ 'phc_oCCCCjjTXkmknHh5gjEhsqJNuJ77BqsZUU96MRtAHoYQ';
20
+ const HOST = process.env.POSTHOG_HOST ?? 'https://eu.i.posthog.com';
21
+ // Telemetry state (anon id + one-time-notice flag) lives next to the session
22
+ // file, so it honors HACKLAB_SESSION_PATH exactly like the update-check cache.
23
+ function telemetryPath() {
24
+ return join(dirname(getSessionPath()), 'telemetry.json');
25
+ }
26
+ /**
27
+ * Telemetry is opt-OUT. It's off when the user sets `HACKLAB_NO_TELEMETRY`
28
+ * (mirrors `HACKLAB_NO_UPDATE_CHECK`) or the cross-tool `DO_NOT_TRACK` standard
29
+ * (https://consoledonottrack.com). Checked at every entry point, so a disabled
30
+ * CLI never constructs a client, phones home, or installs exception handlers.
31
+ */
32
+ export function isTelemetryDisabled() {
33
+ if (process.env.HACKLAB_NO_TELEMETRY)
34
+ return true;
35
+ const dnt = process.env.DO_NOT_TRACK;
36
+ return dnt === '1' || dnt === 'true';
37
+ }
38
+ async function readState() {
39
+ try {
40
+ return JSON.parse(await fs.readFile(telemetryPath(), 'utf8'));
41
+ }
42
+ catch {
43
+ return {};
44
+ }
45
+ }
46
+ async function writeState(state) {
47
+ try {
48
+ await fs.mkdir(dirname(telemetryPath()), { recursive: true });
49
+ await fs.writeFile(telemetryPath(), `${JSON.stringify(state, null, 2)}\n`, 'utf8');
50
+ }
51
+ catch {
52
+ // Best-effort: a failed write just means a fresh anon id / re-shown notice.
53
+ }
54
+ }
55
+ /**
56
+ * A stable anonymous device id for events that fire before (or without) login.
57
+ * Generated once and persisted; on login we `alias` it to the real handle so
58
+ * PostHog stitches the anonymous history onto the identified user.
59
+ */
60
+ async function getAnonymousId() {
61
+ const state = await readState();
62
+ if (state.anonymousId)
63
+ return state.anonymousId;
64
+ const anonymousId = `anon_${randomUUID()}`;
65
+ await writeState({ ...state, anonymousId });
66
+ return anonymousId;
67
+ }
68
+ let client = null;
69
+ function getClient() {
70
+ if (!client) {
71
+ client = new PostHog(PROJECT_API_KEY, {
72
+ host: HOST,
73
+ // We flush explicitly after every capture (and on shutdown), so disable
74
+ // both of posthog-node's background-flush triggers: the count trigger
75
+ // (flushAt — set high enough that a single CLI run never hits it) and the
76
+ // timer (flushInterval: 0). This matters because a background flush routes
77
+ // its failure to a hardcoded console.error we can't intercept — it would
78
+ // dump a network stack trace into the user's terminal on a flaky
79
+ // connection. Our explicit flush rejects into our own try/catch instead,
80
+ // so a telemetry failure stays silent.
81
+ flushAt: 1000,
82
+ flushInterval: 0,
83
+ // Best-effort telemetry: don't retry a failed send. The default is 3
84
+ // retries with a 3s backoff, and that backoff timer is what keeps a
85
+ // one-shot CLI alive for ~10s after the command visibly finished when the
86
+ // network is down. No retries → fail fast → the process exits promptly.
87
+ fetchRetryCount: 0,
88
+ // Tighter than the 10s default so a black-holed connection gives up fast.
89
+ requestTimeout: 3000,
90
+ enableExceptionAutocapture: true,
91
+ });
92
+ }
93
+ return client;
94
+ }
95
+ /**
96
+ * Properties attached to every CLI event. CLI and web now live in separate
97
+ * PostHog projects, but we still tag `source: 'cli'` as a cheap, explicit
98
+ * discriminator — handy if the two datasets are ever combined, and it costs
99
+ * nothing to keep.
100
+ */
101
+ function defaultProperties() {
102
+ return {
103
+ source: 'cli',
104
+ cli_version: CLI_VERSION,
105
+ os: process.platform,
106
+ arch: process.arch,
107
+ node_version: process.versions.node,
108
+ environment: envNameForUrl(resolveAppUrl()) ?? 'unknown',
109
+ };
110
+ }
111
+ // Never let a stuck network hold up the CLI: cap any send at a couple seconds
112
+ // and move on. The timer is unref'd so it can't by itself keep the process
113
+ // alive after the real work is done.
114
+ async function withTimeout(p, ms = 2000) {
115
+ await Promise.race([
116
+ p.catch(() => undefined),
117
+ new Promise((resolve) => {
118
+ const t = setTimeout(resolve, ms);
119
+ t.unref?.();
120
+ }),
121
+ ]);
122
+ }
9
123
  /**
10
- * Capture an event and immediately flush it to PostHog. Since the CLI is a
11
- * short-lived process, flushing after every capture ensures the event is sent
12
- * before the process exits. No-ops silently if distinctId is absent.
124
+ * Capture an event and flush it. Falls back to the anonymous device id when no
125
+ * handle is given, so pre-auth usage is still counted (and later stitched onto
126
+ * the user via `identifyUser`). Fire-and-forget: gated on opt-out, wrapped so it
127
+ * can never slow down or break the command that called it.
13
128
  */
14
129
  export async function captureEvent(distinctId, event, properties) {
15
- if (!distinctId)
130
+ if (isTelemetryDisabled())
16
131
  return;
17
- posthog.capture({ distinctId, event, properties });
18
- await posthog.flush();
132
+ try {
133
+ const id = distinctId ?? (await getAnonymousId());
134
+ const ph = getClient();
135
+ ph.capture({
136
+ distinctId: id,
137
+ event,
138
+ properties: { ...defaultProperties(), ...properties },
139
+ });
140
+ await withTimeout(ph.flush());
141
+ }
142
+ catch {
143
+ // Telemetry must never break a command. Swallow everything.
144
+ }
145
+ }
146
+ /**
147
+ * Identify the logged-in user and merge any anonymous pre-login history onto
148
+ * them. `properties` is passed straight through (callers set `$set` /
149
+ * `$set_once`). Opt-out gated and fully wrapped.
150
+ */
151
+ export async function identifyUser(handle, properties) {
152
+ if (isTelemetryDisabled())
153
+ return;
154
+ try {
155
+ const ph = getClient();
156
+ const { anonymousId } = await readState();
157
+ if (anonymousId && anonymousId !== handle) {
158
+ ph.alias({ distinctId: handle, alias: anonymousId });
159
+ }
160
+ ph.identify({ distinctId: handle, properties });
161
+ await withTimeout(ph.flush());
162
+ }
163
+ catch {
164
+ // Identification is best-effort — never break login/join over it.
165
+ }
166
+ }
167
+ /** Report an unhandled error to PostHog. Opt-out gated and wrapped. */
168
+ export async function captureException(error, distinctId) {
169
+ if (isTelemetryDisabled())
170
+ return;
171
+ try {
172
+ const ph = getClient();
173
+ const id = distinctId ?? (await getAnonymousId());
174
+ ph.captureException(error, id, defaultProperties());
175
+ await withTimeout(ph.flush());
176
+ }
177
+ catch {
178
+ // Swallow — a telemetry failure must not mask the original error.
179
+ }
180
+ }
181
+ /**
182
+ * Final drain before the process exits. No-op if telemetry never initialized.
183
+ * Uses flush(), not shutdown(): shutdown() routes a failed flush to a hardcoded
184
+ * console.error (a network stack trace in the user's terminal), whereas flush()
185
+ * rejects into our own catch and stays silent. There are no background timers to
186
+ * clear (flushInterval is 0), so flush() is a complete drain here.
187
+ */
188
+ export async function shutdownTelemetry() {
189
+ if (!client)
190
+ return;
191
+ try {
192
+ await withTimeout(client.flush());
193
+ }
194
+ catch {
195
+ // Best-effort final flush.
196
+ }
197
+ }
198
+ /**
199
+ * One-time, one-line notice that the CLI collects anonymous usage, with the
200
+ * opt-out. Interactive only (never in pipes / CI / the quiet daily run), shown
201
+ * once per machine (flagged in telemetry.json). Mirrors the update-check nudge:
202
+ * stderr, TTY-gated, and wrapped so it can never break or delay a command.
203
+ */
204
+ export async function maybePrintTelemetryNotice() {
205
+ try {
206
+ if (isTelemetryDisabled())
207
+ return;
208
+ if (!process.stdout.isTTY)
209
+ return;
210
+ const state = await readState();
211
+ if (state.noticeShownAt)
212
+ return;
213
+ await writeState({
214
+ ...state,
215
+ anonymousId: state.anonymousId ?? `anon_${randomUUID()}`,
216
+ noticeShownAt: new Date().toISOString(),
217
+ });
218
+ process.stderr.write(`${dim('hacklab collects anonymous usage analytics to improve the CLI — opt out with HACKLAB_NO_TELEMETRY=1 (or DO_NOT_TRACK=1).')}\n`);
219
+ }
220
+ catch {
221
+ // A notice must never break or delay the actual command.
222
+ }
19
223
  }
20
224
  //# sourceMappingURL=posthog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"posthog.js","sourceRoot":"","sources":["../src/posthog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAChC,OAAO,CAAC,GAAG,CAAC,eAAe;IACzB,kDAAkD,EACpD;IACE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,0BAA0B;IAC5D,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,0BAA0B,EAAE,IAAI;CACjC,CACF,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAA8B,EAC9B,KAAa,EACb,UAAoC;IAEpC,IAAI,CAAC,UAAU;QAAE,OAAM;IACvB,OAAO,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAA;IAClD,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA;AACvB,CAAC"}
1
+ {"version":3,"file":"posthog.js","sourceRoot":"","sources":["../src/posthog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ export type RepoRemote = {
2
+ /** Canonical https URL, no trailing `.git`. */
3
+ url: string;
4
+ /** `owner/name` host path when it parses, e.g. `acme/hacklab`. */
5
+ owner: string | null;
6
+ name: string;
7
+ };
8
+ export type InferredProject = {
9
+ slug: string;
10
+ title: string;
11
+ description: string | null;
12
+ tags: string[];
13
+ repoUrl: string | null;
14
+ liveUrl: string | null;
15
+ /** Full README markdown, the project page's long-form content. */
16
+ content: string | null;
17
+ };
18
+ /**
19
+ * Normalize any common git remote spelling to a canonical https URL.
20
+ * `git@github.com:acme/hacklab.git`, `ssh://git@github.com/acme/hacklab.git`,
21
+ * and `https://github.com/acme/hacklab.git` all become
22
+ * `https://github.com/acme/hacklab`.
23
+ */
24
+ export declare function normalizeRepoUrl(remote: string): RepoRemote | null;
25
+ /** Repo-name-derived slug matching the server's PROJECT_SLUG_PATTERN. */
26
+ export declare function slugFromName(name: string): string;
27
+ /** The first ATX heading's text, e.g. `# hacklab` -> `hacklab`. */
28
+ export declare function titleFromReadme(markdown: string): string | null;
29
+ /**
30
+ * The first prose paragraph of a README: skips headings, badge/image-only
31
+ * lines, block quotes, code fences, and HTML, then joins the first run of
32
+ * plain text lines. This is the description fallback when package.json has
33
+ * none.
34
+ */
35
+ export declare function firstParagraph(markdown: string): string | null;
36
+ /** package.json keywords first, then detected stack tags, deduped, capped. */
37
+ export declare function detectTags(pkg: {
38
+ keywords?: unknown;
39
+ dependencies?: Record<string, string>;
40
+ devDependencies?: Record<string, string>;
41
+ }): string[];
42
+ /** The repo root for cwd, or null when not inside a git work tree. */
43
+ export declare function findRepoRoot(cwd: string): Promise<string | null>;
44
+ /**
45
+ * Build the best project we can from the repo at `root`. Precedence per
46
+ * field: README title > repo name; package.json description > README first
47
+ * paragraph; homepage is the only liveUrl source (anything else is guessing).
48
+ */
49
+ export declare function inferProject(root: string): Promise<InferredProject>;
50
+ //# sourceMappingURL=project-infer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-infer.d.ts","sourceRoot":"","sources":["../src/project-infer.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,UAAU,GAAG;IACvB,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAA;IACX,kEAAkE;IAClE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,kEAAkE;IAClE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAwBlE;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASjD;AAWD,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiC9D;AA2BD,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,GAAG,EAAE;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACzC,GAAG,MAAM,EAAE,CAqBX;AAWD,sEAAsE;AACtE,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEtE;AAmBD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAoCzE"}
@@ -0,0 +1,211 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ // Infer a publishable project from the repo you're standing in — the machine
6
+ // already knows the title, description, links, and tags, so no manifest file
7
+ // is ever required. Everything here is best-effort: a missing README or
8
+ // package.json just means fewer prefilled fields, never a failure. The only
9
+ // hard requirement is a git repo (identity + idempotency come from the
10
+ // remote), enforced by the command, not here.
11
+ const execFileAsync = promisify(execFile);
12
+ /**
13
+ * Normalize any common git remote spelling to a canonical https URL.
14
+ * `git@github.com:acme/hacklab.git`, `ssh://git@github.com/acme/hacklab.git`,
15
+ * and `https://github.com/acme/hacklab.git` all become
16
+ * `https://github.com/acme/hacklab`.
17
+ */
18
+ export function normalizeRepoUrl(remote) {
19
+ const trimmed = remote.trim();
20
+ if (!trimmed)
21
+ return null;
22
+ const scp = trimmed.match(/^(?:[\w.-]+@)?([\w.-]+):(?!\/\/)(.+)$/);
23
+ const url = trimmed.match(/^(?:https?|ssh|git):\/\/(?:[\w.-]+@)?([\w.-]+)(?::\d+)?\/(.+)$/);
24
+ const host = url?.[1] ?? scp?.[1];
25
+ let path = url?.[2] ?? scp?.[2];
26
+ if (!host || !path)
27
+ return null;
28
+ path = path.replace(/\.git$/i, '').replace(/\/+$/, '');
29
+ if (!path)
30
+ return null;
31
+ const segments = path.split('/');
32
+ const name = segments.at(-1);
33
+ if (!name)
34
+ return null;
35
+ return {
36
+ url: `https://${host}/${path}`,
37
+ owner: segments.at(-2) ?? null,
38
+ name,
39
+ };
40
+ }
41
+ /** Repo-name-derived slug matching the server's PROJECT_SLUG_PATTERN. */
42
+ export function slugFromName(name) {
43
+ const slug = name
44
+ .trim()
45
+ .toLowerCase()
46
+ .replace(/[^a-z0-9]+/g, '-')
47
+ .replace(/^-+|-+$/g, '')
48
+ .slice(0, 100)
49
+ .replace(/-+$/, '');
50
+ return slug || 'project';
51
+ }
52
+ /** Strip inline markdown (links, images, emphasis, code ticks) to plain text. */
53
+ function stripInlineMarkdown(line) {
54
+ return line
55
+ .replace(/!\[[^\]]*\]\([^)]*\)/g, '')
56
+ .replace(/\[([^\]]*)\]\([^)]*\)/g, '$1')
57
+ .replace(/[*_`]/g, '')
58
+ .trim();
59
+ }
60
+ /** The first ATX heading's text, e.g. `# hacklab` -> `hacklab`. */
61
+ export function titleFromReadme(markdown) {
62
+ for (const line of markdown.split('\n')) {
63
+ const match = line.match(/^#{1,2}\s+(.+?)\s*#*\s*$/);
64
+ if (match?.[1]) {
65
+ const text = stripInlineMarkdown(match[1]);
66
+ if (text)
67
+ return text;
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * The first prose paragraph of a README: skips headings, badge/image-only
74
+ * lines, block quotes, code fences, and HTML, then joins the first run of
75
+ * plain text lines. This is the description fallback when package.json has
76
+ * none.
77
+ */
78
+ export function firstParagraph(markdown) {
79
+ const collected = [];
80
+ let inFence = false;
81
+ for (const raw of markdown.split('\n')) {
82
+ const line = raw.trim();
83
+ if (/^(```|~~~)/.test(line)) {
84
+ inFence = !inFence;
85
+ continue;
86
+ }
87
+ if (inFence)
88
+ continue;
89
+ const isProse = line.length > 0 &&
90
+ !/^#/.test(line) &&
91
+ !/^>/.test(line) &&
92
+ !/^[-*+]\s/.test(line) &&
93
+ !/^\d+\.\s/.test(line) &&
94
+ !/^</.test(line) &&
95
+ !/^\|/.test(line) &&
96
+ !/^(---|===)/.test(line) &&
97
+ stripInlineMarkdown(line).length > 0;
98
+ if (isProse) {
99
+ collected.push(stripInlineMarkdown(line));
100
+ continue;
101
+ }
102
+ if (collected.length > 0)
103
+ break;
104
+ }
105
+ if (collected.length === 0)
106
+ return null;
107
+ return collected.join(' ').replace(/\s+/g, ' ').slice(0, 2000).trim();
108
+ }
109
+ // Dependency -> tag. Deliberately coarse: tags are for browsing, not a
110
+ // lockfile inventory, so only broadly recognizable stack names make the cut.
111
+ const DEP_TAGS = [
112
+ [/^next$/, 'nextjs'],
113
+ [/^react(-dom)?$/, 'react'],
114
+ [/^vue$/, 'vue'],
115
+ [/^svelte$/, 'svelte'],
116
+ [/^@angular\//, 'angular'],
117
+ [/^solid-js$/, 'solidjs'],
118
+ [/^astro$/, 'astro'],
119
+ [/^expo$|^react-native$/, 'react-native'],
120
+ [/^electron$/, 'electron'],
121
+ [/^tailwindcss$/, 'tailwind'],
122
+ [/^typescript$/, 'typescript'],
123
+ [/^drizzle-orm$/, 'drizzle'],
124
+ [/^@prisma\/client$|^prisma$/, 'prisma'],
125
+ [/^hono$/, 'hono'],
126
+ [/^express$/, 'express'],
127
+ [/^fastify$/, 'fastify'],
128
+ [/^@trpc\//, 'trpc'],
129
+ [/^ai$|^openai$|^@anthropic-ai\//, 'ai'],
130
+ ];
131
+ const MAX_TAGS = 10;
132
+ /** package.json keywords first, then detected stack tags, deduped, capped. */
133
+ export function detectTags(pkg) {
134
+ const tags = [];
135
+ const push = (tag) => {
136
+ const t = tag.trim().toLowerCase().slice(0, 50);
137
+ if (t && !tags.includes(t))
138
+ tags.push(t);
139
+ };
140
+ if (Array.isArray(pkg.keywords)) {
141
+ for (const k of pkg.keywords) {
142
+ if (typeof k === 'string')
143
+ push(k);
144
+ }
145
+ }
146
+ const deps = { ...pkg.devDependencies, ...pkg.dependencies };
147
+ for (const dep of Object.keys(deps)) {
148
+ for (const [pattern, tag] of DEP_TAGS) {
149
+ if (pattern.test(dep))
150
+ push(tag);
151
+ }
152
+ }
153
+ return tags.slice(0, MAX_TAGS);
154
+ }
155
+ async function git(cwd, ...args) {
156
+ try {
157
+ const { stdout } = await execFileAsync('git', ['-C', cwd, ...args]);
158
+ return stdout.trim() || null;
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ }
164
+ /** The repo root for cwd, or null when not inside a git work tree. */
165
+ export async function findRepoRoot(cwd) {
166
+ return git(cwd, 'rev-parse', '--show-toplevel');
167
+ }
168
+ async function readIfExists(path) {
169
+ try {
170
+ return await readFile(path, 'utf8');
171
+ }
172
+ catch {
173
+ return null;
174
+ }
175
+ }
176
+ /**
177
+ * Build the best project we can from the repo at `root`. Precedence per
178
+ * field: README title > repo name; package.json description > README first
179
+ * paragraph; homepage is the only liveUrl source (anything else is guessing).
180
+ */
181
+ export async function inferProject(root) {
182
+ const remoteUrl = await git(root, 'remote', 'get-url', 'origin');
183
+ const remote = remoteUrl ? normalizeRepoUrl(remoteUrl) : null;
184
+ let pkg = {};
185
+ const pkgRaw = await readIfExists(join(root, 'package.json'));
186
+ if (pkgRaw) {
187
+ try {
188
+ pkg = JSON.parse(pkgRaw);
189
+ }
190
+ catch {
191
+ // A broken package.json costs its fields, nothing more.
192
+ }
193
+ }
194
+ const readme = (await readIfExists(join(root, 'README.md'))) ??
195
+ (await readIfExists(join(root, 'readme.md')));
196
+ const dirName = root.split('/').filter(Boolean).pop() ?? 'project';
197
+ const name = remote?.name ?? dirName;
198
+ const homepage = typeof pkg.homepage === 'string' && /^https?:\/\//.test(pkg.homepage)
199
+ ? pkg.homepage
200
+ : null;
201
+ return {
202
+ slug: slugFromName(name),
203
+ title: (readme ? titleFromReadme(readme) : null) ?? name,
204
+ description: pkg.description?.trim() || (readme ? firstParagraph(readme) : null),
205
+ tags: detectTags(pkg),
206
+ repoUrl: remote?.url ?? null,
207
+ liveUrl: homepage,
208
+ content: readme,
209
+ };
210
+ }
211
+ //# sourceMappingURL=project-infer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-infer.js","sourceRoot":"","sources":["../src/project-infer.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,WAAW,GAAG;IACxB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAA;IACf,0FAA0F;IAC1F,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC9C,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,WAAW,EAgFjC,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,aAAa,UAA8B,CAAA;AAExD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,WAAW,GAAG;IACxB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAA;IACf,0FAA0F;IAC1F,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC9C,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,WAAW,EAyGjC,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,aAAa,UAA8B,CAAA;AAExD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEjE"}
package/dist/registry.js CHANGED
@@ -1,13 +1,17 @@
1
- import { brag, parseBragArgs } from './commands/brag.js';
1
+ import { book, parseBookArgs } from './commands/book.js';
2
2
  import { chat } from './commands/chat.js';
3
3
  import { configCommand } from './commands/config.js';
4
4
  import { drop, parseDropArgs } from './commands/drop.js';
5
5
  import { essay } from './commands/essay.js';
6
6
  import { hacker } from './commands/hacker.js';
7
7
  import { join } from './commands/join.js';
8
+ import { keys } from './commands/keys.js';
8
9
  import { login } from './commands/login.js';
9
10
  import { logout } from './commands/logout.js';
10
11
  import { org } from './commands/org.js';
12
+ import { profile } from './commands/profile.js';
13
+ import { project } from './commands/project.js';
14
+ import { scout } from './commands/scout.js';
11
15
  import { sync } from './commands/sync.js';
12
16
  import { update } from './commands/update.js';
13
17
  import { whoami } from './commands/whoami.js';
@@ -56,15 +60,21 @@ export const COMMANDS = [
56
60
  run: (args) => configCommand(args),
57
61
  },
58
62
  {
59
- name: 'brag',
60
- args: '[path]',
61
- summary: 'sync .hacklab/project.yaml',
62
- run: (args) => brag(parseBragArgs(args).manifestPath),
63
+ name: 'project',
64
+ args: '[add|list|delete]',
65
+ summary: 'publish this repo as a project (--json for agents)',
66
+ run: (args) => project(args),
67
+ },
68
+ {
69
+ name: 'book',
70
+ args: '"Title" --author "Name"',
71
+ summary: 'shelve a book you have read (--takeaways "…")',
72
+ run: (args) => book(parseBookArgs(args)),
63
73
  },
64
74
  {
65
75
  name: 'org',
66
- args: '[claim|create]',
67
- summary: 'claim, create, or edit your organization',
76
+ args: '[list|view|set|apply|claim|create]',
77
+ summary: 'claim, create, or edit your organization (--json for agents)',
68
78
  run: (args) => org(args),
69
79
  },
70
80
  {
@@ -81,10 +91,28 @@ export const COMMANDS = [
81
91
  },
82
92
  {
83
93
  name: 'hacker',
84
- args: 'view <handle>',
85
- summary: 'view a hacker profile (--json for agents)',
94
+ args: 'view [handle]',
95
+ summary: 'view a hacker profile — yours by default (--json for agents)',
86
96
  run: (args) => hacker(args),
87
97
  },
98
+ {
99
+ name: 'scout',
100
+ args: 'search|picks [flags]',
101
+ summary: 'talent scouting for partners: search the pool, or our curated picks (invite-only)',
102
+ run: (args) => scout(args),
103
+ },
104
+ {
105
+ name: 'profile',
106
+ args: '[view|set|edit|apply]',
107
+ summary: 'view and edit your own profile (--json for agents)',
108
+ run: (args) => profile(args),
109
+ },
110
+ {
111
+ name: 'keys',
112
+ args: '[create|list|revoke]',
113
+ summary: 'manage API keys for your agent profile endpoint',
114
+ run: (args) => keys(args),
115
+ },
88
116
  {
89
117
  name: 'update',
90
118
  summary: 'update the hacklab CLI to the latest version',
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/sync.d.ts CHANGED
@@ -47,6 +47,9 @@ export declare function syncGithubRepos(session: Session): Promise<{
47
47
  * 401 so callers can tell an expired session apart from a transient failure.
48
48
  * Pass `timeoutMs` to hard-cap a slow upload (join uses this so the ritual can
49
49
  * never hang); omit it for an unbounded one-shot.
50
+ *
51
+ * Tags the upload with this machine's stable id so the backend can sum usage
52
+ * across the user's machines while keeping each machine's re-sync idempotent.
50
53
  */
51
54
  export declare function uploadTokenScan(session: Session, scan: AggregateScan, opts?: {
52
55
  timeoutMs?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,WAAW,EACX,YAAY,EAEb,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAGL,KAAK,OAAO,EAEb,MAAM,cAAc,CAAA;AAGrB,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,CAAA;AAK7D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAA;AAEpC,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/C,gBAAgB,EAAE,gBAAgB,CAAA;CACnC,CAAA;AAED,eAAO,MAAM,qBAAqB,2CAA2C,CAAA;AAE7E,KAAK,YAAY,GACb;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,GAChB;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,GAC1B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAwCzC,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,QAAQ,CAAC,CAMnB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC1E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAWrD;AAoBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,EACnB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA2BlC;AAMD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAK3E;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAyBnE"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,WAAW,EACX,YAAY,EAEb,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAGL,KAAK,OAAO,EAEb,MAAM,cAAc,CAAA;AAGrB,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,CAAA;AAK7D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAA;AAEpC,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC/C,gBAAgB,EAAE,gBAAgB,CAAA;CACnC,CAAA;AAED,eAAO,MAAM,qBAAqB,2CAA2C,CAAA;AAE7E,KAAK,YAAY,GACb;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,GAChB;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,GAC1B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAwCzC,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,QAAQ,CAAC,CAMnB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAgC1E;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAWrD;AAoBD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,EACnB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAChC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA8BlC;AAMD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAyBzB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAK3E;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAyBnE"}