hacklab 0.22.2 → 26.921.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.
- package/README.md +23 -430
- package/dist/index.js +132 -23
- package/package.json +20 -42
- package/LICENSE +0 -21
- package/dist/agent-handoff.d.ts +0 -51
- package/dist/agent-handoff.d.ts.map +0 -1
- package/dist/agent-handoff.js +0 -91
- package/dist/agent-handoff.js.map +0 -1
- package/dist/api-client.d.ts +0 -18
- package/dist/api-client.d.ts.map +0 -1
- package/dist/api-client.js +0 -40
- package/dist/api-client.js.map +0 -1
- package/dist/belt.d.ts +0 -25
- package/dist/belt.d.ts.map +0 -1
- package/dist/belt.js +0 -113
- package/dist/belt.js.map +0 -1
- package/dist/card.d.ts +0 -66
- package/dist/card.d.ts.map +0 -1
- package/dist/card.js +0 -151
- package/dist/card.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -238
- package/dist/cli.js.map +0 -1
- package/dist/commands/book.d.ts +0 -14
- package/dist/commands/book.d.ts.map +0 -1
- package/dist/commands/book.js +0 -90
- package/dist/commands/book.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -36
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/chat.js +0 -642
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/config.d.ts +0 -2
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js +0 -84
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/daemon.d.ts +0 -19
- package/dist/commands/daemon.d.ts.map +0 -1
- package/dist/commands/daemon.js +0 -72
- package/dist/commands/daemon.js.map +0 -1
- package/dist/commands/drop.d.ts +0 -12
- package/dist/commands/drop.d.ts.map +0 -1
- package/dist/commands/drop.js +0 -103
- package/dist/commands/drop.js.map +0 -1
- package/dist/commands/drops.d.ts +0 -9
- package/dist/commands/drops.d.ts.map +0 -1
- package/dist/commands/drops.js +0 -96
- package/dist/commands/drops.js.map +0 -1
- package/dist/commands/essay.d.ts +0 -40
- package/dist/commands/essay.d.ts.map +0 -1
- package/dist/commands/essay.js +0 -651
- package/dist/commands/essay.js.map +0 -1
- package/dist/commands/hackathon.d.ts +0 -2
- package/dist/commands/hackathon.d.ts.map +0 -1
- package/dist/commands/hackathon.js +0 -893
- package/dist/commands/hackathon.js.map +0 -1
- package/dist/commands/hacker.d.ts +0 -2
- package/dist/commands/hacker.d.ts.map +0 -1
- package/dist/commands/hacker.js +0 -87
- package/dist/commands/hacker.js.map +0 -1
- package/dist/commands/jobs.d.ts +0 -18
- package/dist/commands/jobs.d.ts.map +0 -1
- package/dist/commands/jobs.js +0 -138
- package/dist/commands/jobs.js.map +0 -1
- package/dist/commands/keys.d.ts +0 -2
- package/dist/commands/keys.d.ts.map +0 -1
- package/dist/commands/keys.js +0 -138
- package/dist/commands/keys.js.map +0 -1
- package/dist/commands/login.d.ts +0 -83
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js +0 -236
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts +0 -2
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js +0 -22
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/org-jobs.d.ts +0 -50
- package/dist/commands/org-jobs.d.ts.map +0 -1
- package/dist/commands/org-jobs.js +0 -383
- package/dist/commands/org-jobs.js.map +0 -1
- package/dist/commands/org.d.ts +0 -67
- package/dist/commands/org.d.ts.map +0 -1
- package/dist/commands/org.js +0 -1244
- package/dist/commands/org.js.map +0 -1
- package/dist/commands/ping.d.ts +0 -2
- package/dist/commands/ping.d.ts.map +0 -1
- package/dist/commands/ping.js +0 -50
- package/dist/commands/ping.js.map +0 -1
- package/dist/commands/profile.d.ts +0 -72
- package/dist/commands/profile.d.ts.map +0 -1
- package/dist/commands/profile.js +0 -672
- package/dist/commands/profile.js.map +0 -1
- package/dist/commands/project.d.ts +0 -2
- package/dist/commands/project.d.ts.map +0 -1
- package/dist/commands/project.js +0 -583
- package/dist/commands/project.js.map +0 -1
- package/dist/commands/referral.d.ts +0 -6
- package/dist/commands/referral.d.ts.map +0 -1
- package/dist/commands/referral.js +0 -93
- package/dist/commands/referral.js.map +0 -1
- package/dist/commands/rtfm.d.ts +0 -9
- package/dist/commands/rtfm.d.ts.map +0 -1
- package/dist/commands/rtfm.js +0 -114
- package/dist/commands/rtfm.js.map +0 -1
- package/dist/commands/scan.d.ts +0 -13
- package/dist/commands/scan.d.ts.map +0 -1
- package/dist/commands/scan.js +0 -286
- package/dist/commands/scan.js.map +0 -1
- package/dist/commands/scout.d.ts +0 -18
- package/dist/commands/scout.d.ts.map +0 -1
- package/dist/commands/scout.js +0 -232
- package/dist/commands/scout.js.map +0 -1
- package/dist/commands/setup-rail.d.ts +0 -58
- package/dist/commands/setup-rail.d.ts.map +0 -1
- package/dist/commands/setup-rail.js +0 -135
- package/dist/commands/setup-rail.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -29
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -442
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/sync.d.ts +0 -9
- package/dist/commands/sync.d.ts.map +0 -1
- package/dist/commands/sync.js +0 -345
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/update.d.ts +0 -2
- package/dist/commands/update.d.ts.map +0 -1
- package/dist/commands/update.js +0 -92
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/whoami.d.ts +0 -2
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js +0 -41
- package/dist/commands/whoami.js.map +0 -1
- package/dist/config.d.ts +0 -78
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -93
- package/dist/config.js.map +0 -1
- package/dist/daily-sync.d.ts +0 -150
- package/dist/daily-sync.d.ts.map +0 -1
- package/dist/daily-sync.js +0 -665
- package/dist/daily-sync.js.map +0 -1
- package/dist/dossier.d.ts +0 -73
- package/dist/dossier.d.ts.map +0 -1
- package/dist/dossier.js +0 -141
- package/dist/dossier.js.map +0 -1
- package/dist/field-normalize.d.ts +0 -4
- package/dist/field-normalize.d.ts.map +0 -1
- package/dist/field-normalize.js +0 -8
- package/dist/field-normalize.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/job-fields.d.ts +0 -47
- package/dist/job-fields.d.ts.map +0 -1
- package/dist/job-fields.js +0 -148
- package/dist/job-fields.js.map +0 -1
- package/dist/machine.d.ts +0 -15
- package/dist/machine.d.ts.map +0 -1
- package/dist/machine.js +0 -64
- package/dist/machine.js.map +0 -1
- package/dist/org-fields.d.ts +0 -57
- package/dist/org-fields.d.ts.map +0 -1
- package/dist/org-fields.js +0 -167
- package/dist/org-fields.js.map +0 -1
- package/dist/posthog.d.ts +0 -38
- package/dist/posthog.d.ts.map +0 -1
- package/dist/posthog.js +0 -224
- package/dist/posthog.js.map +0 -1
- package/dist/project-fields.d.ts +0 -40
- package/dist/project-fields.d.ts.map +0 -1
- package/dist/project-fields.js +0 -79
- package/dist/project-fields.js.map +0 -1
- package/dist/prompt-consent.d.ts +0 -73
- package/dist/prompt-consent.d.ts.map +0 -1
- package/dist/prompt-consent.js +0 -191
- package/dist/prompt-consent.js.map +0 -1
- package/dist/prompt-stats.d.ts +0 -226
- package/dist/prompt-stats.d.ts.map +0 -1
- package/dist/prompt-stats.js +0 -561
- package/dist/prompt-stats.js.map +0 -1
- package/dist/referral.d.ts +0 -14
- package/dist/referral.d.ts.map +0 -1
- package/dist/referral.js +0 -28
- package/dist/referral.js.map +0 -1
- package/dist/registry.d.ts +0 -15
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -180
- package/dist/registry.js.map +0 -1
- package/dist/resolve-command.d.ts +0 -20
- package/dist/resolve-command.d.ts.map +0 -1
- package/dist/resolve-command.js +0 -21
- package/dist/resolve-command.js.map +0 -1
- package/dist/scanners/antigravity.d.ts +0 -41
- package/dist/scanners/antigravity.d.ts.map +0 -1
- package/dist/scanners/antigravity.js +0 -210
- package/dist/scanners/antigravity.js.map +0 -1
- package/dist/scanners/github-copilot-telemetry.d.ts +0 -23
- package/dist/scanners/github-copilot-telemetry.d.ts.map +0 -1
- package/dist/scanners/github-copilot-telemetry.js +0 -220
- package/dist/scanners/github-copilot-telemetry.js.map +0 -1
- package/dist/scanners/github-copilot.d.ts +0 -68
- package/dist/scanners/github-copilot.d.ts.map +0 -1
- package/dist/scanners/github-copilot.js +0 -262
- package/dist/scanners/github-copilot.js.map +0 -1
- package/dist/scanners/incremental.d.ts +0 -282
- package/dist/scanners/incremental.d.ts.map +0 -1
- package/dist/scanners/incremental.js +0 -788
- package/dist/scanners/incremental.js.map +0 -1
- package/dist/scanners/index.d.ts +0 -116
- package/dist/scanners/index.d.ts.map +0 -1
- package/dist/scanners/index.js +0 -726
- package/dist/scanners/index.js.map +0 -1
- package/dist/scanners/sqlite.d.ts +0 -18
- package/dist/scanners/sqlite.d.ts.map +0 -1
- package/dist/scanners/sqlite.js +0 -63
- package/dist/scanners/sqlite.js.map +0 -1
- package/dist/scanners/util.d.ts +0 -112
- package/dist/scanners/util.d.ts.map +0 -1
- package/dist/scanners/util.js +0 -167
- package/dist/scanners/util.js.map +0 -1
- package/dist/session.d.ts +0 -106
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -191
- package/dist/session.js.map +0 -1
- package/dist/share-card-colors.d.ts +0 -19
- package/dist/share-card-colors.d.ts.map +0 -1
- package/dist/share-card-colors.js +0 -36
- package/dist/share-card-colors.js.map +0 -1
- package/dist/share-card.d.ts +0 -32
- package/dist/share-card.d.ts.map +0 -1
- package/dist/share-card.js +0 -420
- package/dist/share-card.js.map +0 -1
- package/dist/share.d.ts +0 -17
- package/dist/share.d.ts.map +0 -1
- package/dist/share.js +0 -77
- package/dist/share.js.map +0 -1
- package/dist/sync.d.ts +0 -100
- package/dist/sync.d.ts.map +0 -1
- package/dist/sync.js +0 -304
- package/dist/sync.js.map +0 -1
- package/dist/ui.d.ts +0 -33
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js +0 -127
- package/dist/ui.js.map +0 -1
- package/dist/utils/npmGlobal.d.ts +0 -30
- package/dist/utils/npmGlobal.d.ts.map +0 -1
- package/dist/utils/npmGlobal.js +0 -69
- package/dist/utils/npmGlobal.js.map +0 -1
- package/dist/utils/openBrowser.d.ts +0 -14
- package/dist/utils/openBrowser.d.ts.map +0 -1
- package/dist/utils/openBrowser.js +0 -47
- package/dist/utils/openBrowser.js.map +0 -1
- package/dist/utils/updateCheck.d.ts +0 -16
- package/dist/utils/updateCheck.d.ts.map +0 -1
- package/dist/utils/updateCheck.js +0 -111
- package/dist/utils/updateCheck.js.map +0 -1
- package/dist/utils/waitForEnter.d.ts +0 -12
- package/dist/utils/waitForEnter.d.ts.map +0 -1
- package/dist/utils/waitForEnter.js +0 -43
- package/dist/utils/waitForEnter.js.map +0 -1
package/dist/commands/scout.js
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import { resolveCommand } from '../resolve-command.js';
|
|
2
|
-
import { formatTokens } from '../scanners/util.js';
|
|
3
|
-
import { loadSession } from '../session.js';
|
|
4
|
-
import { ensureFreshSession, fetchApi, LOGIN_EXPIRED_MESSAGE } from '../sync.js';
|
|
5
|
-
import { bold, dim, error, hint, info, rankColor, stripControl } from '../ui.js';
|
|
6
|
-
// `hacklab scout` is a namespace over two products, kept together so the pair is
|
|
7
|
-
// obvious and neither is privileged by a bare command:
|
|
8
|
-
// scout search — the client filters the pool themselves (their criteria, their
|
|
9
|
-
// ranking); flags map 1:1 to the API.
|
|
10
|
-
// scout picks — our curated shortlist, pre-ranked with a thesis per hacker.
|
|
11
|
-
// Subcommands resolve by shortest unambiguous prefix (shared resolveCommand), so
|
|
12
|
-
// `hacklab scout se` / `hacklab scout p` work. Access is gated by the API
|
|
13
|
-
// (key scope / grant), never by which subcommand is typed.
|
|
14
|
-
const SUBCOMMANDS = ['search', 'picks'];
|
|
15
|
-
// Exit-code contract for cron consumers (v2 design doc, step 4): 0 = success
|
|
16
|
-
// (including an empty list), 2 = auth expired/missing, 3 = not entitled,
|
|
17
|
-
// 1 = anything else. Errors and hints go to stderr, NEVER onto --json stdout.
|
|
18
|
-
const EXIT_AUTH = 2;
|
|
19
|
-
const EXIT_NOT_ENTITLED = 3;
|
|
20
|
-
const EXIT_OTHER = 1;
|
|
21
|
-
const GATE_MESSAGE = 'scout is invite-only. talk to marin.';
|
|
22
|
-
const BROKEN_MESSAGE = "broken. we're on it.";
|
|
23
|
-
function usage() {
|
|
24
|
-
error('usage: hacklab scout <search|picks> [flags]');
|
|
25
|
-
hint('scout search filter the hacker pool yourself, or --json for crons');
|
|
26
|
-
hint("scout picks this week's curated shortlist");
|
|
27
|
-
process.exit(EXIT_OTHER);
|
|
28
|
-
}
|
|
29
|
-
/** The `scout` namespace dispatcher: routes to search or picks. */
|
|
30
|
-
export async function scout(args) {
|
|
31
|
-
const [subToken, ...rest] = args;
|
|
32
|
-
if (!subToken || subToken.startsWith('-'))
|
|
33
|
-
usage();
|
|
34
|
-
const resolved = resolveCommand(subToken, SUBCOMMANDS);
|
|
35
|
-
if (resolved.kind === 'ambiguous') {
|
|
36
|
-
error(`ambiguous: scout ${subToken} (${resolved.matches.join(', ')})`);
|
|
37
|
-
process.exit(EXIT_OTHER);
|
|
38
|
-
}
|
|
39
|
-
if (resolved.kind === 'unknown') {
|
|
40
|
-
error(`unknown subcommand: scout ${subToken}`);
|
|
41
|
-
usage();
|
|
42
|
-
}
|
|
43
|
-
if (resolved.name === 'search')
|
|
44
|
-
return scoutSearch(rest);
|
|
45
|
-
if (resolved.name === 'picks')
|
|
46
|
-
return scoutPicks(rest);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Monday 00:00 UTC of the current week, for `--new-this-week`. Mirrors
|
|
50
|
-
* @hacklab/db's mondayUtcWeekOf (the week owner for picks); duplicated here
|
|
51
|
-
* because the CLI doesn't depend on the db package — this is client-side
|
|
52
|
-
* sugar over the real contract param, `newSince`.
|
|
53
|
-
*/
|
|
54
|
-
export function mondayUtcStartOfWeek(now) {
|
|
55
|
-
const day = now.getUTCDay();
|
|
56
|
-
const daysSinceMonday = day === 0 ? 6 : day - 1;
|
|
57
|
-
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - daysSinceMonday)).toISOString();
|
|
58
|
-
}
|
|
59
|
-
/** Flag→param mapping is 1:1 with the API contract; the server validates. */
|
|
60
|
-
export function parseSearchArgs(args) {
|
|
61
|
-
const query = new URLSearchParams();
|
|
62
|
-
let json = false;
|
|
63
|
-
let newThisWeek = false;
|
|
64
|
-
let newSince = null;
|
|
65
|
-
for (let i = 0; i < args.length; i++) {
|
|
66
|
-
const arg = args[i];
|
|
67
|
-
if (arg === '--json')
|
|
68
|
-
json = true;
|
|
69
|
-
else if (arg === '--new-this-week')
|
|
70
|
-
newThisWeek = true;
|
|
71
|
-
else if (arg === '--new-since') {
|
|
72
|
-
newSince = args[++i] ?? '';
|
|
73
|
-
}
|
|
74
|
-
else if (arg === '--open-to-work')
|
|
75
|
-
query.set('openToWork', 'true');
|
|
76
|
-
else if (arg === '--sort') {
|
|
77
|
-
const value = args[++i] ?? '';
|
|
78
|
-
query.set('sort', value);
|
|
79
|
-
}
|
|
80
|
-
else if (arg === '--limit') {
|
|
81
|
-
const value = args[++i] ?? '';
|
|
82
|
-
query.set('limit', value);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
return { usage: `unknown flag ${arg}` };
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (newThisWeek && newSince !== null) {
|
|
89
|
-
return { usage: 'use --new-this-week or --new-since, not both' };
|
|
90
|
-
}
|
|
91
|
-
if (newSince !== null) {
|
|
92
|
-
if (Number.isNaN(new Date(newSince).getTime())) {
|
|
93
|
-
return { usage: '--new-since must be an ISO 8601 timestamp' };
|
|
94
|
-
}
|
|
95
|
-
query.set('newSince', newSince);
|
|
96
|
-
}
|
|
97
|
-
if (newThisWeek)
|
|
98
|
-
query.set('newSince', mondayUtcStartOfWeek(new Date()));
|
|
99
|
-
return { json, query };
|
|
100
|
-
}
|
|
101
|
-
function parseJson(body) {
|
|
102
|
-
try {
|
|
103
|
-
return JSON.parse(body);
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
async function fetchScout(path, json) {
|
|
110
|
-
const stored = await loadSession();
|
|
111
|
-
if (!stored) {
|
|
112
|
-
error('not logged in');
|
|
113
|
-
hint(`run ${dim('hacklab login')} to authenticate`);
|
|
114
|
-
process.exit(EXIT_AUTH);
|
|
115
|
-
}
|
|
116
|
-
const session = await ensureFreshSession(stored);
|
|
117
|
-
let res;
|
|
118
|
-
try {
|
|
119
|
-
res = await fetchApi(session, path, {
|
|
120
|
-
headers: { Authorization: `Bearer ${session.token}` },
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
error(err instanceof Error ? err.message : String(err));
|
|
125
|
-
process.exit(EXIT_OTHER);
|
|
126
|
-
}
|
|
127
|
-
if (res.status === 401) {
|
|
128
|
-
error(LOGIN_EXPIRED_MESSAGE);
|
|
129
|
-
process.exit(EXIT_AUTH);
|
|
130
|
-
}
|
|
131
|
-
if (res.status === 403) {
|
|
132
|
-
error(GATE_MESSAGE);
|
|
133
|
-
process.exit(EXIT_NOT_ENTITLED);
|
|
134
|
-
}
|
|
135
|
-
const body = await res.text();
|
|
136
|
-
if (res.status === 400) {
|
|
137
|
-
const data = parseJson(body);
|
|
138
|
-
error(data?.error ?? 'invalid request');
|
|
139
|
-
process.exit(EXIT_OTHER);
|
|
140
|
-
}
|
|
141
|
-
if (!res.ok) {
|
|
142
|
-
error(BROKEN_MESSAGE);
|
|
143
|
-
process.exit(EXIT_OTHER);
|
|
144
|
-
}
|
|
145
|
-
// --json stdout purity: the server envelope, verbatim, nothing else.
|
|
146
|
-
if (json) {
|
|
147
|
-
process.stdout.write(`${body}\n`);
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
// Human path: a 200 with a non-JSON body (proxy/CDN error page) is a broken
|
|
151
|
-
// upstream, not renderable — fail cleanly instead of throwing on parse.
|
|
152
|
-
const data = parseJson(body);
|
|
153
|
-
if (!data) {
|
|
154
|
-
error(BROKEN_MESSAGE);
|
|
155
|
-
process.exit(EXIT_OTHER);
|
|
156
|
-
}
|
|
157
|
-
return { body, data };
|
|
158
|
-
}
|
|
159
|
-
// URLs and free text reach the terminal from user-controlled columns; strip
|
|
160
|
-
// control chars so an embedded ANSI escape can't hijack the viewer's terminal.
|
|
161
|
-
function formatLinks(links) {
|
|
162
|
-
return [links.profile, links.github, links.website]
|
|
163
|
-
.filter((l) => Boolean(l))
|
|
164
|
-
.map((l) => stripControl(l).replace(/^https:\/\//, ''))
|
|
165
|
-
.join(' · ');
|
|
166
|
-
}
|
|
167
|
-
function renderHacker(h) {
|
|
168
|
-
const name = h.displayName ? ` ${stripControl(h.displayName)}` : '';
|
|
169
|
-
const otw = h.openToWork ? dim(' · open to work') : '';
|
|
170
|
-
console.log(` ${rankColor(h.level, `@${stripControl(h.handle)}`)}${name} ${dim(`${h.belt} lv${h.level}`)}${otw}`);
|
|
171
|
-
if (h.bio)
|
|
172
|
-
console.log(dim(` ${stripControl(h.bio)}`));
|
|
173
|
-
console.log(dim(` ${formatTokens(h.tokens30d)} tokens (30d) · ${h.activeDays30} active days · ${h.counts.projects} projects · ${h.counts.essays} essays · ${h.counts.followers} followers`));
|
|
174
|
-
const top = h.projects[0];
|
|
175
|
-
if (top) {
|
|
176
|
-
const desc = top.description ? `, ${stripControl(top.description)}` : '';
|
|
177
|
-
console.log(dim(` building: ${stripControl(top.title)}${desc}`));
|
|
178
|
-
}
|
|
179
|
-
console.log(dim(` ${formatLinks(h.links)}`));
|
|
180
|
-
console.log('');
|
|
181
|
-
}
|
|
182
|
-
async function scoutSearch(args) {
|
|
183
|
-
const parsed = parseSearchArgs(args);
|
|
184
|
-
if ('usage' in parsed) {
|
|
185
|
-
error(parsed.usage);
|
|
186
|
-
hint(`usage: hacklab scout search [--new-this-week | --new-since <iso>] [--open-to-work] [--sort <key>] [--limit <n>] [--json]`);
|
|
187
|
-
process.exit(EXIT_OTHER);
|
|
188
|
-
}
|
|
189
|
-
const qs = parsed.query.size > 0 ? `?${parsed.query}` : '';
|
|
190
|
-
const result = await fetchScout(`/api/scout/hackers${qs}`, parsed.json);
|
|
191
|
-
if (!result)
|
|
192
|
-
return;
|
|
193
|
-
const list = (result.data.hackers ?? []);
|
|
194
|
-
if (list.length === 0) {
|
|
195
|
-
info('no hackers match. loosen the filters?');
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
console.log('');
|
|
199
|
-
console.log(bold(` ${list.length} hacker${list.length === 1 ? '' : 's'}`));
|
|
200
|
-
console.log('');
|
|
201
|
-
for (const h of list)
|
|
202
|
-
renderHacker(h);
|
|
203
|
-
}
|
|
204
|
-
async function scoutPicks(args) {
|
|
205
|
-
const json = args.includes('--json');
|
|
206
|
-
const unknown = args.find((a) => a !== '--json');
|
|
207
|
-
if (unknown) {
|
|
208
|
-
error(`unknown flag ${unknown}`);
|
|
209
|
-
hint('usage: hacklab scout picks [--json]');
|
|
210
|
-
process.exit(EXIT_OTHER);
|
|
211
|
-
}
|
|
212
|
-
const result = await fetchScout('/api/scout/picks', json);
|
|
213
|
-
if (!result)
|
|
214
|
-
return;
|
|
215
|
-
const picks = (result.data.picks ?? []);
|
|
216
|
-
if (picks.length === 0) {
|
|
217
|
-
info('no picks yet this week. check back friday.');
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
console.log('');
|
|
221
|
-
// DESIGN.md Voice: no em-dashes in product copy (hard rule).
|
|
222
|
-
console.log(bold(` scout picks: week of ${result.data.weekOf}`));
|
|
223
|
-
console.log('');
|
|
224
|
-
for (const p of picks) {
|
|
225
|
-
const name = p.displayName ? ` ${stripControl(p.displayName)}` : '';
|
|
226
|
-
console.log(` ${p.position}. ${rankColor(p.level, `@${stripControl(p.handle)}`)}${name} ${dim(`${p.belt} lv${p.level}`)}`);
|
|
227
|
-
console.log(` ${stripControl(p.thesis)}`);
|
|
228
|
-
console.log(dim(` ${formatLinks(p.links)}`));
|
|
229
|
-
console.log('');
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
//# sourceMappingURL=scout.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scout.js","sourceRoot":"","sources":["../../src/commands/scout.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type { DeviceCodeRenderer } from './login.js';
|
|
2
|
-
/**
|
|
3
|
-
* True when the cursor can be walked back over what we printed: a real terminal
|
|
4
|
-
* that reports a width. Down a pipe the escape codes are litter, and a pty that
|
|
5
|
-
* reports zero columns turns row arithmetic — ours and clack's `taskLog` — into
|
|
6
|
-
* a divide by zero.
|
|
7
|
-
*/
|
|
8
|
-
export declare function canRedraw(): boolean;
|
|
9
|
-
/**
|
|
10
|
-
* A run of rail lines that can rub itself out.
|
|
11
|
-
*
|
|
12
|
-
* Accounting is in terminal *rows*, not lines printed: a narrow window wraps a
|
|
13
|
-
* long verification URL onto two, and erasing one row too few leaves a stripe
|
|
14
|
-
* of the old block behind while one too many eats the step above it. Styled
|
|
15
|
-
* text is measured through its plain twin, since ANSI and OSC-8 escapes occupy
|
|
16
|
-
* no columns.
|
|
17
|
-
*/
|
|
18
|
-
export declare class RailBlock {
|
|
19
|
-
private rows;
|
|
20
|
-
/** Print one line. `plain` is the same text stripped of styling. */
|
|
21
|
-
line(styled: string, plain?: string): void;
|
|
22
|
-
/**
|
|
23
|
-
* Count a row drawn by something else that left the cursor parked on it — a
|
|
24
|
-
* `waitForEnter` prompt, which deliberately prints no newline of its own.
|
|
25
|
-
*/
|
|
26
|
-
prompt(plain: string): void;
|
|
27
|
-
/**
|
|
28
|
-
* Erase the block. `cursor` is where the terminal left us: `below` when the
|
|
29
|
-
* last thing written ended in a newline (including the one the user's Enter
|
|
30
|
-
* echoed), `inline` when the cursor still sits on the block's last row.
|
|
31
|
-
*/
|
|
32
|
-
erase(cursor: 'below' | 'inline'): void;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* `setup`'s device-code beat, modelled on GitHub's own CLI:
|
|
36
|
-
*
|
|
37
|
-
* ```
|
|
38
|
-
* │
|
|
39
|
-
* ▲ first copy your one-time code: C98F-E695
|
|
40
|
-
* │
|
|
41
|
-
* │ Press Enter to open https://hacklab.so/cli/login in your browser...
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* The code is the one thing on screen the user has to act on, so it gets the
|
|
45
|
-
* attention glyph and the mint. Once the approval lands, the block has served
|
|
46
|
-
* its purpose and the caller replaces all four rows with one `◇ hacklab · …`
|
|
47
|
-
* line.
|
|
48
|
-
*/
|
|
49
|
-
export declare function railDeviceCode(): DeviceCodeRenderer;
|
|
50
|
-
/**
|
|
51
|
-
* The agent-handoff offer, drawn as a block that clears once answered. Enter is
|
|
52
|
-
* the accept here, so the prompt says so plainly and anything else is a no.
|
|
53
|
-
*/
|
|
54
|
-
export declare function railAgentOffer(agentName: string): {
|
|
55
|
-
prompt: string;
|
|
56
|
-
settle(): void;
|
|
57
|
-
};
|
|
58
|
-
//# sourceMappingURL=setup-rail.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup-rail.d.ts","sourceRoot":"","sources":["../../src/commands/setup-rail.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAmBpD;;;;;GAKG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAMnC;AAiBD;;;;;;;;GAQG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAI;IAEhB,oEAAoE;IACpE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAe,GAAG,IAAI;IAKlD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3B;;;;OAIG;IACH,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI;CAKxC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,IAAI,kBAAkB,CA0BnD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,IAAI,IAAI,CAAA;CACf,CAsBA"}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { S_BAR, S_WARN } from '@clack/prompts';
|
|
2
|
-
import { bold, dim, displayWidth, gray, link, mint, yellow } from '../ui.js';
|
|
3
|
-
/**
|
|
4
|
-
* The step rail `setup` is drawn on.
|
|
5
|
-
*
|
|
6
|
-
* Everything clack prints — prompts, `log.*`, spinners, `taskLog` — hangs off a
|
|
7
|
-
* `│` gutter and leaves one `◇` line per finished step. Two beats of `setup`
|
|
8
|
-
* can't be a clack widget (the device-code beat races an Enter-wait against a
|
|
9
|
-
* poll; the agent offer waits on a bare Enter), so they are drawn here by hand
|
|
10
|
-
* in the same vocabulary and, like every other step, collapse to one line when
|
|
11
|
-
* they are done.
|
|
12
|
-
*/
|
|
13
|
-
/** Columns to wrap at. 80 is what a terminal that won't say implies. */
|
|
14
|
-
function width() {
|
|
15
|
-
const cols = process.stdout.columns;
|
|
16
|
-
return typeof cols === 'number' && cols > 0 ? cols : 80;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* True when the cursor can be walked back over what we printed: a real terminal
|
|
20
|
-
* that reports a width. Down a pipe the escape codes are litter, and a pty that
|
|
21
|
-
* reports zero columns turns row arithmetic — ours and clack's `taskLog` — into
|
|
22
|
-
* a divide by zero.
|
|
23
|
-
*/
|
|
24
|
-
export function canRedraw() {
|
|
25
|
-
return (process.stdout.isTTY === true &&
|
|
26
|
-
typeof process.stdout.columns === 'number' &&
|
|
27
|
-
process.stdout.columns > 0);
|
|
28
|
-
}
|
|
29
|
-
/** Terminal rows a plain, unstyled line occupies at the current width. */
|
|
30
|
-
function rowsFor(plain) {
|
|
31
|
-
return Math.max(1, Math.ceil(displayWidth(plain) / width()));
|
|
32
|
-
}
|
|
33
|
-
const ERASE_LINE = '\u001b[2K';
|
|
34
|
-
const CURSOR_UP = '\u001b[1A';
|
|
35
|
-
/** Erase `count` rows, ending on the topmost one with the cursor at column 1. */
|
|
36
|
-
function eraseRows(count) {
|
|
37
|
-
let out = ERASE_LINE;
|
|
38
|
-
for (let i = 1; i < count; i++)
|
|
39
|
-
out += CURSOR_UP + ERASE_LINE;
|
|
40
|
-
return `${out}\r`;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* A run of rail lines that can rub itself out.
|
|
44
|
-
*
|
|
45
|
-
* Accounting is in terminal *rows*, not lines printed: a narrow window wraps a
|
|
46
|
-
* long verification URL onto two, and erasing one row too few leaves a stripe
|
|
47
|
-
* of the old block behind while one too many eats the step above it. Styled
|
|
48
|
-
* text is measured through its plain twin, since ANSI and OSC-8 escapes occupy
|
|
49
|
-
* no columns.
|
|
50
|
-
*/
|
|
51
|
-
export class RailBlock {
|
|
52
|
-
rows = 0;
|
|
53
|
-
/** Print one line. `plain` is the same text stripped of styling. */
|
|
54
|
-
line(styled, plain = styled) {
|
|
55
|
-
console.log(styled);
|
|
56
|
-
this.rows += rowsFor(plain);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Count a row drawn by something else that left the cursor parked on it — a
|
|
60
|
-
* `waitForEnter` prompt, which deliberately prints no newline of its own.
|
|
61
|
-
*/
|
|
62
|
-
prompt(plain) {
|
|
63
|
-
this.rows += rowsFor(plain);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Erase the block. `cursor` is where the terminal left us: `below` when the
|
|
67
|
-
* last thing written ended in a newline (including the one the user's Enter
|
|
68
|
-
* echoed), `inline` when the cursor still sits on the block's last row.
|
|
69
|
-
*/
|
|
70
|
-
erase(cursor) {
|
|
71
|
-
const rows = this.rows + (cursor === 'below' ? 1 : 0);
|
|
72
|
-
this.rows = 0;
|
|
73
|
-
if (rows > 0 && canRedraw())
|
|
74
|
-
process.stdout.write(eraseRows(rows));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* `setup`'s device-code beat, modelled on GitHub's own CLI:
|
|
79
|
-
*
|
|
80
|
-
* ```
|
|
81
|
-
* │
|
|
82
|
-
* ▲ first copy your one-time code: C98F-E695
|
|
83
|
-
* │
|
|
84
|
-
* │ Press Enter to open https://hacklab.so/cli/login in your browser...
|
|
85
|
-
* ```
|
|
86
|
-
*
|
|
87
|
-
* The code is the one thing on screen the user has to act on, so it gets the
|
|
88
|
-
* attention glyph and the mint. Once the approval lands, the block has served
|
|
89
|
-
* its purpose and the caller replaces all four rows with one `◇ hacklab · …`
|
|
90
|
-
* line.
|
|
91
|
-
*/
|
|
92
|
-
export function railDeviceCode() {
|
|
93
|
-
const block = new RailBlock();
|
|
94
|
-
let enterPlain = '';
|
|
95
|
-
return {
|
|
96
|
-
show({ userCode, verificationUri }) {
|
|
97
|
-
block.line(gray(S_BAR));
|
|
98
|
-
block.line(`${yellow(S_WARN)} first copy your one-time code: ${mint(userCode)}`, `${S_WARN} first copy your one-time code: ${userCode}`);
|
|
99
|
-
block.line(gray(S_BAR));
|
|
100
|
-
enterPlain = `${S_BAR} Press Enter to open ${verificationUri} in your browser... `;
|
|
101
|
-
return `${gray(S_BAR)} ${bold('Press Enter')} to open ${link(verificationUri)} in your browser... `;
|
|
102
|
-
},
|
|
103
|
-
done({ enterPressed }) {
|
|
104
|
-
// No TTY means `waitForEnter` printed nothing and returned at once, so
|
|
105
|
-
// there is no prompt row to account for.
|
|
106
|
-
if (!process.stdin.isTTY) {
|
|
107
|
-
block.erase('below');
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
block.prompt(enterPlain);
|
|
111
|
-
block.erase(enterPressed ? 'below' : 'inline');
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* The agent-handoff offer, drawn as a block that clears once answered. Enter is
|
|
117
|
-
* the accept here, so the prompt says so plainly and anything else is a no.
|
|
118
|
-
*/
|
|
119
|
-
export function railAgentOffer(agentName) {
|
|
120
|
-
const block = new RailBlock();
|
|
121
|
-
block.line(gray(S_BAR));
|
|
122
|
-
block.line(`${gray(S_BAR)} found ${bold(agentName)} — it can set up your profile now`, `${S_BAR} found ${agentName} — it can set up your profile now`);
|
|
123
|
-
block.line(`${gray(S_BAR)} ${dim('it runs here in your terminal, and you approve what it does')}`, `${S_BAR} it runs here in your terminal, and you approve what it does`);
|
|
124
|
-
const plain = `${S_BAR} Press Enter to hand off · anything else skips `;
|
|
125
|
-
return {
|
|
126
|
-
prompt: `${gray(S_BAR)} ${bold('Press Enter')} to hand off ${dim('· anything else skips')} `,
|
|
127
|
-
settle() {
|
|
128
|
-
// Reached only after a line was read, so the echoed newline has already
|
|
129
|
-
// moved the cursor below the prompt row.
|
|
130
|
-
block.prompt(plain);
|
|
131
|
-
block.erase('below');
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
//# sourceMappingURL=setup-rail.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup-rail.js","sourceRoot":"","sources":["../../src/commands/setup-rail.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/setup.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `hacklab setup` — the front door.
|
|
3
|
-
*
|
|
4
|
-
* scan → anonymous rank → sign in → one consent question → upload →
|
|
5
|
-
* daemon → hand the profile work to a coding agent
|
|
6
|
-
*
|
|
7
|
-
* The one deliberate composite command in the CLI (DESIGN.md's "one job per
|
|
8
|
-
* command" carries a recorded exception for it): face-to-face testing showed
|
|
9
|
-
* that install → `login` → `scan` reads as three unrelated chores to someone who
|
|
10
|
-
* has never used hacklab, and people stalled between them. Each stage still
|
|
11
|
-
* degrades on its own terms, and every piece remains its own command for anyone
|
|
12
|
-
* who wants to re-run just that piece.
|
|
13
|
-
*
|
|
14
|
-
* It is also the one command allowed clack chrome, and it spends that allowance
|
|
15
|
-
* on being *one* flow: every line goes on the step rail, and every stage ends as
|
|
16
|
-
* a single line naming the stage and how it went. What a stage shows while it is
|
|
17
|
-
* working — the per-tool receipt, the device code — has done its job by the time
|
|
18
|
-
* the next stage starts, so it comes back off the screen. `setup-rail.ts` holds
|
|
19
|
-
* the two blocks clack has no widget for.
|
|
20
|
-
*
|
|
21
|
-
* Being the front door also means it is the one command that never takes the
|
|
22
|
-
* session file's word for it. The installer runs `setup` after every install,
|
|
23
|
-
* including on a machine that already has a session, so this is where "is this
|
|
24
|
-
* account still real" gets asked of the *server* — a token that was revoked or
|
|
25
|
-
* has expired can't be allowed to pass as set up and arm a daemon that uploads
|
|
26
|
-
* into 401s.
|
|
27
|
-
*/
|
|
28
|
-
export declare function setup(): Promise<void>;
|
|
29
|
-
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AA0CA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA2L3C"}
|