very-happy-cli 0.2.75 → 0.2.76
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/dist/{AcpBackend-5CPQMP3H.mjs → AcpBackend-KEFEf0fa.mjs} +5 -2
- package/dist/{AcpBackend-B0qCm-bY.cjs → AcpBackend-a8B0Y7EF.cjs} +5 -2
- package/dist/{AcpSessionManager-BTmJyKDO.mjs → AcpSessionManager-DpiEroK5.mjs} +1 -1
- package/dist/{AcpSessionManager-B4M0y5fI.cjs → AcpSessionManager-rkoOuyxF.cjs} +1 -1
- package/dist/{config-DBIfKaNJ.cjs → config-Bk2_O4iy.cjs} +2 -2
- package/dist/{config-DbY2R-H7.mjs → config-gCpPGROw.mjs} +2 -2
- package/dist/{index-edEH95Mf.cjs → index-Baq7aDcp.cjs} +19 -15
- package/dist/{index-CJaqyq4z.mjs → index-BpR0Noyc.mjs} +8 -5
- package/dist/{index-Cq30c63l.mjs → index-DBO5ydFO.mjs} +16 -12
- package/dist/{index-CqxywXyf.cjs → index-KFtRhinT.cjs} +7 -4
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-8TUdSFCY.mjs → installTerminalHooks-5MMeWip7.mjs} +2 -2
- package/dist/{installTerminalHooks-BvQbDFcE.cjs → installTerminalHooks-CPbpttk4.cjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +5 -1
- package/dist/lib.d.mts +5 -1
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-D12X7XKG.cjs → mcp-C0ai1fwz.cjs} +2 -2
- package/dist/{mcp-B4UxtBKQ.mjs → mcp-DYaTASOA.mjs} +2 -2
- package/dist/{runGemini-LIck5ard.cjs → runGemini-BOhhFluL.cjs} +5 -4
- package/dist/{runGemini-BD8OGMQr.mjs → runGemini-DypVM7XW.mjs} +5 -4
- package/dist/{runOpenClaw-ENAgQy1E.mjs → runOpenClaw-BLJwhL9y.mjs} +15 -3
- package/dist/{runOpenClaw-B5XNV1zZ.cjs → runOpenClaw-CzYqRkGb.cjs} +15 -3
- package/dist/{send-o4xljyoV.cjs → send-B4dnhYKC.cjs} +2 -2
- package/dist/{send-BVbiwtrQ.mjs → send-BG-4q_Nb.mjs} +2 -2
- package/dist/{spawn-BmqqHUYI.mjs → spawn-BEwPBgbi.mjs} +2 -2
- package/dist/{spawn-DTA6f9TE.cjs → spawn-BXj4rWNL.cjs} +2 -2
- package/dist/{types-Dj9JEGDh.mjs → types-kLTNjWVl.mjs} +96 -17
- package/dist/{types-DEre2zxO.cjs → types-xqPsUU1d.cjs} +97 -18
- package/package.json +7 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-
|
|
4
|
+
import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-kLTNjWVl.mjs';
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIMEOUTS = {
|
|
7
7
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -1094,7 +1094,10 @@ class AcpBackend {
|
|
|
1094
1094
|
sessionId: this.acpSessionId,
|
|
1095
1095
|
blockCount: promptRequest.prompt.length
|
|
1096
1096
|
});
|
|
1097
|
-
await this.connection.prompt(promptRequest);
|
|
1097
|
+
const response = await this.connection.prompt(promptRequest);
|
|
1098
|
+
if (response.usage) {
|
|
1099
|
+
this.emit({ type: "token-count", ...response.usage });
|
|
1100
|
+
}
|
|
1098
1101
|
logger.debug("[AcpBackend] Prompt request sent to ACP connection");
|
|
1099
1102
|
} catch (error) {
|
|
1100
1103
|
logger.debug("[AcpBackend] Error sending prompt:", errorLogMetadata(error));
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var node_child_process = require('node:child_process');
|
|
4
4
|
var sdk = require('@agentclientprotocol/sdk');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var persistence = require('./types-
|
|
6
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TIMEOUTS = {
|
|
9
9
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -1096,7 +1096,10 @@ class AcpBackend {
|
|
|
1096
1096
|
sessionId: this.acpSessionId,
|
|
1097
1097
|
blockCount: promptRequest.prompt.length
|
|
1098
1098
|
});
|
|
1099
|
-
await this.connection.prompt(promptRequest);
|
|
1099
|
+
const response = await this.connection.prompt(promptRequest);
|
|
1100
|
+
if (response.usage) {
|
|
1101
|
+
this.emit({ type: "token-count", ...response.usage });
|
|
1102
|
+
}
|
|
1100
1103
|
persistence.logger.debug("[AcpBackend] Prompt request sent to ACP connection");
|
|
1101
1104
|
} catch (error) {
|
|
1102
1105
|
persistence.logger.debug("[AcpBackend] Error sending prompt:", persistence.errorLogMetadata(error));
|
|
@@ -4,8 +4,8 @@ var fs = require('fs');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var os = require('os');
|
|
6
6
|
var child_process = require('child_process');
|
|
7
|
-
var persistence = require('./types-
|
|
8
|
-
var index = require('./index-
|
|
7
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
8
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('chalk');
|
|
11
11
|
require('node:util');
|
|
@@ -2,8 +2,8 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
|
-
import { l as logger } from './types-
|
|
6
|
-
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-
|
|
5
|
+
import { l as logger } from './types-kLTNjWVl.mjs';
|
|
6
|
+
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-DBO5ydFO.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'chalk';
|
|
9
9
|
import 'node:util';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var persistence = require('./types-
|
|
6
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
7
7
|
var spawn = require('cross-spawn');
|
|
8
8
|
var path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
@@ -8274,7 +8274,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
8274
8274
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
8275
8275
|
function resolveClaudeBinary() {
|
|
8276
8276
|
try {
|
|
8277
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
8277
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Baq7aDcp.cjs', document.baseURI).href)));
|
|
8278
8278
|
const utilsPath = path.resolve(path.join(persistence.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
8279
8279
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
8280
8280
|
const path$1 = getClaudeCliPath();
|
|
@@ -10391,9 +10391,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
10391
10391
|
};
|
|
10392
10392
|
}
|
|
10393
10393
|
|
|
10394
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
10394
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Baq7aDcp.cjs', document.baseURI).href)));
|
|
10395
10395
|
const __dirname$1 = path.dirname(__filename$1);
|
|
10396
|
-
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
10396
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-Baq7aDcp.cjs', document.baseURI).href)));
|
|
10397
10397
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
10398
10398
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
10399
10399
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -11431,6 +11431,7 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
11431
11431
|
},
|
|
11432
11432
|
sendAgentMessage: () => {
|
|
11433
11433
|
},
|
|
11434
|
+
sendAgentUsageSnapshot: () => false,
|
|
11434
11435
|
sendClaudeSessionMessage: () => {
|
|
11435
11436
|
},
|
|
11436
11437
|
keepAlive: () => {
|
|
@@ -12548,6 +12549,9 @@ async function runCodex(opts) {
|
|
|
12548
12549
|
}
|
|
12549
12550
|
});
|
|
12550
12551
|
client.setEventHandler((msg) => {
|
|
12552
|
+
if (msg.type === "token_count") {
|
|
12553
|
+
session.sendAgentUsageSnapshot("codex", msg);
|
|
12554
|
+
}
|
|
12551
12555
|
persistence.logger.debug("[Codex] Event metadata", codexEventLogMetadata(msg));
|
|
12552
12556
|
if (msg.type === "agent_message") {
|
|
12553
12557
|
messageBuffer.addMessage(msg.message, "assistant");
|
|
@@ -13001,7 +13005,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13001
13005
|
process.exit(0);
|
|
13002
13006
|
} else if (subcommand === "install-terminal-hooks") {
|
|
13003
13007
|
try {
|
|
13004
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
13008
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-CPbpttk4.cjs'); });
|
|
13005
13009
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
13006
13010
|
if (command.action === "help") {
|
|
13007
13011
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -13018,7 +13022,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13018
13022
|
}
|
|
13019
13023
|
} else if (subcommand === "spawn") {
|
|
13020
13024
|
try {
|
|
13021
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
13025
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-BXj4rWNL.cjs'); });
|
|
13022
13026
|
await handleSpawnCommand(args.slice(1));
|
|
13023
13027
|
} catch (error) {
|
|
13024
13028
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13030,7 +13034,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13030
13034
|
return;
|
|
13031
13035
|
} else if (subcommand === "send") {
|
|
13032
13036
|
try {
|
|
13033
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
13037
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-B4dnhYKC.cjs'); });
|
|
13034
13038
|
await handleSendCommand(args.slice(1));
|
|
13035
13039
|
} catch (error) {
|
|
13036
13040
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13136,9 +13140,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13136
13140
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
13137
13141
|
const projectId = args[3];
|
|
13138
13142
|
try {
|
|
13139
|
-
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
13140
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-
|
|
13141
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-
|
|
13143
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-Bk2_O4iy.cjs'); });
|
|
13144
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-xqPsUU1d.cjs'); }).then(function (n) { return n.persistence; });
|
|
13145
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-xqPsUU1d.cjs'); }).then(function (n) { return n.api; });
|
|
13142
13146
|
let userEmail = void 0;
|
|
13143
13147
|
try {
|
|
13144
13148
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -13169,7 +13173,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13169
13173
|
}
|
|
13170
13174
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
13171
13175
|
try {
|
|
13172
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
13176
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-Bk2_O4iy.cjs'); });
|
|
13173
13177
|
const config = readGeminiLocalConfig();
|
|
13174
13178
|
if (config.googleCloudProject) {
|
|
13175
13179
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -13209,7 +13213,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13209
13213
|
process.exit(0);
|
|
13210
13214
|
}
|
|
13211
13215
|
try {
|
|
13212
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
13216
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-BOhhFluL.cjs'); });
|
|
13213
13217
|
let startedBy = void 0;
|
|
13214
13218
|
for (let i = 1; i < args.length; i++) {
|
|
13215
13219
|
if (args[i] === "--started-by") {
|
|
@@ -13231,7 +13235,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13231
13235
|
return;
|
|
13232
13236
|
} else if (subcommand === "acp") {
|
|
13233
13237
|
try {
|
|
13234
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
13238
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-KFtRhinT.cjs'); });
|
|
13235
13239
|
let startedBy = void 0;
|
|
13236
13240
|
let verbose = false;
|
|
13237
13241
|
const acpArgs = [];
|
|
@@ -13271,7 +13275,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13271
13275
|
return;
|
|
13272
13276
|
} else if (subcommand === "openclaw") {
|
|
13273
13277
|
try {
|
|
13274
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
13278
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-CzYqRkGb.cjs'); });
|
|
13275
13279
|
let startedBy = void 0;
|
|
13276
13280
|
let verbose = false;
|
|
13277
13281
|
let gatewayUrl;
|
|
@@ -13322,7 +13326,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13322
13326
|
return;
|
|
13323
13327
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
13324
13328
|
try {
|
|
13325
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
13329
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-C0ai1fwz.cjs'); });
|
|
13326
13330
|
await handleMcpCommand();
|
|
13327
13331
|
} catch (error) {
|
|
13328
13332
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-
|
|
2
|
-
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-
|
|
3
|
-
import { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-KEFEf0fa.mjs';
|
|
2
|
+
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-KEFEf0fa.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-kLTNjWVl.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-DpiEroK5.mjs';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, f as startHappyServer, r as registerKillSessionHandler, B as BasePermissionHandler } from './index-
|
|
7
|
+
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, f as startHappyServer, r as registerKillSessionHandler, B as BasePermissionHandler } from './index-DBO5ydFO.mjs';
|
|
8
8
|
import 'node:child_process';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'axios';
|
|
@@ -912,6 +912,9 @@ async function runAcp(opts) {
|
|
|
912
912
|
if (frontendMessage) {
|
|
913
913
|
logAcp(frontendMessage.kind, frontendMessage.text);
|
|
914
914
|
}
|
|
915
|
+
if (msg.type === "token-count") {
|
|
916
|
+
session.sendAgentUsageSnapshot(resolveSessionFlavor(opts.agentName), msg);
|
|
917
|
+
}
|
|
915
918
|
sendEnvelopes(sessionManager.mapMessage(msg));
|
|
916
919
|
};
|
|
917
920
|
backend.onMessage(onBackendMessage);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import { n as readDaemonState, l as logger, c as configuration, o as clearDaemonState, q as getProjectPath, p as projectPath, s as initializeSandbox, t as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, u as AsyncLock, f as packageJson, i as readSettings, v as readCredentials, x as credentialRelayProblem, y as deriveLocalCliUpdateSummary, j as encodeBase64, z as updateSettings, B as encodeBase64Url, C as decodeBase64, D as writeCredentialsLegacy, E as writeCredentialsDataKey, F as readCredentialsForConfiguredRelay, G as encrypt, r as readPersistedSessions, H as getLocalHappyAgentCredentialPath, J as readLocalHappyAgentCredentials, K as decryptWithDataKey, L as decryptLegacy, M as extractCompleteLines, N as decideBackfill, O as parseTerminalHookPayload, P as decideMirrorBinding, Q as persistSession, S as MIRROR_BACKFILL_LINES_DEFAULT, T as mirrorLineKey, U as mirrorLocalId, V as detectResumeSupport, W as detectCLIAvailability, X as acquireDaemonLock, Y as summarizeSpawnSessionForLog, Z as deletePersistedSessions, _ as decrypt, $ as writeDaemonState, A as ApiClient, a0 as fetchCliUpdateState, a1 as resolveCliUpdateCheckInterval, a2 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a3 as releaseDaemonLock, a4 as isValidSessionId, a5 as listVhTerminals, a6 as isValidTerminalId, a7 as readVhTerminal, a8 as sendToVhTerminal, h as connectionState, a9 as startOfflineReconnection, aa as clearCredentials, ab as clearMachineId, k as ensurePrivateDirectorySync, w as writePrivateFileSync, ac as SandboxConfigSchema, b as createEnvelope, ad as CodexAppServerClient, ae as getLatestDaemonLog } from './types-
|
|
4
|
+
import { n as readDaemonState, l as logger, c as configuration, o as clearDaemonState, q as getProjectPath, p as projectPath, s as initializeSandbox, t as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, u as AsyncLock, f as packageJson, i as readSettings, v as readCredentials, x as credentialRelayProblem, y as deriveLocalCliUpdateSummary, j as encodeBase64, z as updateSettings, B as encodeBase64Url, C as decodeBase64, D as writeCredentialsLegacy, E as writeCredentialsDataKey, F as readCredentialsForConfiguredRelay, G as encrypt, r as readPersistedSessions, H as getLocalHappyAgentCredentialPath, J as readLocalHappyAgentCredentials, K as decryptWithDataKey, L as decryptLegacy, M as extractCompleteLines, N as decideBackfill, O as parseTerminalHookPayload, P as decideMirrorBinding, Q as persistSession, S as MIRROR_BACKFILL_LINES_DEFAULT, T as mirrorLineKey, U as mirrorLocalId, V as detectResumeSupport, W as detectCLIAvailability, X as acquireDaemonLock, Y as summarizeSpawnSessionForLog, Z as deletePersistedSessions, _ as decrypt, $ as writeDaemonState, A as ApiClient, a0 as fetchCliUpdateState, a1 as resolveCliUpdateCheckInterval, a2 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a3 as releaseDaemonLock, a4 as isValidSessionId, a5 as listVhTerminals, a6 as isValidTerminalId, a7 as readVhTerminal, a8 as sendToVhTerminal, h as connectionState, a9 as startOfflineReconnection, aa as clearCredentials, ab as clearMachineId, k as ensurePrivateDirectorySync, w as writePrivateFileSync, ac as SandboxConfigSchema, b as createEnvelope, ad as CodexAppServerClient, ae as getLatestDaemonLog } from './types-kLTNjWVl.mjs';
|
|
5
5
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
6
6
|
import path, { join, resolve, isAbsolute, normalize, sep, dirname } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -11409,6 +11409,7 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
11409
11409
|
},
|
|
11410
11410
|
sendAgentMessage: () => {
|
|
11411
11411
|
},
|
|
11412
|
+
sendAgentUsageSnapshot: () => false,
|
|
11412
11413
|
sendClaudeSessionMessage: () => {
|
|
11413
11414
|
},
|
|
11414
11415
|
keepAlive: () => {
|
|
@@ -12526,6 +12527,9 @@ async function runCodex(opts) {
|
|
|
12526
12527
|
}
|
|
12527
12528
|
});
|
|
12528
12529
|
client.setEventHandler((msg) => {
|
|
12530
|
+
if (msg.type === "token_count") {
|
|
12531
|
+
session.sendAgentUsageSnapshot("codex", msg);
|
|
12532
|
+
}
|
|
12529
12533
|
logger.debug("[Codex] Event metadata", codexEventLogMetadata(msg));
|
|
12530
12534
|
if (msg.type === "agent_message") {
|
|
12531
12535
|
messageBuffer.addMessage(msg.message, "assistant");
|
|
@@ -12979,7 +12983,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
12979
12983
|
process.exit(0);
|
|
12980
12984
|
} else if (subcommand === "install-terminal-hooks") {
|
|
12981
12985
|
try {
|
|
12982
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
12986
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-5MMeWip7.mjs');
|
|
12983
12987
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
12984
12988
|
if (command.action === "help") {
|
|
12985
12989
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -12996,7 +13000,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
12996
13000
|
}
|
|
12997
13001
|
} else if (subcommand === "spawn") {
|
|
12998
13002
|
try {
|
|
12999
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
13003
|
+
const { handleSpawnCommand } = await import('./spawn-BEwPBgbi.mjs');
|
|
13000
13004
|
await handleSpawnCommand(args.slice(1));
|
|
13001
13005
|
} catch (error) {
|
|
13002
13006
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13008,7 +13012,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13008
13012
|
return;
|
|
13009
13013
|
} else if (subcommand === "send") {
|
|
13010
13014
|
try {
|
|
13011
|
-
const { handleSendCommand } = await import('./send-
|
|
13015
|
+
const { handleSendCommand } = await import('./send-BG-4q_Nb.mjs');
|
|
13012
13016
|
await handleSendCommand(args.slice(1));
|
|
13013
13017
|
} catch (error) {
|
|
13014
13018
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13114,9 +13118,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13114
13118
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
13115
13119
|
const projectId = args[3];
|
|
13116
13120
|
try {
|
|
13117
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
13118
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-
|
|
13119
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
13121
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-gCpPGROw.mjs');
|
|
13122
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-kLTNjWVl.mjs').then(function (n) { return n.af; });
|
|
13123
|
+
const { ApiClient: ApiClient2 } = await import('./types-kLTNjWVl.mjs').then(function (n) { return n.ag; });
|
|
13120
13124
|
let userEmail = void 0;
|
|
13121
13125
|
try {
|
|
13122
13126
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -13147,7 +13151,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13147
13151
|
}
|
|
13148
13152
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
13149
13153
|
try {
|
|
13150
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
13154
|
+
const { readGeminiLocalConfig } = await import('./config-gCpPGROw.mjs');
|
|
13151
13155
|
const config = readGeminiLocalConfig();
|
|
13152
13156
|
if (config.googleCloudProject) {
|
|
13153
13157
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -13187,7 +13191,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13187
13191
|
process.exit(0);
|
|
13188
13192
|
}
|
|
13189
13193
|
try {
|
|
13190
|
-
const { runGemini } = await import('./runGemini-
|
|
13194
|
+
const { runGemini } = await import('./runGemini-DypVM7XW.mjs');
|
|
13191
13195
|
let startedBy = void 0;
|
|
13192
13196
|
for (let i = 1; i < args.length; i++) {
|
|
13193
13197
|
if (args[i] === "--started-by") {
|
|
@@ -13209,7 +13213,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13209
13213
|
return;
|
|
13210
13214
|
} else if (subcommand === "acp") {
|
|
13211
13215
|
try {
|
|
13212
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
13216
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-BpR0Noyc.mjs');
|
|
13213
13217
|
let startedBy = void 0;
|
|
13214
13218
|
let verbose = false;
|
|
13215
13219
|
const acpArgs = [];
|
|
@@ -13249,7 +13253,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13249
13253
|
return;
|
|
13250
13254
|
} else if (subcommand === "openclaw") {
|
|
13251
13255
|
try {
|
|
13252
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
13256
|
+
const { runOpenClaw } = await import('./runOpenClaw-BLJwhL9y.mjs');
|
|
13253
13257
|
let startedBy = void 0;
|
|
13254
13258
|
let verbose = false;
|
|
13255
13259
|
let gatewayUrl;
|
|
@@ -13300,7 +13304,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13300
13304
|
return;
|
|
13301
13305
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
13302
13306
|
try {
|
|
13303
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
13307
|
+
const { handleMcpCommand } = await import('./mcp-DYaTASOA.mjs');
|
|
13304
13308
|
await handleMcpCommand();
|
|
13305
13309
|
} catch (error) {
|
|
13306
13310
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./types-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
3
|
+
var AcpBackend = require('./AcpBackend-a8B0Y7EF.cjs');
|
|
4
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-rkoOuyxF.cjs');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var index = require('./index-
|
|
8
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
9
9
|
require('node:child_process');
|
|
10
10
|
require('@agentclientprotocol/sdk');
|
|
11
11
|
require('axios');
|
|
@@ -913,6 +913,9 @@ async function runAcp(opts) {
|
|
|
913
913
|
if (frontendMessage) {
|
|
914
914
|
logAcp(frontendMessage.kind, frontendMessage.text);
|
|
915
915
|
}
|
|
916
|
+
if (msg.type === "token-count") {
|
|
917
|
+
session.sendAgentUsageSnapshot(resolveSessionFlavor(opts.agentName), msg);
|
|
918
|
+
}
|
|
916
919
|
sendEnvelopes(sessionManager.mapMessage(msg));
|
|
917
920
|
};
|
|
918
921
|
backend.onMessage(onBackendMessage);
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { join, resolve } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
|
-
import { p as projectPath } from './types-
|
|
7
|
-
import { t as tmuxSupportsSessionEnv } from './index-
|
|
6
|
+
import { p as projectPath } from './types-kLTNjWVl.mjs';
|
|
7
|
+
import { t as tmuxSupportsSessionEnv } from './index-DBO5ydFO.mjs';
|
|
8
8
|
import 'axios';
|
|
9
9
|
import 'node:util';
|
|
10
10
|
import 'node:fs/promises';
|
|
@@ -5,8 +5,8 @@ var path = require('node:path');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var chalk = require('chalk');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
9
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
10
10
|
require('axios');
|
|
11
11
|
require('node:util');
|
|
12
12
|
require('node:fs/promises');
|
package/dist/lib.cjs
CHANGED
package/dist/lib.d.cts
CHANGED
|
@@ -652,6 +652,8 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
652
652
|
private ignoreArchiveSignal;
|
|
653
653
|
private skipInitialMessages;
|
|
654
654
|
private claudeSessionProtocolState;
|
|
655
|
+
private readonly seenClaudeUsageEvents;
|
|
656
|
+
private claudeUsageTotals;
|
|
655
657
|
private lastSeq;
|
|
656
658
|
private pendingOutbox;
|
|
657
659
|
private readonly sendSync;
|
|
@@ -787,7 +789,9 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
787
789
|
/**
|
|
788
790
|
* Send usage data to the server
|
|
789
791
|
*/
|
|
790
|
-
sendUsageData(usage: Usage, model?: string): void;
|
|
792
|
+
sendUsageData(usage: Usage, model?: string, eventId?: string): void;
|
|
793
|
+
/** Save a provider's cumulative session snapshot under one upsert key. */
|
|
794
|
+
sendAgentUsageSnapshot(agent: string, rawUsage: unknown): boolean;
|
|
791
795
|
/**
|
|
792
796
|
* Returns the latest session metadata known to the client.
|
|
793
797
|
*/
|
package/dist/lib.d.mts
CHANGED
|
@@ -652,6 +652,8 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
652
652
|
private ignoreArchiveSignal;
|
|
653
653
|
private skipInitialMessages;
|
|
654
654
|
private claudeSessionProtocolState;
|
|
655
|
+
private readonly seenClaudeUsageEvents;
|
|
656
|
+
private claudeUsageTotals;
|
|
655
657
|
private lastSeq;
|
|
656
658
|
private pendingOutbox;
|
|
657
659
|
private readonly sendSync;
|
|
@@ -787,7 +789,9 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
787
789
|
/**
|
|
788
790
|
* Send usage data to the server
|
|
789
791
|
*/
|
|
790
|
-
sendUsageData(usage: Usage, model?: string): void;
|
|
792
|
+
sendUsageData(usage: Usage, model?: string, eventId?: string): void;
|
|
793
|
+
/** Save a provider's cumulative session snapshot under one upsert key. */
|
|
794
|
+
sendAgentUsageSnapshot(agent: string, rawUsage: unknown): boolean;
|
|
791
795
|
/**
|
|
792
796
|
* Returns the latest session metadata known to the client.
|
|
793
797
|
*/
|
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-kLTNjWVl.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:util';
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
4
4
|
var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
5
5
|
var z = require('zod');
|
|
6
|
-
var index = require('./index-
|
|
6
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
7
7
|
var limits = require('./limits-KdWKmwtH.cjs');
|
|
8
|
-
var persistence = require('./types-
|
|
8
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
9
9
|
require('chalk');
|
|
10
10
|
require('node:os');
|
|
11
11
|
require('node:crypto');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { p as pushClipboardViaDaemon } from './index-
|
|
4
|
+
import { p as pushClipboardViaDaemon } from './index-DBO5ydFO.mjs';
|
|
5
5
|
import { C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, c as CLIPBOARD_MAX_BYTES } from './limits-CwFb5S2b.mjs';
|
|
6
|
-
import { l as logger } from './types-
|
|
6
|
+
import { l as logger } from './types-kLTNjWVl.mjs';
|
|
7
7
|
import 'chalk';
|
|
8
8
|
import 'node:os';
|
|
9
9
|
import 'node:crypto';
|
|
@@ -4,10 +4,10 @@ var ink = require('ink');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
-
var persistence = require('./types-
|
|
8
|
-
var index = require('./index-
|
|
9
|
-
var AcpBackend = require('./AcpBackend-
|
|
10
|
-
var config = require('./config-
|
|
7
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
8
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
9
|
+
var AcpBackend = require('./AcpBackend-a8B0Y7EF.cjs');
|
|
10
|
+
var config = require('./config-Bk2_O4iy.cjs');
|
|
11
11
|
require('axios');
|
|
12
12
|
require('chalk');
|
|
13
13
|
require('node:util');
|
|
@@ -1316,6 +1316,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1316
1316
|
break;
|
|
1317
1317
|
default:
|
|
1318
1318
|
if (msg.type === "token-count") {
|
|
1319
|
+
session.sendAgentUsageSnapshot("gemini", msg);
|
|
1319
1320
|
session.sendAgentMessage("gemini", {
|
|
1320
1321
|
type: "token_count",
|
|
1321
1322
|
...msg,
|
|
@@ -2,10 +2,10 @@ import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-
|
|
6
|
-
import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-
|
|
7
|
-
import { A as AcpBackend } from './AcpBackend-
|
|
8
|
-
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-
|
|
5
|
+
import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-kLTNjWVl.mjs';
|
|
6
|
+
import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-DBO5ydFO.mjs';
|
|
7
|
+
import { A as AcpBackend } from './AcpBackend-KEFEf0fa.mjs';
|
|
8
|
+
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-gCpPGROw.mjs';
|
|
9
9
|
import 'axios';
|
|
10
10
|
import 'chalk';
|
|
11
11
|
import 'node:util';
|
|
@@ -1314,6 +1314,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
|
|
|
1314
1314
|
break;
|
|
1315
1315
|
default:
|
|
1316
1316
|
if (msg.type === "token-count") {
|
|
1317
|
+
session.sendAgentUsageSnapshot("gemini", msg);
|
|
1317
1318
|
session.sendAgentMessage("gemini", {
|
|
1318
1319
|
type: "token_count",
|
|
1319
1320
|
...msg,
|
|
@@ -3,9 +3,9 @@ import { execFileSync } from 'node:child_process';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-
|
|
7
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
8
|
-
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-
|
|
6
|
+
import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-kLTNjWVl.mjs';
|
|
7
|
+
import { A as AcpSessionManager } from './AcpSessionManager-DpiEroK5.mjs';
|
|
8
|
+
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-DBO5ydFO.mjs';
|
|
9
9
|
import WebSocket from 'ws';
|
|
10
10
|
import * as ed from '@noble/ed25519';
|
|
11
11
|
import { sha512 } from '@noble/hashes/sha2.js';
|
|
@@ -651,6 +651,12 @@ class OpenClawBackend {
|
|
|
651
651
|
retryConnect() {
|
|
652
652
|
this.socket.retryConnect();
|
|
653
653
|
}
|
|
654
|
+
/** Return the gateway's cumulative usage for this backend session. */
|
|
655
|
+
async getUsageSnapshot() {
|
|
656
|
+
if (!this.sessionKey || !this.socket.isConnected()) return null;
|
|
657
|
+
const sessions = await this.socket.listSessions(100);
|
|
658
|
+
return sessions.find((session) => session.key === this.sessionKey || session.sessionId === this.sessionKey) ?? null;
|
|
659
|
+
}
|
|
654
660
|
emit(msg) {
|
|
655
661
|
for (const handler of this.handlers) {
|
|
656
662
|
handler(msg);
|
|
@@ -968,6 +974,12 @@ async function runOpenClaw(opts) {
|
|
|
968
974
|
log(`Turn ended: ${JSON.stringify(errorLogMetadata(error))}`);
|
|
969
975
|
sendEnvelopes(sessionManager.endTurn("failed"));
|
|
970
976
|
}
|
|
977
|
+
try {
|
|
978
|
+
const usage = await backend.getUsageSnapshot();
|
|
979
|
+
if (usage) session.sendAgentUsageSnapshot("openclaw", usage);
|
|
980
|
+
} catch (error) {
|
|
981
|
+
logger.debug("[openclaw] Failed to report usage:", errorLogMetadata(error));
|
|
982
|
+
}
|
|
971
983
|
inTurn = false;
|
|
972
984
|
thinking = false;
|
|
973
985
|
session.keepAlive(false, "remote");
|
|
@@ -5,9 +5,9 @@ var node_child_process = require('node:child_process');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_fs = require('node:fs');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
10
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
9
|
+
var AcpSessionManager = require('./AcpSessionManager-rkoOuyxF.cjs');
|
|
10
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
11
11
|
var WebSocket = require('ws');
|
|
12
12
|
var ed = require('@noble/ed25519');
|
|
13
13
|
var sha2_js = require('@noble/hashes/sha2.js');
|
|
@@ -672,6 +672,12 @@ class OpenClawBackend {
|
|
|
672
672
|
retryConnect() {
|
|
673
673
|
this.socket.retryConnect();
|
|
674
674
|
}
|
|
675
|
+
/** Return the gateway's cumulative usage for this backend session. */
|
|
676
|
+
async getUsageSnapshot() {
|
|
677
|
+
if (!this.sessionKey || !this.socket.isConnected()) return null;
|
|
678
|
+
const sessions = await this.socket.listSessions(100);
|
|
679
|
+
return sessions.find((session) => session.key === this.sessionKey || session.sessionId === this.sessionKey) ?? null;
|
|
680
|
+
}
|
|
675
681
|
emit(msg) {
|
|
676
682
|
for (const handler of this.handlers) {
|
|
677
683
|
handler(msg);
|
|
@@ -989,6 +995,12 @@ async function runOpenClaw(opts) {
|
|
|
989
995
|
log(`Turn ended: ${JSON.stringify(persistence.errorLogMetadata(error))}`);
|
|
990
996
|
sendEnvelopes(sessionManager.endTurn("failed"));
|
|
991
997
|
}
|
|
998
|
+
try {
|
|
999
|
+
const usage = await backend.getUsageSnapshot();
|
|
1000
|
+
if (usage) session.sendAgentUsageSnapshot("openclaw", usage);
|
|
1001
|
+
} catch (error) {
|
|
1002
|
+
persistence.logger.debug("[openclaw] Failed to report usage:", persistence.errorLogMetadata(error));
|
|
1003
|
+
}
|
|
992
1004
|
inTurn = false;
|
|
993
1005
|
thinking = false;
|
|
994
1006
|
session.keepAlive(false, "remote");
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var persistence = require('./types-
|
|
7
|
-
var index = require('./index-
|
|
6
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
7
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
8
8
|
require('axios');
|
|
9
9
|
require('node:util');
|
|
10
10
|
require('node:os');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { r as readPersistedSessions, c as configuration } from './types-
|
|
5
|
-
import { b as sendUserMessage, a as sessionWebUrl } from './index-
|
|
4
|
+
import { r as readPersistedSessions, c as configuration } from './types-kLTNjWVl.mjs';
|
|
5
|
+
import { b as sendUserMessage, a as sessionWebUrl } from './index-DBO5ydFO.mjs';
|
|
6
6
|
import 'axios';
|
|
7
7
|
import 'node:util';
|
|
8
8
|
import 'node:os';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-
|
|
5
|
-
import { l as logger } from './types-
|
|
4
|
+
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-DBO5ydFO.mjs';
|
|
5
|
+
import { l as logger } from './types-kLTNjWVl.mjs';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:crypto';
|
|
8
8
|
import 'cross-spawn';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var index = require('./index-
|
|
7
|
-
var persistence = require('./types-
|
|
6
|
+
var index = require('./index-Baq7aDcp.cjs');
|
|
7
|
+
var persistence = require('./types-xqPsUU1d.cjs');
|
|
8
8
|
require('node:os');
|
|
9
9
|
require('node:crypto');
|
|
10
10
|
require('cross-spawn');
|
|
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
|
|
|
29
29
|
import { Expo } from 'expo-server-sdk';
|
|
30
30
|
|
|
31
31
|
var name = "very-happy-cli";
|
|
32
|
-
var version = "0.2.
|
|
32
|
+
var version = "0.2.76";
|
|
33
33
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
34
34
|
var author = "Kirill Dubovitskiy";
|
|
35
35
|
var contributors = [
|
|
@@ -142,12 +142,12 @@ var dependencies = {
|
|
|
142
142
|
zod: "^4.0.0"
|
|
143
143
|
};
|
|
144
144
|
var optionalDependencies = {
|
|
145
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
146
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
147
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
148
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
149
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
150
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
145
|
+
"very-happy-tools-arm64-darwin": "0.2.76",
|
|
146
|
+
"very-happy-tools-x64-darwin": "0.2.76",
|
|
147
|
+
"very-happy-tools-arm64-linux": "0.2.76",
|
|
148
|
+
"very-happy-tools-x64-linux": "0.2.76",
|
|
149
|
+
"very-happy-tools-arm64-win32": "0.2.76",
|
|
150
|
+
"very-happy-tools-x64-win32": "0.2.76"
|
|
151
151
|
};
|
|
152
152
|
var devDependencies = {
|
|
153
153
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -2664,6 +2664,45 @@ class InvalidateSync {
|
|
|
2664
2664
|
};
|
|
2665
2665
|
}
|
|
2666
2666
|
|
|
2667
|
+
function record(value) {
|
|
2668
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
2669
|
+
}
|
|
2670
|
+
function finiteNonNegative(value) {
|
|
2671
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
2672
|
+
}
|
|
2673
|
+
function firstNumber(source, keys) {
|
|
2674
|
+
for (const key of keys) {
|
|
2675
|
+
const value = finiteNonNegative(source[key]);
|
|
2676
|
+
if (value !== void 0) return value;
|
|
2677
|
+
}
|
|
2678
|
+
return void 0;
|
|
2679
|
+
}
|
|
2680
|
+
function normalizeAgentUsage(raw) {
|
|
2681
|
+
const outer = record(raw);
|
|
2682
|
+
if (!outer) return null;
|
|
2683
|
+
const wrapped = record(outer.totalTokenUsage) ?? record(outer.total_token_usage) ?? record(outer.total) ?? record(outer.usage) ?? outer;
|
|
2684
|
+
const input = firstNumber(wrapped, ["inputTokens", "input_tokens", "input"]);
|
|
2685
|
+
const output = firstNumber(wrapped, ["outputTokens", "output_tokens", "output"]);
|
|
2686
|
+
const cacheRead = firstNumber(wrapped, ["cachedInputTokens", "cached_input_tokens", "cachedReadTokens", "cacheReadInputTokens", "cache_read_input_tokens", "cache_read"]);
|
|
2687
|
+
const cacheCreation = firstNumber(wrapped, ["cacheCreationInputTokens", "cache_creation_input_tokens", "cachedWriteTokens", "cacheWriteInputTokens", "cache_write_input_tokens", "cache_creation"]);
|
|
2688
|
+
const reasoning = firstNumber(wrapped, ["reasoningOutputTokens", "reasoning_output_tokens", "thoughtTokens", "reasoning"]);
|
|
2689
|
+
const explicitTotal = firstNumber(wrapped, ["totalTokens", "total_tokens", "total"]);
|
|
2690
|
+
const fallbackTotal = input !== void 0 || output !== void 0 ? (input ?? 0) + (output ?? 0) : void 0;
|
|
2691
|
+
const total = explicitTotal ?? fallbackTotal;
|
|
2692
|
+
if (total === void 0) return null;
|
|
2693
|
+
return {
|
|
2694
|
+
total,
|
|
2695
|
+
...input !== void 0 ? { input } : {},
|
|
2696
|
+
...output !== void 0 ? { output } : {},
|
|
2697
|
+
...cacheCreation !== void 0 ? { cache_creation: cacheCreation } : {},
|
|
2698
|
+
...cacheRead !== void 0 ? { cache_read: cacheRead } : {},
|
|
2699
|
+
...reasoning !== void 0 ? { reasoning } : {}
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2702
|
+
function usageAgentKey(agent) {
|
|
2703
|
+
return agent.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "unknown";
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2667
2706
|
class ApiSessionClient extends EventEmitter {
|
|
2668
2707
|
token;
|
|
2669
2708
|
sessionId;
|
|
@@ -2704,6 +2743,17 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2704
2743
|
startedSubagents: /* @__PURE__ */ new Set(),
|
|
2705
2744
|
activeSubagents: /* @__PURE__ */ new Set()
|
|
2706
2745
|
};
|
|
2746
|
+
seenClaudeUsageEvents = /* @__PURE__ */ new Set();
|
|
2747
|
+
claudeUsageTotals = {
|
|
2748
|
+
total: 0,
|
|
2749
|
+
input: 0,
|
|
2750
|
+
output: 0,
|
|
2751
|
+
cache_creation: 0,
|
|
2752
|
+
cache_read: 0,
|
|
2753
|
+
costTotal: 0,
|
|
2754
|
+
costInput: 0,
|
|
2755
|
+
costOutput: 0
|
|
2756
|
+
};
|
|
2707
2757
|
lastSeq = 0;
|
|
2708
2758
|
pendingOutbox = [];
|
|
2709
2759
|
sendSync;
|
|
@@ -3166,7 +3216,8 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3166
3216
|
}
|
|
3167
3217
|
if (body.type === "assistant" && body.message?.usage) {
|
|
3168
3218
|
try {
|
|
3169
|
-
|
|
3219
|
+
const eventId = typeof body.uuid === "string" ? body.uuid : typeof body.message.id === "string" ? body.message.id : void 0;
|
|
3220
|
+
this.sendUsageData(body.message.usage, body.message.model, eventId);
|
|
3170
3221
|
} catch (error) {
|
|
3171
3222
|
logger.debug("[SOCKET] Failed to send usage data:", error);
|
|
3172
3223
|
}
|
|
@@ -3317,28 +3368,56 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3317
3368
|
/**
|
|
3318
3369
|
* Send usage data to the server
|
|
3319
3370
|
*/
|
|
3320
|
-
sendUsageData(usage, model) {
|
|
3371
|
+
sendUsageData(usage, model, eventId) {
|
|
3372
|
+
if (eventId && this.seenClaudeUsageEvents.has(eventId)) return;
|
|
3373
|
+
if (eventId) this.seenClaudeUsageEvents.add(eventId);
|
|
3321
3374
|
const totalTokens = usage.input_tokens + usage.output_tokens + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
|
|
3322
3375
|
const costs = calculateCost(usage, model);
|
|
3376
|
+
this.claudeUsageTotals.total += totalTokens;
|
|
3377
|
+
this.claudeUsageTotals.input += usage.input_tokens;
|
|
3378
|
+
this.claudeUsageTotals.output += usage.output_tokens;
|
|
3379
|
+
this.claudeUsageTotals.cache_creation += usage.cache_creation_input_tokens || 0;
|
|
3380
|
+
this.claudeUsageTotals.cache_read += usage.cache_read_input_tokens || 0;
|
|
3381
|
+
this.claudeUsageTotals.costTotal += costs.total;
|
|
3382
|
+
this.claudeUsageTotals.costInput += costs.input;
|
|
3383
|
+
this.claudeUsageTotals.costOutput += costs.output;
|
|
3323
3384
|
const usageReport = {
|
|
3385
|
+
// Keep the legacy key so upgrading replaces the old last-call row
|
|
3386
|
+
// instead of making old + new clients double-count one session.
|
|
3324
3387
|
key: "claude-session",
|
|
3325
3388
|
sessionId: this.sessionId,
|
|
3326
3389
|
tokens: {
|
|
3327
|
-
total:
|
|
3328
|
-
input:
|
|
3329
|
-
output:
|
|
3330
|
-
cache_creation:
|
|
3331
|
-
cache_read:
|
|
3390
|
+
total: this.claudeUsageTotals.total,
|
|
3391
|
+
input: this.claudeUsageTotals.input,
|
|
3392
|
+
output: this.claudeUsageTotals.output,
|
|
3393
|
+
cache_creation: this.claudeUsageTotals.cache_creation,
|
|
3394
|
+
cache_read: this.claudeUsageTotals.cache_read
|
|
3332
3395
|
},
|
|
3333
3396
|
cost: {
|
|
3334
|
-
total:
|
|
3335
|
-
input:
|
|
3336
|
-
output:
|
|
3397
|
+
total: this.claudeUsageTotals.costTotal,
|
|
3398
|
+
input: this.claudeUsageTotals.costInput,
|
|
3399
|
+
output: this.claudeUsageTotals.costOutput
|
|
3337
3400
|
}
|
|
3338
3401
|
};
|
|
3339
3402
|
logger.debugLargeJson("[SOCKET] Sending usage data:", usageReport);
|
|
3340
3403
|
this.socket.emit("usage-report", usageReport);
|
|
3341
3404
|
}
|
|
3405
|
+
/** Save a provider's cumulative session snapshot under one upsert key. */
|
|
3406
|
+
sendAgentUsageSnapshot(agent, rawUsage) {
|
|
3407
|
+
const tokens = normalizeAgentUsage(rawUsage);
|
|
3408
|
+
if (!tokens) return false;
|
|
3409
|
+
const usageReport = {
|
|
3410
|
+
key: `usage:${usageAgentKey(agent)}:session`,
|
|
3411
|
+
sessionId: this.sessionId,
|
|
3412
|
+
tokens,
|
|
3413
|
+
// Provider token-count events do not expose reliable billed cost.
|
|
3414
|
+
// The Web treats this sentinel as unknown, not as real $0.00.
|
|
3415
|
+
cost: { total: 0 }
|
|
3416
|
+
};
|
|
3417
|
+
logger.debugLargeJson("[SOCKET] Sending agent usage snapshot:", usageReport);
|
|
3418
|
+
this.socket.emit("usage-report", usageReport);
|
|
3419
|
+
return true;
|
|
3420
|
+
}
|
|
3342
3421
|
/**
|
|
3343
3422
|
* Returns the latest session metadata known to the client.
|
|
3344
3423
|
*/
|
|
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
|
51
51
|
var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
|
|
52
52
|
|
|
53
53
|
var name = "very-happy-cli";
|
|
54
|
-
var version = "0.2.
|
|
54
|
+
var version = "0.2.76";
|
|
55
55
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
56
56
|
var author = "Kirill Dubovitskiy";
|
|
57
57
|
var contributors = [
|
|
@@ -164,12 +164,12 @@ var dependencies = {
|
|
|
164
164
|
zod: "^4.0.0"
|
|
165
165
|
};
|
|
166
166
|
var optionalDependencies = {
|
|
167
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
168
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
169
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
170
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
171
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
172
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
167
|
+
"very-happy-tools-arm64-darwin": "0.2.76",
|
|
168
|
+
"very-happy-tools-x64-darwin": "0.2.76",
|
|
169
|
+
"very-happy-tools-arm64-linux": "0.2.76",
|
|
170
|
+
"very-happy-tools-x64-linux": "0.2.76",
|
|
171
|
+
"very-happy-tools-arm64-win32": "0.2.76",
|
|
172
|
+
"very-happy-tools-x64-win32": "0.2.76"
|
|
173
173
|
};
|
|
174
174
|
var devDependencies = {
|
|
175
175
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -1415,7 +1415,7 @@ class RpcHandlerManager {
|
|
|
1415
1415
|
}
|
|
1416
1416
|
}
|
|
1417
1417
|
|
|
1418
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1418
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-xqPsUU1d.cjs', document.baseURI).href))));
|
|
1419
1419
|
function projectPath() {
|
|
1420
1420
|
const path = path$1.resolve(__dirname$1, "..");
|
|
1421
1421
|
return path;
|
|
@@ -2686,6 +2686,45 @@ class InvalidateSync {
|
|
|
2686
2686
|
};
|
|
2687
2687
|
}
|
|
2688
2688
|
|
|
2689
|
+
function record(value) {
|
|
2690
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
2691
|
+
}
|
|
2692
|
+
function finiteNonNegative(value) {
|
|
2693
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
2694
|
+
}
|
|
2695
|
+
function firstNumber(source, keys) {
|
|
2696
|
+
for (const key of keys) {
|
|
2697
|
+
const value = finiteNonNegative(source[key]);
|
|
2698
|
+
if (value !== void 0) return value;
|
|
2699
|
+
}
|
|
2700
|
+
return void 0;
|
|
2701
|
+
}
|
|
2702
|
+
function normalizeAgentUsage(raw) {
|
|
2703
|
+
const outer = record(raw);
|
|
2704
|
+
if (!outer) return null;
|
|
2705
|
+
const wrapped = record(outer.totalTokenUsage) ?? record(outer.total_token_usage) ?? record(outer.total) ?? record(outer.usage) ?? outer;
|
|
2706
|
+
const input = firstNumber(wrapped, ["inputTokens", "input_tokens", "input"]);
|
|
2707
|
+
const output = firstNumber(wrapped, ["outputTokens", "output_tokens", "output"]);
|
|
2708
|
+
const cacheRead = firstNumber(wrapped, ["cachedInputTokens", "cached_input_tokens", "cachedReadTokens", "cacheReadInputTokens", "cache_read_input_tokens", "cache_read"]);
|
|
2709
|
+
const cacheCreation = firstNumber(wrapped, ["cacheCreationInputTokens", "cache_creation_input_tokens", "cachedWriteTokens", "cacheWriteInputTokens", "cache_write_input_tokens", "cache_creation"]);
|
|
2710
|
+
const reasoning = firstNumber(wrapped, ["reasoningOutputTokens", "reasoning_output_tokens", "thoughtTokens", "reasoning"]);
|
|
2711
|
+
const explicitTotal = firstNumber(wrapped, ["totalTokens", "total_tokens", "total"]);
|
|
2712
|
+
const fallbackTotal = input !== void 0 || output !== void 0 ? (input ?? 0) + (output ?? 0) : void 0;
|
|
2713
|
+
const total = explicitTotal ?? fallbackTotal;
|
|
2714
|
+
if (total === void 0) return null;
|
|
2715
|
+
return {
|
|
2716
|
+
total,
|
|
2717
|
+
...input !== void 0 ? { input } : {},
|
|
2718
|
+
...output !== void 0 ? { output } : {},
|
|
2719
|
+
...cacheCreation !== void 0 ? { cache_creation: cacheCreation } : {},
|
|
2720
|
+
...cacheRead !== void 0 ? { cache_read: cacheRead } : {},
|
|
2721
|
+
...reasoning !== void 0 ? { reasoning } : {}
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
function usageAgentKey(agent) {
|
|
2725
|
+
return agent.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "unknown";
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2689
2728
|
class ApiSessionClient extends node_events.EventEmitter {
|
|
2690
2729
|
token;
|
|
2691
2730
|
sessionId;
|
|
@@ -2726,6 +2765,17 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2726
2765
|
startedSubagents: /* @__PURE__ */ new Set(),
|
|
2727
2766
|
activeSubagents: /* @__PURE__ */ new Set()
|
|
2728
2767
|
};
|
|
2768
|
+
seenClaudeUsageEvents = /* @__PURE__ */ new Set();
|
|
2769
|
+
claudeUsageTotals = {
|
|
2770
|
+
total: 0,
|
|
2771
|
+
input: 0,
|
|
2772
|
+
output: 0,
|
|
2773
|
+
cache_creation: 0,
|
|
2774
|
+
cache_read: 0,
|
|
2775
|
+
costTotal: 0,
|
|
2776
|
+
costInput: 0,
|
|
2777
|
+
costOutput: 0
|
|
2778
|
+
};
|
|
2729
2779
|
lastSeq = 0;
|
|
2730
2780
|
pendingOutbox = [];
|
|
2731
2781
|
sendSync;
|
|
@@ -3188,7 +3238,8 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
3188
3238
|
}
|
|
3189
3239
|
if (body.type === "assistant" && body.message?.usage) {
|
|
3190
3240
|
try {
|
|
3191
|
-
|
|
3241
|
+
const eventId = typeof body.uuid === "string" ? body.uuid : typeof body.message.id === "string" ? body.message.id : void 0;
|
|
3242
|
+
this.sendUsageData(body.message.usage, body.message.model, eventId);
|
|
3192
3243
|
} catch (error) {
|
|
3193
3244
|
logger.debug("[SOCKET] Failed to send usage data:", error);
|
|
3194
3245
|
}
|
|
@@ -3339,28 +3390,56 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
3339
3390
|
/**
|
|
3340
3391
|
* Send usage data to the server
|
|
3341
3392
|
*/
|
|
3342
|
-
sendUsageData(usage, model) {
|
|
3393
|
+
sendUsageData(usage, model, eventId) {
|
|
3394
|
+
if (eventId && this.seenClaudeUsageEvents.has(eventId)) return;
|
|
3395
|
+
if (eventId) this.seenClaudeUsageEvents.add(eventId);
|
|
3343
3396
|
const totalTokens = usage.input_tokens + usage.output_tokens + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
|
|
3344
3397
|
const costs = calculateCost(usage, model);
|
|
3398
|
+
this.claudeUsageTotals.total += totalTokens;
|
|
3399
|
+
this.claudeUsageTotals.input += usage.input_tokens;
|
|
3400
|
+
this.claudeUsageTotals.output += usage.output_tokens;
|
|
3401
|
+
this.claudeUsageTotals.cache_creation += usage.cache_creation_input_tokens || 0;
|
|
3402
|
+
this.claudeUsageTotals.cache_read += usage.cache_read_input_tokens || 0;
|
|
3403
|
+
this.claudeUsageTotals.costTotal += costs.total;
|
|
3404
|
+
this.claudeUsageTotals.costInput += costs.input;
|
|
3405
|
+
this.claudeUsageTotals.costOutput += costs.output;
|
|
3345
3406
|
const usageReport = {
|
|
3407
|
+
// Keep the legacy key so upgrading replaces the old last-call row
|
|
3408
|
+
// instead of making old + new clients double-count one session.
|
|
3346
3409
|
key: "claude-session",
|
|
3347
3410
|
sessionId: this.sessionId,
|
|
3348
3411
|
tokens: {
|
|
3349
|
-
total:
|
|
3350
|
-
input:
|
|
3351
|
-
output:
|
|
3352
|
-
cache_creation:
|
|
3353
|
-
cache_read:
|
|
3412
|
+
total: this.claudeUsageTotals.total,
|
|
3413
|
+
input: this.claudeUsageTotals.input,
|
|
3414
|
+
output: this.claudeUsageTotals.output,
|
|
3415
|
+
cache_creation: this.claudeUsageTotals.cache_creation,
|
|
3416
|
+
cache_read: this.claudeUsageTotals.cache_read
|
|
3354
3417
|
},
|
|
3355
3418
|
cost: {
|
|
3356
|
-
total:
|
|
3357
|
-
input:
|
|
3358
|
-
output:
|
|
3419
|
+
total: this.claudeUsageTotals.costTotal,
|
|
3420
|
+
input: this.claudeUsageTotals.costInput,
|
|
3421
|
+
output: this.claudeUsageTotals.costOutput
|
|
3359
3422
|
}
|
|
3360
3423
|
};
|
|
3361
3424
|
logger.debugLargeJson("[SOCKET] Sending usage data:", usageReport);
|
|
3362
3425
|
this.socket.emit("usage-report", usageReport);
|
|
3363
3426
|
}
|
|
3427
|
+
/** Save a provider's cumulative session snapshot under one upsert key. */
|
|
3428
|
+
sendAgentUsageSnapshot(agent, rawUsage) {
|
|
3429
|
+
const tokens = normalizeAgentUsage(rawUsage);
|
|
3430
|
+
if (!tokens) return false;
|
|
3431
|
+
const usageReport = {
|
|
3432
|
+
key: `usage:${usageAgentKey(agent)}:session`,
|
|
3433
|
+
sessionId: this.sessionId,
|
|
3434
|
+
tokens,
|
|
3435
|
+
// Provider token-count events do not expose reliable billed cost.
|
|
3436
|
+
// The Web treats this sentinel as unknown, not as real $0.00.
|
|
3437
|
+
cost: { total: 0 }
|
|
3438
|
+
};
|
|
3439
|
+
logger.debugLargeJson("[SOCKET] Sending agent usage snapshot:", usageReport);
|
|
3440
|
+
this.socket.emit("usage-report", usageReport);
|
|
3441
|
+
return true;
|
|
3442
|
+
}
|
|
3364
3443
|
/**
|
|
3365
3444
|
* Returns the latest session metadata known to the client.
|
|
3366
3445
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.76",
|
|
4
4
|
"description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"contributors": [
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
117
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
118
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
119
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
120
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
121
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
116
|
+
"very-happy-tools-arm64-darwin": "0.2.76",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.76",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.76",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.76",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.76",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.76"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|