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/package.json
CHANGED
|
@@ -1,53 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hacklab",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"publishConfig": {
|
|
6
|
-
"access": "public"
|
|
7
|
-
},
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/hacklabubu/cli.git"
|
|
11
|
-
},
|
|
12
|
-
"type": "module",
|
|
13
|
-
"packageManager": "pnpm@10.11.1",
|
|
14
|
-
"engines": {
|
|
15
|
-
"node": ">=20"
|
|
16
|
-
},
|
|
3
|
+
"version": "26.921.1",
|
|
4
|
+
"description": "Bun CLI for agent-assisted Hacklab profile onboarding",
|
|
17
5
|
"bin": {
|
|
18
6
|
"hacklab": "./dist/index.js"
|
|
19
7
|
},
|
|
20
|
-
"files": [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"type": "module",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public",
|
|
14
|
+
"tag": "beta"
|
|
27
15
|
},
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"protobufjs": "^8.8.0",
|
|
36
|
-
"satori": "^0.26.0",
|
|
37
|
-
"sql.js": "^1.14.1",
|
|
38
|
-
"string-width": "^7.2.0",
|
|
39
|
-
"yaml": "^2.8.3",
|
|
40
|
-
"zod": "^4.3.6"
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "bun build src/index.ts --target=bun --outdir=dist && chmod +x dist/index.js",
|
|
18
|
+
"start": "bun src/index.ts",
|
|
19
|
+
"lint": "oxlint .",
|
|
20
|
+
"check-types": "tsc --noEmit",
|
|
21
|
+
"prepack": "bun run build",
|
|
22
|
+
"test": "bun test"
|
|
41
23
|
},
|
|
42
24
|
"devDependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"
|
|
45
|
-
"@types/sql.js": "^1.4.11",
|
|
46
|
-
"tsx": "^4.21.0",
|
|
47
|
-
"typescript": "^5.9.3",
|
|
48
|
-
"vitest": "^4.1.2"
|
|
25
|
+
"@types/bun": "^1.4.2",
|
|
26
|
+
"typescript": "^7.0.2"
|
|
49
27
|
},
|
|
50
|
-
"
|
|
51
|
-
"
|
|
28
|
+
"engines": {
|
|
29
|
+
"bun": ">=1.4.2"
|
|
52
30
|
}
|
|
53
31
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Homebrew Hackers Club inc
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/dist/agent-handoff.d.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The handoff: at the end of `hacklab setup` we look for a coding-agent CLI on
|
|
3
|
-
* the machine and, with one keypress of consent, hand it the profile-setup
|
|
4
|
-
* prompt. The agent runs interactively in the same terminal — the user watches
|
|
5
|
-
* it, answers its permission prompts, and (if the agent CLI is installed but
|
|
6
|
-
* logged out) walks its own login flow. Nothing here is silent or headless.
|
|
7
|
-
*
|
|
8
|
-
* Every outcome is reported to the backend, because the web onboarding waits
|
|
9
|
-
* only on positive evidence: a `launched` says an agent is running and the page
|
|
10
|
-
* should sit on "waiting for your agent"; `declined` / `unavailable` (and no
|
|
11
|
-
* signal at all) put the manual paste-the-prompt step up instead.
|
|
12
|
-
*/
|
|
13
|
-
export type AgentCli = {
|
|
14
|
-
/** Executable name, as it appears on PATH. */
|
|
15
|
-
bin: string;
|
|
16
|
-
/** What we call it in the terminal. */
|
|
17
|
-
name: string;
|
|
18
|
-
/** argv for "open interactively, seeded with this prompt". */
|
|
19
|
-
args: (prompt: string) => string[];
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Probed in order — first one on PATH wins. All three take the prompt as a
|
|
23
|
-
* single positional argument today; the shape stays per-entry so one of them
|
|
24
|
-
* can diverge without touching the others.
|
|
25
|
-
*/
|
|
26
|
-
export declare const AGENT_CLIS: AgentCli[];
|
|
27
|
-
/** The first agent CLI installed on this machine, or null if there is none. */
|
|
28
|
-
export declare function findAgentCli(): AgentCli | null;
|
|
29
|
-
/**
|
|
30
|
-
* Hand the terminal to `agent`, seeded with `prompt`, and block until its
|
|
31
|
-
* session exits. Returns false when the process never started (ENOENT, a broken
|
|
32
|
-
* shim) — the caller then treats the agent as unavailable. A non-zero exit is
|
|
33
|
-
* still a launch: the user was there and saw whatever happened.
|
|
34
|
-
*/
|
|
35
|
-
export declare function launchAgentCli(agent: AgentCli, prompt: string): boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Tell the backend what happened to the profile work, so the web onboarding
|
|
38
|
-
* knows which state to show: `launched` is the positive evidence that an agent
|
|
39
|
-
* is now running and the page should wait for it; `declined` and `unavailable`
|
|
40
|
-
* mean nobody took it, so the page shows the manual paste-the-prompt step
|
|
41
|
-
* instead of waiting for a ping that is never coming.
|
|
42
|
-
*
|
|
43
|
-
* Best effort by design: a failure (offline, or a backend too old to know the
|
|
44
|
-
* `launched` outcome and 400ing it) must never break the end of setup.
|
|
45
|
-
*
|
|
46
|
-
* Server contract (POST /api/cli/agent-handoff):
|
|
47
|
-
* `Authorization: Bearer <session token>`, body `{ outcome, agent? }`,
|
|
48
|
-
* where `agent` is the binary name we launched or offered (e.g. `claude`).
|
|
49
|
-
*/
|
|
50
|
-
export declare function notifyAgentHandoff(appUrl: string, token: string, outcome: 'launched' | 'unavailable' | 'declined', agent?: string): Promise<void>;
|
|
51
|
-
//# sourceMappingURL=agent-handoff.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-handoff.d.ts","sourceRoot":"","sources":["../src/agent-handoff.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,QAAQ,GAAG;IACrB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAA;IACX,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,8DAA8D;IAC9D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;CACnC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,EAIhC,CAAA;AA2BD,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,QAAQ,GAAG,IAAI,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAWvE;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,UAAU,GAAG,aAAa,GAAG,UAAU,EAChD,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
package/dist/agent-handoff.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { accessSync, constants } from 'node:fs';
|
|
3
|
-
import { delimiter, join } from 'node:path';
|
|
4
|
-
/**
|
|
5
|
-
* Probed in order — first one on PATH wins. All three take the prompt as a
|
|
6
|
-
* single positional argument today; the shape stays per-entry so one of them
|
|
7
|
-
* can diverge without touching the others.
|
|
8
|
-
*/
|
|
9
|
-
export const AGENT_CLIS = [
|
|
10
|
-
{ bin: 'claude', name: 'Claude Code', args: (prompt) => [prompt] },
|
|
11
|
-
{ bin: 'codex', name: 'Codex', args: (prompt) => [prompt] },
|
|
12
|
-
{ bin: 'grok', name: 'Grok', args: (prompt) => [prompt] },
|
|
13
|
-
];
|
|
14
|
-
/** Is `bin` an executable file in one of the PATH directories? */
|
|
15
|
-
function onPath(bin) {
|
|
16
|
-
const dirs = (process.env.PATH ?? '').split(delimiter).filter(Boolean);
|
|
17
|
-
// On Windows the thing on PATH is `claude.cmd` / `claude.exe`, never a
|
|
18
|
-
// bare-named file, so every candidate needs the PATHEXT suffixes tried.
|
|
19
|
-
const exts = process.platform === 'win32'
|
|
20
|
-
? (process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD')
|
|
21
|
-
.split(';')
|
|
22
|
-
.filter(Boolean)
|
|
23
|
-
: [''];
|
|
24
|
-
for (const dir of dirs) {
|
|
25
|
-
for (const ext of exts) {
|
|
26
|
-
try {
|
|
27
|
-
accessSync(join(dir, bin + ext), constants.X_OK);
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// Not here (missing, or not executable) — keep looking.
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
/** The first agent CLI installed on this machine, or null if there is none. */
|
|
38
|
-
export function findAgentCli() {
|
|
39
|
-
return AGENT_CLIS.find((agent) => onPath(agent.bin)) ?? null;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Hand the terminal to `agent`, seeded with `prompt`, and block until its
|
|
43
|
-
* session exits. Returns false when the process never started (ENOENT, a broken
|
|
44
|
-
* shim) — the caller then treats the agent as unavailable. A non-zero exit is
|
|
45
|
-
* still a launch: the user was there and saw whatever happened.
|
|
46
|
-
*/
|
|
47
|
-
export function launchAgentCli(agent, prompt) {
|
|
48
|
-
// Windows agent CLIs are `.cmd` shims, which Node refuses to spawn without a
|
|
49
|
-
// shell; cmd.exe joins argv verbatim, so the prompt needs its own quotes.
|
|
50
|
-
const win = process.platform === 'win32';
|
|
51
|
-
const args = agent.args(prompt).map((arg) => (win ? `"${arg}"` : arg));
|
|
52
|
-
try {
|
|
53
|
-
const res = spawnSync(agent.bin, args, { stdio: 'inherit', shell: win });
|
|
54
|
-
return !res.error;
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
const HANDOFF_TIMEOUT_MS = 8000;
|
|
61
|
-
/**
|
|
62
|
-
* Tell the backend what happened to the profile work, so the web onboarding
|
|
63
|
-
* knows which state to show: `launched` is the positive evidence that an agent
|
|
64
|
-
* is now running and the page should wait for it; `declined` and `unavailable`
|
|
65
|
-
* mean nobody took it, so the page shows the manual paste-the-prompt step
|
|
66
|
-
* instead of waiting for a ping that is never coming.
|
|
67
|
-
*
|
|
68
|
-
* Best effort by design: a failure (offline, or a backend too old to know the
|
|
69
|
-
* `launched` outcome and 400ing it) must never break the end of setup.
|
|
70
|
-
*
|
|
71
|
-
* Server contract (POST /api/cli/agent-handoff):
|
|
72
|
-
* `Authorization: Bearer <session token>`, body `{ outcome, agent? }`,
|
|
73
|
-
* where `agent` is the binary name we launched or offered (e.g. `claude`).
|
|
74
|
-
*/
|
|
75
|
-
export async function notifyAgentHandoff(appUrl, token, outcome, agent) {
|
|
76
|
-
try {
|
|
77
|
-
await fetch(`${appUrl}/api/cli/agent-handoff`, {
|
|
78
|
-
method: 'POST',
|
|
79
|
-
headers: {
|
|
80
|
-
'Content-Type': 'application/json',
|
|
81
|
-
Authorization: `Bearer ${token}`,
|
|
82
|
-
},
|
|
83
|
-
body: JSON.stringify({ outcome, ...(agent ? { agent } : {}) }),
|
|
84
|
-
signal: AbortSignal.timeout(HANDOFF_TIMEOUT_MS),
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
// Best effort — setup is already done, and this only steers the web page.
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=agent-handoff.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-handoff.js","sourceRoot":"","sources":["../src/agent-handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAwB3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAe;IACpC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;IAClE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;IAC3D,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;CAC1D,CAAA;AAED,kEAAkE;AAClE,SAAS,MAAM,CAAC,GAAW;IACzB,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtE,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,IAAI,GACR,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC1B,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,qBAAqB,CAAC;aAC3C,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAEV,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAA;gBAChD,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,wDAAwD;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAA;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAe,EAAE,MAAc;IAC5D,6EAA6E;IAC7E,0EAA0E;IAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAA;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACtE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QACxE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAE/B;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,KAAa,EACb,OAAgD,EAChD,KAAc;IAEd,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,GAAG,MAAM,wBAAwB,EAAE;YAC7C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9D,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;SAChD,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;IAC5E,CAAC;AACH,CAAC"}
|
package/dist/api-client.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type Session } from './session.js';
|
|
2
|
-
/** Print the versioned JSON error envelope and exit 1 (agent mode). */
|
|
3
|
-
export declare function emitJsonError(code: string, message: string): never;
|
|
4
|
-
/** Login gate: returns the session or exits with mode-appropriate copy. */
|
|
5
|
-
export declare function requireSession(json: boolean): Promise<Session>;
|
|
6
|
-
/**
|
|
7
|
-
* Human-readable message for a non-2xx envelope body. 401 gets the per-backend
|
|
8
|
-
* re-login hint (an --env mismatch names the exact login command), 429 the
|
|
9
|
-
* slow-down copy; anything else relays the server's message.
|
|
10
|
-
*/
|
|
11
|
-
export declare function apiErrorMessage(status: number, body: {
|
|
12
|
-
error?: {
|
|
13
|
-
message?: string;
|
|
14
|
-
};
|
|
15
|
-
} | null, session: Session): string;
|
|
16
|
-
/** Read a failed Response's envelope and shape it via apiErrorMessage. */
|
|
17
|
-
export declare function readApiError(res: Response, session: Session): Promise<string>;
|
|
18
|
-
//# sourceMappingURL=api-client.d.ts.map
|
package/dist/api-client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,OAAO,EAAoB,MAAM,cAAc,CAAA;AAO1E,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,CAGlE;AAED,2EAA2E;AAC3E,wBAAsB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CASpE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,EAC7C,OAAO,EAAE,OAAO,GACf,MAAM,CAIR;AAED,0EAA0E;AAC1E,wBAAsB,YAAY,CAChC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAKjB"}
|
package/dist/api-client.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { loadSession, unauthorizedHint } from './session.js';
|
|
2
|
-
import { dim, error, info } from './ui.js';
|
|
3
|
-
// Shared plumbing for authenticated agent-friendly commands (profile, hacker):
|
|
4
|
-
// one login gate, one JSON error envelope, one reader for the server's
|
|
5
|
-
// {schemaVersion, error} shape — so the 401/429 copy can't drift per command.
|
|
6
|
-
/** Print the versioned JSON error envelope and exit 1 (agent mode). */
|
|
7
|
-
export function emitJsonError(code, message) {
|
|
8
|
-
console.log(JSON.stringify({ schemaVersion: 1, error: { code, message } }));
|
|
9
|
-
process.exit(1);
|
|
10
|
-
}
|
|
11
|
-
/** Login gate: returns the session or exits with mode-appropriate copy. */
|
|
12
|
-
export async function requireSession(json) {
|
|
13
|
-
const session = await loadSession();
|
|
14
|
-
if (!session) {
|
|
15
|
-
if (json)
|
|
16
|
-
emitJsonError('unauthorized', 'not logged in');
|
|
17
|
-
error('not logged in');
|
|
18
|
-
info(`run ${dim('hacklab login')} first`);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
return session;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Human-readable message for a non-2xx envelope body. 401 gets the per-backend
|
|
25
|
-
* re-login hint (an --env mismatch names the exact login command), 429 the
|
|
26
|
-
* slow-down copy; anything else relays the server's message.
|
|
27
|
-
*/
|
|
28
|
-
export function apiErrorMessage(status, body, session) {
|
|
29
|
-
if (status === 401)
|
|
30
|
-
return unauthorizedHint(session);
|
|
31
|
-
if (status === 429)
|
|
32
|
-
return 'slow down. try again in a minute.';
|
|
33
|
-
return body?.error?.message ?? `request failed (${status})`;
|
|
34
|
-
}
|
|
35
|
-
/** Read a failed Response's envelope and shape it via apiErrorMessage. */
|
|
36
|
-
export async function readApiError(res, session) {
|
|
37
|
-
const body = (await res.json().catch(() => null));
|
|
38
|
-
return apiErrorMessage(res.status, body, session);
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=api-client.js.map
|
package/dist/api-client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC1E,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE1C,+EAA+E;AAC/E,uEAAuE;AACvE,8EAA8E;AAE9E,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe;IACzD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAa;IAChD,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,IAAI,IAAI;YAAE,aAAa,CAAC,cAAc,EAAE,eAAe,CAAC,CAAA;QACxD,KAAK,CAAC,eAAe,CAAC,CAAA;QACtB,IAAI,CAAC,OAAO,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,IAA6C,EAC7C,OAAgB;IAEhB,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,mCAAmC,CAAA;IAC9D,OAAO,IAAI,EAAE,KAAK,EAAE,OAAO,IAAI,mBAAmB,MAAM,GAAG,CAAA;AAC7D,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAa,EACb,OAAgB;IAEhB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAExC,CAAA;IACR,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;AACnD,CAAC"}
|
package/dist/belt.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export type BeltColor = 'white' | 'orange' | 'red' | 'blue' | 'cyan' | 'yellow' | 'lime' | 'green' | 'pink' | 'purple' | 'black';
|
|
2
|
-
export type Title = 'gaijin' | 'deshi' | 'ronin' | 'shinobi' | 'samurai' | 'senpai' | 'tatsujin' | 'kensei' | 'oni' | 'ryujin';
|
|
3
|
-
export type DanTitle = 'shodan' | 'nidan' | 'sandan' | 'yondan' | 'godan' | 'rokudan' | 'nanadan' | 'hachidan' | 'kudan' | 'judan';
|
|
4
|
-
export type GrandMasterTitle = 'shihan' | 'hanshi' | 'meijin' | 'oyama';
|
|
5
|
-
/** Convert raw token count to Pyro XP. 1,000 tokens = 1 XP. */
|
|
6
|
-
export declare function tokensToXp(tokens: number): number;
|
|
7
|
-
/** Convert total XP to level (fractional). */
|
|
8
|
-
export declare function xpToLevel(xp: number): number;
|
|
9
|
-
/** Convert level to minimum XP required. */
|
|
10
|
-
export declare function levelToMinXp(level: number): number;
|
|
11
|
-
/** Get the integer level (floor of fractional level). */
|
|
12
|
-
export declare function getLevel(xp: number): number;
|
|
13
|
-
/** Get belt color for a given level. */
|
|
14
|
-
export declare function getBeltColor(level: number): BeltColor;
|
|
15
|
-
/** Get title for a given level. */
|
|
16
|
-
export declare function getTitle(level: number): Title | DanTitle | GrandMasterTitle;
|
|
17
|
-
export type BeltProgress = {
|
|
18
|
-
level: number;
|
|
19
|
-
title: Title | DanTitle | GrandMasterTitle;
|
|
20
|
-
beltColor: BeltColor;
|
|
21
|
-
progressPercent: number;
|
|
22
|
-
};
|
|
23
|
-
/** Belt info for a raw token total (pyro-only — correct for a fresh account). */
|
|
24
|
-
export declare function beltForTokens(tokensTotal: number): BeltProgress;
|
|
25
|
-
//# sourceMappingURL=belt.d.ts.map
|
package/dist/belt.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"belt.d.ts","sourceRoot":"","sources":["../src/belt.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,MAAM,GACN,QAAQ,GACR,OAAO,CAAA;AAEX,MAAM,MAAM,KAAK,GACb,QAAQ,GACR,OAAO,GACP,OAAO,GACP,SAAS,GACT,SAAS,GACT,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,KAAK,GACL,QAAQ,CAAA;AAEZ,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,SAAS,GACT,SAAS,GACT,UAAU,GACV,OAAO,GACP,OAAO,CAAA;AAEX,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAqCvE,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,yDAAyD;AACzD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAMrD;AAED,mCAAmC;AACnC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,gBAAgB,CAkB3E;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,gBAAgB,CAAA;IAC1C,SAAS,EAAE,SAAS,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAgB/D"}
|
package/dist/belt.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
// Belt / level math — ported verbatim from @hacklab/db `levels.ts` so the CLI
|
|
2
|
-
// can render the share card instantly (locally) without waiting on the server.
|
|
3
|
-
// The CLI is a standalone published package and must not pull in @hacklab/db
|
|
4
|
-
// (drizzle/pg/etc.), so we copy the small, stable curve here.
|
|
5
|
-
//
|
|
6
|
-
// One curve: xp(level) = 23 × level^3.32 up to level 100, exponential above.
|
|
7
|
-
// Pyro XP = tokens / 1000. For a brand-new account, hacker + mason XP are 0, so
|
|
8
|
-
// belt XP == pyro XP — which is exactly what the server computes right after
|
|
9
|
-
// the first sync. Kept in sync via belt.test.ts (anchored to the known points).
|
|
10
|
-
const K = 3.32;
|
|
11
|
-
const A = 23;
|
|
12
|
-
const LEVEL_100_XP = 100_000_000; // 100M XP
|
|
13
|
-
const BELT_TIERS = [
|
|
14
|
-
{ minLevel: 0, color: 'white', title: 'gaijin' },
|
|
15
|
-
{ minLevel: 10, color: 'orange', title: 'deshi' },
|
|
16
|
-
{ minLevel: 20, color: 'red', title: 'ronin' },
|
|
17
|
-
{ minLevel: 30, color: 'blue', title: 'shinobi' },
|
|
18
|
-
{ minLevel: 40, color: 'cyan', title: 'samurai' },
|
|
19
|
-
{ minLevel: 50, color: 'yellow', title: 'senpai' },
|
|
20
|
-
{ minLevel: 60, color: 'lime', title: 'tatsujin' },
|
|
21
|
-
{ minLevel: 70, color: 'green', title: 'kensei' },
|
|
22
|
-
{ minLevel: 80, color: 'pink', title: 'oni' },
|
|
23
|
-
{ minLevel: 90, color: 'purple', title: 'ryujin' },
|
|
24
|
-
];
|
|
25
|
-
const DAN_TITLES = [
|
|
26
|
-
'shodan',
|
|
27
|
-
'nidan',
|
|
28
|
-
'sandan',
|
|
29
|
-
'yondan',
|
|
30
|
-
'godan',
|
|
31
|
-
'rokudan',
|
|
32
|
-
'nanadan',
|
|
33
|
-
'hachidan',
|
|
34
|
-
'kudan',
|
|
35
|
-
'judan',
|
|
36
|
-
];
|
|
37
|
-
const GRAND_MASTER_TIERS = [
|
|
38
|
-
{ minLevel: 200, title: 'shihan' },
|
|
39
|
-
{ minLevel: 300, title: 'hanshi' },
|
|
40
|
-
{ minLevel: 400, title: 'meijin' },
|
|
41
|
-
{ minLevel: 500, title: 'oyama' },
|
|
42
|
-
];
|
|
43
|
-
/** Convert raw token count to Pyro XP. 1,000 tokens = 1 XP. */
|
|
44
|
-
export function tokensToXp(tokens) {
|
|
45
|
-
return Math.floor(tokens / 1_000);
|
|
46
|
-
}
|
|
47
|
-
/** Convert total XP to level (fractional). */
|
|
48
|
-
export function xpToLevel(xp) {
|
|
49
|
-
if (xp <= 0)
|
|
50
|
-
return 0;
|
|
51
|
-
if (xp >= LEVEL_100_XP) {
|
|
52
|
-
return 100 + 100 * Math.log10(xp / LEVEL_100_XP);
|
|
53
|
-
}
|
|
54
|
-
return (xp / A) ** (1 / K);
|
|
55
|
-
}
|
|
56
|
-
/** Convert level to minimum XP required. */
|
|
57
|
-
export function levelToMinXp(level) {
|
|
58
|
-
if (level <= 0)
|
|
59
|
-
return 0;
|
|
60
|
-
if (level >= 100) {
|
|
61
|
-
return Math.round(LEVEL_100_XP * 10 ** ((level - 100) / 100));
|
|
62
|
-
}
|
|
63
|
-
return Math.round(A * level ** K);
|
|
64
|
-
}
|
|
65
|
-
/** Get the integer level (floor of fractional level). */
|
|
66
|
-
export function getLevel(xp) {
|
|
67
|
-
return Math.floor(xpToLevel(xp));
|
|
68
|
-
}
|
|
69
|
-
/** Get belt color for a given level. */
|
|
70
|
-
export function getBeltColor(level) {
|
|
71
|
-
if (level >= 100)
|
|
72
|
-
return 'black';
|
|
73
|
-
for (let i = BELT_TIERS.length - 1; i >= 0; i--) {
|
|
74
|
-
if (level >= BELT_TIERS[i].minLevel)
|
|
75
|
-
return BELT_TIERS[i].color;
|
|
76
|
-
}
|
|
77
|
-
return 'white';
|
|
78
|
-
}
|
|
79
|
-
/** Get title for a given level. */
|
|
80
|
-
export function getTitle(level) {
|
|
81
|
-
if (level >= 200) {
|
|
82
|
-
for (let i = GRAND_MASTER_TIERS.length - 1; i >= 0; i--) {
|
|
83
|
-
if (level >= GRAND_MASTER_TIERS[i].minLevel)
|
|
84
|
-
return GRAND_MASTER_TIERS[i].title;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (level >= 100) {
|
|
88
|
-
const danIndex = Math.min(Math.floor((level - 100) / 10), DAN_TITLES.length - 1);
|
|
89
|
-
return DAN_TITLES[danIndex];
|
|
90
|
-
}
|
|
91
|
-
for (let i = BELT_TIERS.length - 1; i >= 0; i--) {
|
|
92
|
-
if (level >= BELT_TIERS[i].minLevel)
|
|
93
|
-
return BELT_TIERS[i].title;
|
|
94
|
-
}
|
|
95
|
-
return 'gaijin';
|
|
96
|
-
}
|
|
97
|
-
/** Belt info for a raw token total (pyro-only — correct for a fresh account). */
|
|
98
|
-
export function beltForTokens(tokensTotal) {
|
|
99
|
-
const xp = tokensToXp(tokensTotal);
|
|
100
|
-
const level = getLevel(xp);
|
|
101
|
-
const currentLevelXp = levelToMinXp(level);
|
|
102
|
-
const nextLevelXp = levelToMinXp(level + 1);
|
|
103
|
-
const xpIntoLevel = xp - currentLevelXp;
|
|
104
|
-
const xpNeeded = nextLevelXp - currentLevelXp;
|
|
105
|
-
const progressPercent = xpNeeded > 0 ? Math.min(Math.round((xpIntoLevel / xpNeeded) * 100), 100) : 0;
|
|
106
|
-
return {
|
|
107
|
-
level,
|
|
108
|
-
title: getTitle(level),
|
|
109
|
-
beltColor: getBeltColor(level),
|
|
110
|
-
progressPercent,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=belt.js.map
|
package/dist/belt.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"belt.js","sourceRoot":"","sources":["../src/belt.ts"],"names":[],"mappings":"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"}
|
package/dist/card.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export type HackerCardData = {
|
|
2
|
-
handle: string;
|
|
3
|
-
displayName: string | null;
|
|
4
|
-
bio: string | null;
|
|
5
|
-
joinedAt: string;
|
|
6
|
-
claimedAt: string | null;
|
|
7
|
-
level: number;
|
|
8
|
-
tokensTotal: number;
|
|
9
|
-
tokens30d: number;
|
|
10
|
-
estimatedCost: number;
|
|
11
|
-
rank: number | null;
|
|
12
|
-
topModels30d: {
|
|
13
|
-
model: string;
|
|
14
|
-
tokens: number;
|
|
15
|
-
pct: number;
|
|
16
|
-
}[];
|
|
17
|
-
currentStreak: number;
|
|
18
|
-
longestStreak: number;
|
|
19
|
-
activeDays30: number;
|
|
20
|
-
activity30: number[];
|
|
21
|
-
counts: {
|
|
22
|
-
projects: number;
|
|
23
|
-
essays: number;
|
|
24
|
-
drops: number;
|
|
25
|
-
followers: number;
|
|
26
|
-
};
|
|
27
|
-
recent: {
|
|
28
|
-
projects: {
|
|
29
|
-
title: string;
|
|
30
|
-
description: string | null;
|
|
31
|
-
}[];
|
|
32
|
-
essays: {
|
|
33
|
-
title: string;
|
|
34
|
-
publishedAt: string | null;
|
|
35
|
-
}[];
|
|
36
|
-
drops: {
|
|
37
|
-
text: string;
|
|
38
|
-
createdAt: string;
|
|
39
|
-
}[];
|
|
40
|
-
};
|
|
41
|
-
links: {
|
|
42
|
-
profile: string;
|
|
43
|
-
website: string | null;
|
|
44
|
-
github: string | null;
|
|
45
|
-
x: string | null;
|
|
46
|
-
};
|
|
47
|
-
openToWork: boolean;
|
|
48
|
-
};
|
|
49
|
-
export type RenderCardOptions = {
|
|
50
|
-
/** Terminal columns. Clamped to [MIN_WIDTH, DESIGN_WIDTH]. */
|
|
51
|
-
columns?: number;
|
|
52
|
-
now?: Date;
|
|
53
|
-
};
|
|
54
|
-
/**
|
|
55
|
-
* Render the full one-screen card as an array of lines (caller joins with \n).
|
|
56
|
-
* Pure: no I/O, deterministic given `now`. Every user-supplied string is passed
|
|
57
|
-
* through stripControl before it reaches the terminal.
|
|
58
|
-
*/
|
|
59
|
-
export declare function renderCard(card: HackerCardData, opts?: RenderCardOptions): string[];
|
|
60
|
-
/**
|
|
61
|
-
* The compact in-chat card (`/who`): 4 lines, no rules, no sparkline. Same
|
|
62
|
-
* strip discipline. Returned as separate lines so the chat renderer can push
|
|
63
|
-
* them as one Entry per row (preserving the one-row-per-entry invariant).
|
|
64
|
-
*/
|
|
65
|
-
export declare function renderCompact(card: HackerCardData): string[];
|
|
66
|
-
//# sourceMappingURL=card.d.ts.map
|
package/dist/card.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../src/card.ts"],"names":[],"mappings":"AAuBA,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC9D,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9E,MAAM,EAAE;QACN,QAAQ,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,EAAE,CAAA;QACzD,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,EAAE,CAAA;QACvD,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC7C,CAAA;IACD,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;QACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACjB,CAAA;IACD,UAAU,EAAE,OAAO,CAAA;CACpB,CAAA;AAQD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,IAAI,CAAA;CACX,CAAA;AAyFD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE,iBAAsB,GAC3B,MAAM,EAAE,CAiHV;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAY5D"}
|