Download src/tools/BriefTool/attachments.ts from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/chenbhao/codev/resolve/afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/tools/BriefTool/attachments.ts
- Command line
-
hf download hf://chenbhao/codev@afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/tools/BriefTool/attachments.ts
-
curl -L -o attachments.ts https://huggingface.co/chenbhao/codev/resolve/afbc7edaae4e6bb0102ba024b49ce8be89d2264c/src/tools/BriefTool/attachments.ts
3.89 kB
| /** | |
| * Shared attachment validation + resolution for SendUserMessage and | |
| * SendUserFile. Lives in BriefTool/ so the dynamic `./upload.js` import | |
| * inside the feature('BRIDGE_MODE') guard stays relative and upload.ts | |
| * (axios, crypto, auth utils) remains tree-shakeable from non-bridge builds. | |
| */ | |
| import { feature } from 'bun:bundle' | |
| import { stat } from 'fs/promises' | |
| import type { ValidationResult } from '../../Tool.js' | |
| import { getCwd } from '../../utils/cwd.js' | |
| import { isEnvTruthy } from '../../utils/envUtils.js' | |
| import { getErrnoCode } from '../../utils/errors.js' | |
| import { IMAGE_EXTENSION_REGEX } from '../../utils/imagePaste.js' | |
| import { expandPath } from '../../utils/path.js' | |
| export type ResolvedAttachment = { | |
| path: string | |
| size: number | |
| isImage: boolean | |
| file_uuid?: string | |
| } | |
| export async function validateAttachmentPaths( | |
| rawPaths: string[], | |
| ): Promise<ValidationResult> { | |
| const cwd = getCwd() | |
| for (const rawPath of rawPaths) { | |
| const fullPath = expandPath(rawPath) | |
| try { | |
| const stats = await stat(fullPath) | |
| if (!stats.isFile()) { | |
| return { | |
| result: false, | |
| message: `Attachment "${rawPath}" is not a regular file.`, | |
| errorCode: 1, | |
| } | |
| } | |
| } catch (e) { | |
| const code = getErrnoCode(e) | |
| if (code === 'ENOENT') { | |
| return { | |
| result: false, | |
| message: `Attachment "${rawPath}" does not exist. Current working directory: ${cwd}.`, | |
| errorCode: 1, | |
| } | |
| } | |
| if (code === 'EACCES' || code === 'EPERM') { | |
| return { | |
| result: false, | |
| message: `Attachment "${rawPath}" is not accessible (permission denied).`, | |
| errorCode: 1, | |
| } | |
| } | |
| throw e | |
| } | |
| } | |
| return { result: true } | |
| } | |
| export async function resolveAttachments( | |
| rawPaths: string[], | |
| uploadCtx: { replBridgeEnabled: boolean; signal?: AbortSignal }, | |
| ): Promise<ResolvedAttachment[]> { | |
| // Stat serially (local, fast) to keep ordering deterministic, then upload | |
| // in parallel (network, slow). Upload failures resolve undefined — the | |
| // attachment still carries {path, size, isImage} for local renderers. | |
| const stated: ResolvedAttachment[] = [] | |
| for (const rawPath of rawPaths) { | |
| const fullPath = expandPath(rawPath) | |
| // Single stat — we need size, so this is the operation, not a guard. | |
| // validateInput ran before us, but the file could have moved since | |
| // (TOCTOU); if it did, let the error propagate so the model sees it. | |
| const stats = await stat(fullPath) | |
| stated.push({ | |
| path: fullPath, | |
| size: stats.size, | |
| isImage: IMAGE_EXTENSION_REGEX.test(fullPath), | |
| }) | |
| } | |
| // Dynamic import inside the feature() guard so upload.ts (axios, crypto, | |
| // zod, auth utils, MIME map) is fully eliminated from non-BRIDGE_MODE | |
| // builds. A static import would force module-scope evaluation regardless | |
| // of the guard inside uploadBriefAttachment — CLAUDE.md: "helpers defined | |
| // outside remain in the build even if never called". | |
| if (feature('BRIDGE_MODE')) { | |
| // Headless/SDK callers never set appState.replBridgeEnabled (only the TTY | |
| // REPL does, at main.tsx init). CLAUDE_CODE_BRIEF_UPLOAD lets a host that | |
| // runs the CLI as a subprocess opt in — e.g. the cowork desktop bridge, | |
| // which already passes CLAUDE_CODE_OAUTH_TOKEN for auth. | |
| const shouldUpload = | |
| uploadCtx.replBridgeEnabled || | |
| isEnvTruthy(process.env.CLAUDE_CODE_BRIEF_UPLOAD) | |
| const { uploadBriefAttachment } = await import('./upload.js') | |
| const uuids = await Promise.all( | |
| stated.map(a => | |
| uploadBriefAttachment(a.path, a.size, { | |
| replBridgeEnabled: shouldUpload, | |
| signal: uploadCtx.signal, | |
| }), | |
| ), | |
| ) | |
| return stated.map((a, i) => | |
| uuids[i] === undefined ? a : { ...a, file_uuid: uuids[i] }, | |
| ) | |
| } | |
| return stated | |
| } | |