From 9e507bd8238cf6ee224a9a5afc7820eaf2c7f9c7 Mon Sep 17 00:00:00 2001 From: claude-code-best Date: Sat, 20 Jun 2026 11:38:02 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E7=A7=BB=E9=99=A4=20src/=20=E4=B8=8B?= =?UTF-8?q?=E5=A4=9A=E5=A4=84=E6=9C=AA=E5=BC=95=E7=94=A8=E7=9A=84=E5=AF=BC?= =?UTF-8?q?=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 涉及 18 个文件,每处均为独立的 unreferenced export 删除或 export 关键字冗余移除: - bridge/bridgeStatusUtil.ts、components/TrustDialog/utils.ts、context/stats.tsx - keybindings/loadUserBindings.ts、memdir/paths.ts、remote/sdkMessageAdapter.ts - services/acp/utils.ts(删除 nodeToWebReadable,全仓零引用) - services/api/metricsOptOut.ts、services/lsp/LSPDiagnosticRegistry.ts、services/lsp/manager.ts - services/mcp/utils.ts、services/skillLearning/projectContext.ts - services/teamMemorySync/secretScanner.ts、services/teamMemorySync/watcher.ts - skills/loadSkillsDir.ts、utils/attachments.ts、utils/filePersistence/filePersistence.ts - utils/messageQueueManager.ts Co-Authored-By: glm-5.2 --- src/bridge/bridgeStatusUtil.ts | 5 --- src/components/TrustDialog/utils.ts | 32 ------------------ src/context/stats.tsx | 5 --- src/keybindings/loadUserBindings.ts | 16 --------- src/memdir/paths.ts | 16 --------- src/remote/sdkMessageAdapter.ts | 10 ------ src/services/acp/utils.ts | 16 +-------- src/services/api/metricsOptOut.ts | 5 --- src/services/lsp/LSPDiagnosticRegistry.ts | 7 ---- src/services/lsp/manager.ts | 13 -------- src/services/mcp/utils.ts | 9 ----- src/services/skillLearning/projectContext.ts | 5 --- src/services/teamMemorySync/secretScanner.ts | 21 ------------ src/services/teamMemorySync/watcher.ts | 35 -------------------- src/skills/loadSkillsDir.ts | 7 ---- src/utils/attachments.ts | 2 +- src/utils/filePersistence/filePersistence.ts | 28 ++++------------ src/utils/messageQueueManager.ts | 32 ------------------ 18 files changed, 9 insertions(+), 255 deletions(-) diff --git a/src/bridge/bridgeStatusUtil.ts b/src/bridge/bridgeStatusUtil.ts index e5a7706f7..eb1504753 100644 --- a/src/bridge/bridgeStatusUtil.ts +++ b/src/bridge/bridgeStatusUtil.ts @@ -28,11 +28,6 @@ export function timestamp(): string { export { formatDuration, truncateToWidth as truncatePrompt } -/** Abbreviate a tool activity summary for the trail display. */ -export function abbreviateActivity(summary: string): string { - return truncateToWidth(summary, 30) -} - /** Build the connect URL shown when the bridge is idle. */ export function buildBridgeConnectUrl( environmentId: string, diff --git a/src/components/TrustDialog/utils.ts b/src/components/TrustDialog/utils.ts index 4e8db9f97..827b80772 100644 --- a/src/components/TrustDialog/utils.ts +++ b/src/components/TrustDialog/utils.ts @@ -71,38 +71,6 @@ export function getBashPermissionSources(): string[] { return sources } -/** - * Format a list of items with proper "and" conjunction. - * @param items - Array of items to format - * @param limit - Optional limit for how many items to show before summarizing (ignored if 0) - */ -export function formatListWithAnd(items: string[], limit?: number): string { - if (items.length === 0) return '' - - // Ignore limit if it's 0 - const effectiveLimit = limit === 0 ? undefined : limit - - // If no limit or items are within limit, use normal formatting - if (!effectiveLimit || items.length <= effectiveLimit) { - if (items.length === 1) return items[0]! - if (items.length === 2) return `${items[0]} and ${items[1]}` - - const lastItem = items[items.length - 1]! - const allButLast = items.slice(0, -1) - return `${allButLast.join(', ')}, and ${lastItem}` - } - - // If we have more items than the limit, show first few and count the rest - const shown = items.slice(0, effectiveLimit) - const remaining = items.length - effectiveLimit - - if (shown.length === 1) { - return `${shown[0]} and ${remaining} more` - } - - return `${shown.join(', ')}, and ${remaining} more` -} - /** * Check if settings have otelHeadersHelper configured */ diff --git a/src/context/stats.tsx b/src/context/stats.tsx index 395bf3fd3..ddf1285c3 100644 --- a/src/context/stats.tsx +++ b/src/context/stats.tsx @@ -137,11 +137,6 @@ export function useStats(): StatsStore { return store; } -export function useCounter(name: string): (value?: number) => void { - const store = useStats(); - return useCallback((value?: number) => store.increment(name, value), [store, name]); -} - export function useGauge(name: string): (value: number) => void { const store = useStats(); return useCallback((value: number) => store.set(name, value), [store, name]); diff --git a/src/keybindings/loadUserBindings.ts b/src/keybindings/loadUserBindings.ts index 416abe7a1..37520879f 100644 --- a/src/keybindings/loadUserBindings.ts +++ b/src/keybindings/loadUserBindings.ts @@ -454,19 +454,3 @@ function handleDelete(path: string): void { export function getCachedKeybindingWarnings(): KeybindingWarning[] { return cachedWarnings } - -/** - * Reset internal state for testing. - */ -export function resetKeybindingLoaderForTesting(): void { - initialized = false - disposed = false - cachedBindings = null - cachedWarnings = [] - lastCustomBindingsLogDate = null - if (watcher) { - void watcher.close() - watcher = null - } - keybindingsChanged.clear() -} diff --git a/src/memdir/paths.ts b/src/memdir/paths.ts index 68a6baf04..626555649 100644 --- a/src/memdir/paths.ts +++ b/src/memdir/paths.ts @@ -234,22 +234,6 @@ export const getAutoMemPath = memoize( () => getProjectRoot(), ) -/** - * Returns the daily log file path for the given date (defaults to today). - * Shape: /logs/YYYY/MM/YYYY-MM-DD.md - * - * Used by assistant mode (feature('KAIROS')): rather than maintaining - * MEMORY.md as a live index, the agent appends to a date-named log file - * as it works. A separate nightly /dream skill distills these logs into - * topic files + MEMORY.md. - */ -export function getAutoMemDailyLogPath(date: Date = new Date()): string { - const yyyy = date.getFullYear().toString() - const mm = (date.getMonth() + 1).toString().padStart(2, '0') - const dd = date.getDate().toString().padStart(2, '0') - return join(getAutoMemPath(), 'logs', yyyy, mm, `${yyyy}-${mm}-${dd}.md`) -} - /** * Returns the auto-memory entrypoint (MEMORY.md inside the auto-memory dir). * Follows the same resolution order as getAutoMemPath(). diff --git a/src/remote/sdkMessageAdapter.ts b/src/remote/sdkMessageAdapter.ts index 9158fde5b..29ea3a0ad 100644 --- a/src/remote/sdkMessageAdapter.ts +++ b/src/remote/sdkMessageAdapter.ts @@ -313,13 +313,3 @@ export function isSessionEndMessage(msg: SDKMessage): boolean { export function isSuccessResult(msg: SDKResultMessage): boolean { return msg.subtype === 'success' } - -/** - * Extract the result text from a successful SDKResultMessage - */ -export function getResultText(msg: SDKResultMessage): string | null { - if (msg.subtype === 'success') { - return msg.result ?? null - } - return null -} diff --git a/src/services/acp/utils.ts b/src/services/acp/utils.ts index 0ce4c2057..9e7ab92df 100644 --- a/src/services/acp/utils.ts +++ b/src/services/acp/utils.ts @@ -2,7 +2,7 @@ * Shared utilities for the ACP service. * Ported from claude-agent-acp-main/src/utils.ts and acp-agent.ts helpers. */ -import { Readable, Writable } from 'node:stream' +import { Writable } from 'node:stream' import type { PermissionMode } from '../../entrypoints/sdk/coreTypes.generated.js' // ── Pushable ────────────────────────────────────────────────────── @@ -71,20 +71,6 @@ export function nodeToWebWritable( }) } -export function nodeToWebReadable( - nodeStream: Readable, -): ReadableStream { - return new ReadableStream({ - start(controller) { - nodeStream.on('data', (chunk: Buffer) => { - controller.enqueue(new Uint8Array(chunk)) - }) - nodeStream.on('end', () => controller.close()) - nodeStream.on('error', err => controller.error(err)) - }, - }) -} - // ── unreachable ─────────────────────────────────────────────────── export function unreachable( diff --git a/src/services/api/metricsOptOut.ts b/src/services/api/metricsOptOut.ts index 8ef884a7f..682a8300c 100644 --- a/src/services/api/metricsOptOut.ts +++ b/src/services/api/metricsOptOut.ts @@ -152,8 +152,3 @@ export async function checkMetricsEnabled(): Promise { // First-ever run on this machine: block on the network to populate disk. return refreshMetricsStatus() } - -// Export for testing purposes only -export const _clearMetricsEnabledCacheForTesting = (): void => { - memoizedCheckMetrics.cache.clear() -} diff --git a/src/services/lsp/LSPDiagnosticRegistry.ts b/src/services/lsp/LSPDiagnosticRegistry.ts index 65330b764..7e8394155 100644 --- a/src/services/lsp/LSPDiagnosticRegistry.ts +++ b/src/services/lsp/LSPDiagnosticRegistry.ts @@ -377,10 +377,3 @@ export function clearDeliveredDiagnosticsForFile(fileUri: string): void { deliveredDiagnostics.delete(fileUri) } } - -/** - * Get count of pending diagnostics (for monitoring) - */ -export function getPendingLSPDiagnosticCount(): number { - return pendingDiagnostics.size -} diff --git a/src/services/lsp/manager.ts b/src/services/lsp/manager.ts index b9dc623c0..8ff3a0125 100644 --- a/src/services/lsp/manager.ts +++ b/src/services/lsp/manager.ts @@ -39,19 +39,6 @@ let initializationGeneration = 0 */ let initializationPromise: Promise | undefined -/** - * Test-only sync reset. shutdownLspServerManager() is async and tears down - * real connections; this only clears the module-scope singleton state so - * reinitializeLspServerManager() early-returns on 'not-started' in downstream - * tests on the same shard. - */ -export function _resetLspManagerForTesting(): void { - initializationState = 'not-started' - initializationError = undefined - initializationPromise = undefined - initializationGeneration++ -} - /** * Get the singleton LSP server manager instance. * Returns undefined if not yet initialized, initialization failed, or still pending. diff --git a/src/services/mcp/utils.ts b/src/services/mcp/utils.ts index fb3bd2d38..8252b71e2 100644 --- a/src/services/mcp/utils.ts +++ b/src/services/mcp/utils.ts @@ -246,15 +246,6 @@ export function isMcpTool(tool: Tool): boolean { return tool.name?.startsWith('mcp__') || tool.isMcp === true } -/** - * Checks if a command belongs to any MCP server - * @param command The command to check - * @returns True if the command is from an MCP server - */ -export function isMcpCommand(command: Command): boolean { - return command.name?.startsWith('mcp__') || command.isMcp === true -} - /** * Describe the file path for a given MCP config scope. * @param scope The config scope ('user', 'project', 'local', or 'dynamic') diff --git a/src/services/skillLearning/projectContext.ts b/src/services/skillLearning/projectContext.ts index 3f5037973..e7eac52ae 100644 --- a/src/services/skillLearning/projectContext.ts +++ b/src/services/skillLearning/projectContext.ts @@ -100,11 +100,6 @@ export function resolveProjectContext( return resolved } -export function resetProjectContextCacheForTest(): void { - contextCache.clear() - lastPersistAt = 0 -} - export function listKnownProjects(): SkillLearningProjectRecord[] { const registry = readProjectsRegistry(getProjectsRegistryPath()) return Object.values(registry.projects).sort((a, b) => diff --git a/src/services/teamMemorySync/secretScanner.ts b/src/services/teamMemorySync/secretScanner.ts index ed9116248..e1fb51d05 100644 --- a/src/services/teamMemorySync/secretScanner.ts +++ b/src/services/teamMemorySync/secretScanner.ts @@ -301,24 +301,3 @@ export function scanForSecrets(content: string): SecretMatch[] { export function getSecretLabel(ruleId: string): string { return ruleIdToLabel(ruleId) } - -/** - * Redact any matched secrets in-place with [REDACTED]. - * Unlike scanForSecrets, this returns the content with spans replaced - * so the surrounding text can still be written to disk safely. - */ -let redactRules: RegExp[] | null = null - -export function redactSecrets(content: string): string { - redactRules ??= SECRET_RULES.map( - r => new RegExp(r.source, (r.flags ?? '').replace('g', '') + 'g'), - ) - for (const re of redactRules) { - // Replace only the captured group, not the full match — patterns include - // boundary chars (space, quote, ;) outside the group that must survive. - content = content.replace(re, (match, g1) => - typeof g1 === 'string' ? match.replace(g1, '[REDACTED]') : '[REDACTED]', - ) - } - return content -} diff --git a/src/services/teamMemorySync/watcher.ts b/src/services/teamMemorySync/watcher.ts index 0d9874e6e..6befa594d 100644 --- a/src/services/teamMemorySync/watcher.ts +++ b/src/services/teamMemorySync/watcher.ts @@ -350,38 +350,3 @@ export async function stopTeamMemoryWatcher(): Promise { } } } - -/** - * Test-only: reset module state and optionally seed syncState. - * The feature('TEAMMEM') gate at the top of startTeamMemoryWatcher() is - * always false in bun test, so tests can't set syncState through the normal - * path. This helper lets tests drive notifyTeamMemoryWrite() / - * stopTeamMemoryWatcher() directly. - * - * `skipWatcher: true` marks the watcher as already-started without actually - * starting it. Tests that only exercise the schedulePush/flush path don't - * need a real watcher. - */ -export function _resetWatcherStateForTesting(opts?: { - syncState?: SyncState - skipWatcher?: boolean - pushSuppressedReason?: string | null -}): void { - watcher = null - debounceTimer = null - pushInProgress = false - hasPendingChanges = false - currentPushPromise = null - watcherStarted = opts?.skipWatcher ?? false - pushSuppressedReason = opts?.pushSuppressedReason ?? null - syncState = opts?.syncState ?? null -} - -/** - * Test-only: start the real fs.watch on a specified directory. - * Used by the fd-count regression test — startTeamMemoryWatcher() is gated - * by feature('TEAMMEM') which is false under bun test. - */ -export function _startFileWatcherForTesting(dir: string): Promise { - return startFileWatcher(dir) -} diff --git a/src/skills/loadSkillsDir.ts b/src/skills/loadSkillsDir.ts index b1138eede..2f000accd 100644 --- a/src/skills/loadSkillsDir.ts +++ b/src/skills/loadSkillsDir.ts @@ -1057,13 +1057,6 @@ export function activateConditionalSkillsForPaths( return activated } -/** - * Gets the number of pending conditional skills (for testing/debugging). - */ -export function getConditionalSkillCount(): number { - return conditionalSkills.size -} - /** * Clears dynamic skill state (for testing). */ diff --git a/src/utils/attachments.ts b/src/utils/attachments.ts index d63342027..4cff94eb9 100644 --- a/src/utils/attachments.ts +++ b/src/utils/attachments.ts @@ -1106,7 +1106,7 @@ export async function getQueuedCommandAttachments( // Include both 'prompt' and 'task-notification' commands as attachments. // During proactive agentic loops, task-notification commands would otherwise // stay in the queue permanently (useQueueProcessor can't run while a query - // is active), causing hasPendingNotifications() to return true and Sleep to + // is active), causing hasCommandsInQueue() to return true and Sleep to // wake immediately with 0ms duration in an infinite loop. const filtered = queuedCommands.filter(_ => INLINE_NOTIFICATION_MODES.has(_.mode), diff --git a/src/utils/filePersistence/filePersistence.ts b/src/utils/filePersistence/filePersistence.ts index 219efc6c4..217cef19d 100644 --- a/src/utils/filePersistence/filePersistence.ts +++ b/src/utils/filePersistence/filePersistence.ts @@ -91,17 +91,13 @@ export async function runFilePersistence( }) try { - let result: FilesPersistedEventData - if (environmentKind === 'byoc') { - result = await executeBYOCPersistence( - turnStartTime, - config, - outputsDir, - signal, - ) - } else { - result = await executeCloudPersistence() - } + // environmentKind === 'byoc' is guaranteed by the early return above + const result = await executeBYOCPersistence( + turnStartTime, + config, + outputsDir, + signal, + ) // Nothing to report if (result.files.length === 0 && result.failed.length === 0) { @@ -240,16 +236,6 @@ async function executeBYOCPersistence( } } -/** - * Execute Cloud (1P) mode persistence. - * TODO: Read file_id from xattr on output files. xattr-based file IDs are - * currently being added for 1P environments. - */ -function executeCloudPersistence(): FilesPersistedEventData { - logDebug('Cloud mode: xattr-based file ID reading not yet implemented') - return { files: [], failed: [] } -} - /** * Execute file persistence and emit result via callback. * Handles errors internally. diff --git a/src/utils/messageQueueManager.ts b/src/utils/messageQueueManager.ts index be34d32ac..699260ab5 100644 --- a/src/utils/messageQueueManager.ts +++ b/src/utils/messageQueueManager.ts @@ -485,38 +485,6 @@ export function popAllEditable( return { text: newInput, cursorOffset, images } } -// ============================================================================ -// Backward-compatible aliases (deprecated — prefer new names) -// ============================================================================ - -/** @deprecated Use subscribeToCommandQueue */ -export const subscribeToPendingNotifications = subscribeToCommandQueue - -/** @deprecated Use getCommandQueueSnapshot */ -export function getPendingNotificationsSnapshot(): readonly QueuedCommand[] { - return snapshot -} - -/** @deprecated Use hasCommandsInQueue */ -export const hasPendingNotifications = hasCommandsInQueue - -/** @deprecated Use getCommandQueueLength */ -export const getPendingNotificationsCount = getCommandQueueLength - -/** @deprecated Use recheckCommandQueue */ -export const recheckPendingNotifications = recheckCommandQueue - -/** @deprecated Use dequeue */ -export function dequeuePendingNotification(): QueuedCommand | undefined { - return dequeue() -} - -/** @deprecated Use resetCommandQueue */ -export const resetPendingNotifications = resetCommandQueue - -/** @deprecated Use clearCommandQueue */ -export const clearPendingNotifications = clearCommandQueue - /** * Get commands at or above a given priority level without removing them. * Useful for mid-chain draining where only urgent items should be processed.