@laitszkin/apollo-toolkit 4.1.4 → 5.0.1
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.
- package/CHANGELOG.md +45 -0
- package/bin/apollo-toolkit.ts +4 -0
- package/dist/bin/apollo-toolkit.js +4 -0
- package/package.json +3 -2
- package/packages/cli/dist/help-text-builder.d.ts +23 -0
- package/packages/cli/dist/help-text-builder.js +166 -0
- package/packages/cli/dist/index.d.ts +6 -17
- package/packages/cli/dist/index.js +52 -246
- package/packages/cli/dist/installer.d.ts +1 -0
- package/packages/cli/dist/installer.js +20 -7
- package/packages/cli/dist/parsers/install-parser.d.ts +15 -0
- package/packages/cli/dist/parsers/install-parser.js +87 -0
- package/packages/cli/dist/parsers/parser-utils.d.ts +9 -0
- package/packages/cli/dist/parsers/parser-utils.js +16 -0
- package/packages/cli/dist/parsers/tool-parser.d.ts +16 -0
- package/packages/cli/dist/parsers/tool-parser.js +58 -0
- package/packages/cli/dist/parsers/types.d.ts +50 -0
- package/packages/cli/dist/parsers/types.js +1 -0
- package/packages/cli/dist/parsers/uninstall-parser.d.ts +15 -0
- package/packages/cli/dist/parsers/uninstall-parser.js +67 -0
- package/packages/cli/dist/tool-registration.d.ts +2 -0
- package/packages/cli/dist/tool-registration.js +2 -0
- package/packages/cli/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/cli/dist/types.d.ts +3 -1
- package/packages/cli/dist/updater.js +11 -5
- package/packages/cli/help-text-builder.ts +180 -0
- package/packages/cli/index.ts +59 -251
- package/packages/cli/installer.ts +19 -7
- package/packages/cli/package.json +14 -4
- package/packages/cli/parsers/install-parser.ts +94 -0
- package/packages/cli/parsers/parser-utils.ts +17 -0
- package/packages/cli/parsers/tool-parser.ts +65 -0
- package/packages/cli/parsers/types.ts +56 -0
- package/packages/cli/parsers/uninstall-parser.ts +75 -0
- package/packages/cli/tool-registration.ts +3 -0
- package/packages/cli/types.ts +6 -1
- package/packages/cli/updater.ts +11 -5
- package/packages/tool-registry/dist/registry.js +3 -4
- package/packages/tool-registry/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tool-registry/dist/types.d.ts +2 -9
- package/packages/tool-registry/package.json +11 -4
- package/packages/tool-registry/registry.ts +3 -4
- package/packages/tool-registry/tsconfig.json +6 -2
- package/packages/tool-registry/types.ts +3 -9
- package/packages/tool-utils/app-error.ts +97 -0
- package/packages/tool-utils/dist/app-error.d.ts +49 -0
- package/packages/tool-utils/dist/app-error.js +80 -0
- package/packages/tool-utils/dist/index.d.ts +5 -0
- package/packages/tool-utils/dist/index.js +3 -0
- package/packages/tool-utils/dist/platform-adapter.d.ts +48 -0
- package/packages/tool-utils/dist/platform-adapter.js +73 -0
- package/packages/tool-utils/dist/schema.d.ts +68 -0
- package/packages/tool-utils/dist/schema.js +67 -0
- package/packages/tool-utils/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tool-utils/index.ts +12 -0
- package/packages/tool-utils/package.json +11 -4
- package/packages/tool-utils/platform-adapter.ts +112 -0
- package/packages/tool-utils/schema.ts +122 -0
- package/packages/tools/architecture/dist/index.d.ts +13 -0
- package/packages/tools/architecture/dist/index.js +55 -57
- package/packages/tools/architecture/dist/index.test.js +17 -4
- package/packages/tools/architecture/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/architecture/index.test.ts +27 -14
- package/packages/tools/architecture/index.ts +85 -88
- package/packages/tools/architecture/package.json +11 -4
- package/packages/tools/codegraph/dist/index.js +12 -22
- package/packages/tools/codegraph/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/codegraph/index.ts +13 -22
- package/packages/tools/codegraph/package.json +11 -4
- package/packages/tools/create-review-report/dist/index.d.ts +1 -2
- package/packages/tools/create-review-report/dist/index.js +46 -77
- package/packages/tools/create-review-report/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/create-review-report/index.ts +52 -81
- package/packages/tools/create-review-report/package.json +11 -4
- package/packages/tools/create-specs/dist/index.d.ts +1 -2
- package/packages/tools/create-specs/dist/index.js +70 -123
- package/packages/tools/create-specs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/create-specs/index.ts +82 -128
- package/packages/tools/create-specs/package.json +11 -4
- package/packages/tools/docs-to-voice/dist/index.d.ts +1 -2
- package/packages/tools/docs-to-voice/dist/index.js +116 -219
- package/packages/tools/docs-to-voice/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/docs-to-voice/index.ts +265 -385
- package/packages/tools/docs-to-voice/package.json +11 -4
- package/packages/tools/enforce-video-aspect-ratio/dist/index.d.ts +1 -2
- package/packages/tools/enforce-video-aspect-ratio/dist/index.js +77 -154
- package/packages/tools/enforce-video-aspect-ratio/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/enforce-video-aspect-ratio/index.ts +87 -172
- package/packages/tools/enforce-video-aspect-ratio/package.json +11 -4
- package/packages/tools/eval/dist/index.js +7 -0
- package/packages/tools/eval/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/eval/index.ts +8 -0
- package/packages/tools/eval/package.json +11 -4
- package/packages/tools/extract-conversations/dist/index.d.ts +1 -2
- package/packages/tools/extract-conversations/dist/index.js +31 -29
- package/packages/tools/extract-conversations/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/extract-conversations/index.ts +37 -30
- package/packages/tools/extract-conversations/package.json +11 -4
- package/packages/tools/extract-pdf-text/dist/index.d.ts +1 -2
- package/packages/tools/extract-pdf-text/dist/index.js +44 -65
- package/packages/tools/extract-pdf-text/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/extract-pdf-text/index.ts +55 -74
- package/packages/tools/extract-pdf-text/package.json +11 -4
- package/packages/tools/filter-logs/dist/index.js +60 -84
- package/packages/tools/filter-logs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/filter-logs/index.ts +67 -97
- package/packages/tools/filter-logs/package.json +11 -4
- package/packages/tools/find-github-issues/dist/index.d.ts +10 -0
- package/packages/tools/find-github-issues/dist/index.js +34 -5
- package/packages/tools/find-github-issues/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/find-github-issues/index.ts +37 -5
- package/packages/tools/find-github-issues/package.json +11 -4
- package/packages/tools/generate-storyboard-images/dist/index.d.ts +1 -2
- package/packages/tools/generate-storyboard-images/dist/index.js +98 -173
- package/packages/tools/generate-storyboard-images/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/generate-storyboard-images/index.ts +100 -188
- package/packages/tools/generate-storyboard-images/package.json +11 -4
- package/packages/tools/open-github-issue/dist/index.d.ts +13 -0
- package/packages/tools/open-github-issue/dist/index.js +67 -68
- package/packages/tools/open-github-issue/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/open-github-issue/index.ts +71 -72
- package/packages/tools/open-github-issue/package.json +11 -4
- package/packages/tools/read-github-issue/dist/index.d.ts +16 -1
- package/packages/tools/read-github-issue/dist/index.js +32 -40
- package/packages/tools/read-github-issue/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/read-github-issue/index.ts +32 -45
- package/packages/tools/read-github-issue/package.json +11 -4
- package/packages/tools/render-error-book/dist/index.d.ts +1 -2
- package/packages/tools/render-error-book/dist/index.js +74 -95
- package/packages/tools/render-error-book/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/render-error-book/index.ts +88 -103
- package/packages/tools/render-error-book/package.json +11 -4
- package/packages/tools/render-katex/dist/index.d.ts +1 -2
- package/packages/tools/render-katex/dist/index.js +70 -157
- package/packages/tools/render-katex/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/render-katex/index.ts +138 -222
- package/packages/tools/render-katex/package.json +11 -4
- package/packages/tools/review-threads/dist/index.d.ts +12 -0
- package/packages/tools/review-threads/dist/index.js +83 -86
- package/packages/tools/review-threads/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/review-threads/index.ts +90 -84
- package/packages/tools/review-threads/package.json +11 -4
- package/packages/tools/search-logs/dist/index.js +100 -136
- package/packages/tools/search-logs/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/search-logs/index.ts +113 -145
- package/packages/tools/search-logs/package.json +11 -4
- package/packages/tools/sync-memory-index/dist/index.js +34 -28
- package/packages/tools/sync-memory-index/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/sync-memory-index/index.ts +37 -28
- package/packages/tools/sync-memory-index/package.json +11 -4
- package/packages/tools/validate-openai-agent-config/dist/index.js +13 -7
- package/packages/tools/validate-openai-agent-config/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/validate-openai-agent-config/index.ts +13 -7
- package/packages/tools/validate-openai-agent-config/package.json +11 -4
- package/packages/tools/validate-skill-frontmatter/dist/index.js +12 -6
- package/packages/tools/validate-skill-frontmatter/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tools/validate-skill-frontmatter/index.ts +12 -6
- package/packages/tools/validate-skill-frontmatter/package.json +11 -4
- package/packages/tui/dist/index.d.ts +2 -1
- package/packages/tui/dist/index.js +1 -0
- package/packages/tui/dist/stdio-adapter.d.ts +36 -0
- package/packages/tui/dist/stdio-adapter.js +69 -0
- package/packages/tui/dist/terminal.js +3 -1
- package/packages/tui/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/tui/dist/types.d.ts +17 -0
- package/packages/tui/index.ts +2 -1
- package/packages/tui/package.json +14 -6
- package/packages/tui/stdio-adapter.ts +85 -0
- package/packages/tui/terminal.ts +3 -1
- package/packages/tui/tsconfig.json +5 -2
- package/packages/tui/types.ts +19 -0
- package/resources/project-architecture/assets/architecture.css +2 -1
- package/resources/project-architecture/atlas/atlas.history.log +1 -0
- package/resources/project-architecture/atlas/atlas.history.undo.json +13 -2
- package/resources/project-architecture/atlas/atlas.history.undo.stack.json +610 -0
- package/resources/project-architecture/atlas/atlas.index.yaml +81 -5
- package/resources/project-architecture/atlas/features/cli-dispatch.yaml +43 -0
- package/resources/project-architecture/atlas/features/terminal-ui.yaml +29 -0
- package/resources/project-architecture/atlas/features/tool-registry.yaml +22 -0
- package/resources/project-architecture/atlas/features/tool-utils.yaml +22 -0
- package/resources/project-architecture/features/cli-dispatch/arg-parser.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/help-builder.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/index.html +64 -0
- package/resources/project-architecture/features/cli-dispatch/installer-core.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/tool-discovery.html +40 -0
- package/resources/project-architecture/features/cli-dispatch/update-checker.html +40 -0
- package/resources/project-architecture/features/terminal-ui/banner-display.html +40 -0
- package/resources/project-architecture/features/terminal-ui/index.html +50 -0
- package/resources/project-architecture/features/terminal-ui/interactive-prompts.html +40 -0
- package/resources/project-architecture/features/terminal-ui/terminal-detection.html +40 -0
- package/resources/project-architecture/features/tool-registry/formatter.html +40 -0
- package/resources/project-architecture/features/tool-registry/index.html +43 -0
- package/resources/project-architecture/features/tool-registry/registry-core.html +40 -0
- package/resources/project-architecture/features/tool-utils/index.html +43 -0
- package/resources/project-architecture/features/tool-utils/log-utils.html +40 -0
- package/resources/project-architecture/features/tool-utils/skill-discovery.html +40 -0
- package/resources/project-architecture/index.html +365 -121
- package/scripts/rewrite-imports.mjs +2 -2
- package/scripts/test.sh +144 -8
- package/skills/design/SKILL.md +57 -64
- package/skills/design/assets/templates/DESIGN.md +12 -0
- package/skills/design/references/code-smells.md +94 -0
- package/skills/design/references/module-boundary-adjustment.md +126 -0
- package/skills/design/references/module-internal-restructuring.md +132 -0
- package/skills/design/references/module-internal-simplification.md +164 -0
|
@@ -3,91 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import https from 'node:https';
|
|
4
4
|
import http from 'node:http';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
|
|
7
|
-
const parsed = {
|
|
8
|
-
contentName: null,
|
|
9
|
-
projectDir: '.',
|
|
10
|
-
envFile: null,
|
|
11
|
-
apiUrl: null,
|
|
12
|
-
apiKey: null,
|
|
13
|
-
promptsFile: null,
|
|
14
|
-
prompts: [],
|
|
15
|
-
imageModel: null,
|
|
16
|
-
aspectRatio: null,
|
|
17
|
-
imageSize: null,
|
|
18
|
-
quality: null,
|
|
19
|
-
style: null,
|
|
20
|
-
help: false,
|
|
21
|
-
};
|
|
22
|
-
for (let i = 0; i < args.length; i++) {
|
|
23
|
-
const arg = args[i];
|
|
24
|
-
if (arg === '--help' || arg === '-h') {
|
|
25
|
-
parsed.help = true;
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
if (arg.startsWith('--')) {
|
|
29
|
-
const eqIndex = arg.indexOf('=');
|
|
30
|
-
let key;
|
|
31
|
-
let value;
|
|
32
|
-
if (eqIndex !== -1) {
|
|
33
|
-
key = arg.slice(2, eqIndex);
|
|
34
|
-
value = arg.slice(eqIndex + 1);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
key = arg.slice(2);
|
|
38
|
-
if (key === 'prompt') {
|
|
39
|
-
// --prompt can be multiple
|
|
40
|
-
value = args[++i] || '';
|
|
41
|
-
parsed.prompts.push(value);
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
value = args[++i] || '';
|
|
45
|
-
}
|
|
46
|
-
switch (key) {
|
|
47
|
-
case 'input':
|
|
48
|
-
case 'content-name':
|
|
49
|
-
parsed.contentName = value;
|
|
50
|
-
break;
|
|
51
|
-
case 'project-dir':
|
|
52
|
-
parsed.projectDir = value;
|
|
53
|
-
break;
|
|
54
|
-
case 'env-file':
|
|
55
|
-
parsed.envFile = value;
|
|
56
|
-
break;
|
|
57
|
-
case 'api-url':
|
|
58
|
-
parsed.apiUrl = value;
|
|
59
|
-
break;
|
|
60
|
-
case 'api-key':
|
|
61
|
-
parsed.apiKey = value;
|
|
62
|
-
break;
|
|
63
|
-
case 'prompts-file':
|
|
64
|
-
parsed.promptsFile = value;
|
|
65
|
-
break;
|
|
66
|
-
case 'image-model':
|
|
67
|
-
parsed.imageModel = value;
|
|
68
|
-
break;
|
|
69
|
-
case 'aspect-ratio':
|
|
70
|
-
parsed.aspectRatio = value;
|
|
71
|
-
break;
|
|
72
|
-
case 'image-size':
|
|
73
|
-
case 'size':
|
|
74
|
-
parsed.imageSize = value;
|
|
75
|
-
break;
|
|
76
|
-
case 'quality':
|
|
77
|
-
parsed.quality = value;
|
|
78
|
-
break;
|
|
79
|
-
case 'style':
|
|
80
|
-
parsed.style = value;
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else if (!parsed.contentName && !arg.startsWith('-')) {
|
|
85
|
-
// positional: content name
|
|
86
|
-
parsed.contentName = arg;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return parsed;
|
|
90
|
-
}
|
|
6
|
+
import { UserInputError, createToolRunner } from '../../../tool-utils/dist/index.js';
|
|
91
7
|
function sanitizeComponent(name, fallback) {
|
|
92
8
|
return name
|
|
93
9
|
.replace(/[\\/:*?"<>|]+/g, '_')
|
|
@@ -163,7 +79,7 @@ function parsePromptEntries(raw) {
|
|
|
163
79
|
if (typeof item === 'string') {
|
|
164
80
|
const prompt = item.trim();
|
|
165
81
|
if (!prompt)
|
|
166
|
-
throw new
|
|
82
|
+
throw new UserInputError(`Empty prompt at index ${i}`);
|
|
167
83
|
items.push({ title: `scene-${i + 1}`, prompt });
|
|
168
84
|
}
|
|
169
85
|
else if (item && typeof item === 'object') {
|
|
@@ -171,15 +87,15 @@ function parsePromptEntries(raw) {
|
|
|
171
87
|
const prompt = String(obj.prompt || '').trim();
|
|
172
88
|
const title = String(obj.title || `scene-${i + 1}`).trim() || `scene-${i + 1}`;
|
|
173
89
|
if (!prompt)
|
|
174
|
-
throw new
|
|
90
|
+
throw new UserInputError(`Empty prompt in object at index ${i}`);
|
|
175
91
|
items.push({ title, prompt });
|
|
176
92
|
}
|
|
177
93
|
else {
|
|
178
|
-
throw new
|
|
94
|
+
throw new UserInputError(`Invalid item type at index ${i}: expected string or object`);
|
|
179
95
|
}
|
|
180
96
|
}
|
|
181
97
|
if (items.length === 0)
|
|
182
|
-
throw new
|
|
98
|
+
throw new UserInputError('No prompts found.');
|
|
183
99
|
return items;
|
|
184
100
|
}
|
|
185
101
|
function parsePromptsFile(filePath) {
|
|
@@ -190,7 +106,7 @@ function parsePromptsFile(filePath) {
|
|
|
190
106
|
if (raw && typeof raw === 'object') {
|
|
191
107
|
const scenes = raw.scenes;
|
|
192
108
|
if (!Array.isArray(scenes) || scenes.length === 0) {
|
|
193
|
-
throw new
|
|
109
|
+
throw new UserInputError('Object mode requires a top-level "scenes" array.');
|
|
194
110
|
}
|
|
195
111
|
const characters = {};
|
|
196
112
|
if (Array.isArray(raw.characters)) {
|
|
@@ -213,12 +129,12 @@ function parsePromptsFile(filePath) {
|
|
|
213
129
|
for (let si = 0; si < scenes.length; si++) {
|
|
214
130
|
const scene = scenes[si];
|
|
215
131
|
if (!scene || typeof scene !== 'object') {
|
|
216
|
-
throw new
|
|
132
|
+
throw new UserInputError(`Invalid scene at index ${si}: expected object.`);
|
|
217
133
|
}
|
|
218
134
|
const title = String(scene.title || `scene-${si + 1}`).trim() || `scene-${si + 1}`;
|
|
219
135
|
const description = String(scene.description || '').trim();
|
|
220
136
|
if (!description)
|
|
221
|
-
throw new
|
|
137
|
+
throw new UserInputError(`Scene ${si}: 'description' is required.`);
|
|
222
138
|
let promptPayload = {
|
|
223
139
|
scene_title: title,
|
|
224
140
|
description,
|
|
@@ -248,44 +164,56 @@ function parsePromptsFile(filePath) {
|
|
|
248
164
|
}
|
|
249
165
|
return items;
|
|
250
166
|
}
|
|
251
|
-
throw new
|
|
167
|
+
throw new UserInputError('Top-level JSON must be an array or an object.');
|
|
252
168
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
169
|
+
const schema = {
|
|
170
|
+
options: {
|
|
171
|
+
'input': { type: 'string' },
|
|
172
|
+
'content-name': { type: 'string' },
|
|
173
|
+
'project-dir': { type: 'string', default: '.' },
|
|
174
|
+
'env-file': { type: 'string' },
|
|
175
|
+
'api-url': { type: 'string' },
|
|
176
|
+
'api-key': { type: 'string' },
|
|
177
|
+
'prompts-file': { type: 'string' },
|
|
178
|
+
'prompt': { type: 'string', multiple: true },
|
|
179
|
+
'image-model': { type: 'string' },
|
|
180
|
+
'aspect-ratio': { type: 'string' },
|
|
181
|
+
'image-size': { type: 'string' },
|
|
182
|
+
'size': { type: 'string' },
|
|
183
|
+
'quality': { type: 'string' },
|
|
184
|
+
'style': { type: 'string' },
|
|
185
|
+
},
|
|
186
|
+
allowPositionals: true,
|
|
187
|
+
usage: 'apltk generate-storyboard-images --input <name> [options]',
|
|
188
|
+
description: 'Generate storyboard images from prompts via OpenAI-compatible API.',
|
|
189
|
+
handler: async (values, positionals, context) => {
|
|
190
|
+
const stdout = context.stdout || process.stdout;
|
|
191
|
+
const stderr = context.stderr || process.stderr;
|
|
192
|
+
const contentName = values['input'] ||
|
|
193
|
+
values['content-name'] ||
|
|
194
|
+
positionals[0] ||
|
|
195
|
+
null;
|
|
196
|
+
const projectDir = values['project-dir'] || '.';
|
|
197
|
+
const envFile = values['env-file'] ?? null;
|
|
198
|
+
const apiUrl = values['api-url'] ?? null;
|
|
199
|
+
const apiKey = values['api-key'] ?? null;
|
|
200
|
+
const promptsFile = values['prompts-file'] ?? null;
|
|
201
|
+
const prompts = values['prompt'] || [];
|
|
202
|
+
const imageModel = values['image-model'] ?? null;
|
|
203
|
+
const aspectRatio = values['aspect-ratio'] ?? null;
|
|
204
|
+
const imageSize = values['image-size'] || values['size'] || null;
|
|
205
|
+
const quality = values['quality'] ?? null;
|
|
206
|
+
const style = values['style'] ?? null;
|
|
207
|
+
if (!contentName) {
|
|
208
|
+
throw new UserInputError('--input or --content-name is required.');
|
|
280
209
|
}
|
|
281
|
-
const
|
|
282
|
-
const contentName = opts.contentName;
|
|
210
|
+
const resolvedProjectDir = path.resolve(projectDir);
|
|
283
211
|
// Resolve API config
|
|
284
212
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
285
213
|
const sourceRoot = context.sourceRoot || path.resolve(__dirname, '..', '..');
|
|
286
214
|
// Try loading env file
|
|
287
|
-
const envFilePath =
|
|
288
|
-
? path.resolve(
|
|
215
|
+
const envFilePath = envFile
|
|
216
|
+
? path.resolve(envFile)
|
|
289
217
|
: path.join(sourceRoot, 'openai-text-to-image-storyboard', '.env');
|
|
290
218
|
if (fs.existsSync(envFilePath)) {
|
|
291
219
|
const envContent = fs.readFileSync(envFilePath, 'utf-8');
|
|
@@ -309,60 +237,58 @@ Either --prompts-file or at least one --prompt is required.
|
|
|
309
237
|
}
|
|
310
238
|
}
|
|
311
239
|
}
|
|
312
|
-
const
|
|
313
|
-
const
|
|
314
|
-
const
|
|
315
|
-
const
|
|
316
|
-
const
|
|
317
|
-
const
|
|
318
|
-
const
|
|
319
|
-
if (!
|
|
320
|
-
|
|
321
|
-
return 1;
|
|
240
|
+
const resolvedApiUrl = apiUrl || process.env.OPENAI_API_URL || '';
|
|
241
|
+
const resolvedApiKey = apiKey || process.env.OPENAI_API_KEY || '';
|
|
242
|
+
const resolvedImageModel = imageModel || process.env.OPENAI_IMAGE_MODEL || 'gpt-image-1';
|
|
243
|
+
const resolvedAspectRatio = aspectRatio || process.env.OPENAI_IMAGE_RATIO || process.env.OPENAI_IMAGE_ASPECT_RATIO || null;
|
|
244
|
+
const resolvedImageSize = imageSize || process.env.OPENAI_IMAGE_SIZE || null;
|
|
245
|
+
const resolvedQuality = quality || process.env.OPENAI_IMAGE_QUALITY || null;
|
|
246
|
+
const resolvedStyle = style || process.env.OPENAI_IMAGE_STYLE || null;
|
|
247
|
+
if (!resolvedApiUrl) {
|
|
248
|
+
throw new UserInputError('Missing API URL. Set --api-url or OPENAI_API_URL.');
|
|
322
249
|
}
|
|
323
|
-
if (!
|
|
324
|
-
|
|
325
|
-
return 1;
|
|
250
|
+
if (!resolvedApiKey) {
|
|
251
|
+
throw new UserInputError('Missing API key. Set --api-key or OPENAI_API_KEY.');
|
|
326
252
|
}
|
|
327
253
|
// Build prompt items
|
|
328
254
|
let promptItems;
|
|
329
|
-
if (
|
|
330
|
-
promptItems = parsePromptsFile(path.resolve(
|
|
255
|
+
if (promptsFile) {
|
|
256
|
+
promptItems = parsePromptsFile(path.resolve(promptsFile));
|
|
331
257
|
}
|
|
332
|
-
else if (
|
|
333
|
-
promptItems =
|
|
258
|
+
else if (prompts.length > 0) {
|
|
259
|
+
promptItems = prompts.map((p, i) => ({ title: `scene-${i + 1}`, prompt: p.trim() }));
|
|
334
260
|
}
|
|
335
261
|
else {
|
|
336
|
-
|
|
337
|
-
return 1;
|
|
262
|
+
throw new UserInputError('Either --prompts-file or at least one --prompt is required.');
|
|
338
263
|
}
|
|
339
264
|
if (promptItems.length === 0) {
|
|
340
|
-
|
|
341
|
-
return 1;
|
|
265
|
+
throw new UserInputError('No prompts provided.');
|
|
342
266
|
}
|
|
343
|
-
const outputDir = path.join(
|
|
267
|
+
const outputDir = path.join(resolvedProjectDir, 'pictures', sanitizeComponent(contentName, 'untitled-content'));
|
|
344
268
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
345
269
|
const records = [];
|
|
270
|
+
let failures = 0;
|
|
346
271
|
for (let i = 0; i < promptItems.length; i++) {
|
|
347
272
|
const item = promptItems[i];
|
|
348
273
|
const titleSlug = sanitizeComponent(item.title, `scene-${i + 1}`);
|
|
349
274
|
const imagePath = uniquePath(path.join(outputDir, `${String(i + 1).padStart(2, '0')}_${titleSlug}.png`));
|
|
350
275
|
const payload = {
|
|
351
|
-
model:
|
|
276
|
+
model: resolvedImageModel,
|
|
352
277
|
prompt: item.prompt,
|
|
353
278
|
};
|
|
354
|
-
if (
|
|
355
|
-
payload.aspect_ratio =
|
|
356
|
-
if (
|
|
357
|
-
payload.size =
|
|
358
|
-
if (
|
|
359
|
-
payload.quality =
|
|
360
|
-
if (
|
|
361
|
-
payload.style =
|
|
362
|
-
const response = await postJson(
|
|
279
|
+
if (resolvedAspectRatio)
|
|
280
|
+
payload.aspect_ratio = resolvedAspectRatio;
|
|
281
|
+
if (resolvedImageSize)
|
|
282
|
+
payload.size = resolvedImageSize;
|
|
283
|
+
if (resolvedQuality)
|
|
284
|
+
payload.quality = resolvedQuality;
|
|
285
|
+
if (resolvedStyle)
|
|
286
|
+
payload.style = resolvedStyle;
|
|
287
|
+
const response = await postJson(resolvedApiUrl, '/images/generations', resolvedApiKey, payload);
|
|
363
288
|
const data = response.data;
|
|
364
289
|
if (!Array.isArray(data) || data.length === 0) {
|
|
365
|
-
stderr.write(`
|
|
290
|
+
stderr.write(`No image data returned for prompt ${i + 1}.\n`);
|
|
291
|
+
failures++;
|
|
366
292
|
continue;
|
|
367
293
|
}
|
|
368
294
|
const first = data[0];
|
|
@@ -374,7 +300,8 @@ Either --prompts-file or at least one --prompt is required.
|
|
|
374
300
|
imageBytes = await fetchBinary(first.url);
|
|
375
301
|
}
|
|
376
302
|
else {
|
|
377
|
-
stderr.write(`
|
|
303
|
+
stderr.write(`Image payload missing b64_json/url for prompt ${i + 1}.\n`);
|
|
304
|
+
failures++;
|
|
378
305
|
continue;
|
|
379
306
|
}
|
|
380
307
|
fs.writeFileSync(imagePath, imageBytes);
|
|
@@ -393,29 +320,27 @@ Either --prompts-file or at least one --prompt is required.
|
|
|
393
320
|
// Write summary
|
|
394
321
|
const summary = {
|
|
395
322
|
content_name: contentName,
|
|
396
|
-
project_dir:
|
|
323
|
+
project_dir: resolvedProjectDir,
|
|
397
324
|
output_dir: outputDir,
|
|
398
|
-
image_model:
|
|
325
|
+
image_model: resolvedImageModel,
|
|
399
326
|
images: records,
|
|
400
327
|
};
|
|
401
|
-
if (
|
|
402
|
-
summary.aspect_ratio =
|
|
403
|
-
if (
|
|
404
|
-
summary.image_size =
|
|
328
|
+
if (resolvedAspectRatio)
|
|
329
|
+
summary.aspect_ratio = resolvedAspectRatio;
|
|
330
|
+
if (resolvedImageSize)
|
|
331
|
+
summary.image_size = resolvedImageSize;
|
|
405
332
|
const summaryPath = path.join(outputDir, 'storyboard.json');
|
|
406
333
|
fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2), 'utf-8');
|
|
407
334
|
stdout.write(`[OK] Wrote plan to ${summaryPath}\n`);
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
}
|
|
335
|
+
if (failures > 0) {
|
|
336
|
+
stderr.write(`Warning: ${failures} out of ${promptItems.length} prompts failed to generate images.\n`);
|
|
337
|
+
}
|
|
338
|
+
return failures > 0 ? 1 : 0;
|
|
339
|
+
},
|
|
340
|
+
};
|
|
416
341
|
export const tool = {
|
|
417
342
|
name: 'generate-storyboard-images',
|
|
418
343
|
category: 'media',
|
|
419
344
|
description: 'Generate storyboard images from prompts via OpenAI-compatible API.',
|
|
420
|
-
handler:
|
|
345
|
+
handler: createToolRunner(schema),
|
|
421
346
|
};
|