charness 3.4.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/DEVELOPMENT.md +12 -1
- package/README.md +89 -6
- package/SETUP.md +199 -1
- package/dist/adapters/adapterEventRouting.d.ts +2 -2
- package/dist/adapters/adapterEventRouting.d.ts.map +1 -1
- package/dist/adapters/adapterEventRouting.js +4 -3
- package/dist/adapters/adapterEventRouting.js.map +1 -1
- package/dist/adapters/claudeCliAdapter.js +2 -2
- package/dist/adapters/claudeCliAdapter.js.map +1 -1
- package/dist/adapters/claudeConfigDir.d.ts +18 -0
- package/dist/adapters/claudeConfigDir.d.ts.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.d.ts +82 -6
- package/dist/adapters/claudeJsonStreamAdapter.d.ts.map +1 -1
- package/dist/adapters/claudeJsonStreamAdapter.js +211 -14
- package/dist/adapters/claudeJsonStreamAdapter.js.map +1 -1
- package/dist/adapters/createAdapter.d.ts +14 -1
- package/dist/adapters/createAdapter.d.ts.map +1 -1
- package/dist/adapters/createAdapter.js +54 -2
- package/dist/adapters/createAdapter.js.map +1 -1
- package/dist/adapters/openCodeAdapter.d.ts +5 -0
- package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/openCodeAdapter.js +7 -0
- package/dist/adapters/openCodeAdapter.js.map +1 -1
- package/dist/agentLogin/agentLogin.d.ts +18 -1
- package/dist/agentLogin/agentLogin.d.ts.map +1 -1
- package/dist/agentLogin/agentLogin.js +59 -18
- package/dist/agentLogin/agentLogin.js.map +1 -1
- package/dist/apiErrorRetry.d.ts +3 -1
- package/dist/apiErrorRetry.d.ts.map +1 -1
- package/dist/apiErrorRetry.js +11 -1
- package/dist/apiErrorRetry.js.map +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +475 -105
- package/dist/bot.js.map +1 -1
- package/dist/cli/claudeProfiles.d.ts +1 -1
- package/dist/cli/claudeProfiles.d.ts.map +1 -1
- package/dist/cli/claudeProfiles.js +11 -6
- package/dist/cli/claudeProfiles.js.map +1 -1
- package/dist/connectors/jira/connector.d.ts +2 -0
- package/dist/connectors/jira/connector.d.ts.map +1 -1
- package/dist/connectors/jira/connector.js +5 -4
- package/dist/connectors/jira/connector.js.map +1 -1
- package/dist/connectors/telegram/commands/claudeAccounts.d.ts +6 -2
- package/dist/connectors/telegram/commands/claudeAccounts.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/claudeAccounts.js +127 -28
- package/dist/connectors/telegram/commands/claudeAccounts.js.map +1 -1
- package/dist/connectors/telegram/commands/compaction.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/compaction.js +39 -8
- package/dist/connectors/telegram/commands/compaction.js.map +1 -1
- package/dist/connectors/telegram/commands/fallbackChain.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/fallbackChain.js +6 -2
- package/dist/connectors/telegram/commands/fallbackChain.js.map +1 -1
- package/dist/connectors/telegram/forumTopicCreated.d.ts +20 -0
- package/dist/connectors/telegram/forumTopicCreated.d.ts.map +1 -0
- package/dist/connectors/telegram/forumTopicCreated.js +16 -0
- package/dist/connectors/telegram/forumTopicCreated.js.map +1 -0
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/de.js +42 -1
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +42 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +42 -1
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +42 -1
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/hi.d.ts.map +1 -1
- package/dist/i18n/hi.js +42 -1
- package/dist/i18n/hi.js.map +1 -1
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ja.js +42 -1
- package/dist/i18n/ja.js.map +1 -1
- package/dist/i18n/ka.d.ts.map +1 -1
- package/dist/i18n/ka.js +42 -1
- package/dist/i18n/ka.js.map +1 -1
- package/dist/i18n/pt.d.ts.map +1 -1
- package/dist/i18n/pt.js +42 -1
- package/dist/i18n/pt.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +42 -1
- package/dist/i18n/ru.js.map +1 -1
- package/dist/i18n/uk.d.ts.map +1 -1
- package/dist/i18n/uk.js +42 -1
- package/dist/i18n/uk.js.map +1 -1
- package/dist/i18n/uz.d.ts.map +1 -1
- package/dist/i18n/uz.js +42 -1
- package/dist/i18n/uz.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +42 -1
- package/dist/i18n/zh.js.map +1 -1
- package/dist/i18n.d.ts +2 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js.map +1 -1
- package/dist/rateLimiter.d.ts +6 -0
- package/dist/rateLimiter.d.ts.map +1 -1
- package/dist/rateLimiter.js +9 -0
- package/dist/rateLimiter.js.map +1 -1
- package/dist/requests/wakeUpEngine.d.ts +4 -0
- package/dist/requests/wakeUpEngine.d.ts.map +1 -1
- package/dist/requests/wakeUpEngine.js +3 -3
- package/dist/requests/wakeUpEngine.js.map +1 -1
- package/dist/requests/wakeUpRules.d.ts +2 -1
- package/dist/requests/wakeUpRules.d.ts.map +1 -1
- package/dist/requests/wakeUpRules.js +3 -2
- package/dist/requests/wakeUpRules.js.map +1 -1
- package/dist/scheduler/mcpSurface.d.ts.map +1 -1
- package/dist/scheduler/mcpSurface.js +5 -3
- package/dist/scheduler/mcpSurface.js.map +1 -1
- package/dist/selfUpdate/updateMessages.d.ts +1 -1
- package/dist/selfUpdate/updateMessages.d.ts.map +1 -1
- package/dist/selfUpdate/updateMessages.js.map +1 -1
- package/dist/state.d.ts +67 -5
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +76 -7
- package/dist/state.js.map +1 -1
- package/dist/testTimings.d.ts +45 -0
- package/dist/testTimings.d.ts.map +1 -0
- package/dist/testTimings.js +89 -0
- package/dist/testTimings.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/adapterSwitchSessionIds.d.ts +5 -1
- package/dist/utils/adapterSwitchSessionIds.d.ts.map +1 -1
- package/dist/utils/adapterSwitchSessionIds.js +1 -1
- package/dist/utils/adapterSwitchSessionIds.js.map +1 -1
- package/dist/utils/adoptedToolList.d.ts +16 -21
- package/dist/utils/adoptedToolList.d.ts.map +1 -1
- package/dist/utils/adoptedToolList.js +18 -17
- package/dist/utils/adoptedToolList.js.map +1 -1
- package/dist/utils/anthropicApiKeyCheck.d.ts +19 -0
- package/dist/utils/anthropicApiKeyCheck.d.ts.map +1 -0
- package/dist/utils/anthropicApiKeyCheck.js +41 -0
- package/dist/utils/anthropicApiKeyCheck.js.map +1 -0
- package/dist/utils/claudeAccountPickerPlan.d.ts +6 -1
- package/dist/utils/claudeAccountPickerPlan.d.ts.map +1 -1
- package/dist/utils/claudeAccountPickerPlan.js +5 -1
- package/dist/utils/claudeAccountPickerPlan.js.map +1 -1
- package/dist/utils/claudeApiKeyHelper.d.ts +19 -0
- package/dist/utils/claudeApiKeyHelper.d.ts.map +1 -0
- package/dist/utils/claudeApiKeyHelper.js +32 -0
- package/dist/utils/claudeApiKeyHelper.js.map +1 -0
- package/dist/utils/claudeApiSpend.d.ts +73 -0
- package/dist/utils/claudeApiSpend.d.ts.map +1 -0
- package/dist/utils/claudeApiSpend.js +82 -0
- package/dist/utils/claudeApiSpend.js.map +1 -0
- package/dist/utils/claudeCompactHook.d.ts +11 -6
- package/dist/utils/claudeCompactHook.d.ts.map +1 -1
- package/dist/utils/claudeCompactHook.js +28 -11
- package/dist/utils/claudeCompactHook.js.map +1 -1
- package/dist/utils/claudeLimitSwitch.d.ts +2 -1
- package/dist/utils/claudeLimitSwitch.d.ts.map +1 -1
- package/dist/utils/claudeLimitSwitch.js +3 -2
- package/dist/utils/claudeLimitSwitch.js.map +1 -1
- package/dist/utils/claudeProfileUsageLines.d.ts +18 -3
- package/dist/utils/claudeProfileUsageLines.d.ts.map +1 -1
- package/dist/utils/claudeProfileUsageLines.js +23 -2
- package/dist/utils/claudeProfileUsageLines.js.map +1 -1
- package/dist/utils/claudeProfiles.d.ts +57 -2
- package/dist/utils/claudeProfiles.d.ts.map +1 -1
- package/dist/utils/claudeProfiles.js +96 -3
- package/dist/utils/claudeProfiles.js.map +1 -1
- package/dist/utils/claudeScheduledJobs.d.ts +49 -0
- package/dist/utils/claudeScheduledJobs.d.ts.map +1 -0
- package/dist/utils/claudeScheduledJobs.js +62 -0
- package/dist/utils/claudeScheduledJobs.js.map +1 -0
- package/dist/utils/claudeStreamJson.d.ts +35 -2
- package/dist/utils/claudeStreamJson.d.ts.map +1 -1
- package/dist/utils/claudeStreamJson.js +31 -8
- package/dist/utils/claudeStreamJson.js.map +1 -1
- package/dist/utils/claudeTranscriptContent.d.ts +8 -0
- package/dist/utils/claudeTranscriptContent.d.ts.map +1 -1
- package/dist/utils/claudeTranscriptContent.js +44 -0
- package/dist/utils/claudeTranscriptContent.js.map +1 -1
- package/dist/utils/claudeUsage.d.ts +22 -6
- package/dist/utils/claudeUsage.d.ts.map +1 -1
- package/dist/utils/claudeUsage.js +12 -5
- package/dist/utils/claudeUsage.js.map +1 -1
- package/dist/utils/claudeUsageRefresher.d.ts +6 -0
- package/dist/utils/claudeUsageRefresher.d.ts.map +1 -1
- package/dist/utils/claudeUsageRefresher.js +2 -2
- package/dist/utils/claudeUsageRefresher.js.map +1 -1
- package/dist/utils/compactOnIdle.d.ts +12 -0
- package/dist/utils/compactOnIdle.d.ts.map +1 -1
- package/dist/utils/compactOnIdle.js +15 -1
- package/dist/utils/compactOnIdle.js.map +1 -1
- package/dist/utils/doctorLine.d.ts +13 -0
- package/dist/utils/doctorLine.d.ts.map +1 -0
- package/dist/utils/doctorLine.js +18 -0
- package/dist/utils/doctorLine.js.map +1 -0
- package/dist/utils/effortPickerPlan.d.ts +1 -2
- package/dist/utils/effortPickerPlan.d.ts.map +1 -1
- package/dist/utils/effortPickerPlan.js.map +1 -1
- package/dist/utils/fallbackChain.d.ts +15 -8
- package/dist/utils/fallbackChain.d.ts.map +1 -1
- package/dist/utils/fallbackChain.js +30 -13
- package/dist/utils/fallbackChain.js.map +1 -1
- package/dist/utils/jsonStreamHost.d.ts +19 -7
- package/dist/utils/jsonStreamHost.d.ts.map +1 -1
- package/dist/utils/jsonStreamHost.js +25 -11
- package/dist/utils/jsonStreamHost.js.map +1 -1
- package/dist/utils/jsonStreamPendingWork.d.ts +44 -0
- package/dist/utils/jsonStreamPendingWork.d.ts.map +1 -0
- package/dist/utils/jsonStreamPendingWork.js +48 -0
- package/dist/utils/jsonStreamPendingWork.js.map +1 -0
- package/dist/utils/limitsBoardPlan.d.ts +4 -2
- package/dist/utils/limitsBoardPlan.d.ts.map +1 -1
- package/dist/utils/limitsBoardPlan.js +12 -5
- package/dist/utils/limitsBoardPlan.js.map +1 -1
- package/dist/utils/lostWork.d.ts +117 -0
- package/dist/utils/lostWork.d.ts.map +1 -0
- package/dist/utils/lostWork.js +187 -0
- package/dist/utils/lostWork.js.map +1 -0
- package/dist/utils/nativeWindows.d.ts +29 -0
- package/dist/utils/nativeWindows.d.ts.map +1 -0
- package/dist/utils/nativeWindows.js +50 -0
- package/dist/utils/nativeWindows.js.map +1 -0
- package/dist/utils/recvPreviewRedaction.d.ts +7 -2
- package/dist/utils/recvPreviewRedaction.d.ts.map +1 -1
- package/dist/utils/recvPreviewRedaction.js +10 -4
- package/dist/utils/recvPreviewRedaction.js.map +1 -1
- package/dist/utils/threadStatusReport.d.ts +12 -1
- package/dist/utils/threadStatusReport.d.ts.map +1 -1
- package/dist/utils/threadStatusReport.js +13 -4
- package/dist/utils/threadStatusReport.js.map +1 -1
- package/dist/utils/updateScreenPlan.d.ts +1 -1
- package/dist/utils/updateScreenPlan.d.ts.map +1 -1
- package/dist/utils/updateScreenPlan.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @description
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
2
|
+
* @description Whether a json-stream process ADOPTED at boot runs a stale bot-MCP
|
|
3
|
+
* tool list (plan 2026-10-04-claude-process-lifecycle, L4). An MCP client fetches
|
|
4
|
+
* the tool list when it connects, and the bot's server is stateless (one
|
|
5
|
+
* `McpServer` per request), so it has no channel to push a `tools/list_changed`
|
|
6
|
+
* to a running client. A process started under an earlier bot build therefore
|
|
7
|
+
* keeps that build's tools — a live test (2026-10-04) saw `answer_request`
|
|
8
|
+
* missing from an adopted session. The bot persists a digest of the tool
|
|
9
|
+
* definitions a session was started with and compares it at adopt.
|
|
10
|
+
*
|
|
11
|
+
* A stale process is NOT stopped early: an early stop at its next idle point
|
|
12
|
+
* killed the agent's own pending work (a background task about to report, a
|
|
13
|
+
* scheduled job) and was never weighed against the idle compaction. It follows
|
|
14
|
+
* the normal lifecycle — compacted at the idle mark, then stopped — and the
|
|
15
|
+
* next trigger resumes it with the current tools.
|
|
13
16
|
*/
|
|
14
|
-
export
|
|
15
|
-
/** The process got the current tools at its start — nothing to do. */
|
|
16
|
-
'fresh'
|
|
17
|
-
/** Stale and idle: stop now; the next trigger resumes it with the current tools. */
|
|
18
|
-
| 'stopNow'
|
|
19
|
-
/** Stale but working: keep it until it is idle, then stop it. */
|
|
20
|
-
| 'stopWhenIdle';
|
|
21
|
-
export declare function decideAdoptedToolListRefresh(input: {
|
|
17
|
+
export declare function checkIsAdoptedToolListStale(input: {
|
|
22
18
|
/** The digest persisted when the process was started; absent for a row written before it was tracked. */
|
|
23
19
|
persistedDigest: string | undefined;
|
|
24
20
|
currentDigest: string;
|
|
25
|
-
|
|
26
|
-
}): AdoptedToolListRefresh;
|
|
21
|
+
}): boolean;
|
|
27
22
|
//# sourceMappingURL=adoptedToolList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adoptedToolList.d.ts","sourceRoot":"","sources":["../../src/utils/adoptedToolList.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adoptedToolList.d.ts","sourceRoot":"","sources":["../../src/utils/adoptedToolList.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,yGAAyG;IACzG,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAEV"}
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkIsAdoptedToolListStale = checkIsAdoptedToolListStale;
|
|
2
4
|
/**
|
|
3
|
-
* @description
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
5
|
+
* @description Whether a json-stream process ADOPTED at boot runs a stale bot-MCP
|
|
6
|
+
* tool list (plan 2026-10-04-claude-process-lifecycle, L4). An MCP client fetches
|
|
7
|
+
* the tool list when it connects, and the bot's server is stateless (one
|
|
8
|
+
* `McpServer` per request), so it has no channel to push a `tools/list_changed`
|
|
9
|
+
* to a running client. A process started under an earlier bot build therefore
|
|
10
|
+
* keeps that build's tools — a live test (2026-10-04) saw `answer_request`
|
|
11
|
+
* missing from an adopted session. The bot persists a digest of the tool
|
|
12
|
+
* definitions a session was started with and compares it at adopt.
|
|
13
|
+
*
|
|
14
|
+
* A stale process is NOT stopped early: an early stop at its next idle point
|
|
15
|
+
* killed the agent's own pending work (a background task about to report, a
|
|
16
|
+
* scheduled job) and was never weighed against the idle compaction. It follows
|
|
17
|
+
* the normal lifecycle — compacted at the idle mark, then stopped — and the
|
|
18
|
+
* next trigger resumes it with the current tools.
|
|
14
19
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function decideAdoptedToolListRefresh(input) {
|
|
18
|
-
if (input.persistedDigest === input.currentDigest)
|
|
19
|
-
return 'fresh';
|
|
20
|
-
return input.isWorking ? 'stopWhenIdle' : 'stopNow';
|
|
20
|
+
function checkIsAdoptedToolListStale(input) {
|
|
21
|
+
return input.persistedDigest !== input.currentDigest;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=adoptedToolList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adoptedToolList.js","sourceRoot":"","sources":["../../src/utils/adoptedToolList.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"adoptedToolList.js","sourceRoot":"","sources":["../../src/utils/adoptedToolList.ts"],"names":[],"mappings":";;AAgBA,kEAMC;AAtBD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,2BAA2B,CAAC,KAI3C;IACC,OAAO,KAAK,CAAC,eAAe,KAAK,KAAK,CAAC,aAAa,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Whether a pasted Anthropic API key is accepted by the API, before the bot stores it for an API-billed
|
|
3
|
+
* Claude account (`utils/claudeProfiles.ts`). One `GET /v1/models` — it lists models and costs nothing: `200` is a
|
|
4
|
+
* working key, `401` / `403` a key the API refuses (revoked, mistyped, another kind of credential), anything else —
|
|
5
|
+
* a timeout, a 5xx, no network — says nothing about the key (`unknown`: the caller stores it and says it could not
|
|
6
|
+
* check). A key with no credits left still lists models: the balance shows only on the first real request.
|
|
7
|
+
*
|
|
8
|
+
* The key travels only in the request's `x-api-key` header; it is never logged and never part of the result.
|
|
9
|
+
*/
|
|
10
|
+
import type { UsageFetchLike } from './claudeUsage';
|
|
11
|
+
export declare const anthropicModelsEndpoint = "https://api.anthropic.com/v1/models?limit=1";
|
|
12
|
+
export declare const anthropicApiKeyCheckTimeoutMs = 15000;
|
|
13
|
+
export type AnthropicApiKeyCheck = 'valid' | 'invalid' | 'unknown';
|
|
14
|
+
/** @description Ask the API whether `apiKey` works (see the module). Never throws. */
|
|
15
|
+
export declare function verifyAnthropicApiKey(apiKey: string, options?: {
|
|
16
|
+
fetchImpl?: UsageFetchLike;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}): Promise<AnthropicApiKeyCheck>;
|
|
19
|
+
//# sourceMappingURL=anthropicApiKeyCheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropicApiKeyCheck.d.ts","sourceRoot":"","sources":["../../src/utils/anthropicApiKeyCheck.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,eAAO,MAAM,uBAAuB,gDAAgD,CAAC;AAKrF,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAEpD,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAEnE,sFAAsF;AACtF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,cAAc,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/D,OAAO,CAAC,oBAAoB,CAAC,CAiB/B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description Whether a pasted Anthropic API key is accepted by the API, before the bot stores it for an API-billed
|
|
4
|
+
* Claude account (`utils/claudeProfiles.ts`). One `GET /v1/models` — it lists models and costs nothing: `200` is a
|
|
5
|
+
* working key, `401` / `403` a key the API refuses (revoked, mistyped, another kind of credential), anything else —
|
|
6
|
+
* a timeout, a 5xx, no network — says nothing about the key (`unknown`: the caller stores it and says it could not
|
|
7
|
+
* check). A key with no credits left still lists models: the balance shows only on the first real request.
|
|
8
|
+
*
|
|
9
|
+
* The key travels only in the request's `x-api-key` header; it is never logged and never part of the result.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.anthropicApiKeyCheckTimeoutMs = exports.anthropicModelsEndpoint = void 0;
|
|
13
|
+
exports.verifyAnthropicApiKey = verifyAnthropicApiKey;
|
|
14
|
+
exports.anthropicModelsEndpoint = 'https://api.anthropic.com/v1/models?limit=1';
|
|
15
|
+
/** The API version header every Anthropic API request carries. */
|
|
16
|
+
const anthropicApiVersion = '2023-06-01';
|
|
17
|
+
exports.anthropicApiKeyCheckTimeoutMs = 15_000;
|
|
18
|
+
/** @description Ask the API whether `apiKey` works (see the module). Never throws. */
|
|
19
|
+
async function verifyAnthropicApiKey(apiKey, options = {}) {
|
|
20
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? exports.anthropicApiKeyCheckTimeoutMs);
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetchImpl(exports.anthropicModelsEndpoint, {
|
|
25
|
+
headers: { 'x-api-key': apiKey, 'anthropic-version': anthropicApiVersion, Accept: 'application/json' },
|
|
26
|
+
signal: controller.signal,
|
|
27
|
+
});
|
|
28
|
+
if (response.status === 200)
|
|
29
|
+
return 'valid';
|
|
30
|
+
if (response.status === 401 || response.status === 403)
|
|
31
|
+
return 'invalid';
|
|
32
|
+
return 'unknown';
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return 'unknown';
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=anthropicApiKeyCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropicApiKeyCheck.js","sourceRoot":"","sources":["../../src/utils/anthropicApiKeyCheck.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAcH,sDAoBC;AA9BY,QAAA,uBAAuB,GAAG,6CAA6C,CAAC;AAErF,kEAAkE;AAClE,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAE5B,QAAA,6BAA6B,GAAG,MAAM,CAAC;AAIpD,sFAAsF;AAC/E,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,UAA8D,EAAE;IAEhE,MAAM,SAAS,GAAmB,OAAO,CAAC,SAAS,IAAK,UAAU,CAAC,KAAmC,CAAC;IACvG,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,SAAS,IAAI,qCAA6B,CAAC,CAAC;IACvG,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,+BAAuB,EAAE;YACxD,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACtG,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,OAAO,CAAC;QAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,SAAS,CAAC;QACzE,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* named — a removed name simply resolves to "unknown profile".
|
|
7
7
|
*/
|
|
8
8
|
import type { ClaudeProfileRecord } from '../state';
|
|
9
|
-
import { type ClaudeAccountKind } from './claudeProfiles';
|
|
9
|
+
import { type ClaudeAccountKind, type ClaudeProfileBilling } from './claudeProfiles';
|
|
10
10
|
/** Switch the topic (General: the instance default) to the named profile. */
|
|
11
11
|
export declare const accountUseCallbackRe: RegExp;
|
|
12
12
|
/** Open the sub-picker that chooses a profile to sign in again / to remove. */
|
|
@@ -19,6 +19,8 @@ export declare const accountRemoveCallbackRe: RegExp;
|
|
|
19
19
|
export declare const accountRemoveConfirmCallbackRe: RegExp;
|
|
20
20
|
/** Ask for a new profile's name. */
|
|
21
21
|
export declare const accountAddCallback = "acct_add";
|
|
22
|
+
/** Ask for the name of a new account billed to a Claude Console organization's API balance. */
|
|
23
|
+
export declare const accountAddApiCallback = "acct_addapi";
|
|
22
24
|
/** A topic drops its own pick and follows the instance default again. */
|
|
23
25
|
export declare const accountFollowDefaultCallback = "acct_follow";
|
|
24
26
|
/** Arm the OpenCode provider-id capture (the next plain message names the provider to connect). */
|
|
@@ -70,6 +72,8 @@ export interface AccountPickerRow {
|
|
|
70
72
|
email: string | null;
|
|
71
73
|
subscriptionType: string | null;
|
|
72
74
|
kind: ClaudeAccountKind;
|
|
75
|
+
/** How the account pays; `null` when never recorded (a subscription account added before billing was). */
|
|
76
|
+
billing: ClaudeProfileBilling | null;
|
|
73
77
|
/** How many bound topics resolve to this profile. */
|
|
74
78
|
topicCount: number;
|
|
75
79
|
}
|
|
@@ -84,6 +88,7 @@ export declare function buildAccountPickerRows(input: {
|
|
|
84
88
|
loggedIn: boolean | undefined;
|
|
85
89
|
email: string | null;
|
|
86
90
|
subscriptionType: string | null;
|
|
91
|
+
billing?: ClaudeProfileBilling | null;
|
|
87
92
|
};
|
|
88
93
|
/** The account the ✓ sits on; `null` for none (the topic runs OpenCode). */
|
|
89
94
|
activeName: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeAccountPickerPlan.d.ts","sourceRoot":"","sources":["../../src/utils/claudeAccountPickerPlan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAIL,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"claudeAccountPickerPlan.d.ts","sourceRoot":"","sources":["../../src/utils/claudeAccountPickerPlan.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* named — a removed name simply resolves to "unknown profile".
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.accountAutoSwitchOffCallback = exports.accountAutoSwitchOnCallback = exports.accountBackCallback = exports.accountOpenCodePageCallbackRe = exports.accountOpenCodeModelCallbackRe = exports.accountOpenCodeUseCallbackRe = exports.accountReconnectCallbackRe = exports.accountDisconnectConfirmCallbackRe = exports.accountDisconnectCallbackRe = exports.accountAddProviderCallback = exports.accountFollowDefaultCallback = exports.accountAddCallback = exports.accountRemoveConfirmCallbackRe = exports.accountRemoveCallbackRe = exports.accountLoginCallbackRe = exports.accountRemoveMenuCallback = exports.accountLoginMenuCallback = exports.accountUseCallbackRe = void 0;
|
|
10
|
+
exports.accountAutoSwitchOffCallback = exports.accountAutoSwitchOnCallback = exports.accountBackCallback = exports.accountOpenCodePageCallbackRe = exports.accountOpenCodeModelCallbackRe = exports.accountOpenCodeUseCallbackRe = exports.accountReconnectCallbackRe = exports.accountDisconnectConfirmCallbackRe = exports.accountDisconnectCallbackRe = exports.accountAddProviderCallback = exports.accountFollowDefaultCallback = exports.accountAddApiCallback = exports.accountAddCallback = exports.accountRemoveConfirmCallbackRe = exports.accountRemoveCallbackRe = exports.accountLoginCallbackRe = exports.accountRemoveMenuCallback = exports.accountLoginMenuCallback = exports.accountUseCallbackRe = void 0;
|
|
11
11
|
exports.buildAccountUseCallback = buildAccountUseCallback;
|
|
12
12
|
exports.buildAccountLoginCallback = buildAccountLoginCallback;
|
|
13
13
|
exports.buildAccountDisconnectCallback = buildAccountDisconnectCallback;
|
|
@@ -35,6 +35,8 @@ exports.accountRemoveCallbackRe = new RegExp(`^acct_rm_${nameGroup}$`);
|
|
|
35
35
|
exports.accountRemoveConfirmCallbackRe = new RegExp(`^acct_rmok_${nameGroup}$`);
|
|
36
36
|
/** Ask for a new profile's name. */
|
|
37
37
|
exports.accountAddCallback = 'acct_add';
|
|
38
|
+
/** Ask for the name of a new account billed to a Claude Console organization's API balance. */
|
|
39
|
+
exports.accountAddApiCallback = 'acct_addapi';
|
|
38
40
|
/** A topic drops its own pick and follows the instance default again. */
|
|
39
41
|
exports.accountFollowDefaultCallback = 'acct_follow';
|
|
40
42
|
/** Arm the OpenCode provider-id capture (the next plain message names the provider to connect). */
|
|
@@ -115,6 +117,7 @@ function buildAccountPickerRows(input) {
|
|
|
115
117
|
email: input.defaultStatus.email,
|
|
116
118
|
subscriptionType: input.defaultStatus.subscriptionType,
|
|
117
119
|
kind: (0, claudeProfiles_1.getClaudeAccountKind)(input.defaultStatus.subscriptionType),
|
|
120
|
+
billing: input.defaultStatus.billing ?? null,
|
|
118
121
|
topicCount: input.topicCounts.get(claudeProfiles_1.defaultClaudeProfileName) ?? 0,
|
|
119
122
|
}];
|
|
120
123
|
const added = Object.entries(input.records)
|
|
@@ -127,6 +130,7 @@ function buildAccountPickerRows(input) {
|
|
|
127
130
|
email: record.email ?? null,
|
|
128
131
|
subscriptionType: record.subscriptionType ?? null,
|
|
129
132
|
kind: (0, claudeProfiles_1.getClaudeAccountKind)(record.subscriptionType ?? null),
|
|
133
|
+
billing: record.billing ?? null,
|
|
130
134
|
topicCount: input.topicCounts.get(name) ?? 0,
|
|
131
135
|
});
|
|
132
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeAccountPickerPlan.js","sourceRoot":"","sources":["../../src/utils/claudeAccountPickerPlan.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;
|
|
1
|
+
{"version":3,"file":"claudeAccountPickerPlan.js","sourceRoot":"","sources":["../../src/utils/claudeAccountPickerPlan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description How a Claude process reads the API key pasted for an API account (`utils/claudeProfiles.ts`: the key
|
|
3
|
+
* file in the profile's own directory): an `apiKeyHelper` that prints the file, riding that profile's `--settings`
|
|
4
|
+
* only — the launch settings file (`claudeCompactHook.ts`) and the inline settings of a `claude auth status` probe.
|
|
5
|
+
* The helper names the file, never the key. Apart from `claudeProfiles.ts` so the connector guards, which load that
|
|
6
|
+
* module before any env file is read, never load the shell-quoting one.
|
|
7
|
+
*/
|
|
8
|
+
/** The `apiKeyHelper` command: print the key file (the CLI runs it through `/bin/sh` and trims the output). */
|
|
9
|
+
export declare function buildClaudeApiKeyHelperCommand(configDir: string): string;
|
|
10
|
+
/** The settings fragment that makes the CLI read the profile's pasted key: `{ apiKeyHelper }`. */
|
|
11
|
+
export declare function buildClaudeApiKeyHelperSettings(configDir: string): {
|
|
12
|
+
apiKeyHelper: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* @description The `--settings` argument pair a `claude auth status` probe of `configDir` needs: the inline helper
|
|
16
|
+
* settings when the directory holds a pasted key (the probe must see the key the sessions use), else nothing.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildClaudeAuthProbeSettingsArgs(configDir: string | null): string[];
|
|
19
|
+
//# sourceMappingURL=claudeApiKeyHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeApiKeyHelper.d.ts","sourceRoot":"","sources":["../../src/utils/claudeApiKeyHelper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,+GAA+G;AAC/G,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,kGAAkG;AAClG,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAE3F;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAGnF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description How a Claude process reads the API key pasted for an API account (`utils/claudeProfiles.ts`: the key
|
|
4
|
+
* file in the profile's own directory): an `apiKeyHelper` that prints the file, riding that profile's `--settings`
|
|
5
|
+
* only — the launch settings file (`claudeCompactHook.ts`) and the inline settings of a `claude auth status` probe.
|
|
6
|
+
* The helper names the file, never the key. Apart from `claudeProfiles.ts` so the connector guards, which load that
|
|
7
|
+
* module before any env file is read, never load the shell-quoting one.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.buildClaudeApiKeyHelperCommand = buildClaudeApiKeyHelperCommand;
|
|
11
|
+
exports.buildClaudeApiKeyHelperSettings = buildClaudeApiKeyHelperSettings;
|
|
12
|
+
exports.buildClaudeAuthProbeSettingsArgs = buildClaudeAuthProbeSettingsArgs;
|
|
13
|
+
const claudeProfiles_1 = require("./claudeProfiles");
|
|
14
|
+
const tmuxExec_1 = require("./tmuxExec");
|
|
15
|
+
/** The `apiKeyHelper` command: print the key file (the CLI runs it through `/bin/sh` and trims the output). */
|
|
16
|
+
function buildClaudeApiKeyHelperCommand(configDir) {
|
|
17
|
+
return `cat ${(0, tmuxExec_1.shellSingleQuote)((0, claudeProfiles_1.resolveClaudeProfileApiKeyFile)(configDir))}`;
|
|
18
|
+
}
|
|
19
|
+
/** The settings fragment that makes the CLI read the profile's pasted key: `{ apiKeyHelper }`. */
|
|
20
|
+
function buildClaudeApiKeyHelperSettings(configDir) {
|
|
21
|
+
return { apiKeyHelper: buildClaudeApiKeyHelperCommand(configDir) };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @description The `--settings` argument pair a `claude auth status` probe of `configDir` needs: the inline helper
|
|
25
|
+
* settings when the directory holds a pasted key (the probe must see the key the sessions use), else nothing.
|
|
26
|
+
*/
|
|
27
|
+
function buildClaudeAuthProbeSettingsArgs(configDir) {
|
|
28
|
+
if (configDir === null || !(0, claudeProfiles_1.checkHasClaudeProfileApiKey)(configDir))
|
|
29
|
+
return [];
|
|
30
|
+
return ['--settings', JSON.stringify(buildClaudeApiKeyHelperSettings(configDir))];
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=claudeApiKeyHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeApiKeyHelper.js","sourceRoot":"","sources":["../../src/utils/claudeApiKeyHelper.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAMH,wEAEC;AAGD,0EAEC;AAMD,4EAGC;AApBD,qDAA+F;AAC/F,yCAA8C;AAE9C,+GAA+G;AAC/G,SAAgB,8BAA8B,CAAC,SAAiB;IAC9D,OAAO,OAAO,IAAA,2BAAgB,EAAC,IAAA,+CAA8B,EAAC,SAAS,CAAC,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,kGAAkG;AAClG,SAAgB,+BAA+B,CAAC,SAAiB;IAC/D,OAAO,EAAE,YAAY,EAAE,8BAA8B,CAAC,SAAS,CAAC,EAAE,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,SAAgB,gCAAgC,CAAC,SAAwB;IACvE,IAAI,SAAS,KAAK,IAAI,IAAI,CAAC,IAAA,4CAA2B,EAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7E,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,+BAA+B,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description What an account billed to API credits (`utils/claudeProfiles.ts`, `billing: 'api'`) has spent through
|
|
3
|
+
* the bot, from the `total_cost_usd` of Claude's stream `result` frames (the json-stream backend; the tmux backend
|
|
4
|
+
* reports no figure).
|
|
5
|
+
*
|
|
6
|
+
* That figure is the CONVERSATION's running cost, not the turn's: Claude Code writes it into the transcript when its
|
|
7
|
+
* process exits and restores it on `--resume`, so a resumed process starts from the conversation's last saved total,
|
|
8
|
+
* and a subscription turn of the same conversation counts in it too (a notional figure). The turn's spend is therefore
|
|
9
|
+
* a DELTA, and only a turn on an API account adds to that account's spend. The first turn of a process the bot
|
|
10
|
+
* started is measured against the total that process restored (the adapter reads it from the transcript before the
|
|
11
|
+
* launch: `0` for a new conversation) — never against the last total the bot saw, which a turn the bot did not see
|
|
12
|
+
* (the tmux backend's, which reports none) or a process that died without its exit flush (the next one restores an
|
|
13
|
+
* OLDER total) makes wrong. Every later turn is measured against the last total the bot saw for that conversation (a
|
|
14
|
+
* per-topic baseline it keeps for every account, persisted, so an adopted process after a restart goes on from it).
|
|
15
|
+
*
|
|
16
|
+
* It is what the bot OBSERVED, not the organization's balance: reading that needs an Admin API key.
|
|
17
|
+
*
|
|
18
|
+
* Pure: the clock and the zone come from the caller.
|
|
19
|
+
*/
|
|
20
|
+
import type { ClaudeProfileBilling } from './claudeProfiles';
|
|
21
|
+
/** The last `total_cost_usd` the bot saw for a topic's conversation (`state.json` `claudeCostBaselines`). */
|
|
22
|
+
export interface ClaudeCostBaseline {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
totalCostUsd: number;
|
|
25
|
+
}
|
|
26
|
+
/** An API account's spend through the bot (`ClaudeProfileRecord.apiSpend`). */
|
|
27
|
+
export interface ClaudeApiSpend {
|
|
28
|
+
totalUsd: number;
|
|
29
|
+
/** ISO instant of the first turn counted. */
|
|
30
|
+
since: string;
|
|
31
|
+
lastTurnUsd: number;
|
|
32
|
+
/** ISO instant of the last turn counted. */
|
|
33
|
+
lastTurnAt: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @description The spend of the turn whose `result` reported `totalCostUsd` for `sessionId` (see the module). The first
|
|
37
|
+
* turn of a process the bot started (`startCostUsd` known) counts from the total that process restored; any other turn
|
|
38
|
+
* is the delta against the baseline of the same conversation, `null` (unknown) without one. A total BELOW the figure it
|
|
39
|
+
* is measured against means the CLI counted from zero (it restored nothing), so the total is the turn's.
|
|
40
|
+
*/
|
|
41
|
+
export declare function computeClaudeTurnCostUsd(input: {
|
|
42
|
+
previous: ClaudeCostBaseline | undefined;
|
|
43
|
+
sessionId: string;
|
|
44
|
+
totalCostUsd: number;
|
|
45
|
+
startCostUsd: number | null;
|
|
46
|
+
}): number | null;
|
|
47
|
+
/** What one turn's cost report does to the account it ran on. */
|
|
48
|
+
export interface ClaudeTurnCostOutcome {
|
|
49
|
+
/** What to add to the account's spend: the turn's cost on an account billed to API credits; `null` for nothing. */
|
|
50
|
+
spendUsd: number | null;
|
|
51
|
+
/** A billed turn went through on an account marked out of credits: the balance is back, the mark ends. */
|
|
52
|
+
isCreditMarkCleared: boolean;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* @description The effect of a turn's cost on its account: only an account billed to API credits has spend (a
|
|
56
|
+
* subscription's figure is notional), and only a positive, known cost adds to it. A turn that did not end on an error
|
|
57
|
+
* AND was billed proves the account works again, so it ends a used-up-credits mark on ANY account (the refusal marks
|
|
58
|
+
* whichever account it came from) — a result that made no request (a compaction with nothing to compact, a local
|
|
59
|
+
* command) costs nothing and proves nothing.
|
|
60
|
+
*/
|
|
61
|
+
export declare function getClaudeTurnCostOutcome(input: {
|
|
62
|
+
billing: ClaudeProfileBilling | null;
|
|
63
|
+
isCreditExhausted: boolean;
|
|
64
|
+
isError: boolean;
|
|
65
|
+
turnCostUsd: number | null;
|
|
66
|
+
}): ClaudeTurnCostOutcome;
|
|
67
|
+
/** The account's spend after a turn that cost `turnCostUsd` at `atIso` (the first counted turn opens `since`). */
|
|
68
|
+
export declare function addClaudeApiSpend(previous: ClaudeApiSpend | undefined, turnCostUsd: number, atIso: string): ClaudeApiSpend;
|
|
69
|
+
/** `$12.34`; `<$0.01` for a positive amount under a cent; `$0.00` for none. */
|
|
70
|
+
export declare function formatUsd(amount: number): string;
|
|
71
|
+
/** The day a spend is counted since, in the instance zone: `23.10` (the year when it is not this one: `23.10.2025`). */
|
|
72
|
+
export declare function formatSpendSinceDay(sinceIso: string, timezone: string, nowMs: number): string;
|
|
73
|
+
//# sourceMappingURL=claudeApiSpend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeApiSpend.d.ts","sourceRoot":"","sources":["../../src/utils/claudeApiSpend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,6GAA6G;AAC7G,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,QAAQ,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GAAG,MAAM,GAAG,IAAI,CAMhB;AAED,iEAAiE;AACjE,MAAM,WAAW,qBAAqB;IACpC,mHAAmH;IACnH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,0GAA0G;IAC1G,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,qBAAqB,CAMxB;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAO1H;AAKD,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wHAAwH;AACxH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ7F"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description What an account billed to API credits (`utils/claudeProfiles.ts`, `billing: 'api'`) has spent through
|
|
4
|
+
* the bot, from the `total_cost_usd` of Claude's stream `result` frames (the json-stream backend; the tmux backend
|
|
5
|
+
* reports no figure).
|
|
6
|
+
*
|
|
7
|
+
* That figure is the CONVERSATION's running cost, not the turn's: Claude Code writes it into the transcript when its
|
|
8
|
+
* process exits and restores it on `--resume`, so a resumed process starts from the conversation's last saved total,
|
|
9
|
+
* and a subscription turn of the same conversation counts in it too (a notional figure). The turn's spend is therefore
|
|
10
|
+
* a DELTA, and only a turn on an API account adds to that account's spend. The first turn of a process the bot
|
|
11
|
+
* started is measured against the total that process restored (the adapter reads it from the transcript before the
|
|
12
|
+
* launch: `0` for a new conversation) — never against the last total the bot saw, which a turn the bot did not see
|
|
13
|
+
* (the tmux backend's, which reports none) or a process that died without its exit flush (the next one restores an
|
|
14
|
+
* OLDER total) makes wrong. Every later turn is measured against the last total the bot saw for that conversation (a
|
|
15
|
+
* per-topic baseline it keeps for every account, persisted, so an adopted process after a restart goes on from it).
|
|
16
|
+
*
|
|
17
|
+
* It is what the bot OBSERVED, not the organization's balance: reading that needs an Admin API key.
|
|
18
|
+
*
|
|
19
|
+
* Pure: the clock and the zone come from the caller.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.computeClaudeTurnCostUsd = computeClaudeTurnCostUsd;
|
|
23
|
+
exports.getClaudeTurnCostOutcome = getClaudeTurnCostOutcome;
|
|
24
|
+
exports.addClaudeApiSpend = addClaudeApiSpend;
|
|
25
|
+
exports.formatUsd = formatUsd;
|
|
26
|
+
exports.formatSpendSinceDay = formatSpendSinceDay;
|
|
27
|
+
/**
|
|
28
|
+
* @description The spend of the turn whose `result` reported `totalCostUsd` for `sessionId` (see the module). The first
|
|
29
|
+
* turn of a process the bot started (`startCostUsd` known) counts from the total that process restored; any other turn
|
|
30
|
+
* is the delta against the baseline of the same conversation, `null` (unknown) without one. A total BELOW the figure it
|
|
31
|
+
* is measured against means the CLI counted from zero (it restored nothing), so the total is the turn's.
|
|
32
|
+
*/
|
|
33
|
+
function computeClaudeTurnCostUsd(input) {
|
|
34
|
+
const { previous, totalCostUsd } = input;
|
|
35
|
+
const measuredFromUsd = input.startCostUsd ?? (previous?.sessionId === input.sessionId ? previous.totalCostUsd : null);
|
|
36
|
+
if (measuredFromUsd === null)
|
|
37
|
+
return null;
|
|
38
|
+
const delta = totalCostUsd - measuredFromUsd;
|
|
39
|
+
return delta >= 0 ? delta : totalCostUsd;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @description The effect of a turn's cost on its account: only an account billed to API credits has spend (a
|
|
43
|
+
* subscription's figure is notional), and only a positive, known cost adds to it. A turn that did not end on an error
|
|
44
|
+
* AND was billed proves the account works again, so it ends a used-up-credits mark on ANY account (the refusal marks
|
|
45
|
+
* whichever account it came from) — a result that made no request (a compaction with nothing to compact, a local
|
|
46
|
+
* command) costs nothing and proves nothing.
|
|
47
|
+
*/
|
|
48
|
+
function getClaudeTurnCostOutcome(input) {
|
|
49
|
+
const billedUsd = input.turnCostUsd !== null && input.turnCostUsd > 0 ? input.turnCostUsd : null;
|
|
50
|
+
return {
|
|
51
|
+
spendUsd: input.billing === 'api' ? billedUsd : null,
|
|
52
|
+
isCreditMarkCleared: input.isCreditExhausted && !input.isError && billedUsd !== null,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** The account's spend after a turn that cost `turnCostUsd` at `atIso` (the first counted turn opens `since`). */
|
|
56
|
+
function addClaudeApiSpend(previous, turnCostUsd, atIso) {
|
|
57
|
+
return {
|
|
58
|
+
totalUsd: (previous?.totalUsd ?? 0) + turnCostUsd,
|
|
59
|
+
since: previous?.since ?? atIso,
|
|
60
|
+
lastTurnUsd: turnCostUsd,
|
|
61
|
+
lastTurnAt: atIso,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Below a cent a figure reads as `<$0.01` rather than a misleading `$0.00`. */
|
|
65
|
+
const smallestShownUsd = 0.01;
|
|
66
|
+
/** `$12.34`; `<$0.01` for a positive amount under a cent; `$0.00` for none. */
|
|
67
|
+
function formatUsd(amount) {
|
|
68
|
+
if (amount > 0 && amount < smallestShownUsd)
|
|
69
|
+
return `<$${smallestShownUsd.toFixed(2)}`;
|
|
70
|
+
return `$${amount.toFixed(2)}`;
|
|
71
|
+
}
|
|
72
|
+
/** The day a spend is counted since, in the instance zone: `23.10` (the year when it is not this one: `23.10.2025`). */
|
|
73
|
+
function formatSpendSinceDay(sinceIso, timezone, nowMs) {
|
|
74
|
+
const at = Date.parse(sinceIso);
|
|
75
|
+
if (Number.isNaN(at))
|
|
76
|
+
return '?';
|
|
77
|
+
const read = (options, instant) => new Intl.DateTimeFormat('en-GB', { timeZone: timezone, ...options }).format(instant);
|
|
78
|
+
const day = `${read({ day: '2-digit' }, at)}.${read({ month: '2-digit' }, at)}`;
|
|
79
|
+
const year = read({ year: 'numeric' }, at);
|
|
80
|
+
return year === read({ year: 'numeric' }, nowMs) ? day : `${day}.${year}`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=claudeApiSpend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claudeApiSpend.js","sourceRoot":"","sources":["../../src/utils/claudeApiSpend.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,11 +54,16 @@ export declare function buildClaudeCompactHookSettings(command: string): {
|
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
56
|
/**
|
|
57
|
-
* @description Write the
|
|
58
|
-
*
|
|
59
|
-
* a concurrently starting session never reads a half-written file) so a changed
|
|
60
|
-
*
|
|
61
|
-
*
|
|
57
|
+
* @description Write the launch settings file and return the `--settings <path>` argument pair for a Claude
|
|
58
|
+
* launch under `configDir` (the account profile's directory, `null` = `~/.claude`). Rewritten on every launch
|
|
59
|
+
* (atomic rename, so a concurrently starting session never reads a half-written file) so a changed guidance
|
|
60
|
+
* reaches the next session.
|
|
61
|
+
*
|
|
62
|
+
* Only the LAST `--settings` a launch carries counts (probed on 2.1.304), so a profile that holds a pasted API key
|
|
63
|
+
* (`utils/claudeProfiles.ts`) gets ONE file of its own, in its directory: the hook plus the `apiKeyHelper` that
|
|
64
|
+
* reads the key. Every other launch shares the hook file in `dataDir`. A write failure of the shared file returns
|
|
65
|
+
* `[]` and only logs (the hook improves a summary, it must never stop an agent from starting); for a key profile
|
|
66
|
+
* the same settings go inline instead, so the account never loses its key to a full disk.
|
|
62
67
|
*/
|
|
63
|
-
export declare function prepareClaudeCompactHookFlags(dataDir: string): string[];
|
|
68
|
+
export declare function prepareClaudeCompactHookFlags(dataDir: string, configDir?: string | null): string[];
|
|
64
69
|
//# sourceMappingURL=claudeCompactHook.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudeCompactHook.d.ts","sourceRoot":"","sources":["../../src/utils/claudeCompactHook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"claudeCompactHook.d.ts","sourceRoot":"","sources":["../../src/utils/claudeCompactHook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAaH;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,6BAA6B,CAAC;AAE5E;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAOrD;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,CAET;AAED,6FAA6F;AAC7F,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG;IAC/D,KAAK,EAAE;QAAE,UAAU,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,SAAS,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CACtF,CAEA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,EAAE,CAaxG"}
|
|
@@ -33,6 +33,8 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
33
33
|
const path_1 = __importDefault(require("path"));
|
|
34
34
|
const compactOnIdle_1 = require("./compactOnIdle");
|
|
35
35
|
const tmuxExec_1 = require("./tmuxExec");
|
|
36
|
+
const claudeProfiles_1 = require("./claudeProfiles");
|
|
37
|
+
const claudeApiKeyHelper_1 = require("./claudeApiKeyHelper");
|
|
36
38
|
/**
|
|
37
39
|
* Name of the hook settings file inside `DATA_DIR`. ONE file shared by every
|
|
38
40
|
* session: its content is the same for all of them, and a session that outlives
|
|
@@ -67,22 +69,37 @@ function buildClaudeCompactHookSettings(command) {
|
|
|
67
69
|
return { hooks: { PreCompact: [{ hooks: [{ type: 'command', command }] }] } };
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
|
-
* @description Write the
|
|
71
|
-
*
|
|
72
|
-
* a concurrently starting session never reads a half-written file) so a changed
|
|
73
|
-
*
|
|
74
|
-
*
|
|
72
|
+
* @description Write the launch settings file and return the `--settings <path>` argument pair for a Claude
|
|
73
|
+
* launch under `configDir` (the account profile's directory, `null` = `~/.claude`). Rewritten on every launch
|
|
74
|
+
* (atomic rename, so a concurrently starting session never reads a half-written file) so a changed guidance
|
|
75
|
+
* reaches the next session.
|
|
76
|
+
*
|
|
77
|
+
* Only the LAST `--settings` a launch carries counts (probed on 2.1.304), so a profile that holds a pasted API key
|
|
78
|
+
* (`utils/claudeProfiles.ts`) gets ONE file of its own, in its directory: the hook plus the `apiKeyHelper` that
|
|
79
|
+
* reads the key. Every other launch shares the hook file in `dataDir`. A write failure of the shared file returns
|
|
80
|
+
* `[]` and only logs (the hook improves a summary, it must never stop an agent from starting); for a key profile
|
|
81
|
+
* the same settings go inline instead, so the account never loses its key to a full disk.
|
|
75
82
|
*/
|
|
76
|
-
function prepareClaudeCompactHookFlags(dataDir) {
|
|
77
|
-
const settingsPath = path_1.default.join(dataDir, exports.claudeCompactHookSettingsFileName);
|
|
83
|
+
function prepareClaudeCompactHookFlags(dataDir, configDir = null) {
|
|
78
84
|
const command = buildPreCompactHookCommand({
|
|
79
85
|
instruction: getHookCompactionInstruction(),
|
|
80
86
|
alreadySentMarker: compactOnIdle_1.compactionSkillsGuidance,
|
|
81
87
|
});
|
|
88
|
+
const hookSettings = buildClaudeCompactHookSettings(command);
|
|
89
|
+
if (configDir !== null && (0, claudeProfiles_1.checkHasClaudeProfileApiKey)(configDir)) {
|
|
90
|
+
const settings = { ...hookSettings, ...(0, claudeApiKeyHelper_1.buildClaudeApiKeyHelperSettings)(configDir) };
|
|
91
|
+
const written = writeLaunchSettingsFile(configDir, path_1.default.join(configDir, claudeProfiles_1.claudeProfileLaunchSettingsFileName), settings);
|
|
92
|
+
return ['--settings', written ?? JSON.stringify(settings)];
|
|
93
|
+
}
|
|
94
|
+
const written = writeLaunchSettingsFile(dataDir, path_1.default.join(dataDir, exports.claudeCompactHookSettingsFileName), hookSettings);
|
|
95
|
+
return written === null ? [] : ['--settings', written];
|
|
96
|
+
}
|
|
97
|
+
/** Write `settings` to `settingsPath` atomically (`0600`); the path, or `null` when the write failed (logged). */
|
|
98
|
+
function writeLaunchSettingsFile(dir, settingsPath, settings) {
|
|
82
99
|
const tmpPath = `${settingsPath}.${process.pid}.${Date.now()}.tmp`;
|
|
83
100
|
try {
|
|
84
|
-
fs_1.default.mkdirSync(
|
|
85
|
-
fs_1.default.writeFileSync(tmpPath, JSON.stringify(
|
|
101
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
102
|
+
fs_1.default.writeFileSync(tmpPath, JSON.stringify(settings), { mode: 0o600 });
|
|
86
103
|
fs_1.default.renameSync(tmpPath, settingsPath);
|
|
87
104
|
}
|
|
88
105
|
catch (e) {
|
|
@@ -91,8 +108,8 @@ function prepareClaudeCompactHookFlags(dataDir) {
|
|
|
91
108
|
fs_1.default.unlinkSync(tmpPath);
|
|
92
109
|
}
|
|
93
110
|
catch { /* never written */ }
|
|
94
|
-
return
|
|
111
|
+
return null;
|
|
95
112
|
}
|
|
96
|
-
return
|
|
113
|
+
return settingsPath;
|
|
97
114
|
}
|
|
98
115
|
//# sourceMappingURL=claudeCompactHook.js.map
|