@lawtedwu/climax-vault 0.1.0

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 ADDED
@@ -0,0 +1,67 @@
1
+ # @lawtedwu/climax-vault
2
+
3
+ Climax Racing Team 2026 GTWCA 赛季文件库 CLI(zero-token 客户端)。
4
+
5
+ 数据通过私有 Cloudflare Worker 提供,需要团队 token 才能访问。
6
+
7
+ ## 使用方式
8
+
9
+ 把下面这段 prompt 粘进 Claude / Coze / Cursor(**替换 `<TOKEN>` 为你的团队 token**):
10
+
11
+ ```
12
+ 我们的 Climax vault token 是 <TOKEN>。
13
+ 先跑 `CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest dump` 拉取
14
+ 全部赛季文档,然后回答我的问题。
15
+ ```
16
+
17
+ 或者直接命令行:
18
+
19
+ ```bash
20
+ CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest dump # 全量文档
21
+ CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest event sepang # Sepang 站
22
+ CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest regulations # 赛事规章
23
+ CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest tires # 轮胎数据
24
+ CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest team # 车队成员
25
+ CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest search "pit" # 全文搜索
26
+ ```
27
+
28
+ ## 获取 Token
29
+
30
+ 向车队经理(Arna Fong 方琨)申请。Token 用于鉴权所有 API 请求。
31
+
32
+ ## Commands
33
+
34
+ | Command | Description |
35
+ |---------|-------------|
36
+ | `help` | 显示帮助 |
37
+ | `dump` | 输出全部文档(给 agent 完整 context) |
38
+ | `list` | 列出 vault 中所有文件 |
39
+ | `regulations` | 赛事规章(规则/罚则/积分/进站) |
40
+ | `event <name>` | 分站信息(sepang/mandalika/shanghai/fuji/okayama/beijing) |
41
+ | `tires` | Pirelli 手册 + 规格索引 |
42
+ | `team` | 车队成员 + 联系方式 |
43
+ | `search <term>` | 全文搜索 |
44
+ | `file <path>` | 读取指定文件 |
45
+
46
+ ## Architecture
47
+
48
+ ```
49
+ Coze / Claude / Cursor
50
+
51
+ │ paste prompt with token
52
+
53
+ npx @lawtedwu/climax-vault
54
+
55
+ │ HTTPS + Bearer token
56
+
57
+ climax-vault.lawtedwu.workers.dev (Cloudflare Worker)
58
+
59
+ │ embedded vault data
60
+
61
+ Markdown content → stdout → agent reads it
62
+ ```
63
+
64
+ - **零 token 消耗**:CLI 不调用任何 AI API
65
+ - **数据私有**:托管在私有 Cloudflare Worker,token 鉴权
66
+ - **零基础设施**:Worker 跑在 Cloudflare 免费 tier
67
+ - **任何 agent 可用**:只要能跑 npx 命令就行
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+ const WORKER_URL = process.env.CLIMAX_WORKER_URL ?? "https://climax-vault.lawtedwu.workers.dev";
3
+ function getToken(args) {
4
+ const flagIdx = args.findIndex(a => a === "--token" || a.startsWith("--token="));
5
+ if (flagIdx !== -1) {
6
+ const arg = args[flagIdx];
7
+ if (arg.includes("="))
8
+ return arg.split("=").slice(1).join("=");
9
+ return args[flagIdx + 1] ?? "";
10
+ }
11
+ return process.env.CLIMAX_TOKEN ?? "";
12
+ }
13
+ function stripTokenArgs(args) {
14
+ const out = [];
15
+ for (let i = 0; i < args.length; i++) {
16
+ const a = args[i];
17
+ if (a === "--token") {
18
+ i++;
19
+ continue;
20
+ }
21
+ if (a.startsWith("--token="))
22
+ continue;
23
+ out.push(a);
24
+ }
25
+ return out;
26
+ }
27
+ async function fetchWorker(path, token) {
28
+ if (!token) {
29
+ console.error("❌ Missing team token. Set CLIMAX_TOKEN env var or pass --token=<token>.");
30
+ console.error(" Contact Climax Racing team manager for the token.");
31
+ process.exit(1);
32
+ }
33
+ const url = `${WORKER_URL}${path}`;
34
+ const res = await fetch(url, {
35
+ headers: { Authorization: `Bearer ${token}` },
36
+ });
37
+ if (res.status === 401) {
38
+ console.error("❌ Unauthorized. Token rejected by Climax vault Worker.");
39
+ process.exit(1);
40
+ }
41
+ if (!res.ok) {
42
+ console.error(`❌ Worker returned ${res.status}: ${await res.text()}`);
43
+ process.exit(1);
44
+ }
45
+ return await res.text();
46
+ }
47
+ function printHelp() {
48
+ console.log(`
49
+ climax-vault — Climax Racing Team 2026 GTWCA Document Vault (zero-token client)
50
+
51
+ USAGE
52
+ npx @lawtedwu/climax-vault <command> [options]
53
+ CLIMAX_TOKEN=<token> npx @lawtedwu/climax-vault <command>
54
+
55
+ AUTH
56
+ This CLI fetches data from a private Cloudflare Worker.
57
+ You need a team token. Get it from your team manager (Arna Fong 方琨).
58
+
59
+ Pass via env var: CLIMAX_TOKEN=xxx npx @lawtedwu/climax-vault dump
60
+ Or via flag: npx @lawtedwu/climax-vault dump --token=xxx
61
+
62
+ COMMANDS
63
+ help Show this help message
64
+ dump Output ALL documents (for full agent context)
65
+ list List all available files in the vault
66
+ regulations Sporting regulations (rules, penalties, points)
67
+ event <name> Event info (sepang, mandalika, shanghai, fuji, okayama, beijing)
68
+ tires Tire data: Pirelli book + specs index
69
+ team Team roster & contacts
70
+ search <term> Search across all documents
71
+
72
+ EXAMPLES
73
+ CLIMAX_TOKEN=xxx npx @lawtedwu/climax-vault dump
74
+ CLIMAX_TOKEN=xxx npx @lawtedwu/climax-vault event sepang
75
+ CLIMAX_TOKEN=xxx npx @lawtedwu/climax-vault search "pit stop"
76
+
77
+ ZERO-TOKEN PROMPT (paste into Claude / Coze / Cursor):
78
+
79
+ 我们的 Climax vault token 是 <TOKEN>。
80
+ 先跑 \`CLIMAX_TOKEN=<TOKEN> npx @lawtedwu/climax-vault@latest dump\` 拉取
81
+ 全部赛季文档,然后回答我的问题。
82
+ `);
83
+ }
84
+ const EVENT_ALIASES = {
85
+ sepang: "r1-r2-sepang",
86
+ mandalika: "r3-r4-mandalika",
87
+ shanghai: "r5-r6-shanghai",
88
+ fuji: "r7-r8-fuji",
89
+ okayama: "r9-r10-okayama",
90
+ beijing: "r11-r12-beijing",
91
+ r1: "r1-r2-sepang", r2: "r1-r2-sepang",
92
+ r3: "r3-r4-mandalika", r4: "r3-r4-mandalika",
93
+ r5: "r5-r6-shanghai", r6: "r5-r6-shanghai",
94
+ r7: "r7-r8-fuji", r8: "r7-r8-fuji",
95
+ r9: "r9-r10-okayama", r10: "r9-r10-okayama",
96
+ r11: "r11-r12-beijing", r12: "r11-r12-beijing",
97
+ };
98
+ async function main() {
99
+ const rawArgs = process.argv.slice(2);
100
+ const token = getToken(rawArgs);
101
+ const args = stripTokenArgs(rawArgs);
102
+ const cmd = args[0] ?? "help";
103
+ switch (cmd) {
104
+ case "help":
105
+ case "--help":
106
+ case "-h":
107
+ printHelp();
108
+ return;
109
+ case "list":
110
+ console.log(await fetchWorker("/list", token));
111
+ return;
112
+ case "dump":
113
+ console.log(await fetchWorker("/dump", token));
114
+ return;
115
+ case "regulations":
116
+ case "regs":
117
+ case "rules":
118
+ console.log(await fetchWorker("/file/regulations/sporting-regulations.md", token));
119
+ return;
120
+ case "tires":
121
+ case "tyres":
122
+ case "tire": {
123
+ const book = await fetchWorker("/file/tires/pirelli-book.md", token);
124
+ const specs = await fetchWorker("/file/tires/specs-index.md", token);
125
+ console.log(book);
126
+ console.log("\n" + "=".repeat(60) + "\n");
127
+ console.log(specs);
128
+ return;
129
+ }
130
+ case "team":
131
+ case "staff": {
132
+ const staff = await fetchWorker("/file/team/staff.md", token);
133
+ const contacts = await fetchWorker("/file/team/contacts.md", token);
134
+ console.log(staff);
135
+ console.log("\n" + "=".repeat(60) + "\n");
136
+ console.log(contacts);
137
+ return;
138
+ }
139
+ case "event": {
140
+ const name = (args[1] ?? "sepang").toLowerCase().replace(/[^a-z0-9]/g, "");
141
+ const dir = EVENT_ALIASES[name] ?? name;
142
+ const files = ["overview.md", "timetable.md", "cars.md", "logistics.md"];
143
+ for (const f of files) {
144
+ try {
145
+ const content = await fetchWorker(`/file/events/${dir}/${f}`, token);
146
+ console.log(`\n${"=".repeat(60)}\n📄 events/${dir}/${f}\n${"=".repeat(60)}\n`);
147
+ console.log(content);
148
+ }
149
+ catch {
150
+ // skip missing files (e.g. future events)
151
+ }
152
+ }
153
+ return;
154
+ }
155
+ case "search":
156
+ case "find":
157
+ case "grep": {
158
+ const term = args.slice(1).join(" ");
159
+ if (!term) {
160
+ console.error("Usage: search <term>");
161
+ process.exit(1);
162
+ }
163
+ console.log(await fetchWorker(`/search/${encodeURIComponent(term)}`, token));
164
+ return;
165
+ }
166
+ case "file": {
167
+ const path = args[1];
168
+ if (!path) {
169
+ console.error("Usage: file <path> (e.g. file regulations/sporting-regulations.md)");
170
+ process.exit(1);
171
+ }
172
+ console.log(await fetchWorker(`/file/${path}`, token));
173
+ return;
174
+ }
175
+ default:
176
+ console.error(`Unknown command: ${cmd}. Run "climax-vault help" for usage.`);
177
+ process.exit(1);
178
+ }
179
+ }
180
+ main().catch(err => {
181
+ console.error("❌ Error:", err.message);
182
+ process.exit(1);
183
+ });
184
+ export {};
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@lawtedwu/climax-vault",
3
+ "version": "0.1.0",
4
+ "description": "Climax Racing Team 2026 GTWCA document vault CLI. Zero-token client — fetches private team data from Cloudflare Worker.",
5
+ "type": "module",
6
+ "bin": {
7
+ "climax-vault": "dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/LAWTED/climax-vault.git",
13
+ "directory": "cli"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "dev": "tsx src/index.ts",
25
+ "prepublishOnly": "npm run build"
26
+ },
27
+ "keywords": [
28
+ "climax",
29
+ "racing",
30
+ "gtwca",
31
+ "gt3",
32
+ "vault",
33
+ "zero-token"
34
+ ],
35
+ "license": "UNLICENSED",
36
+ "engines": {
37
+ "node": ">=18"
38
+ },
39
+ "dependencies": {},
40
+ "devDependencies": {
41
+ "@types/node": "^20.11.0",
42
+ "tsx": "^4.7.0",
43
+ "typescript": "^5.4.0"
44
+ }
45
+ }