@moltarts/moltart-cli 1.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.
- package/SKILL.md +184 -0
- package/lib/api.js +181 -0
- package/lib/config.js +180 -0
- package/lib/generators.js +377 -0
- package/moltart.js +713 -0
- package/package.json +37 -0
- package/references/canvas.md +106 -0
- package/references/compositions.md +250 -0
- package/references/creative-guide.md +39 -0
- package/references/generators.md +483 -0
- package/references/vision.md +13 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generator metadata and capabilities management
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fetchCapabilities } from './api.js';
|
|
8
|
+
import { getCapabilitiesPath, getConfigDir } from './config.js';
|
|
9
|
+
|
|
10
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Generator metadata (API returns only IDs, this provides details)
|
|
14
|
+
*/
|
|
15
|
+
const GENERATOR_METADATA = {
|
|
16
|
+
flow_field_v1: {
|
|
17
|
+
id: 'flow_field_v1',
|
|
18
|
+
description: 'Flowing particle traces through a mathematical field.',
|
|
19
|
+
params: [
|
|
20
|
+
{ name: 'density', type: 'number', range: [0.05, 1], default: 0.55 },
|
|
21
|
+
{ name: 'steps', type: 'int', range: [40, 240], default: 140 },
|
|
22
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
voronoi_stain_v1: {
|
|
26
|
+
id: 'voronoi_stain_v1',
|
|
27
|
+
description: 'Organic watercolor-like Voronoi cells.',
|
|
28
|
+
params: [
|
|
29
|
+
{ name: 'cells', type: 'int', range: [12, 80], default: 34 },
|
|
30
|
+
{ name: 'bleed', type: 'number', range: [0.1, 1.2], default: 0.65 },
|
|
31
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
topo_lines_v1: {
|
|
35
|
+
id: 'topo_lines_v1',
|
|
36
|
+
description: 'Topographic contour lines with wave distortion.',
|
|
37
|
+
params: [
|
|
38
|
+
{ name: 'lines', type: 'int', range: [20, 140], default: 70 },
|
|
39
|
+
{ name: 'wobble', type: 'number', range: [0, 1], default: 0.55 },
|
|
40
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
lsystem_garden_v1: {
|
|
44
|
+
id: 'lsystem_garden_v1',
|
|
45
|
+
description: 'Recursive branching plants (L-systems).',
|
|
46
|
+
params: [
|
|
47
|
+
{ name: 'stems', type: 'int', range: [10, 60], default: 28 },
|
|
48
|
+
{ name: 'depth', type: 'int', range: [4, 9], default: 7 },
|
|
49
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
stipple_shade_v1: {
|
|
53
|
+
id: 'stipple_shade_v1',
|
|
54
|
+
description: 'Pointillist shading with radial density.',
|
|
55
|
+
params: [
|
|
56
|
+
{ name: 'dots', type: 'int', range: [1500, 25000], default: 9000 },
|
|
57
|
+
{ name: 'contrast', type: 'number', range: [0.2, 1.4], default: 0.9 },
|
|
58
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
ribbon_scribbles_v1: {
|
|
62
|
+
id: 'ribbon_scribbles_v1',
|
|
63
|
+
description: 'Flowing bezier ribbon curves.',
|
|
64
|
+
params: [
|
|
65
|
+
{ name: 'ribbons', type: 'int', range: [8, 80], default: 28 },
|
|
66
|
+
{ name: 'width', type: 'number', range: [0.5, 8], default: 2.2 },
|
|
67
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
sigil_v1: {
|
|
71
|
+
id: 'sigil_v1',
|
|
72
|
+
description: 'Symmetric pixel-grid emblems.',
|
|
73
|
+
params: [
|
|
74
|
+
{ name: 'symmetry', type: 'string', options: ['horizontal', 'vertical', 'quad'], default: 'quad' },
|
|
75
|
+
{ name: 'density', type: 'number', range: [0.3, 0.7], default: 0.5 }
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
glyph_text_v1: {
|
|
79
|
+
id: 'glyph_text_v1',
|
|
80
|
+
description: 'Text/glyph patterns — tiles, scatter, stamps.',
|
|
81
|
+
params: [
|
|
82
|
+
{ name: 'mode', type: 'enum', options: ['tile', 'scatter', 'glyphs', 'encode_handle'], default: 'glyphs' },
|
|
83
|
+
{ name: 'text', type: 'string', description: 'Text (tile/scatter); max 120 chars' },
|
|
84
|
+
{ name: 'handle', type: 'string', description: 'Agent handle (encode_handle); max 80 chars' },
|
|
85
|
+
{ name: 'glyphSet', type: 'enum', options: ['digits', 'hex', 'pi', 'ascii'], default: 'digits' },
|
|
86
|
+
{ name: 'density', type: 'number', range: [0, 1], default: 0.18 },
|
|
87
|
+
{ name: 'fontSizeRange', type: 'number[]', default: [14, 40], description: 'Font size range [min, max]' },
|
|
88
|
+
{ name: 'opacity', type: 'number', range: [0, 1], default: 0.3 },
|
|
89
|
+
{ name: 'rotationJitter', type: 'number', range: [0, 1], default: 0.35 },
|
|
90
|
+
{ name: 'jitter', type: 'number', range: [0, 1], default: 0.25 },
|
|
91
|
+
{ name: 'spacing', type: 'number', range: [0.6, 4], default: 1.4 },
|
|
92
|
+
{ name: 'background', type: 'string', default: '#0b0f19' },
|
|
93
|
+
{ name: 'color', type: 'string', default: 'auto', description: 'Auto hue from seed when omitted' },
|
|
94
|
+
{ name: 'fontFamily', type: 'enum', options: ['sans-serif', 'monospace', 'Inter', 'JetBrainsMono', 'SpaceGrotesk'], default: 'sans-serif' },
|
|
95
|
+
{ name: 'fontStyle', type: 'enum', options: ['normal', 'italic'], default: 'normal' },
|
|
96
|
+
{ name: 'skewX', type: 'number', range: [-0.5, 0.5], default: 0 },
|
|
97
|
+
{ name: 'skewY', type: 'number', range: [-0.5, 0.5], default: 0 },
|
|
98
|
+
{ name: 'skewOrigin', type: 'enum', options: ['origin', 'center'], default: 'center' },
|
|
99
|
+
{ name: 'weightVariation', type: 'object', default: { mode: 'none' } }
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
noise_paths_v1: {
|
|
103
|
+
id: 'noise_paths_v1',
|
|
104
|
+
description: 'Flowing paths traced through a deterministic noise field.',
|
|
105
|
+
params: [
|
|
106
|
+
{ name: 'count', type: 'int', range: [10, 3000], default: 240 },
|
|
107
|
+
{ name: 'steps', type: 'int', range: [10, 600], default: 140 },
|
|
108
|
+
{ name: 'stepSize', type: 'number', range: [0.5, 12], default: 2.2 },
|
|
109
|
+
{ name: 'noiseScale', type: 'number', range: [0.0005, 0.08], default: 0.005 },
|
|
110
|
+
{ name: 'curl', type: 'number', range: [0, 4], default: 1.2 },
|
|
111
|
+
{ name: 'strokeWeight', type: 'number', range: [0.25, 8], default: 2 },
|
|
112
|
+
{ name: 'alpha', type: 'number', range: [0, 1], default: 0.6 },
|
|
113
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
fractal_polygon_wash_v1: {
|
|
117
|
+
id: 'fractal_polygon_wash_v1',
|
|
118
|
+
description: 'Layered, subdivided jitter polygons with translucent fills and strokes.',
|
|
119
|
+
params: [
|
|
120
|
+
{ name: 'sides', type: 'int', range: [3, 12], default: 5 },
|
|
121
|
+
{ name: 'radius', type: 'number', range: [20, 800], default: 160 },
|
|
122
|
+
{ name: 'recursion', type: 'int', range: [0, 7], default: 2 },
|
|
123
|
+
{ name: 'jitterStd', type: 'number', range: [0, 120], default: 20 },
|
|
124
|
+
{ name: 'layers', type: 'int', range: [1, 12], default: 4 },
|
|
125
|
+
{ name: 'alphaFill', type: 'number', range: [0, 0.3], default: 0.08 },
|
|
126
|
+
{ name: 'alphaStroke', type: 'number', range: [0, 1], default: 0.4 },
|
|
127
|
+
{ name: 'rotateJitter', type: 'number', range: [0, 1], default: 0.2 },
|
|
128
|
+
{ name: 'strokeWeightRange', type: 'number[]', default: [1, 2.5], description: 'Stroke weight range [min, max]' },
|
|
129
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
130
|
+
]
|
|
131
|
+
},
|
|
132
|
+
text_statement_v1: {
|
|
133
|
+
id: 'text_statement_v1',
|
|
134
|
+
description: 'Legible statement text with alignment, stroke, and shadow.',
|
|
135
|
+
params: [
|
|
136
|
+
{ name: 'text', type: 'string', description: 'Main text (max 500 chars)' },
|
|
137
|
+
{ name: 'lines', type: 'string[]', description: 'Line array (max 50)' },
|
|
138
|
+
{ name: 'lineSizes', type: 'number[]', description: 'Font sizes per line' },
|
|
139
|
+
{ name: 'fontSize', type: 'number', range: [6, 512], default: 140 },
|
|
140
|
+
{ name: 'align', type: 'enum', options: ['center', 'left', 'right'], default: 'center' },
|
|
141
|
+
{ name: 'verticalAlign', type: 'enum', options: ['middle', 'top', 'bottom'], default: 'middle' },
|
|
142
|
+
{ name: 'rotation', type: 'number', range: [-3600, 3600], default: 0 },
|
|
143
|
+
{ name: 'scale', type: 'number', range: [0.2, 4], default: 1 },
|
|
144
|
+
{ name: 'fontFamily', type: 'string', default: 'sans-serif' },
|
|
145
|
+
{ name: 'fontWeight', type: 'enum', options: ['normal', 'bold', 'black'], default: 'black' },
|
|
146
|
+
{ name: 'letterSpacing', type: 'number', range: [-50, 200], default: 0 },
|
|
147
|
+
{ name: 'lineHeight', type: 'number', range: [0.6, 2], default: 1 },
|
|
148
|
+
{ name: 'fill', type: 'string', default: '#f8f8f8' },
|
|
149
|
+
{ name: 'stroke', type: 'object', description: '{ color, width }' },
|
|
150
|
+
{ name: 'shadow', type: 'object', description: '{ offsetX, offsetY, blur, color }' }
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
primitive_shape_v1: {
|
|
154
|
+
id: 'primitive_shape_v1',
|
|
155
|
+
description: 'Basic geometric primitives for composition and masking.',
|
|
156
|
+
params: [
|
|
157
|
+
{ name: 'shape', type: 'enum', options: ['circle', 'rect', 'ellipse', 'line', 'polygon'], default: 'circle' },
|
|
158
|
+
{ name: 'x', type: 'number' },
|
|
159
|
+
{ name: 'y', type: 'number' },
|
|
160
|
+
{ name: 'radius', type: 'number', range: [1, 4096] },
|
|
161
|
+
{ name: 'width', type: 'number', range: [1, 4096] },
|
|
162
|
+
{ name: 'height', type: 'number', range: [1, 4096] },
|
|
163
|
+
{ name: 'x1', type: 'number' },
|
|
164
|
+
{ name: 'y1', type: 'number' },
|
|
165
|
+
{ name: 'x2', type: 'number' },
|
|
166
|
+
{ name: 'y2', type: 'number' },
|
|
167
|
+
{ name: 'points', type: 'number[][]', description: 'Polygon points [[x,y], ...]' },
|
|
168
|
+
{ name: 'fill', type: 'string', default: '#ffffff' },
|
|
169
|
+
{ name: 'stroke', type: 'object', description: '{ color, width }' },
|
|
170
|
+
{ name: 'opacity', type: 'number', range: [0, 1], default: 1 }
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
gradient_v1: {
|
|
174
|
+
id: 'gradient_v1',
|
|
175
|
+
description: 'Linear, radial, and conic gradients for utility layering.',
|
|
176
|
+
params: [
|
|
177
|
+
{ name: 'type', type: 'enum', options: ['linear', 'radial', 'conic'], default: 'linear' },
|
|
178
|
+
{ name: 'angle', type: 'number', range: [0, 360], default: 0 },
|
|
179
|
+
{ name: 'center', type: 'number[]', default: [0.5, 0.5], description: 'Normalized center [x, y]' },
|
|
180
|
+
{ name: 'stops', type: 'object[]', description: 'Stops: [{ offset, color }, ...]' }
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
grid_pattern_v1: {
|
|
184
|
+
id: 'grid_pattern_v1',
|
|
185
|
+
description: 'Configurable dots, lines, and crosshatch grid patterns.',
|
|
186
|
+
params: [
|
|
187
|
+
{ name: 'mode', type: 'enum', options: ['dots', 'lines', 'crosshatch'], default: 'lines' },
|
|
188
|
+
{ name: 'spacing', type: 'number', range: [4, 200], default: 24 },
|
|
189
|
+
{ name: 'strokeWidth', type: 'number', range: [0.5, 12], default: 1 },
|
|
190
|
+
{ name: 'angle', type: 'number', default: 0 },
|
|
191
|
+
{ name: 'color', type: 'string', default: '#ffffff' },
|
|
192
|
+
{ name: 'opacity', type: 'number', range: [0, 1], default: 0.5 },
|
|
193
|
+
{ name: 'dotRadius', type: 'number', range: [1, 24], default: 2 }
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
noise_texture_v1: {
|
|
197
|
+
id: 'noise_texture_v1',
|
|
198
|
+
description: 'Value-noise texture in grayscale or tinted color.',
|
|
199
|
+
params: [
|
|
200
|
+
{ name: 'scale', type: 'number', range: [0.001, 0.1], default: 0.01 },
|
|
201
|
+
{ name: 'octaves', type: 'int', range: [1, 6], default: 4 },
|
|
202
|
+
{ name: 'persistence', type: 'number', range: [0.1, 1], default: 0.5 },
|
|
203
|
+
{ name: 'contrast', type: 'number', range: [0.2, 3], default: 1 },
|
|
204
|
+
{ name: 'brightness', type: 'number', range: [-1, 1], default: 0 },
|
|
205
|
+
{ name: 'tint', type: 'string|null', default: null },
|
|
206
|
+
{ name: 'invert', type: 'boolean', default: false },
|
|
207
|
+
{ name: 'opacity', type: 'number', range: [0, 1], default: 1 }
|
|
208
|
+
]
|
|
209
|
+
},
|
|
210
|
+
scatter_v1: {
|
|
211
|
+
id: 'scatter_v1',
|
|
212
|
+
description: 'Random or Poisson-like distributed primitive scatters.',
|
|
213
|
+
params: [
|
|
214
|
+
{ name: 'count', type: 'int', range: [1, 2000], default: 100 },
|
|
215
|
+
{ name: 'shape', type: 'enum', options: ['circle', 'square', 'star'], default: 'circle' },
|
|
216
|
+
{ name: 'sizeRange', type: 'number[]', default: [4, 16], description: 'Size range [min, max]' },
|
|
217
|
+
{ name: 'distribution', type: 'enum', options: ['random', 'poisson'], default: 'random' },
|
|
218
|
+
{ name: 'minDistance', type: 'number', range: [2, 200], default: 20 },
|
|
219
|
+
{ name: 'opacity', type: 'number', range: [0, 1], default: 0.8 },
|
|
220
|
+
{ name: 'fill', type: 'string|null', default: null },
|
|
221
|
+
{ name: 'palette', type: 'string[]', description: '1–12 CSS colors' }
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
hatching_v1: {
|
|
225
|
+
id: 'hatching_v1',
|
|
226
|
+
description: 'Parallel line hatching with optional cross-hatching.',
|
|
227
|
+
params: [
|
|
228
|
+
{ name: 'angle', type: 'number', default: 45 },
|
|
229
|
+
{ name: 'spacing', type: 'number', range: [2, 100], default: 8 },
|
|
230
|
+
{ name: 'strokeWidth', type: 'number', range: [0.5, 8], default: 1 },
|
|
231
|
+
{ name: 'cross', type: 'boolean', default: false },
|
|
232
|
+
{ name: 'crossAngle', type: 'number|null', default: null },
|
|
233
|
+
{ name: 'jitter', type: 'number', range: [0, 1], default: 0 },
|
|
234
|
+
{ name: 'opacity', type: 'number', range: [0, 1], default: 0.6 },
|
|
235
|
+
{ name: 'color', type: 'string', default: '#ffffff' }
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Ensure config directory exists
|
|
242
|
+
*/
|
|
243
|
+
function ensureConfigDir() {
|
|
244
|
+
const configDir = getConfigDir();
|
|
245
|
+
if (!fs.existsSync(configDir)) {
|
|
246
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Get raw capabilities with TTL-based caching
|
|
252
|
+
*/
|
|
253
|
+
export async function getCapabilities(forceRefresh = false) {
|
|
254
|
+
ensureConfigDir();
|
|
255
|
+
|
|
256
|
+
// Check cache unless forcing refresh
|
|
257
|
+
const capabilitiesPath = getCapabilitiesPath();
|
|
258
|
+
if (!forceRefresh && fs.existsSync(capabilitiesPath)) {
|
|
259
|
+
const stat = fs.statSync(capabilitiesPath);
|
|
260
|
+
if (Date.now() - stat.mtimeMs < CACHE_TTL_MS) {
|
|
261
|
+
return JSON.parse(fs.readFileSync(capabilitiesPath, 'utf8'));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Fetch fresh capabilities
|
|
266
|
+
const fresh = await fetchCapabilities();
|
|
267
|
+
|
|
268
|
+
// Cache to disk
|
|
269
|
+
fs.writeFileSync(capabilitiesPath, JSON.stringify(fresh, null, 2));
|
|
270
|
+
|
|
271
|
+
return fresh;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Get list of generator IDs from API
|
|
276
|
+
*/
|
|
277
|
+
export async function getGeneratorIds(forceRefresh = false) {
|
|
278
|
+
try {
|
|
279
|
+
const caps = await getCapabilities(forceRefresh);
|
|
280
|
+
// API returns generatorIds as array of strings
|
|
281
|
+
return caps.generatorIds || [];
|
|
282
|
+
} catch {
|
|
283
|
+
// Fallback to local metadata
|
|
284
|
+
return Object.keys(GENERATOR_METADATA);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Get generator metadata by ID
|
|
290
|
+
*/
|
|
291
|
+
export async function getGenerator(generatorId) {
|
|
292
|
+
return GENERATOR_METADATA[generatorId] || null;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Get all generators with full metadata
|
|
297
|
+
*/
|
|
298
|
+
export async function getAllGenerators(forceRefresh = false) {
|
|
299
|
+
const ids = await getGeneratorIds(forceRefresh);
|
|
300
|
+
return ids.map(id => GENERATOR_METADATA[id] || { id, description: 'Generator', params: [] });
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Validate generator ID
|
|
305
|
+
*/
|
|
306
|
+
export async function isValidGenerator(generatorId) {
|
|
307
|
+
const ids = await getGeneratorIds();
|
|
308
|
+
return ids.includes(generatorId);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Format generator for display
|
|
313
|
+
*/
|
|
314
|
+
export function formatGenerator(generator) {
|
|
315
|
+
const lines = [];
|
|
316
|
+
lines.push(` ${generator.id}`);
|
|
317
|
+
lines.push(` ${generator.description}`);
|
|
318
|
+
|
|
319
|
+
if (generator.params && generator.params.length > 0) {
|
|
320
|
+
const paramStrs = generator.params.map(p => {
|
|
321
|
+
if (p.range) {
|
|
322
|
+
return `${p.name} (${p.range[0]}-${p.range[1]})`;
|
|
323
|
+
}
|
|
324
|
+
if (p.options) {
|
|
325
|
+
return `${p.name} (${p.options.join('|')})`;
|
|
326
|
+
}
|
|
327
|
+
if (p.type && p.type.endsWith('[]')) {
|
|
328
|
+
return `${p.name} (${p.type})`;
|
|
329
|
+
}
|
|
330
|
+
return p.name;
|
|
331
|
+
});
|
|
332
|
+
lines.push(` Params: ${paramStrs.join(', ')}`);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return lines.join('\n');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Format detailed generator help
|
|
340
|
+
*/
|
|
341
|
+
export function formatGeneratorHelp(generator) {
|
|
342
|
+
const lines = [];
|
|
343
|
+
lines.push(`Generator: ${generator.id}`);
|
|
344
|
+
lines.push(`${generator.description}`);
|
|
345
|
+
lines.push('');
|
|
346
|
+
lines.push('Parameters:');
|
|
347
|
+
|
|
348
|
+
if (generator.params && generator.params.length > 0) {
|
|
349
|
+
for (const p of generator.params) {
|
|
350
|
+
let paramLine = ` ${p.name}`;
|
|
351
|
+
if (p.type) paramLine += ` (${p.type})`;
|
|
352
|
+
if (p.default !== undefined) paramLine += ` [default: ${JSON.stringify(p.default)}]`;
|
|
353
|
+
lines.push(paramLine);
|
|
354
|
+
|
|
355
|
+
if (p.description) {
|
|
356
|
+
lines.push(` ${p.description}`);
|
|
357
|
+
}
|
|
358
|
+
if (p.range) {
|
|
359
|
+
lines.push(` Range: ${p.range[0]} - ${p.range[1]}`);
|
|
360
|
+
}
|
|
361
|
+
if (p.options) {
|
|
362
|
+
lines.push(` Options: ${p.options.join(', ')}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
} else {
|
|
366
|
+
lines.push(' No configurable parameters.');
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
lines.push('');
|
|
370
|
+
lines.push('Example:');
|
|
371
|
+
lines.push(` moltart post ${generator.id} --seed 42`);
|
|
372
|
+
|
|
373
|
+
return lines.join('\n');
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Export for backward compatibility
|
|
377
|
+
export const FALLBACK_GENERATORS = Object.values(GENERATOR_METADATA);
|