@mcptoolshop/style-dataset-lab 2.2.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/README.es.md +76 -144
  3. package/README.fr.md +75 -143
  4. package/README.hi.md +75 -143
  5. package/README.it.md +76 -144
  6. package/README.ja.md +75 -143
  7. package/README.md +36 -8
  8. package/README.pt-BR.md +75 -143
  9. package/README.zh.md +76 -144
  10. package/SECURITY.md +3 -1
  11. package/bin/sdlab.js +146 -17
  12. package/lib/adapters/comfyui-runner.js +170 -0
  13. package/lib/adapters/comfyui-workflows.js +163 -0
  14. package/lib/batch-compiler.js +118 -0
  15. package/lib/batch-modes.js +111 -0
  16. package/lib/batch-runs.js +168 -0
  17. package/lib/batch-sheet-render.js +206 -0
  18. package/lib/brief-compiler.js +598 -0
  19. package/lib/brief-render.js +205 -0
  20. package/lib/critique-engine.js +413 -0
  21. package/lib/critique-render.js +171 -0
  22. package/lib/errors.js +82 -0
  23. package/lib/generated-provenance.js +87 -0
  24. package/lib/log.js +36 -0
  25. package/lib/paths.js +31 -0
  26. package/lib/refine-briefs.js +329 -0
  27. package/lib/reingest-selected.js +173 -0
  28. package/lib/run-summary.js +131 -0
  29. package/lib/runtime-runs.js +168 -0
  30. package/lib/selections.js +323 -0
  31. package/lib/snapshot.js +5 -2
  32. package/lib/split.js +5 -2
  33. package/lib/workflow-profiles.js +161 -0
  34. package/package.json +8 -6
  35. package/scripts/batch-generate.js +167 -0
  36. package/scripts/batch-sheet.js +46 -0
  37. package/scripts/batch-show.js +86 -0
  38. package/scripts/brief-compile.js +134 -0
  39. package/scripts/brief-show.js +52 -0
  40. package/scripts/critique-show.js +50 -0
  41. package/scripts/critique.js +70 -0
  42. package/scripts/doctor.js +169 -1
  43. package/scripts/init.js +22 -0
  44. package/scripts/refine.js +119 -0
  45. package/scripts/reingest-selected.js +78 -0
  46. package/scripts/reingest.js +7 -1
  47. package/scripts/run-generate.js +76 -0
  48. package/scripts/run-list.js +58 -0
  49. package/scripts/run-show.js +63 -0
  50. package/scripts/select.js +118 -0
  51. package/scripts/selection-show.js +88 -0
  52. package/scripts/snapshot.js +27 -23
  53. package/scripts/split.js +3 -1
  54. package/scripts/workflow-list.js +61 -0
  55. package/scripts/workflow-show.js +96 -0
  56. package/templates/domains/architecture/workflows/profiles/environment-moodboard.json +62 -0
  57. package/templates/domains/architecture/workflows/profiles/interior-variant-pack.json +60 -0
  58. package/templates/domains/character-design/workflows/profiles/character-portrait-set.json +61 -0
  59. package/templates/domains/character-design/workflows/profiles/expression-sheet.json +59 -0
  60. package/templates/domains/creature-design/workflows/profiles/creature-portrait-set.json +61 -0
  61. package/templates/domains/creature-design/workflows/profiles/silhouette-exploration.json +58 -0
  62. package/templates/domains/game-art/workflows/profiles/character-portrait-set.json +62 -0
  63. package/templates/domains/game-art/workflows/profiles/environment-moodboard.json +61 -0
  64. package/templates/domains/vehicle-mech/workflows/profiles/variant-pack.json +60 -0
  65. package/templates/domains/vehicle-mech/workflows/profiles/vehicle-silhouette-pack.json +59 -0
package/README.zh.md CHANGED
@@ -11,196 +11,128 @@
11
11
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License"></a>
12
12
  </p>
13
13
 
14
- # style-dataset-lab
14
+ 编写您的视觉规则。生成艺术作品。根据这些规则评估每张图像。将结果作为版本控制的、可审计的训练数据发布。
15
15
 
16
- 将已批准的视觉素材转化为版本控制、经过审核的数据集、分片、导出包和评估包。
16
+ Style Dataset Lab 将您关于艺术风格的描述与实际用于训练的数据集联系起来。您定义一套规范,包括轮廓规则、调色板限制、材质语言,以及对您的项目而言重要的任何内容。流水线生成候选作品,根据这些规则对其进行评分,并将通过的成果打包成可重复的数据集,其中每个记录都解释了它被包含的原因。
17
17
 
18
- ## 这是什么
18
+ 循环闭合:训练一个模型,生成新的输出,根据相同的标准对其进行评分,并将通过的作品重新导入。数据集不断增长,规则始终有效。
19
19
 
20
- 一个用于视觉数据规范和数据集生成的**流水线**。明确您的项目外观。根据既定规则进行筛选。生成可重复的数据集包,并确保数据分割的安全性。生成评估数据集,用于未来模型的验证。
21
-
22
- 流水线会生成四个产出物:
23
-
24
- | 文物。 | 它是什么。 |
25
- |----------|-----------|
26
- | **Snapshot** | 经过筛选,符合条件的记录已冻结,并进行了指纹识别。所有被选入的记录都有明确的纳入理由。 |
27
- | **Split** | 安全的训练/验证/测试数据集划分,防止数据泄露。共享相同主题的数据记录始终会被划分到同一个子集。 |
28
- | **Export package** | 自包含的数据集:包含清单、元数据、图像、数据集划分、数据集描述文档以及校验和。 |
29
- | **Eval pack** | 符合佳能标准的验证任务包括:车道覆盖、禁止漂移、锚点/黄金区域、主体连续性。 |
30
-
31
- 流水线中的每个资产都包含以下三个要素:
32
-
33
- 1. **来源信息** -- 完整的生成历史记录(检查点、LoRA、种子、采样器、配置参数、生成时间)。
34
- 2. **合规性** -- 指示该资产是否符合相关规定,以及是否完全符合、不符合或部分符合。
35
- 3. **质量评估** -- 采用每维度的评分标准,对质量进行评估,结果分为:通过/未通过/临界。
36
-
37
- 主要从事游戏美术、角色设计、生物设计、建筑设计、车辆/机械概念设计等工作,以及任何需要保持视觉风格一致性的领域。
38
-
39
- ## 快速入门
20
+ ## 流水线
40
21
 
41
22
  ```bash
42
- # Install the CLI + pipeline
43
- npm install -g @mcptoolshop/style-dataset-lab
44
-
45
- # Scaffold a new project
23
+ # Write your canon. Scaffold the project.
46
24
  sdlab init my-project --domain character-design
47
25
 
48
- # Validate the project structure
49
- sdlab project doctor --project my-project
50
- ```
26
+ # Generate candidates via ComfyUI, then review them
27
+ sdlab generate inputs/prompts/wave1.json --project my-project
28
+ sdlab curate <id> approved "Strong silhouette, correct faction palette"
51
29
 
52
- 可用的领域包括:`game-art`(游戏美术)、`character-design`(角色设计)、`creature-design`(生物设计)、`architecture`(架构)、`vehicle-mech`(车辆机械设计)或`generic`(通用)。
30
+ # Bind approved work to constitution rules
31
+ sdlab bind --project my-project
53
32
 
54
- ## 命令行界面
33
+ # Freeze a versioned dataset
34
+ sdlab snapshot create --project my-project
35
+ sdlab split build
36
+ sdlab export build
55
37
 
56
- ```bash
57
- sdlab init <name> [--domain <domain>] # Scaffold a new project
58
- sdlab project doctor [--project <name>] # Validate project config
59
-
60
- sdlab generate <pack> [--project <name>] # Generate candidates via ComfyUI
61
- sdlab generate:identity <packet> # Named-subject identity images
62
- sdlab generate:controlnet # ControlNet-guided generation
63
- sdlab generate:ipadapter # IP-Adapter reference-guided
64
-
65
- sdlab curate <id> <status> <explanation> # Record review judgment
66
- sdlab compare <a> <b> <winner> <reason> # Pairwise A-vs-B comparison
67
- sdlab bind [--project <name>] # Bind records to constitution rules
68
- sdlab painterly [--project <name>] # Post-processing style pass
69
-
70
- sdlab snapshot create [--profile <name>] # Create frozen dataset snapshot
71
- sdlab snapshot list # List all snapshots
72
- sdlab snapshot diff <a> <b> # Compare two snapshots
73
- sdlab eligibility audit # Audit record training eligibility
74
- sdlab split build [--snapshot <id>] # Build train/val/test split
75
- sdlab split audit <id> # Audit split for leakage + balance
76
- sdlab card generate # Generate dataset card (md + JSON)
77
- sdlab export build [--snapshot <id>] # Build versioned export package
78
- sdlab eval-pack build # Build canon-aware eval pack
38
+ # Build a training package and close the loop
39
+ sdlab training-manifest create --profile character-style-lora
40
+ sdlab training-package build
41
+ sdlab eval-run create && sdlab eval-run score <id> --outputs results.jsonl
42
+ sdlab reingest generated --source ./outputs --manifest <id>
79
43
  ```
80
44
 
81
- 所有命令都支持 `--project <名称>` 参数,默认值为 `star-freight`。
45
+ 那个最后的命令至关重要。生成的输出会经过与所有其他内容相同的审查流程。循环闭合。
82
46
 
83
- ## 项目模型
47
+ ## 它产生的内容
84
48
 
85
- 每个项目都位于 `projects/` 目录下,作为一个独立的目录,拥有自己的规范、配置文件和数据。
49
+ 七个版本控制的、具有校验和的成果。每个成果都链接到其前身,因此您可以追溯任何训练记录,了解它是根据哪个规则被批准的。
86
50
 
87
- ```
88
- projects/
89
- my-project/
90
- project.json Project identity + generation defaults
91
- constitution.json Rules array with rationale templates
92
- lanes.json Subject lanes with detection patterns
93
- rubric.json Scoring dimensions + thresholds
94
- terminology.json Group vocabulary + detection order
95
- canon/ Style constitution (markdown)
96
- records/ Per-asset JSON (provenance + judgment + canon)
97
- inputs/prompts/ Prompt packs (JSON)
98
- outputs/ Generated images (gitignored)
99
- comparisons/ A-vs-B preference judgments
100
- snapshots/ Frozen dataset snapshots
101
- splits/ Train/val/test partitions
102
- exports/ Versioned export packages
103
- eval-packs/ Canon-aware eval instruments
104
- ```
51
+ | 成果 | 它的定义 |
52
+ |----------|-----------|
53
+ | **Snapshot** | 带有配置指纹的冻结记录选择。每个包含项都有明确的理由。 |
54
+ | **Split** | 训练/验证/测试数据集,其中主题类别之间绝不交叉。 |
55
+ | **Export package** | 自包含的数据集:清单、元数据、图像、数据集划分、数据集描述、校验和。 |
56
+ | **Eval pack** | 与规范相关的测试任务:覆盖范围、避免偏差、锚定/黄金标准、主题连续性。 |
57
+ | **Training package** | 通过适配器(`diffusers-lora`、`generic-image-caption`)提供可供训练器使用的布局。相同的真理,不同的格式。 |
58
+ | **Eval scorecard** | 每个任务的通过/失败结果,基于生成的输出与评估包的比较。 |
59
+ | **Implementation pack** | 提示示例、已知的失败案例、连续性测试以及重新导入指南。 |
105
60
 
106
- ## 流水线
61
+ ## 存在的理由
107
62
 
108
- ```
109
- canon → generate → curate → bind → snapshot → split → export → eval
110
- | | | | | | | |
111
- rules ComfyUI judgment rules frozen subject package verify
112
- selection isolation
113
- ```
63
+ 训练数据是任何视觉人工智能流水线中最具价值的资源。但大多数训练数据只是一个包含图像的文件夹,没有任何历史记录、评估记录,以及与它应该遵循的风格规则的联系。
114
64
 
115
- 1. **定义规范**:编写您的风格指南和评估标准。
116
- 2. **生成**:ComfyUI 生成具有完整溯源信息的候选结果。
117
- 3. **筛选**:根据每个维度的评分和失败模式,进行批准/拒绝。
118
- 4. **关联**:将每个资源与规范规则关联,并给出通过/失败/部分通过的判定。
119
- 5. **快照**:将符合条件的记录冻结为具有确定性和唯一标识的选择。
120
- 6. **划分**:划分为训练集/验证集/测试集,同时进行主题隔离和类别平衡。
121
- 7. **导出**:构建一个独立的软件包,包含清单、元数据、图像和校验和。
122
- 8. **评估**:生成符合规范要求的测试工具,用于模型验证。
65
+ Style Dataset Lab 明确地建立了这种联系。您的规范定义了规则。您的评分标准定义了评分维度。您的筛选记录记录了评估结果。您的规范证明了这种联系。您的数据集将所有这些信息以结构化、可查询、可重复的方式传递下去。
123
66
 
124
- 下游格式转换(例如:TRL、LLaVA、Parquet等)由[`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 负责。`sdlab` 拥有数据集的原始数据,而 `repo-dataset` 将其转换为各种特定格式。
67
+ 实际结果:当您的 LoRA 出现偏差时,您可以询问*原因*。当您的下一个训练轮需要更好的数据时,您清楚地知道哪些记录是接近理想的,以及它们违反了哪个规则。当新团队成员询问项目的视觉语言是什么时,答案不是一个 Figma 板,而是一份包含 1182 个已评分示例的可搜索规范。
125
68
 
126
- ## 域名模板
69
+ ## 五个领域,真实的规则
127
70
 
128
- 每个领域模板都包含针对特定生产环境设计的车道定义、规则、评分标准和术语结构。
71
+ 不是占位符模板。每个领域都包含生产级别的规范规则、定义、评分标准和词汇表。
129
72
 
130
- | 域名。 | 车道。 | 主要关注点。 |
131
- |--------|-------|-------------|
132
- | **game-art** | 角色、环境、道具、用户界面、飞船、内部、设备。 | 游戏中的角色轮廓、阵营区分、以及磨损/老化效果。 |
133
- | **character-design** | 人像、全身照、360度展示图、表情图、动作姿势图。 | 比例准确性、服装的合理性、人物性格的刻画、动作的清晰度。 |
134
- | **creature-design** | 概念、正字法、详细研究、动作、比例参考、栖息地。 | 解剖学上的合理性、进化逻辑、轮廓的独特性。 |
135
- | **architecture** | 外观、内部、街道景观、结构细节、废墟、景观。 | 结构合理性、材料一致性、视角、时代背景的协调性。 |
136
- | **vehicle-mech** | 外观、驾驶舱、部件、示意图、轮廓图、损坏类型。 | 机械逻辑,功能性设计语言,访问点,损坏描述。 |
73
+ | 领域 | 定义 | 评估内容 |
74
+ |--------|-------|-----------------|
75
+ | **game-art** | 角色、环境、道具、UI、飞船、内部、设备 | 游戏场景中的轮廓、派系特征、磨损和老化 |
76
+ | **character-design** | 人像、全身照、旋转视图、表情图、动作姿势 | 比例、服装逻辑、个性、姿势清晰度 |
77
+ | **creature-design** | 概念图、正交视图、细节研究、动作、比例参考、栖息地 | 解剖结构、进化逻辑、轮廓区分 |
78
+ | **architecture** | 外部、内部、街道景观、结构细节、废墟、景观 | 结构、材质一致性、透视、时代一致性 |
79
+ | **vehicle-mech** | 外部、驾驶舱、组件、示意图、轮廓图、损坏变体 | 机械逻辑、设计语言、访问点、损坏叙述 |
137
80
 
138
- ## 数据集生成
81
+ ## 项目结构
139
82
 
140
- 完整的数据集流程:快照、分割、导出、评估。
83
+ 每个项目都是独立的。五个 JSON 配置文件定义了规则;其他所有内容都是数据。
141
84
 
142
85
  ```
143
- snapshot --> split --> export --> eval-pack
144
- | | | |
145
- frozen subject package canon-aware
146
- selection isolation (manifest, test instruments
147
- + lane metadata, (4 task types)
148
- balance images,
149
- checksums,
150
- card)
86
+ projects/my-project/
87
+ project.json Identity + generation defaults
88
+ constitution.json Rules with rationale templates
89
+ lanes.json Subject lanes with detection patterns
90
+ rubric.json Scoring dimensions + thresholds
91
+ terminology.json Group vocabulary + detection order
92
+ records/ Per-asset JSON (provenance + judgment + canon)
93
+ snapshots/ Frozen dataset snapshots
94
+ splits/ Train/val/test partitions
95
+ exports/ Versioned export packages
96
+ training/ Profiles, manifests, packages, eval runs, implementations
151
97
  ```
152
98
 
153
- **快照**:冻结符合条件的记录的确定性选择。每个包含记录都有其原因的追踪。配置指纹确保可重复性。
154
-
155
- **分割**:将记录分配到训练集/验证集/测试集,同时保证样本隔离(同一个样本家族不会出现在多个分割中),并实现通道平衡的分布。使用种子伪随机数生成器,确保从相同的种子生成相同的结果。
156
-
157
- **导出包**:是自包含的:清单、metadata.jsonl、图像(符号链接或复制)、分割、数据集卡(Markdown + JSON)以及 BSD 格式的校验和。 包含重建数据集所需的所有内容。
99
+ ## 信任属性
158
100
 
159
- **评估包**:是考虑规范的测试工具,包含四种任务类型:通道覆盖、禁止漂移、锚定/黄金标准、以及样本连续性。 它们证明数据集流程正在为未来的模型评估提供支持,而不仅仅是导出文件。
101
+ 这些不是理想化的目标,而是强制执行的。
160
102
 
161
- 通过 [`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 导出到下游格式(TRL, LLaVA, Qwen2-VL, JSONL, Parquet 等)。 `repo-dataset` 负责格式转换;`sdlab` 负责数据集的真实性。
103
+ - **快照是不可变的。** 配置文件指纹(SHA-256)可以证明没有发生任何更改。
104
+ - **分片可以防止数据泄露。** 按照身份、血统或 ID 后缀划分的主体类别永远不会跨越分区边界。
105
+ - **清单是冻结的合同。** 导出哈希值 + 配置文件指纹。如果任何内容发生更改,请创建一个新的清单。
106
+ - **适配器不能修改原始数据。** 不同的布局,相同的记录。不允许添加、删除或重新分类。
107
+ - **生成的输出需要经过审核才能重新使用。** 不允许绕过。像其他内容一样,进行筛选和绑定。
162
108
 
163
- ## Star Freight 示例
109
+ ## Star Freight
164
110
 
165
- 克隆仓库以获取完整的示例:1182 条记录,28 个提示序列,5 个派系,7 个通道,24 条宪法规则,以及来自一个硬核科幻角色扮演游戏的 892 个已批准的资源。
111
+ 该仓库包含一个完整的示例:1182 条记录,5 个派系,7 条路线,24 条宪法规则,892 个已批准的资源,2 个训练配置文件。这是一个充满科幻感的角色扮演游戏视觉素材库,经过完整的筛选。
166
112
 
167
113
  ```bash
168
114
  git clone https://github.com/mcp-tool-shop-org/style-dataset-lab
169
115
  cd style-dataset-lab
170
-
171
- # Validate the project
172
116
  sdlab project doctor --project star-freight
173
-
174
- # Run the full dataset spine
175
- sdlab snapshot create --project star-freight # 839 eligible records
176
- sdlab split build --project star-freight # ~80/10/10, zero leakage
177
- sdlab export build --project star-freight # package with checksums
178
- sdlab eval-pack build --project star-freight # 78 eval records
117
+ sdlab snapshot create --project star-freight # 839 eligible records
118
+ sdlab split build --project star-freight # zero subject leakage
179
119
  ```
180
120
 
181
- ## 从 v1.x 迁移
121
+ ## 下游格式
182
122
 
183
- v2.0 将 `games/` 重命名为 `projects/`,并将 `--game` 重命名为 `--project`。
123
+ `sdlab` 拥有数据集。格式转换由 [`repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 处理:支持 TRL、LLaVA、Qwen2-VL、JSONL、Parquet 等格式。`repo-dataset` 用于渲染,但不决定数据的包含与否。
184
124
 
185
- ```bash
186
- # Rename your data directory
187
- mv games projects
125
+ ## 安装
188
126
 
189
- # --game still works with a deprecation warning (removed in v3.0)
190
- sdlab bind --game star-freight # works, prints warning
191
- sdlab bind --project star-freight # canonical form
127
+ ```bash
128
+ npm install -g @mcptoolshop/style-dataset-lab
192
129
  ```
193
130
 
194
- ## 安全模型
195
-
196
- **仅本地。** 与运行在 `localhost:8188` 上的 ComfyUI 通信。 没有遥测,没有分析,没有外部请求。 图像保留在您的 GPU 和文件系统中。
131
+ 需要 Node.js 20+ 以及安装在本地主机 8188 端口上的 [ComfyUI](https://github.com/comfyanonymous/ComfyUI) 才能进行生成。
197
132
 
198
- ## 要求
133
+ ## 安全性
199
134
 
200
- - 运行在 `localhost:8188` 上的 [ComfyUI](https://github.com/comfyanonymous/ComfyUI)
201
- - DreamShaper XL Turbo 检查点 + ClassipeintXL LoRA
202
- - Node.js 20+
203
- - [`@mcptoolshop/repo-dataset`](https://github.com/mcp-tool-shop-org/repo-dataset) 用于训练数据导出
135
+ 仅在本地运行。没有遥测数据,没有分析,没有外部请求。图像保留在您的 GPU 和文件系统中。
204
136
 
205
137
  ## 许可证
206
138
 
package/SECURITY.md CHANGED
@@ -4,7 +4,9 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |---------|-----------|
7
- | 0.x | Yes |
7
+ | 2.x | Yes |
8
+ | 1.x | No |
9
+ | 0.x | No |
8
10
 
9
11
  ## Threat Model
10
12
 
package/bin/sdlab.js CHANGED
@@ -7,6 +7,9 @@
7
7
  * Each script exports run(argv) and is lazy-loaded on demand.
8
8
  */
9
9
 
10
+ import { enableDebug, handleCliError, inputError } from '../lib/errors.js';
11
+ import { setLogLevel } from '../lib/log.js';
12
+
10
13
  const COMMANDS = {
11
14
  'init': '../scripts/init.js',
12
15
  'generate': '../scripts/generate.js',
@@ -40,6 +43,42 @@ const PROJECT_COMMANDS = {
40
43
  'migrate': '../scripts/migrate-records.js',
41
44
  };
42
45
 
46
+ // Two-word commands under "workflow" namespace
47
+ const WORKFLOW_COMMANDS = {
48
+ 'list': '../scripts/workflow-list.js',
49
+ 'show': '../scripts/workflow-show.js',
50
+ };
51
+
52
+ // Two-word commands under "brief" namespace
53
+ const BRIEF_COMMANDS = {
54
+ 'compile': '../scripts/brief-compile.js',
55
+ 'show': '../scripts/brief-show.js',
56
+ };
57
+
58
+ // Two-word commands under "run" namespace
59
+ const RUN_COMMANDS = {
60
+ 'generate': '../scripts/run-generate.js',
61
+ 'show': '../scripts/run-show.js',
62
+ 'list': '../scripts/run-list.js',
63
+ };
64
+
65
+ // Two-word commands under "critique" namespace
66
+ const CRITIQUE_COMMANDS = {
67
+ 'show': '../scripts/critique-show.js',
68
+ };
69
+
70
+ // Two-word commands under "batch" namespace
71
+ const BATCH_COMMANDS = {
72
+ 'generate': '../scripts/batch-generate.js',
73
+ 'show': '../scripts/batch-show.js',
74
+ 'sheet': '../scripts/batch-sheet.js',
75
+ };
76
+
77
+ // Two-word commands under "selection" namespace
78
+ const SELECTION_COMMANDS = {
79
+ 'show': '../scripts/selection-show.js',
80
+ };
81
+
43
82
  function printHelp() {
44
83
  console.log(`\x1b[1msdlab\x1b[0m — Style Dataset Lab CLI\n`);
45
84
  console.log('Usage: sdlab <command> [options]\n');
@@ -96,21 +135,49 @@ function printHelp() {
96
135
  console.log(' reingest generated --source <dir> Re-ingest generated outputs');
97
136
  console.log(' reingest audit Audit re-ingested record status');
98
137
  console.log('');
138
+ console.log('Production:');
139
+ console.log(' workflow list List workflow profiles');
140
+ console.log(' workflow show <id> Show workflow profile details');
141
+ console.log(' brief compile Compile generation brief from project truth');
142
+ console.log(' brief show <id> Show compiled brief');
143
+ console.log(' run generate --brief <id> Execute brief through ComfyUI');
144
+ console.log(' run show <id> Show run details');
145
+ console.log(' run list List all runs');
146
+ console.log(' critique --run <id> Critique a completed run');
147
+ console.log(' critique show --run <id> Show saved critique');
148
+ console.log(' refine --run <id> --pick <file> Generate refined next-pass brief');
149
+ console.log(' batch generate --mode <id> Execute a batch production mode');
150
+ console.log(' batch show [batch-id] List batches or show details');
151
+ console.log(' batch sheet <batch-id> Re-render batch sheet from manifest');
152
+ console.log(' select --run <id> --approve <files> Select approved outputs from a run');
153
+ console.log(' select --batch <id> --approve ... Select approved outputs from a batch');
154
+ console.log(' selection show [selection-id] List selections or show details');
155
+ console.log(' reingest selected --selection <id> Re-ingest selected outputs as records');
156
+ console.log('');
99
157
  console.log('Options:');
100
158
  console.log(' --project <name> Project to operate on (default: star-freight)');
101
159
  console.log(' --game <name> Deprecated alias for --project');
160
+ console.log(' --debug Show stack traces on error');
161
+ console.log(' --verbose Verbose output');
162
+ console.log(' --quiet Suppress non-essential output');
163
+ console.log(' --dry-run Preview changes without writing (where supported)');
102
164
  console.log(' --help Show this help');
103
165
  console.log('');
104
166
  console.log('Examples:');
105
167
  console.log(' sdlab init my-project --domain character-design');
106
- console.log(' sdlab generate inputs/prompts/wave1.json --project star-freight');
107
- console.log(' sdlab bind --stats --project star-freight');
108
- console.log(' sdlab project doctor --project star-freight');
168
+ console.log(' sdlab snapshot create --project star-freight');
169
+ console.log(' sdlab split build --dry-run --project star-freight');
170
+ console.log(' sdlab training-package build --debug --project star-freight');
109
171
  }
110
172
 
111
173
  async function main() {
112
174
  const args = process.argv.slice(2);
113
175
 
176
+ // Global flags
177
+ if (args.includes('--debug')) enableDebug();
178
+ if (args.includes('--verbose')) setLogLevel('verbose');
179
+ if (args.includes('--quiet')) setLogLevel('quiet');
180
+
114
181
  if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
115
182
  printHelp();
116
183
  process.exit(0);
@@ -123,30 +190,92 @@ async function main() {
123
190
  if (command === 'project' && args[1] && PROJECT_COMMANDS[args[1]]) {
124
191
  commandArgs = args.slice(2);
125
192
  const modulePath = PROJECT_COMMANDS[args[1]];
126
- try {
193
+ const mod = await import(modulePath);
194
+ await mod.run(commandArgs);
195
+ return;
196
+ }
197
+
198
+ // Handle "workflow <subcommand>" two-word form
199
+ if (command === 'workflow' && args[1] && WORKFLOW_COMMANDS[args[1]]) {
200
+ commandArgs = args.slice(2);
201
+ const modulePath = WORKFLOW_COMMANDS[args[1]];
202
+ const mod = await import(modulePath);
203
+ await mod.run(commandArgs);
204
+ return;
205
+ }
206
+
207
+ // Handle "brief <subcommand>" two-word form
208
+ if (command === 'brief' && args[1] && BRIEF_COMMANDS[args[1]]) {
209
+ commandArgs = args.slice(2);
210
+ const modulePath = BRIEF_COMMANDS[args[1]];
211
+ const mod = await import(modulePath);
212
+ await mod.run(commandArgs);
213
+ return;
214
+ }
215
+
216
+ // Handle "run <subcommand>" two-word form
217
+ if (command === 'run' && args[1] && RUN_COMMANDS[args[1]]) {
218
+ commandArgs = args.slice(2);
219
+ const modulePath = RUN_COMMANDS[args[1]];
220
+ const mod = await import(modulePath);
221
+ await mod.run(commandArgs);
222
+ return;
223
+ }
224
+
225
+ // Handle "critique" — bare or "critique show" two-word form
226
+ if (command === 'critique') {
227
+ if (args[1] && CRITIQUE_COMMANDS[args[1]]) {
228
+ commandArgs = args.slice(2);
229
+ const modulePath = CRITIQUE_COMMANDS[args[1]];
127
230
  const mod = await import(modulePath);
128
231
  await mod.run(commandArgs);
129
- } catch (err) {
130
- console.error(`\x1b[31mError:\x1b[0m ${err.message}`);
131
- process.exit(1);
232
+ return;
132
233
  }
234
+ // Bare "critique" → generate critique
235
+ const mod = await import('../scripts/critique.js');
236
+ await mod.run(commandArgs);
133
237
  return;
134
238
  }
135
239
 
136
- const modulePath = COMMANDS[command];
137
- if (!modulePath) {
138
- console.error(`Unknown command: ${command}`);
139
- console.error(`Run "sdlab --help" for available commands.`);
140
- process.exit(1);
240
+ // Handle "refine" — single command
241
+ if (command === 'refine') {
242
+ const mod = await import('../scripts/refine.js');
243
+ await mod.run(commandArgs);
244
+ return;
245
+ }
246
+
247
+ // Handle "batch <subcommand>" two-word form
248
+ if (command === 'batch' && args[1] && BATCH_COMMANDS[args[1]]) {
249
+ commandArgs = args.slice(2);
250
+ const modulePath = BATCH_COMMANDS[args[1]];
251
+ const mod = await import(modulePath);
252
+ await mod.run(commandArgs);
253
+ return;
254
+ }
255
+
256
+ // Handle "select" — single command
257
+ if (command === 'select') {
258
+ const mod = await import('../scripts/select.js');
259
+ await mod.run(commandArgs);
260
+ return;
141
261
  }
142
262
 
143
- try {
263
+ // Handle "selection <subcommand>" two-word form
264
+ if (command === 'selection' && args[1] && SELECTION_COMMANDS[args[1]]) {
265
+ commandArgs = args.slice(2);
266
+ const modulePath = SELECTION_COMMANDS[args[1]];
144
267
  const mod = await import(modulePath);
145
268
  await mod.run(commandArgs);
146
- } catch (err) {
147
- console.error(`\x1b[31mError:\x1b[0m ${err.message}`);
148
- process.exit(1);
269
+ return;
149
270
  }
271
+
272
+ const modulePath = COMMANDS[command];
273
+ if (!modulePath) {
274
+ throw inputError('INPUT_UNKNOWN_COMMAND', `Unknown command: ${command}`, 'Run "sdlab --help" for available commands.');
275
+ }
276
+
277
+ const mod = await import(modulePath);
278
+ await mod.run(commandArgs);
150
279
  }
151
280
 
152
- main();
281
+ main().catch(handleCliError);