feat: rebrand as Open Claude and harden OpenAI REPL
This commit is contained in:
@@ -52,8 +52,11 @@ const result = await Bun.build({
|
|||||||
naming: 'cli.mjs',
|
naming: 'cli.mjs',
|
||||||
define: {
|
define: {
|
||||||
// MACRO.* build-time constants
|
// MACRO.* build-time constants
|
||||||
// Set version high enough to pass minimum version checks
|
// Keep the internal compatibility version high enough to pass
|
||||||
|
// first-party minimum-version guards, but expose the real package
|
||||||
|
// version separately in Open Claude branding.
|
||||||
'MACRO.VERSION': JSON.stringify('99.0.0'),
|
'MACRO.VERSION': JSON.stringify('99.0.0'),
|
||||||
|
'MACRO.DISPLAY_VERSION': JSON.stringify(version),
|
||||||
'MACRO.BUILD_TIME': JSON.stringify(new Date().toISOString()),
|
'MACRO.BUILD_TIME': JSON.stringify(new Date().toISOString()),
|
||||||
'MACRO.ISSUES_EXPLAINER':
|
'MACRO.ISSUES_EXPLAINER':
|
||||||
JSON.stringify('report the issue at https://github.com/anthropics/claude-code/issues'),
|
JSON.stringify('report the issue at https://github.com/anthropics/claude-code/issues'),
|
||||||
|
|||||||
@@ -33,42 +33,42 @@ type Segments = {
|
|||||||
};
|
};
|
||||||
const POSES: Record<ClawdPose, Segments> = {
|
const POSES: Record<ClawdPose, Segments> = {
|
||||||
default: {
|
default: {
|
||||||
r1L: ' ▐',
|
r1L: ' ╭',
|
||||||
r1E: '▛███▜',
|
r1E: '○ ○ ',
|
||||||
r1R: '▌',
|
r1R: '╮',
|
||||||
r2L: '▝▜',
|
r2L: ' │',
|
||||||
r2R: '▛▘'
|
r2R: '│ '
|
||||||
},
|
},
|
||||||
'look-left': {
|
'look-left': {
|
||||||
r1L: ' ▐',
|
r1L: ' ╭',
|
||||||
r1E: '▟███▟',
|
r1E: '◔ ○ ',
|
||||||
r1R: '▌',
|
r1R: '╮',
|
||||||
r2L: '▝▜',
|
r2L: ' │',
|
||||||
r2R: '▛▘'
|
r2R: '│ '
|
||||||
},
|
},
|
||||||
'look-right': {
|
'look-right': {
|
||||||
r1L: ' ▐',
|
r1L: ' ╭',
|
||||||
r1E: '▙███▙',
|
r1E: '○ ◔ ',
|
||||||
r1R: '▌',
|
r1R: '╮',
|
||||||
r2L: '▝▜',
|
r2L: ' │',
|
||||||
r2R: '▛▘'
|
r2R: '│ '
|
||||||
},
|
},
|
||||||
'arms-up': {
|
'arms-up': {
|
||||||
r1L: '▗▟',
|
r1L: '\\╭',
|
||||||
r1E: '▛███▜',
|
r1E: '○ ○ ',
|
||||||
r1R: '▙▖',
|
r1R: '╮/',
|
||||||
r2L: ' ▜',
|
r2L: ' │',
|
||||||
r2R: '▛ '
|
r2R: '│ '
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Apple Terminal uses a bg-fill trick (see below), so only eye poses make
|
// Apple Terminal uses a bg-fill trick (see below), so only eye poses make
|
||||||
// sense. Arm poses fall back to default.
|
// sense. Arm poses fall back to default.
|
||||||
const APPLE_EYES: Record<ClawdPose, string> = {
|
const APPLE_EYES: Record<ClawdPose, string> = {
|
||||||
default: ' ▗ ▖ ',
|
default: ' ○ ○ ',
|
||||||
'look-left': ' ▘ ▘ ',
|
'look-left': ' ◔ ○ ',
|
||||||
'look-right': ' ▝ ▝ ',
|
'look-right': ' ○ ◔ ',
|
||||||
'arms-up': ' ▗ ▖ '
|
'arms-up': ' ○ ○ '
|
||||||
};
|
};
|
||||||
export function Clawd(t0) {
|
export function Clawd(t0) {
|
||||||
const $ = _c(26);
|
const $ = _c(26);
|
||||||
@@ -140,7 +140,7 @@ export function Clawd(t0) {
|
|||||||
}
|
}
|
||||||
let t8;
|
let t8;
|
||||||
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t8 = <Text color="clawd_body" backgroundColor="clawd_background">█████</Text>;
|
t8 = <Text color="clawd_body" backgroundColor="clawd_background">OPEN </Text>;
|
||||||
$[16] = t8;
|
$[16] = t8;
|
||||||
} else {
|
} else {
|
||||||
t8 = $[16];
|
t8 = $[16];
|
||||||
@@ -164,7 +164,7 @@ export function Clawd(t0) {
|
|||||||
}
|
}
|
||||||
let t11;
|
let t11;
|
||||||
if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t11 = <Text color="clawd_body">{" "}▘▘ ▝▝{" "}</Text>;
|
t11 = <Text color="clawd_body">{" "}╰─◡─╯{" "}</Text>;
|
||||||
$[22] = t11;
|
$[22] = t11;
|
||||||
} else {
|
} else {
|
||||||
t11 = $[22];
|
t11 = $[22];
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export function CondensedLogo() {
|
|||||||
}
|
}
|
||||||
let t5;
|
let t5;
|
||||||
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t5 = <Text bold={true}>Claude Code</Text>;
|
t5 = <Text bold={true}>Open Claude</Text>;
|
||||||
$[8] = t5;
|
$[8] = t5;
|
||||||
} else {
|
} else {
|
||||||
t5 = $[8];
|
t5 = $[8];
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export function WelcomeV2() {
|
|||||||
let t7;
|
let t7;
|
||||||
let t8;
|
let t8;
|
||||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t0 = <Text><Text color="claude">{"Welcome to Claude Code"} </Text><Text dimColor={true}>v{MACRO.VERSION} </Text></Text>;
|
t0 = <Text><Text color="claude">{"Welcome to Open Claude"} </Text><Text dimColor={true}>v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} </Text></Text>;
|
||||||
t1 = <Text>{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}</Text>;
|
t1 = <Text>{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}</Text>;
|
||||||
t2 = <Text>{" "}</Text>;
|
t2 = <Text>{" "}</Text>;
|
||||||
t3 = <Text>{" "}</Text>;
|
t3 = <Text>{" "}</Text>;
|
||||||
@@ -113,7 +113,7 @@ export function WelcomeV2() {
|
|||||||
let t5;
|
let t5;
|
||||||
let t6;
|
let t6;
|
||||||
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t0 = <Text><Text color="claude">{"Welcome to Claude Code"} </Text><Text dimColor={true}>v{MACRO.VERSION} </Text></Text>;
|
t0 = <Text><Text color="claude">{"Welcome to Open Claude"} </Text><Text dimColor={true}>v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} </Text></Text>;
|
||||||
t1 = <Text>{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}</Text>;
|
t1 = <Text>{"\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026"}</Text>;
|
||||||
t2 = <Text>{" "}</Text>;
|
t2 = <Text>{" "}</Text>;
|
||||||
t3 = <Text>{" * \u2588\u2588\u2588\u2588\u2588\u2593\u2593\u2591 "}</Text>;
|
t3 = <Text>{" * \u2588\u2588\u2588\u2588\u2588\u2593\u2593\u2591 "}</Text>;
|
||||||
@@ -218,7 +218,7 @@ function AppleTerminalWelcomeV2(t0) {
|
|||||||
}
|
}
|
||||||
let t2;
|
let t2;
|
||||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t2 = <Text dimColor={true}>v{MACRO.VERSION} </Text>;
|
t2 = <Text dimColor={true}>v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} </Text>;
|
||||||
$[2] = t2;
|
$[2] = t2;
|
||||||
} else {
|
} else {
|
||||||
t2 = $[2];
|
t2 = $[2];
|
||||||
@@ -329,7 +329,7 @@ function AppleTerminalWelcomeV2(t0) {
|
|||||||
}
|
}
|
||||||
let t2;
|
let t2;
|
||||||
if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
|
if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
|
||||||
t2 = <Text dimColor={true}>v{MACRO.VERSION} </Text>;
|
t2 = <Text dimColor={true}>v{MACRO.DISPLAY_VERSION ?? MACRO.VERSION} </Text>;
|
||||||
$[24] = t2;
|
$[24] = t2;
|
||||||
} else {
|
} else {
|
||||||
t2 = $[24];
|
t2 = $[24];
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ async function main(): Promise<void> {
|
|||||||
if (args.length === 1 && (args[0] === '--version' || args[0] === '-v' || args[0] === '-V')) {
|
if (args.length === 1 && (args[0] === '--version' || args[0] === '-v' || args[0] === '-V')) {
|
||||||
// MACRO.VERSION is inlined at build time
|
// MACRO.VERSION is inlined at build time
|
||||||
// biome-ignore lint/suspicious/noConsole:: intentional console output
|
// biome-ignore lint/suspicious/noConsole:: intentional console output
|
||||||
console.log(`${MACRO.VERSION} (Claude Code)`);
|
console.log(`${MACRO.DISPLAY_VERSION ?? MACRO.VERSION} (Open Claude)`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,10 +322,12 @@ async function main(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No special flags detected, load and run the full CLI
|
// No special flags detected, load and run the full CLI
|
||||||
|
if (process.env.OPENCLAUDE_ENABLE_EARLY_INPUT === '1') {
|
||||||
const {
|
const {
|
||||||
startCapturingEarlyInput
|
startCapturingEarlyInput
|
||||||
} = await import('../utils/earlyInput.js');
|
} = await import('../utils/earlyInput.js');
|
||||||
startCapturingEarlyInput();
|
startCapturingEarlyInput();
|
||||||
|
}
|
||||||
profileCheckpoint('cli_before_main_import');
|
profileCheckpoint('cli_before_main_import');
|
||||||
const {
|
const {
|
||||||
main: cliMain
|
main: cliMain
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ export default class App extends PureComponent<Props, State> {
|
|||||||
keyParseState = INITIAL_STATE;
|
keyParseState = INITIAL_STATE;
|
||||||
// Timer for flushing incomplete escape sequences
|
// Timer for flushing incomplete escape sequences
|
||||||
incompleteEscapeTimer: NodeJS.Timeout | null = null;
|
incompleteEscapeTimer: NodeJS.Timeout | null = null;
|
||||||
|
stdinMode: 'readable' | 'data' = process.env.OPENCLAUDE_USE_READABLE_STDIN === '1' ? 'readable' : 'data';
|
||||||
// Timeout durations for incomplete sequences (ms)
|
// Timeout durations for incomplete sequences (ms)
|
||||||
readonly NORMAL_TIMEOUT = 50; // Short timeout for regular esc sequences
|
readonly NORMAL_TIMEOUT = 50; // Short timeout for regular esc sequences
|
||||||
readonly PASTE_TIMEOUT = 500; // Longer timeout for paste operations
|
readonly PASTE_TIMEOUT = 500; // Longer timeout for paste operations
|
||||||
@@ -228,7 +229,12 @@ export default class App extends PureComponent<Props, State> {
|
|||||||
stopCapturingEarlyInput();
|
stopCapturingEarlyInput();
|
||||||
stdin.ref();
|
stdin.ref();
|
||||||
stdin.setRawMode(true);
|
stdin.setRawMode(true);
|
||||||
|
stdin.resume();
|
||||||
|
if (this.stdinMode === 'data') {
|
||||||
|
stdin.addListener('data', this.handleDataChunk);
|
||||||
|
} else {
|
||||||
stdin.addListener('readable', this.handleReadable);
|
stdin.addListener('readable', this.handleReadable);
|
||||||
|
}
|
||||||
// Enable bracketed paste mode
|
// Enable bracketed paste mode
|
||||||
this.props.stdout.write(EBP);
|
this.props.stdout.write(EBP);
|
||||||
// Enable terminal focus reporting (DECSET 1004)
|
// Enable terminal focus reporting (DECSET 1004)
|
||||||
@@ -275,6 +281,8 @@ export default class App extends PureComponent<Props, State> {
|
|||||||
this.props.stdout.write(DBP);
|
this.props.stdout.write(DBP);
|
||||||
stdin.setRawMode(false);
|
stdin.setRawMode(false);
|
||||||
stdin.removeListener('readable', this.handleReadable);
|
stdin.removeListener('readable', this.handleReadable);
|
||||||
|
stdin.removeListener('data', this.handleDataChunk);
|
||||||
|
stdin.pause();
|
||||||
stdin.unref();
|
stdin.unref();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -366,6 +374,27 @@ export default class App extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
handleDataChunk = (chunk: string | Buffer): void => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - this.lastStdinTime > STDIN_RESUME_GAP_MS) {
|
||||||
|
this.props.onStdinResume?.();
|
||||||
|
}
|
||||||
|
this.lastStdinTime = now;
|
||||||
|
try {
|
||||||
|
this.processInput(chunk);
|
||||||
|
} catch (error) {
|
||||||
|
logError(error);
|
||||||
|
const {
|
||||||
|
stdin
|
||||||
|
} = this.props;
|
||||||
|
if (this.rawModeEnabledCount > 0 && !stdin.listeners('data').includes(this.handleDataChunk)) {
|
||||||
|
logForDebugging('handleDataChunk: re-attaching stdin data listener after error recovery', {
|
||||||
|
level: 'warn'
|
||||||
|
});
|
||||||
|
stdin.addListener('data', this.handleDataChunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
handleInput = (input: string | undefined): void => {
|
handleInput = (input: string | undefined): void => {
|
||||||
// Exit on Ctrl+C
|
// Exit on Ctrl+C
|
||||||
if (input === '\x03' && this.props.exitOnCtrlC) {
|
if (input === '\x03' && this.props.exitOnCtrlC) {
|
||||||
|
|||||||
@@ -165,6 +165,12 @@ const EXTENDED_KEYS_TERMINALS = [
|
|||||||
/** True if this terminal correctly handles extended key reporting
|
/** True if this terminal correctly handles extended key reporting
|
||||||
* (Kitty keyboard protocol + xterm modifyOtherKeys). */
|
* (Kitty keyboard protocol + xterm modifyOtherKeys). */
|
||||||
export function supportsExtendedKeys(): boolean {
|
export function supportsExtendedKeys(): boolean {
|
||||||
|
// Open Claude defaults this off because some real terminals render the UI
|
||||||
|
// but stop delivering normal typing once kitty/modifyOtherKeys negotiation
|
||||||
|
// is enabled. Power users can opt back in explicitly.
|
||||||
|
if (process.env.OPENCLAUDE_ENABLE_EXTENDED_KEYS !== '1') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return EXTENDED_KEYS_TERMINALS.includes(env.terminal ?? '')
|
return EXTENDED_KEYS_TERMINALS.includes(env.terminal ?? '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3782,7 +3782,7 @@ async function run(): Promise<CommanderCommand> {
|
|||||||
pendingHookMessages
|
pendingHookMessages
|
||||||
}, renderAndRun);
|
}, renderAndRun);
|
||||||
}
|
}
|
||||||
}).version(`${MACRO.VERSION} (Claude Code)`, '-v, --version', 'Output the version number');
|
}).version(`${MACRO.DISPLAY_VERSION ?? MACRO.VERSION} (Open Claude)`, '-v, --version', 'Output the version number');
|
||||||
|
|
||||||
// Worktree flags
|
// Worktree flags
|
||||||
program.option('-w, --worktree [name]', 'Create a new git worktree for this session (optionally specify a name)');
|
program.option('-w, --worktree [name]', 'Create a new git worktree for this session (optionally specify a name)');
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ import { IdeOnboardingDialog } from '../components/IdeOnboardingDialog.js';
|
|||||||
import { EffortCallout, shouldShowEffortCallout } from '../components/EffortCallout.js';
|
import { EffortCallout, shouldShowEffortCallout } from '../components/EffortCallout.js';
|
||||||
import type { EffortValue } from '../utils/effort.js';
|
import type { EffortValue } from '../utils/effort.js';
|
||||||
import { RemoteCallout } from '../components/RemoteCallout.js';
|
import { RemoteCallout } from '../components/RemoteCallout.js';
|
||||||
|
import { getAPIProvider } from '../utils/model/providers.js';
|
||||||
/* eslint-disable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
|
/* eslint-disable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
|
||||||
const AntModelSwitchCallout = "external" === 'ant' ? require('../components/AntModelSwitchCallout.js').AntModelSwitchCallout : null;
|
const AntModelSwitchCallout = "external" === 'ant' ? require('../components/AntModelSwitchCallout.js').AntModelSwitchCallout : null;
|
||||||
const shouldShowAntModelSwitch = "external" === 'ant' ? require('../components/AntModelSwitchCallout.js').shouldShowModelSwitchCallout : (): boolean => false;
|
const shouldShowAntModelSwitch = "external" === 'ant' ? require('../components/AntModelSwitchCallout.js').shouldShowModelSwitchCallout : (): boolean => false;
|
||||||
@@ -2675,7 +2676,7 @@ export function REPL({
|
|||||||
// useDeferredHookMessages) and attachment messages (appended by
|
// useDeferredHookMessages) and attachment messages (appended by
|
||||||
// processTextPrompt) — both pushed length past 1 on turn one, so the
|
// processTextPrompt) — both pushed length past 1 on turn one, so the
|
||||||
// title silently fell through to the "Claude Code" default.
|
// title silently fell through to the "Claude Code" default.
|
||||||
if (!titleDisabled && !sessionTitle && !agentTitle && !haikuTitleAttemptedRef.current) {
|
if (getAPIProvider() === 'firstParty' && !titleDisabled && !sessionTitle && !agentTitle && !haikuTitleAttemptedRef.current) {
|
||||||
const firstUserMessage = newMessages.find(m => m.type === 'user' && !m.isMeta);
|
const firstUserMessage = newMessages.find(m => m.type === 'user' && !m.isMeta);
|
||||||
const text = firstUserMessage?.type === 'user' ? getContentText(firstUserMessage.message.content) : null;
|
const text = firstUserMessage?.type === 'user' ? getContentText(firstUserMessage.message.content) : null;
|
||||||
// Skip synthetic breadcrumbs — slash-command output, prompt-skill
|
// Skip synthetic breadcrumbs — slash-command output, prompt-skill
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { getModelBetas } from '../utils/betas.js'
|
|||||||
import { getGlobalConfig, saveGlobalConfig } from '../utils/config.js'
|
import { getGlobalConfig, saveGlobalConfig } from '../utils/config.js'
|
||||||
import { logError } from '../utils/log.js'
|
import { logError } from '../utils/log.js'
|
||||||
import { getSmallFastModel } from '../utils/model/model.js'
|
import { getSmallFastModel } from '../utils/model/model.js'
|
||||||
|
import { getAPIProvider } from '../utils/model/providers.js'
|
||||||
import { isEssentialTrafficOnly } from '../utils/privacyLevel.js'
|
import { isEssentialTrafficOnly } from '../utils/privacyLevel.js'
|
||||||
import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from './analytics/index.js'
|
import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from './analytics/index.js'
|
||||||
import { logEvent } from './analytics/index.js'
|
import { logEvent } from './analytics/index.js'
|
||||||
@@ -223,6 +224,10 @@ export async function checkQuotaStatus(): Promise<void> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getAPIProvider() !== 'firstParty') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we should process rate limits (real subscriber or mock testing)
|
// Check if we should process rate limits (real subscriber or mock testing)
|
||||||
if (!shouldProcessRateLimits(isClaudeAISubscriber())) {
|
if (!shouldProcessRateLimits(isClaudeAISubscriber())) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { getClaudeAIOAuthTokens } from 'src/utils/auth.js'
|
|||||||
import { getGlobalConfig, saveGlobalConfig } from 'src/utils/config.js'
|
import { getGlobalConfig, saveGlobalConfig } from 'src/utils/config.js'
|
||||||
import { logForDebugging } from 'src/utils/debug.js'
|
import { logForDebugging } from 'src/utils/debug.js'
|
||||||
import { isEnvDefinedFalsy } from 'src/utils/envUtils.js'
|
import { isEnvDefinedFalsy } from 'src/utils/envUtils.js'
|
||||||
|
import { getAPIProvider } from 'src/utils/model/providers.js'
|
||||||
import { clearMcpAuthCache } from './client.js'
|
import { clearMcpAuthCache } from './client.js'
|
||||||
import { normalizeNameForMCP } from './normalization.js'
|
import { normalizeNameForMCP } from './normalization.js'
|
||||||
import type { ScopedMcpServerConfig } from './types.js'
|
import type { ScopedMcpServerConfig } from './types.js'
|
||||||
@@ -39,6 +40,15 @@ const MCP_SERVERS_BETA_HEADER = 'mcp-servers-2025-12-04'
|
|||||||
export const fetchClaudeAIMcpConfigsIfEligible = memoize(
|
export const fetchClaudeAIMcpConfigsIfEligible = memoize(
|
||||||
async (): Promise<Record<string, ScopedMcpServerConfig>> => {
|
async (): Promise<Record<string, ScopedMcpServerConfig>> => {
|
||||||
try {
|
try {
|
||||||
|
if (getAPIProvider() !== 'firstParty') {
|
||||||
|
logForDebugging('[claudeai-mcp] Skipped: non-first-party provider')
|
||||||
|
logEvent('tengu_claudeai_mcp_eligibility', {
|
||||||
|
state:
|
||||||
|
'non_first_party_provider' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||||
|
})
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
if (isEnvDefinedFalsy(process.env.ENABLE_CLAUDEAI_MCP_SERVERS)) {
|
if (isEnvDefinedFalsy(process.env.ENABLE_CLAUDEAI_MCP_SERVERS)) {
|
||||||
logForDebugging('[claudeai-mcp] Disabled via env var')
|
logForDebugging('[claudeai-mcp] Disabled via env var')
|
||||||
logEvent('tengu_claudeai_mcp_eligibility', {
|
logEvent('tengu_claudeai_mcp_eligibility', {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export function execFileNoThrowWithCwd(
|
|||||||
// Use execa for cross-platform .bat/.cmd compatibility on Windows
|
// Use execa for cross-platform .bat/.cmd compatibility on Windows
|
||||||
execa(file, args, {
|
execa(file, args, {
|
||||||
maxBuffer,
|
maxBuffer,
|
||||||
signal: abortSignal,
|
cancelSignal: abortSignal,
|
||||||
timeout: finalTimeout,
|
timeout: finalTimeout,
|
||||||
cwd: finalCwd,
|
cwd: finalCwd,
|
||||||
env: finalEnv,
|
env: finalEnv,
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ import {
|
|||||||
import { createSignal } from './signal.js'
|
import { createSignal } from './signal.js'
|
||||||
|
|
||||||
export function isFastModeEnabled(): boolean {
|
export function isFastModeEnabled(): boolean {
|
||||||
|
if (getAPIProvider() !== 'firstParty') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_FAST_MODE)
|
return !isEnvTruthy(process.env.CLAUDE_CODE_DISABLE_FAST_MODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +73,10 @@ function getDisabledReasonMessage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getFastModeUnavailableReason(): string | null {
|
export function getFastModeUnavailableReason(): string | null {
|
||||||
|
if (getAPIProvider() !== 'firstParty') {
|
||||||
|
return 'Fast mode is not available on third-party providers'
|
||||||
|
}
|
||||||
|
|
||||||
if (!isFastModeEnabled()) {
|
if (!isFastModeEnabled()) {
|
||||||
return 'Fast mode is not available'
|
return 'Fast mode is not available'
|
||||||
}
|
}
|
||||||
@@ -109,13 +116,6 @@ export function getFastModeUnavailableReason(): string | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only available for 1P (not Bedrock/Vertex/Foundry)
|
|
||||||
if (getAPIProvider() !== 'firstParty') {
|
|
||||||
const reason = 'Fast mode is not available on Bedrock, Vertex, or Foundry'
|
|
||||||
logForDebugging(`Fast mode unavailable: ${reason}`)
|
|
||||||
return reason
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orgStatus.status === 'disabled') {
|
if (orgStatus.status === 'disabled') {
|
||||||
if (
|
if (
|
||||||
orgStatus.reason === 'network_error' ||
|
orgStatus.reason === 'network_error' ||
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ export function getLogoDisplayData(): {
|
|||||||
billingType: string
|
billingType: string
|
||||||
agentName: string | undefined
|
agentName: string | undefined
|
||||||
} {
|
} {
|
||||||
const version = process.env.DEMO_VERSION ?? MACRO.VERSION
|
const version = process.env.DEMO_VERSION ?? MACRO.DISPLAY_VERSION ?? MACRO.VERSION
|
||||||
const serverUrl = getDirectConnectServerUrl()
|
const serverUrl = getDirectConnectServerUrl()
|
||||||
const displayPath = process.env.DEMO_VERSION
|
const displayPath = process.env.DEMO_VERSION
|
||||||
? '/code/claude'
|
? '/code/claude'
|
||||||
|
|||||||
Reference in New Issue
Block a user