theclawbay 0.3.58 → 0.3.60
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 +4 -0
- package/dist/commands/setup.js +167 -12
- package/dist/commands/usage.d.ts +10 -0
- package/dist/commands/usage.js +135 -0
- package/package.json +5 -1
- package/theclawbay-supported-models.json +9 -0
package/README.md
CHANGED
package/dist/commands/setup.js
CHANGED
|
@@ -49,6 +49,8 @@ const CLAUDE_CODE_EDITOR_DISABLE_LOGIN_PROMPT_SETTING = "claudeCode.disableLogin
|
|
|
49
49
|
const ANTHROPIC_PROVIDER_ID = "anthropic";
|
|
50
50
|
const MANAGED_EDITOR_TERMINAL_ENV_NAMES = [
|
|
51
51
|
ENV_KEY_NAME,
|
|
52
|
+
];
|
|
53
|
+
const MANAGED_CLAUDE_ENV_NAMES = [
|
|
52
54
|
CLAUDE_ENV_API_KEY_NAME,
|
|
53
55
|
CLAUDE_ENV_BASE_URL_NAME,
|
|
54
56
|
CLAUDE_ENV_SIMPLE_MODE_NAME,
|
|
@@ -736,6 +738,18 @@ async function readFileIfExists(filePath) {
|
|
|
736
738
|
throw error;
|
|
737
739
|
}
|
|
738
740
|
}
|
|
741
|
+
async function removeFileIfExists(filePath) {
|
|
742
|
+
try {
|
|
743
|
+
await promises_1.default.unlink(filePath);
|
|
744
|
+
return true;
|
|
745
|
+
}
|
|
746
|
+
catch (error) {
|
|
747
|
+
const err = error;
|
|
748
|
+
if (err.code === "ENOENT")
|
|
749
|
+
return false;
|
|
750
|
+
throw error;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
739
753
|
async function readJsonObjectFile(filePath) {
|
|
740
754
|
const existingRaw = await readFileIfExists(filePath);
|
|
741
755
|
if (existingRaw === null || !existingRaw.trim())
|
|
@@ -1948,14 +1962,9 @@ function terminalIntegratedEnvSettingsKey() {
|
|
|
1948
1962
|
return "terminal.integrated.env.linux";
|
|
1949
1963
|
}
|
|
1950
1964
|
function buildManagedEditorTerminalEnv(params) {
|
|
1951
|
-
|
|
1965
|
+
return {
|
|
1952
1966
|
[ENV_KEY_NAME]: params.apiKey,
|
|
1953
1967
|
};
|
|
1954
|
-
if (params.claudeEnabled) {
|
|
1955
|
-
env[CLAUDE_ENV_API_KEY_NAME] = params.apiKey;
|
|
1956
|
-
env[CLAUDE_ENV_BASE_URL_NAME] = anthropicCompatibleProxyUrl(params.backendUrl);
|
|
1957
|
-
}
|
|
1958
|
-
return env;
|
|
1959
1968
|
}
|
|
1960
1969
|
function buildManagedClaudeEditorEnv(params) {
|
|
1961
1970
|
return {
|
|
@@ -2069,6 +2078,12 @@ async function persistClaudeEditorSettings(params) {
|
|
|
2069
2078
|
nextEnv[name] = value;
|
|
2070
2079
|
changed = true;
|
|
2071
2080
|
}
|
|
2081
|
+
for (const name of MANAGED_CLAUDE_ENV_NAMES) {
|
|
2082
|
+
if (name in desiredEnv || !(name in nextEnv))
|
|
2083
|
+
continue;
|
|
2084
|
+
delete nextEnv[name];
|
|
2085
|
+
changed = true;
|
|
2086
|
+
}
|
|
2072
2087
|
settings[CLAUDE_CODE_EDITOR_ENV_SETTING] = nextEnv;
|
|
2073
2088
|
if (settings[CLAUDE_CODE_EDITOR_DISABLE_LOGIN_PROMPT_SETTING] !== true) {
|
|
2074
2089
|
settings[CLAUDE_CODE_EDITOR_DISABLE_LOGIN_PROMPT_SETTING] = true;
|
|
@@ -2093,6 +2108,126 @@ async function persistClaudeEditorSettings(params) {
|
|
|
2093
2108
|
await writeJsonObjectFile(CLAUDE_EDITOR_SETTINGS_STATE_PATH, Array.from(snapshotByPath.values()), 0o600);
|
|
2094
2109
|
return managedPaths;
|
|
2095
2110
|
}
|
|
2111
|
+
async function cleanupClaudeEditorSettings() {
|
|
2112
|
+
const snapshotRaw = await readFileIfExists(CLAUDE_EDITOR_SETTINGS_STATE_PATH);
|
|
2113
|
+
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
2114
|
+
return [];
|
|
2115
|
+
let entries = [];
|
|
2116
|
+
try {
|
|
2117
|
+
entries = JSON.parse(snapshotRaw);
|
|
2118
|
+
}
|
|
2119
|
+
catch {
|
|
2120
|
+
return [];
|
|
2121
|
+
}
|
|
2122
|
+
const updated = [];
|
|
2123
|
+
for (const entry of entries) {
|
|
2124
|
+
const settings = await readJsonObjectFile(entry.settingsPath);
|
|
2125
|
+
if (!entry.envHadKey) {
|
|
2126
|
+
delete settings[CLAUDE_CODE_EDITOR_ENV_SETTING];
|
|
2127
|
+
}
|
|
2128
|
+
else {
|
|
2129
|
+
settings[CLAUDE_CODE_EDITOR_ENV_SETTING] = entry.envPreviousValue;
|
|
2130
|
+
}
|
|
2131
|
+
if (!entry.disableLoginPromptHadKey) {
|
|
2132
|
+
delete settings[CLAUDE_CODE_EDITOR_DISABLE_LOGIN_PROMPT_SETTING];
|
|
2133
|
+
}
|
|
2134
|
+
else {
|
|
2135
|
+
settings[CLAUDE_CODE_EDITOR_DISABLE_LOGIN_PROMPT_SETTING] = entry.disableLoginPromptPreviousValue;
|
|
2136
|
+
}
|
|
2137
|
+
if (entry.existed || Object.keys(settings).length > 0) {
|
|
2138
|
+
await writeJsonObjectFile(entry.settingsPath, settings);
|
|
2139
|
+
updated.push(entry.settingsPath);
|
|
2140
|
+
continue;
|
|
2141
|
+
}
|
|
2142
|
+
if (await removeFileIfExists(entry.settingsPath)) {
|
|
2143
|
+
updated.push(entry.settingsPath);
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
await removeFileIfExists(CLAUDE_EDITOR_SETTINGS_STATE_PATH);
|
|
2147
|
+
return updated;
|
|
2148
|
+
}
|
|
2149
|
+
async function cleanupClaudeDesktop3pConfig() {
|
|
2150
|
+
const snapshotRaw = await readFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
2151
|
+
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
2152
|
+
return false;
|
|
2153
|
+
let snapshot = null;
|
|
2154
|
+
try {
|
|
2155
|
+
snapshot = JSON.parse(snapshotRaw);
|
|
2156
|
+
}
|
|
2157
|
+
catch {
|
|
2158
|
+
snapshot = null;
|
|
2159
|
+
}
|
|
2160
|
+
if (!snapshot?.configPath) {
|
|
2161
|
+
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
2162
|
+
return false;
|
|
2163
|
+
}
|
|
2164
|
+
if (!snapshot.existed) {
|
|
2165
|
+
const removed = await removeFileIfExists(snapshot.configPath);
|
|
2166
|
+
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
2167
|
+
return removed;
|
|
2168
|
+
}
|
|
2169
|
+
const previousRaw = snapshot.previousRaw ?? "";
|
|
2170
|
+
const existingRaw = await readFileIfExists(snapshot.configPath);
|
|
2171
|
+
if (existingRaw === previousRaw) {
|
|
2172
|
+
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
2173
|
+
return false;
|
|
2174
|
+
}
|
|
2175
|
+
await promises_1.default.mkdir(node_path_1.default.dirname(snapshot.configPath), { recursive: true });
|
|
2176
|
+
await promises_1.default.writeFile(snapshot.configPath, previousRaw, "utf8");
|
|
2177
|
+
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
2178
|
+
return true;
|
|
2179
|
+
}
|
|
2180
|
+
async function cleanupLegacyClaudeEditorTerminalEnvSettings(params) {
|
|
2181
|
+
const snapshotRaw = await readFileIfExists(EDITOR_TERMINAL_ENV_STATE_PATH);
|
|
2182
|
+
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
2183
|
+
return [];
|
|
2184
|
+
let entries = [];
|
|
2185
|
+
try {
|
|
2186
|
+
entries = JSON.parse(snapshotRaw);
|
|
2187
|
+
}
|
|
2188
|
+
catch {
|
|
2189
|
+
return [];
|
|
2190
|
+
}
|
|
2191
|
+
const settingsKey = terminalIntegratedEnvSettingsKey();
|
|
2192
|
+
const managedClaudeEnv = {
|
|
2193
|
+
[CLAUDE_ENV_API_KEY_NAME]: params.apiKey,
|
|
2194
|
+
[CLAUDE_ENV_BASE_URL_NAME]: anthropicCompatibleProxyUrl(params.backendUrl),
|
|
2195
|
+
};
|
|
2196
|
+
const updated = [];
|
|
2197
|
+
for (const entry of entries) {
|
|
2198
|
+
const settings = await readJsonObjectFile(entry.settingsPath);
|
|
2199
|
+
const currentValue = settings[settingsKey];
|
|
2200
|
+
if (typeof currentValue !== "object" || currentValue === null || Array.isArray(currentValue))
|
|
2201
|
+
continue;
|
|
2202
|
+
const currentEnv = { ...currentValue };
|
|
2203
|
+
const previousEnv = typeof entry.previousValue === "object" &&
|
|
2204
|
+
entry.previousValue !== null &&
|
|
2205
|
+
!Array.isArray(entry.previousValue)
|
|
2206
|
+
? { ...entry.previousValue }
|
|
2207
|
+
: {};
|
|
2208
|
+
let changed = false;
|
|
2209
|
+
for (const name of MANAGED_CLAUDE_ENV_NAMES) {
|
|
2210
|
+
const expectedManagedValue = managedClaudeEnv[name];
|
|
2211
|
+
const currentManagedValue = currentEnv[name];
|
|
2212
|
+
const currentMatchesManaged = typeof expectedManagedValue === "string" ? currentManagedValue === expectedManagedValue : false;
|
|
2213
|
+
if (!currentMatchesManaged)
|
|
2214
|
+
continue;
|
|
2215
|
+
if (Object.prototype.hasOwnProperty.call(previousEnv, name)) {
|
|
2216
|
+
currentEnv[name] = previousEnv[name];
|
|
2217
|
+
}
|
|
2218
|
+
else {
|
|
2219
|
+
delete currentEnv[name];
|
|
2220
|
+
}
|
|
2221
|
+
changed = true;
|
|
2222
|
+
}
|
|
2223
|
+
if (!changed)
|
|
2224
|
+
continue;
|
|
2225
|
+
settings[settingsKey] = currentEnv;
|
|
2226
|
+
await writeJsonObjectFile(entry.settingsPath, settings);
|
|
2227
|
+
updated.push(entry.settingsPath);
|
|
2228
|
+
}
|
|
2229
|
+
return updated;
|
|
2230
|
+
}
|
|
2096
2231
|
function expandClaudeDesktopInferenceModels(modelIds) {
|
|
2097
2232
|
const expanded = [];
|
|
2098
2233
|
const add = (value) => {
|
|
@@ -2846,6 +2981,7 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
2846
2981
|
let updatedVsCodeEnvFiles = [];
|
|
2847
2982
|
let updatedEditorTerminalSettings = [];
|
|
2848
2983
|
let updatedClaudeEditorSettings = [];
|
|
2984
|
+
let restoredClaudeDesktop3pConfig = false;
|
|
2849
2985
|
let claudeDesktop3pConfigPathManaged = null;
|
|
2850
2986
|
let sessionMigration = null;
|
|
2851
2987
|
let authSeed = null;
|
|
@@ -2908,18 +3044,34 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
2908
3044
|
backendUrl,
|
|
2909
3045
|
claudeEnabled: claudeEnvEnabled,
|
|
2910
3046
|
});
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
3047
|
+
}
|
|
3048
|
+
if (selectedSetupClients.has("claude")) {
|
|
3049
|
+
updatedClaudeEditorSettings = await persistClaudeEditorSettings({
|
|
3050
|
+
apiKey: authCredential,
|
|
3051
|
+
backendUrl,
|
|
3052
|
+
claudeEnabled: claudeEnvEnabled,
|
|
3053
|
+
});
|
|
3054
|
+
if (claudeEnvEnabled) {
|
|
2917
3055
|
claudeDesktop3pConfigPathManaged = await writeClaudeDesktop3pConfig({
|
|
2918
3056
|
backendUrl,
|
|
2919
3057
|
apiKey: authCredential,
|
|
2920
3058
|
claudeModels: claudeAccess?.enabled ? claudeAccess.models : [],
|
|
2921
3059
|
});
|
|
2922
3060
|
}
|
|
3061
|
+
else {
|
|
3062
|
+
restoredClaudeDesktop3pConfig = await cleanupClaudeDesktop3pConfig();
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
else {
|
|
3066
|
+
updatedEditorTerminalSettings = [
|
|
3067
|
+
...updatedEditorTerminalSettings,
|
|
3068
|
+
...await cleanupLegacyClaudeEditorTerminalEnvSettings({
|
|
3069
|
+
apiKey: authCredential,
|
|
3070
|
+
backendUrl,
|
|
3071
|
+
}),
|
|
3072
|
+
];
|
|
3073
|
+
updatedClaudeEditorSettings = await cleanupClaudeEditorSettings();
|
|
3074
|
+
restoredClaudeDesktop3pConfig = await cleanupClaudeDesktop3pConfig();
|
|
2923
3075
|
}
|
|
2924
3076
|
if (selectedSetupClients.has("codex")) {
|
|
2925
3077
|
progress.update("Configuring Codex");
|
|
@@ -3137,6 +3289,9 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
3137
3289
|
if (updatedClaudeEditorSettings.length > 0) {
|
|
3138
3290
|
this.log(`- Claude editor settings updated: ${updatedClaudeEditorSettings.join(", ")}`);
|
|
3139
3291
|
}
|
|
3292
|
+
if (restoredClaudeDesktop3pConfig) {
|
|
3293
|
+
this.log("- Claude Desktop 3P config: restored the pre-The Claw Bay config.");
|
|
3294
|
+
}
|
|
3140
3295
|
if (selectedSetupClients.has("codex")) {
|
|
3141
3296
|
this.log(`- Codex: configured (${codexConfigPath})`);
|
|
3142
3297
|
if (resolved)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseCommand } from "../lib/base-command";
|
|
2
|
+
export default class UsageCommand extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static flags: {
|
|
5
|
+
backend: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
6
|
+
"api-key": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../lib/base-command");
|
|
5
|
+
const api_key_1 = require("../lib/managed/api-key");
|
|
6
|
+
const config_1 = require("../lib/managed/config");
|
|
7
|
+
const errors_1 = require("../lib/managed/errors");
|
|
8
|
+
const DEFAULT_BACKEND_URL = "https://theclawbay.com";
|
|
9
|
+
function formatPercent(value) {
|
|
10
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
11
|
+
return "n/a";
|
|
12
|
+
return `${value.toFixed(value >= 10 ? 1 : 2).replace(/\.0+$/u, "").replace(/(\.\d*?)0+$/u, "$1")}%`;
|
|
13
|
+
}
|
|
14
|
+
function formatUsd(value) {
|
|
15
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
16
|
+
return "n/a";
|
|
17
|
+
return new Intl.NumberFormat("en-US", {
|
|
18
|
+
style: "currency",
|
|
19
|
+
currency: "USD",
|
|
20
|
+
minimumFractionDigits: 2,
|
|
21
|
+
maximumFractionDigits: 2,
|
|
22
|
+
}).format(value);
|
|
23
|
+
}
|
|
24
|
+
function formatTimestamp(value) {
|
|
25
|
+
if (!value)
|
|
26
|
+
return "n/a";
|
|
27
|
+
const parsed = Date.parse(value);
|
|
28
|
+
if (!Number.isFinite(parsed))
|
|
29
|
+
return value;
|
|
30
|
+
return new Date(parsed).toISOString();
|
|
31
|
+
}
|
|
32
|
+
function formatDuration(seconds) {
|
|
33
|
+
const totalSeconds = Math.max(0, Math.round(seconds));
|
|
34
|
+
const days = Math.floor(totalSeconds / 86400);
|
|
35
|
+
const hours = Math.floor((totalSeconds % 86400) / 3600);
|
|
36
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
37
|
+
const remainingSeconds = totalSeconds % 60;
|
|
38
|
+
const parts = [];
|
|
39
|
+
if (days > 0)
|
|
40
|
+
parts.push(`${days}d`);
|
|
41
|
+
if (hours > 0)
|
|
42
|
+
parts.push(`${hours}h`);
|
|
43
|
+
if (minutes > 0)
|
|
44
|
+
parts.push(`${minutes}m`);
|
|
45
|
+
if (parts.length === 0 || (parts.length < 2 && remainingSeconds > 0)) {
|
|
46
|
+
parts.push(`${remainingSeconds}s`);
|
|
47
|
+
}
|
|
48
|
+
return parts.slice(0, 2).join(" ");
|
|
49
|
+
}
|
|
50
|
+
function printWindow(log, label, window, showCosts) {
|
|
51
|
+
log(`${label}`);
|
|
52
|
+
log(` Used: ${formatPercent(window.progressPercentUsed ?? window.percentUsed)}`);
|
|
53
|
+
log(` Remaining: ${formatPercent(window.percentRemaining)}`);
|
|
54
|
+
log(` Requests: ${window.requestCount} total, ${window.successCount} succeeded, ${window.failedCount} failed`);
|
|
55
|
+
log(` Runtime: ${window.runtimeSecondsUsed.toFixed(1)}s`);
|
|
56
|
+
log(` Resets: ${formatDuration(window.secondsUntilReset)} (${formatTimestamp(window.windowEnd)})`);
|
|
57
|
+
if (showCosts) {
|
|
58
|
+
log(` Cost: ${formatUsd(window.estimatedCostUsdUsed)} used / ${formatUsd(window.costUsdLimit)} limit / ${formatUsd(window.costUsdRemaining)} remaining`);
|
|
59
|
+
}
|
|
60
|
+
log(` Last request: ${formatTimestamp(window.lastRequestAt)}`);
|
|
61
|
+
if (window.limitReached) {
|
|
62
|
+
log(" Status: limit reached");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class UsageCommand extends base_command_1.BaseCommand {
|
|
66
|
+
async run() {
|
|
67
|
+
await this.runSafe(async () => {
|
|
68
|
+
const { flags } = await this.parse(UsageCommand);
|
|
69
|
+
let managed = null;
|
|
70
|
+
try {
|
|
71
|
+
managed = await (0, config_1.readManagedConfig)();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (!(error instanceof errors_1.ManagedConfigMissingError))
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
const credential = (flags["api-key"] ?? managed?.credential ?? "").trim();
|
|
78
|
+
if (!credential) {
|
|
79
|
+
this.error('No saved credential found. Run "theclawbay setup" or pass --api-key.');
|
|
80
|
+
}
|
|
81
|
+
const backendRaw = flags.backend ??
|
|
82
|
+
(0, api_key_1.tryInferBackendUrlFromApiKey)(credential) ??
|
|
83
|
+
managed?.backendUrl ??
|
|
84
|
+
DEFAULT_BACKEND_URL;
|
|
85
|
+
const backendUrl = backendRaw.replace(/\/+$/u, "");
|
|
86
|
+
const response = await fetch(`${backendUrl}/api/codex-auth/v1/quota`, {
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${credential}`,
|
|
89
|
+
Accept: "application/json",
|
|
90
|
+
},
|
|
91
|
+
signal: AbortSignal.timeout(20000),
|
|
92
|
+
});
|
|
93
|
+
const body = (await response.json().catch(() => ({})));
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
this.error(body.error || `Failed to load usage (HTTP ${response.status})`);
|
|
96
|
+
}
|
|
97
|
+
if (flags.json) {
|
|
98
|
+
this.log(JSON.stringify(body, null, 2));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const showCosts = body.usageLimitPresentation !== "percent_only";
|
|
102
|
+
this.log("The Claw Bay usage");
|
|
103
|
+
this.log(`Observed: ${formatTimestamp(body.observedAt)}`);
|
|
104
|
+
this.log(`Auth scope: ${body.pooled ? "shared pooled usage" : body.mode}`);
|
|
105
|
+
if (body.mode === "direct" && typeof body.planMultiplier === "number" && Number.isFinite(body.planMultiplier)) {
|
|
106
|
+
this.log(`Plan multiplier: ${body.planMultiplier}x`);
|
|
107
|
+
}
|
|
108
|
+
if (body.anyLimitReached) {
|
|
109
|
+
this.log("Status: at least one usage window has been reached");
|
|
110
|
+
}
|
|
111
|
+
this.log("");
|
|
112
|
+
printWindow((message) => this.log(message), "5-hour window", body.usage.fiveHour, showCosts);
|
|
113
|
+
this.log("");
|
|
114
|
+
printWindow((message) => this.log(message), "Weekly window", body.usage.weekly, showCosts);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
UsageCommand.description = "Show your current The Claw Bay pooled 5-hour and weekly usage";
|
|
119
|
+
UsageCommand.flags = {
|
|
120
|
+
backend: core_1.Flags.string({
|
|
121
|
+
required: false,
|
|
122
|
+
description: "Backend base URL override (default: saved managed config or https://theclawbay.com)",
|
|
123
|
+
}),
|
|
124
|
+
"api-key": core_1.Flags.string({
|
|
125
|
+
required: false,
|
|
126
|
+
aliases: ["apiKey"],
|
|
127
|
+
description: "API key or linked device-session token override",
|
|
128
|
+
}),
|
|
129
|
+
json: core_1.Flags.boolean({
|
|
130
|
+
required: false,
|
|
131
|
+
default: false,
|
|
132
|
+
description: "Print the raw quota response as JSON",
|
|
133
|
+
}),
|
|
134
|
+
};
|
|
135
|
+
exports.default = UsageCommand;
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "theclawbay",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.60",
|
|
4
4
|
"description": "CLI for connecting Codex, Continue, Cline, GSD, OpenClaw, OpenCode, Kilo, Roo Code, Aider, experimental Trae, and experimental Zo to The Claw Bay.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/RCRTCBHAL900/TheClawBay"
|
|
9
|
+
},
|
|
6
10
|
"bin": {
|
|
7
11
|
"theclawbay": "dist/index.js"
|
|
8
12
|
},
|
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
"cachedInputPer1M": 0.125,
|
|
18
18
|
"outputPer1M": 10.0
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
"id": "gpt-image-1.5",
|
|
22
|
+
"label": "GPT Image 1.5",
|
|
23
|
+
"note": "Native image generation model for direct image outputs.",
|
|
24
|
+
"tone": "coral",
|
|
25
|
+
"inputPer1M": 8.0,
|
|
26
|
+
"cachedInputPer1M": 2.0,
|
|
27
|
+
"outputPer1M": 32.0
|
|
28
|
+
},
|
|
20
29
|
{
|
|
21
30
|
"id": "gpt-5.3-codex",
|
|
22
31
|
"label": "GPT-5.3 Codex",
|