Files
claude-code/packages/acp-link/src/server/runtime-state.ts
claude-code-best 65f81de52b refactor: 拆分 3 个过大 ACP 文件为模块化子文件(每个 <500 行)
通过 4 阶段 workflow(分析 → 计划 → 重构 → 验证)将 3 个超大的 ACP
源文件拆分为 28 个模块化子文件,每个均严格小于 500 行,且完整保留
所有公共 API(barrel 模式重导出)。

变更概要:
- packages/acp-link/src/server.ts: 1800 → 20 行(barrel),新增 11 个子模块
  (server/types、payload-decode、permission-mode、runtime-state、dispatch、
  handlers-agent、handlers-session、acp-client、client-send、start-server、
  testing-internals)
- src/services/acp/agent.ts: 1297 → 33 行(barrel),新增 9 个子模块
  (agent/AcpAgent、sessionTypes、permissionMode、configOptions、promptQueue、
  internalAccessors、createSessionMethod、sessionLifecycle、promptFlow)
- src/services/acp/bridge.ts: 1516 → 29 行(barrel),新增 8 个子模块
  (bridge/types、paths、contentBlocks、toolInfo、toolResults、modelUsage、
  notifications、forwarding)

验证:
- bun run precheck 全通过(typecheck + lint + 5851 tests)
- ACP service tests: 176 pass / 0 fail
- ACP link tests: 47 pass / 0 fail
- 所有外部消费者(entry.ts、permissions.ts、__tests__/)的 import 路径不变
- 测试文件零修改

迁移计划详见 docs/acp-refactor-plan.md。

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
2026-06-20 12:38:43 +08:00

126 lines
3.1 KiB
TypeScript

import type { WSContext } from 'hono/ws'
import { createLogger } from '../logger.js'
import type { RcsUpstreamClient } from '../rcs-upstream.js'
import type { ClientState } from './types.js'
// Module-level state (set when server starts)
let AGENT_COMMAND: string
let AGENT_ARGS: string[]
let AGENT_CWD: string
let SERVER_PORT: number
let SERVER_HOST: string
let AUTH_TOKEN: string | undefined
let DEFAULT_PERMISSION_MODE: string | undefined
export const clients = new Map<WSContext, ClientState>()
// Module-scoped child loggers
export const logWs = createLogger('ws')
export const logAgent = createLogger('agent')
export const logSession = createLogger('session')
export const logPrompt = createLogger('prompt')
export const logPerm = createLogger('perm')
export const logRelay = createLogger('relay')
export const logServer = createLogger('server')
// RCS upstream client (optional — enabled via ACP_RCS_URL env var)
let rcsUpstream: RcsUpstreamClient | null = null
// Permission request timeout (5 minutes)
export const PERMISSION_TIMEOUT_MS = 5 * 60 * 1000
// Heartbeat interval for WebSocket ping/pong (30 seconds)
export const HEARTBEAT_INTERVAL_MS = 30_000
export interface ServerConfigFields {
command: string
args: string[]
cwd: string
port: number
host: string
token?: string
permissionMode?: string
}
export function setServerConfig(fields: ServerConfigFields): void {
AGENT_COMMAND = fields.command
AGENT_ARGS = fields.args
AGENT_CWD = fields.cwd
SERVER_PORT = fields.port
SERVER_HOST = fields.host
AUTH_TOKEN = fields.token
DEFAULT_PERMISSION_MODE = fields.permissionMode
}
export interface ServerConfigSnapshot {
command: string
args: string[]
cwd: string
port: number
host: string
token?: string
}
export function getServerConfig(): ServerConfigSnapshot {
return {
command: AGENT_COMMAND,
args: AGENT_ARGS,
cwd: AGENT_CWD,
port: SERVER_PORT,
host: SERVER_HOST,
token: AUTH_TOKEN,
}
}
export function getAgentConfig(): ServerConfigSnapshot {
return getServerConfig()
}
export function getAuthToken(): string | undefined {
return AUTH_TOKEN
}
export function getDefaultPermissionMode(): string | undefined {
return DEFAULT_PERMISSION_MODE
}
export function setDefaultPermissionMode(
mode: string | undefined,
): string | undefined {
const previous = DEFAULT_PERMISSION_MODE
DEFAULT_PERMISSION_MODE = mode
return previous
}
export function getRcsUpstream(): RcsUpstreamClient | null {
return rcsUpstream
}
export function setRcsUpstream(client: RcsUpstreamClient | null): void {
rcsUpstream = client
}
/**
* Create a virtual WSContext for RCS relay messages.
* Responses via send() go to RCS upstream (not a local WS).
*/
export function createRelayWs(): WSContext {
return {
get readyState() {
return 1
}, // always OPEN
send: () => {}, // no-op — responses go through rcsUpstream.send()
close: () => {},
raw: null,
isInner: false,
url: '',
origin: '',
protocol: '',
} as unknown as WSContext
}
// Generate unique request ID
export function generateRequestId(): string {
return `perm_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`
}