@cortexkit/anthropic-auth-core 1.23.0 → 2.0.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.
Files changed (134) hide show
  1. package/README.md +2 -0
  2. package/dist/accounts.d.ts +3 -16
  3. package/dist/cachekeep.d.ts +9 -0
  4. package/dist/claude-code.d.ts +16 -0
  5. package/dist/claustrum-enrollment.d.ts +2 -0
  6. package/dist/claustrum-scoped-roster.d.ts +4 -0
  7. package/dist/claustrum-scoped-runtime.d.ts +3 -0
  8. package/dist/claustrum-scoped.d.ts +14 -0
  9. package/dist/claustrum.d.ts +0 -209
  10. package/dist/commands/account.d.ts +2 -3
  11. package/dist/index.d.ts +44 -1
  12. package/dist/index.js +29700 -38
  13. package/dist/internal-types/LICENSE +21 -0
  14. package/dist/internal-types/commands/builtins.d.ts +71 -0
  15. package/dist/internal-types/commands/index.d.ts +10 -0
  16. package/dist/internal-types/commands/menu.d.ts +61 -0
  17. package/dist/internal-types/commands/model.d.ts +238 -0
  18. package/dist/internal-types/commands/pi.d.ts +23 -0
  19. package/dist/internal-types/commands/seam.d.ts +72 -0
  20. package/dist/internal-types/fs/refresh-file-lock.d.ts +33 -0
  21. package/dist/internal-types/logger/capture-sink.d.ts +14 -0
  22. package/dist/internal-types/logger/engine.d.ts +100 -0
  23. package/dist/internal-types/logger/index.d.ts +6 -0
  24. package/dist/internal-types/logger/redact.d.ts +11 -0
  25. package/dist/internal-types/pi-slot/index.d.ts +3 -0
  26. package/dist/internal-types/pi-slot/slot.d.ts +49 -0
  27. package/dist/internal-types/quota/codec.d.ts +11 -0
  28. package/dist/internal-types/quota/format.d.ts +46 -0
  29. package/dist/internal-types/quota/index.d.ts +10 -0
  30. package/dist/internal-types/quota/map.d.ts +63 -0
  31. package/dist/internal-types/quota/merge.d.ts +48 -0
  32. package/dist/internal-types/quota/projection.d.ts +64 -0
  33. package/dist/internal-types/store/attribution.d.ts +28 -0
  34. package/dist/internal-types/store/errors.d.ts +55 -0
  35. package/dist/internal-types/store/hooks.d.ts +12 -0
  36. package/dist/internal-types/store/identity.d.ts +39 -0
  37. package/dist/internal-types/store/index.d.ts +21 -0
  38. package/dist/internal-types/store/mutate.d.ts +189 -0
  39. package/dist/internal-types/store/pool.d.ts +196 -0
  40. package/dist/internal-types/store/provider-state.d.ts +131 -0
  41. package/dist/internal-types/store/publication.d.ts +47 -0
  42. package/dist/internal-types/store/pull.d.ts +36 -0
  43. package/dist/internal-types/store/refresh-lock.d.ts +63 -0
  44. package/dist/internal-types/store/refresh.d.ts +72 -0
  45. package/dist/internal-types/store/rows.d.ts +313 -0
  46. package/dist/internal-types/store/runtime.d.ts +36 -0
  47. package/dist/internal-types/store/schema.d.ts +443 -0
  48. package/dist/internal-types/store/settings.d.ts +63 -0
  49. package/dist/internal-types/store/torn.d.ts +78 -0
  50. package/dist/migration-source.d.ts +33 -0
  51. package/dist/models.d.ts +41 -0
  52. package/dist/native-account-runtime.d.ts +121 -0
  53. package/dist/native-account-view.d.ts +126 -0
  54. package/dist/native-command-effects.d.ts +59 -0
  55. package/dist/native-credential-validation.d.ts +42 -0
  56. package/dist/native-custody-activation.d.ts +45 -0
  57. package/dist/native-custody.d.ts +114 -0
  58. package/dist/native-enrollment-authority.d.ts +2 -0
  59. package/dist/native-host-auth-read.d.ts +3 -0
  60. package/dist/native-host-auth-write.d.ts +51 -0
  61. package/dist/native-host-auth.d.ts +12 -0
  62. package/dist/native-local-credential-service.d.ts +76 -0
  63. package/dist/native-local-runtime-readers.d.ts +22 -0
  64. package/dist/native-lock-observer.d.ts +12 -0
  65. package/dist/native-menu-executor.d.ts +243 -0
  66. package/dist/native-menu-model.d.ts +142 -0
  67. package/dist/native-migration-proof.d.ts +28 -0
  68. package/dist/native-migration-source.d.ts +47 -0
  69. package/dist/native-migration.d.ts +66 -0
  70. package/dist/native-quota-codec.d.ts +32 -0
  71. package/dist/native-refresh-coordinator.d.ts +240 -0
  72. package/dist/native-roster-seed.d.ts +115 -0
  73. package/dist/native-runtime-registry.d.ts +19 -0
  74. package/dist/native-runtime.d.ts +204 -0
  75. package/dist/native-transient-account.d.ts +38 -0
  76. package/dist/native-ui.d.ts +45 -0
  77. package/dist/native-usage-publication.d.ts +11 -0
  78. package/dist/native-vault-admission.d.ts +8 -0
  79. package/dist/native-vault-connection.d.ts +33 -0
  80. package/dist/native-vault-paths.d.ts +13 -0
  81. package/dist/native-vault-runtime.d.ts +102 -0
  82. package/dist/native-vault-seed.d.ts +16 -0
  83. package/dist/pool-authority.d.ts +159 -0
  84. package/dist/pool-binding.d.ts +32 -0
  85. package/dist/pool-paths.d.ts +21 -0
  86. package/dist/pool-store.d.ts +32 -0
  87. package/dist/provider-error.d.ts +139 -0
  88. package/dist/quota-manager.d.ts +18 -7
  89. package/dist/relay.d.ts +14 -1
  90. package/dist/request-history.d.ts +34 -0
  91. package/dist/sse.d.ts +81 -0
  92. package/dist/sticky-routing.d.ts +27 -0
  93. package/package.json +9 -4
  94. package/dist/accounts.js +0 -3881
  95. package/dist/auth.js +0 -185
  96. package/dist/cache1h.js +0 -97
  97. package/dist/cachekeep-registry.js +0 -124
  98. package/dist/cachekeep.js +0 -604
  99. package/dist/cch.js +0 -172
  100. package/dist/claude-code.js +0 -403
  101. package/dist/claustrum-enrollment-registry.d.ts +0 -17
  102. package/dist/claustrum-enrollment-registry.js +0 -194
  103. package/dist/claustrum-enrollment.js +0 -485
  104. package/dist/claustrum-scoped-roster.js +0 -194
  105. package/dist/claustrum-scoped-runtime.js +0 -230
  106. package/dist/claustrum-scoped.js +0 -193
  107. package/dist/claustrum.js +0 -1471
  108. package/dist/commands/account.js +0 -368
  109. package/dist/constants.js +0 -83
  110. package/dist/custom-headers.js +0 -102
  111. package/dist/dump.js +0 -616
  112. package/dist/fast.js +0 -66
  113. package/dist/json.js +0 -10
  114. package/dist/killswitch.js +0 -132
  115. package/dist/logger.js +0 -288
  116. package/dist/logging.js +0 -59
  117. package/dist/mid-conversation-output-config.js +0 -89
  118. package/dist/model-remap.js +0 -72
  119. package/dist/models.js +0 -177
  120. package/dist/network-errors.js +0 -27
  121. package/dist/oauth-profile.js +0 -60
  122. package/dist/pkce.js +0 -17
  123. package/dist/prime.js +0 -841
  124. package/dist/provider.js +0 -0
  125. package/dist/quota-header-feed.js +0 -331
  126. package/dist/quota-headers.js +0 -121
  127. package/dist/quota-manager.js +0 -856
  128. package/dist/quotas.js +0 -141
  129. package/dist/relay.js +0 -1303
  130. package/dist/routing.js +0 -94
  131. package/dist/start.js +0 -29
  132. package/dist/sticky-routing.js +0 -541
  133. package/dist/thinking-binding.js +0 -54
  134. package/dist/token-fingerprint.js +0 -8
@@ -1,132 +0,0 @@
1
- import { DEFAULT_KILLSWITCH_THRESHOLDS as DEFAULT_THRESHOLDS, normalizeKillswitchThresholds, } from './accounts.js';
2
- export const KILLSWITCH_COMMAND_NAME = 'claude-killswitch';
3
- export function parseKillswitchCommandAction(argumentsText) {
4
- const parts = argumentsText.trim().split(/\s+/).filter(Boolean);
5
- if (parts.length === 0)
6
- return { type: 'status' };
7
- if (parts.length === 1 && parts[0] === 'on')
8
- return { type: 'on' };
9
- if (parts.length === 1 && parts[0] === 'off')
10
- return { type: 'off' };
11
- if (parts[0] === 'set') {
12
- const entries = [];
13
- for (let i = 1; i < parts.length; i++) {
14
- const match = parts[i]?.match(/^([^:]+):(\d+),(\d+)(?:,(\d+))?$/);
15
- if (!match)
16
- return { type: 'usage' };
17
- const [, account, fhStr, sdStr, scopedStr] = match;
18
- const scoped = typeof scopedStr === 'string' && scopedStr.length > 0
19
- ? Number.parseInt(scopedStr, 10)
20
- : undefined;
21
- const entry = {
22
- account,
23
- fh: Number.parseInt(fhStr, 10),
24
- sd: Number.parseInt(sdStr, 10),
25
- };
26
- if (scoped !== undefined)
27
- entry.scoped = scoped;
28
- entries.push(entry);
29
- }
30
- if (entries.length === 0)
31
- return { type: 'usage' };
32
- return { type: 'set', entries };
33
- }
34
- return { type: 'usage' };
35
- }
36
- function buildStatusTable(config, accountIds) {
37
- const enabled = config.enabled === true;
38
- const lines = [
39
- '## Killswitch',
40
- '',
41
- `Status: **${enabled ? 'ON' : 'OFF'}**`,
42
- ];
43
- if (enabled) {
44
- lines.push('');
45
- lines.push('| Account | 5h threshold | 1w threshold | Scoped |');
46
- lines.push('| ------- | ------------ | ------------ | ------ |');
47
- const mainT = normalizeKillswitchThresholds(config.main);
48
- lines.push(`| main | \u2265 ${mainT.five_hour}% | \u2265 ${mainT.seven_day}% | \u2264 ${mainT.scoped}% |`);
49
- for (const id of accountIds) {
50
- const t = normalizeKillswitchThresholds(config.accounts?.[id] ?? config.main);
51
- lines.push(`| ${id} | \u2265 ${t.five_hour}% | \u2265 ${t.seven_day}% | \u2264 ${t.scoped}% |`);
52
- }
53
- }
54
- return lines.join('\n');
55
- }
56
- const USAGE_TEXT = [
57
- '## Killswitch Commands',
58
- '',
59
- '```',
60
- `/${KILLSWITCH_COMMAND_NAME} — show status`,
61
- `/${KILLSWITCH_COMMAND_NAME} on — enable with current or default thresholds`,
62
- `/${KILLSWITCH_COMMAND_NAME} off — disable`,
63
- `/${KILLSWITCH_COMMAND_NAME} set all:5,10 — set all accounts to 5h≥5%, 1w≥10%`,
64
- `/${KILLSWITCH_COMMAND_NAME} set main:3,8,0 — set 5h≥3%, 1w≥8%, scoped≤0%`,
65
- `/${KILLSWITCH_COMMAND_NAME} set main:3,8 work-alt:5,10 — per-account`,
66
- '```',
67
- ].join('\n');
68
- export function executeKillswitchCommand(input) {
69
- const action = parseKillswitchCommandAction(input.argumentsText);
70
- if (action.type === 'status') {
71
- const status = buildStatusTable(input.config, input.accountIds);
72
- return { text: `${status}\n\n${USAGE_TEXT}` };
73
- }
74
- if (action.type === 'on') {
75
- const updated = {
76
- ...input.config,
77
- enabled: true,
78
- main: input.config.main ?? {
79
- five_hour: DEFAULT_THRESHOLDS.five_hour,
80
- seven_day: DEFAULT_THRESHOLDS.seven_day,
81
- },
82
- };
83
- const status = buildStatusTable(updated, input.accountIds);
84
- return {
85
- text: `## Killswitch Enabled\n\n${status}`,
86
- updatedConfig: updated,
87
- };
88
- }
89
- if (action.type === 'off') {
90
- const updated = { ...input.config, enabled: false };
91
- return {
92
- text: '## Killswitch Disabled',
93
- updatedConfig: updated,
94
- };
95
- }
96
- if (action.type === 'set') {
97
- const accounts = { ...(input.config.accounts ?? {}) };
98
- const updated = {
99
- ...input.config,
100
- enabled: true,
101
- accounts,
102
- };
103
- for (const entry of action.entries) {
104
- const thresholds = {
105
- five_hour: entry.fh,
106
- seven_day: entry.sd,
107
- };
108
- if (entry.scoped !== undefined)
109
- thresholds.scoped = entry.scoped;
110
- if (entry.account === 'main') {
111
- updated.main = thresholds;
112
- }
113
- else if (entry.account === 'all') {
114
- updated.main = thresholds;
115
- for (const id of input.accountIds) {
116
- accounts[id] = thresholds;
117
- }
118
- }
119
- else {
120
- accounts[entry.account] = thresholds;
121
- }
122
- }
123
- const status = buildStatusTable(updated, input.accountIds);
124
- return {
125
- text: `## Killswitch Updated\n\n${status}`,
126
- updatedConfig: updated,
127
- };
128
- }
129
- // usage
130
- const status = buildStatusTable(input.config, input.accountIds);
131
- return { text: `${status}\n\n${USAGE_TEXT}` };
132
- }
package/dist/logger.js DELETED
@@ -1,288 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as os from 'node:os';
3
- import * as path from 'node:path';
4
- import { CUSTODY_HANDLE_PATTERN } from './constants.js';
5
- const LEVEL_ORDER = {
6
- error: 0,
7
- warn: 1,
8
- info: 2,
9
- debug: 3,
10
- trace: 4,
11
- };
12
- const VALID_LEVELS = new Set(Object.keys(LEVEL_ORDER));
13
- function parseLogLevel(value) {
14
- if (!value)
15
- return null;
16
- const normalized = value.trim().toLowerCase();
17
- return VALID_LEVELS.has(normalized) ? normalized : null;
18
- }
19
- const envLevel = parseLogLevel(process.env.OPENCODE_ANTHROPIC_AUTH_LOG_LEVEL);
20
- let currentLevel = envLevel ?? 'info';
21
- export function setLogLevel(level) {
22
- currentLevel = level;
23
- }
24
- export function getLogLevel() {
25
- return currentLevel;
26
- }
27
- export { parseLogLevel };
28
- // -- Emission control ------------------------------------------------------
29
- export function shouldEmit(level) {
30
- return LEVEL_ORDER[level] <= LEVEL_ORDER[currentLevel];
31
- }
32
- // -- File path -------------------------------------------------------------
33
- const LOG_FILE = process.env.OPENCODE_ANTHROPIC_AUTH_LOG_FILE ??
34
- path.join(os.tmpdir(), 'opencode-anthropic-auth.log');
35
- export function getLogFilePath() {
36
- return LOG_FILE;
37
- }
38
- // -- Rotation --------------------------------------------------------------
39
- const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB
40
- const MAX_GENERATIONS = 3;
41
- function rotateLogFile() {
42
- try {
43
- if (!fs.existsSync(LOG_FILE))
44
- return;
45
- const stat = fs.statSync(LOG_FILE);
46
- if (stat.size < MAX_FILE_SIZE)
47
- return;
48
- }
49
- catch {
50
- return;
51
- }
52
- try {
53
- for (let i = MAX_GENERATIONS; i >= 1; i--) {
54
- const oldPath = i === 1 ? LOG_FILE : `${LOG_FILE}.${i - 1}`;
55
- const newPath = `${LOG_FILE}.${i}`;
56
- try {
57
- if (i === MAX_GENERATIONS) {
58
- try {
59
- fs.unlinkSync(newPath);
60
- }
61
- catch {
62
- // .3 might not exist
63
- }
64
- }
65
- if (fs.existsSync(oldPath)) {
66
- fs.renameSync(oldPath, newPath);
67
- }
68
- }
69
- catch {
70
- // Rotation best-effort — never throw
71
- }
72
- }
73
- }
74
- catch {
75
- // Rotation must never throw
76
- }
77
- }
78
- // -- Redaction ------------------------------------------------------------
79
- export const SECRET_KEY_EXACT = /^(authorization|x-api-key|cookie|set-cookie|refresh|access|token|handle)$/i;
80
- export function isSecretKey(key) {
81
- if (SECRET_KEY_EXACT.test(key))
82
- return true;
83
- const k = key.toLowerCase().replace(/[-_]/g, '');
84
- if (k.includes('apikey'))
85
- return true;
86
- if (k.endsWith('secret') || k.endsWith('password'))
87
- return true;
88
- if (k.endsWith('token') && !k.endsWith('tokens'))
89
- return true;
90
- return false;
91
- }
92
- const REDACT_VALUE_PATTERNS = [
93
- /Bearer\s+\S+/,
94
- /sk-[A-Za-z0-9-]+/,
95
- /eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/,
96
- CUSTODY_HANDLE_PATTERN,
97
- ];
98
- function isRedactableValue(value) {
99
- if (typeof value !== 'string')
100
- return false;
101
- return REDACT_VALUE_PATTERNS.some((pattern) => pattern.test(value));
102
- }
103
- export function redactPayload(payload) {
104
- if (payload == null || Object.keys(payload).length === 0)
105
- return undefined;
106
- const seen = new WeakSet();
107
- function walk(value) {
108
- if (value == null || typeof value !== 'object') {
109
- if (isRedactableValue(value))
110
- return '***REDACTED***';
111
- return value;
112
- }
113
- if (seen.has(value))
114
- return '[Circular]';
115
- seen.add(value);
116
- try {
117
- if (Array.isArray(value))
118
- return value.map(walk);
119
- const obj = value;
120
- const result = {};
121
- for (const [key, entry] of Object.entries(obj)) {
122
- if (isSecretKey(key)) {
123
- result[key] = '***REDACTED***';
124
- continue;
125
- }
126
- result[key] = walk(entry);
127
- }
128
- return result;
129
- }
130
- finally {
131
- seen.delete(value);
132
- }
133
- }
134
- return walk(payload);
135
- }
136
- // -- Line formatting ------------------------------------------------------
137
- export function formatLogLine(level, channel, message, payload) {
138
- const now = new Date().toISOString();
139
- const levelUpper = level.toUpperCase().padEnd(5);
140
- const channelSegment = channel ? ` [${channel}]` : '';
141
- const payloadJson = (() => {
142
- try {
143
- const redacted = redactPayload(payload);
144
- const withPid = redacted
145
- ? { ...redacted, pid: process.pid }
146
- : { pid: process.pid };
147
- return ` ${JSON.stringify(withPid)}`;
148
- }
149
- catch {
150
- return ` {"pid":${process.pid},"payload":"[unserializable]"}`;
151
- }
152
- })();
153
- return `[${now}] ${levelUpper}${channelSegment} ${message}${payloadJson}`;
154
- }
155
- let testSink = null;
156
- export function __setLogTestSink(sink) {
157
- testSink = sink;
158
- }
159
- // -- Leveled API ----------------------------------------------------------
160
- function emit(level, channel, message, payload) {
161
- if (!shouldEmit(level))
162
- return;
163
- if (testSink) {
164
- try {
165
- testSink({ level, channel, message, payload: redactPayload(payload) });
166
- }
167
- catch {
168
- // Sink must never throw into production.
169
- }
170
- }
171
- if (isTestEnv)
172
- return;
173
- try {
174
- const line = `${formatLogLine(level, channel, message, payload)}\n`;
175
- buffer.push(line);
176
- if (buffer.length >= BUFFER_SIZE_LIMIT) {
177
- flush();
178
- }
179
- else {
180
- scheduleFlush();
181
- }
182
- }
183
- catch {
184
- // Logging must never throw.
185
- }
186
- }
187
- export const logger = {
188
- error(channel, message, payload) {
189
- emit('error', channel, message, payload);
190
- },
191
- warn(channel, message, payload) {
192
- emit('warn', channel, message, payload);
193
- },
194
- info(channel, message, payload) {
195
- emit('info', channel, message, payload);
196
- },
197
- debug(channel, message, payload) {
198
- emit('debug', channel, message, payload);
199
- },
200
- trace(channel, message, payload) {
201
- emit('trace', channel, message, payload);
202
- },
203
- };
204
- // -- Buffered writes ------------------------------------------------------
205
- const isTestEnv = process.env.NODE_ENV === 'test';
206
- const FLUSH_INTERVAL_MS = 500;
207
- const BUFFER_SIZE_LIMIT = 50;
208
- let buffer = [];
209
- let flushTimer = null;
210
- function flush() {
211
- if (flushTimer) {
212
- clearTimeout(flushTimer);
213
- flushTimer = null;
214
- }
215
- if (buffer.length === 0)
216
- return;
217
- const data = buffer.join('');
218
- buffer = [];
219
- try {
220
- rotateLogFile();
221
- fs.appendFileSync(LOG_FILE, data);
222
- }
223
- catch {
224
- // Logging must never throw.
225
- }
226
- }
227
- function scheduleFlush() {
228
- if (flushTimer)
229
- return;
230
- flushTimer = setTimeout(() => {
231
- flushTimer = null;
232
- flush();
233
- }, FLUSH_INTERVAL_MS);
234
- }
235
- // -- Back-compat shims ----------------------------------------------------
236
- const CHANNEL_REGEX = /^\[([\w-]+)\]\s*/;
237
- export function log(message, data) {
238
- if (!shouldEmit('debug'))
239
- return;
240
- if (isTestEnv)
241
- return;
242
- try {
243
- let channel = '';
244
- let msg = message;
245
- const match = message.match(CHANNEL_REGEX);
246
- if (match) {
247
- channel = match[1] ?? '';
248
- msg = message.slice(match[0].length);
249
- }
250
- let payload;
251
- if (data != null) {
252
- if (data instanceof Error) {
253
- payload = {
254
- error: `${data.message}${data.stack ? `\n${data.stack}` : ''}`,
255
- };
256
- }
257
- else if (typeof data === 'object') {
258
- payload = data;
259
- }
260
- }
261
- emit('debug', channel, msg, payload);
262
- }
263
- catch {
264
- // Logging must never throw.
265
- }
266
- }
267
- export function relayLog(message, data) {
268
- if (!shouldEmit('debug'))
269
- return;
270
- if (isTestEnv)
271
- return;
272
- try {
273
- let payload;
274
- if (data != null) {
275
- if (typeof data === 'object' && !(data instanceof Error)) {
276
- payload = data;
277
- }
278
- }
279
- emit('debug', 'relay', message, payload);
280
- }
281
- catch {
282
- // Logging must never throw.
283
- }
284
- }
285
- // -- Exit flush -----------------------------------------------------------
286
- if (!isTestEnv) {
287
- process.on('exit', flush);
288
- }
package/dist/logging.js DELETED
@@ -1,59 +0,0 @@
1
- // Known limitation: the TUI bundle is a SEPARATE module instance from the loader,
2
- // so /claude-logging sets the SERVER-side (loader) logger level and persists it
3
- // (applied on next boot); the TUI-side logger level is only raised via the
4
- // OPENCODE_ANTHROPIC_AUTH_LOG_LEVEL env override. The command still correctly
5
- // persists and applies server-side — just note this asymmetry.
6
- export const CLAUDE_LOGGING_COMMAND_NAME = 'claude-logging';
7
- export const LOGGING_LEVELS = [
8
- 'error',
9
- 'warn',
10
- 'info',
11
- 'debug',
12
- 'trace',
13
- ];
14
- const LOGGING_USAGE = 'Usage: `/claude-logging`, `/claude-logging error|warn|info|debug|trace`.';
15
- export function parseLoggingCommandAction(argumentsText) {
16
- const tokens = argumentsText.trim().toLowerCase().split(/\s+/).filter(Boolean);
17
- if (tokens.length === 0)
18
- return { type: 'status' };
19
- if (tokens.length === 1 && LOGGING_LEVELS.includes(tokens[0])) {
20
- return { type: 'level', level: tokens[0] };
21
- }
22
- return { type: 'usage' };
23
- }
24
- export function buildLoggingStatusSummary(input) {
25
- const level = input?.level ?? 'info';
26
- return [
27
- '## Claude Log Level',
28
- '',
29
- `Current log level: \`${level}\``,
30
- '- Persisted: ~/.config/opencode/anthropic-auth.json',
31
- '- Valid levels: error, warn, info, debug, trace',
32
- '',
33
- LOGGING_USAGE,
34
- ].join('\n');
35
- }
36
- export function executeLoggingCommand(input) {
37
- const action = parseLoggingCommandAction(input.argumentsText);
38
- const level = input.level ?? 'info';
39
- if (action.type === 'status')
40
- return buildLoggingStatusSummary({ level });
41
- if (action.type === 'level') {
42
- return [
43
- '## Claude Log Level Updated',
44
- '',
45
- `Level set to \`${action.level}\`.`,
46
- '',
47
- ...buildLoggingStatusSummary({ level: action.level })
48
- .split('\n')
49
- .slice(2),
50
- ].join('\n');
51
- }
52
- return [
53
- '## Claude Log Level Usage',
54
- '',
55
- LOGGING_USAGE,
56
- '',
57
- ...buildLoggingStatusSummary({ level }).split('\n').slice(2),
58
- ].join('\n');
59
- }
@@ -1,89 +0,0 @@
1
- import { isClaudeFable51Model } from './models.js';
2
- export const MID_CONVERSATION_OUTPUT_CONFIG_BETA = 'mid-conversation-output-config-2026-07-01';
3
- function isRecord(value) {
4
- return typeof value === 'object' && value !== null && !Array.isArray(value);
5
- }
6
- export function normalizeAdaptiveEffort(value) {
7
- if (value === 'minimal')
8
- return 'low';
9
- if (value === 'low' ||
10
- value === 'medium' ||
11
- value === 'high' ||
12
- value === 'xhigh' ||
13
- value === 'max') {
14
- return value;
15
- }
16
- return undefined;
17
- }
18
- export function usesMidConversationOutputConfig(body) {
19
- return isClaudeFable51Model(body.model);
20
- }
21
- function compactTransitions(transitions) {
22
- const compacted = [];
23
- for (const transition of transitions) {
24
- if (!Number.isSafeInteger(transition.afterAssistantMessages) ||
25
- transition.afterAssistantMessages < 0 ||
26
- !normalizeAdaptiveEffort(transition.effort)) {
27
- continue;
28
- }
29
- const normalized = {
30
- afterAssistantMessages: transition.afterAssistantMessages,
31
- effort: transition.effort,
32
- };
33
- const previous = compacted.at(-1);
34
- if (previous &&
35
- previous.afterAssistantMessages === normalized.afterAssistantMessages) {
36
- previous.effort = normalized.effort;
37
- continue;
38
- }
39
- if (previous?.effort === normalized.effort)
40
- continue;
41
- compacted.push(normalized);
42
- }
43
- return compacted;
44
- }
45
- export function applyMidConversationOutputConfig(body, transitions) {
46
- if (!usesMidConversationOutputConfig(body) || !Array.isArray(body.messages)) {
47
- return { applied: false, inserted: 0 };
48
- }
49
- const compacted = compactTransitions(transitions);
50
- const currentOutputConfig = isRecord(body.output_config)
51
- ? body.output_config
52
- : {};
53
- const baseline = compacted[0]?.effort ??
54
- normalizeAdaptiveEffort(currentOutputConfig.effort) ??
55
- 'high';
56
- body.output_config = { ...currentOutputConfig, effort: baseline };
57
- if (compacted.length < 2)
58
- return { applied: true, inserted: 0 };
59
- const messages = body.messages;
60
- const transitionsByBoundary = new Map();
61
- for (const transition of compacted.slice(1)) {
62
- transitionsByBoundary.set(transition.afterAssistantMessages, transition.effort);
63
- }
64
- let assistantMessages = 0;
65
- let activeEffort = baseline;
66
- let inserted = 0;
67
- const rewritten = [];
68
- for (const message of messages) {
69
- if (isRecord(message) &&
70
- message.role === 'user' &&
71
- transitionsByBoundary.has(assistantMessages)) {
72
- const effort = transitionsByBoundary.get(assistantMessages);
73
- if (effort && effort !== activeEffort) {
74
- rewritten.push({
75
- role: 'system',
76
- content: [],
77
- output_config: { effort },
78
- });
79
- activeEffort = effort;
80
- inserted++;
81
- }
82
- }
83
- rewritten.push(message);
84
- if (isRecord(message) && message.role === 'assistant')
85
- assistantMessages++;
86
- }
87
- body.messages = rewritten;
88
- return { applied: true, inserted };
89
- }
@@ -1,72 +0,0 @@
1
- /**
2
- * Remap canonical Claude model IDs to proxy-compatible names
3
- * using ANTHROPIC_DEFAULT_*_MODEL env vars.
4
- *
5
- * LiteLLM/proxy backends often use shorter model aliases
6
- * (e.g. `claude-sonnet-4-6` instead of `claude-sonnet-4-20250514`).
7
- * These proxy-route variables follow the Claude Code convention, except
8
- * ANTHROPIC_DEFAULT_FABLE_MODEL, which is plugin-specific:
9
- *
10
- * ANTHROPIC_MODEL — default for any claude-* model
11
- * ANTHROPIC_DEFAULT_SONNET_MODEL — models matching claude-sonnet-*
12
- * ANTHROPIC_DEFAULT_OPUS_MODEL — models matching claude-opus-*
13
- * ANTHROPIC_DEFAULT_HAIKU_MODEL — models matching claude-haiku-*
14
- * ANTHROPIC_DEFAULT_FABLE_MODEL — models matching claude-fable / claude-mythos
15
- *
16
- * Tier-specific vars take precedence over the generic ANTHROPIC_MODEL.
17
- */
18
- function getEnv(name) {
19
- const value = process.env[name]?.trim();
20
- return value || undefined;
21
- }
22
- function getModelTier(model) {
23
- if (/^claude-sonnet(?:-|$)/.test(model))
24
- return 'sonnet';
25
- if (/^claude-opus(?:-|$)/.test(model))
26
- return 'opus';
27
- if (/^claude-haiku(?:-|$)/.test(model))
28
- return 'haiku';
29
- if (/^claude-(?:fable|mythos)(?:-|$)/.test(model))
30
- return 'fable';
31
- return null;
32
- }
33
- const TIER_ENV_MAP = {
34
- sonnet: 'ANTHROPIC_DEFAULT_SONNET_MODEL',
35
- opus: 'ANTHROPIC_DEFAULT_OPUS_MODEL',
36
- haiku: 'ANTHROPIC_DEFAULT_HAIKU_MODEL',
37
- fable: 'ANTHROPIC_DEFAULT_FABLE_MODEL',
38
- };
39
- /**
40
- * Resolve a canonical model ID to its proxy-compatible alias.
41
- * Returns the original model when no env override is configured.
42
- */
43
- export function remapModelId(model) {
44
- if (typeof model !== 'string' || !model)
45
- return model;
46
- const tier = getModelTier(model);
47
- if (tier) {
48
- const tierModel = getEnv(TIER_ENV_MAP[tier]);
49
- if (tierModel)
50
- return tierModel;
51
- }
52
- // Generic fallback for any claude-* model
53
- if (model.startsWith('claude-')) {
54
- const defaultModel = getEnv('ANTHROPIC_MODEL');
55
- if (defaultModel)
56
- return defaultModel;
57
- }
58
- return model;
59
- }
60
- /**
61
- * Remap the `model` field in a parsed request body in place.
62
- * Returns true if the model was changed.
63
- */
64
- export function remapRequestBodyModel(parsed) {
65
- if (typeof parsed.model !== 'string')
66
- return false;
67
- const remapped = remapModelId(parsed.model);
68
- if (remapped === parsed.model)
69
- return false;
70
- parsed.model = remapped;
71
- return true;
72
- }