Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
2.6 kB · 88 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889import type { McpbManifest } from '@anthropic-ai/mcpb'import { errorMessage } from '../errors.js'import { jsonParse } from '../slowOperations.js'
/** * Parses and validates a DXT manifest from a JSON object. * * Lazy-imports @anthropic-ai/mcpb: that package uses zod v3 which eagerly * creates 24 .bind(this) closures per schema instance (~300 instances between * schemas.js and schemas-loose.js). Deferring the import keeps ~700KB of bound * closures out of the startup heap for sessions that never touch .dxt/.mcpb. */export async function validateManifest( manifestJson: unknown,): Promise<McpbManifest> { const { McpbManifestSchema } = await import('@anthropic-ai/mcpb') const parseResult = McpbManifestSchema.safeParse(manifestJson)
if (!parseResult.success) { const errors = parseResult.error.flatten() const errorMessages = [ ...Object.entries(errors.fieldErrors).map( ([field, errs]) => `${field}: ${errs?.join(', ')}`, ), ...(errors.formErrors || []), ] .filter(Boolean) .join('; ')
throw new Error(`Invalid manifest: ${errorMessages}`) }
return parseResult.data}
/** * Parses and validates a DXT manifest from raw text data. */export async function parseAndValidateManifestFromText( manifestText: string,): Promise<McpbManifest> { let manifestJson: unknown
try { manifestJson = jsonParse(manifestText) } catch (error) { throw new Error(`Invalid JSON in manifest.json: ${errorMessage(error)}`) }
return validateManifest(manifestJson)}
/** * Parses and validates a DXT manifest from raw binary data. */export async function parseAndValidateManifestFromBytes( manifestData: Uint8Array,): Promise<McpbManifest> { const manifestText = new TextDecoder().decode(manifestData) return parseAndValidateManifestFromText(manifestText)}
/** * Generates an extension ID from author name and extension name. * Uses the same algorithm as the directory backend for consistency. */export function generateExtensionId( manifest: McpbManifest, prefix?: 'local.unpacked' | 'local.dxt',): string { const sanitize = (str: string) => str .toLowerCase() .replace(/\s+/g, '-') .replace(/[^a-z0-9-_.]/g, '') .replace(/-+/g, '-') .replace(/^-+|-+$/g, '')
const authorName = manifest.author.name const extensionName = manifest.name
const sanitizedAuthor = sanitize(authorName) const sanitizedName = sanitize(extensionName)
return prefix ? `${prefix}.${sanitizedAuthor}.${sanitizedName}` : `${sanitizedAuthor}.${sanitizedName}`}