theclawbay 0.3.59 → 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 +162 -13
- 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,7 +2078,7 @@ async function persistClaudeEditorSettings(params) {
|
|
|
2069
2078
|
nextEnv[name] = value;
|
|
2070
2079
|
changed = true;
|
|
2071
2080
|
}
|
|
2072
|
-
for (const name of
|
|
2081
|
+
for (const name of MANAGED_CLAUDE_ENV_NAMES) {
|
|
2073
2082
|
if (name in desiredEnv || !(name in nextEnv))
|
|
2074
2083
|
continue;
|
|
2075
2084
|
delete nextEnv[name];
|
|
@@ -2099,6 +2108,126 @@ async function persistClaudeEditorSettings(params) {
|
|
|
2099
2108
|
await writeJsonObjectFile(CLAUDE_EDITOR_SETTINGS_STATE_PATH, Array.from(snapshotByPath.values()), 0o600);
|
|
2100
2109
|
return managedPaths;
|
|
2101
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
|
+
}
|
|
2102
2231
|
function expandClaudeDesktopInferenceModels(modelIds) {
|
|
2103
2232
|
const expanded = [];
|
|
2104
2233
|
const add = (value) => {
|
|
@@ -2852,6 +2981,7 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
2852
2981
|
let updatedVsCodeEnvFiles = [];
|
|
2853
2982
|
let updatedEditorTerminalSettings = [];
|
|
2854
2983
|
let updatedClaudeEditorSettings = [];
|
|
2984
|
+
let restoredClaudeDesktop3pConfig = false;
|
|
2855
2985
|
let claudeDesktop3pConfigPathManaged = null;
|
|
2856
2986
|
let sessionMigration = null;
|
|
2857
2987
|
let authSeed = null;
|
|
@@ -2914,18 +3044,34 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
2914
3044
|
backendUrl,
|
|
2915
3045
|
claudeEnabled: claudeEnvEnabled,
|
|
2916
3046
|
});
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
3047
|
+
}
|
|
3048
|
+
if (selectedSetupClients.has("claude")) {
|
|
3049
|
+
updatedClaudeEditorSettings = await persistClaudeEditorSettings({
|
|
3050
|
+
apiKey: authCredential,
|
|
3051
|
+
backendUrl,
|
|
3052
|
+
claudeEnabled: claudeEnvEnabled,
|
|
3053
|
+
});
|
|
3054
|
+
if (claudeEnvEnabled) {
|
|
2923
3055
|
claudeDesktop3pConfigPathManaged = await writeClaudeDesktop3pConfig({
|
|
2924
3056
|
backendUrl,
|
|
2925
3057
|
apiKey: authCredential,
|
|
2926
3058
|
claudeModels: claudeAccess?.enabled ? claudeAccess.models : [],
|
|
2927
3059
|
});
|
|
2928
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();
|
|
2929
3075
|
}
|
|
2930
3076
|
if (selectedSetupClients.has("codex")) {
|
|
2931
3077
|
progress.update("Configuring Codex");
|
|
@@ -3143,6 +3289,9 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
3143
3289
|
if (updatedClaudeEditorSettings.length > 0) {
|
|
3144
3290
|
this.log(`- Claude editor settings updated: ${updatedClaudeEditorSettings.join(", ")}`);
|
|
3145
3291
|
}
|
|
3292
|
+
if (restoredClaudeDesktop3pConfig) {
|
|
3293
|
+
this.log("- Claude Desktop 3P config: restored the pre-The Claw Bay config.");
|
|
3294
|
+
}
|
|
3146
3295
|
if (selectedSetupClients.has("codex")) {
|
|
3147
3296
|
this.log(`- Codex: configured (${codexConfigPath})`);
|
|
3148
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",
|