fix(daemon-ui): forward opts in daemonBlockToPlainText tool case

wenshao review 4350741340 (2026-05-23 13:00): the prior doudouOUC
review fixed only the HTML path; the plainText tool case still called
`daemonToolPreviewToPlainText(block.preview)` without `opts`, so
`sanitizeUrls` + `maxFieldLength` were silently ignored when consumers
used the plain-text projection (logs, clipboard, terminal mirroring).

Symmetric fix to the HTML path (line 509). Added test verifying token
stripping reaches `web_fetch.url` via plainText path.

Validation: 153/153 SDK tests, SDK + WebUI typecheck clean.

Generated with AI

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
秦奇 2026-05-23 22:31:49 +08:00
parent 93bb279f7c
commit d35cbb75a3
2 changed files with 32 additions and 1 deletions

View file

@ -357,7 +357,12 @@ export function daemonBlockToPlainText(
]
.filter(Boolean)
.join(' ');
const preview = daemonToolPreviewToPlainText(block.preview);
// wenshao review (review 4350741340): forward `opts` so
// `sanitizeUrls` + `maxFieldLength` reach the preview's URL fields
// (web_fetch URL, image_generation thumbnailUrl). The HTML path at
// line 509 already did this; plainText was missed in the prior
// doudouOUC fix.
const preview = daemonToolPreviewToPlainText(block.preview, opts);
const status = `status: ${block.status}`;
return [header, preview, status].filter(Boolean).join('\n');
}

View file

@ -4270,3 +4270,29 @@ describe('KNOWN_DEVICE_FLOW_ERROR_KINDS stays in sync with public type', async (
expect(KNOWN_DEVICE_FLOW_ERROR_KINDS).toHaveLength(6);
});
});
describe('daemonBlockToPlainText forwards opts (wenshao review 4350741340)', () => {
it('sanitizes URL on tool preview when opts.sanitizeUrls is set', async () => {
const {
daemonBlockToPlainText,
createDaemonToolPreview,
} = await import('../../src/daemon/ui/index.js');
const block = {
id: 'b',
kind: 'tool' as const,
toolCallId: 't',
title: 'fetch',
status: 'completed',
preview: createDaemonToolPreview(
{ url: 'https://api.example.com/x?token=SECRET&q=keep', method: 'GET' },
{ toolName: 'WebFetch', toolKind: 'tool' },
),
clientReceivedAt: 1,
createdAt: 1,
updatedAt: 1,
};
const sanitized = daemonBlockToPlainText(block, { sanitizeUrls: true });
expect(sanitized).not.toContain('SECRET');
expect(sanitized).toContain('keep');
});
});