feat: reconstruct bun cli build

This commit is contained in:
paoloanzn committed 2026-03-31 14:34:56 +02:00
1 parent 4b9d30f795
commit e878a7ce35
39 files changed
+2756 -32

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
node_modules/
dist/
cli
+21
View File
@@ -0,0 +1,21 @@
# App Structure - Claude Code Source Snapshot
# Last updated: 2026-03-31
## Repositories
- GitHub: https://github.com/paoloanzn/claude-code
## Backend (Supabase)
- N/A
## Deployed Services (Railway)
- N/A
## Environment Variables Required
- USER_TYPE (optional; external/public build defaults to non-ant behavior)
- CLAUDE_CODE_ENABLE_CFC (optional)
- CLAUDE_CODE_REMOTE (optional)
## Notes
- This repository is a reconstructed Bun CLI workspace built from a leaked TypeScript source snapshot.
- The source build targets `src/entrypoints/cli.tsx` and emits `cli.js` via `bun run build`.
- Anthropic-internal `@ant/*` packages are treated as optional/external. Chrome integration is lazy-loaded so the default CLI startup path does not fail when those packages are unavailable.
+1685
View File
File diff suppressed because it is too large. Load diff
Vendored
+14
View File
@@ -0,0 +1,14 @@
declare const MACRO: {
VERSION: string
BUILD_TIME: string
PACKAGE_URL?: string
NATIVE_PACKAGE_URL?: string
FEEDBACK_CHANNEL?: string
ISSUES_EXPLAINER?: string
VERSION_CHANGELOG?: string
}
declare module '*.node' {
const value: unknown
export default value
}
+119
View File
@@ -0,0 +1,119 @@
{
"name": "claude-code-source-snapshot",
"version": "0.1.0",
"private": true,
"description": "Reconstructed Bun CLI workspace for the Claude Code source snapshot.",
"type": "module",
"packageManager": "bun@1.3.11",
"bin": {
"claude": "./cli",
"claude-source": "./cli"
},
"engines": {
"bun": ">=1.3.11"
},
"scripts": {
"build": "bun run ./scripts/build.ts",
"compile": "bun run ./scripts/build.ts --compile",
"dev": "bun run ./src/entrypoints/cli.tsx"
},
"dependencies": {
"@alcalzone/ansi-tokenize": "^0.3.0",
"@anthropic-ai/bedrock-sdk": "^0.26.4",
"@anthropic-ai/claude-agent-sdk": "^0.2.87",
"@anthropic-ai/foundry-sdk": "^0.2.3",
"@anthropic-ai/mcpb": "^2.1.2",
"@anthropic-ai/sandbox-runtime": "^0.0.44",
"@anthropic-ai/sdk": "^0.80.0",
"@anthropic-ai/vertex-sdk": "^0.14.4",
"@aws-sdk/client-bedrock": "^3.1020.0",
"@aws-sdk/client-bedrock-runtime": "^3.1020.0",
"@aws-sdk/client-sts": "^3.1020.0",
"@aws-sdk/credential-provider-node": "^3.972.28",
"@aws-sdk/credential-providers": "^3.1020.0",
"@azure/identity": "^4.13.1",
"@commander-js/extra-typings": "^14.0.0",
"@growthbook/growthbook": "^1.6.5",
"@modelcontextprotocol/sdk": "^1.29.0",
"@opentelemetry/api": "^1.9.1",
"@opentelemetry/api-logs": "^0.214.0",
"@opentelemetry/core": "^2.6.1",
"@opentelemetry/exporter-logs-otlp-grpc": "^0.214.0",
"@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
"@opentelemetry/exporter-logs-otlp-proto": "^0.214.0",
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.214.0",
"@opentelemetry/exporter-metrics-otlp-http": "^0.214.0",
"@opentelemetry/exporter-metrics-otlp-proto": "^0.214.0",
"@opentelemetry/exporter-prometheus": "^0.214.0",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.214.0",
"@opentelemetry/exporter-trace-otlp-http": "^0.214.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.214.0",
"@opentelemetry/resources": "^2.6.1",
"@opentelemetry/sdk-logs": "^0.214.0",
"@opentelemetry/sdk-metrics": "^2.6.1",
"@opentelemetry/sdk-trace-base": "^2.6.1",
"@opentelemetry/semantic-conventions": "^1.40.0",
"@smithy/core": "^3.23.13",
"@smithy/node-http-handler": "^4.5.1",
"ajv": "^8.18.0",
"asciichart": "^1.5.25",
"auto-bind": "^5.0.1",
"axios": "^1.14.0",
"bidi-js": "^1.0.3",
"cacache": "^20.0.4",
"chalk": "^5.6.2",
"chokidar": "^5.0.0",
"cli-boxes": "^4.0.1",
"cli-highlight": "^2.1.11",
"code-excerpt": "^4.0.0",
"diff": "^8.0.4",
"emoji-regex": "^10.6.0",
"env-paths": "^4.0.0",
"execa": "^9.6.1",
"fflate": "^0.8.2",
"figures": "^6.1.0",
"fuse.js": "^7.1.0",
"get-east-asian-width": "^1.5.0",
"google-auth-library": "^10.6.2",
"highlight.js": "^11.11.1",
"https-proxy-agent": "^8.0.0",
"ignore": "^7.0.5",
"indent-string": "^5.0.0",
"ink": "^6.8.0",
"jsonc-parser": "^3.3.1",
"lodash-es": "^4.17.23",
"lru-cache": "^11.2.7",
"marked": "^17.0.5",
"p-map": "^7.0.4",
"picomatch": "^4.0.4",
"plist": "^3.1.0",
"proper-lockfile": "^4.1.2",
"qrcode": "^1.5.4",
"react": "^19.2.4",
"react-reconciler": "^0.33.0",
"semver": "^7.7.4",
"sharp": "^0.34.5",
"shell-quote": "^1.8.3",
"signal-exit": "^4.1.0",
"stack-utils": "^2.0.6",
"strip-ansi": "^7.2.0",
"supports-hyperlinks": "^4.4.0",
"tree-kill": "^1.2.2",
"turndown": "^7.2.2",
"type-fest": "^5.5.0",
"undici": "^7.24.6",
"usehooks-ts": "^3.1.1",
"vscode-jsonrpc": "^8.2.1",
"vscode-languageserver-protocol": "^3.17.5",
"vscode-languageserver-types": "^3.17.5",
"wrap-ansi": "^10.0.0",
"ws": "^8.20.0",
"xss": "^1.0.15",
"yaml": "^2.8.3",
"zod": "^4.3.6"
},
"devDependencies": {
"@types/bun": "^1.3.11",
"typescript": "^6.0.2"
}
}
+96
View File
@@ -0,0 +1,96 @@
import { chmodSync, existsSync, mkdirSync } from 'fs'
import { dirname } from 'path'
const pkg = await Bun.file(new URL('../package.json', import.meta.url)).json() as {
name: string
version: string
}
const args = process.argv.slice(2)
const compile = args.includes('--compile')
const features: string[] = []
for (let i = 0; i < args.length; i += 1) {
const arg = args[i]
if (arg === '--feature' && args[i + 1]) {
features.push(args[i + 1]!)
i += 1
continue
}
if (arg.startsWith('--feature=')) {
features.push(arg.slice('--feature='.length))
}
}
const outfile = compile ? './dist/cli' : './cli'
const buildTime = new Date().toISOString()
mkdirSync(dirname(outfile), { recursive: true })
const externals = [
'@ant/*',
'audio-capture-napi',
'image-processor-napi',
'modifiers-napi',
'url-handler-napi',
]
const defines = {
'process.env.USER_TYPE': JSON.stringify('external'),
'process.env.CLAUDE_CODE_VERIFY_PLAN': JSON.stringify('false'),
'MACRO.VERSION': JSON.stringify(pkg.version),
'MACRO.BUILD_TIME': JSON.stringify(buildTime),
'MACRO.PACKAGE_URL': JSON.stringify(pkg.name),
'MACRO.NATIVE_PACKAGE_URL': 'undefined',
'MACRO.FEEDBACK_CHANNEL': JSON.stringify('github'),
'MACRO.ISSUES_EXPLAINER': JSON.stringify(
'This reconstructed source snapshot does not include Anthropic internal issue routing.',
),
'MACRO.VERSION_CHANGELOG': JSON.stringify(
'https://github.com/paoloanzn/claude-code',
),
} as const
const cmd = [
'bun',
'build',
'./src/entrypoints/cli.tsx',
'--compile',
'--target',
'bun',
'--format',
'esm',
'--outfile',
outfile,
'--minify',
'--bytecode',
'--packages',
'bundle',
'--conditions',
'bun',
]
for (const external of externals) {
cmd.push('--external', external)
}
for (const [key, value] of Object.entries(defines)) {
cmd.push('--define', `${key}=${value}`)
}
const proc = Bun.spawnSync({
cmd,
cwd: process.cwd(),
stdout: 'inherit',
stderr: 'inherit',
})
if (proc.exitCode !== 0) {
process.exit(proc.exitCode ?? 1)
}
if (existsSync(outfile)) {
chmodSync(outfile, 0o755)
}
console.log(`Built ${outfile}`)
+15
View File
@@ -0,0 +1,15 @@
import { useEffect } from 'react'
type Props = {
sessions: unknown[]
onSelect: (sessionId: string) => void
onCancel: () => void
}
export function AssistantSessionChooser({ onCancel }: Props) {
useEffect(() => {
onCancel()
}, [onCancel])
return null
}
+22
View File
@@ -0,0 +1,22 @@
import { homedir } from 'os'
import { join } from 'path'
import { useEffect } from 'react'
type Props = {
defaultDir: string
onInstalled: (dir: string) => void
onCancel: () => void
onError: (message: string) => void
}
export async function computeDefaultInstallDir(): Promise<string> {
return join(homedir(), '.claude', 'assistant')
}
export function NewInstallWizard({ onCancel }: Props) {
useEffect(() => {
onCancel()
}, [onCancel])
return null
}
+3 -3
View File
@@ -3,7 +3,7 @@ import {
ColorFile,
getSyntaxTheme as nativeGetSyntaxTheme,
type SyntaxTheme,
} from 'color-diff-napi'
} from '../../native-ts/color-diff/index.js'
import { isEnvDefinedFalsy } from '../../utils/envUtils.js'
export type ColorModuleUnavailableReason = 'env'
@@ -12,8 +12,8 @@ export type ColorModuleUnavailableReason = 'env'
* Returns a static reason why the color-diff module is unavailable, or null if available.
* 'env' = disabled via CLAUDE_CODE_SYNTAX_HIGHLIGHT
*
* The TS port of color-diff works in all build modes, so the only way to
* disable it is via the env var.
* The reconstructed project always uses the bundled TypeScript port, so the
* only way to disable syntax highlighting is via the env var.
*/
export function getColorModuleUnavailableReason(): ColorModuleUnavailableReason | null {
if (isEnvDefinedFalsy(process.env.CLAUDE_CODE_SYNTAX_HIGHLIGHT)) {
@@ -0,0 +1,17 @@
import { useEffect } from 'react'
type Props = {
agentType: string
scope: unknown
snapshotTimestamp: string
onComplete: (choice: 'merge' | 'keep' | 'replace') => void
onCancel: () => void
}
export function SnapshotUpdateDialog({ onCancel }: Props) {
useEffect(() => {
onCancel()
}, [onCancel])
return null
}
+169
View File
@@ -0,0 +1,169 @@
export type PermissionMode =
| 'default'
| 'acceptEdits'
| 'bypassPermissions'
| 'plan'
export type ExitReason =
| 'clear'
| 'resume'
| 'logout'
| 'prompt_input_exit'
| 'other'
| 'bypass_permissions_disabled'
export type HookEvent =
| 'PreToolUse'
| 'PostToolUse'
| 'PostToolUseFailure'
| 'Notification'
| 'UserPromptSubmit'
| 'SessionStart'
| 'SessionEnd'
| 'Stop'
| 'StopFailure'
| 'SubagentStart'
| 'SubagentStop'
| 'PreCompact'
| 'PostCompact'
| 'PermissionRequest'
| 'PermissionDenied'
| 'Setup'
| 'TeammateIdle'
| 'TaskCreated'
| 'TaskCompleted'
| 'Elicitation'
| 'ElicitationResult'
| 'ConfigChange'
| 'WorktreeCreate'
| 'WorktreeRemove'
| 'InstructionsLoaded'
| 'CwdChanged'
| 'FileChanged'
export type ModelUsage = {
costUSD?: number
inputTokens?: number
outputTokens?: number
cacheCreationInputTokens?: number
cacheReadInputTokens?: number
[key: string]: number | undefined
}
export type SDKStatus = 'compacting' | string | null
export type SDKBaseMessage = {
type: string
subtype?: string
uuid?: string
session_id?: string
[key: string]: unknown
}
export type SDKAssistantMessage = SDKBaseMessage & {
type: 'assistant'
message?: { content?: unknown[] }
}
export type SDKAssistantMessageError = SDKBaseMessage & {
type: 'assistant_error'
message?: string
}
export type SDKPartialAssistantMessage = SDKBaseMessage & {
type: 'assistant_partial'
delta?: string
}
export type SDKResultMessage = SDKBaseMessage & {
type: 'result'
is_error?: boolean
result?: string
duration_ms?: number
total_cost_usd?: number
}
export type SDKStatusMessage = SDKBaseMessage & {
type: 'status'
status: SDKStatus
}
export type SDKSystemMessage = SDKBaseMessage & {
type: 'system'
content?: string
}
export type SDKCompactBoundaryMessage = SDKSystemMessage & {
subtype: 'compact_boundary' | 'microcompact_boundary'
}
export type SDKToolProgressMessage = SDKBaseMessage & {
type: 'tool_progress'
data?: Record<string, unknown>
}
export type SDKPermissionDenial = SDKBaseMessage & {
type: 'permission_denial'
mode?: PermissionMode
toolName?: string
}
export type SDKRateLimitInfo = {
remaining?: number
resetAt?: string
}
export type SDKUserMessage = SDKBaseMessage & {
type: 'user'
message?: { content?: unknown }
}
export type SDKUserMessageReplay = SDKUserMessage & {
isReplay?: boolean
}
export type SDKSessionInfo = {
sessionId: string
summary?: string
cwd?: string
createdAt?: string
updatedAt?: string
}
export type PermissionResult =
| { behavior: 'allow'; updatedInput?: Record<string, unknown> }
| { behavior: 'deny'; message?: string }
| { behavior: 'ask'; updatedInput?: Record<string, unknown>; message?: string }
export type HookInput = {
session_id?: string
event?: HookEvent
[key: string]: unknown
}
export type HookJSONOutput = {
continue?: boolean
stopReason?: string
message?: string
decision?: 'allow' | 'deny' | 'ask'
[key: string]: unknown
}
export type SyncHookJSONOutput = HookJSONOutput
export type AsyncHookJSONOutput = HookJSONOutput & {
waitMs?: number
}
export type SDKMessage =
| SDKAssistantMessage
| SDKAssistantMessageError
| SDKCompactBoundaryMessage
| SDKPartialAssistantMessage
| SDKPermissionDenial
| SDKResultMessage
| SDKStatusMessage
| SDKSystemMessage
| SDKToolProgressMessage
| SDKUserMessage
| SDKUserMessageReplay
+59
View File
@@ -0,0 +1,59 @@
import type { CallToolResult, ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'
import type { ZodTypeAny } from 'zod/v4'
export type EffortLevel = 'low' | 'medium' | 'high' | 'max'
export type AnyZodRawShape = Record<string, ZodTypeAny>
export type InferShape<Schema extends AnyZodRawShape> = {
[K in keyof Schema]?: unknown
}
export type SdkMcpToolDefinition<Schema extends AnyZodRawShape> = {
name: string
description: string
inputSchema: Schema
handler: (args: InferShape<Schema>, extra: unknown) => Promise<CallToolResult>
annotations?: ToolAnnotations
searchHint?: string
alwaysLoad?: boolean
}
export type McpSdkServerConfigWithInstance = Record<string, unknown>
export type Options = Record<string, unknown>
export type InternalOptions = Options
export type SDKSessionOptions = Options & {
model?: string
}
export type Query = AsyncIterable<unknown>
export type InternalQuery = AsyncIterable<unknown>
export type SessionMutationOptions = {
dir?: string
}
export type ListSessionsOptions = SessionMutationOptions & {
limit?: number
offset?: number
}
export type GetSessionInfoOptions = SessionMutationOptions
export type GetSessionMessagesOptions = SessionMutationOptions & {
limit?: number
offset?: number
includeSystemMessages?: boolean
}
export type ForkSessionOptions = SessionMutationOptions
export type ForkSessionResult = {
sessionId: string
}
export type SDKSession = {
id: string
}
+1
View File
@@ -0,0 +1 @@
export {}
+1
View File
@@ -0,0 +1 @@
export {}
+1
View File
@@ -0,0 +1 @@
export {}
+2 -2
View File
@@ -973,7 +973,7 @@ async function run(): Promise<CommanderCommand> {
// If not provided but flag is present, value will be true
// The actual filtering is handled in debug.ts by parsing process.argv
return true;
}).addOption(new Option('-d2e, --debug-to-stderr', 'Enable debug mode (to stderr)').argParser(Boolean).hideHelp()).option('--debug-file <path>', 'Write debug logs to a specific file path (implicitly enables debug mode)', () => true).option('--verbose', 'Override verbose mode setting from config', () => true).option('-p, --print', 'Print response and exit (useful for pipes). Note: The workspace trust dialog is skipped when Claude is run with the -p mode. Only use this flag in directories you trust.', () => true).option('--bare', 'Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read). 3P providers (Bedrock/Vertex/Foundry) use their own credentials. Skills still resolve via /skill-name. Explicitly provide context via: --system-prompt[-file], --append-system-prompt[-file], --add-dir (CLAUDE.md dirs), --mcp-config, --settings, --agents, --plugin-dir.', () => true).addOption(new Option('--init', 'Run Setup hooks with init trigger, then continue').hideHelp()).addOption(new Option('--init-only', 'Run Setup and SessionStart:startup hooks, then exit').hideHelp()).addOption(new Option('--maintenance', 'Run Setup hooks with maintenance trigger, then continue').hideHelp()).addOption(new Option('--output-format <format>', 'Output format (only works with --print): "text" (default), "json" (single result), or "stream-json" (realtime streaming)').choices(['text', 'json', 'stream-json'])).addOption(new Option('--json-schema <schema>', 'JSON Schema for structured output validation. ' + 'Example: {"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}').argParser(String)).option('--include-hook-events', 'Include all hook lifecycle events in the output stream (only works with --output-format=stream-json)', () => true).option('--include-partial-messages', 'Include partial message chunks as they arrive (only works with --print and --output-format=stream-json)', () => true).addOption(new Option('--input-format <format>', 'Input format (only works with --print): "text" (default), or "stream-json" (realtime streaming input)').choices(['text', 'stream-json'])).option('--mcp-debug', '[DEPRECATED. Use --debug instead] Enable MCP debug mode (shows MCP server errors)', () => true).option('--dangerously-skip-permissions', 'Bypass all permission checks. Recommended only for sandboxes with no internet access.', () => true).option('--allow-dangerously-skip-permissions', 'Enable bypassing all permission checks as an option, without it being enabled by default. Recommended only for sandboxes with no internet access.', () => true).addOption(new Option('--thinking <mode>', 'Thinking mode: enabled (equivalent to adaptive), disabled').choices(['enabled', 'adaptive', 'disabled']).hideHelp()).addOption(new Option('--max-thinking-tokens <tokens>', '[DEPRECATED. Use --thinking instead for newer models] Maximum number of thinking tokens (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-turns <turns>', 'Maximum number of agentic turns in non-interactive mode. This will early exit the conversation after the specified number of turns. (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-budget-usd <amount>', 'Maximum dollar amount to spend on API calls (only works with --print)').argParser(value => {
}).addOption(new Option('-D, --debug-to-stderr', 'Enable debug mode (to stderr)').argParser(Boolean).hideHelp()).option('--debug-file <path>', 'Write debug logs to a specific file path (implicitly enables debug mode)', () => true).option('--verbose', 'Override verbose mode setting from config', () => true).option('-p, --print', 'Print response and exit (useful for pipes). Note: The workspace trust dialog is skipped when Claude is run with the -p mode. Only use this flag in directories you trust.', () => true).option('--bare', 'Minimal mode: skip hooks, LSP, plugin sync, attribution, auto-memory, background prefetches, keychain reads, and CLAUDE.md auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read). 3P providers (Bedrock/Vertex/Foundry) use their own credentials. Skills still resolve via /skill-name. Explicitly provide context via: --system-prompt[-file], --append-system-prompt[-file], --add-dir (CLAUDE.md dirs), --mcp-config, --settings, --agents, --plugin-dir.', () => true).addOption(new Option('--init', 'Run Setup hooks with init trigger, then continue').hideHelp()).addOption(new Option('--init-only', 'Run Setup and SessionStart:startup hooks, then exit').hideHelp()).addOption(new Option('--maintenance', 'Run Setup hooks with maintenance trigger, then continue').hideHelp()).addOption(new Option('--output-format <format>', 'Output format (only works with --print): "text" (default), "json" (single result), or "stream-json" (realtime streaming)').choices(['text', 'json', 'stream-json'])).addOption(new Option('--json-schema <schema>', 'JSON Schema for structured output validation. ' + 'Example: {"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}').argParser(String)).option('--include-hook-events', 'Include all hook lifecycle events in the output stream (only works with --output-format=stream-json)', () => true).option('--include-partial-messages', 'Include partial message chunks as they arrive (only works with --print and --output-format=stream-json)', () => true).addOption(new Option('--input-format <format>', 'Input format (only works with --print): "text" (default), or "stream-json" (realtime streaming input)').choices(['text', 'stream-json'])).option('--mcp-debug', '[DEPRECATED. Use --debug instead] Enable MCP debug mode (shows MCP server errors)', () => true).option('--dangerously-skip-permissions', 'Bypass all permission checks. Recommended only for sandboxes with no internet access.', () => true).option('--allow-dangerously-skip-permissions', 'Enable bypassing all permission checks as an option, without it being enabled by default. Recommended only for sandboxes with no internet access.', () => true).addOption(new Option('--thinking <mode>', 'Thinking mode: enabled (equivalent to adaptive), disabled').choices(['enabled', 'adaptive', 'disabled']).hideHelp()).addOption(new Option('--max-thinking-tokens <tokens>', '[DEPRECATED. Use --thinking instead for newer models] Maximum number of thinking tokens (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-turns <turns>', 'Maximum number of agentic turns in non-interactive mode. This will early exit the conversation after the specified number of turns. (only works with --print)').argParser(Number).hideHelp()).addOption(new Option('--max-budget-usd <amount>', 'Maximum dollar amount to spend on API calls (only works with --print)').argParser(value => {
const amount = Number(value);
if (isNaN(amount) || amount <= 0) {
throw new Error('--max-budget-usd must be a positive number greater than 0');
@@ -4681,4 +4681,4 @@ function extractTeammateOptions(options: unknown): TeammateOptions {
agentType: typeof opts.agentType === 'string' ? opts.agentType : undefined
};
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwcm9maWxlQ2hlY2twb2ludCIsInByb2ZpbGVSZXBvcnQiLCJzdGFydE1kbVJhd1JlYWQiLCJlbnN1cmVLZXljaGFpblByZWZldGNoQ29tcGxldGVkIiwic3RhcnRLZXljaGFpblByZWZldGNoIiwiZmVhdHVyZSIsIkNvbW1hbmQiLCJDb21tYW5kZXJDb21tYW5kIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJPcHRpb24iLCJjaGFsayIsInJlYWRGaWxlU3luYyIsIm1hcFZhbHVlcyIsInBpY2tCeSIsInVuaXFCeSIsIlJlYWN0IiwiZ2V0T2F1dGhDb25maWciLCJnZXRSZW1vdGVTZXNzaW9uVXJsIiwiZ2V0U3lzdGVtQ29udGV4dCIsImdldFVzZXJDb250ZXh0IiwiaW5pdCIsImluaXRpYWxpemVUZWxlbWV0cnlBZnRlclRydXN0IiwiYWRkVG9IaXN0b3J5IiwiUm9vdCIsImxhdW5jaFJlcGwiLCJoYXNHcm93dGhCb29rRW52T3ZlcnJpZGUiLCJpbml0aWFsaXplR3Jvd3RoQm9vayIsInJlZnJlc2hHcm93dGhCb29rQWZ0ZXJBdXRoQ2hhbmdlIiwiZmV0Y2hCb290c3RyYXBEYXRhIiwiRG93bmxvYWRSZXN1bHQiLCJkb3dubG9hZFNlc3Npb25GaWxlcyIsIkZpbGVzQXBpQ29uZmlnIiwicGFyc2VGaWxlU3BlY3MiLCJwcmVmZXRjaFBhc3Nlc0VsaWdpYmlsaXR5IiwicHJlZmV0Y2hPZmZpY2lhbE1jcFVybHMiLCJNY3BTZGtTZXJ2ZXJDb25maWciLCJNY3BTZXJ2ZXJDb25maWciLCJTY29wZWRNY3BTZXJ2ZXJDb25maWciLCJpc1BvbGljeUFsbG93ZWQiLCJsb2FkUG9saWN5TGltaXRzIiwicmVmcmVzaFBvbGljeUxpbWl0cyIsIndhaXRGb3JQb2xpY3lMaW1pdHNUb0xvYWQiLCJsb2FkUmVtb3RlTWFuYWdlZFNldHRpbmdzIiwicmVmcmVzaFJlbW90ZU1hbmFnZWRTZXR0aW5ncyIsIlRvb2xJbnB1dEpTT05TY2hlbWEiLCJjcmVhdGVTeW50aGV0aWNPdXRwdXRUb29sIiwiaXNTeW50aGV0aWNPdXRwdXRUb29sRW5hYmxlZCIsImdldFRvb2xzIiwiY2FuVXNlckNvbmZpZ3VyZUFkdmlzb3IiLCJnZXRJbml0aWFsQWR2aXNvclNldHRpbmciLCJpc0Fkdmlzb3JFbmFibGVkIiwiaXNWYWxpZEFkdmlzb3JNb2RlbCIsIm1vZGVsU3VwcG9ydHNBZHZpc29yIiwiaXNBZ2VudFN3YXJtc0VuYWJsZWQiLCJjb3VudCIsInVuaXEiLCJpbnN0YWxsQXNjaWljYXN0UmVjb3JkZXIiLCJnZXRTdWJzY3JpcHRpb25UeXBlIiwiaXNDbGF1ZGVBSVN1YnNjcmliZXIiLCJwcmVmZXRjaEF3c0NyZWRlbnRpYWxzQW5kQmVkUm9ja0luZm9JZlNhZmUiLCJwcmVmZXRjaEdjcENyZWRlbnRpYWxzSWZTYWZlIiwidmFsaWRhdGVGb3JjZUxvZ2luT3JnIiwiY2hlY2tIYXNUcnVzdERpYWxvZ0FjY2VwdGVkIiwiZ2V0R2xvYmFsQ29uZmlnIiwiZ2V0UmVtb3RlQ29udHJvbEF0U3RhcnR1cCIsImlzQXV0b1VwZGF0ZXJEaXNhYmxlZCIsInNhdmVHbG9iYWxDb25maWciLCJzZWVkRWFybHlJbnB1dCIsInN0b3BDYXB0dXJpbmdFYXJseUlucHV0IiwiZ2V0SW5pdGlhbEVmZm9ydFNldHRpbmciLCJwYXJzZUVmZm9ydFZhbHVlIiwiZ2V0SW5pdGlhbEZhc3RNb2RlU2V0dGluZyIsImlzRmFzdE1vZGVFbmFibGVkIiwicHJlZmV0Y2hGYXN0TW9kZVN0YXR1cyIsInJlc29sdmVGYXN0TW9kZVN0YXR1c0Zyb21DYWNoZSIsImFwcGx5Q29uZmlnRW52aXJvbm1lbnRWYXJpYWJsZXMiLCJjcmVhdGVTeXN0ZW1NZXNzYWdlIiwiY3JlYXRlVXNlck1lc3NhZ2UiLCJnZXRQbGF0Zm9ybSIsImdldEJhc2VSZW5kZXJPcHRpb25zIiwiZ2V0U2Vzc2lvbkluZ3Jlc3NBdXRoVG9rZW4iLCJzZXR0aW5nc0NoYW5nZURldGVjdG9yIiwic2tpbGxDaGFuZ2VEZXRlY3RvciIsImpzb25QYXJzZSIsIndyaXRlRmlsZVN5bmNfREVQUkVDQVRFRCIsImNvbXB1dGVJbml0aWFsVGVhbUNvbnRleHQiLCJpbml0aWFsaXplV2FybmluZ0hhbmRsZXIiLCJpc1dvcmt0cmVlTW9kZUVuYWJsZWQiLCJnZXRUZWFtbWF0ZVV0aWxzIiwicmVxdWlyZSIsImdldFRlYW1tYXRlUHJvbXB0QWRkZW5kdW0iLCJnZXRUZWFtbWF0ZU1vZGVTbmFwc2hvdCIsImNvb3JkaW5hdG9yTW9kZU1vZHVsZSIsImFzc2lzdGFudE1vZHVsZSIsImthaXJvc0dhdGUiLCJyZWxhdGl2ZSIsInJlc29sdmUiLCJpc0FuYWx5dGljc0Rpc2FibGVkIiwiZ2V0RmVhdHVyZVZhbHVlX0NBQ0hFRF9NQVlfQkVfU1RBTEUiLCJBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTIiwibG9nRXZlbnQiLCJpbml0aWFsaXplQW5hbHl0aWNzR2F0ZXMiLCJnZXRPcmlnaW5hbEN3ZCIsInNldEFkZGl0aW9uYWxEaXJlY3Rvcmllc0ZvckNsYXVkZU1kIiwic2V0SXNSZW1vdGVNb2RlIiwic2V0TWFpbkxvb3BNb2RlbE92ZXJyaWRlIiwic2V0TWFpblRocmVhZEFnZW50VHlwZSIsInNldFRlbGVwb3J0ZWRTZXNzaW9uSW5mbyIsImZpbHRlckNvbW1hbmRzRm9yUmVtb3RlTW9kZSIsImdldENvbW1hbmRzIiwiU3RhdHNTdG9yZSIsImxhdW5jaEFzc2lzdGFudEluc3RhbGxXaXphcmQiLCJsYXVuY2hBc3Npc3RhbnRTZXNzaW9uQ2hvb3NlciIsImxhdW5jaEludmFsaWRTZXR0aW5nc0RpYWxvZyIsImxhdW5jaFJlc3VtZUNob29zZXIiLCJsYXVuY2hTbmFwc2hvdFVwZGF0ZURpYWxvZyIsImxhdW5jaFRlbGVwb3J0UmVwb01pc21hdGNoRGlhbG9nIiwibGF1bmNoVGVsZXBvcnRSZXN1bWVXcmFwcGVyIiwiU0hPV19DVVJTT1IiLCJleGl0V2l0aEVycm9yIiwiZXhpdFdpdGhNZXNzYWdlIiwiZ2V0UmVuZGVyQ29udGV4dCIsInJlbmRlckFuZFJ1biIsInNob3dTZXR1cFNjcmVlbnMiLCJpbml0QnVpbHRpblBsdWdpbnMiLCJjaGVja1F1b3RhU3RhdHVzIiwiZ2V0TWNwVG9vbHNDb21tYW5kc0FuZFJlc291cmNlcyIsInByZWZldGNoQWxsTWNwUmVzb3VyY2VzIiwiVkFMSURfSU5TVEFMTEFCTEVfU0NPUEVTIiwiVkFMSURfVVBEQVRFX1NDT1BFUyIsImluaXRCdW5kbGVkU2tpbGxzIiwiQWdlbnRDb2xvck5hbWUiLCJnZXRBY3RpdmVBZ2VudHNGcm9tTGlzdCIsImdldEFnZW50RGVmaW5pdGlvbnNXaXRoT3ZlcnJpZGVzIiwiaXNCdWlsdEluQWdlbnQiLCJpc0N1c3RvbUFnZW50IiwicGFyc2VBZ2VudHNGcm9tSnNvbiIsIkxvZ09wdGlvbiIsIk1lc3NhZ2UiLCJNZXNzYWdlVHlwZSIsImFzc2VydE1pblZlcnNpb24iLCJDTEFVREVfSU5fQ0hST01FX1NLSUxMX0hJTlQiLCJDTEFVREVfSU5fQ0hST01FX1NLSUxMX0hJTlRfV0lUSF9XRUJCUk9XU0VSIiwic2V0dXBDbGF1ZGVJbkNocm9tZSIsInNob3VsZEF1dG9FbmFibGVDbGF1ZGVJbkNocm9tZSIsInNob3VsZEVuYWJsZUNsYXVkZUluQ2hyb21lIiwiZ2V0Q29udGV4dFdpbmRvd0Zvck1vZGVsIiwibG9hZENvbnZlcnNhdGlvbkZvclJlc3VtZSIsImJ1aWxkRGVlcExpbmtCYW5uZXIiLCJoYXNOb2RlT3B0aW9uIiwiaXNCYXJlTW9kZSIsImlzRW52VHJ1dGh5IiwiaXNJblByb3RlY3RlZE5hbWVzcGFjZSIsInJlZnJlc2hFeGFtcGxlQ29tbWFuZHMiLCJGcHNNZXRyaWNzIiwiZ2V0V29ya3RyZWVQYXRocyIsImZpbmRHaXRSb290IiwiZ2V0QnJhbmNoIiwiZ2V0SXNHaXQiLCJnZXRXb3JrdHJlZUNvdW50IiwiZ2V0R2hBdXRoU3RhdHVzIiwic2FmZVBhcnNlSlNPTiIsImxvZ0Vycm9yIiwiZ2V0TW9kZWxEZXByZWNhdGlvbldhcm5pbmciLCJnZXREZWZhdWx0TWFpbkxvb3BNb2RlbCIsImdldFVzZXJTcGVjaWZpZWRNb2RlbFNldHRpbmciLCJub3JtYWxpemVNb2RlbFN0cmluZ0ZvckFQSSIsInBhcnNlVXNlclNwZWNpZmllZE1vZGVsIiwiZW5zdXJ Line truncated
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwcm9maWxlQ2hlY2twb2ludCIsInByb2ZpbGVSZXBvcnQiLCJzdGFydE1kbVJhd1JlYWQiLCJlbnN1cmVLZXljaGFpblByZWZldGNoQ29tcGxldGVkIiwic3RhcnRLZXljaGFpblByZWZldGNoIiwiZmVhdHVyZSIsIkNvbW1hbmQiLCJDb21tYW5kZXJDb21tYW5kIiwiSW52YWxpZEFyZ3VtZW50RXJyb3IiLCJPcHRpb24iLCJjaGFsayIsInJlYWRGaWxlU3luYyIsIm1hcFZhbHVlcyIsInBpY2tCeSIsInVuaXFCeSIsIlJlYWN0IiwiZ2V0T2F1dGhDb25maWciLCJnZXRSZW1vdGVTZXNzaW9uVXJsIiwiZ2V0U3lzdGVtQ29udGV4dCIsImdldFVzZXJDb250ZXh0IiwiaW5pdCIsImluaXRpYWxpemVUZWxlbWV0cnlBZnRlclRydXN0IiwiYWRkVG9IaXN0b3J5IiwiUm9vdCIsImxhdW5jaFJlcGwiLCJoYXNHcm93dGhCb29rRW52T3ZlcnJpZGUiLCJpbml0aWFsaXplR3Jvd3RoQm9vayIsInJlZnJlc2hHcm93dGhCb29rQWZ0ZXJBdXRoQ2hhbmdlIiwiZmV0Y2hCb290c3RyYXBEYXRhIiwiRG93bmxvYWRSZXN1bHQiLCJkb3dubG9hZFNlc3Npb25GaWxlcyIsIkZpbGVzQXBpQ29uZmlnIiwicGFyc2VGaWxlU3BlY3MiLCJwcmVmZXRjaFBhc3Nlc0VsaWdpYmlsaXR5IiwicHJlZmV0Y2hPZmZpY2lhbE1jcFVybHMiLCJNY3BTZGtTZXJ2ZXJDb25maWciLCJNY3BTZXJ2ZXJDb25maWciLCJTY29wZWRNY3BTZXJ2ZXJDb25maWciLCJpc1BvbGljeUFsbG93ZWQiLCJsb2FkUG9saWN5TGltaXRzIiwicmVmcmVzaFBvbGljeUxpbWl0cyIsIndhaXRGb3JQb2xpY3lMaW1pdHNUb0xvYWQiLCJsb2FkUmVtb3RlTWFuYWdlZFNldHRpbmdzIiwicmVmcmVzaFJlbW90ZU1hbmFnZWRTZXR0aW5ncyIsIlRvb2xJbnB1dEpTT05TY2hlbWEiLCJjcmVhdGVTeW50aGV0aWNPdXRwdXRUb29sIiwiaXNTeW50aGV0aWNPdXRwdXRUb29sRW5hYmxlZCIsImdldFRvb2xzIiwiY2FuVXNlckNvbmZpZ3VyZUFkdmlzb3IiLCJnZXRJbml0aWFsQWR2aXNvclNldHRpbmciLCJpc0Fkdmlzb3JFbmFibGVkIiwiaXNWYWxpZEFkdmlzb3JNb2RlbCIsIm1vZGVsU3VwcG9ydHNBZHZpc29yIiwiaXNBZ2VudFN3YXJtc0VuYWJsZWQiLCJjb3VudCIsInVuaXEiLCJpbnN0YWxsQXNjaWljYXN0UmVjb3JkZXIiLCJnZXRTdWJzY3JpcHRpb25UeXBlIiwiaXNDbGF1ZGVBSVN1YnNjcmliZXIiLCJwcmVmZXRjaEF3c0NyZWRlbnRpYWxzQW5kQmVkUm9ja0luZm9JZlNhZmUiLCJwcmVmZXRjaEdjcENyZWRlbnRpYWxzSWZTYWZlIiwidmFsaWRhdGVGb3JjZUxvZ2luT3JnIiwiY2hlY2tIYXNUcnVzdERpYWxvZ0FjY2VwdGVkIiwiZ2V0R2xvYmFsQ29uZmlnIiwiZ2V0UmVtb3RlQ29udHJvbEF0U3RhcnR1cCIsImlzQXV0b1VwZGF0ZXJEaXNhYmxlZCIsInNhdmVHbG9iYWxDb25maWciLCJzZWVkRWFybHlJbnB1dCIsInN0b3BDYXB0dXJpbmdFYXJseUlucHV0IiwiZ2V0SW5pdGlhbEVmZm9ydFNldHRpbmciLCJwYXJzZUVmZm9ydFZhbHVlIiwiZ2V0SW5pdGlhbEZhc3RNb2RlU2V0dGluZyIsImlzRmFzdE1vZGVFbmFibGVkIiwicHJlZmV0Y2hGYXN0TW9kZVN0YXR1cyIsInJlc29sdmVGYXN0TW9kZVN0YXR1c0Zyb21DYWNoZSIsImFwcGx5Q29uZmlnRW52aXJvbm1lbnRWYXJpYWJsZXMiLCJjcmVhdGVTeXN0ZW1NZXNzYWdlIiwiY3JlYXRlVXNlck1lc3NhZ2UiLCJnZXRQbGF0Zm9ybSIsImdldEJhc2VSZW5kZXJPcHRpb25zIiwiZ2V0U2Vzc2lvbkluZ3Jlc3NBdXRoVG9rZW4iLCJzZXR0aW5nc0NoYW5nZURldGVjdG9yIiwic2tpbGxDaGFuZ2VEZXRlY3RvciIsImpzb25QYXJzZSIsIndyaXRlRmlsZVN5bmNfREVQUkVDQVRFRCIsImNvbXB1dGVJbml0aWFsVGVhbUNvbnRleHQiLCJpbml0aWFsaXplV2FybmluZ0hhbmRsZXIiLCJpc1dvcmt0cmVlTW9kZUVuYWJsZWQiLCJnZXRUZWFtbWF0ZVV0aWxzIiwicmVxdWlyZSIsImdldFRlYW1tYXRlUHJvbXB0QWRkZW5kdW0iLCJnZXRUZWFtbWF0ZU1vZGVTbmFwc2hvdCIsImNvb3JkaW5hdG9yTW9kZU1vZHVsZSIsImFzc2lzdGFudE1vZHVsZSIsImthaXJvc0dhdGUiLCJyZWxhdGl2ZSIsInJlc29sdmUiLCJpc0FuYWx5dGljc0Rpc2FibGVkIiwiZ2V0RmVhdHVyZVZhbHVlX0NBQ0hFRF9NQVlfQkVfU1RBTEUiLCJBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTIiwibG9nRXZlbnQiLCJpbml0aWFsaXplQW5hbHl0aWNzR2F0ZXMiLCJnZXRPcmlnaW5hbEN3ZCIsInNldEFkZGl0aW9uYWxEaXJlY3Rvcmllc0ZvckNsYXVkZU1kIiwic2V0SXNSZW1vdGVNb2RlIiwic2V0TWFpbkxvb3BNb2RlbE92ZXJyaWRlIiwic2V0TWFpblRocmVhZEFnZW50VHlwZSIsInNldFRlbGVwb3J0ZWRTZXNzaW9uSW5mbyIsImZpbHRlckNvbW1hbmRzRm9yUmVtb3RlTW9kZSIsImdldENvbW1hbmRzIiwiU3RhdHNTdG9yZSIsImxhdW5jaEFzc2lzdGFudEluc3RhbGxXaXphcmQiLCJsYXVuY2hBc3Npc3RhbnRTZXNzaW9uQ2hvb3NlciIsImxhdW5jaEludmFsaWRTZXR0aW5nc0RpYWxvZyIsImxhdW5jaFJlc3VtZUNob29zZXIiLCJsYXVuY2hTbmFwc2hvdFVwZGF0ZURpYWxvZyIsImxhdW5jaFRlbGVwb3J0UmVwb01pc21hdGNoRGlhbG9nIiwibGF1bmNoVGVsZXBvcnRSZXN1bWVXcmFwcGVyIiwiU0hPV19DVVJTT1IiLCJleGl0V2l0aEVycm9yIiwiZXhpdFdpdGhNZXNzYWdlIiwiZ2V0UmVuZGVyQ29udGV4dCIsInJlbmRlckFuZFJ1biIsInNob3dTZXR1cFNjcmVlbnMiLCJpbml0QnVpbHRpblBsdWdpbnMiLCJjaGVja1F1b3RhU3RhdHVzIiwiZ2V0TWNwVG9vbHNDb21tYW5kc0FuZFJlc291cmNlcyIsInByZWZldGNoQWxsTWNwUmVzb3VyY2VzIiwiVkFMSURfSU5TVEFMTEFCTEVfU0NPUEVTIiwiVkFMSURfVVBEQVRFX1NDT1BFUyIsImluaXRCdW5kbGVkU2tpbGxzIiwiQWdlbnRDb2xvck5hbWUiLCJnZXRBY3RpdmVBZ2VudHNGcm9tTGlzdCIsImdldEFnZW50RGVmaW5pdGlvbnNXaXRoT3ZlcnJpZGVzIiwiaXNCdWlsdEluQWdlbnQiLCJpc0N1c3RvbUFnZW50IiwicGFyc2VBZ2VudHNGcm9tSnNvbiIsIkxvZ09wdGlvbiIsIk1lc3NhZ2UiLCJNZXNzYWdlVHlwZSIsImFzc2VydE1pblZlcnNpb24iLCJDTEFVREVfSU5fQ0hST01FX1NLSUxMX0hJTlQiLCJDTEFVREVfSU5fQ0hST01FX1NLSUxMX0hJTlRfV0lUSF9XRUJCUk9XU0VSIiwic2V0dXBDbGF1ZGVJbkNocm9tZSIsInNob3VsZEF1dG9FbmFibGVDbGF1ZGVJbkNocm9tZSIsInNob3VsZEVuYWJsZUNsYXVkZUluQ2hyb21lIiwiZ2V0Q29udGV4dFdpbmRvd0Zvck1vZGVsIiwibG9hZENvbnZlcnNhdGlvbkZvclJlc3VtZSIsImJ1aWxkRGVlcExpbmtCYW5uZXIiLCJoYXNOb2RlT3B0aW9uIiwiaXNCYXJlTW9kZSIsImlzRW52VHJ1dGh5IiwiaXNJblByb3RlY3RlZE5hbWVzcGFjZSIsInJlZnJlc2hFeGFtcGxlQ29tbWFuZHMiLCJGcHNNZXRyaWNzIiwiZ2V0V29ya3RyZWVQYXRocyIsImZpbmRHaXRSb290IiwiZ2V0QnJhbmNoIiwiZ2V0SXNHaXQiLCJnZXRXb3JrdHJlZUNvdW50IiwiZ2V0R2hBdXRoU3RhdHVzIiwic2FmZVBhcnNlSlNPTiIsImxvZ0Vycm9yIiwiZ2V0TW9kZWxEZXByZWNhdGlvbldhcm5pbmciLCJnZXREZWZhdWx0TWFpbkxvb3BNb2RlbCIsImdldFVzZXJTcGVjaWZpZWRNb2RlbFNldHRpbmciLCJub3JtYWxpemVNb2RlbFN0cmluZ0ZvckFQSSIsInBhcnNlVXNlclNwZWNpZmllZE1vZGVsIiwiZW5zdXJ Line truncated
+19
View File
@@ -0,0 +1,19 @@
export type CachedMCConfig = {
enabled: boolean
triggerThreshold: number
keepRecent: number
supportedModels: string[]
systemPromptSuggestSummaries: boolean
}
const DEFAULT_CACHED_MC_CONFIG: CachedMCConfig = {
enabled: false,
triggerThreshold: 12,
keepRecent: 3,
supportedModels: ['claude-opus-4-6', 'claude-sonnet-4-6'],
systemPromptSuggestSummaries: false,
}
export function getCachedMCConfig(): CachedMCConfig {
return DEFAULT_CACHED_MC_CONFIG
}
+104
View File
@@ -0,0 +1,104 @@
import {
getCachedMCConfig,
type CachedMCConfig,
} from './cachedMCConfig.js'
export type CacheEditsBlock = {
type: 'cache_edits'
edits: { type: 'delete'; cache_reference: string }[]
}
export type PinnedCacheEdits = {
userMessageIndex: number
block: CacheEditsBlock
}
export type CachedMCState = {
pinnedEdits: PinnedCacheEdits[]
registeredTools: Set<string>
toolOrder: string[]
deletedRefs: Set<string>
}
export function createCachedMCState(): CachedMCState {
return {
pinnedEdits: [],
registeredTools: new Set(),
toolOrder: [],
deletedRefs: new Set(),
}
}
export function isCachedMicrocompactEnabled(): boolean {
return getCachedMCConfig().enabled
}
export function isModelSupportedForCacheEditing(model: string): boolean {
return getCachedMCConfig().supportedModels.some(pattern =>
model.includes(pattern),
)
}
export { getCachedMCConfig }
export type { CachedMCConfig }
export function registerToolResult(
state: CachedMCState,
toolUseId: string,
): void {
if (state.registeredTools.has(toolUseId)) {
return
}
state.registeredTools.add(toolUseId)
state.toolOrder.push(toolUseId)
}
export function registerToolMessage(
_state: CachedMCState,
_toolUseIds: string[],
): void {}
export function getToolResultsToDelete(state: CachedMCState): string[] {
const config = getCachedMCConfig()
const activeRefs = state.toolOrder.filter(id => !state.deletedRefs.has(id))
if (!config.enabled || activeRefs.length < config.triggerThreshold) {
return []
}
return activeRefs.slice(0, Math.max(0, activeRefs.length - config.keepRecent))
}
export function createCacheEditsBlock(
state: CachedMCState,
toolUseIds: string[],
): CacheEditsBlock | null {
const edits = toolUseIds
.filter(id => !state.deletedRefs.has(id))
.map(id => {
state.deletedRefs.add(id)
return {
type: 'delete' as const,
cache_reference: id,
}
})
if (edits.length === 0) {
return null
}
return {
type: 'cache_edits',
edits,
}
}
export function markToolsSentToAPI(_state: CachedMCState): void {}
export function resetCachedMCState(state: CachedMCState): void {
state.pinnedEdits.length = 0
state.registeredTools.clear()
state.toolOrder.length = 0
state.deletedRefs.clear()
}
+39
View File
@@ -0,0 +1,39 @@
type SnipLikeMessage = {
type?: string
subtype?: string
}
export const SNIP_NUDGE_TEXT =
'Context-efficiency hints are unavailable in this reconstructed source snapshot.'
export function isSnipRuntimeEnabled(): boolean {
return false
}
export function shouldNudgeForSnips(_messages: readonly unknown[]): boolean {
return false
}
export function isSnipMarkerMessage(message: unknown): boolean {
return (
typeof message === 'object' &&
message !== null &&
(message as SnipLikeMessage).subtype === 'snip_marker'
)
}
export function snipCompactIfNeeded<T>(
messages: T[],
_options?: { force?: boolean },
): {
messages: T[]
tokensFreed: number
boundaryMessage?: T
executed: boolean
} {
return {
messages,
tokensFreed: 0,
executed: false,
}
}
+16
View File
@@ -0,0 +1,16 @@
type BoundaryLikeMessage = {
type?: string
subtype?: string
}
export function isSnipBoundaryMessage(message: unknown): boolean {
return (
typeof message === 'object' &&
message !== null &&
(message as BoundaryLikeMessage).subtype === 'snip_boundary'
)
}
export function projectSnippedView<T>(messages: T[]): T[] {
return messages
}
+67
View File
@@ -0,0 +1,67 @@
type ContextCollapseStats = {
collapsedSpans: number
collapsedMessages: number
stagedSpans: number
health: {
totalErrors: number
totalEmptySpawns: number
totalSpawns: number
emptySpawnWarningEmitted: boolean
lastError: string | null
}
}
const EMPTY_STATS: ContextCollapseStats = {
collapsedSpans: 0,
collapsedMessages: 0,
stagedSpans: 0,
health: {
totalErrors: 0,
totalEmptySpawns: 0,
totalSpawns: 0,
emptySpawnWarningEmitted: false,
lastError: null,
},
}
export function initContextCollapse(): void {}
export function resetContextCollapse(): void {}
export function isContextCollapseEnabled(): boolean {
return false
}
export function getStats(): ContextCollapseStats {
return EMPTY_STATS
}
export function subscribe(_callback: () => void): () => void {
return () => {}
}
export async function applyCollapsesIfNeeded<T>(
messages: T[],
_toolUseContext: unknown,
_querySource?: string,
): Promise<{ messages: T[] }> {
return { messages }
}
export function recoverFromOverflow<T>(
messages: T[],
_querySource?: string,
): { messages: T[]; committed: number } {
return {
messages,
committed: 0,
}
}
export function isWithheldPromptTooLong(
_message: unknown,
_isPromptTooLongMessage: (message: unknown) => boolean,
_querySource?: string,
): boolean {
return false
}
@@ -0,0 +1,3 @@
export function projectView<T>(messages: T[]): T[] {
return messages
}
+4
View File
@@ -0,0 +1,4 @@
export function restoreFromEntries(
_commits: unknown[],
_snapshot: unknown,
): void {}
+4 -2
View File
@@ -910,9 +910,11 @@ export const connectToServer = memoize(
const { createChromeContext } = await import(
'../../utils/claudeInChrome/mcpServer.js'
)
const { createClaudeForChromeMcpServer } = await import(
'@ant/claude-for-chrome-mcp'
const { importClaudeForChromePackage } = await import(
'../../utils/claudeInChrome/package.js'
)
const { createClaudeForChromeMcpServer } =
await importClaudeForChromePackage()
const { createLinkedTransportPair } = await import(
'./InProcessTransport.js'
)
+6 -6
View File
@@ -1,12 +1,8 @@
import { BROWSER_TOOLS } from '@ant/claude-for-chrome-mcp'
import { BASE_CHROME_PROMPT } from '../../utils/claudeInChrome/prompt.js'
import { getChromeBrowserTools } from '../../utils/claudeInChrome/package.js'
import { shouldAutoEnableClaudeInChrome } from '../../utils/claudeInChrome/setup.js'
import { registerBundledSkill } from '../bundledSkills.js'
const CLAUDE_IN_CHROME_MCP_TOOLS = BROWSER_TOOLS.map(
tool => `mcp__claude-in-chrome__${tool.name}`,
)
const SKILL_ACTIVATION_MESSAGE = `
Now that this skill is invoked, you have access to Chrome browser automation tools. You can now use the mcp__claude-in-chrome__* tools to interact with web pages.
@@ -14,13 +10,17 @@ IMPORTANT: Start by calling mcp__claude-in-chrome__tabs_context_mcp to get infor
`
export function registerClaudeInChromeSkill(): void {
const allowedTools = getChromeBrowserTools().map(
tool => `mcp__claude-in-chrome__${tool.name}`,
)
registerBundledSkill({
name: 'claude-in-chrome',
description:
'Automates your Chrome browser to interact with web pages - clicking elements, filling forms, capturing screenshots, reading console logs, and navigating sites. Opens pages in new tabs within your existing Chrome session. Requires site-level permissions before executing (configured in the extension).',
whenToUse:
'When the user wants to interact with web pages, automate browser tasks, capture screenshots, read console logs, or perform any browser-based actions. Always invoke BEFORE attempting to use any mcp__claude-in-chrome__* tools.',
allowedTools: CLAUDE_IN_CHROME_MCP_TOOLS,
allowedTools,
userInvocable: true,
isEnabled: () => shouldAutoEnableClaudeInChrome(),
async getPromptForCommand(args) {
+10 -8
View File
@@ -1,13 +1,15 @@
// Content for the verify bundled skill.
// Each .md file is inlined as a string at build time via Bun's text loader.
// The published snapshot is missing the bundled verify markdown assets.
// Keep the module shape intact with minimal placeholder content so the CLI
// can build and the feature can fail gracefully if reached.
import cliMd from './verify/examples/cli.md'
import serverMd from './verify/examples/server.md'
import skillMd from './verify/SKILL.md'
export const SKILL_MD = `# Verify
export const SKILL_MD: string = skillMd
This reconstructed source snapshot does not include the original bundled
verify skill content.
`
export const SKILL_FILES: Record<string, string> = {
'examples/cli.md': cliMd,
'examples/server.md': serverMd,
'examples/cli.md': '# Verify CLI example\n\nUnavailable in this snapshot.\n',
'examples/server.md':
'# Verify server example\n\nUnavailable in this snapshot.\n',
}
@@ -0,0 +1,3 @@
export function TungstenLiveMonitor() {
return null
}
+72
View File
@@ -0,0 +1,72 @@
import { z } from 'zod/v4'
import { buildTool, type ToolDef } from '../../Tool.js'
import { lazySchema } from '../../utils/lazySchema.js'
export const TUNGSTEN_TOOL_NAME = 'Tungsten'
const inputSchema = lazySchema(() => z.strictObject({}))
type InputSchema = ReturnType<typeof inputSchema>
const outputSchema = lazySchema(() =>
z.object({
available: z.boolean(),
message: z.string(),
}),
)
type OutputSchema = ReturnType<typeof outputSchema>
type Output = z.infer<OutputSchema>
const UNAVAILABLE_MESSAGE =
'Tungsten is only available in Anthropic internal builds.'
export function clearSessionsWithTungstenUsage(): void {}
export function resetInitializationState(): void {}
export const TungstenTool = buildTool({
name: TUNGSTEN_TOOL_NAME,
maxResultSizeChars: 4_096,
get inputSchema(): InputSchema {
return inputSchema()
},
get outputSchema(): OutputSchema {
return outputSchema()
},
isEnabled() {
return false
},
isConcurrencySafe() {
return false
},
isReadOnly() {
return true
},
async description() {
return UNAVAILABLE_MESSAGE
},
async prompt() {
return UNAVAILABLE_MESSAGE
},
mapToolResultToToolResultBlockParam(output: Output, toolUseID: string) {
return {
tool_use_id: toolUseID,
type: 'tool_result',
content: output.message,
}
},
renderToolUseMessage() {
return null
},
renderToolResultMessage() {
return null
},
async call() {
return {
data: {
available: false,
message: UNAVAILABLE_MESSAGE,
},
}
},
} satisfies ToolDef<InputSchema, Output>)
@@ -0,0 +1,67 @@
import { z } from 'zod/v4'
import { buildTool, type ToolDef } from '../../Tool.js'
import { lazySchema } from '../../utils/lazySchema.js'
import { VERIFY_PLAN_EXECUTION_TOOL_NAME } from './constants.js'
const inputSchema = lazySchema(() => z.strictObject({}))
type InputSchema = ReturnType<typeof inputSchema>
const outputSchema = lazySchema(() =>
z.object({
verified: z.boolean(),
message: z.string(),
}),
)
type OutputSchema = ReturnType<typeof outputSchema>
type Output = z.infer<OutputSchema>
const UNAVAILABLE_MESSAGE =
'Plan execution verification is unavailable in this reconstructed build.'
export const VerifyPlanExecutionTool = buildTool({
name: VERIFY_PLAN_EXECUTION_TOOL_NAME,
maxResultSizeChars: 4_096,
get inputSchema(): InputSchema {
return inputSchema()
},
get outputSchema(): OutputSchema {
return outputSchema()
},
isEnabled() {
return false
},
isConcurrencySafe() {
return true
},
isReadOnly() {
return true
},
async description() {
return UNAVAILABLE_MESSAGE
},
async prompt() {
return UNAVAILABLE_MESSAGE
},
mapToolResultToToolResultBlockParam(output: Output, toolUseID: string) {
return {
tool_use_id: toolUseID,
type: 'tool_result',
content: output.message,
}
},
renderToolUseMessage() {
return null
},
renderToolResultMessage() {
return null
},
async call() {
return {
data: {
verified: false,
message: UNAVAILABLE_MESSAGE,
},
}
},
} satisfies ToolDef<InputSchema, Output>)
@@ -0,0 +1 @@
export const VERIFY_PLAN_EXECUTION_TOOL_NAME = 'VerifyPlanExecution'
+1
View File
@@ -0,0 +1 @@
export const WORKFLOW_TOOL_NAME = 'Workflow'
+22
View File
@@ -0,0 +1,22 @@
export type ConnectorTextBlock = {
type: 'connector_text'
connector_text: string
}
export type ConnectorTextDelta = {
type: 'connector_text_delta'
connector_text: string
}
export function isConnectorTextBlock(
value: unknown,
): value is ConnectorTextBlock {
return (
typeof value === 'object' &&
value !== null &&
'type' in value &&
'connector_text' in value &&
(value as { type?: unknown }).type === 'connector_text' &&
typeof (value as { connector_text?: unknown }).connector_text === 'string'
)
}
+6 -8
View File
@@ -1,9 +1,3 @@
import {
type ClaudeForChromeContext,
createClaudeForChromeMcpServer,
type Logger,
type PermissionMode,
} from '@ant/claude-for-chrome-mcp'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { format } from 'util'
import { shutdownDatadog } from '../../services/analytics/datadog.js'
@@ -20,6 +14,7 @@ import { logForDebugging } from '../debug.js'
import { isEnvTruthy } from '../envUtils.js'
import { sideQuery } from '../sideQuery.js'
import { getAllSocketPaths, getSecureSocketPath } from './common.js'
import { importClaudeForChromePackage } from './package.js'
const EXTENSION_DOWNLOAD_URL = 'https://claude.ai/chrome'
const BUG_REPORT_URL =
@@ -39,6 +34,8 @@ const PERMISSION_MODES: readonly PermissionMode[] = [
'follow_a_plan',
]
type PermissionMode = (typeof PERMISSION_MODES)[number]
function isPermissionMode(raw: string): raw is PermissionMode {
return PERMISSION_MODES.some(m => m === raw)
}
@@ -84,7 +81,7 @@ function isLocalBridge(): boolean {
*/
export function createChromeContext(
env?: Record<string, string>,
): ClaudeForChromeContext {
) {
const logger = new DebugLogger()
const chromeBridgeUrl = getChromeBridgeUrl()
logger.info(`Bridge URL: ${chromeBridgeUrl ?? 'none (using native socket)'}`)
@@ -249,6 +246,7 @@ export async function runClaudeInChromeMcpServer(): Promise<void> {
enableConfigs()
initializeAnalyticsSink()
const context = createChromeContext()
const { createClaudeForChromeMcpServer } = await importClaudeForChromePackage()
const server = createClaudeForChromeMcpServer(context)
const transport = new StdioServerTransport()
@@ -274,7 +272,7 @@ export async function runClaudeInChromeMcpServer(): Promise<void> {
logForDebugging('[Claude in Chrome] MCP server started')
}
class DebugLogger implements Logger {
class DebugLogger {
silly(message: string, ...args: unknown[]): void {
logForDebugging(format(message, ...args), { level: 'debug' })
}
+32
View File
@@ -0,0 +1,32 @@
type BrowserTool = { name: string }
type ClaudeForChromePackage = {
BROWSER_TOOLS?: BrowserTool[]
createClaudeForChromeMcpServer?: (...args: any[]) => any
}
let cachedPackage: ClaudeForChromePackage | null | undefined
function loadClaudeForChromePackage(): ClaudeForChromePackage | null {
if (cachedPackage !== undefined) {
return cachedPackage
}
try {
/* eslint-disable @typescript-eslint/no-require-imports */
cachedPackage = require('@ant/claude-for-chrome-mcp') as ClaudeForChromePackage
/* eslint-enable @typescript-eslint/no-require-imports */
} catch {
cachedPackage = null
}
return cachedPackage
}
export function getChromeBrowserTools(): BrowserTool[] {
return loadClaudeForChromePackage()?.BROWSER_TOOLS ?? []
}
export async function importClaudeForChromePackage(): Promise<ClaudeForChromePackage> {
return (await import('@ant/claude-for-chrome-mcp')) as ClaudeForChromePackage
}
+2 -2
View File
@@ -1,4 +1,3 @@
import { BROWSER_TOOLS } from '@ant/claude-for-chrome-mcp'
import { chmod, mkdir, readFile, writeFile } from 'fs/promises'
import { homedir } from 'os'
import { join } from 'path'
@@ -28,6 +27,7 @@ import {
getAllWindowsRegistryKeys,
openInChrome,
} from './common.js'
import { getChromeBrowserTools } from './package.js'
import { getChromeSystemPrompt } from './prompt.js'
import { isChromeExtensionInstalledPortable } from './setupPortable.js'
@@ -94,7 +94,7 @@ export function setupClaudeInChrome(): {
systemPrompt: string
} {
const isNativeBuild = isInBundledMode()
const allowedTools = BROWSER_TOOLS.map(
const allowedTools = getChromeBrowserTools().map(
tool => `mcp__claude-in-chrome__${tool.name}`,
)
+1 -1
View File
@@ -84,7 +84,7 @@ export const getDebugFilter = memoize((): DebugFilter | null => {
export const isDebugToStdErr = memoize((): boolean => {
return (
process.argv.includes('--debug-to-stderr') || process.argv.includes('-d2e')
process.argv.includes('--debug-to-stderr') || process.argv.includes('-D')
)
})
+20
View File
@@ -0,0 +1,20 @@
export const DEFAULT_UPLOAD_CONCURRENCY = 4
export const FILE_COUNT_LIMIT = 200
export const OUTPUTS_SUBDIR = 'outputs'
export type TurnStartTime = number
export type PersistedFile = {
filename: string
file_id: string
}
export type FailedPersistence = {
filename: string
error: string
}
export type FilesPersistedEventData = {
files: PersistedFile[]
failed: FailedPersistence[]
}
+6
View File
@@ -0,0 +1,6 @@
Create a concise, execution-ready plan for the user's request.
Focus on:
- The smallest set of steps that will actually unblock implementation
- Clear assumptions and risks
- Concrete deliverables instead of generic brainstorming
+23
View File
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
"types": ["bun"],
"baseUrl": ".",
"paths": {
"src/*": ["src/*"]
},
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"strict": false,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "scripts", "env.d.ts"]
}