the claude code sourcemaps leaked march 31
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 110 lines 3.9 kB view raw
1/** 2 * Shared attachment validation + resolution for SendUserMessage and 3 * SendUserFile. Lives in BriefTool/ so the dynamic `./upload.js` import 4 * inside the feature('BRIDGE_MODE') guard stays relative and upload.ts 5 * (axios, crypto, auth utils) remains tree-shakeable from non-bridge builds. 6 */ 7 8import { feature } from 'bun:bundle' 9import { stat } from 'fs/promises' 10 11import type { ValidationResult } from '../../Tool.js' 12 13import { getCwd } from '../../utils/cwd.js' 14import { isEnvTruthy } from '../../utils/envUtils.js' 15import { getErrnoCode } from '../../utils/errors.js' 16import { IMAGE_EXTENSION_REGEX } from '../../utils/imagePaste.js' 17import { expandPath } from '../../utils/path.js' 18 19export type ResolvedAttachment = { 20 path: string 21 size: number 22 isImage: boolean 23 file_uuid?: string 24} 25 26export async function validateAttachmentPaths( 27 rawPaths: string[], 28): Promise<ValidationResult> { 29 const cwd = getCwd() 30 for (const rawPath of rawPaths) { 31 const fullPath = expandPath(rawPath) 32 try { 33 const stats = await stat(fullPath) 34 if (!stats.isFile()) { 35 return { 36 result: false, 37 message: `Attachment "${rawPath}" is not a regular file.`, 38 errorCode: 1, 39 } 40 } 41 } catch (e) { 42 const code = getErrnoCode(e) 43 if (code === 'ENOENT') { 44 return { 45 result: false, 46 message: `Attachment "${rawPath}" does not exist. Current working directory: ${cwd}.`, 47 errorCode: 1, 48 } 49 } 50 if (code === 'EACCES' || code === 'EPERM') { 51 return { 52 result: false, 53 message: `Attachment "${rawPath}" is not accessible (permission denied).`, 54 errorCode: 1, 55 } 56 } 57 throw e 58 } 59 } 60 return { result: true } 61} 62 63export async function resolveAttachments( 64 rawPaths: string[], 65 uploadCtx: { replBridgeEnabled: boolean; signal?: AbortSignal }, 66): Promise<ResolvedAttachment[]> { 67 // Stat serially (local, fast) to keep ordering deterministic, then upload 68 // in parallel (network, slow). Upload failures resolve undefined — the 69 // attachment still carries {path, size, isImage} for local renderers. 70 const stated: ResolvedAttachment[] = [] 71 for (const rawPath of rawPaths) { 72 const fullPath = expandPath(rawPath) 73 // Single stat — we need size, so this is the operation, not a guard. 74 // validateInput ran before us, but the file could have moved since 75 // (TOCTOU); if it did, let the error propagate so the model sees it. 76 const stats = await stat(fullPath) 77 stated.push({ 78 path: fullPath, 79 size: stats.size, 80 isImage: IMAGE_EXTENSION_REGEX.test(fullPath), 81 }) 82 } 83 // Dynamic import inside the feature() guard so upload.ts (axios, crypto, 84 // zod, auth utils, MIME map) is fully eliminated from non-BRIDGE_MODE 85 // builds. A static import would force module-scope evaluation regardless 86 // of the guard inside uploadBriefAttachment — CLAUDE.md: "helpers defined 87 // outside remain in the build even if never called". 88 if (feature('BRIDGE_MODE')) { 89 // Headless/SDK callers never set appState.replBridgeEnabled (only the TTY 90 // REPL does, at main.tsx init). CLAUDE_CODE_BRIEF_UPLOAD lets a host that 91 // runs the CLI as a subprocess opt in — e.g. the cowork desktop bridge, 92 // which already passes CLAUDE_CODE_OAUTH_TOKEN for auth. 93 const shouldUpload = 94 uploadCtx.replBridgeEnabled || 95 isEnvTruthy(process.env.CLAUDE_CODE_BRIEF_UPLOAD) 96 const { uploadBriefAttachment } = await import('./upload.js') 97 const uuids = await Promise.all( 98 stated.map(a => 99 uploadBriefAttachment(a.path, a.size, { 100 replBridgeEnabled: shouldUpload, 101 signal: uploadCtx.signal, 102 }), 103 ), 104 ) 105 return stated.map((a, i) => 106 uuids[i] === undefined ? a : { ...a, file_uuid: uuids[i] }, 107 ) 108 } 109 return stated 110}