diff --git a/.impeccable/design.json b/.impeccable/design.json deleted file mode 100644 index f6cf184..0000000 --- a/.impeccable/design.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "schemaVersion": 2, - "generatedAt": "2026-07-16T19:19:35.000Z", - "title": "Design System: 漫剧资产工作台", - "extensions": { - "colorMeta": { - "primary-brick": { - "role": "primary", - "displayName": "沉稳砖红", - "canonical": "#8E3F23", - "tonalRamp": ["#35130C", "#552014", "#71311B", "#8E3F23", "#AD5A3C", "#CC8066", "#E7B3A2", "#F8E4DD"] - }, - "ink": { - "role": "neutral", - "displayName": "温黑墨色", - "canonical": "#272320", - "tonalRamp": ["#171412", "#272320", "#4C443F", "#756E67", "#9C958F", "#C4BFBA", "#E4E1DE", "#F6F5F4"] - }, - "workspace": { - "role": "neutral", - "displayName": "暖灰工作区", - "canonical": "#F5F0E8", - "tonalRamp": ["#2D2924", "#514A42", "#756C61", "#9A8F81", "#BDB3A5", "#D8D0C4", "#EBE5DC", "#F5F0E8"] - }, - "surface": { - "role": "neutral", - "displayName": "清洁表面", - "canonical": "#FFFDF9", - "tonalRamp": ["#302D29", "#56514A", "#7D766C", "#A49C91", "#C9C2B8", "#E4DED6", "#F4F0EA", "#FFFDF9"] - }, - "success": { - "role": "secondary", - "displayName": "审核绿色", - "canonical": "#1F6A46", - "tonalRamp": ["#0B281A", "#123C28", "#195238", "#1F6A46", "#4D8969", "#7CAB91", "#B0D0BC", "#E5F2E9"] - }, - "danger": { - "role": "tertiary", - "displayName": "返工红色", - "canonical": "#9E3D31", - "tonalRamp": ["#35120F", "#571E19", "#7A2D25", "#9E3D31", "#BD6155", "#D88C82", "#EABCB6", "#FAE9E6"] - } - }, - "typographyMeta": { - "project-title": { - "displayName": "项目标题", - "purpose": "只用于项目名称和最高层创作标题。" - }, - "headline": { - "displayName": "界面标题", - "purpose": "详情章节和 Dialog 主标题。" - }, - "body": { - "displayName": "正文", - "purpose": "资产说明、提示词和状态解释。" - }, - "label": { - "displayName": "标签", - "purpose": "字段名、状态和辅助信息。" - } - }, - "shadows": [ - { - "name": "dialog-lift", - "value": "0 24px 64px rgba(39, 35, 32, 0.22)", - "purpose": "首次设置 Dialog 和阻断背景操作的确认浮层。" - }, - { - "name": "compact-popover", - "value": "0 8px 20px rgba(39, 35, 32, 0.14)", - "purpose": "小型菜单、Toast 和大图预览入口。" - } - ], - "motion": [ - { - "name": "state-fast", - "value": "160ms cubic-bezier(0.22, 1, 0.36, 1)", - "purpose": "按钮、筛选器和选中状态反馈。" - }, - { - "name": "disclosure", - "value": "220ms cubic-bezier(0.22, 1, 0.36, 1)", - "purpose": "辅助信息的展开收起。" - } - ], - "breakpoints": [ - { - "name": "laptop", - "value": "1180px" - }, - { - "name": "desktop", - "value": "1440px" - } - ] - }, - "components": [ - { - "name": "主要按钮", - "kind": "button", - "refersTo": "button-primary", - "description": "用于保存决定、确认设置和推进当前阶段。", - "html": "", - "css": ".ds-btn-primary { border: 0; border-radius: 8px; padding: 10px 16px; color: #FFFDF9; background: #8E3F23; font: 700 14px/1.45 \"PingFang SC\", system-ui, sans-serif; cursor: pointer; transition: background 160ms cubic-bezier(0.22,1,0.36,1); } .ds-btn-primary:hover { background: #71311B; } .ds-btn-primary:focus-visible { outline: 3px solid rgba(170,101,61,.24); outline-offset: 2px; }" - }, - { - "name": "次要按钮", - "kind": "button", - "refersTo": "button-secondary", - "description": "用于重新载入、取消和非主要操作。", - "html": "", - "css": ".ds-btn-secondary { border: 1px solid #DED5CA; border-radius: 8px; padding: 9px 14px; color: #5E4E43; background: #FFFDF9; font: 700 14px/1.45 \"PingFang SC\", system-ui, sans-serif; cursor: pointer; transition: border-color 160ms cubic-bezier(0.22,1,0.36,1), background 160ms cubic-bezier(0.22,1,0.36,1); } .ds-btn-secondary:hover { border-color: #AA653D; background: #F5F0E8; } .ds-btn-secondary:focus-visible { outline: 3px solid rgba(170,101,61,.2); outline-offset: 2px; }" - }, - { - "name": "搜索字段", - "kind": "input", - "refersTo": "field", - "description": "用于筛选角色、状态、场景和道具。", - "html": "", - "css": ".ds-field { display: grid; gap: 6px; color: #5E4E43; font: 600 11px/1.4 \"PingFang SC\", system-ui, sans-serif; } .ds-field input { width: 280px; border: 1px solid #DED5CA; border-radius: 8px; padding: 9px 11px; color: #272320; background: #FFFDF9; font: 400 13px/1.65 \"PingFang SC\", system-ui, sans-serif; outline: none; } .ds-field input:focus { border-color: #AA653D; box-shadow: 0 0 0 3px rgba(170,101,61,.14); }" - }, - { - "name": "选中筛选器", - "kind": "chip", - "refersTo": "chip-selected", - "description": "表示当前资产类型或筛选范围。", - "html": "", - "css": ".ds-chip-selected { border: 0; border-radius: 999px; padding: 4px 9px; color: #FFFDF9; background: #8E3F23; font: 600 11px/1.4 \"PingFang SC\", system-ui, sans-serif; cursor: pointer; } .ds-chip-selected:focus-visible { outline: 3px solid rgba(170,101,61,.2); outline-offset: 2px; }" - }, - { - "name": "工作流导航", - "kind": "nav", - "description": "显示固定生产阶段和当前进度。", - "html": "", - "css": ".ds-workflow { width: 220px; padding: 8px; background: #EBE4D9; font-family: \"PingFang SC\", system-ui, sans-serif; } .ds-stage { display: grid; width: 100%; gap: 3px; border: 0; border-radius: 8px; padding: 10px 12px; color: #5E4E43; background: transparent; text-align: left; cursor: pointer; } .ds-stage span { font-size: 13px; font-weight: 700; } .ds-stage small { color: #756E67; font-size: 11px; } .ds-stage:hover { background: rgba(255,253,249,.55); } .ds-stage.is-current { color: #272320; background: #FFFDF9; } .ds-stage.is-current span { color: #8E3F23; }" - }, - { - "name": "资产列表项", - "kind": "custom", - "description": "在左侧列表中显示资产缩略图、名称和审视状态。", - "html": "", - "css": ".ds-asset-row { display: grid; grid-template-columns: 40px 1fr auto; align-items: center; gap: 10px; width: 320px; border: 0; border-bottom: 1px solid #DED5CA; padding: 10px 12px; color: #272320; background: #FFFDF9; text-align: left; cursor: pointer; font-family: \"PingFang SC\", system-ui, sans-serif; } .ds-asset-row:hover { background: #F5F0E8; } .ds-thumb { width: 40px; height: 40px; border-radius: 6px; background: #EBE4D9; } .ds-asset-copy { display: grid; gap: 3px; } .ds-asset-copy strong { font-size: 13px; } .ds-asset-copy small { color: #756E67; font-size: 11px; } .ds-status { border-radius: 999px; padding: 3px 7px; color: #875D25; background: #F8EBCB; font-size: 10px; font-weight: 700; } .ds-asset-row:focus-visible { outline: 3px solid rgba(170,101,61,.2); outline-offset: -3px; }" - }, - { - "name": "初始化 Dialog", - "kind": "custom", - "refersTo": "dialog", - "description": "首次进入项目时承载视觉范式和角色构图选择。", - "html": "
项目初始化

建立视觉基线

选择视觉范式和默认角色构图后,工作台将继续解析剧本。
", - "css": ".ds-dialog { width: 680px; overflow: hidden; border-radius: 10px; color: #272320; background: #F5F0E8; box-shadow: 0 24px 64px rgba(39,35,32,.22); font-family: \"PingFang SC\", system-ui, sans-serif; } .ds-dialog header, .ds-dialog footer { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; background: #FFFDF9; } .ds-dialog header { border-bottom: 1px solid #DED5CA; } .ds-dialog footer { justify-content: flex-end; border-top: 1px solid #DED5CA; } .ds-dialog h2 { margin: 3px 0 0; font: 600 22px/1.2 \"Songti SC\", STSong, serif; } .ds-dialog small { color: #756E67; } .ds-dialog header > button { border: 0; color: #756E67; background: transparent; font-size: 22px; cursor: pointer; } .ds-dialog-body { min-height: 220px; padding: 24px; color: #5E4E43; } .ds-dialog-confirm { border: 0; border-radius: 8px; padding: 10px 16px; color: #FFFDF9; background: #8E3F23; font-weight: 700; cursor: pointer; } .ds-dialog-confirm:hover { background: #71311B; }" - } - ], - "narrative": { - "northStar": "安静的主美工作台", - "overview": "这套界面应像一张长期使用的数字工作桌:信息稳定地留在原位,图片、角色关系和生产状态比界面本身更醒目。暖灰和砖红保留现有创作气质,布局与控件则遵循生产工具的秩序,减少展示页式文案、虚构背景和重复容器。\n\n工作台采用连续的桌面产品结构。初始化 Dialog、工作流进度、资产列表和资产详情共享同一套导航、排版和状态语言。系统明确拒绝炫技的 AI 科幻控制台,也拒绝大量同质卡片、层层容器和重复摘要组成的 SaaS 仪表盘。", - "keyCharacteristics": [ - "暖灰工作区,砖红色只用于主要操作和当前选择。", - "项目标题可使用宋体,其余界面统一使用系统无衬线字体。", - "左侧工作流与资产列表保持紧凑,右侧详情为主要阅读和编辑区域。", - "大部分表面保持扁平,使用留白、分隔线和背景层建立层级。", - "前端展示正式状态并提交受控意图,不表现为自由实时协同编辑器。" - ], - "rules": [ - { - "name": "The One Action Color Rule", - "body": "砖红只表示主要操作、当前选择和需要注意的状态;不得把它用于标题装饰、大片背景或无意义图形。", - "section": "colors" - }, - { - "name": "The Status Pair Rule", - "body": "成功、警告和错误状态始终使用深色文字配同色浅底,不能只依赖文字颜色表达。", - "section": "colors" - }, - { - "name": "The One Serif Role Rule", - "body": "宋体只能用于项目名称或最高层创作标题。按钮、表单、导航、状态和数据禁止使用宋体。", - "section": "typography" - }, - { - "name": "The Chinese First Rule", - "body": "面向用户的界面文案以中文为主;英文只保留不可替代的模型名、格式名和短技术标识。", - "section": "typography" - }, - { - "name": "The Flat Workspace Rule", - "body": "工作区、导航、资产列表和详情面板在静止状态下不得使用投影;层级由背景色和一像素分隔线表达。", - "section": "elevation" - }, - { - "name": "The One Floating Layer Rule", - "body": "同一时刻最多有一个主要浮层。不得在 Dialog 内继续堆叠带阴影卡片。", - "section": "elevation" - } - ], - "dos": [ - "Do 使用暖灰工作区、清洁详情表面和一像素分隔线建立稳定的桌面工具结构。", - "Do 把图片、资产名称、审视状态和下一步操作放在视觉层级前面。", - "Do 使用左侧资产列表与右侧详情,让一个角色及其状态保持在同一上下文中。", - "Do 让初始化 Dialog 与主工作台共用颜色、字体、按钮和状态组件。", - "Do 让 Loading、折叠和预览组件解决明确的信息或等待问题。" - ], - "donts": [ - "Don't 制作炫技的 AI 科幻控制台、霓虹 HUD 或无功能意义的动态效果。", - "Don't 使用大量同质卡片、层层容器和重复摘要组成 SaaS 仪表盘。", - "Don't 使用横向宽度超过正常笔记本视口的大表格作为主要资产审视方式。", - "Don't 在普通容器上同时叠加一像素边框和宽而柔的装饰阴影。", - "Don't 在每个章节上方重复小号英文大写标签或编号眉题。", - "Don't 使用超过 10px 的普通容器圆角,或把所有按钮做成胶囊形。", - "Don't 让前端和 Agent 同时自由修改 canonical 项目状态。" - ] - } -} diff --git a/.impeccable/live/config.json b/.impeccable/live/config.json deleted file mode 100644 index fcf2de1..0000000 --- a/.impeccable/live/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "files": [ - "assets/setup-app/index.html", - "assets/review-app/index.html" - ], - "insertBefore": "", - "commentSyntax": "html", - "cspChecked": true -} diff --git a/CHANGELOG.md b/CHANGELOG.md index a1de513..7d603ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,237 @@ 后续接手此 skill 的窗口在修改前应先阅读本文件、`SKILL.md` 与相关数据契约。记录应说明行为变化、兼容性和验证方式,而不是逐行重复代码差异。 +## 当前行为速览 + +- 新项目默认 promptProfile v3:最终 prompt 等于 `promptBody`,无隐藏拼接;v1/v2 只在恢复存量项目时按条件加载兼容说明。 +- 新建 v3 项目同时启用 `textPolicyVersion: 1`;每个正文声明 none / decorative / readable。无标记的存量 v3 项目继续兼容旧链路,G03 词表暂时保留。 +- 五阶段为 setup → 故事资产圣经 → 创作方向与正式名册 → Prompt / 审查 → 增量生成 / 收割;圣经和总纲锁定后在原项目不可改。 +- 项目状态、审查、执行与供应商事实分层保存;canonical 只经官方脚本写入,执行确认与 checkpoint 由 hash 保护。已批准的正文被官方脚本改写时审查自动回 needs_review;v3 下 F02 逐字开头在总纲可确定取证时由 validate 与批量放行机械校验。 +- 四类资产使用各自 presentation 与 ratio;角色后续版本只引用本角色锁定的默认 artifact。 +- 可逆动作直接执行并复述;锁定、超出持久授权的扣费和其他不可逆动作需要确认。高后果创作项必须用成图后果句显式呈现。 +- 运行时按阶段读取 references;生产不变量、岗位准入、Prompt 契约、旧版本兼容和供应商边界各有唯一权威文件。 + +## 2026-07-20 — 单张全身立绘改为竖版 9:16,补全 Dialog 构图预览 + +- **新建项目规格**:补齐“特写 + 正侧背三视图”“标准正侧背三视图”“单张全身立绘”“上半身肖像”的白底构图预览;`single-full-body` 默认角色构图由 4:3 改为 9:16,提示词明确人物居中、占主要画面高度、从发梢到足部完整可见及均衡留白。manifest 升至 v5,确保初始化选择 hash 反映规格变更。 +- **Dialog 展示**:统一工作台与兼容 setup 页面均从 manifest 的 ratio 动态设置预览框比例,不再把竖图强制裁进 16:9。 +- **资源体积**:四张新增构图预览均压缩为预览级 JPEG;横图为 1280×720,肖像为 720×960,竖版全身为 720×1279,总体约 450KB,不把原始 PNG 带入 Skill 包。 +- **兼容性与验证**:仅影响未固化 setup 的新项目;既有项目不迁移、不重写。测试锁定 9:16 契约、同规格预览和新项目落盘传播。 + +## 2026-07-20 — 工作台前后端收敛:viewComputed 单一编译出口 + +- `/api/view-state` 新增 `viewComputed`:每资产附带后端 `compilePrompt()` 编译文本与解析后的呈现配置(含 setup-era 兜底文案)。viewer.js 删除三处后端逻辑拷贝(`fallbackPresentations` 逐字拷贝、客户端编译 `compiledPrompt`/`uniqueSegments`、presentation 兜底解析),改为直接消费 viewComputed——"工作台展示、批次、供应商提交同一物化文本"从"两份实现恰好相同"变为机制保证。 +- 新增 `tests/workspace-view-state.test.mjs`:真实起服校验 viewComputed 编译文本与后端逐字一致、缺省呈现走后端兜底、写入 405 限制与越权路径拒绝(补上 workspace_server 此前的零测试项)。 +- 兼容性:`/api/project-state` canonical 原样返回不变;viewer 与 server 同包发布,无独立部署路径。全量 78/78。 + +## 2026-07-20 — 独立架构审查回收:参考图链路修复、审查失效机械化与 F02 门禁 + +背景:C5 安装后的独立只读审查(含两个隔离子代理复核)发现执行后半程存在断链与零测试带;用户拍板 F02 进机械门禁、表达型角色板保留姿态放宽待成图验收、历史批次分次提交。 + +- **参考图 backendPath 断链修复(P1)**:`normalize_awb_image_results.mjs` 现从签名 URL 提取 COS 对象路径(`material/...`)落为 `backendPath`——此前全链路无任何写入方,而 `map_awb_image_batch.mjs` 硬性要求它,后续外观版本的真实生图必然在 map 阶段阻塞。reconcile 的幂等短路同步改为比较图片定位,重归一化可补齐 backendPath;完全无变化时不再空写状态文件。新增"锁定默认态 → 建批 → map"端到端测试封住该链路。 +- **审查失效机械化(P1,兑现 project-schema 既有承诺)**:merge patch 或 review decision 改写已 approved 资产的正文/文字策略且未显式给出新 status 时,审查自动回 needs_review,不静默保留旧批准;配合批量放行授权仍是零人工闭环。`generatedAgainst` 改为只随本次决定盖章,不再无条件覆盖全部资产。merge 白名单收紧:角色容器不再接受 promptBody/textPolicy/deltaPrompt;roster 重合并按 opId 幂等,不空转推进 revision。 +- **F02 CONTRACT 机械门禁(用户拍板)**:v3 项目总纲"媒介与画质"可确定性解析且当前资产类型恰有唯一媒介块时,`validate_project_state.mjs` 与 `approve_prompt_batch.mjs` 机械比对正文逐字开头,不一致即拒并回流岗位四;解析不确定(unsupported/多候选)一律放行,宁漏勿误伤。拒绝消费者是子代理,不占用户时间。 +- **授权与调度小修**:`record_execution_approval.mjs --auto` 校验 plan 与 state 的 projectId,持久授权不得跨项目使用;`--confirm-plan-hash` 失配拒绝补测试。plan_work_dag 的 chunk 完成检测改为边界感知匹配。apply_review_decisions 对陈旧 baseStateRevision 输出警告。 +- **总纲必填章节**:"世界语言与局部气质分流"(localTone 与差异矩阵的语义来源)加入 v3 锁定必填清单;record 的幂等检查提前到内容校验之前,存量锁定项目重复 record 不受新校验规则影响。 +- **展示同文**:工作台 `/api/view-state` 对显式 v1 项目同样投影过滤后的全局渲染语言,修复"工作台展示 ≠ 后端编译"的 v1 分叉。 +- **测试**:新增 `tests/execution-chain.test.mjs`(10 用例)覆盖此前的零测试带——checkpoint 状态机、planHash 失配、reconcile 防降回/跨批次保护、审查失效、changes_requested 不覆盖、readiness 后续版本链四个负向分支、F02 门禁、backendPath 端到端。全量 77/77。 +- **记录补欠**:`map_awb_image_batch.mjs` 与 `normalize_awb_image_results.mjs` 为 C4 执行窗口新增的确定性映射/归一化工具,此前缺 CHANGELOG 条目,本条补记;行为契约见 `references/provider-policy.md`。 +- **降噪**:localTone 边界措辞在 creative-charter / subagent-contracts 与权威表述对齐(补齐"资产事实"要素);SKILL.md 派生项目段落移出命令块之间;lib 中被转义的中文注释还原;record_story_bible 对缺失 sourceScript 给出明确错误。 +- **兼容性**:F02 门禁仅 v3 且取证确定才拦,v1/v2 与无总纲场景不受影响;审查失效只在"批准后被官方脚本改写"时触发;新必填章节只影响新锁定总纲。表达型角色板的姿态放宽按用户拍板保留,待下一批代表图按成图验收 rubric 验证。 + +## 2026-07-20 — C5 付费视觉矩阵回收:局部气质边界与成图验收 + +- **真实 A/B 证据**:隔离派生项目使用 GPT Image 2 普通低价 2K 生成 8 个 B 候选,8/8 成功、无重试、实际 16 点。最强正证据来自核心角色差异矩阵和信息覆盖式自然站姿;事件历史改为当前可见状态后未损失金瞳信息。 +- **localTone 防越权**:F02 原样 CONTRACT 不变;localTone 新增媒介、时代地域、世界类型和资产事实边界,不得借气氛发明新的文化母题、建筑类型或正在发生的事件。阴冷地宫滑向西式恶鬼祭坛被保留为短反例,但不增加词表或 readiness 门禁。 +- **预设上游修正**:`cg-xianxia` 种子移除“梦幻仙气、唯美古风”,保留国风仙侠三维游戏 CG 的媒介定位;manifest 升至 v4,仅影响新 setup,锁定项目不迁移。 +- **派生边界**:以新规则更换视觉预设或 F02 时,旧总纲只作回归证据;派生项目必须用自己的 setup 与故事事实重新确认总纲,不能把旧 F02 污染复制成新的 CONTRACT。 +- **成图 rubric**:核心角色增加“脱离配对、缩略图单看仍可读”的验收;角色戏剧功能不得固化为通用反派脸、低机位或配饰配方。代表图同时检查 localTone 越界、角色独立可读和姿态信息覆盖;视觉判断不进入自动 readiness。 +- **presentation**:表达型正背面角色板释放非对称重心与角色化姿态;严格正侧背布局继续保留明确生产角度。M08 的增强 CG 核只改善部分表面质量,未进入任何视觉预设,待跨角色复测。 +- **兼容性**:不改 schema、prompt 编译、审查门禁或存量项目;新规则只进入新模板、新 setup 与创作审查。验证见本条落地后的全量测试、`git diff --check` 和 skill quick validation。 + +## 2026-07-19 — v3.1 视觉质量与注意力预算第一批 + +- **F02 边界收窄,契约不放松**:总纲模板把“媒介与画质”限定为渲染范式、材质/体积/光照、人物防漂移钉子与跨资产一致性;项目题材、全局情绪、角色关系、善恶评价和局部场景气氛不得进入媒介核。岗位四仍须把对应 `维度 × 资产类型` 的 F02 整行逐字放在正文开头。 +- **局部气质与核心角色差异上移**:总纲新增“世界语言与局部气质分流”,只把当前资产的一句 `localTone` 摘入任务卡;只为高碰撞核心角色建立轻量差异矩阵,验收至少三项非颜色差异且不共享“脸型 + 发型 + 姿态”组合。调度任务卡契约同步携带相关矩阵行与 localTone,不新增 canonical schema 字段。 +- **故事圣经与 Prompt 减负**:剧情梗概默认目标不超过 300 个汉字,复杂长剧目标不超过 600,只保留影响资产判断的转折;角色/场景/道具改为短事实条目。Prompt Agent 新增“像素租金”、分资产软信息预算和角色组对审;它们只用于创作审查,不是字符或气质词表门禁,四步写法仍是 RECIPE。 +- **4:3 角色板释放姿态**:`closeup-front-back` 保留占主要视觉面积的面部近景、正面全身和背面/三分之四背面信息;移除统一“平静、平视端庄、排版紧密”。体态事实优先,允许不遮挡轮廓和服装结构的非对称、自然或角色化姿态,不强制直立、放松或端庄站姿。ratio、layout id 与 requirements 不变;存量项目不迁移、不重写。 +- **新增只读 Prompt 审计**:`audit_prompt_bodies.mjs` 从总纲取证 F02,输出关系/叙事/逐视图重复、可变正文软预算、角色词汇碰撞和 `textPolicy` 分布;证据不足时返回 `unsupported`。全部结果明确是 observation,不参与 readiness、不证明视觉质量、绝不写项目。 +- **独立前向审查**:布局盲审发现“足够大”与“放松站姿”仍可能欠约束/过约束,已改为“占主要视觉面积 + 体态事实优先”。另一个隔离 Agent 在旧项目上自然拉开苏念/苏雅五项非颜色差异,同时仍被旧 F02 迫使地宫携带“梦幻唯美”,证明新边界须在新总纲或派生项目生效,不能改写锁定项目。 +- **验证与兼容**:47/47 全量测试、Node 语法、`git diff --check` 与 skill-creator `quick_validate.py` 通过。两个真实项目只读审计成功:23/23 与 57/57 个正文均可精确取证 F02;《你也配修仙》观测到 6 个关系词资产、1 个叙事词资产、4 个逐视图重复资产;《三年之约》的碰撞启发式标出苏念/苏雅。未建批、未调用 AWB、未扣费。 + +## 2026-07-19 — 强 Agent 第二阶段:rubric、结构化文字策略与开放调度 + +- **P1 Prompt 自主性**:四步写法从硬 SOP 降为推荐 `RECIPE`,正文改按事实忠实、风格一致、视觉可执行、信息经济、规格完整和锚点价值六项 rubric 审查。F02“对应媒介块原样抄写”继续是不可协商 `CONTRACT`;主美式完整示例保留。下一次真实项目需统计关系词、叙事词、逐视图重复是否回潮。 +- **P2 第一步完成,第二步明确未做**:新建 v3 项目记录 `promptProfile.textPolicyVersion: 1`;每个有正文的资产声明 `textPolicy.mode = none / decorative / readable`,readable 还必须声明语言和逐条原文。readiness、validate、批量放行、DAG 完整性、missing-only 分片、sidecar merge、review patch 和 prompt sourceHash 已接入。无标记的存量 v3 继续兼容;G03 可读文字词表仍并行生效,必须完成至少一轮真实项目实测后才能在后续独立改动中评估删除。 +- **P3 取消鞋靴机械排除**:删除 presentation exclusions 的传播、预设词表和 readiness 拒绝;“局部构图只描述可见范围”保留为语义 rubric,不再用鞋、靴、裙摆词表猜测越界。 +- **P4 调度开放且可观测**:shard 继续作为硬审计单位,bundle 改为 planner 建议;主代理可按复杂度和槽位调整。保留“禁止按资产类型三分”负面清单;planner 输出建议并发和预期波数,收尾必须回报实际波数、总耗时和偏差。 +- **P5 确认收敛**:人物群体呈现、画面内文字语言可并入一个总纲确认包;两项仍须分别用“这意味着成图……”一类后果句醒目呈现,不要求逐条问答,不得退化为笼统“请确认总纲”。扣费、锁定和 approval hash 审计不变。 +- **验证**:35/35 测试通过;新增用例证明结构化 textPolicy 生效、旧 G03 仍生效、validate 会拒绝缺策略资产、missing-only 会追回缺策略资产;Node 语法检查通过。 + +## 2026-07-19 — 面向强 Agent 的第一阶段精简(行为保持) + +- **入口重写**:`SKILL.md` 从补丁式全量 SOP 改为“入口判断 + 统一授权模型 + 五阶段完成条件 + 按需加载索引 + 上下文预算”。仍保留当前锁定、确认、调度、审查与恢复行为。 +- **单一事实源**:新增 `references/invariants.md` 承载生产不变量,新增 `references/legacy-profiles.md` 隔离 v1/v2 兼容;重写 creative-charter、prompt-authoring、subagent-contracts、project-schema、execution-modes、provider-policy。删除已过时且与当前差量白名单冲突的 `image-consistency.md`,其有效内容已归入 invariants / schema / prompt 契约。 +- **模板降噪**:重写两个 bootstrap 内嵌模板,保留全部 required headings、候选编号、身份事实、媒介双块、人物群体呈现、文字语言和辨识度语义;模板只说明产物字段,详细原则回到权威 reference。 +- **校验合并但不松门禁**:readiness、validate、批量放行共享 `promptBodyFindings()`;角色专属措辞和带可读文字判断统一到后端 lib。viewer 的旧 render 过滤改由 `/api/view-state` 使用后端唯一兼容解析器提供,`/api/project-state` 仍返回原始 canonical 数据。 +- **体积**:盘点范围总字符 40,890 → 27,165,下降 33.6%;其中运行文档 32,047 → 20,352,下降 36.5%。 +- **兼容性**:v1/v2/v3 编译、当前全部词表/正则门禁、名册对账、授权、checkpoint、viewer 展示与真实项目数据不变。用户已批准的 rubric、textPolicy、鞋靴排除门禁取消、调度开放和确认收敛留给独立第二阶段,不在本批“边建边拆”。 +- **验证**:`node --check` 覆盖改动脚本;32/32 测试通过;工作台 `/api/view-state`、`/api/project-state`、首页均返回 200,旧项目只读投影正确过滤污染 render;skill-creator `quick_validate.py` 通过。 + +## 2026-07-18 — 呈现排除项:局部构图的"不能有什么"清单(用户提问暴露的缺口) + +- 背景:需求规格(requirements)只是"必须有什么"的存在性检查——选"上半身肖像"后,正文写整套服装(皮靴/裙摆)照样通过校验,而画外内容会诱导生图模型拉远构图破坏版式;B4 状态图继承构图后该风险被放大。 +- 呈现配置新增可选 `exclusions`(与 requirements 同构的 label/match 清单);`lib/project.mjs` 新增 `foundPresentationExclusions`,readiness 在 v2/v3 正文命中排除项时拒绝(理由回流岗位四裁剪重写)。`apply_setup_decisions.mjs` 把 layout 的 exclusions 传递给 characterDefault 与派生的 characterState。首个应用:`upper-body` 上半身肖像排除 `鞋|靴|足部|脚踝|裤脚|裙摆`(保守词表,宁漏勿误伤——"长裙/连衣裙"等上下连体衣物不拦)。 +- prompt-authoring 新增"可见范围裁剪"规则与自检项:只写所选呈现范围内可见的部分,被裁剪的服装事实留给全身构图资产或镜头级提示词,圣经记录不丢失。 +- 验证:32/32 测试(新增排除项用例:写鞋靴拒绝、裁剪后放行)。兼容性:exclusions 为可选字段,存量项目呈现配置无此字段即无行为变化。 + +## 2026-07-18 — 体验松绑与调度解耦:持久授权、打包派发、状态构图跟随(第四轮实测 B1-B6+B8) + +依据交接稿第九节拍板(除 B7 API 直调外全做)。背景:长短双剧本实测——A1 门禁被执行得过死(用户明确说了选择仍被要求去页面点选+反复确认);159 资产 76 分片一片一派跑 26 波耗时 51 分钟;角色状态图不跟随所选构图;CG 角色 Q 版漂移(缺头身比钉子);主代理即兴写 approve-self-checked-prompts.mjs 绕过审查闸门。 + +- **B2 初始化授权规则改写**:setup 在总纲锁定前可随时重选,不是不可逆动作——用户在对话明确说出选择即为授权,主代理直接代写并在同一条回复复述预设名/定位/种子原文/构图,不再前置确认、不要求去页面点选;未明确表达时仍禁止猜测匹配与参考历史偏好;描述与预设不完全对应时列候选让用户挑。 +- **B3 构图库补主美标准版式**:新增 `closeup-turnaround`"特写 + 正侧背三视图"(16:9,左大特写+右正侧背三视图——主美文档标准版式,此前库中只能"特写+正背面"或"纯三视图"二选一)。 +- **B4 角色状态图跟随所选构图**:`apply_setup_decisions.mjs` 为全新 setup 派生 characterState(继承所选 layout 的 prompt/ratio/requirements + "当前外观版本"要素),不再固定 16:9 单图;顺带消除状态图单/多视图混杂(岗位四按需求规格写作后视图数一致)。存量补齐(presentationOnlyUpgrade)与豁免(grandfathered)路径保留旧 characterState,不影响在途项目。 +- **B5 两类钉子**:prompt-authoring 新增硬规则"角色资产默认空手"(禁手持包/电脑/话筒等,职业用服装气质表达,佩挂按圣经装备体系事实写佩挂不写手持);"头身比例"入总纲角色块钉子清单与正文主体句要素(写实七至八头身/按定位声明夸张头身比——防 Q 版/幼态漂移,实测两三个 CG 角色因此漂移)。 +- **B6 调度解耦(分片=审计单位,包=派发单位)**:`plan_prompt_shards.mjs` 新增 bundles 输出——普通分片按资产数聚合(角色 ≤6、场景/道具 ≤10),≥3 外观角色独占一包;SKILL/契约改为"每包一个子代理、完成一包立即领取下一包(常驻消费)",任务卡必须自包含(名册条目+圣经事实摘录+媒介块+构图规格+文字策略,不回读剧本/圣经/项目状态全文)。实测长剧本项目:76 片 → 29 包,3 worker 理论 26 波 → 约 10 波。 +- **B1 小额扣费免确认(项目级持久授权)**:新增 `record_standing_authorizations.mjs`(`--auto-approve-below <积分>|off`,用户明确授权后运行,写入 `config.authorizations`,可撤销);`record_execution_approval.mjs` 新增 `--auto --state `——估价 ≤ 阈值时自动确认(approvedBy 记 standing-authorization),快照/估价/哈希照常播报留档;超阈值或未授权硬拒回人工。默认关闭,skill 不设默认阈值。 +- **B8 批量放行官方化 + 禁野生脚本**:新增 `approve_prompt_batch.mjs`——需 `--batch-prompt-approval on` 持久授权;对 v2/v3 正文做质量自检(呈现要素/漂移或文字语言/比例/中文),通过者批量写入 review-decisions approved 决定(仍走 apply 统一应用,保留全部审查链路语义);**带可读文字的资产默认留人审**(`--include-readable-text` 显式放开),changes_requested 永不覆盖。SKILL 上下文纪律新增:禁止主代理即兴编写脚本写入项目目录或绕过审查/扣费闸门,官方脚本未覆盖的需求报告用户而不是自建通道。 +- 验证:31/31 测试(新增打包规则、批量放行集成、免确认阈值集成 3 个用例;presentation-scope 的 characterState 断言按 B4 新契约更新并注明日期)。长剧本项目只读冒烟:29 包。兼容性:B4 仅全新 setup 生效;B1/B8 授权默认关闭;manifest 保持版本 3(构图为纯增项)。 +- 暂缓:B7 API 直调 worker(B6 落地后实测仍慢再议;将作为引擎化第一块砖)。 + +## 2026-07-18 — 主美风格词体系落地:种子重写与定位标签、媒介块分资产类型、正文写作规范(第三轮实测 A1-A5) + +依据《comic-assets-第二轮实测问题交接-2026-07-19.md》第八节拍板(A1-A5 做,A6 参考链暂缓,A7 不做)。背景:《你也配修仙》v3 首跑暴露——主代理未经确认代选预设导致"二次元"种子污染总纲;媒介句无防漂移钉子致 5 张成图 2 张跨次元漂移(游戏立绘/写实照片);正文混入叙事概念、人物关系、逐视图重复与比例错写。主美《美术中台流程 20260608》文档(飞书)证实其风格词的稳定性来自"防漂移钉子"(无毛孔/无油光/非真人感/哑光分束发丝/夸张五官比例…)与短语铺陈格式。 + +- **A1 初始化代选防线**:SKILL.md 硬规则——主代理不得代写/代提交 setup-decisions,不得把用户文字描述自行匹配预设或参考其他项目历史偏好代选;用户明确要求代选时须先复述"预设名+定位+种子原文"获同意。`apply_setup_decisions.mjs` 应用后输出预设名(含定位)与种子原文,要求主代理转述用户核对。 +- **A2 预设种子按主美文档重写(manifest version 2→3)**:11 个种子以主美验证过的风格词为底稿重写——保留媒介词+防漂移钉子,剥离主体词(贵公子/美女等)与版式块;**有意保留人物钉子(面部/五官/发丝/服装/毛孔),推翻批次 A"种子不含角色措辞"的决定**——v3 架构下钉子经总纲"××·角色"块只进入角色正文,不再走公共段拼接,污染路径已消除。工作室/画家品牌词维持中性化(皮克斯/新海诚不进种子),工具词保留(UE5/Blender)。cg-xianxia 去掉"二次元"字样改以"国风游戏 CG 宣传图质感"承载同一定位。每个预设新增 `positioning` 定位标签(游戏立绘向/超写实真人向/国漫 CG 向…),贯通 Dialog 详情、`config.visualPreset`、总纲"已选视觉范式"注入,防止"名字最像就代选"的媒介预期错配。 +- **A3 媒介与画质分资产类型**:总纲 v3 模板"媒介与画质"改为按 维度×资产类型 给块("主维度·角色"可含人物钉子;"主维度·场景与道具"不含人物专属词),并禁止叙事概念与剧情结构词("反套路/师徒故事"——生图模型无法执行)。`record_art_direction_brief` v3 校验改为**按行分块作用**:角色块豁免"角色局部细节"版式项与人物措辞检查;场景道具块及未标注行维持拦截(角色/人物/肤质/发丝/毛孔)。 +- **A4 正文写作规范(prompt-authoring v3 重写)**:写作格式固化为主美式四步短语铺陈流——①原样抄本维度本类型媒介块;②主体身份一短句+可画外观短语;③服装识别物一次性铺陈;④版式收尾模板(语义覆盖需求规格+文字策略默认"不带文字"、可读文字逐个点名、禁全称句)。硬规则"只写画得出来的东西":头衔/人物关系/剧情来历/设计意图字面全部禁止(师尊/宿主/之妹/"视觉层级服从功能角色"),只允许转译为视觉;构图只说一遍,禁逐视图重复服装结构。新增校验 `findMismatchedRatioTerms`:v3 正文中的比例数字与呈现配置 ratio 不一致即拒绝(readiness + validate,一致或省略均可)。 +- **A5 宪法负向词边界澄清**:creative-charter 与 prompt-authoring 明确——禁止的是负向提示词参数通道、排除词清单与"避免…"补丁;"无毛孔/无油光/非真人感/不带文字/不要露沟"等内联否定描述词是防漂移钉子,合法且常常必要,agent 不得自我审查删除。 +- 验证:28/28 测试通过(新增 3:比例一致性校验、record 媒介块分块校验、预设种子卫生检查 `tests/style-presets.test.mjs`);冒烟——apply 输出种子复述、模板含双块指引与定位行。兼容性:种子与模板仅新项目生效;v1/v2 存量项目路径不变(v2 防漂移词表、v1 五段拼接原样);positioning 为可选字段,旧 manifest 项目不受影响。 +- 暂缓/不做(用户拍板):A6 跨角色风格参考链(先实测钉子效果,漂移仍超预期再做);A7 分片对账提示(Codex 并发设置调整后观察)。 + +## 2026-07-18 — promptProfile v3(整段正文,推翻锚定式拼接)、画面内文字语言与人物群体呈现默认锚(第二轮实测 P5/P8/P9) + +依据《comic-assets-第二轮实测问题交接-2026-07-19.md》第五、六节三轮拍板结论。**这是锚定式设计的第三轮修订:用户确认 Q 版形象等多媒介剧本是业务常态,"全局唯一逐字拼接段"假设不成立**——维度是资产事实(与性别/族裔同机制),由岗位四写进正文,不做系统机制轴。 + +- **promptProfile v3(新项目默认)**:无 styleAnchor,最终提示词 = 岗位四整段正文(`promptBody`),逐字物化、零拼接、零隐藏追加。总纲模板改版:`公共风格锚点`章节替换为`媒介与画质`(每个媒介维度一句,岗位四把本维度句子原样落进正文开头;允许感性的题材气质/调性,**禁止具体色名、材质枚举**——阵营色彩体系下放到分类型美术语言,修复真实项目"锚点写死色域、全资产挤在窄色域、主配角拉不开")。record 按"媒介与画质"标题识别 v3,校验中文/版式词/角色措辞(与 v2 锚点同词表),写入 `promptProfile: { version: 3 }`。**v3 下防漂移词表撤销**(正文必须自带媒介词);v2(锚定式)与 v1 存量项目全链路兼容不变,真实 v2 项目 validate 回归通过。 +- **辨识度层级(从轻)**:总纲模板"分类型美术语言·角色"新增指引——辨识度是显式决策、手段服从剧本人设:英雄型主角用独占轮廓/专属色/贯穿符号;**普通人代入型主角(废柴逆袭等)保持大众形象,用一两个克制的贯穿特征承载辨识并在总纲写明**(同日修订:初版"必须拥有独占特征"措辞会误导美术总监给代入型主角强加英雄式设计,用户指出后改为按人设分流);功能角色明确让位。prompt-authoring 自检同步"按声明的辨识手段核对,不得自行加戏"。不加圣经字段、不加必填章节、不加校验(用户拍板,待批量测试后再评估是否需要重的版本)。 +- **画面内文字语言(P8,v3 硬校验)**:总纲 v3 新增必填章节"画面内文字语言"(未明确时按世界观决策;默认策略:证据类道具与场景标识写明语言+内容原文,装饰类纹样化不可读);圣经模板世界观章节新增"世界文字语言"事实行;prompt-authoring 新增执行规则;readiness/validate 在 v3 下硬拒"要求可读文字(铭文/招牌/标签/字样/刻字/题字/信笺/菜单/字迹)但未指定语言或声明不可读"的正文——**拒绝理由回流岗位四自动重写,不卡用户**。词表故意保守(宁漏勿误伤),漏网由一致性检查岗与对话审查兜底。v2 存量项目不受此校验影响。 +- **人物群体呈现默认锚改写(P9)**:创作宪法与总纲模板——"未明确"角色默认按**剧本文化语境的主流面孔**呈现(西式命名+西式世界观→欧美面貌为主);除非剧本明确写了多元设定,不得以"国际化都市/开放港城"语境推演为由做多族裔均衡分布(真实项目实锤:美术总监的多元化默认与用户北美市场商业预期相反)。原有红线保留:不推断个别角色、不把族裔编码为善恶/权力等级。SKILL.md 新增**高后果章节确认协议**:总纲确认前必须把"人物群体呈现""画面内文字语言"单独摘出、各用一句后果化语言复述,等用户逐条回应。"目标发行市场"初始化输入按用户决定后置,待多轮测试再评估。 +- **外观版本定义扩展**:圣经模板与 subagent-contracts 闸门二——贯穿复现的媒介/画风形态变化(Q 版形象、异维度固定形态)构成独立外观版本(注明所属维度),走候选编号与对账;单场一闪而过的 Q 版演出仍降级为镜头级。 +- 验证:新增 `tests/prompt-body-v3.test.mjs`(7 用例:v3 编译逐字、媒介词通过、需求规格拒绝、画面文字三态、词表不误伤、缺正文、record v3 识别与缺章节拒绝)。全套 25/25 通过(`node --test tests/presentation-scope.test.mjs tests/anchored-prompt-v2.test.mjs tests/prompt-shards.test.mjs tests/prompt-body-v3.test.mjs`);v3 模板生成冒烟(三个新章节齐全);真实 v2 项目 validate 只读回归通过。 +- 兼容性:仅新项目走 v3(record 按模板标题分流);v1/v2 行为不变;viewer 编译展示同步 v3 分支。 + +## 2026-07-18 — 岗位四分片清单、大产物落盘总则、lj-awb 接口速查与等待页文档内嵌(第二轮实测 P4/P6/P7/P2) + +- **岗位四并发派发脚本化**(P4 根因:契约建议式措辞对主代理无强制力,Codex 实跑按资产类型只开 3 个子代理串行扛 80 资产)。新增 `scripts/plan_prompt_shards.mjs`:从项目状态确定性生成分片清单(每个角色一个分片含其全部外观版本;场景、道具按 ≤4 聚类;`--missing-only` 只列缺正文资产),输出 `workflow/prompt-shards.json`。SKILL.md 核心 DAG 与 subagent-contracts 岗位四条目改为规定式:按分片清单派发、并发 = min(分片数, 槽位)、按 shardId 对账、显式禁止按类型三分。新增 `tests/prompt-shards.test.mjs`(3 用例:分片规则、确定性、missing-only)。真实项目冒烟:80 资产 → 38 分片。 +- **大产物落盘总则**(P6 根因:大 JSON 走终端 stdout 被 Codex 摘要截断成半截文件)。SKILL.md 主代理上下文纪律与 subagent-contracts 新增:结构化产物必须用文件写入工具整体写入项目内路径,对话/终端只传路径+条目数+摘要,禁止 echo/heredoc 拼接大文件。`merge_agent_patches.mjs` 与 `apply_review_decisions.mjs` 在 JSON 解析失败时输出定向修复指引(提示截断成因与整体重写)。 +- **lj-awb 接口速查内置**(P7 根因:执行前置全串行且反复整篇阅读 lj-awb 文档,9-10 分钟黑箱)。新增 `references/lj-awb-quickref.md`(浓缩自 lj-awb 0.5.5:命令链、JSONL 契约、硬规则;**模型/价格等易变数据不内置**,保持动态查询);速查页记录适配版本号,preflight 版本不一致时才回读完整文档并更新。SKILL.md 执行段改写:接口知识以速查页为准;preflight 与渠道查询在岗位四写正文期间**前移并行**;查询结果缓存 `workflow/awb-capabilities.json`(24h + 版本双条件);估价与总积分永远全量重算展示;阶段进度逐步向用户播报。 +- **等待页文档内嵌**(P2)。等待页"查看圣经/创作方向"由 `target="_blank"` 链接改为页签按钮 + 内嵌 iframe(复用 `doc.html` 渲染器与自动更新,新增 `?embed=1` 隐藏顶栏模式),保留"在新窗口打开"次级链接;链接内容未变时不重建 DOM,轮询不打断阅读;离开等待态自动收起并清空 iframe。进度弹层链接行为不变。 +- 兼容性:无 schema 与编译行为变化;分片脚本为新增入口,旧流程命令不受影响。验证:18/18 测试(新增 3);真实项目只读冒烟——工作台/viewer.js/doc.html?embed=1 均 200,新逻辑已服务。 + +## 2026-07-18 — 工作台初始化选择轮询保护与提示词进度展示(第二轮实测 P1/P3) + +- 修复 `viewer.js` 初始化选择被轮询重置:`loadSetup()` 此前每次轮询(前台 2 秒)无条件以 `decisions ?? 默认值` 覆盖本地选择,用户未提交时页面选中状态被重置回默认,最终提交的是默认值(真实项目实锤,用户被迫重建项目)。现在只有已提交的 decisions 才回写本地状态,未提交时保留用户当前选择;setup 面板仅在首次加载或值变化时重绘,轮询期间不再打断交互。 +- 详情面板:锚定式项目(promptProfile v2+)`promptBody` 尚未编写时,不再把公共风格锚点以"最终生图提示词"标题展示(用户曾误认锚点为最终提示词)。改为"提示词进度"区块:明确标注锚点身份 + "正文尚未编写"状态,并隐藏复制按钮。正文存在时行为不变;v1 项目不受影响。 +- 兼容性:纯前端改动,无 schema、脚本或编译行为变化。验证:`node --check` + 既有 15 测试通过;建议手工冒烟——初始化页更改选择后等待 ≥3 个轮询周期确认不被重置,提交后 `setup-decisions.json` 与所选一致。 + +## 2026-07-18 — 海外剧本适配:基础身份事实、人物群体呈现与专有名词豁免 + +背景:用户审查发现四个欠考虑项——海外剧本(东南亚/欧美/拉美)的族裔呈现无执行抓手(宪法"不推断族裔"在图像层失效:中文提示词+不写人种=生图模型默认东亚面孔的沉默偏置)、性别/年龄无任何结构化约束、`isPrimarilyChinese` 会误杀拉丁人名密集的合法正文、"集-场"编号假设未覆盖 Scene/INT./EXT. 格式。 + +- **采集层**:圣经模板角色档案新增"基础身份事实"必填行(性别/年龄段/族裔或地域出身;只抄剧本明确写的,未写显式填"未明确",不得从名字或剧本语言推断)。`record_story_bible.mjs` 新增软校验:具名角色缺"性别"字样时逐个警告。模板头部新增非集-场剧本的编号映射规则与任意语言剧本声明。 +- **决策层**:美术总纲 v2 模板新增必填章节"人物群体呈现":剧本明确的照实沿用;"未明确"角色由 AI 美术总监按剧本地域与文化语境**自行决策**并写一行理由,随总纲整体确认(按用户要求弱化单独确认卡点,以美术总监指导为主,面向自动化流程)。`record_art_direction_brief.mjs` requiredHeadingsV2 同步;creative-charter 族裔条款改写:"项目级决策不允许留空——留空等于交给生图模型的默认值"。 +- **执行层**:prompt-authoring 岗位四契约新增:正文必须体现已确认的性别、年龄段、族裔面貌;圣经"未明确"且总纲无决策时不得自行发明,回报主代理。subagent-contracts 岗位一职责同步。 +- **`isPrimarilyChinese` 重写**:拉丁文从按字母计数改为按词计数,首字母大写的词(含 À-Þ 变音)按专有名词豁免。效果:含 María Fernández、Johnson 的中文正文通过;纯英文与英文为主的混杂描述仍被拒绝。影响所有中文占比校验点(readiness/validate/record),对存量中文项目无行为变化。 +- 验证:15/15 测试通过(新增 2 用例:专有名词豁免 + 缺"人物群体呈现"章节拒绝锁定)。兼容性:v2 新必填章节只影响新项目(v2 于同日发布,无存量 v2 草稿);v1 路径不变。 + +## 2026-07-18 — 四岗位架构重构:外观版本、并行流程、锚定式提示词与名册对账 + +依据《comic-assets-架构问题与解决方案-交叉验证交接.md》第十一节已确认结论,按批次 A→C→B 实施。 + +**批次 A(文案与规则层)** +- 重写 7 句带角色措辞的视觉范式种子(style-presets.json,manifest version→2):去掉角色/肤质/发丝/服饰等主体专属词,只留媒介与画质。修复根因之一:种子进公共段后污染场景与道具提示词。 +- 标点修复:`joinPromptSegments()`(去段尾句号再以"。"连接、末尾补一个)应用于 `compilePrompt` 与前端 `compiledPrompt`;`record_art_direction_brief` 拼接同步修复。消灭"。。"。兼容性注意:会改变既有项目重新编译时的 promptHash——对已锁定项目按"prompt 变化旧确认失效"原则处理,测试项目不受影响。 +- 故事资产圣经模板重写(bootstrap_story_bible):岗位一改称"剧本统筹与资产研究员";角色"状态"改为"外观版本"(定义:需独立参考图才能让多镜头稳定复现的固定视觉形态;服装/装备体系变化与永久身体变化构成新版本;表情/姿势/临时受伤/血迹/光效不记录——**推翻此前"状态全量记录"设计,用户拍板,排除项不留痕**);新增入册条件(有名字/台词/功能/关系任一命中即入册,与场次数无关,宁多勿漏)、类别代表与固定组合拆分规则、候选编号(C/L/P-XX);"别名、重复项和待确认项"章节改为"确定性处理结果"(五选一处置+一行理由,不再悬置待人工)。record_story_bible 校验同步(新标题+旧标题兼容别名,软校验措辞改外观版本)。 +- subagent-contracts 重写:四岗位边界(岗位一任务卡隔离:只给剧本+提取规则;岗位三不读美术总纲不写提示词;岗位四为主要并发阶段);"资产化准入"改为两层闸门——闸门一(入册,定性条件)永不由场次数决定角色存在性;闸门二(额外造型出图:≥2 场,或单场但贯穿主要段落按对话轮次/动作段计,或用户点名)。creative-charter 的不确定项条款改为确定性处置+留痕。prompt-authoring 差量白名单:只允许服装、装备体系、永久身体变化。 +- 验证:13/13 测试通过;临时项目端到端冒烟——新模板生成、新标题锁定、场景提示词开头为媒介级描述(无角色泄漏)、全链无"。。"。 + +**批次 C(流程层)** +- 圣经锁定后岗位二(美术总监)与岗位三(名册编制)并行:SKILL.md 正文与核心 DAG 改写;已核实 merge_agent_patches 本无美术总纲闸门,实测美术总纲未锁定时名册可合并。岗位四仍须等创作方向锁定。 + +**批次 B(结构层,锚定式合成方案,仅新项目生效)** +- `promptProfile` v2:唯一字段 `styleAnchor`(≤240 字);美术总纲模板 v2 以"公共风格锚点"+"分类型美术语言"取代"公共视觉语言"+"全局渲染语言";record 识别新章节走 v2(校验中文/无版式词/无角色措辞/长度),**不再拼接种子原文**(美术总监消化进锚点);旧模板走 v1 兼容路径不变。 +- 资产新增 `promptBody`:最终提示词 = 锚点 ⊕ 岗位四整段正文,逐字物化、无隐藏追加。呈现模板降级为需求规格(layouts 与分域默认配置新增 `requirements`,"站立"移出必备要素——修复轮椅角色与构图模板的结构性冲突);readiness 逐要素语义校验 + 防风格漂移词表(锚点级风格词出现在正文即拒绝)。merge update 白名单、审查 patch、plan_work_dag 提示词完整性、validate(v2 下 identityPrompt/deltaPrompt 退为可空输入材料)、viewer 编译展示全部同步 v2 分支。 +- 名册对账:patch 顶层可选 `roster`(candidateId/disposition/reason),merge 与圣经候选编号做 100% 对账(缺一多一均拒绝),通过后写入 `workflow.roster`;工作台新增 `/roster.html` 名册对照视图(统计+表格,自动更新),进度弹层在名册存在时给入口。 +- 新增 `tests/anchored-prompt-v2.test.mjs`(7 用例):锚点⊕正文逐字编译、轮椅坐姿正文通过需求规格(回归用例)、缺要素/风格漂移/缺正文拒绝 ready、名册对账失败与成功、record v2 写入与角色措辞拒绝。全部通过;旧套件 6/6 不受影响。 +- 已知边界:v1 存量项目行为不变(除标点规范化);圣经无候选编号时名册对账自动跳过;本轮未实现"呈现规格变化自动标记正文 stale"的增量工具,靠 sourceHash 失效兜底。 + +## 2026-07-17 — 工作台文档渲染与最终提示词展示(《你也配修仙》实测反馈) + +- 新增 `assets/viewer-app/doc.html`:项目内 markdown 文档的只读渲染视图(自带轻量渲染器,全文本先转义再插入受控标签,不执行文档内 HTML;前台 4 秒轮询自动更新)。故事资产圣经与项目创作方向在**草稿阶段**即可从工作台等待页预览("预览圣经草稿 / 预览创作方向草稿"链接),锁定后从进度弹层与等待页打开渲染版;确认与锁定仍全部在 Agent 对话中完成,服务端未新增任何写入口,`/project/` 的 `.md` 仍按 text/plain 提供原文。背景:用户实测反馈圣经简报只能看 md 源码,审阅体验断裂。 +- 详情检查器"最终生图提示词"改为只展示最终拼接文本(原五段分层展示删除;`compiledPrompt` 前端拼接逻辑未动,仍与后端 `compilePrompt()` 顺序、去重、"。"连接完全一致),保留一键复制。按来源分段的解释移到 Agent 对话按需进行,SKILL.md 审查章节措辞同步更新。背景:用户反馈右侧分层过多,只需要看发给模型的最终文本。 +- 兼容性:无 schema、状态、批次或脚本行为变化,纯前端与文档改动;旧项目直接生效。验证:`node --test tests/presentation-scope.test.mjs` 全部通过;在真实项目上启动 workspace_server 冒烟验证 doc.html 渲染、草稿/锁定两态链接与最终提示词展示。 + +## 2026-07-17 — 资产呈现作用域修复(第一阶段) + +- schemaVersion 继续保持 3,在配置内新增可判别的分域版本:`promptProfile.version: 1` 使用 `commonVisualLanguage` / `globalRenderLanguage`;`assetPresentation.version: 1` 明确拆分 `characterDefault`、`characterState`、`location`、`prop`。四类呈现各自保存 prompt 与 ratio,`config.image` 对新项目只承担质量等跨类型参数。 +- `compilePrompt()` 和 `imageSettingsForRecord()` 现在先解析资产类型,再只拼接该类型的呈现 prompt、只读取该类型的 ratio。角色默认设定板仍只作用于 `sequence: 0`;角色状态、场景和道具分别使用单一状态图、宽幅环境图和单一道具图默认配置。批次 item 新增 `presentation: { scope, id }`,便于审计最终比例来源。 +- 创作方向模板把“默认渲染规格”改为“全局渲染语言”;`record_art_direction_brief.mjs` 会拒绝把画幅比例、白底/影棚背景、胸像/半身像、多视图、正背面、站姿、角色局部细节和左右排版写入全局字段。尚未锁定的旧模板标题仍可读取,但内容按新边界校验。 +- `validate_project_state.mjs` 对新分域模型硬校验四类配置的 id / prompt / ratio、逐资产呈现 scope 与最终 ratio,并拒绝全局渲染语言中的专属交付版式。统一工作台的分段展示同步使用相同作用域和旧 render 过滤规则,避免审查文本与正式批次再次分叉。 +- 旧项目保持 v3 可读:历史 `style` / `render` 通过兼容解析器读取;污染的 render 分句只在编译/展示时过滤,不改写 canonical 状态;已有 `characterDefault` 的 setup-era 项目缺少角色状态、场景、道具配置时使用内置分域默认值,更早且完全没有呈现配置的项目仍保留历史比例兜底。重新运行相同 `apply_setup_decisions.mjs` 可选择性持久化四类配置,不改已锁定创作方向、成功 artifact 或锚点;新的 promptHash / generationKey 仍须重新审查和执行确认。 +- 新增 `tests/fixtures/presentation-scopes/project-state.json` 与 `tests/presentation-scope.test.mjs`。自动验证四类资产最终 prompt 与 ratio 不跨域、旧污染 render 只读过滤、validator 反例、`build_image_batch.mjs` 写出的四类 presentation 来源、创作方向录入拒绝专属版式,以及新项目初始化落盘。验证命令:`node --test tests/presentation-scope.test.mjs`(6/6 通过)。用户指定的真实回归项目仅做定向只读字段与编译解析检查,未修改、未建批、未提交 AWB、未下载或重新生成资产。 + +## 2026-07-17 — 统一工作台贯穿五阶段 + +- 新增 `scripts/workspace_server.mjs`:用一个仅本机监听的常驻服务承载初始化、剧本解析等待、资产整理、资产生成和结果确认;初始化提交后不再关闭服务或让浏览器断开。旧 `setup_server.mjs` 与 `asset_viewer_server.mjs` 保留为兼容入口,但都会启动同一工作台。 +- 以当前只读 `assets/viewer-app/` 为底座合入初始化 Dialog。提交后页面切换为“设置已保存,等待 Agent 继续”,轮询 `project-state.json` 自动更新阶段;资产出现后自动显示三栏浏览。前台约 2 秒轮询,后台降低频率,断线保留当前内容并指数退避重连。 +- 工作台唯一写入端点只原子写 `setup-decisions.json`,并校验 schemaVersion、projectId、视觉范式与构图 ID;设置固化后拒绝重写。审查、提示词修改、锁图、生图和付费仍全部留在 Agent 与确定性脚本,未恢复旧审视台 PATCH。 +- 恢复精简的 `PRODUCT.md` / `DESIGN.md`,锁定“同一项目、同一工作空间、初始化是浮层”的产品边界,避免后续维护再次把五阶段拆成彼此无关的页面。 +- 保留现有 `localPath` 图片优先、自动下载、中文提示词、正向提示词和主代理上下文纪律;未修改 schema、DAG、AWB、批次或审查 patch 契约。 +- 本次只解决工作台生命周期与状态呈现,不提前实现此前明确延期的“初始化时一次性选择模型 / 通用图片规格 / 质量”自动化;新项目在这些参数尚未由 Agent 固化前仍不会进入 ready。供应商执行中的细粒度 checkpoint 仍以 `execution-plan.json` 为准,工作台在 reconcile 写回 `project-state.json` 后显示结果。 +- 独立审查同时确认若干既有后端缺口不属于本次 UI 改动:成功图片被打回后的重生闭环、审查 patch 乐观锁、源剧本锁定后重验、已存在角色追加状态。后续若要实现真正的全自动五阶段,应单独修复并加契约测试,不能把这些语义偷偷塞进前端。 +- 验证要求:新项目提交选择后原 URL 持续可用并进入等待态;应用设置后自动进入解析态;真实项目三栏、提示词和本地图片正常;初始化之外的写请求返回 405,路径越权被拒绝;1600×900 与 1180×800 无页面级溢出。 + +## 2026-07-17 — 还原三栏浏览为只读资产查看台 + +- 新增 `scripts/asset_viewer_server.mjs` 与 `assets/viewer-app/`:还原三栏资产浏览(资产列表 / 图片预览 / 详情检查器),保留搜索、类型与状态筛选、按来源分段的提示词展示、编译文本查看与复制、项目进度弹层;图片预览优先项目内 `localPath`。 +- 与此前"审视工作台"的区别:**无任何编辑、审批、保存、导出或锁定操作**,服务端只接受 GET(PATCH 返回 405);顶栏常驻"只读 · 修改请在 Agent 对话中进行"。审查决定仍全部走对话式链路(review-decisions.json → apply)。 +- 背景:上一条目移除审视界面时把浏览能力一并删除属于超范围;用户需要的是去掉编辑/提意见功能、保留三栏查看。 +- 验证:在真实项目上实测——页面渲染、状态 API、`/project/` 本地图片(384KB JPEG 直出)、写入请求 405 拒绝、越权路径拒绝,全部通过。 + +## 2026-07-17 — 图片本地化、主代理上下文纪律与编译对账(《抢亲局中局》实跑复盘) + +- 新增 `scripts/download_artifacts.mjs`:把生成成功资产的远程图下载到项目 `assets/images/<资产ID>.` 并写回 `image.localPath`;SKILL.md 结果回收步骤在 reconcile 后必跑。背景:供应商返回带时效签名的 URL(约 7 天失效),实跑项目 18 张图零本地副本,不下载等于丢结果。已用本脚本在真实项目上抢救 18/18 成功。 +- SKILL.md 新增"主代理上下文纪律":全文理解/编译/提示词三环节必须派子代理;主代理不读剧本原文与大 JSON;对话式审查分批展示;禁止即兴编写前端查看器(实跑中主代理包揽全部环节导致上下文耗尽,并自建了一个风格不一致的 index.html)。 +- `record_story_bible.mjs` 新增锁定前软校验(只警告不阻塞):具名角色档案缺少带集-场证据的状态列表时逐个列出提醒,防止圣经层状态缺失顺流成为单默认态资产。 +- 子代理契约"资产化准入"新增状态对账硬要求:圣经每条状态要么建 state 要么进 downgraded,只编译默认态视为编译不完整须退回重编。背景:实跑中圣经正确记录了女主 7 套状态(均带多处集-场证据),编译却只产出 1 个默认态且未记录降级,状态被静默丢弃。 +- 已知缺口(未修):`merge_agent_patches.mjs` 不支持向已存在角色追加 state(add 只能整资产、update 只能改语义字段),编译不完整的存量项目无法通过 patch 补状态,只能派生重编或人工改状态文件。待定方案:新增 `add` assetType `character-state`(携带 characterId)。 + +- 移除资产审视前端与其服务:删除 `scripts/review_server.mjs`;`assets/setup-app/` 回归纯初始化 Dialog(index.html / setup.js / setup.css 全部重写为 setup 单一职责,删除三栏工作台、资产列表、检查器与相关样式);`setup_server.mjs` 移除 `/api/capabilities`。 +- 审查数据链路完整保留:`review-decisions.json`(bootstrap_review_package 初始化)→ `apply_review_decisions.mjs` → validate → plan_work_dag 不变,schema v3 不变。差别只在写入方:此前由审视界面 PATCH,现在由主代理依据用户在对话中的确认代写稀疏 patch(status / note / identityPrompt / deltaPrompt / 默认态锁定),baseRevision 乐观锁语义不变。存量项目和已锁定资产零影响。 +- 决策依据:目标用户(美术/导演/编导)在 Agent 对话里直接改提示词比切到独立界面更顺;审视界面的维护成本(预览一致性、并发端口、返工闭环)大于收益。 +- 同时清理设计过程产物:删除 `PRODUCT.md`、`DESIGN.md`、`.impeccable/`(Impeccable 工具的设计系统状态,不参与 skill 运行时)。 +- SKILL.md"审查"章节改为对话式流程,并新增硬要求:apply 之后必须向用户复述被打回资产及意见,不让 changes_requested 静默滞留(此前该闭环仅靠约定,DAG 不感知返工)。 +- 验证方式:全新项目初始化 → Dialog 随机端口正常渲染与提交 → apply_setup_decisions 固化;手写审查 patch → apply_review_decisions 正确应用。 + ## 0.1.0 — 首次公开发布 - 以 MIT 许可证发布;新增面向安装、更新、反馈和安全报告的公开仓库说明。 - 新增中性视觉范式 `cg-stylized-3d`(显示名“柔和三维动画”);仅调整预设标识与预览资源路径,不改变对应提示词种子。 - 维护方式为 Issues 与 Discussions 收集反馈,不接收外部 Pull Request。 +## 2026-07-17 — 初始化与审视合并为共享资产工作台 + +- `assets/setup-app/` 现承载初始化和资产审视共用的唯一前端代码;`setup_server.mjs` 与 `review_server.mjs` 通过 `/api/capabilities` 选择运行模式。历史目录名保留以避免无必要的资源迁移。 +- `bootstrap_review_package.mjs` 不再把 HTML、CSS 和 JavaScript 复制到每个项目的 `review/` 目录,只初始化 `review-decisions.json`。`review_server.mjs` 直接从 skill 资源提供 `/review/`,旧项目内已有的 `review/` 副本不会被读取或删除。 +- 审视界面改为“资产列表 + 图片预览 + 详情检查器”的三栏桌面工作台;移除常驻工作流侧栏,顶部阶段入口只展示只读项目进度和历史产物入口,不允许直接回退 canonical 工作流。 +- 右侧只保留两个主要信息区域:剧情层的“角色描述 / 场景说明 / 道具说明”,以及按来源分段的“最终生图提示词”。项目风格、渲染规范和默认构图只读;默认角色的 `identityPrompt` 与当前资产的 `deltaPrompt` 仍通过现有稀疏 patch 局部编辑。 +- 修复审视预览与正式建批不一致:前端最终提示词现包含 `assetPresentation.characterDefault.prompt`,并按与后端 `compilePrompt()` 相同的顺序去重拼接。未引入 `promptOverride`,schema、prompt hash、批次和 AWB 链路保持不变。 +- 图片展示优先使用项目内 `localPath`,再回退到远程 URL / backendPath,避免结果已下载但远程地址不可用时预览空白。 +- 验证:初始化模式 12 个视觉选项和 5 个构图选项可切换与提交;真实项目显示 43 个可见状态行;1600×900 与 1180×800 无页面级横向溢出;浏览器无 console error / 失败请求;前端完整提示词与后端编译结果逐字一致;隔离项目中的 identityPrompt、审视备注和 changes_requested patch 可保存并由 `apply_review_decisions.mjs` 正确应用。 + ## 2026-07-17 — 统一工作台产品与设计基线 - 新增 `PRODUCT.md`,将前端定义为覆盖初始化、解析、资产审视、生图和结果状态的统一桌面工作台;初始化选择是工作台首次启动的 Dialog。 diff --git a/DESIGN.md b/DESIGN.md index 4edc614..04a79c4 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,246 +1,66 @@ --- name: "漫剧资产工作台" -description: "专业、可靠、克制的 AI 漫剧资产生产界面" +description: "专业、可靠、克制的连续漫剧资产生产界面" colors: - primary-brick: "#8E3F23" - primary-brick-hover: "#71311B" + accent: "#8E3F23" + accent-hover: "#71311B" ink: "#272320" - ink-soft: "#5E4E43" muted: "#756E67" workspace: "#F5F0E8" surface: "#FFFDF9" surface-muted: "#EBE4D9" divider: "#DED5CA" - focus: "#AA653D" success: "#1F6A46" - success-soft: "#DCEFE2" warning: "#875D25" - warning-soft: "#F8EBCB" danger: "#9E3D31" - danger-soft: "#F6DFD7" typography: - project-title: - fontFamily: "\"Songti SC\", STSong, Georgia, serif" - fontSize: "26px" - fontWeight: 600 - lineHeight: 1.2 - letterSpacing: "-0.02em" - headline: - fontFamily: "\"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", system-ui, sans-serif" - fontSize: "18px" - fontWeight: 700 - lineHeight: 1.35 - title: - fontFamily: "\"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", system-ui, sans-serif" - fontSize: "14px" - fontWeight: 700 - lineHeight: 1.45 - body: - fontFamily: "\"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", system-ui, sans-serif" - fontSize: "13px" - fontWeight: 400 - lineHeight: 1.65 - label: - fontFamily: "\"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", system-ui, sans-serif" - fontSize: "11px" - fontWeight: 600 - lineHeight: 1.4 + ui: "PingFang SC, Hiragino Sans GB, Microsoft YaHei, system-ui, sans-serif" + project-title: "Songti SC, STSong, Georgia, serif" rounded: sm: "6px" md: "8px" lg: "10px" - pill: "999px" spacing: xs: "4px" sm: "8px" md: "12px" lg: "16px" xl: "24px" - xxl: "32px" -components: - button-primary: - backgroundColor: "{colors.primary-brick}" - textColor: "{colors.surface}" - typography: "{typography.title}" - rounded: "{rounded.md}" - padding: "10px 16px" - button-primary-hover: - backgroundColor: "{colors.primary-brick-hover}" - textColor: "{colors.surface}" - rounded: "{rounded.md}" - button-secondary: - backgroundColor: "{colors.surface}" - textColor: "{colors.ink-soft}" - typography: "{typography.title}" - rounded: "{rounded.md}" - padding: "9px 14px" - field: - backgroundColor: "{colors.surface}" - textColor: "{colors.ink}" - typography: "{typography.body}" - rounded: "{rounded.md}" - padding: "9px 11px" - chip-selected: - backgroundColor: "{colors.primary-brick}" - textColor: "{colors.surface}" - typography: "{typography.label}" - rounded: "{rounded.pill}" - padding: "4px 9px" - dialog: - backgroundColor: "{colors.workspace}" - textColor: "{colors.ink}" - rounded: "{rounded.lg}" - padding: "24px" --- # Design System: 漫剧资产工作台 -## Overview +## North Star -**Creative North Star: "安静的主美工作台"** +“安静的主美工作台”。同一应用外壳贯穿项目设置、剧本解析、资产整理、资产生成和结果确认。初始化是工作台上的一次性浮层,不是独立网页。 -这套界面应像一张长期使用的数字工作桌:信息稳定地留在原位,图片、角色关系和生产状态比界面本身更醒目。暖灰和砖红保留现有创作气质,布局与控件则遵循生产工具的秩序,减少展示页式文案、虚构背景和重复容器。 +## Layout -工作台采用连续的桌面产品结构。初始化 Dialog、工作流进度、资产列表和资产详情共享同一套导航、排版和状态语言。桌面大屏是主场景,常见笔记本宽度通过收窄列表、折叠辅助信息和保持详情区可滚动来适配,不设计手机和平板布局。 +- 顶栏展示项目名称、当前阶段和只读边界。 +- 资产存在时使用“左侧资产列表 / 中间图片 / 右侧详情”三栏结构。 +- 资产尚未出现时保持同一壳体,用中央等待区解释当前可靠状态和下一步。 +- 五阶段进度放在顶部紧凑弹层中,不常驻占用左侧空间。 +- 1600×900 为主要画布;1180×800 通过收窄列表和详情栏适配。 -系统明确拒绝炫技的 AI 科幻控制台,也拒绝大量同质卡片、层层容器和重复摘要组成的 SaaS 仪表盘。动画只解释状态变化;Loading、展开收起和图片预览必须减少认知负担,否则不应加入。 +## Interaction -**Key Characteristics:** +- 初始化提交后显示“设置已保存,等待 Agent 继续”,页面保持连接。 +- 前台页面定时读取项目状态,后台标签降低频率;状态未变化不重绘。 +- 断线时保留现有内容,显示重连提示;恢复后自动继续。 +- Loading 使用轻量骨架和状态文案,不使用大型旋转动画,不伪造百分比。 +- 动画只解释浮层关闭、阶段变化和内容出现,控制在 150~220ms,并支持减少动画。 -- 暖灰工作区,砖红色只用于主要操作和当前选择。 -- 项目标题可使用宋体,其余界面统一使用系统无衬线字体。 -- 左侧工作流与资产列表保持紧凑,右侧详情为主要阅读和编辑区域。 -- 大部分表面保持扁平,使用留白、分隔线和背景层建立层级。 -- 前端展示正式状态并提交受控意图,不表现为自由实时协同编辑器。 +## Visual Rules -## Colors +- 暖灰工作区、清洁表面和一像素分隔线建立层级。 +- 砖红只用于主要操作和当前选择;成功、警告、错误使用语义色。 +- 项目名称可用宋体,其余操作、数据和提示词统一使用系统中文无衬线。 +- 普通容器最大 10px 圆角且无宽投影;阴影只用于 Dialog、Popover 和 Toast。 +- 不使用玻璃拟态、渐变文字、霓虹、装饰性指标卡和层层卡片。 -色彩应像稳定的创作工具,而不是内容本身。暖灰承载长时间工作,砖红提供稀少而明确的行动信号。 +## State Boundaries -### Primary - -- **沉稳砖红** (`primary-brick`):用于主要操作、当前步骤、当前资产和明确确认状态;同一屏幕上的占比必须克制。 -- **深砖红** (`primary-brick-hover`):仅用于主操作的悬停与按下反馈。 - -### Secondary - -- **安静橄榄色**:仅用于风格分类、辅助元信息或非行动性的视觉区分,不承担主要按钮职责。 - -### Neutral - -- **温黑墨色** (`ink`):标题、关键数值和主要文本。 -- **柔和墨棕** (`ink-soft`):说明文本、资产摘要和次级操作。 -- **暖灰工作区** (`workspace`):应用主背景。 -- **清洁表面** (`surface`):详情编辑区、输入框和图片查看区。 -- **导航暖灰** (`surface-muted`):左侧导航、列表选中前的分层背景。 -- **柔和分隔线** (`divider`):结构分隔,不用于装饰性描边。 - -### Named Rules - -**The One Action Color Rule.** 砖红只表示主要操作、当前选择和需要注意的状态;不得把它用于标题装饰、大片背景或无意义图形。 - -**The Status Pair Rule.** 成功、警告和错误状态始终使用深色文字配同色浅底,不能只依赖文字颜色表达。 - -## Typography - -**Display Font:** 宋体(`Songti SC`,回退到 `STSong`、`Georgia`、`serif`) -**Body Font:** 系统中文无衬线(`PingFang SC`、`Hiragino Sans GB`、`Microsoft YaHei`、`system-ui`) -**Label/Mono Font:** 标签继续使用系统中文无衬线;稳定 ID 可使用系统等宽字体。 - -**Character:** 宋体只给项目名称和极少数高层标题带来创作气质。操作标签、状态、按钮、输入框和正文全部使用清晰的系统无衬线字体,避免产品界面出现杂志式排版。 - -### Hierarchy - -- **Project Title**(600,26px,1.2):项目名称和工作台最高层标题,仅少量出现。 -- **Headline**(700,18px,1.35):详情区章节标题、Dialog 主标题。 -- **Title**(700,14px,1.45):资产名称、字段分组、主要按钮。 -- **Body**(400,13px,1.65):资产说明、提示词、状态解释;连续说明文本限制在约 70 个中文字符的舒适行宽内。 -- **Label**(600,11px,1.4):字段名、状态标签、辅助信息;不使用整句英文大写标签。 - -### Named Rules - -**The One Serif Role Rule.** 宋体只能用于项目名称或最高层创作标题。按钮、表单、导航、状态和数据禁止使用宋体。 - -**The Chinese First Rule.** 面向用户的界面文案以中文为主;英文只保留不可替代的模型名、格式名和短技术标识。 - -## Elevation - -系统默认扁平。主工作台通过背景层、分隔线、固定栏位和留白建立结构,不为每个资产、统计数字或字段制造独立悬浮卡片。阴影只用于初始化 Dialog、菜单浮层、Toast 和大图预览浮层,表达它们临时位于工作台之上。 - -### Shadow Vocabulary - -- **Dialog Lift** (`0 24px 64px rgba(39, 35, 32, 0.22)`):仅用于首次设置 Dialog 和需要阻断背景操作的确认浮层;浮层使用阴影时不再叠加装饰性边框。 -- **Compact Popover** (`0 8px 20px rgba(39, 35, 32, 0.14)`):用于小型菜单、图片放大入口和 Toast。 - -### Named Rules - -**The Flat Workspace Rule.** 工作区、导航、资产列表和详情面板在静止状态下不得使用投影;层级由背景色和一像素分隔线表达。 - -**The One Floating Layer Rule.** 同一时刻最多有一个主要浮层。不得在 Dialog 内继续堆叠带阴影卡片。 - -## Components - -### Buttons - -- **Shape:** 紧凑圆角矩形(8px),不使用夸张胶囊造型作为主要按钮。 -- **Primary:** 沉稳砖红底、清洁表面色文字,内边距 10px × 16px;标签使用“动词 + 对象”,例如“保存审视决定”。 -- **Hover / Focus:** 悬停变为深砖红;焦点使用 3px 半透明砖红焦点环,不通过位移制造跳动。 -- **Secondary:** 清洁表面底、柔和墨棕文字和柔和分隔线;不与主按钮争夺视觉重量。 - -### Chips - -- **Style:** 仅用于类型、状态和过滤条件。状态使用深色文字配同色浅底,过滤选中态使用砖红底。 -- **State:** 标签不可承担主要操作;可点击过滤器必须有明确的选中与未选中差异。 - -### Cards / Containers - -- **Corner Style:** 普通容器最大 10px 圆角;资产列表项不做独立卡片。 -- **Background:** 工作区、导航层和清洁详情表面形成三层结构。 -- **Shadow Strategy:** 工作区容器无阴影;只有浮层遵循 Elevation 规则。 -- **Border:** 仅使用 1px 柔和分隔线表达真实结构边界。 -- **Internal Padding:** 紧凑区域 12~16px,主要详情章节 16~24px。 - -### Inputs / Fields - -- **Style:** 清洁表面底、1px 柔和分隔线、8px 圆角。提示词编辑器按内容需要提供足够高度,不把所有字段永久展开。 -- **Focus:** 边框切换为焦点砖色,并显示 3px 低透明度焦点环。 -- **Error / Disabled:** 错误使用危险色浅底和说明文字;禁用态降低对比度但仍保持可读。 - -### Navigation - -- 工作台左侧第一层显示固定工作流阶段;第二层显示当前阶段的资产列表或任务列表。 -- 当前阶段和当前资产使用背景层与砖红色小范围强调,不使用粗侧边色条。 -- 笔记本小屏允许收窄或折叠第一层工作流导航,但不能隐藏当前阶段和返回路径。 - -### Asset Master–Detail - -- 左侧资产列表按角色、场景、道具分组,显示名称、状态和必要缩略图。 -- 右侧详情集中展示当前资产的图片、视觉需求、分层提示词、审视意见和执行状态。 -- 角色默认态与后续状态在同一角色分组内展示,避免把关联状态拆成横向超宽表格。 -- 长提示词、技术 ID 和执行记录默认折叠,用户需要时再展开。 - -### Loading and Disclosure - -- 数据加载使用与真实布局一致的轻量骨架,不在页面中央放置持续旋转的大型 Loading。 -- 展开收起只用于长提示词、技术信息、历史执行记录和辅助预览。 -- 过渡时间控制在 150~220ms;用户启用减少动画时立即切换。 - -## Do's and Don'ts - -### Do: - -- **Do** 使用暖灰工作区、清洁详情表面和一像素分隔线建立稳定的桌面工具结构。 -- **Do** 把图片、资产名称、审视状态和下一步操作放在视觉层级前面。 -- **Do** 使用左侧资产列表与右侧详情,让一个角色及其状态保持在同一上下文中。 -- **Do** 让初始化 Dialog 与主工作台共用颜色、字体、按钮和状态组件。 -- **Do** 让 Loading、折叠和预览组件解决明确的信息或等待问题。 - -### Don't: - -- **Don't** 制作炫技的 AI 科幻控制台、霓虹 HUD 或无功能意义的动态效果。 -- **Don't** 使用大量同质卡片、层层容器和重复摘要组成 SaaS 仪表盘。 -- **Don't** 使用横向宽度超过正常笔记本视口的大表格作为主要资产审视方式。 -- **Don't** 在普通容器上同时叠加一像素边框和宽而柔的装饰阴影。 -- **Don't** 在每个章节上方重复小号英文大写标签或编号眉题。 -- **Don't** 使用超过 10px 的普通容器圆角,或把所有按钮做成胶囊形。 -- **Don't** 让前端和 Agent 同时自由修改 canonical 项目状态。 +- 前端唯一写入:`setup-decisions.json`。 +- `project-state.json`、`review-decisions.json`、提示词和执行状态只读。 +- 不提供审批、提示词编辑、图片锁定、生图提交或扣费按钮。 +- 图片优先展示项目内 `localPath`,再回退远程 URL。 diff --git a/PRODUCT.md b/PRODUCT.md index f557f8a..81e73d5 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -6,34 +6,34 @@ product ## Users -面向中文创作者和漫剧资产生产人员。使用者通常熟悉基本创作与生图流程,希望在桌面大屏或常见笔记本上完成项目初始化、剧本解析跟踪、资产查阅与审视、生图执行和结果选择。 +面向中文漫剧创作者和资产生产人员。用户主要在桌面大屏或常见笔记本上完成项目初始化、剧本解析跟踪、资产查阅、生图执行和结果确认。 ## Product Purpose -将 `comic-assets` 的固定工作流呈现为一个连续的资产工作台。初始化 Dialog 是工作台的首次启动浮层;后续解析进度、角色/场景/道具资产、提示词、图片和执行状态在同一产品结构中持续呈现。 +把 `comic-assets` 的固定工作流呈现为一个连续的本地资产工作台。初始化选择是工作台首次启动的 Dialog;提交后工作台保持同一地址,通过项目文件展示剧本解析、资产整理、资产生成和结果确认状态。 -前端负责读取项目事实、展示状态,并提交风格选择、审视决定或其他明确意图。Agent 和确定性脚本负责验证这些输入、修改 canonical 项目状态、编写提示词、执行生图和处理恢复。成功意味着用户始终知道当前阶段、项目状态和下一步,同时项目文件保持可恢复、可审计和不被并发覆盖。 +前端只读取 canonical 项目状态,并写入明确允许的初始化意图。Agent 和确定性脚本仍是 `project-state.json`、审查 patch、生图执行与结果合并的唯一受控写入者。 ## Brand Personality -专业、可靠、克制。界面应像稳定的创作生产工具,图片与资产信息是视觉中心,装饰退后。 +专业、可靠、克制。图片、资产信息和下一步是视觉中心,界面本身退后。 ## Anti-references -- 炫技的 AI 科幻控制台、霓虹 HUD、无功能意义的动态效果。 +- 炫技的 AI 科幻控制台、霓虹 HUD 和无功能意义的动态效果。 - 大量同质卡片、层层容器和重复摘要组成的 SaaS 仪表盘。 -- 为了展示设计感而牺牲信息密度、阅读顺序或操作确定性的界面。 -- 前端和 Agent 同时自由修改 canonical 状态的实时协同模式。 +- 前端直接审批、改写 canonical 状态或触发生图扣费。 +- 初始化提交后断开页面,或要求用户在多个随机地址之间切换。 ## Design Principles -1. 一个项目对应一套连续的工作空间,初始化、解析、审视和生成不应像彼此无关的产品。 -2. 当前阶段、当前状态和下一步始终清楚,状态表达优先于装饰。 -3. 资产图片、角色关系和生产信息优先,采用左侧资产列表与右侧详情的主从结构。 -4. 前端提交意图,Agent 和确定性脚本验证并执行;canonical 项目状态始终只有一个受控写入路径。 -5. 功能优先。Loading、折叠、预览等轻量组件只有在减少等待焦虑或信息负担时才加入。 -6. 稳定性和可恢复性优先于自由实时交互;新能力应逐层增加,不破坏现有文件与 patch 契约。 +1. 一个项目对应一套连续工作空间和一个当前服务地址。 +2. 初始化 Dialog 提交后只关闭浮层,不关闭工作台。 +3. 当前阶段、可靠状态和下一步始终清楚;不展示虚假百分比。 +4. 资产图片、角色关系和生产信息优先,使用紧凑的三栏主从结构。 +5. 前端只提交初始化意图;审查、提示词修改和付费执行留在 Agent 对话。 +6. 稳定性、可恢复性和兼容性优先于实时协作与复杂动效。 ## Accessibility & Inclusion -主要支持桌面大屏,并保证常见笔记本小屏可完整使用。不为手机和平板设计,不建设额外的复杂键盘操作或无障碍系统。保留浏览器原生交互、基本焦点状态、文本可读性和必要的减少动画兜底,不为此引入重型依赖。 +主要支持桌面大屏,并保证常见笔记本小屏可完整使用。不为手机和平板设计。保留基本焦点、可读对比度和减少动画兜底,不引入重型无障碍依赖。 diff --git a/README.md b/README.md index cba7286..01373b8 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ ## 前置条件 - 已安装并登录 Codex。 -- 已安装 Node.js(用于本地工作台和确定性脚本)。 -- 如需正式生图,另行安装并登录 `lj-awb`;生图、积分与账号授权均由该环境处理。 +- 已安装 Node.js(用于初始化 Dialog 和确定性脚本)。 +- 如需正式生图,安装并登录 [lj-awb CLI(官方安装说明)](https://animeworkbench.lingjingai.cn/lj-awb-cli);生图、积分与账号授权均由该环境处理。 ## 安装 @@ -18,7 +18,7 @@ git clone https://github.com/Shanzoon/comic-assets-skill.git ~/.codex/skills/comic-assets ``` -重启 Codex 后,上传剧本并提出“将这个剧本做成漫剧资产图片项目”等请求即可触发。skill 会先打开本地初始化界面,再引导你确认资产圣经和创作方向。 +重启 Codex 后,上传剧本并提出“将这个剧本做成漫剧资产图片项目”等请求即可触发。skill 会先打开本地统一工作台,在同一地址完成初始化、跟踪解析和浏览资产,再引导你在 Agent 对话中确认资产圣经和创作方向。 ## 更新 diff --git a/SKILL.md b/SKILL.md index 3ca4011..57eb519 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,130 +1,138 @@ --- name: comic-assets -description: 将用户上传的剧本直接转成可审查、可恢复、逐角色流式生成的 AI 漫剧资产图片项目。用于从剧本提取角色/状态/场景/道具,生成分层视觉提示词,打开资产审查台,依赖 lj-awb 估价、批量生图、轮询、重试和收割结果;也用于继续中断项目、只重跑失败资产或导入上游资产清单。 +description: 将任意语言剧本转成可审查、可恢复、逐角色流式生成的 AI 漫剧资产项目。用于提取角色与外观版本、场景、道具,建立故事资产圣经和美术总纲,编写与审查中文生图提示词,通过 lj-awb 估价、批量生图、轮询、重试和收割结果;也用于恢复中断项目、只重跑失败资产或导入上游资产清单。 --- # 漫剧资产生图 -目标是让用户只做三件事:上传剧本、补充缺失的美术风格、确认审查与付费批次。其余目录、ID、DAG、checkpoint、提示词编译和结果合并由本 skill 完成。 +把剧本转成可审查、可恢复、可增量生成的资产项目。让 Agent 对理解、设计、调度和交付质量负责;把稳定 ID、锁定、hash、审查、扣费、checkpoint 与恢复交给确定性脚本。 -## 接手与变更记录 +## 先判断入口 -修改本 skill 前必须先阅读 [CHANGELOG.md](CHANGELOG.md)。它记录当前行为、兼容性和已验证的改动;不要在不了解既有锁定规则的情况下覆盖流程。 +- **新剧本**:初始化项目并立即启动统一工作台。 +- **已有项目**:使用同一入口加 `--resume`,根据项目文件恢复,不从头重做。 +- **只审查或继续生图**:重新启动工作台,读取当前 DAG,不重建已存在产物。 +- **依赖不可用**:仍交付完整项目、审查数据和供应商无关批次;不要伪造生图完成。 -## 零配置入口 +要求 Node.js >=20;真实生图还要求 lj-awb 可用、联网并已登录。 -要求 Node.js >=20。真实生图还要求安装 lj-awb skill、联网并完成 AWB 登录;依赖不可用时仍交付完整项目、审查台和供应商无关批次。 +```bash +node "/scripts/run_project.mjs" "<剧本文件>" --project-dir "<项目目录>" +node "/scripts/workspace_server.mjs" "<项目目录>" +``` -收到新剧本后直接初始化,不要求用户命名目录: +工作台使用同一本地地址贯穿项目。初始化预览图只帮助用户选择,绝不作为图生图参考上传。 -~~~bash -node "/scripts/run_project.mjs" "<剧本文件>" --project-dir "<项目目录>" -~~~ +## 自主权与确认 + +按后果决定是否暂停: + +- **可逆动作**:直接执行并透明复述,包括初始化选择的落盘、草稿、分片、局部重写和状态扫描。 +- **用户已明确选择**:视为授权;setup 锁定前可直接代写 `setup-decisions.json` 并运行 apply,同条回复复述预设名、定位、种子原文和构图。 +- **选择不明确**:不得猜测匹配预设或借用其他项目偏好;给最接近候选让用户选择。 +- **不可逆动作**:锁定故事圣经、锁定创作方向、锁定参考图、超出持久授权的扣费与破坏性迁移必须确认。 +- **持久授权**:只在记录的范围和阈值内自动执行,仍保留快照、hash 和日志。 + +创作方向确认可合并成一个确认包,但“人物群体呈现”和“画面内文字语言”必须在包内分别用成图后果句醒目呈现,例如“这意味着成图主角将呈现为欧美面孔”“道具文字将渲染为英文”。用户可以一次确认整个包;不得退化为笼统的“请确认总纲”,也不得让高后果项被其他摘要淹没。 -初始化后,**先立即启动项目初始化 Dialog**,不要先问用户模型或参数。用户单选一个视觉范式和一个默认角色资产构图;Dialog 的预览图只用于帮助选择,绝不作为图生图参考上传。选择提交后运行: +完整授权、审查和执行状态见 [references/execution-modes.md](references/execution-modes.md)。所有阶段共同遵守 [references/invariants.md](references/invariants.md)。 -~~~bash -node "/scripts/setup_server.mjs" "<项目目录>" -# 在浏览器打开终端给出的 URL,提交选择后: +## 五阶段 + +### 1. 初始化 + +打开工作台,让用户选择视觉范式和默认角色构图;明确选择也可由主代理代写 sidecar。工作台只写 `setup-decisions.json`,随后运行: + +```bash node "/scripts/apply_setup_decisions.mjs" "<项目目录>/project-state.json" -~~~ +``` + +### 2. 全剧事实 -该操作把风格的中文提示词种子、默认角色构图描述和比例写入项目状态。随后才让一个可读取全文的 Agent 用自然语言完成 `story-asset-bible.md` 的世界观、剧情时间线、角色别名与身份演变、场景、道具、证据和不确定项;不要要求它输出 JSON 或供应商提示词。证据一律用"集-场"编号指针而非台词全文;状态全量记录(含仅出现一次的),资产化取舍留给编译阶段按复用度决定。完成后固化该全局理解: +派岗位一完成 `story-asset-bible.md`。任务卡只含剧本路径和事实提取规则,不携带画风、构图、模型参数或无关对话;主代理不读剧本全文。岗位边界、外观版本定义和准入规则只读 [references/subagent-contracts.md](references/subagent-contracts.md)。 -~~~bash +```bash node "/scripts/record_story_bible.mjs" "<项目目录>/project-state.json" -~~~ +``` -确认会锁定故事资产圣经。后续日常修改应落在美术风格、提示词差量、审查意见或图片锚点;如果发现全局剧情理解错误,保留当前项目和产物,另建或派生项目重新开始,不在原项目内改写圣经。 +这一步会锁定全局理解。发现重大理解错误时保留产物并派生项目,不在原项目改写。 -故事资产圣经锁定后,由 AI 美术总监填写 `art-direction-brief.md`:提出创作命题、用户确认方向、公共视觉语言、默认渲染规格、正向设计重点与跨资产设计原则。用户确认后固化: +### 3. 创作方向与正式名册 -~~~bash -node "/scripts/record_art_direction_brief.mjs" "<项目目录>/project-state.json" -~~~ +圣经锁定后并行推进: -它会把已确认的公共视觉语言和默认渲染规格写入 `styleProfile` / `promptProfile`。运行时只遵循 [references/creative-charter.md](references/creative-charter.md) 与 [references/prompt-authoring.md](references/prompt-authoring.md) 的短原则;不加载外部美术知识库原文作为逐条命令,也不使用负向提示词。 +- 岗位二依据圣经、用户意图和视觉范式完成 `art-direction-brief.md`;只读 [references/creative-charter.md](references/creative-charter.md)。 +- 岗位三依据圣经和准入规则生成 canonical sidecar patch;不读美术总纲,不写 prompt。主代理运行 `merge_agent_patches.mjs`。 -随后由编译 Agent 依据故事资产圣经和项目创作方向生成 canonical 资产 sidecar patch,再运行 `merge_agent_patches.mjs`。仅在需要核验覆盖率或补漏时,才按剧本切片: +名册必须对每个候选和每个外观版本给出唯一处置;未生成的版本进入 `downgraded` 并说明理由。总纲确认后运行: -~~~bash -node "/scripts/build_script_shards.mjs" "<项目目录>/<原始剧本>" --output "<项目目录>/workflow/chunks" -~~~ +```bash +node "/scripts/record_art_direction_brief.mjs" "<项目目录>/project-state.json" +``` -换机或首次执行 AWB 前运行: +派生项目若用于更换视觉预设、F02 或其他创作方向,旧总纲只作回归证据;用新项目的 setup 和故事事实重新提出、确认并锁定总纲,不把旧 F02 复制成新项目 CONTRACT。旧项目及其已生成资产保持只读。 -~~~bash -node "/scripts/preflight.mjs" --bootstrap -~~~ +### 4. Prompt 与审查 -恢复已有项目时使用同一入口并加 --resume,随后扫描状态,不从头重做。 +创作方向锁定且名册合并后,岗位四按 [references/prompt-authoring.md](references/prompt-authoring.md) 编写中文 `promptBody` 并同步声明结构化 `textPolicy`。新项目最终 prompt 就是该正文;处理 v1/v2 或无文字策略标记的存量项目时才读 [references/legacy-profiles.md](references/legacy-profiles.md)。 -## 核心 DAG +先生成确定性工作清单: -1. 项目启动即打开初始化 Dialog,用户单选视觉范式和默认角色资产构图;`apply_setup_decisions.mjs` 将选择固化为项目事实。预览图仅供人判断,不进入任何模型输入。 -2. 全文理解 Agent 先写 `story-asset-bible.md`,建立全局实体、别名、身份演变、证据与不确定项;运行 `record_story_bible.mjs` 后锁定,才可继续。 -3. AI 美术总监依据故事资产圣经、用户意图和已选视觉范式提出 `art-direction-brief.md`;用户确认后运行 `record_art_direction_brief.mjs`,锁定项目创作方向。 -4. 编译 Agent 依据这两个已锁定产物生成 canonical 资产 sidecar patch,按复用度准入规则取舍状态并在 patch 的 `downgraded` 数组回报降级清单(见 subagent-contracts);主代理运行 `merge_agent_patches.mjs`,统一稳定 ID、revision 和冲突。 -5. 剧本分片只用于核验与补漏。worker 不能在核验阶段自行创建最终 canonical ID;疑似新实体或别名冲突必须回报主代理。 -6. Prompt Agent 在公共方向已确认后自主用中文设计并写入分层提示词;提示词按“项目公共风格 + 角色身份锚点 + 状态差量”存储,完整 prompt 仅在出批时编译,不追加负向提示词。默认角色态额外继承用户选定的构图描述和比例;后续状态、场景和道具不误用该排版。专有名词可保留必要原文。 -7. 运行 apply_review_decisions.mjs 消费稀疏审查 patch,再运行 plan_work_dag.mjs。 -8. 默认态按角色独立释放。某角色默认图成功且用户锁定具体 artifactId 后,只解锁该角色后续状态;不等待其他角色。 -9. 场景和道具按各自 ready 状态独立入批。单个阻塞项不得阻止其他可执行项。 +```bash +node "/scripts/plan_prompt_shards.mjs" "<项目目录>/project-state.json" --missing-only +``` -详细数据契约见 [references/project-schema.md](references/project-schema.md),子代理交接见 [references/subagent-contracts.md](references/subagent-contracts.md),创作原则见 [references/creative-charter.md](references/creative-charter.md),Prompt Agent 契约见 [references/prompt-authoring.md](references/prompt-authoring.md)。 +shard 是审计单位,bundle 是 planner 给出的建议派发单位。保持同一角色全部外观在同一上下文,覆盖全部 shard;主代理可按复杂度和可用槽位自主调整 bundle 分配。**禁止按资产类型只开三个大任务**。执行前播报 planner 的建议并发与预期波数;完成后按 shardId 对账并回报实际波数、总耗时和偏差原因。 -## 审查 +做新规则回归或收到 Prompt 质量反馈时,可运行只读审计;它只输出关系词、叙事词、逐视图重复、软预算、F02 取证、角色碰撞和文字策略的观测 JSON,不参与 readiness,也不能替代成图判断: -~~~bash -node "/scripts/bootstrap_review_package.mjs" "<项目目录>" -node "/scripts/review_server.mjs" "<项目目录>" -~~~ +```bash +node "/scripts/audit_prompt_bodies.mjs" "<项目目录>/project-state.json" --art-direction-brief "art-direction-brief.md" +``` -把终端输出的 /review/ URL 发给用户。审查台只保存实际修改字段;筛选和搜索不会丢编辑。保存后运行: +审查决定只写稀疏 `review-decisions.json`,然后统一应用: -~~~bash +```bash node "/scripts/apply_review_decisions.mjs" "<项目目录>/project-state.json" node "/scripts/validate_project_state.mjs" "<项目目录>/project-state.json" node "/scripts/plan_work_dag.mjs" "<项目目录>/project-state.json" -~~~ +``` + +立即把 `changes_requested` 的资产和理由回流岗位四,不让打回意见静默滞留。用户授权“提示词不用逐条确认”后,用 `record_standing_authorizations.mjs --batch-prompt-approval on` 记录,再运行 `approve_prompt_batch.mjs`;带可读文字资产默认仍留人审,人工打回项永不覆盖。 -## 增量生图 +### 5. 增量生成与收割 -只从 canonical ready 构建批次;approved、submitted、succeeded 不得直接或重复入批: +只从 canonical ready 构建批次;默认态按角色独立释放,后续外观只等待本角色锁定的默认 artifact,场景和道具各自独立 ready。 -~~~bash +```bash node "/scripts/build_image_batch.mjs" "<项目目录>/project-state.json" --scope "character:<角色ID>" --output "<项目目录>/image-batch.json" -~~~ +``` -真实执行前必须读取当前 lj-awb skill 和 schema。动态查询模型、参数、价格与项目组,生成执行确认快照: +进入真实执行阶段才读取 [references/lj-awb-quickref.md](references/lj-awb-quickref.md) 和 [references/provider-policy.md](references/provider-policy.md)。preflight、渠道能力和项目组查询可与 Prompt 编写并行;能力缓存可复用,估价与总积分必须全量重算并展示。 -~~~bash +```bash +node "/scripts/preflight.mjs" --bootstrap node "/scripts/prepare_awb_execution.mjs" "<项目目录>/image-batch.json" --model-group-code "" --project-group-no "" --estimated-cost "<积分>" -~~~ - -向用户展示模型、尺寸、数量、预计积分、失败项重试策略和 executionPlanHash。用户明确确认后才运行 record_execution_approval.mjs,再按 lj-awb 当前 dry-run / --yes 规则提交。详细边界见 [references/execution-modes.md](references/execution-modes.md) 与 [references/provider-policy.md](references/provider-policy.md)。 +``` -紧邻供应商调用前后使用 update_execution_checkpoint.mjs 记录 prepared → submitting → submitted;调用中断且没有 taskId 时转 submission_unknown。 +确认当前 executionPlanHash 后才记录 approval 并提交。用户已设置 `--auto-approve-below <积分>` 时只在阈值内自动确认。供应商调用前后更新 checkpoint;回收后立即本地化: -将 AWB 结果归一化后合并: - -~~~bash +```bash node "/scripts/reconcile_awb_results.mjs" "<项目目录>/project-state.json" "<项目目录>/awb-results.json" --batch "<项目目录>/image-batch.json" +node "/scripts/download_artifacts.mjs" "<项目目录>/project-state.json" node "/scripts/plan_work_dag.mjs" "<项目目录>/project-state.json" -~~~ +``` + +向用户展示项目内 `localPath`,不要依赖带时效签名的远程 URL。 -## 断点恢复 +## 主代理上下文预算 -- job 的 inputHash 未变化时保留 checkpoint;变化时仅使该 job 失效。 -- 已有 taskId 只恢复轮询,不重新创建。 -- 提交状态为 submitting 且没有 taskId 时标记 submission_unknown,暂停并人工核对;不得自动重提。 -- 失败只重试失败项;成功 artifact 不覆盖、不删除。 -- prompt、风格、参考 artifact、模型或批次范围变化后,旧确认自动失效。故事资产圣经锁定后不得在原项目内修改;重大剧情理解修订须新建或派生项目。 +- 把全文理解、canonical 名册编制和批量 Prompt 写作交给隔离上下文;主代理只调度、合并和报告。 +- 圣经与总纲锁定后只摘取相关条目,不整篇重复载入。 +- 不读取 image-batch、AWB 回执、task record 等大 JSON 全文;用脚本摘要或定向字段。 +- 结构化产物整体写入项目文件;终端和对话只传路径、数量、冲突与摘要,不用 stdout、echo 或 heredoc 拼大文件。 +- 不为项目即兴写查看器或 canonical 写入脚本;使用统一工作台和 skill 自带脚本。 -## 不变量 +## 维护本 skill -- project-state.json 是资产业务投影;不可变批次、AWB 原始回执和 task record 是独立审计事实。 -- 原剧本是剧情真相源;上游 Prompt B 是镜头真相源;本项目只维护资产运营状态。 -- 审查状态与供应商执行状态分轴保存,旧审查 patch 不能覆盖执行终态。 -- 后续角色状态必须直接引用本角色唯一默认态,并绑定用户锁定的确切 artifactId。 -- 真实提交、扣费、切换项目组和重试始终遵守当前 lj-awb 确认规则。 +修改运行行为前阅读 [CHANGELOG.md](CHANGELOG.md) 的当前行为速览和相关历史条目;保持真实项目只读。改后运行全量测试并记录行为、兼容性和验证。数据字段见 [references/project-schema.md](references/project-schema.md)。 diff --git a/agents/openai.yaml b/agents/openai.yaml index c1b0a4e..bce4596 100644 --- a/agents/openai.yaml +++ b/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "漫剧资产生图" - short_description: "上传剧本,逐角色流式生成可恢复的漫剧资产图片" - default_prompt: "使用 $comic-assets 读取我上传的剧本:先立即打开初始化 Dialog,让我单选视觉范式和默认角色资产构图;再建立故事资产圣经,由 AI 美术总监提出并等待我确认项目创作方向,最后生成可审查的资产图片。" + short_description: "上传剧本,在统一工作台逐角色生成可审查、可恢复的漫剧资产图片" + default_prompt: "使用 $comic-assets 读取我上传的剧本:立即打开贯穿五阶段的统一工作台,让我完成视觉范式和角色构图设置,再建立故事资产圣经、确认创作方向并逐步生成资产图片。" diff --git a/assets/review-app/app.js b/assets/review-app/app.js deleted file mode 100644 index 1893f55..0000000 --- a/assets/review-app/app.js +++ /dev/null @@ -1,304 +0,0 @@ -const app = { - state: null, - saved: { schemaVersion: 3, projectId: "", revision: 0, decisions: {} }, - pending: {}, - type: "all", - search: "", - dirty: false -}; - -const body = document.querySelector("#asset-table-body"); -const summary = document.querySelector("#summary"); -const title = document.querySelector("#project-title"); -const subtitle = document.querySelector("#project-subtitle"); -const toast = document.querySelector("#toast"); - -function escapeHtml(value) { - return String(value ?? "").replace(/[&<>'"]/g, (character) => ({ "&": "&", "<": "<", ">": ">", "'": "'", '"': """ })[character]); -} - -function escapedAttribute(value) { - return escapeHtml(value).replace(/\x60/g, "`"); -} - -function notify(message, error = false) { - toast.textContent = message; - toast.classList.toggle("error", error); - toast.classList.add("visible"); - window.clearTimeout(notify.timer); - notify.timer = window.setTimeout(() => toast.classList.remove("visible"), 3500); -} - -async function requestJson(url, options) { - const response = await fetch(url, options); - const payload = await response.json().catch(() => ({})); - if (!response.ok) { - const error = new Error(payload.error || "请求失败(" + response.status + ")"); - error.status = response.status; - error.payload = payload; - throw error; - } - return payload; -} - -function imageValue(image) { - if (!image || typeof image !== "object") return ""; - return image.url ?? image.backendPath ?? image.localPath ?? ""; -} - -function executionStatus(asset) { - return asset.execution?.status ?? (["submitted", "succeeded", "failed"].includes(asset.status) ? asset.status : "idle"); -} - -function canonical(row) { - const asset = row.asset; - const promptStatus = asset.review?.promptStatus ?? (["needs_review", "changes_requested", "approved"].includes(asset.status) ? asset.status : "needs_review"); - return { - status: promptStatus, - imageStatus: asset.review?.imageStatus ?? "needs_review", - identityPrompt: row.isDefault ? row.character?.identityPrompt ?? "" : "", - deltaPrompt: asset.deltaPrompt ?? asset.prompt ?? "", - imageUrl: imageValue(asset.image), - artifactId: asset.image?.artifactId ?? "", - lockedReference: Boolean(asset.referenceAnchor?.artifactId), - note: asset.review?.note ?? "" - }; -} - -function combinedPatch(id) { - return { ...(app.saved.decisions?.[id] ?? {}), ...(app.pending[id] ?? {}) }; -} - -function effective(row) { - const base = canonical(row); - const patch = combinedPatch(row.id); - for (const [field, value] of Object.entries(patch)) { - if (field === "updatedAt" || value == null) continue; - base[field] = value; - } - return base; -} - -function setPending(row, field, value) { - const base = canonical(row)[field]; - const savedHasField = Object.hasOwn(app.saved.decisions?.[row.id] ?? {}, field); - const patch = { ...(app.pending[row.id] ?? {}) }; - if (JSON.stringify(value) === JSON.stringify(base)) { - if (savedHasField) patch[field] = null; - else delete patch[field]; - } else { - patch[field] = value; - } - if (Object.keys(patch).length) app.pending[row.id] = patch; - else delete app.pending[row.id]; - app.dirty = Object.keys(app.pending).length > 0; -} - -function uniqueSegments(values) { - const seen = new Set(); - return values.map((value) => String(value ?? "").trim().replace(/\s+/g, " ")).filter((value) => { - if (!value) return false; - const key = value.toLocaleLowerCase("zh-CN"); - if (seen.has(key)) return false; - seen.add(key); - return true; - }); -} - -function compiledPrompt(row) { - const current = effective(row); - const profile = app.state.config?.promptProfile ?? {}; - const identityPrompt = row.isDefault ? current.identityPrompt : row.character?.identityPrompt; - const positive = uniqueSegments([profile.style, profile.render, identityPrompt, current.deltaPrompt]); - return positive.join("。"); -} - -function createRows() { - const rows = []; - for (const character of app.state.assets?.characters ?? []) { - const states = character.states ?? []; - const anchor = states.find((item) => item.sequence === 0); - for (const asset of states) { - rows.push({ - kind: "character", - id: asset.id, - asset, - character, - label: character.name, - secondaryLabel: asset.name, - description: [character.description, asset.visualBrief].filter(Boolean).join("\n"), - isDefault: asset.sequence === 0, - reference: asset.sequence > 0 && anchor ? anchor : null - }); - } - } - for (const [kind, group] of [["location", "locations"], ["prop", "props"]]) { - for (const asset of app.state.assets?.[group] ?? []) { - rows.push({ kind, id: asset.id, asset, character: null, label: asset.name, secondaryLabel: kind === "location" ? "场景资产" : "道具资产", description: asset.description ?? asset.visualBrief ?? "", isDefault: false, reference: null }); - } - } - return rows; -} - -function statusClass(status) { - return "status-" + String(status).replace(/[^a-z_]/g, ""); -} - -function renderSummary(rows) { - const promptApproved = rows.filter((row) => effective(row).status === "approved").length; - const ready = rows.filter((row) => row.asset.status === "ready").length; - const succeeded = rows.filter((row) => executionStatus(row.asset) === "succeeded").length; - const pending = rows.filter((row) => ["needs_review", "changes_requested"].includes(effective(row).status)).length; - summary.innerHTML = [ - ["待审 / 返工", pending], - ["提示词已通过", promptApproved], - ["当前可执行", ready], - ["已生成图片", succeeded] - ].map(([label, value]) => '
' + label + '
' + value + "
").join(""); -} - -function rowHtml(row) { - const current = effective(row); - const execution = executionStatus(row.asset); - const image = current.imageUrl; - const imagePreview = image - ? '' + escapedAttribute(row.label) + '图片' - : "尚未生成图片"; - let referenceText = row.isDefault ? "这是该角色的身份锚点;图片生成并通过后锁定。" : "独立资产,无角色身份参考。"; - if (row.reference) { - const artifactId = row.reference.referenceAnchor?.artifactId; - referenceText = "依赖:" + row.reference.name + (artifactId ? "(已锁定 " + artifactId + ")" : "(待生成/锁定)"); - } - const identityEditor = row.isDefault && row.kind === "character" - ? '" - : ""; - const lockButton = row.isDefault && row.kind === "character" - ? '" - : ""; - return '' - + "
" + escapeHtml(row.label) + "
" + escapeHtml(row.secondaryLabel) + "
" - + '
' + (row.kind === "character" ? "角色" : row.kind === "location" ? "场景" : "道具") + '审查 ' + escapeHtml(current.status) + '执行 ' + escapeHtml(execution) + "
" - + '' + escapeHtml(row.id) + "" - + '
' + escapeHtml(row.description || "待补充视觉需求") + "
" - + "" + identityEditor + '
查看提交时完整提示词
' + escapeHtml(compiledPrompt(row)) + "
" - + '
' + imagePreview + '
' + escapeHtml(referenceText) + "
" - + '
' + lockButton + "
"; -} - -function render() { - const rows = createRows(); - renderSummary(rows); - const query = app.search.trim().toLowerCase(); - const visible = rows.filter((row) => (app.type === "all" || row.kind === app.type) && (!query || [row.label, row.secondaryLabel, row.description, row.id].join(" ").toLowerCase().includes(query))); - body.innerHTML = visible.length ? visible.map(rowHtml).join("") : '没有匹配的资产。'; -} - -function rowById(id) { - return createRows().find((row) => row.id === id); -} - -async function save() { - if (!app.dirty) { - notify("没有需要保存的修改。"); - return; - } - try { - const result = await requestJson("/api/review-decisions", { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ projectId: app.state.project?.id, baseRevision: app.saved.revision ?? 0, decisions: app.pending }) - }); - app.saved = result; - app.pending = {}; - app.dirty = false; - notify("稀疏审查 patch 已保存。"); - render(); - } catch (error) { - notify(error.status === 409 ? "审查数据已被更新,请先重新载入后再保存。" : "保存失败:" + error.message, true); - } -} - -function exportDecisions() { - const data = { schemaVersion: 3, projectId: app.state.project?.id, baseRevision: app.saved.revision ?? 0, decisions: app.pending }; - const blob = new Blob([JSON.stringify(data, null, 2) + "\n"], { type: "application/json" }); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = "review-patch.json"; - link.click(); - URL.revokeObjectURL(url); - notify("已导出当前未保存 patch。"); -} - -async function load(force = false) { - if (app.dirty && !force && !window.confirm("存在未保存修改,确定重新载入吗?")) return; - try { - const [state, saved] = await Promise.all([requestJson("/api/project-state"), requestJson("/api/review-decisions")]); - if (saved.projectId !== state.project?.id) throw new Error("审查文件与当前项目不匹配"); - app.state = state; - app.saved = saved; - app.pending = {}; - app.dirty = false; - title.textContent = (state.project?.title ?? "未命名项目") + " · 资产审查台"; - const style = state.config?.styleProfile?.name ?? "尚未设置美术风格"; - subtitle.textContent = "项目 revision " + (state.revision ?? 0) + " · 风格:" + style + " · 只保存实际改动字段"; - render(); - } catch (error) { - title.textContent = "无法加载审查项目"; - subtitle.textContent = "请通过 review_server.mjs 打开,并检查 project-state.json 与 review-decisions.json。"; - body.innerHTML = '' + escapeHtml(error.message) + ""; - notify("项目数据加载失败。", true); - } -} - -document.querySelector("#type-filters").addEventListener("click", (event) => { - const button = event.target.closest("[data-type]"); - if (!button) return; - app.type = button.dataset.type; - document.querySelectorAll("[data-type]").forEach((item) => item.classList.toggle("active", item === button)); - render(); -}); - -document.querySelector("#search-input").addEventListener("input", (event) => { - app.search = event.target.value; - render(); -}); - -body.addEventListener("input", (event) => { - const input = event.target.closest("[data-field][data-id]"); - if (!input) return; - const row = rowById(input.dataset.id); - if (!row) return; - setPending(row, input.dataset.field, input.dataset.field === "imageUrl" ? input.value.trim() : input.value); -}); - -body.addEventListener("click", (event) => { - const button = event.target.closest("[data-action]"); - if (!button) return; - const row = rowById(button.dataset.id); - if (!row) return; - if (button.dataset.action === "approve") setPending(row, "status", "approved"); - if (button.dataset.action === "revise") setPending(row, "status", "changes_requested"); - if (button.dataset.action === "lock") { - const artifactId = row.asset.image?.artifactId; - if (executionStatus(row.asset) !== "succeeded" || !artifactId || !imageValue(row.asset.image)) { - notify("只有已成功生成且带 artifactId 的默认状态图片可以锁定。", true); - return; - } - setPending(row, "artifactId", artifactId); - setPending(row, "lockedReference", true); - setPending(row, "imageStatus", "approved"); - } - render(); -}); - -document.querySelector("#save-button").addEventListener("click", save); -document.querySelector("#export-button").addEventListener("click", exportDecisions); -document.querySelector("#reload-button").addEventListener("click", () => load()); -window.addEventListener("beforeunload", (event) => { - if (!app.dirty) return; - event.preventDefault(); - event.returnValue = ""; -}); - -load(true); diff --git a/assets/review-app/index.html b/assets/review-app/index.html deleted file mode 100644 index f13d7d9..0000000 --- a/assets/review-app/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - AI 漫剧资产审查台 - - - -
-
-
-

AI COMIC · REVIEW DESK

-

资产审查台

-

加载项目状态中…

-
-
- - - -
-
- -
- -
-
- - - - -
- -
- -
- - - - - - - - - - - -
资产 / 状态视觉需求分层提示词(只编辑差量)图片与参考图(可直接填入)审查 patch
-
-
-
- - - diff --git a/assets/review-app/styles.css b/assets/review-app/styles.css deleted file mode 100644 index 11914a1..0000000 --- a/assets/review-app/styles.css +++ /dev/null @@ -1,126 +0,0 @@ -:root { - color-scheme: light; - font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif; - color: #241e1a; - background: #f4f0e8; - font-synthesis: none; -} - -* { box-sizing: border-box; } - -body { - margin: 0; - min-width: 320px; - background: - radial-gradient(circle at 84% 0%, rgba(211, 164, 88, .16), transparent 28rem), - linear-gradient(120deg, #f8f4ec 0%, #efe9dd 100%); -} - -button, input, textarea { font: inherit; } -button { cursor: pointer; } - -.page-shell { - width: min(100% - 32px, 2100px); - margin: 0 auto; - padding: 36px 0 64px; -} - -.hero { - display: flex; - justify-content: space-between; - gap: 32px; - align-items: end; - padding: 8px 4px 28px; -} - -.eyebrow { - margin: 0 0 7px; - color: #a25c2d; - font-size: 12px; - font-weight: 800; - letter-spacing: .13em; -} - -h1 { margin: 0; font-family: "Songti SC", STSong, serif; font-size: clamp(28px, 3vw, 42px); letter-spacing: .03em; } -.subtitle { margin: 10px 0 0; max-width: 700px; color: #70655d; line-height: 1.65; } - -.header-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; } -.button, .filter, .review-action { - border: 1px solid transparent; - border-radius: 9px; - padding: 9px 13px; - font-weight: 700; - transition: transform .16s ease, background .16s ease, border-color .16s ease; -} -.button:hover, .filter:hover, .review-action:hover { transform: translateY(-1px); } -.button.primary { color: #fffaf2; background: #8e3f23; box-shadow: 0 4px 12px rgba(99, 46, 23, .21); } -.button.secondary { color: #5f4635; border-color: #d2c1ad; background: rgba(255, 252, 246, .7); } - -.summary { display: grid; grid-template-columns: repeat(4, minmax(150px, 1fr)); gap: 12px; margin-bottom: 18px; } -.summary-card { min-height: 94px; padding: 17px 20px; border: 1px solid #e2d8c9; border-radius: 13px; background: rgba(255, 253, 248, .77); box-shadow: 0 9px 24px rgba(86, 60, 39, .05); } -.summary-label { color: #7d6e62; font-size: 13px; } -.summary-number { margin-top: 5px; font-family: "Songti SC", STSong, serif; font-size: 30px; font-weight: 700; } - -.toolbar { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin: 20px 0 12px; } -.filter-group { display: flex; flex-wrap: wrap; gap: 8px; } -.filter { color: #715c4c; border-color: #d9ccbd; background: rgba(255,255,255,.42); } -.filter.active { color: #fffaf4; border-color: #8e3f23; background: #8e3f23; } -.search-field { display: flex; align-items: center; gap: 8px; color: #75675d; font-size: 13px; font-weight: 700; } -.search-field input { width: 270px; border: 1px solid #d9ccbd; border-radius: 8px; padding: 9px 11px; color: #332820; background: rgba(255,255,255,.7); outline: none; } -.search-field input:focus, textarea:focus, .image-url:focus, .note-input:focus { border-color: #aa653d; box-shadow: 0 0 0 3px rgba(170,101,61,.12); } - -.table-shell { overflow-x: auto; border: 1px solid #d8cbb9; border-radius: 15px; background: #fffdf9; box-shadow: 0 16px 36px rgba(78, 51, 34, .09); } -table { width: 100%; min-width: 1760px; border-collapse: separate; border-spacing: 0; } -th { position: sticky; top: 0; z-index: 1; padding: 14px 16px; text-align: left; color: #715a48; border-bottom: 1px solid #d8cbb9; background: #f7f0e5; font-size: 13px; letter-spacing: .04em; } -td { padding: 15px 16px; vertical-align: top; border-bottom: 1px solid #eadfd2; background: rgba(255,253,249,.94); } -tbody tr:last-child td { border-bottom: 0; } -tbody tr:hover td { background: #fffaf1; } -.identity-column { width: 210px; }.brief-column { width: 280px; }.prompt-column { width: 565px; }.image-column { width: 455px; }.review-column { width: 250px; } - -.asset-name { color: #39291f; font-size: 16px; font-weight: 800; } -.state-name { margin-top: 6px; color: #6a594d; font-size: 13px; line-height: 1.45; } -.asset-id { display: inline-block; max-width: 180px; margin-top: 9px; overflow: hidden; color: #9a8778; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; } -.chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; } -.chip { padding: 3px 7px; border-radius: 999px; background: #eee2d1; color: #765338; font-size: 11px; font-weight: 800; } -.chip.status-approved, .chip.status-ready, .chip.status-succeeded { color: #1f6a46; background: #dcefe2; } -.chip.status-changes_requested, .chip.status-failed, .chip.status-blocked { color: #9e3d31; background: #f6dfd7; } -.chip.status-needs_style, .chip.status-needs_review, .chip.status-draft { color: #875d25; background: #f8ebcb; } - -.brief { color: #5e4e43; font-size: 13px; line-height: 1.7; white-space: pre-wrap; } -.muted { color: #9b8d81; } -textarea, .image-url, .note-input { width: 100%; border: 1px solid #d9ccbd; border-radius: 8px; color: #36291f; background: #fffefa; outline: none; } -textarea { min-height: 176px; padding: 11px 12px; resize: vertical; line-height: 1.6; font-size: 13px; } -.field-label { display: block; margin: 0 0 6px; color: #745643; font-size: 11px; font-weight: 800; } -.field-label:not(:first-child) { margin-top: 10px; } -.identity-input { min-height: 108px; background: #fffaf0; } -.delta-input { min-height: 120px; } -.compiled-preview { margin-top: 9px; padding: 8px 10px; border: 1px solid #e2d5c5; border-radius: 8px; color: #725f51; background: #faf7f1; font-size: 12px; line-height: 1.6; } -.compiled-preview summary { cursor: pointer; font-weight: 800; } -.compiled-preview div { margin-top: 7px; white-space: pre-wrap; } -.prompt-empty { border-color: #d4966c; background: #fff8ed; } -.image-stack { display: grid; grid-template-columns: minmax(154px, .75fr) minmax(200px, 1fr); gap: 12px; } -.image-preview { display: grid; min-height: 175px; place-items: center; overflow: hidden; border: 1px dashed #cdbda9; border-radius: 9px; color: #968273; background: #faf6ef; font-size: 12px; text-align: center; } -.image-preview img { width: 100%; height: 100%; min-height: 175px; object-fit: cover; } -.image-details { display: flex; flex-direction: column; gap: 8px; } -.image-url { padding: 8px 9px; font-size: 12px; } -.reference-box { padding: 8px 10px; border-left: 3px solid #bd7c48; border-radius: 4px; color: #715e50; background: #faf0e3; font-size: 12px; line-height: 1.55; word-break: break-all; } -.reference-box strong { color: #714324; } -.note-input { min-height: 60px; padding: 8px 9px; resize: vertical; font-size: 12px; line-height: 1.45; } -.review-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin-top: 9px; } -.review-action { padding: 7px 8px; color: #695244; border-color: #d8c9b6; background: #fffdf9; font-size: 12px; } -.review-action.approve { color: #236641; border-color: #aad5b8; background: #eff9f1; } -.review-action.revise { color: #a34635; border-color: #e4b5a9; background: #fff4f0; } -.review-action.lock { grid-column: 1 / -1; color: #825226; border-color: #dfbf96; background: #fff6e8; } -.empty-row td { padding: 60px; color: #8d7e72; text-align: center; } - -.toast { position: fixed; right: 22px; bottom: 22px; z-index: 4; max-width: 360px; padding: 12px 15px; border-radius: 9px; color: #fffaf2; background: #352820; box-shadow: 0 12px 30px rgba(0,0,0,.2); opacity: 0; transform: translateY(12px); pointer-events: none; transition: opacity .2s ease, transform .2s ease; } -.toast.visible { opacity: 1; transform: translateY(0); } -.toast.error { background: #8a3329; } - -@media (max-width: 760px) { - .page-shell { width: min(100% - 20px, 2100px); padding-top: 24px; } - .hero, .toolbar { align-items: stretch; flex-direction: column; } - .header-actions { justify-content: flex-start; } - .summary { grid-template-columns: repeat(2, 1fr); } - .search-field input { width: min(100%, 280px); } -} diff --git a/assets/setup-app/index.html b/assets/setup-app/index.html index aa90d8e..eb5fdef 100644 --- a/assets/setup-app/index.html +++ b/assets/setup-app/index.html @@ -3,99 +3,12 @@ - 漫剧资产工作台 + 项目初始化 · 漫剧资产 + -
-
-
- - 漫剧资产工作台 -
- -
-

正在读取项目

- - -
-
-
- - - 修改已保存 - -
-
- -
- - -
-
-
-
-

选择一个资产

-
-
-

从左侧列表选择角色、场景或道具。

-
-
-
-
- 暂无资产图片 - 图片生成后会在这里作为主要审视对象展示。 -
-
-
-
- - -
-
- -