theclawbay 0.3.8 → 0.3.10

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 CHANGED
@@ -1,15 +1,6 @@
1
- # The Claw Bay (`theclawbay`)
1
+ # theclawbay
2
2
 
3
- `theclawbay` is a customer CLI for The Claw Bay.
4
-
5
- This package no longer runs local account login automation or local account switching flows.
6
-
7
- > Not affiliated with OpenAI or Codex. Not an official tool.
8
-
9
- ## Requirements
10
-
11
- - Node.js 18+
12
- - Codex CLI (`@openai/codex`) and/or OpenClaw CLI
3
+ CLI for connecting Codex, OpenClaw, and OpenCode to The Claw Bay.
13
4
 
14
5
  ## Install
15
6
 
@@ -17,75 +8,20 @@ This package no longer runs local account login automation or local account swit
17
8
  npm i -g theclawbay
18
9
  ```
19
10
 
20
- If you use `nvm`, keep a single global prefix to avoid duplicate binaries:
21
-
22
- ```sh
23
- npm config delete prefix
24
- ```
25
-
26
- ## One-Time Setup (Recommended)
11
+ ## Setup
27
12
 
28
- Use your purchased API key from your dashboard:
13
+ Get your API key from `https://theclawbay.com/dashboard`.
29
14
 
30
15
  ```sh
31
16
  theclawbay setup --api-key <apiKey>
32
17
  ```
33
18
 
34
- This auto-detects installed clients and writes direct WAN API-key config so users can run directly.
35
- It configures Codex with `model_provider = "theclawbay"` and a managed bearer token, auto-selects the highest backend-advertised model, and preserves conversation visibility by neutralizing legacy local session provider tags so chats remain visible across provider modes.
36
-
37
- It also configures OpenClaw/OpenCode automatically when those CLIs are installed.
38
- OpenClaw/OpenCode provider configs are written with a literal API key (no env var dependency).
39
- If OpenClaw has a stale `${CODEX_LB_API_KEY}` placeholder from an older setup, `theclawbay setup` now auto-heals `~/.openclaw/openclaw.json`.
40
-
41
- `CODEX_LB_API_KEY` is persisted for restarts in:
42
-
43
- - `~/.config/theclawbay/env`
44
- - `~/.bashrc`
45
- - `~/.zshrc`
46
- - `~/.profile`
47
- - `~/.vscode-server/server-env-setup` (and `~/.vscode-server-insiders/server-env-setup` when present)
48
-
49
- If you operate a custom backend, pass it explicitly:
50
-
51
- ```sh
52
- theclawbay setup --api-key <apiKey> --backend https://your-domain.com
53
- ```
54
-
55
- After setup, restart terminal/VS Code once only if your own shell workflows depend on `CODEX_LB_API_KEY`.
19
+ ## Optional
56
20
 
57
- ## Codex Extension Behavior
21
+ `theclawbay link --api-key <apiKey>`
58
22
 
59
- - In API-key provider mode, Codex may label the model source as `Custom`.
60
- - Full ChatGPT account model-picker behavior is tied to ChatGPT auth mode.
61
- - `theclawbay setup` keeps your existing Codex login state unchanged on purpose (so local history context is preserved and setup stays non-destructive).
62
-
63
- ## Link Only (Optional)
64
-
65
- If you only want to save backend/API-key state without applying local client config yet:
66
-
67
- ```sh
68
- theclawbay link --api-key <apiKey>
69
- ```
70
-
71
- ## Logout
72
-
73
- To remove local The Claw Bay API-key auth state from this machine:
74
-
75
- ```sh
76
- theclawbay logout
77
- ```
78
-
79
- ## Release Notes (Maintainers)
80
-
81
- If a previous publish failed after version bump, publish the current local version without bumping again:
82
-
83
- ```sh
84
- npm run release:publish
85
- ```
23
+ Saves the API key without writing local client config.
86
24
 
87
- ## Notes
25
+ `theclawbay logout`
88
26
 
89
- - End users only need API keys. They do not need upstream account credentials.
90
- - Keep your backend on HTTPS for WAN usage.
91
- - Linked config is stored at `~/.codex/theclawbay.managed.json`.
27
+ Removes The Claw Bay-managed local config from this machine.
@@ -530,6 +530,9 @@ class SetupCommand extends base_command_1.BaseCommand {
530
530
  else if (modelCacheMigration.action === "created") {
531
531
  this.log("- Codex model cache: created a local picker cache with GPT-5.4.");
532
532
  }
533
+ else if (modelCacheMigration.action === "refreshed") {
534
+ this.log("- Codex model cache: refreshed the local picker cache for GPT-5.4.");
535
+ }
533
536
  else if (modelCacheMigration.action === "already_seeded") {
534
537
  this.log("- Codex model cache: GPT-5.4 was already seeded locally.");
535
538
  }
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ async function maybePrintBareInvocationHint() {
29
29
  currentVersion,
30
30
  log: (message) => console.log(message),
31
31
  }).catch(() => { });
32
- console.log("Get your API key at: https://theclawbay.com/keys");
32
+ console.log("Get your API key at: https://theclawbay.com/dashboard");
33
33
  console.log("Then run: theclawbay setup --api-key <apiKey>");
34
34
  console.log("");
35
35
  }
@@ -1,5 +1,5 @@
1
1
  export type EnsureCodexModelCacheResult = {
2
- action: "seeded" | "created" | "already_present" | "already_seeded" | "skipped";
2
+ action: "seeded" | "created" | "refreshed" | "already_present" | "already_seeded" | "skipped";
3
3
  warning?: string;
4
4
  };
5
5
  export type CleanupCodexModelCacheResult = {
@@ -196,6 +196,19 @@ function buildSeedModel(models) {
196
196
  }
197
197
  return normalizeSeedModel(null);
198
198
  }
199
+ function setCacheFreshnessMetadata(doc, clientVersion) {
200
+ let changed = false;
201
+ const now = new Date().toISOString();
202
+ if (doc.fetched_at !== now) {
203
+ doc.fetched_at = now;
204
+ changed = true;
205
+ }
206
+ if (clientVersion && doc.client_version !== clientVersion) {
207
+ doc.client_version = clientVersion;
208
+ changed = true;
209
+ }
210
+ return changed;
211
+ }
199
212
  function parseCodexVersion(stdout) {
200
213
  const match = stdout.match(/\b(\d+\.\d+\.\d+)\b/);
201
214
  return match ? match[1] : null;
@@ -356,31 +369,46 @@ async function ensureCodexModelCacheHasGpt54(params) {
356
369
  warning: "Codex models cache exists but is not valid JSON in the expected format; skipped GPT-5.4 seed.",
357
370
  };
358
371
  }
372
+ const clientVersion = (await inferCodexClientVersion(params.codexHome)) ??
373
+ (typeof doc.client_version === "string" && doc.client_version ? doc.client_version : null);
359
374
  const existingModel = findModel(doc.models, TARGET_MODEL_ID);
360
375
  if (existingModel) {
361
376
  const currentFingerprint = fingerprintModel(existingModel);
362
377
  if (existingState && existingState.fingerprint === currentFingerprint && !hasSeedMarker(existingModel)) {
363
378
  const seededModel = applySeedMarker(existingModel);
364
379
  doc.models = doc.models.map((entry) => (entry.slug === TARGET_MODEL_ID ? seededModel : entry));
380
+ setCacheFreshnessMetadata(doc, clientVersion);
365
381
  await promises_1.default.writeFile(cachePath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
366
382
  await writePatchState(statePath, fingerprintModel(seededModel));
367
383
  return { action: "seeded" };
368
384
  }
369
385
  if (hasSeedMarker(existingModel)) {
386
+ const docChanged = setCacheFreshnessMetadata(doc, clientVersion);
370
387
  if (!existingState || existingState.fingerprint !== currentFingerprint) {
371
388
  await writePatchState(statePath, currentFingerprint);
389
+ await promises_1.default.writeFile(cachePath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
390
+ return { action: "refreshed" };
391
+ }
392
+ if (docChanged) {
393
+ await promises_1.default.writeFile(cachePath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
394
+ return { action: "refreshed" };
372
395
  }
373
396
  return { action: "already_seeded" };
374
397
  }
375
398
  if (existingState && existingState.fingerprint !== currentFingerprint) {
376
399
  await removeFileIfExists(statePath);
377
400
  }
401
+ if (setCacheFreshnessMetadata(doc, clientVersion)) {
402
+ await promises_1.default.writeFile(cachePath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
403
+ return { action: "refreshed" };
404
+ }
378
405
  return {
379
406
  action: existingState && existingState.fingerprint === currentFingerprint ? "already_seeded" : "already_present",
380
407
  };
381
408
  }
382
409
  const seed = buildSeedModel(doc.models);
383
410
  doc.models = [seed, ...doc.models];
411
+ setCacheFreshnessMetadata(doc, clientVersion);
384
412
  await promises_1.default.writeFile(cachePath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
385
413
  await writePatchState(statePath, fingerprintModel(seed));
386
414
  return { action: "seeded" };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "theclawbay",
3
- "version": "0.3.8",
4
- "description": "The Claw Bay CLI: one-time API-key setup for direct Codex access.",
3
+ "version": "0.3.10",
4
+ "description": "CLI for connecting Codex, OpenClaw, and OpenCode to The Claw Bay.",
5
5
  "license": "MIT",
6
6
  "bin": {
7
7
  "theclawbay": "dist/index.js"
@@ -30,8 +30,9 @@
30
30
  "claw-bay",
31
31
  "cli",
32
32
  "setup",
33
- "wan",
34
- "api-key"
33
+ "api-key",
34
+ "openclaw",
35
+ "opencode"
35
36
  ],
36
37
  "preferGlobal": true,
37
38
  "dependencies": {