rebrand better-clawd and ship initial npm-ready release
This commit is contained in:
@@ -37,7 +37,7 @@ async function main(): Promise<void> {
|
||||
if (args.length === 1 && (args[0] === '--version' || args[0] === '-v' || args[0] === '-V')) {
|
||||
// MACRO.VERSION is inlined at build time
|
||||
// biome-ignore lint/suspicious/noConsole:: intentional console output
|
||||
console.log(`${MACRO.VERSION} (Claude Code)`);
|
||||
console.log(`${MACRO.VERSION} (Better-Clawd)`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { profileCheckpoint } from '../utils/startupProfiler.js'
|
||||
import '../bootstrap/state.js'
|
||||
import '../utils/config.js'
|
||||
import type { Attributes, MetricOptions } from '@opentelemetry/api'
|
||||
import memoize from 'lodash-es/memoize.js'
|
||||
import { getIsNonInteractiveSession } from 'src/bootstrap/state.js'
|
||||
import type { AttributedCounter } from '../bootstrap/state.js'
|
||||
import { getSessionCounter, setMeter } from '../bootstrap/state.js'
|
||||
import { shutdownLspServerManager } from '../services/lsp/manager.js'
|
||||
import { populateOAuthAccountInfoIfNeeded } from '../services/oauth/client.js'
|
||||
import {
|
||||
@@ -15,7 +12,6 @@ import {
|
||||
import {
|
||||
initializeRemoteManagedSettingsLoadingPromise,
|
||||
isEligibleForRemoteManagedSettings,
|
||||
waitForRemoteManagedSettingsToLoad,
|
||||
} from '../services/remoteManagedSettings/index.js'
|
||||
import { preconnectAnthropicApi } from '../utils/apiPreconnect.js'
|
||||
import { applyExtraCACertsFromConfig } from '../utils/caCertsConfig.js'
|
||||
@@ -26,34 +22,21 @@ import { detectCurrentRepository } from '../utils/detectRepository.js'
|
||||
import { logForDiagnosticsNoPII } from '../utils/diagLogs.js'
|
||||
import { initJetBrainsDetection } from '../utils/envDynamic.js'
|
||||
import { isEnvTruthy } from '../utils/envUtils.js'
|
||||
import { ConfigParseError, errorMessage } from '../utils/errors.js'
|
||||
import { ConfigParseError } from '../utils/errors.js'
|
||||
// showInvalidConfigDialog is dynamically imported in the error path to avoid loading React at init
|
||||
import {
|
||||
gracefulShutdownSync,
|
||||
setupGracefulShutdown,
|
||||
} from '../utils/gracefulShutdown.js'
|
||||
import {
|
||||
applyConfigEnvironmentVariables,
|
||||
applySafeConfigEnvironmentVariables,
|
||||
} from '../utils/managedEnv.js'
|
||||
import { applySafeConfigEnvironmentVariables } from '../utils/managedEnv.js'
|
||||
import { configureGlobalMTLS } from '../utils/mtls.js'
|
||||
import {
|
||||
ensureScratchpadDir,
|
||||
isScratchpadEnabled,
|
||||
} from '../utils/permissions/filesystem.js'
|
||||
// initializeTelemetry is loaded lazily via import() in setMeterState() to defer
|
||||
// ~400KB of OpenTelemetry + protobuf modules until telemetry is actually initialized.
|
||||
// gRPC exporters (~700KB via @grpc/grpc-js) are further lazy-loaded within instrumentation.ts.
|
||||
import { configureGlobalAgents } from '../utils/proxy.js'
|
||||
import { isBetaTracingEnabled } from '../utils/telemetry/betaSessionTracing.js'
|
||||
import { getTelemetryAttributes } from '../utils/telemetryAttributes.js'
|
||||
import { setShellIfWindows } from '../utils/windowsPaths.js'
|
||||
|
||||
// initialize1PEventLogging is dynamically imported to defer OpenTelemetry sdk-logs/resources
|
||||
|
||||
// Track if telemetry has been initialized to prevent double initialization
|
||||
let telemetryInitialized = false
|
||||
|
||||
export const init = memoize(async (): Promise<void> => {
|
||||
const initStartTime = Date.now()
|
||||
logForDiagnosticsNoPII('info', 'init_started')
|
||||
@@ -87,22 +70,7 @@ export const init = memoize(async (): Promise<void> => {
|
||||
setupGracefulShutdown()
|
||||
profileCheckpoint('init_after_graceful_shutdown')
|
||||
|
||||
// Initialize 1P event logging (no security concerns, but deferred to avoid
|
||||
// loading OpenTelemetry sdk-logs at startup). growthbook.js is already in
|
||||
// the module cache by this point (firstPartyEventLogger imports it), so the
|
||||
// second dynamic import adds no load cost.
|
||||
void Promise.all([
|
||||
import('../services/analytics/firstPartyEventLogger.js'),
|
||||
import('../services/analytics/growthbook.js'),
|
||||
]).then(([fp, gb]) => {
|
||||
fp.initialize1PEventLogging()
|
||||
// Rebuild the logger provider if tengu_1p_event_batch_config changes
|
||||
// mid-session. Change detection (isEqual) is inside the handler so
|
||||
// unchanged refreshes are no-ops.
|
||||
gb.onGrowthBookRefresh(() => {
|
||||
void fp.reinitialize1PEventLoggingIfConfigChanged()
|
||||
})
|
||||
})
|
||||
// Better-Clawd disables outbound telemetry, so the 1P event logger stays off.
|
||||
profileCheckpoint('init_after_1p_event_logging')
|
||||
|
||||
// Populate OAuth account info if it is not already cached in config. This is needed since the
|
||||
@@ -245,96 +213,5 @@ export const init = memoize(async (): Promise<void> => {
|
||||
* This should only be called once, after the trust dialog has been accepted.
|
||||
*/
|
||||
export function initializeTelemetryAfterTrust(): void {
|
||||
if (isEligibleForRemoteManagedSettings()) {
|
||||
// For SDK/headless mode with beta tracing, initialize eagerly first
|
||||
// to ensure the tracer is ready before the first query runs.
|
||||
// The async path below will still run but doInitializeTelemetry() guards against double init.
|
||||
if (getIsNonInteractiveSession() && isBetaTracingEnabled()) {
|
||||
void doInitializeTelemetry().catch(error => {
|
||||
logForDebugging(
|
||||
`[3P telemetry] Eager telemetry init failed (beta tracing): ${errorMessage(error)}`,
|
||||
{ level: 'error' },
|
||||
)
|
||||
})
|
||||
}
|
||||
logForDebugging(
|
||||
'[3P telemetry] Waiting for remote managed settings before telemetry init',
|
||||
)
|
||||
void waitForRemoteManagedSettingsToLoad()
|
||||
.then(async () => {
|
||||
logForDebugging(
|
||||
'[3P telemetry] Remote managed settings loaded, initializing telemetry',
|
||||
)
|
||||
// Re-apply env vars to pick up remote settings before initializing telemetry.
|
||||
applyConfigEnvironmentVariables()
|
||||
await doInitializeTelemetry()
|
||||
})
|
||||
.catch(error => {
|
||||
logForDebugging(
|
||||
`[3P telemetry] Telemetry init failed (remote settings path): ${errorMessage(error)}`,
|
||||
{ level: 'error' },
|
||||
)
|
||||
})
|
||||
} else {
|
||||
void doInitializeTelemetry().catch(error => {
|
||||
logForDebugging(
|
||||
`[3P telemetry] Telemetry init failed: ${errorMessage(error)}`,
|
||||
{ level: 'error' },
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function doInitializeTelemetry(): Promise<void> {
|
||||
if (telemetryInitialized) {
|
||||
// Already initialized, nothing to do
|
||||
return
|
||||
}
|
||||
|
||||
// Set flag before init to prevent double initialization
|
||||
telemetryInitialized = true
|
||||
try {
|
||||
await setMeterState()
|
||||
} catch (error) {
|
||||
// Reset flag on failure so subsequent calls can retry
|
||||
telemetryInitialized = false
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function setMeterState(): Promise<void> {
|
||||
// Lazy-load instrumentation to defer ~400KB of OpenTelemetry + protobuf
|
||||
const { initializeTelemetry } = await import(
|
||||
'../utils/telemetry/instrumentation.js'
|
||||
)
|
||||
// Initialize customer OTLP telemetry (metrics, logs, traces)
|
||||
const meter = await initializeTelemetry()
|
||||
if (meter) {
|
||||
// Create factory function for attributed counters
|
||||
const createAttributedCounter = (
|
||||
name: string,
|
||||
options: MetricOptions,
|
||||
): AttributedCounter => {
|
||||
const counter = meter?.createCounter(name, options)
|
||||
|
||||
return {
|
||||
add(value: number, additionalAttributes: Attributes = {}) {
|
||||
// Always fetch fresh telemetry attributes to ensure they're up to date
|
||||
const currentAttributes = getTelemetryAttributes()
|
||||
const mergedAttributes = {
|
||||
...currentAttributes,
|
||||
...additionalAttributes,
|
||||
}
|
||||
counter?.add(value, mergedAttributes)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
setMeter(meter, createAttributedCounter)
|
||||
|
||||
// Increment session counter here because the startup telemetry path
|
||||
// runs before this async initialization completes, so the counter
|
||||
// would be null there.
|
||||
getSessionCounter()?.add(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1341,7 +1341,7 @@ export const SDKRateLimitInfoSchema = lazySchema(() =>
|
||||
isUsingOverage: z.boolean().optional(),
|
||||
surpassedThreshold: z.number().optional(),
|
||||
})
|
||||
.describe('Rate limit information for claude.ai subscription users.'),
|
||||
.describe('Rate limit information for browser-authenticated subscription users.'),
|
||||
)
|
||||
|
||||
export const SDKAssistantMessageSchema = lazySchema(() =>
|
||||
|
||||
1
src/entrypoints/sdk/coreTypes.generated.ts
Normal file
1
src/entrypoints/sdk/coreTypes.generated.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type GeneratedSDKType = Record<string, unknown>
|
||||
23
src/entrypoints/sdk/runtimeTypes.ts
Normal file
23
src/entrypoints/sdk/runtimeTypes.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export type EffortLevel = 'low' | 'medium' | 'high' | 'max'
|
||||
|
||||
export type AnyZodRawShape = Record<string, unknown>
|
||||
export type InferShape<T> = T extends Record<string, unknown> ? T : never
|
||||
|
||||
export type Options = Record<string, unknown>
|
||||
export type InternalOptions = Record<string, unknown>
|
||||
export type Query = Record<string, unknown>
|
||||
export type InternalQuery = Record<string, unknown>
|
||||
export type ListSessionsOptions = Record<string, unknown>
|
||||
export type GetSessionInfoOptions = Record<string, unknown>
|
||||
export type GetSessionMessagesOptions = Record<string, unknown>
|
||||
export type SessionMutationOptions = Record<string, unknown>
|
||||
export type ForkSessionOptions = Record<string, unknown>
|
||||
export type ForkSessionResult = Record<string, unknown>
|
||||
export type McpSdkServerConfigWithInstance = Record<string, unknown>
|
||||
export type SessionMessage = Record<string, unknown>
|
||||
export type SDKSession = Record<string, unknown>
|
||||
export type SDKSessionOptions = Record<string, unknown>
|
||||
export type SDKSessionInfo = Record<string, unknown>
|
||||
export type SDKUserMessage = Record<string, unknown>
|
||||
export type SDKResultMessage = Record<string, unknown>
|
||||
export type SdkMcpToolDefinition<T = Record<string, unknown>> = T
|
||||
1
src/entrypoints/sdk/toolTypes.ts
Normal file
1
src/entrypoints/sdk/toolTypes.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type SDKTool = Record<string, unknown>
|
||||
Reference in New Issue
Block a user