Files
video-create/.claude/skills/video-from-script/scripts/lib/cmd-validate.js
sion123 35488beef2 feat(skills): 集成 GPT Image 图片生成和编辑能力
- 新增 gpt-image-generator.js 脚本,支持文生图、图生图/重绘、批量生成
- 更新 pipeline 和 phase-images 支持 GPT Image 模型
- 更新技能文档,添加 GPT Image 使用说明和 API 特点
- 新增配置文件中的 GPT Image API 参数
2026-05-05 23:49:30 +08:00

120 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Command: validate — 校验 manifest.json 完整性
* Command: validate-account — 校验账号目录完整性
*/
const fs = require('fs')
const path = require('path')
const { loadManifest, ACCOUNTS_DIR } = require('./pipeline-utils')
function validateManifest(manifestPath) {
const issues = []
if (!fs.existsSync(manifestPath)) {
console.error(`错误: manifest 不存在: ${manifestPath}`)
process.exit(1)
}
let manifest
try {
manifest = loadManifest(manifestPath)
} catch (e) {
console.error(`错误: JSON 解析失败: ${e.message}`)
process.exit(1)
}
if (!manifest.account) issues.push('缺少顶层 account')
if (!manifest.imageModel) issues.push('缺少顶层 imageModel可选: gemini, gpt-image, mj')
if (!manifest.format) issues.push('缺少顶层 format如 9:16')
if (!manifest.items || !Array.isArray(manifest.items)) issues.push('缺少顶层 items 数组')
if (!manifest.mode) issues.push('缺少顶层 modesingle 或 framePair')
if (manifest.items && Array.isArray(manifest.items)) {
manifest.items.forEach((item, i) => {
const prefix = `items[${i}]`
if (!('script' in item || 'text' in item)) issues.push(`${prefix} 缺少 script 或 text中文文案`)
if (!item.shotDesc) issues.push(`${prefix} 缺少 shotDesc分镜描述`)
if (!item.imagePrompt) issues.push(`${prefix} 缺少 imagePrompt`)
if (manifest.mode === 'framePair' && !item.lastFramePrompt) {
issues.push(`${prefix} 首尾帧模式缺少 lastFramePromptimagePrompt 作为第一帧)`)
}
if (item.status && !['pending', 'generating', 'done', 'failed'].includes(item.status)) {
issues.push(`${prefix} status 无效: ${item.status}`)
}
if (item.status === 'done' && !item.file && !item.video && !item.url) {
issues.push(`${prefix} status=done 但缺少 file/video/url素材路径`)
}
})
}
if (issues.length === 0) {
console.log(`✓ Manifest 校验通过: ${manifestPath}`)
console.log(` ${manifest.items?.length || 0} items, account=${manifest.account}, mode=${manifest.mode}`)
} else {
console.error(`✗ 发现 ${issues.length} 个问题:`)
issues.forEach(issue => console.error(` - ${issue}`))
process.exit(1)
}
}
function validateAccount(accountId) {
const issues = []
const accountDir = path.join(ACCOUNTS_DIR, accountId)
if (!fs.existsSync(accountDir)) { console.error(`错误: 账号不存在: ${accountDir}`); process.exit(1) }
const accountPath = path.join(accountDir, 'account.json')
if (!fs.existsSync(accountPath)) { console.error('错误: 缺少 account.json'); process.exit(1) }
let config
try { config = JSON.parse(fs.readFileSync(accountPath, 'utf-8')) }
catch (e) { console.error(`错误: JSON 解析失败: ${e.message}`); process.exit(1) }
if (config.id !== accountId) issues.push(`id 不匹配: json="${config.id}" vs 目录="${accountId}"`)
if (!config.name) issues.push('缺少 name')
if (!config.imageModel) issues.push('缺少 imageModel')
if (!config.defaultFormat) issues.push('缺少 defaultFormat')
// 检查 prompts 文件
const promptFiles = [
{ field: 'storyboardPrompt', label: '分镜' },
{ field: 'imageStylePrompt', label: '图片提示词' },
{ field: 'videoStylePrompt', label: '视频提示词' },
]
for (const { field, label } of promptFiles) {
const relPath = config[field]
if (!relPath) {
issues.push(`缺少 ${field}prompts 路径)`)
} else {
const absPath = path.join(accountDir, relPath)
if (!fs.existsSync(absPath)) {
issues.push(`${label}文件不存在: ${relPath}`)
}
}
}
const refDir = path.join(accountDir, 'references')
const localRefs = fs.existsSync(refDir)
? fs.readdirSync(refDir).filter(f => /\.(png|jpg|jpeg|webp)$/i.test(f))
: []
const topRefs = config.references || []
if (localRefs.length === 0 && topRefs.length === 0) {
issues.push('无参考图(建议至少 1 张)')
}
for (const ref of topRefs) {
if (!ref.url) issues.push(`参考图 ${ref.file} 缺少 url未上传 OSS`)
}
if (issues.length === 0) {
console.log(`✓ 账号校验通过: ${accountId}`)
console.log(` ${config.name}, 模型: ${config.imageModel}+${config.videoModel || '(未指定)'}`)
console.log(` 参考图: ${localRefs.length} 本地, ${topRefs.length} 已上传`)
} else {
console.error(`✗ 发现 ${issues.length} 个问题:`)
issues.forEach(i => console.error(` - ${i}`))
process.exit(1)
}
}
module.exports = { validateManifest, validateAccount }