// npm 패키지
@antv/chart-visualization-skills
Chart visualization skills for AntV, can be used in various scenarios such as data analysis, business intelligence, and dashboard development. Skills and CLI are included.
버전
4
메인테이너
51
라이선스
MIT
최초 publish
2026-04-14
publisher
kn9117
tarball
1,402,663 B
AUTO-PUBLISHED·1개 버전 인덱싱됨·최근 publish: 2026-04-28
// publisher 캠페인by kn9117
이 계정에서 catch된 패키지 4건고립된 catch가 아닙니다. 동일 publisher가 3개의 다른 패키지를 추가로 발행했고, 모두 파이프라인이 catch했습니다 — 일회성이 아닌 조직적 캠페인의 형태. 아래 링크는 각 형제 catch의 분석으로 이동합니다.
// offending code· @0.1.3· no static-pattern hits
llm: benign · 0.85→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
- @0.1.3··AUTO-PUBLISHED·publisher: kn9117heuristic 75/100static flags 0llm benign (0.85) via ollamanew-publisher:21dosv-flagged:MAL-2026-3859
→ 의심 전송지 없음, 원격 실행 형태 없음 — 1 known-vendor host(s).
// offending code· no static-pattern hits
--- package.json (entry) --- { "name": "@antv/chart-visualization-skills", "version": "0.1.3", "description": "Chart visualization skills for AntV, can be used in various scenarios such as data analysis, business intelligence, and dashboard development. Skills and CLI are included.", "type": "commonjs", "main": "dist/api.js", "types": "dist/api.d.ts", "bin": { "antv": "dist/index.js" }, "files": [ "dist", "README.md", "LICENSE" ], "keywords": [ "antv", "chart", "visualization", "skills", "cli" ], "scripts": { "build": "npm run build:index && tsc && npm run copy:index", "build:index": "tsx src/scripts/build.ts", "copy:index": "rm -rf dist/index && cp -R src/index dist/", "test": "vitest run", "test:watch": "vitest", "precommit": "npm run build" }, "dependencies": { "commander": "^12.1.0", "gray-matter": "^4.0.3" }, "devDependencies": { "@types/node": "^20.11.0", "tsx": "^4.21.0", "typescript": "^5.3.0", "vitest": "^1.2.0" }, "author": "AntV AI Team", "license": "MIT", "repository": "git@github.com:antvis/chart-visualization-skills.git" } --- index.js (entry) --- #!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const path_1 = __importDefault(require("path")); const retrieve_1 = require("./commands/retrieve"); const list_1 = require("./commands/list"); const info_1 = require("./commands/info"); const get_1 = require("./commands/get"); const pkg = require(path_1.default.resolve(__dirname, '../package.json')); const program = new commander_1.Command(); program .name('antv') .description('CLI tool for AntV chart visualization skills retrieval') .version(pkg.version) .option('--debug', 'Show full stack trace on error'); (0, retrieve_1.registerRetrieveCommand)(program); (0, get_1.registerGetCommand)(program); (0, list_1.registerListCommand)(program); (0, info_1.registerInfoCommand)(program); // Wrap parse() so errors thrown inside synchronous action handlers are caught // here rather than relying on the global uncaughtException hook, which would // also swallow unexpected programming errors (TypeError, Ref --- bundled output (OSV-MAL flagged — LLM scope expansion) --- --- dist/api.d.ts (bundled) --- import type { Skill, SkillInfo, RetrieveOptions } from './core/types'; export type { Skill, SkillInfo, RetrieveOptions }; /** * Retrieve skills based on a query. * * Preferred: pass an options object. * @example retrieve('bar chart', { library: 'g2', topK: 5, content: true }) * * Legacy positional signature still supported for backwards compatibility. * @example retrieve('bar chart', 'g2', 5, true) */ export declare function retrieve(query: string, options?: RetrieveOptions): Skill[]; /** @deprecated Use the options-object overload instead. */ export declare function retrieve(query: string, library?: string, topk?: number, content?: boolean): Skill[]; /** * Get a single skill by its exact ID. * * @param id The skill ID (e.g. 'g2-mark-bar'). * @param library Optional: restrict the search to a specific library. * @returns The skill with full content, or undefined if not found. * @example getSkillById('g2-mark-bar') */ export declare function getSkillById(id: string, library?: string): Skill | undefined; /** * Get skill info embedded in the library index. * * @param library The library to get info for (default: 'g2'). * @example info('g2') * @returns The skill info, or undefined if not available. */ export declare function info(library?: string): SkillInfo | undefined; /** * Return the list of libraries that have a built index on disk. * @example libraries() // ['g2', 'g6'] */ export declare function libraries(): string[]; --- dist/api.js (bundled) --- "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.retrieve = retrieve; exports.getSkillById = getSkillById; exports.info = info; exports.libraries = libraries; const retriever_1 = require("./core/retriever"); function retrieve(query, libraryOrOpts, topk = 7, content = false) { if (typeof libraryOrOpts === 'string' || libraryOrOpts === undefined) { return (0, retriever_1.retrieve)(query, { library: libraryOrOpts, topK: topk, content }); } return (0, retriever_1.retrieve)(query, libraryOrOpts); } /** * Get a single skill by its exact ID. * * @param id The skill ID (e.g. 'g2-mark-bar'). * @param library Optional: restrict the search to a specific library. * @returns The skill with full content, or undefined if not found. * @example getSkillById('g2-mark-bar') */ function getSkillById(id, library) { return (0, retriever_1.getSkillById)(id, library); } /** * Get skill info embedded in the library index. * * @param library The library to get info for (default: 'g2'). * @example info('g2') * @returns The skill info, or undefined if not available. */ function info(library = 'g2') { return (0, retriever_1.getSkillInfo)(library); } /** * Return the list of libraries that have a built index on disk. * @example libraries() // ['g2', 'g6'] */ function libraries() { return (0, retriever_1.availableLibraries)(); } //# sourceMappingURL=api.js.map --- dist/index.d.ts (bundled) --- #!/usr/bin/env node export {}; --- dist/index.js (bundled) --- #!/usr/bin/env node "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const path_1 = __importDefault(require("path")); const retrieve_1 = require("./commands/retrieve"); const list_1 = require("./commands/list"); const info_1 = require("./commands/info"); const get_1 = require("./commands/get"); const pkg = require(path_1.default.resolve(__dirname, '../package.json')); const program = new commander_1.Command(); program .name('antv') .description('CLI tool for AntV chart visualization skills retrieval') .version(pkg.version) .option('--debug', 'Show full stack trace on error'); (0, retrieve_1.registerRetrieveCommand)(program); (0, get_1.registerGetCommand)(program); (0, list_1.registerListCommand)(program); (0, info_1.registerInfoCommand)(program); // Wrap parse() so errors thrown inside synchronous action handlers are caught // here rather than relying on the global uncaughtException hook, which would // also swallow unexpected programming errors (TypeError, ReferenceError, etc.). // Pass --debug to see the full stack when debugging unexpected failures. try { program.parse(); } catch (err) { const debug = process.argv.includes('--debug'); if (debug) { console.error(err); } else { console.error(`Error: ${err instanceof Error ? err.message : String(err)}`); } process.exit(1); } //# sourceMappingURL=index.js.map --- dist/scripts/build.d.ts (bundled) --- #!/usr/bin/env node /** * Build script: generates JSON index files from skill markdown files. * Run independently before publishing: `node dist/scripts/build.js` */ export {}; --- dist/scripts/build.js (bundled) --- #!/usr/bin/env node "use strict"; /** * Build script: generates JSON index files from skill markdown files. * Run independently before publishing: `node dist/scripts/build.js` */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const gray_matter_1 = __importDefault(require("gray-matter")); // Allow overriding the project root via --root=<dir> (used by harness when running inside a worktree) const rootArg = process.argv.find((a) => a.startsWith('--root=')); const PKG_ROOT = rootArg ? path_1.default.resolve(rootArg.slice('--root='.length)) : path_1.default.resolve(__dirname, '../..'); const SKILLS_DIR = path_1.default.join(PKG_ROOT, 'skills'); const INDEX_DIR = path_1.default.join(PKG_ROOT, 'src', 'index'); const LIBRARY_PATHS = { g2: 'antv-g2-chart', g6: 'antv-g6-graph', }; function walkDir(dir, library) { const skills = []; if (!fs_1.default.existsSync(dir)) return skills; // Keep deterministic output across environments to avoid index diff noise. const entries = fs_1.default.readdirSync(dir, { withFileTypes: true }) .sort((a, b) => a.name.localeCompare(b.name)); for (const entry of entries) { const fullPath = path_1.default.join(dir, entry.name); if (entry.isDirectory()) { skills.push(...walkDir(fullPath, library)); } else if (entry.isFile() && entry.name.endsWith('.md') && !['README.md', 'CONTRIBUTING.md'].includes(entry.name)) { const content = fs_1.default.readFileSync(fullPath, 'utf-8'); const parsed = (0, gray_matter_1.default)(content); const meta = parsed.data; if (library && meta.library && meta.library !== library) continue; if (!meta.id) { --- dist/mcp/server.d.ts (bundled) --- export declare function startMcpServer(): Promise<void>; --- dist/mcp/server.js (bundled) --- "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.startMcpServer = startMcpServer; const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); const retriever_1 = require("../core/retriever"); const pkg = require('../../package.json'); async function startMcpServer() { const server = new index_js_1.Server({ name: 'antv-chart-visualization-skills', version: pkg.version }, { capabilities: { tools: {} } }); server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({ tools: [ { name: 'retrieve_skill', description: 'BM25 full-text search over AntV chart visualization skills. ' + 'Returns the most relevant skills for a given query. ' +
