chore: 移除 src/ 下多处未引用的导出

涉及 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 <zai-org@claude-code-best.win>
This commit is contained in:
claude-code-best
2026-06-20 11:38:02 +08:00
parent d0414a0a5c
commit 9e507bd823
18 changed files with 9 additions and 255 deletions

View File

@@ -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,

View File

@@ -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
*/

View File

@@ -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]);

View File

@@ -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()
}

View File

@@ -234,22 +234,6 @@ export const getAutoMemPath = memoize(
() => getProjectRoot(),
)
/**
* Returns the daily log file path for the given date (defaults to today).
* Shape: <autoMemPath>/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().

View File

@@ -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
}

View File

@@ -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<Uint8Array> {
return new ReadableStream<Uint8Array>({
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(

View File

@@ -152,8 +152,3 @@ export async function checkMetricsEnabled(): Promise<MetricsStatus> {
// 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()
}

View File

@@ -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
}

View File

@@ -39,19 +39,6 @@ let initializationGeneration = 0
*/
let initializationPromise: Promise<void> | 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.

View File

@@ -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')

View File

@@ -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) =>

View File

@@ -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
}

View File

@@ -350,38 +350,3 @@ export async function stopTeamMemoryWatcher(): Promise<void> {
}
}
}
/**
* 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<void> {
return startFileWatcher(dir)
}

View File

@@ -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).
*/

View File

@@ -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),

View File

@@ -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.

View File

@@ -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.