Reduce local debug detail in mailbox and session helpers
This commit is contained in:
@@ -513,9 +513,7 @@ export function useInboxPoller({
|
|||||||
for (const m of teamPermissionUpdates) {
|
for (const m of teamPermissionUpdates) {
|
||||||
const parsed = isTeamPermissionUpdate(m.text)
|
const parsed = isTeamPermissionUpdate(m.text)
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
logForDebugging(
|
logForDebugging('[InboxPoller] Failed to parse team permission update')
|
||||||
`[InboxPoller] Failed to parse team permission update: ${m.text.substring(0, 100)}`,
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,10 +530,7 @@ export function useInboxPoller({
|
|||||||
|
|
||||||
// Apply the permission update to the teammate's context
|
// Apply the permission update to the teammate's context
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[InboxPoller] Applying team permission update: ${parsed.toolName} allowed in ${parsed.directoryPath}`,
|
`[InboxPoller] Applying team permission update for ${parsed.toolName} (${parsed.permissionUpdate.rules.length} rule(s))`,
|
||||||
)
|
|
||||||
logForDebugging(
|
|
||||||
`[InboxPoller] Permission update rules: ${jsonStringify(parsed.permissionUpdate.rules)}`,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
setAppState(prev => {
|
setAppState(prev => {
|
||||||
@@ -546,7 +541,7 @@ export function useInboxPoller({
|
|||||||
destination: 'session',
|
destination: 'session',
|
||||||
})
|
})
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[InboxPoller] Updated session allow rules: ${jsonStringify(updated.alwaysAllowRules.session)}`,
|
`[InboxPoller] Updated session allow rules (${updated.alwaysAllowRules.session.length} total)`,
|
||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
@@ -573,9 +568,7 @@ export function useInboxPoller({
|
|||||||
|
|
||||||
const parsed = isModeSetRequest(m.text)
|
const parsed = isModeSetRequest(m.text)
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
logForDebugging(
|
logForDebugging('[InboxPoller] Failed to parse mode set request')
|
||||||
`[InboxPoller] Failed to parse mode set request: ${m.text.substring(0, 100)}`,
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ export async function connectVoiceStream(
|
|||||||
|
|
||||||
const url = `${wsBaseUrl}${VOICE_STREAM_PATH}?${params.toString()}`
|
const url = `${wsBaseUrl}${VOICE_STREAM_PATH}?${params.toString()}`
|
||||||
|
|
||||||
logForDebugging(`[voice_stream] Connecting to ${url}`)
|
logForDebugging('[voice_stream] Connecting to voice stream websocket')
|
||||||
|
|
||||||
const headers: Record<string, string> = {
|
const headers: Record<string, string> = {
|
||||||
Authorization: `Bearer ${tokens.accessToken}`,
|
Authorization: `Bearer ${tokens.accessToken}`,
|
||||||
@@ -357,7 +357,7 @@ export async function connectVoiceStream(
|
|||||||
ws.on('message', (raw: Buffer | string) => {
|
ws.on('message', (raw: Buffer | string) => {
|
||||||
const text = raw.toString()
|
const text = raw.toString()
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[voice_stream] Message received (${String(text.length)} chars): ${text.slice(0, 200)}`,
|
`[voice_stream] Message received (${String(text.length)} chars)`,
|
||||||
)
|
)
|
||||||
let msg: VoiceStreamMessage
|
let msg: VoiceStreamMessage
|
||||||
try {
|
try {
|
||||||
@@ -369,7 +369,9 @@ export async function connectVoiceStream(
|
|||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case 'TranscriptText': {
|
case 'TranscriptText': {
|
||||||
const transcript = msg.data
|
const transcript = msg.data
|
||||||
logForDebugging(`[voice_stream] TranscriptText: "${transcript ?? ''}"`)
|
logForDebugging(
|
||||||
|
`[voice_stream] TranscriptText received (${String((transcript ?? '').length)} chars)`,
|
||||||
|
)
|
||||||
// Data arrived after CloseStream — disarm the no-data timer so
|
// Data arrived after CloseStream — disarm the no-data timer so
|
||||||
// a slow-but-real flush isn't cut off. Only disarm once finalized
|
// a slow-but-real flush isn't cut off. Only disarm once finalized
|
||||||
// (CloseStream sent); pre-CloseStream data racing the deferred
|
// (CloseStream sent); pre-CloseStream data racing the deferred
|
||||||
@@ -403,7 +405,7 @@ export async function connectVoiceStream(
|
|||||||
!prev.startsWith(next)
|
!prev.startsWith(next)
|
||||||
) {
|
) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[voice_stream] Auto-finalizing previous segment (new segment detected): "${lastTranscriptText}"`,
|
'[voice_stream] Auto-finalizing previous segment (new segment detected)',
|
||||||
)
|
)
|
||||||
callbacks.onTranscript(lastTranscriptText, true)
|
callbacks.onTranscript(lastTranscriptText, true)
|
||||||
}
|
}
|
||||||
@@ -416,7 +418,7 @@ export async function connectVoiceStream(
|
|||||||
}
|
}
|
||||||
case 'TranscriptEndpoint': {
|
case 'TranscriptEndpoint': {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[voice_stream] TranscriptEndpoint received, lastTranscriptText="${lastTranscriptText}"`,
|
`[voice_stream] TranscriptEndpoint received (hasBufferedTranscript=${Boolean(lastTranscriptText)})`,
|
||||||
)
|
)
|
||||||
// The server signals the end of an utterance. Emit the last
|
// The server signals the end of an utterance. Emit the last
|
||||||
// TranscriptText as a final transcript so the caller can commit it.
|
// TranscriptText as a final transcript so the caller can commit it.
|
||||||
@@ -441,7 +443,9 @@ export async function connectVoiceStream(
|
|||||||
case 'TranscriptError': {
|
case 'TranscriptError': {
|
||||||
const desc =
|
const desc =
|
||||||
msg.description ?? msg.error_code ?? 'unknown transcription error'
|
msg.description ?? msg.error_code ?? 'unknown transcription error'
|
||||||
logForDebugging(`[voice_stream] TranscriptError: ${desc}`)
|
logForDebugging(
|
||||||
|
`[voice_stream] TranscriptError received (${msg.error_code ?? 'unknown'})`,
|
||||||
|
)
|
||||||
if (!finalizing) {
|
if (!finalizing) {
|
||||||
callbacks.onError(desc)
|
callbacks.onError(desc)
|
||||||
}
|
}
|
||||||
@@ -449,7 +453,7 @@ export async function connectVoiceStream(
|
|||||||
}
|
}
|
||||||
case 'error': {
|
case 'error': {
|
||||||
const errorDetail = msg.message ?? jsonStringify(msg)
|
const errorDetail = msg.message ?? jsonStringify(msg)
|
||||||
logForDebugging(`[voice_stream] Server error: ${errorDetail}`)
|
logForDebugging('[voice_stream] Server error received')
|
||||||
if (!finalizing) {
|
if (!finalizing) {
|
||||||
callbacks.onError(errorDetail)
|
callbacks.onError(errorDetail)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function maybePersistTokenForSubprocesses(
|
|||||||
mkdirSync(CCR_TOKEN_DIR, { recursive: true, mode: 0o700 })
|
mkdirSync(CCR_TOKEN_DIR, { recursive: true, mode: 0o700 })
|
||||||
// eslint-disable-next-line custom-rules/no-sync-fs -- one-shot startup write in CCR, caller is sync
|
// eslint-disable-next-line custom-rules/no-sync-fs -- one-shot startup write in CCR, caller is sync
|
||||||
writeFileSync(path, token, { encoding: 'utf8', mode: 0o600 })
|
writeFileSync(path, token, { encoding: 'utf8', mode: 0o600 })
|
||||||
logForDebugging(`Persisted ${tokenName} to ${path} for subprocess access`)
|
logForDebugging(`Persisted ${tokenName} for subprocess access`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Failed to persist ${tokenName} to disk (non-fatal): ${errorMessage(error)}`,
|
`Failed to persist ${tokenName} to disk (non-fatal): ${errorMessage(error)}`,
|
||||||
@@ -65,7 +65,7 @@ export function readTokenFromWellKnownFile(
|
|||||||
if (!token) {
|
if (!token) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
logForDebugging(`Read ${tokenName} from well-known file ${path}`)
|
logForDebugging(`Read ${tokenName} from well-known file`)
|
||||||
return token
|
return token
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// ENOENT is the expected outcome outside CCR — stay silent. Anything
|
// ENOENT is the expected outcome outside CCR — stay silent. Anything
|
||||||
@@ -73,7 +73,7 @@ export function readTokenFromWellKnownFile(
|
|||||||
// debug log so subprocess auth failures aren't mysterious.
|
// debug log so subprocess auth failures aren't mysterious.
|
||||||
if (!isENOENT(error)) {
|
if (!isENOENT(error)) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Failed to read ${tokenName} from ${path}: ${errorMessage(error)}`,
|
`Failed to read ${tokenName} from well-known file: ${errorMessage(error)}`,
|
||||||
{ level: 'debug' },
|
{ level: 'debug' },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ function getCredentialFromFd({
|
|||||||
const fd = parseInt(fdEnv, 10)
|
const fd = parseInt(fdEnv, 10)
|
||||||
if (Number.isNaN(fd)) {
|
if (Number.isNaN(fd)) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`${envVar} must be a valid file descriptor number, got: ${fdEnv}`,
|
`${envVar} must be a valid file descriptor number`,
|
||||||
{ level: 'error' },
|
{ level: 'error' },
|
||||||
)
|
)
|
||||||
setCached(null)
|
setCached(null)
|
||||||
@@ -148,13 +148,13 @@ function getCredentialFromFd({
|
|||||||
setCached(null)
|
setCached(null)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
logForDebugging(`Successfully read ${label} from file descriptor ${fd}`)
|
logForDebugging(`Successfully read ${label} from file descriptor`)
|
||||||
setCached(token)
|
setCached(token)
|
||||||
maybePersistTokenForSubprocesses(wellKnownPath, token, label)
|
maybePersistTokenForSubprocesses(wellKnownPath, token, label)
|
||||||
return token
|
return token
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Failed to read ${label} from file descriptor ${fd}: ${errorMessage(error)}`,
|
`Failed to read ${label} from file descriptor: ${errorMessage(error)}`,
|
||||||
{ level: 'error' },
|
{ level: 'error' },
|
||||||
)
|
)
|
||||||
// FD env var was set but read failed — typically a subprocess that
|
// FD env var was set but read failed — typically a subprocess that
|
||||||
|
|||||||
@@ -78,13 +78,13 @@ export async function getSessionEnvironmentScript(): Promise<string | null> {
|
|||||||
if (envScript) {
|
if (envScript) {
|
||||||
scripts.push(envScript)
|
scripts.push(envScript)
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Session environment loaded from CLAUDE_ENV_FILE: ${envFile} (${envScript.length} chars)`,
|
`Session environment loaded from CLAUDE_ENV_FILE (${envScript.length} chars)`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const code = getErrnoCode(e)
|
const code = getErrnoCode(e)
|
||||||
if (code !== 'ENOENT') {
|
if (code !== 'ENOENT') {
|
||||||
logForDebugging(`Failed to read CLAUDE_ENV_FILE: ${errorMessage(e)}`)
|
logForDebugging('Failed to read CLAUDE_ENV_FILE')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,9 +109,7 @@ export async function getSessionEnvironmentScript(): Promise<string | null> {
|
|||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const code = getErrnoCode(e)
|
const code = getErrnoCode(e)
|
||||||
if (code !== 'ENOENT') {
|
if (code !== 'ENOENT') {
|
||||||
logForDebugging(
|
logForDebugging(`Failed to read hook env file ${file}`)
|
||||||
`Failed to read hook file ${filePath}: ${errorMessage(e)}`,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ function getTokenFromFileDescriptor(): string | null {
|
|||||||
const fd = parseInt(fdEnv, 10)
|
const fd = parseInt(fdEnv, 10)
|
||||||
if (Number.isNaN(fd)) {
|
if (Number.isNaN(fd)) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR must be a valid file descriptor number, got: ${fdEnv}`,
|
'CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR must be a valid file descriptor number',
|
||||||
{ level: 'error' },
|
{ level: 'error' },
|
||||||
)
|
)
|
||||||
setSessionIngressToken(null)
|
setSessionIngressToken(null)
|
||||||
@@ -61,7 +61,7 @@ function getTokenFromFileDescriptor(): string | null {
|
|||||||
setSessionIngressToken(null)
|
setSessionIngressToken(null)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
logForDebugging(`Successfully read token from file descriptor ${fd}`)
|
logForDebugging('Successfully read token from file descriptor')
|
||||||
setSessionIngressToken(token)
|
setSessionIngressToken(token)
|
||||||
maybePersistTokenForSubprocesses(
|
maybePersistTokenForSubprocesses(
|
||||||
CCR_SESSION_INGRESS_TOKEN_PATH,
|
CCR_SESSION_INGRESS_TOKEN_PATH,
|
||||||
@@ -71,7 +71,7 @@ function getTokenFromFileDescriptor(): string | null {
|
|||||||
return token
|
return token
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`Failed to read token from file descriptor ${fd}: ${errorMessage(error)}`,
|
`Failed to read token from file descriptor: ${errorMessage(error)}`,
|
||||||
{ level: 'error' },
|
{ level: 'error' },
|
||||||
)
|
)
|
||||||
// FD env var was set but read failed — typically a subprocess that
|
// FD env var was set but read failed — typically a subprocess that
|
||||||
|
|||||||
@@ -57,11 +57,7 @@ export function getInboxPath(agentName: string, teamName?: string): string {
|
|||||||
const safeTeam = sanitizePathComponent(team)
|
const safeTeam = sanitizePathComponent(team)
|
||||||
const safeAgentName = sanitizePathComponent(agentName)
|
const safeAgentName = sanitizePathComponent(agentName)
|
||||||
const inboxDir = join(getTeamsDir(), safeTeam, 'inboxes')
|
const inboxDir = join(getTeamsDir(), safeTeam, 'inboxes')
|
||||||
const fullPath = join(inboxDir, `${safeAgentName}.json`)
|
return join(inboxDir, `${safeAgentName}.json`)
|
||||||
logForDebugging(
|
|
||||||
`[TeammateMailbox] getInboxPath: agent=${agentName}, team=${team}, fullPath=${fullPath}`,
|
|
||||||
)
|
|
||||||
return fullPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,7 +68,7 @@ async function ensureInboxDir(teamName?: string): Promise<void> {
|
|||||||
const safeTeam = sanitizePathComponent(team)
|
const safeTeam = sanitizePathComponent(team)
|
||||||
const inboxDir = join(getTeamsDir(), safeTeam, 'inboxes')
|
const inboxDir = join(getTeamsDir(), safeTeam, 'inboxes')
|
||||||
await mkdir(inboxDir, { recursive: true })
|
await mkdir(inboxDir, { recursive: true })
|
||||||
logForDebugging(`[TeammateMailbox] Ensured inbox directory: ${inboxDir}`)
|
logForDebugging('[TeammateMailbox] Ensured inbox directory')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,7 +81,6 @@ export async function readMailbox(
|
|||||||
teamName?: string,
|
teamName?: string,
|
||||||
): Promise<TeammateMessage[]> {
|
): Promise<TeammateMessage[]> {
|
||||||
const inboxPath = getInboxPath(agentName, teamName)
|
const inboxPath = getInboxPath(agentName, teamName)
|
||||||
logForDebugging(`[TeammateMailbox] readMailbox: path=${inboxPath}`)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const content = await readFile(inboxPath, 'utf-8')
|
const content = await readFile(inboxPath, 'utf-8')
|
||||||
@@ -100,7 +95,7 @@ export async function readMailbox(
|
|||||||
logForDebugging(`[TeammateMailbox] readMailbox: file does not exist`)
|
logForDebugging(`[TeammateMailbox] readMailbox: file does not exist`)
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
logForDebugging(`Failed to read inbox for ${agentName}: ${error}`)
|
logForDebugging(`[TeammateMailbox] Failed to read inbox for ${agentName}`)
|
||||||
logError(error)
|
logError(error)
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -141,7 +136,7 @@ export async function writeToMailbox(
|
|||||||
const lockFilePath = `${inboxPath}.lock`
|
const lockFilePath = `${inboxPath}.lock`
|
||||||
|
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[TeammateMailbox] writeToMailbox: recipient=${recipientName}, from=${message.from}, path=${inboxPath}`,
|
`[TeammateMailbox] writeToMailbox: recipient=${recipientName}, from=${message.from}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure the inbox file exists before locking (proper-lockfile requires the file to exist)
|
// Ensure the inbox file exists before locking (proper-lockfile requires the file to exist)
|
||||||
@@ -152,7 +147,7 @@ export async function writeToMailbox(
|
|||||||
const code = getErrnoCode(error)
|
const code = getErrnoCode(error)
|
||||||
if (code !== 'EEXIST') {
|
if (code !== 'EEXIST') {
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[TeammateMailbox] writeToMailbox: failed to create inbox file: ${error}`,
|
`[TeammateMailbox] writeToMailbox: failed to create inbox file`,
|
||||||
)
|
)
|
||||||
logError(error)
|
logError(error)
|
||||||
return
|
return
|
||||||
@@ -181,7 +176,9 @@ export async function writeToMailbox(
|
|||||||
`[TeammateMailbox] Wrote message to ${recipientName}'s inbox from ${message.from}`,
|
`[TeammateMailbox] Wrote message to ${recipientName}'s inbox from ${message.from}`,
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logForDebugging(`Failed to write to inbox for ${recipientName}: ${error}`)
|
logForDebugging(
|
||||||
|
`[TeammateMailbox] Failed to write to inbox for ${recipientName}`,
|
||||||
|
)
|
||||||
logError(error)
|
logError(error)
|
||||||
} finally {
|
} finally {
|
||||||
if (release) {
|
if (release) {
|
||||||
@@ -204,7 +201,7 @@ export async function markMessageAsReadByIndex(
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const inboxPath = getInboxPath(agentName, teamName)
|
const inboxPath = getInboxPath(agentName, teamName)
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[TeammateMailbox] markMessageAsReadByIndex called: agentName=${agentName}, teamName=${teamName}, index=${messageIndex}, path=${inboxPath}`,
|
`[TeammateMailbox] markMessageAsReadByIndex called: agentName=${agentName}, index=${messageIndex}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
const lockFilePath = `${inboxPath}.lock`
|
const lockFilePath = `${inboxPath}.lock`
|
||||||
@@ -256,13 +253,11 @@ export async function markMessageAsReadByIndex(
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
const code = getErrnoCode(error)
|
const code = getErrnoCode(error)
|
||||||
if (code === 'ENOENT') {
|
if (code === 'ENOENT') {
|
||||||
logForDebugging(
|
logForDebugging(`[TeammateMailbox] markMessageAsReadByIndex: file missing`)
|
||||||
`[TeammateMailbox] markMessageAsReadByIndex: file does not exist at ${inboxPath}`,
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logForDebugging(
|
logForDebugging(
|
||||||
`[TeammateMailbox] markMessageAsReadByIndex FAILED for ${agentName}: ${error}`,
|
`[TeammateMailbox] markMessageAsReadByIndex failed for ${agentName}`,
|
||||||
)
|
)
|
||||||
logError(error)
|
logError(error)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -296,7 +291,7 @@ export async function clearMailbox(
|
|||||||
if (code === 'ENOENT') {
|
if (code === 'ENOENT') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logForDebugging(`Failed to clear inbox for ${agentName}: ${error}`)
|
logForDebugging(`[TeammateMailbox] Failed to clear inbox for ${agentName}`)
|
||||||
logError(error)
|
logError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1108,7 +1103,7 @@ export function getLastPeerDmSummary(messages: Message[]): string | undefined {
|
|||||||
const summary =
|
const summary =
|
||||||
'summary' in block.input && typeof block.input.summary === 'string'
|
'summary' in block.input && typeof block.input.summary === 'string'
|
||||||
? block.input.summary
|
? block.input.summary
|
||||||
: block.input.message.slice(0, 80)
|
: 'sent update'
|
||||||
return `[to ${to}] ${summary}`
|
return `[to ${to}] ${summary}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user