Download apps/vscode/scripts/vsix-verify.mjs from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 17.2 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/apps/vscode/scripts/vsix-verify.mjs
- Command line
-
hf download hf://SaylorTwift/kimi-code/apps/vscode/scripts/vsix-verify.mjs
-
curl -L -o vsix-verify.mjs https://huggingface.co/SaylorTwift/kimi-code/resolve/main/apps/vscode/scripts/vsix-verify.mjs
17.2 kB
| import { builtinModules } from 'node:module'; | |
| import { spawnSync } from 'node:child_process'; | |
| import { existsSync } from 'node:fs'; | |
| import { | |
| mkdtemp, | |
| mkdir, | |
| readFile, | |
| readdir, | |
| rm, | |
| stat, | |
| writeFile, | |
| } from 'node:fs/promises'; | |
| import { homedir, tmpdir } from 'node:os'; | |
| import { dirname, extname, join, relative, resolve, sep } from 'node:path'; | |
| import { pathToFileURL } from 'node:url'; | |
| import { isDeepStrictEqual } from 'node:util'; | |
| import { parse } from 'acorn'; | |
| import { extractZip } from './zip.mjs'; | |
| import { | |
| defaultVsixOutputDir, | |
| extensionRoot, | |
| isMainModule, | |
| normalizeVsixTargets, | |
| vsixFileName, | |
| } from './vsix-targets.mjs'; | |
| const REQUIRED_WEBVIEW_FILES = [ | |
| 'dist/webview.js', | |
| 'dist/kimi-banner-dark.svg', | |
| 'dist/kimi-banner-light.svg', | |
| 'dist/kimi-logo.png', | |
| ]; | |
| const FORBIDDEN_PATH_SEGMENTS = new Set([ | |
| '.kimi', | |
| '.kimi-code', | |
| '.vscode', | |
| '__tests__', | |
| 'cache', | |
| 'caches', | |
| 'credentials', | |
| 'logs', | |
| 'node_modules', | |
| 'profile', | |
| 'profiles', | |
| 'runtime', | |
| 'scripts', | |
| 'session', | |
| 'sessions', | |
| 'src', | |
| 'state', | |
| 'states', | |
| 'test', | |
| 'tests', | |
| 'tokens', | |
| 'webview-ui', | |
| ]); | |
| const FORBIDDEN_EXTENSIONS = new Set(['.jsonl', '.log', '.map', '.py', '.pyc', '.ts', '.tsx']); | |
| const TEXT_EXTENSIONS = new Set([ | |
| '.cjs', | |
| '.css', | |
| '.html', | |
| '.js', | |
| '.json', | |
| '.md', | |
| '.mjs', | |
| '.svg', | |
| '.txt', | |
| '.xml', | |
| ]); | |
| const BUILTIN_IMPORTS = new Set( | |
| builtinModules.flatMap((name) => [name, name.startsWith('node:') ? name.slice(5) : `node:${name}`]), | |
| ); | |
| // `ws` probes these native accelerators inside try/catch and immediately uses | |
| // its bundled JavaScript fallback when they are absent. They are not required | |
| // runtime dependencies and must not be shipped as cross-platform native code. | |
| const OPTIONAL_FALLBACK_IMPORTS = new Set(['bufferutil', 'canvas', 'utf-8-validate']); | |
| const MANIFEST_FIELDS = [ | |
| 'name', | |
| 'publisher', | |
| 'displayName', | |
| 'version', | |
| 'engines', | |
| 'extensionKind', | |
| 'capabilities', | |
| 'activationEvents', | |
| 'main', | |
| 'icon', | |
| ]; | |
| const CONTRIBUTE_FIELDS = [ | |
| 'commands', | |
| 'configuration', | |
| 'keybindings', | |
| 'menus', | |
| 'views', | |
| 'viewsContainers', | |
| ]; | |
| export async function verifyVsix(vsixPath, target, options = {}) { | |
| const extractionRoot = await mkdtemp(join(tmpdir(), 'kimi-vsix-audit-')); | |
| try { | |
| await extractZip(vsixPath, extractionRoot); | |
| return await auditExtractedVsix(extractionRoot, target, options); | |
| } finally { | |
| await rm(extractionRoot, { recursive: true, force: true }); | |
| } | |
| } | |
| export async function auditExtractedVsix(extractionRoot, target, options = {}) { | |
| const sourceRoot = options.sourceRoot ?? extensionRoot; | |
| const extensionDir = join(extractionRoot, 'extension'); | |
| const files = await listFiles(extractionRoot); | |
| const fileSet = new Set(files); | |
| requireFile(fileSet, 'extension.vsixmanifest'); | |
| requireFile(fileSet, '[Content_Types].xml'); | |
| requireFile(fileSet, 'extension/package.json'); | |
| const packagedManifest = await readJson(join(extensionDir, 'package.json'), 'package.json'); | |
| const sourceManifest = await readJson(join(sourceRoot, 'package.json'), 'source package.json'); | |
| await verifyTargetManifest(extractionRoot, target); | |
| verifyPackageManifest(packagedManifest, sourceManifest); | |
| verifyRequiredFiles(fileSet, packagedManifest); | |
| verifyForbiddenFiles(files); | |
| await verifyNoSensitiveContent(extractionRoot, files, sourceRoot, options.forbiddenText ?? []); | |
| await verifyRuntimeImports(extensionDir, files); | |
| await verifyEntryImport(extensionDir, packagedManifest.main); | |
| const bytes = await totalSize(extractionRoot, files); | |
| return { target, files: files.length, bytes }; | |
| } | |
| async function verifyTargetManifest(extractionRoot, target) { | |
| const xml = await readFile(join(extractionRoot, 'extension.vsixmanifest'), 'utf8'); | |
| const actual = xml.match(/\bTargetPlatform="([^"]+)"/)?.[1]; | |
| if (actual !== target) { | |
| throw new Error( | |
| `VSIX manifest target is ${actual ?? 'missing'}, expected ${target}.`, | |
| ); | |
| } | |
| } | |
| function verifyPackageManifest(packaged, source) { | |
| if (typeof packaged.main !== 'string' || !packaged.main.endsWith('.js')) { | |
| throw new Error(`Packaged extension main must be a .js entry, got ${String(packaged.main)}.`); | |
| } | |
| if (packaged.main !== './dist/extension.js') { | |
| throw new Error(`Packaged extension main is ${packaged.main}, expected ./dist/extension.js.`); | |
| } | |
| for (const field of MANIFEST_FIELDS) { | |
| if (!isDeepStrictEqual(packaged[field], source[field])) { | |
| throw new Error(`Packaged package.json field "${field}" does not match the source manifest.`); | |
| } | |
| } | |
| for (const field of CONTRIBUTE_FIELDS) { | |
| if (!isDeepStrictEqual(packaged.contributes?.[field], source.contributes?.[field])) { | |
| throw new Error( | |
| `Packaged package.json contributes.${field} does not match the source manifest.`, | |
| ); | |
| } | |
| } | |
| } | |
| function verifyRequiredFiles(fileSet, manifest) { | |
| const required = [ | |
| 'extension/LICENSE.txt', | |
| `extension/${stripLeadingDotSlash(manifest.main)}`, | |
| ...REQUIRED_WEBVIEW_FILES.map((file) => `extension/${file}`), | |
| ]; | |
| requireOneOf(fileSet, ['extension/README.md', 'extension/readme.md'], 'marketplace README'); | |
| if (typeof manifest.icon === 'string') required.push(`extension/${manifest.icon}`); | |
| for (const container of Object.values(manifest.contributes?.viewsContainers ?? {})) { | |
| if (!Array.isArray(container)) continue; | |
| for (const view of container) { | |
| if (typeof view?.icon === 'string') required.push(`extension/${view.icon}`); | |
| } | |
| } | |
| for (const file of required) requireFile(fileSet, file); | |
| } | |
| function verifyForbiddenFiles(files) { | |
| for (const file of files) { | |
| const normalized = file.replaceAll('\\', '/'); | |
| const lower = normalized.toLowerCase(); | |
| const extensionRelative = lower.startsWith('extension/') ? lower.slice('extension/'.length) : lower; | |
| const segments = extensionRelative.split('/'); | |
| const forbiddenSegment = segments.find((segment) => FORBIDDEN_PATH_SEGMENTS.has(segment)); | |
| if (forbiddenSegment !== undefined) { | |
| throw new Error(`Forbidden package path segment "${forbiddenSegment}" in ${normalized}.`); | |
| } | |
| if (FORBIDDEN_EXTENSIONS.has(extname(lower))) { | |
| throw new Error(`Forbidden package file type in ${normalized}.`); | |
| } | |
| if ( | |
| lower.includes('kimi-agent-sdk') || | |
| lower.includes('download-cli') || | |
| lower.includes('/bin/kimi/') || | |
| /(^|\/)uv(?:\.exe)?$/.test(lower) | |
| ) { | |
| throw new Error(`Legacy CLI/runtime artifact found in ${normalized}.`); | |
| } | |
| } | |
| } | |
| async function verifyNoSensitiveContent(extractionRoot, files, sourceRoot, extraForbiddenText) { | |
| const secretValues = [process.env.VSCE_PAT, process.env.OVSX_PAT] | |
| .filter((value) => typeof value === 'string' && value.length >= 8); | |
| const forbidden = [sourceRoot, homedir(), ...extraForbiddenText, ...secretValues] | |
| .filter((value) => typeof value === 'string' && value.length >= 4) | |
| .flatMap((value) => [value, value.replaceAll('\\', '/'), value.replaceAll('/', '\\')]); | |
| for (const file of files) { | |
| if (!TEXT_EXTENSIONS.has(extname(file).toLowerCase())) continue; | |
| const content = await readFile(join(extractionRoot, file), 'utf8'); | |
| const match = forbidden.find((value) => content.includes(value)); | |
| if (match === undefined) continue; | |
| const label = secretValues.includes(match) ? 'a marketplace token' : 'a local filesystem path'; | |
| throw new Error(`Packaged text file ${file} contains ${label}.`); | |
| } | |
| } | |
| async function verifyRuntimeImports(extensionDir, files) { | |
| const distFiles = files.filter( | |
| (file) => file.startsWith('extension/dist/') && ['.cjs', '.js', '.mjs'].includes(extname(file)), | |
| ); | |
| if (distFiles.length === 0) throw new Error('No JavaScript extension bundle files were packaged.'); | |
| for (const archivePath of distFiles) { | |
| const localPath = join(dirname(extensionDir), archivePath); | |
| const source = await readFile(localPath, 'utf8'); | |
| for (const specifier of collectLiteralImports(source)) { | |
| if (specifier === 'vscode' || BUILTIN_IMPORTS.has(specifier)) continue; | |
| if (OPTIONAL_FALLBACK_IMPORTS.has(specifier)) continue; | |
| if (specifier.startsWith('node:')) continue; | |
| if (specifier.startsWith('.') || specifier.startsWith('/')) { | |
| if (specifier.startsWith('/')) { | |
| throw new Error(`Absolute runtime import "${specifier}" in ${archivePath}.`); | |
| } | |
| const dependencyPath = resolve(dirname(localPath), stripImportSuffix(specifier)); | |
| if (!runtimeImportExists(dependencyPath)) { | |
| throw new Error(`Missing relative runtime import "${specifier}" in ${archivePath}.`); | |
| } | |
| continue; | |
| } | |
| if (specifier.startsWith('data:') || specifier.startsWith('file:')) continue; | |
| throw new Error(`Bare runtime dependency "${specifier}" remains in ${archivePath}.`); | |
| } | |
| } | |
| } | |
| function collectLiteralImports(source) { | |
| const imports = new Set(); | |
| const program = parse(source, { | |
| allowHashBang: true, | |
| ecmaVersion: 'latest', | |
| sourceType: 'module', | |
| }); | |
| walkSyntax(program, (node) => { | |
| if ( | |
| node.type === 'ImportDeclaration' || | |
| node.type === 'ExportAllDeclaration' || | |
| node.type === 'ExportNamedDeclaration' | |
| ) { | |
| const specifier = literalString(node.source); | |
| if (specifier !== undefined) imports.add(specifier); | |
| return; | |
| } | |
| if (node.type === 'ImportExpression') { | |
| const specifier = literalString(node.source); | |
| if (specifier !== undefined) imports.add(specifier); | |
| return; | |
| } | |
| if (node.type === 'CallExpression' && isRuntimeRequire(node.callee)) { | |
| const specifier = literalString(node.arguments?.[0]); | |
| if (specifier !== undefined) imports.add(specifier); | |
| } | |
| }); | |
| return imports; | |
| } | |
| function walkSyntax(value, visit) { | |
| if (Array.isArray(value)) { | |
| for (const item of value) walkSyntax(item, visit); | |
| return; | |
| } | |
| if (typeof value !== 'object' || value === null) return; | |
| if (typeof value.type === 'string') visit(value); | |
| for (const [key, child] of Object.entries(value)) { | |
| if (key === 'start' || key === 'end' || key === 'loc' || key === 'range') continue; | |
| walkSyntax(child, visit); | |
| } | |
| } | |
| function isRuntimeRequire(callee) { | |
| if (callee?.type === 'Identifier') return /^(?:__)?require\d*$/.test(callee.name); | |
| if (callee?.type !== 'MemberExpression' || callee.computed === true) return false; | |
| // `this.require(...)` is an ordinary class method call (e.g. a private field | |
| // accessor in bundled sources), never a CommonJS require of a bare specifier. | |
| if (callee.object?.type === 'ThisExpression') return false; | |
| return callee.property?.type === 'Identifier' && callee.property.name === 'require'; | |
| } | |
| function literalString(node) { | |
| if (node?.type === 'Literal' && typeof node.value === 'string') return node.value; | |
| if (node?.type === 'TemplateLiteral' && node.expressions?.length === 0) { | |
| return node.quasis?.[0]?.value?.cooked; | |
| } | |
| return undefined; | |
| } | |
| async function verifyEntryImport(extensionDir, main) { | |
| const mainPath = join(extensionDir, stripLeadingDotSlash(main)); | |
| const stubDir = join(extensionDir, 'node_modules', 'vscode'); | |
| await mkdir(stubDir, { recursive: true }); | |
| await writeFile( | |
| join(stubDir, 'package.json'), | |
| `${JSON.stringify({ name: 'vscode', version: '0.0.0-test', type: 'module', exports: './index.js' }, null, 2)}\n`, | |
| ); | |
| await writeFile(join(stubDir, 'index.js'), 'export {};\n'); | |
| const script = [ | |
| `const extension = await import(${JSON.stringify(pathToFileURL(mainPath).href)});`, | |
| 'if (typeof extension.activate !== "function") {', | |
| ' throw new Error("extension bundle does not export activate");', | |
| '}', | |
| ].join('\n'); | |
| const env = { ...process.env }; | |
| delete env.NODE_PATH; | |
| const result = spawnSync(process.execPath, ['--input-type=module', '--eval', script], { | |
| cwd: dirname(extensionDir), | |
| env, | |
| encoding: 'utf8', | |
| timeout: 30_000, | |
| }); | |
| await rm(join(extensionDir, 'node_modules'), { recursive: true, force: true }); | |
| if (result.error !== undefined) { | |
| throw new Error(`Unable to import the unpacked extension entry: ${result.error.message}`); | |
| } | |
| if (result.status !== 0) { | |
| const detail = conciseProcessError(result.stderr || result.stdout); | |
| throw new Error(`Unpacked extension entry import failed: ${detail}`); | |
| } | |
| } | |
| async function readJson(path, label) { | |
| try { | |
| return JSON.parse(await readFile(path, 'utf8')); | |
| } catch (error) { | |
| throw new Error(`${label} is not valid JSON: ${describeError(error)}`, { cause: error }); | |
| } | |
| } | |
| async function listFiles(root) { | |
| const output = []; | |
| async function visit(directory) { | |
| const entries = await readdir(directory, { withFileTypes: true }); | |
| for (const entry of entries) { | |
| const localPath = join(directory, entry.name); | |
| if (entry.isDirectory()) { | |
| await visit(localPath); | |
| } else if (entry.isFile()) { | |
| output.push(relative(root, localPath).split(sep).join('/')); | |
| } else { | |
| throw new Error(`Unsupported non-file entry in unpacked VSIX: ${localPath}`); | |
| } | |
| } | |
| } | |
| await visit(root); | |
| return output.sort(); | |
| } | |
| async function totalSize(root, files) { | |
| let bytes = 0; | |
| for (const file of files) bytes += (await stat(join(root, file))).size; | |
| return bytes; | |
| } | |
| function requireFile(fileSet, file) { | |
| if (fileSet.has(file)) return; | |
| throw new Error(`Required VSIX resource is missing: ${file}`); | |
| } | |
| function requireOneOf(fileSet, files, label) { | |
| if (files.some((file) => fileSet.has(file))) return; | |
| throw new Error(`Required VSIX resource is missing: ${label} (${files.join(' or ')}).`); | |
| } | |
| function runtimeImportExists(path) { | |
| return [path, `${path}.js`, `${path}.mjs`, `${path}.cjs`, join(path, 'index.js')].some(existsSync); | |
| } | |
| function stripImportSuffix(specifier) { | |
| return specifier.split(/[?#]/, 1)[0]; | |
| } | |
| function stripLeadingDotSlash(value) { | |
| return String(value).replace(/^\.\//, ''); | |
| } | |
| function describeError(error) { | |
| return error instanceof Error ? error.message : String(error); | |
| } | |
| function conciseProcessError(output) { | |
| const lines = String(output).trim().split(/\r?\n/).filter(Boolean); | |
| return lines.slice(-4).join('\n') || 'process exited without an error message'; | |
| } | |
| function parseArguments(argv) { | |
| const targets = []; | |
| let outputDir = defaultVsixOutputDir; | |
| let file; | |
| let directory; | |
| let help = false; | |
| for (let index = 0; index < argv.length; index += 1) { | |
| const argument = argv[index]; | |
| if (argument === '--') { | |
| continue; | |
| } else if (argument === '--help' || argument === '-h') { | |
| help = true; | |
| } else if (argument === '--out-dir') { | |
| outputDir = requireOptionValue(argv, ++index, '--out-dir'); | |
| } else if (argument === '--target') { | |
| targets.push(requireOptionValue(argv, ++index, '--target')); | |
| } else if (argument === '--file') { | |
| file = requireOptionValue(argv, ++index, '--file'); | |
| } else if (argument === '--directory') { | |
| directory = requireOptionValue(argv, ++index, '--directory'); | |
| } else if (argument.startsWith('-')) { | |
| throw new Error(`Unknown option: ${argument}`); | |
| } else { | |
| targets.push(argument); | |
| } | |
| } | |
| if (file !== undefined && directory !== undefined) { | |
| throw new Error('--file and --directory cannot be used together.'); | |
| } | |
| const normalizedTargets = normalizeVsixTargets(targets); | |
| if ((file !== undefined || directory !== undefined) && normalizedTargets.length !== 1) { | |
| throw new Error('--file and --directory require exactly one target.'); | |
| } | |
| return { targets: normalizedTargets, outputDir: resolve(outputDir), file, directory, help }; | |
| } | |
| function requireOptionValue(argv, index, option) { | |
| const value = argv[index]; | |
| if (value !== undefined && !value.startsWith('-')) return value; | |
| throw new Error(`${option} requires a value.`); | |
| } | |
| function usage() { | |
| return [ | |
| 'Usage: node scripts/vsix-verify.mjs [targets...] [--out-dir <directory>]', | |
| ' node scripts/vsix-verify.mjs --target <target> --file <file.vsix>', | |
| ' node scripts/vsix-verify.mjs --target <target> --directory <unpacked-vsix>', | |
| '', | |
| 'The verifier performs a package-content audit and an entry import smoke only.', | |
| 'It does not claim that a target passed a real operating-system E2E run.', | |
| ].join('\n'); | |
| } | |
| async function main() { | |
| const options = parseArguments(process.argv.slice(2)); | |
| if (options.help) { | |
| console.log(usage()); | |
| return; | |
| } | |
| for (const target of options.targets) { | |
| const input = options.directory ?? options.file ?? join(options.outputDir, vsixFileName(target)); | |
| const result = options.directory === undefined | |
| ? await verifyVsix(resolve(input), target, { sourceRoot: extensionRoot }) | |
| : await auditExtractedVsix(resolve(input), target, { sourceRoot: extensionRoot }); | |
| console.log( | |
| `Verified ${target}: ${result.files} files, ${result.bytes} unpacked bytes; static audit and entry import smoke passed (package-only).`, | |
| ); | |
| } | |
| } | |
| if (isMainModule(import.meta.url)) { | |
| main().catch((error) => { | |
| console.error(`VSIX verification failed: ${describeError(error)}`); | |
| process.exitCode = 1; | |
| }); | |
| } | |