mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-20 07:15:51 +00:00
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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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().
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
*/
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user