|
@@ -13,12 +13,13 @@ const PACKAGE_ID = 'claude-code-voc-intelligence';
|
|
|
const NPM_PACKAGE_NAME = '@vocmarket/voc-skill';
|
|
const NPM_PACKAGE_NAME = '@vocmarket/voc-skill';
|
|
|
const PACKAGE_ZIP = path.join(DIST_DIR, `${PACKAGE_ID}.zip`);
|
|
const PACKAGE_ZIP = path.join(DIST_DIR, `${PACKAGE_ID}.zip`);
|
|
|
const DIST_MANIFEST = path.join(DIST_DIR, `${PACKAGE_ID}-suite-manifest.json`);
|
|
const DIST_MANIFEST = path.join(DIST_DIR, `${PACKAGE_ID}-suite-manifest.json`);
|
|
|
-const TEMP_ROOT = path.join(os.tmpdir(), 'claude-code-voc-pkg', PACKAGE_ID);
|
|
|
|
|
|
|
+const TEMP_ROOT = path.join(os.tmpdir(), 'claude-code-voc-pkg', `${PACKAGE_ID}-${process.pid}-${Date.now()}`);
|
|
|
const TEST_ROOT = path.join(os.tmpdir(), 'claude-code-voc-pkg-test', PACKAGE_ID);
|
|
const TEST_ROOT = path.join(os.tmpdir(), 'claude-code-voc-pkg-test', PACKAGE_ID);
|
|
|
const CDN_PREFIX = 'x/claude-code-skills/packages';
|
|
const CDN_PREFIX = 'x/claude-code-skills/packages';
|
|
|
const CDN_KEY = `${CDN_PREFIX}/${PACKAGE_ID}.zip`;
|
|
const CDN_KEY = `${CDN_PREFIX}/${PACKAGE_ID}.zip`;
|
|
|
const CDN_DOMAIN = 'https://repos.fmode.cn';
|
|
const CDN_DOMAIN = 'https://repos.fmode.cn';
|
|
|
const BUCKET = 'nova-repos';
|
|
const BUCKET = 'nova-repos';
|
|
|
|
|
+const { auditIndex } = require(path.join(SUITE_DIR, 'scripts', 'audit-index.js'));
|
|
|
|
|
|
|
|
const REQUIRED_FILES = [
|
|
const REQUIRED_FILES = [
|
|
|
'SKILL.md',
|
|
'SKILL.md',
|
|
@@ -67,6 +68,7 @@ const REQUIRED_FILES = [
|
|
|
const EXCLUDED_DIRS = new Set([
|
|
const EXCLUDED_DIRS = new Set([
|
|
|
'node_modules',
|
|
'node_modules',
|
|
|
'memory',
|
|
'memory',
|
|
|
|
|
+ 'output',
|
|
|
'outputs',
|
|
'outputs',
|
|
|
'.npm-cache-acceptance',
|
|
'.npm-cache-acceptance',
|
|
|
'.tmp',
|
|
'.tmp',
|
|
@@ -131,16 +133,16 @@ function readJson(filePath) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function copyDirRecursive(srcDir, destDir) {
|
|
function copyDirRecursive(srcDir, destDir) {
|
|
|
- ensureDir(destDir);
|
|
|
|
|
let count = 0;
|
|
let count = 0;
|
|
|
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
|
if (entry.isDirectory() && EXCLUDED_DIRS.has(entry.name)) continue;
|
|
if (entry.isDirectory() && EXCLUDED_DIRS.has(entry.name)) continue;
|
|
|
- if (entry.isFile() && EXCLUDED_FILES.has(entry.name)) continue;
|
|
|
|
|
|
|
+ if (entry.isFile() && (EXCLUDED_FILES.has(entry.name) || /\.bak-[^/\\]+$/i.test(entry.name))) continue;
|
|
|
const src = path.join(srcDir, entry.name);
|
|
const src = path.join(srcDir, entry.name);
|
|
|
const dest = path.join(destDir, entry.name);
|
|
const dest = path.join(destDir, entry.name);
|
|
|
if (entry.isDirectory()) {
|
|
if (entry.isDirectory()) {
|
|
|
count += copyDirRecursive(src, dest);
|
|
count += copyDirRecursive(src, dest);
|
|
|
} else if (entry.isFile()) {
|
|
} else if (entry.isFile()) {
|
|
|
|
|
+ ensureDir(destDir);
|
|
|
ensureDir(path.dirname(dest));
|
|
ensureDir(path.dirname(dest));
|
|
|
fs.copyFileSync(src, dest);
|
|
fs.copyFileSync(src, dest);
|
|
|
count++;
|
|
count++;
|
|
@@ -204,6 +206,8 @@ function validateSuite() {
|
|
|
const manifest = readJson(MANIFEST_PATH);
|
|
const manifest = readJson(MANIFEST_PATH);
|
|
|
const mcpJson = readJson(path.join(SUITE_DIR, '.mcp.json'));
|
|
const mcpJson = readJson(path.join(SUITE_DIR, '.mcp.json'));
|
|
|
const rootSkill = fs.readFileSync(path.join(SUITE_DIR, 'SKILL.md'), 'utf8');
|
|
const rootSkill = fs.readFileSync(path.join(SUITE_DIR, 'SKILL.md'), 'utf8');
|
|
|
|
|
+ const indexAudit = auditIndex(SUITE_DIR);
|
|
|
|
|
+ if (indexAudit.status !== 'ok') missing.push(...indexAudit.issues.map(issue => `index audit: ${issue}`));
|
|
|
if (packageJson.name !== NPM_PACKAGE_NAME) missing.push('package.json:name mismatch');
|
|
if (packageJson.name !== NPM_PACKAGE_NAME) missing.push('package.json:name mismatch');
|
|
|
if (pluginJson.name !== 'voc-intelligence') missing.push('.claude-plugin/plugin.json:name mismatch');
|
|
if (pluginJson.name !== 'voc-intelligence') missing.push('.claude-plugin/plugin.json:name mismatch');
|
|
|
if (!/^description:\s*\S.+$/m.test(rootSkill)) missing.push('SKILL.md missing description');
|
|
if (!/^description:\s*\S.+$/m.test(rootSkill)) missing.push('SKILL.md missing description');
|