atomism 0.1.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 (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +210 -0
  3. package/dist/chunk-34O5KJWR.js +81 -0
  4. package/dist/chunk-34O5KJWR.js.map +1 -0
  5. package/dist/chunk-55AP34JO.js +116 -0
  6. package/dist/chunk-55AP34JO.js.map +1 -0
  7. package/dist/chunk-6MDHM2B4.js +17 -0
  8. package/dist/chunk-6MDHM2B4.js.map +1 -0
  9. package/dist/chunk-GU2R4KLP.js +43 -0
  10. package/dist/chunk-GU2R4KLP.js.map +1 -0
  11. package/dist/chunk-H7WC3NXZ.js +39 -0
  12. package/dist/chunk-H7WC3NXZ.js.map +1 -0
  13. package/dist/chunk-P33CQFMY.js +329 -0
  14. package/dist/chunk-P33CQFMY.js.map +1 -0
  15. package/dist/chunk-P6X7T4KA.js +200 -0
  16. package/dist/chunk-P6X7T4KA.js.map +1 -0
  17. package/dist/chunk-PLQJM2KT.js +9 -0
  18. package/dist/chunk-PLQJM2KT.js.map +1 -0
  19. package/dist/chunk-RS2IEGW3.js +10 -0
  20. package/dist/chunk-RS2IEGW3.js.map +1 -0
  21. package/dist/chunk-S6Z5G5DB.js +84 -0
  22. package/dist/chunk-S6Z5G5DB.js.map +1 -0
  23. package/dist/chunk-UVUDQ4XP.js +259 -0
  24. package/dist/chunk-UVUDQ4XP.js.map +1 -0
  25. package/dist/chunk-UWVZQSP4.js +597 -0
  26. package/dist/chunk-UWVZQSP4.js.map +1 -0
  27. package/dist/chunk-YKJO3ZFY.js +308 -0
  28. package/dist/chunk-YKJO3ZFY.js.map +1 -0
  29. package/dist/cli.d.ts +1 -0
  30. package/dist/cli.js +152 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/create-atom-AXPDBYQL.js +153 -0
  33. package/dist/create-atom-AXPDBYQL.js.map +1 -0
  34. package/dist/escalate-BTEJT5NL.js +211 -0
  35. package/dist/escalate-BTEJT5NL.js.map +1 -0
  36. package/dist/extract-RPKCTINT.js +514 -0
  37. package/dist/extract-RPKCTINT.js.map +1 -0
  38. package/dist/graduate-453M7ZRQ.js +222 -0
  39. package/dist/graduate-453M7ZRQ.js.map +1 -0
  40. package/dist/helpers-PJPFPYBQ.js +11 -0
  41. package/dist/helpers-PJPFPYBQ.js.map +1 -0
  42. package/dist/history-OPD7NLZW.js +258 -0
  43. package/dist/history-OPD7NLZW.js.map +1 -0
  44. package/dist/import-generator-4CKRBMTE.js +1864 -0
  45. package/dist/import-generator-4CKRBMTE.js.map +1 -0
  46. package/dist/index.d.ts +230 -0
  47. package/dist/index.js +41 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/init-2FINDMYK.js +741 -0
  50. package/dist/init-2FINDMYK.js.map +1 -0
  51. package/dist/list-NEBVBGG3.js +71 -0
  52. package/dist/list-NEBVBGG3.js.map +1 -0
  53. package/dist/parser-3BILOSOO.js +157 -0
  54. package/dist/parser-3BILOSOO.js.map +1 -0
  55. package/dist/plan-DNVARHWH.js +249 -0
  56. package/dist/plan-DNVARHWH.js.map +1 -0
  57. package/dist/register-XTRMSH7Y.js +91 -0
  58. package/dist/register-XTRMSH7Y.js.map +1 -0
  59. package/dist/revert-J4CRDE2K.js +87 -0
  60. package/dist/revert-J4CRDE2K.js.map +1 -0
  61. package/dist/run-3GI3SBYL.js +188 -0
  62. package/dist/run-3GI3SBYL.js.map +1 -0
  63. package/dist/scan-generators-ST4TBEY7.js +375 -0
  64. package/dist/scan-generators-ST4TBEY7.js.map +1 -0
  65. package/dist/signatures-K5QIL4WG.js +258 -0
  66. package/dist/signatures-K5QIL4WG.js.map +1 -0
  67. package/dist/skills-assign-IHOXX4AI.js +182 -0
  68. package/dist/skills-assign-IHOXX4AI.js.map +1 -0
  69. package/dist/skills-load-JSD5UG2K.js +20 -0
  70. package/dist/skills-load-JSD5UG2K.js.map +1 -0
  71. package/dist/skills-scan-WACJFRJN.js +25 -0
  72. package/dist/skills-scan-WACJFRJN.js.map +1 -0
  73. package/dist/skills-suggest-JFI2NUJI.js +269 -0
  74. package/dist/skills-suggest-JFI2NUJI.js.map +1 -0
  75. package/dist/status-KQVSAZFR.js +111 -0
  76. package/dist/status-KQVSAZFR.js.map +1 -0
  77. package/dist/suggest-IFFJQFIW.js +183 -0
  78. package/dist/suggest-IFFJQFIW.js.map +1 -0
  79. package/dist/test-HP3FG3MO.js +152 -0
  80. package/dist/test-HP3FG3MO.js.map +1 -0
  81. package/dist/test-gen-2ZGPOP35.js +347 -0
  82. package/dist/test-gen-2ZGPOP35.js.map +1 -0
  83. package/dist/trust-4R26DULG.js +248 -0
  84. package/dist/trust-4R26DULG.js.map +1 -0
  85. package/dist/validate-generator-46H2LYYQ.js +410 -0
  86. package/dist/validate-generator-46H2LYYQ.js.map +1 -0
  87. package/dist/workflow-5UVLBS7J.js +655 -0
  88. package/dist/workflow-5UVLBS7J.js.map +1 -0
  89. package/package.json +84 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/trust.ts"],"sourcesContent":["/**\n * Trust command for the atomic CLI.\n *\n * This module implements the `atomic trust` command which manages\n * trust levels for atom stacks.\n *\n * @module commands/trust\n */\n\nimport { join } from 'node:path';\nimport { readdir, readFile, writeFile, rename, unlink } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { ATOMIC_DIR, fileExists, getRegistryPath } from '../storage/index.js';\nimport { AtomStack, TrustLevel } from '../schemas/index.js';\nimport { toErrorMessage } from '../utils/errors.js';\n\ntype TrustLevelType = z.infer<typeof TrustLevel>;\ntype AtomStackType = z.infer<typeof AtomStack>;\n\nexport const STACKS_DIR = 'stacks';\n\n/**\n * Options for the trust set command.\n */\nexport interface TrustSetOptions {\n stack: string;\n level: string;\n json?: boolean;\n}\n\n/**\n * Options for the trust reset command.\n */\nexport interface TrustResetOptions {\n stack: string;\n json?: boolean;\n}\n\n/**\n * Options for the trust list command.\n */\nexport interface TrustListOptions {\n json?: boolean;\n}\n\n/**\n * Result of trust operations.\n */\nexport interface TrustResult {\n success: boolean;\n stack?: AtomStackType;\n previousLevel?: string;\n error?: string;\n}\n\n/**\n * Get the path to the stacks directory.\n */\nfunction getStacksDir(projectRoot: string): string {\n return join(projectRoot, ATOMIC_DIR, STACKS_DIR);\n}\n\n/**\n * Get the path to a specific stack file.\n */\nfunction getStackPath(projectRoot: string, stackName: string): string {\n return join(getStacksDir(projectRoot), `${stackName}.json`);\n}\n\n/**\n * Load a stack from disk.\n */\nasync function loadStack(projectRoot: string, stackName: string): Promise<AtomStackType | null> {\n // Defensive validation to prevent path traversal\n if (!/^[a-z][a-z0-9_]*$/.test(stackName)) {\n return null;\n }\n const stackPath = getStackPath(projectRoot, stackName);\n if (!(await fileExists(stackPath))) {\n return null;\n }\n try {\n const content = await readFile(stackPath, 'utf-8');\n return AtomStack.parse(JSON.parse(content));\n } catch (err) {\n throw new Error(`Failed to load stack '${stackName}': ${toErrorMessage(err)}`);\n }\n}\n\n/**\n * Save a stack to disk atomically.\n */\nasync function saveStack(projectRoot: string, stack: AtomStackType): Promise<void> {\n // Defensive validation to prevent path traversal\n if (!/^[a-z][a-z0-9_]*$/.test(stack.name)) {\n throw new Error(`Invalid stack name: ${stack.name}`);\n }\n const stackPath = getStackPath(projectRoot, stack.name);\n const tempPath = `${stackPath}.tmp`;\n try {\n await writeFile(tempPath, JSON.stringify(stack, null, 2));\n await rename(tempPath, stackPath);\n } catch (err) {\n try {\n await unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw err;\n }\n}\n\n/**\n * Validate that the provided level is a valid TrustLevel.\n */\nfunction validateTrustLevel(level: string): level is TrustLevelType {\n try {\n TrustLevel.parse(level);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Set trust level for an atom stack.\n */\nexport async function trustSetCommand(options: TrustSetOptions): Promise<void> {\n const projectRoot = process.cwd();\n const registryPath = getRegistryPath(projectRoot);\n\n try {\n // Check if initialized\n if (!(await fileExists(registryPath))) {\n throw new Error('Storage not initialized. Run `atomic init` first.');\n }\n\n // Validate trust level\n if (!validateTrustLevel(options.level)) {\n throw new Error(\n `Invalid trust level: ${options.level}\\n` +\n 'Valid levels are: new, proven, trusted'\n );\n }\n\n // Load the stack\n const stack = await loadStack(projectRoot, options.stack);\n if (!stack) {\n throw new Error(`Stack '${options.stack}' not found.`);\n }\n\n const previousLevel = stack.trustLevel;\n\n // Update trust level\n const updatedStack = AtomStack.parse({\n ...stack,\n trustLevel: options.level,\n updatedAt: new Date().toISOString(),\n });\n\n // Save to disk\n await saveStack(projectRoot, updatedStack);\n\n const result: TrustResult = {\n success: true,\n stack: updatedStack,\n previousLevel,\n };\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`✓ Updated trust level for stack '${options.stack}'`);\n console.log(` Previous: ${previousLevel}`);\n console.log(` New: ${options.level}`);\n console.log(` Updated: ${updatedStack.updatedAt}`);\n }\n } catch (err) {\n const errorMessage = toErrorMessage(err);\n\n if (options.json) {\n console.log(\n JSON.stringify({\n success: false,\n error: errorMessage,\n } satisfies TrustResult)\n );\n process.exit(1);\n } else {\n console.error(`Error: ${errorMessage}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * List all stacks with their trust levels.\n */\nexport async function trustListCommand(options: TrustListOptions): Promise<void> {\n const projectRoot = process.cwd();\n const registryPath = getRegistryPath(projectRoot);\n const stacksDir = getStacksDir(projectRoot);\n\n try {\n // Check if initialized\n if (!(await fileExists(registryPath))) {\n throw new Error('Storage not initialized. Run `atomic init` first.');\n }\n\n // Check if stacks directory exists\n if (!(await fileExists(stacksDir))) {\n if (options.json) {\n console.log(JSON.stringify({ stacks: [] }, null, 2));\n } else {\n console.log('No stacks defined.');\n console.log('');\n console.log('Create one with: atomic stack create <name>');\n }\n return;\n }\n\n // Read all stack files\n const files = await readdir(stacksDir);\n const stackFiles = files.filter((f) => f.endsWith('.json'));\n\n const stacks: Array<{ name: string; trustLevel: string; atoms: number }> = [];\n const errors: Array<{ file: string; error: string }> = [];\n\n for (const file of stackFiles) {\n try {\n const content = await readFile(join(stacksDir, file), 'utf-8');\n const stack = AtomStack.parse(JSON.parse(content));\n stacks.push({\n name: stack.name,\n trustLevel: stack.trustLevel,\n atoms: stack.atoms.length,\n });\n } catch (parseErr) {\n const errorMessage = toErrorMessage(parseErr);\n errors.push({ file, error: errorMessage });\n if (!options.json) {\n console.warn(`Warning: Failed to parse ${file}, skipping.`);\n }\n }\n }\n\n // Sort stacks by name for consistent output\n stacks.sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.json) {\n const result: { stacks: typeof stacks; errors?: typeof errors } = { stacks };\n if (errors.length > 0) {\n result.errors = errors;\n }\n console.log(JSON.stringify(result, null, 2));\n } else {\n if (stacks.length === 0) {\n console.log('No stacks defined.');\n console.log('');\n console.log('Create one with: atomic stack create <name>');\n return;\n }\n\n console.log('Stack Trust Levels:');\n console.log('');\n const nameWidth = Math.max(22, ...stacks.map((s) => s.name.length));\n const trustWidth = 10;\n const header = ` ${'Name'.padEnd(nameWidth)} ${'Trust'.padEnd(trustWidth)} Atoms`;\n console.log(header);\n console.log(' ' + '─'.repeat(header.length - 2));\n for (const stack of stacks) {\n const name = stack.name.padEnd(nameWidth);\n const trust = stack.trustLevel.padEnd(trustWidth);\n console.log(` ${name} ${trust} ${stack.atoms}`);\n }\n }\n } catch (err) {\n const errorMessage = toErrorMessage(err);\n\n if (options.json) {\n console.log(JSON.stringify({ error: errorMessage }, null, 2));\n process.exit(1);\n } else {\n console.error(`Error: ${errorMessage}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * Reset a stack's trust level to 'new'.\n */\nexport async function trustResetCommand(options: TrustResetOptions): Promise<void> {\n const projectRoot = process.cwd();\n const registryPath = getRegistryPath(projectRoot);\n\n try {\n // Check if initialized\n if (!(await fileExists(registryPath))) {\n throw new Error('Storage not initialized. Run `atomic init` first.');\n }\n\n // Load the stack\n const stack = await loadStack(projectRoot, options.stack);\n if (!stack) {\n throw new Error(`Stack '${options.stack}' not found.`);\n }\n\n const previousLevel = stack.trustLevel;\n\n // Reset to 'new' level\n const updatedStack = AtomStack.parse({\n ...stack,\n trustLevel: 'new',\n updatedAt: new Date().toISOString(),\n });\n\n // Save to disk\n await saveStack(projectRoot, updatedStack);\n\n const result: TrustResult = {\n success: true,\n stack: updatedStack,\n previousLevel,\n };\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(`✓ Reset trust level for stack '${options.stack}'`);\n console.log(` Previous: ${previousLevel}`);\n console.log(` New: new`);\n console.log(` Updated: ${updatedStack.updatedAt}`);\n }\n } catch (err) {\n const errorMessage = toErrorMessage(err);\n\n if (options.json) {\n console.log(\n JSON.stringify({\n success: false,\n error: errorMessage,\n } satisfies TrustResult)\n );\n process.exit(1);\n } else {\n console.error(`Error: ${errorMessage}`);\n process.exit(1);\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,410 @@
1
+ import {
2
+ toErrorMessage
3
+ } from "./chunk-PLQJM2KT.js";
4
+
5
+ // src/commands/validate-generator.ts
6
+ import { join, basename } from "path";
7
+ import { readFile, readdir } from "fs/promises";
8
+ import { pathToFileURL } from "url";
9
+ function generateSampleFromSchema(schema) {
10
+ const schemaAny = schema;
11
+ const def = schemaAny.def;
12
+ const schemaType = def?.["type"] || def?.["typeName"] || schemaAny.type;
13
+ if (schemaType === "object" || "shape" in schemaAny) {
14
+ const shape = schemaAny.shape;
15
+ if (shape) {
16
+ const sample = {};
17
+ for (const [key, fieldSchema] of Object.entries(shape)) {
18
+ sample[key] = generateSampleFromSchema(fieldSchema);
19
+ }
20
+ return sample;
21
+ }
22
+ }
23
+ if (schemaType === "string") {
24
+ return "sample_string";
25
+ }
26
+ if (schemaType === "number") {
27
+ return 42;
28
+ }
29
+ if (schemaType === "boolean") {
30
+ return true;
31
+ }
32
+ if (schemaType === "array") {
33
+ const innerType = def?.["element"];
34
+ if (innerType) {
35
+ return [generateSampleFromSchema(innerType)];
36
+ }
37
+ return ["sample"];
38
+ }
39
+ if (schemaType === "enum") {
40
+ const entries = def?.["entries"];
41
+ if (entries) {
42
+ const values = Object.values(entries);
43
+ if (values.length > 0) {
44
+ return values[0];
45
+ }
46
+ }
47
+ return "enum_value";
48
+ }
49
+ if (schemaType === "optional") {
50
+ const innerType = def?.["innerType"];
51
+ if (innerType) {
52
+ return generateSampleFromSchema(innerType);
53
+ }
54
+ }
55
+ if (schemaType === "nullable") {
56
+ const innerType = def?.["innerType"];
57
+ if (innerType) {
58
+ return generateSampleFromSchema(innerType);
59
+ }
60
+ }
61
+ if (schemaType === "default") {
62
+ const defaultValue = def?.["defaultValue"];
63
+ if (defaultValue !== void 0) {
64
+ return typeof defaultValue === "function" ? defaultValue() : defaultValue;
65
+ }
66
+ const innerType = def?.["innerType"];
67
+ if (innerType) {
68
+ return generateSampleFromSchema(innerType);
69
+ }
70
+ }
71
+ return "unknown";
72
+ }
73
+ function validateTypeScriptSyntax(code) {
74
+ const errors = [];
75
+ const balanceChecks = [
76
+ ["{", "}", "braces"],
77
+ ["[", "]", "brackets"],
78
+ ["(", ")", "parentheses"]
79
+ ];
80
+ for (const [open, close, name] of balanceChecks) {
81
+ const openCount = (code.match(new RegExp(`\\${open}`, "g")) || []).length;
82
+ const closeCount = (code.match(new RegExp(`\\${close}`, "g")) || []).length;
83
+ if (openCount !== closeCount) {
84
+ errors.push(`Unbalanced ${name}: ${openCount} open, ${closeCount} close`);
85
+ }
86
+ }
87
+ const lines = code.split("\n");
88
+ for (let i = 0; i < lines.length; i++) {
89
+ const line = lines[i];
90
+ if (line.trim().startsWith("//")) continue;
91
+ const singleQuotes = (line.match(/'/g) || []).length;
92
+ const doubleQuotes = (line.match(/"/g) || []).length;
93
+ const _backticks = (line.match(/`/g) || []).length;
94
+ if (singleQuotes % 2 !== 0 && !line.includes("`")) {
95
+ if (!code.includes("`")) {
96
+ errors.push(`Unclosed single quote on line ${i + 1}`);
97
+ }
98
+ }
99
+ if (doubleQuotes % 2 !== 0 && !line.includes("`")) {
100
+ if (!code.includes("`")) {
101
+ errors.push(`Unclosed double quote on line ${i + 1}`);
102
+ }
103
+ }
104
+ }
105
+ if (/;\s*;/.test(code)) {
106
+ errors.push("Double semicolon detected");
107
+ }
108
+ if (/\(\s*\)[\s\n]*\{[\s\n]*\}[\s\n]*\(/.test(code)) {
109
+ errors.push("Empty function followed by call - possible syntax error");
110
+ }
111
+ return {
112
+ valid: errors.length === 0,
113
+ errors
114
+ };
115
+ }
116
+ function validatePythonSyntax(code) {
117
+ const errors = [];
118
+ const lines = code.split("\n");
119
+ let prevIndent = 0;
120
+ let inMultilineString = false;
121
+ for (let i = 0; i < lines.length; i++) {
122
+ const line = lines[i];
123
+ const tripleQuotes = (line.match(/"""|'''/g) || []).length;
124
+ if (tripleQuotes % 2 !== 0) {
125
+ inMultilineString = !inMultilineString;
126
+ }
127
+ if (inMultilineString) continue;
128
+ if (line.trim() === "" || line.trim().startsWith("#")) continue;
129
+ const indent = line.match(/^(\s*)/)?.[1]?.length || 0;
130
+ const hasTab = /^\s*\t/.test(line);
131
+ const hasSpace = /^\s* /.test(line);
132
+ if (hasTab && hasSpace) {
133
+ errors.push(`Mixed tabs and spaces on line ${i + 1}`);
134
+ }
135
+ const prevLine = i > 0 ? lines[i - 1].trim() : "";
136
+ if (prevLine.endsWith(":") && indent <= prevIndent && !line.trim().startsWith("#")) {
137
+ errors.push(`Expected indented block after line ${i}`);
138
+ }
139
+ prevIndent = indent;
140
+ }
141
+ const balanceChecks = [
142
+ ["(", ")", "parentheses"],
143
+ ["[", "]", "brackets"],
144
+ ["{", "}", "braces"]
145
+ ];
146
+ for (const [open, close, name] of balanceChecks) {
147
+ const openCount = (code.match(new RegExp(`\\${open}`, "g")) || []).length;
148
+ const closeCount = (code.match(new RegExp(`\\${close}`, "g")) || []).length;
149
+ if (openCount !== closeCount) {
150
+ errors.push(`Unbalanced ${name}: ${openCount} open, ${closeCount} close`);
151
+ }
152
+ }
153
+ return {
154
+ valid: errors.length === 0,
155
+ errors
156
+ };
157
+ }
158
+ function validateSQLSyntax(code) {
159
+ const errors = [];
160
+ const normalizedCode = code.toUpperCase();
161
+ const openParens = (code.match(/\(/g) || []).length;
162
+ const closeParens = (code.match(/\)/g) || []).length;
163
+ if (openParens !== closeParens) {
164
+ errors.push(`Unbalanced parentheses: ${openParens} open, ${closeParens} close`);
165
+ }
166
+ const singleQuotes = (code.match(/'/g) || []).length;
167
+ if (singleQuotes % 2 !== 0) {
168
+ errors.push("Unclosed single quote in SQL");
169
+ }
170
+ if (normalizedCode.includes("SELECT") && !normalizedCode.includes("FROM")) {
171
+ if (!/SELECT\s+(?:[\d'"@]|\w+(?:\.\w+)?\s*\(|CURRENT_(?:DATE|TIME|TIMESTAMP)|TRUE|FALSE|NULL)\b/i.test(code)) {
172
+ errors.push("SELECT statement without FROM clause");
173
+ }
174
+ }
175
+ return {
176
+ valid: errors.length === 0,
177
+ errors
178
+ };
179
+ }
180
+ function validateMarkdownSyntax(code) {
181
+ const errors = [];
182
+ const codeBlockCount = (code.match(/```/g) || []).length;
183
+ if (codeBlockCount % 2 !== 0) {
184
+ errors.push("Unclosed code block (```)");
185
+ }
186
+ const withoutCodeBlocks = code.replace(/```[\s\S]*?```/g, "");
187
+ const inlineBackticks = (withoutCodeBlocks.match(/`/g) || []).length;
188
+ if (inlineBackticks % 2 !== 0) {
189
+ errors.push("Unclosed inline code (`)");
190
+ }
191
+ return {
192
+ valid: errors.length === 0,
193
+ errors
194
+ };
195
+ }
196
+ function validateSyntax(code, language) {
197
+ switch (language.toLowerCase()) {
198
+ case "typescript":
199
+ case "javascript":
200
+ case "js":
201
+ case "ts":
202
+ return validateTypeScriptSyntax(code);
203
+ case "python":
204
+ case "py":
205
+ return validatePythonSyntax(code);
206
+ case "sql":
207
+ return validateSQLSyntax(code);
208
+ case "markdown":
209
+ case "md":
210
+ return validateMarkdownSyntax(code);
211
+ default:
212
+ return validateTypeScriptSyntax(code);
213
+ }
214
+ }
215
+ async function listGenerators(generatorsDir) {
216
+ try {
217
+ const entries = await readdir(generatorsDir, { withFileTypes: true });
218
+ return entries.filter((e) => e.isFile() && e.name.endsWith(".ts") && !e.name.endsWith(".test.ts")).map((e) => e.name.replace(".ts", ""));
219
+ } catch (err) {
220
+ if (err instanceof Error && "code" in err && err.code !== "ENOENT") {
221
+ console.warn(`Warning: Could not read generators directory: ${err.message}`);
222
+ }
223
+ return [];
224
+ }
225
+ }
226
+ async function validateGenerator(generatorPath) {
227
+ const generatorName = basename(generatorPath, ".ts");
228
+ const result = {
229
+ success: false,
230
+ generatorName,
231
+ generatorPath,
232
+ language: "unknown",
233
+ sampleParams: {},
234
+ output: "",
235
+ syntaxValid: false,
236
+ syntaxErrors: [],
237
+ warnings: [],
238
+ errors: []
239
+ };
240
+ let content;
241
+ try {
242
+ content = await readFile(generatorPath, "utf-8");
243
+ } catch (err) {
244
+ result.errors.push(`Failed to read generator: ${toErrorMessage(err)}`);
245
+ return result;
246
+ }
247
+ const languageMatch = content.match(/language:\s*['"`]([a-zA-Z0-9_-]+)['"`]/);
248
+ result.language = languageMatch?.[1]?.toLowerCase() || "typescript";
249
+ let module;
250
+ try {
251
+ const fileUrl = pathToFileURL(generatorPath).href;
252
+ module = await import(fileUrl);
253
+ } catch (err) {
254
+ result.errors.push(`Failed to import generator: ${toErrorMessage(err)}`);
255
+ return result;
256
+ }
257
+ const gen = module.generator || module.default;
258
+ const paramsSchema = module.paramsSchema || gen?.params;
259
+ const templateFn = module.template || gen?.template;
260
+ if (gen?.language) {
261
+ result.language = String(gen.language).toLowerCase();
262
+ }
263
+ if (!templateFn) {
264
+ result.errors.push("Generator missing template function");
265
+ return result;
266
+ }
267
+ if (paramsSchema) {
268
+ try {
269
+ const sample = generateSampleFromSchema(paramsSchema);
270
+ if (sample && typeof sample === "object" && !Array.isArray(sample)) {
271
+ result.sampleParams = sample;
272
+ } else {
273
+ result.warnings.push("Params schema did not produce an object - generators typically use object schemas");
274
+ result.sampleParams = {};
275
+ }
276
+ } catch (err) {
277
+ result.warnings.push(`Could not generate sample params: ${toErrorMessage(err)}`);
278
+ result.sampleParams = {};
279
+ }
280
+ }
281
+ try {
282
+ result.output = templateFn(result.sampleParams);
283
+ } catch (err) {
284
+ result.errors.push(`Template execution failed: ${toErrorMessage(err)}`);
285
+ return result;
286
+ }
287
+ const syntaxResult = validateSyntax(result.output, result.language);
288
+ result.syntaxValid = syntaxResult.valid;
289
+ result.syntaxErrors = syntaxResult.errors;
290
+ if (!syntaxResult.valid) {
291
+ result.warnings.push("Output has syntax issues that may need review");
292
+ }
293
+ if (result.output.includes("TODO")) {
294
+ result.warnings.push("Template contains TODO markers - implementation may be incomplete");
295
+ }
296
+ result.success = result.errors.length === 0;
297
+ return result;
298
+ }
299
+ async function validateGeneratorCommand(options) {
300
+ const projectRoot = process.cwd();
301
+ const generatorsDir = join(projectRoot, "generators");
302
+ if (!options.generator && !options.all) {
303
+ if (options.json) {
304
+ console.log(JSON.stringify({
305
+ success: false,
306
+ error: "Must specify --generator <name> or --all"
307
+ }));
308
+ } else {
309
+ console.error("Error: Must specify --generator <name> or --all");
310
+ console.error("");
311
+ console.error("Usage:");
312
+ console.error(" atomic validate-generator --generator <name>");
313
+ console.error(" atomic validate-generator --all");
314
+ }
315
+ process.exit(1);
316
+ }
317
+ let generators;
318
+ if (options.all) {
319
+ generators = await listGenerators(generatorsDir);
320
+ if (generators.length === 0) {
321
+ if (options.json) {
322
+ console.log(JSON.stringify({
323
+ success: false,
324
+ error: "No generators found in generators/ directory"
325
+ }));
326
+ } else {
327
+ console.error("No generators found in generators/ directory");
328
+ }
329
+ process.exit(1);
330
+ }
331
+ } else {
332
+ generators = [options.generator];
333
+ }
334
+ const results = [];
335
+ let allPassed = true;
336
+ for (const generatorName of generators) {
337
+ const generatorPath = join(generatorsDir, `${generatorName}.ts`);
338
+ const result = await validateGenerator(generatorPath);
339
+ results.push(result);
340
+ if (!result.success || !result.syntaxValid) {
341
+ allPassed = false;
342
+ }
343
+ }
344
+ if (options.json) {
345
+ console.log(JSON.stringify({
346
+ success: allPassed,
347
+ results
348
+ }));
349
+ if (!allPassed) {
350
+ process.exit(1);
351
+ }
352
+ return;
353
+ }
354
+ console.log(`Validated ${results.length} generator${results.length === 1 ? "" : "s"}:
355
+ `);
356
+ for (const result of results) {
357
+ const status = result.success && result.syntaxValid ? "\u2713" : "\u2717";
358
+ console.log(`${status} ${result.generatorName}`);
359
+ console.log(` Path: ${result.generatorPath}`);
360
+ console.log(` Language: ${result.language}`);
361
+ if (Object.keys(result.sampleParams).length > 0) {
362
+ console.log(` Sample params: ${JSON.stringify(result.sampleParams)}`);
363
+ }
364
+ if (result.output) {
365
+ const outputPreview = result.output.length > 100 ? result.output.substring(0, 100) + "..." : result.output;
366
+ console.log(` Output preview: ${outputPreview.replace(/\n/g, "\\n")}`);
367
+ }
368
+ if (result.syntaxValid) {
369
+ console.log(" Syntax: \u2713 Valid");
370
+ } else {
371
+ console.log(" Syntax: \u2717 Invalid");
372
+ for (const error of result.syntaxErrors) {
373
+ console.log(` - ${error}`);
374
+ }
375
+ }
376
+ if (result.warnings.length > 0) {
377
+ console.log(" Warnings:");
378
+ for (const warning of result.warnings) {
379
+ console.log(` \u26A0 ${warning}`);
380
+ }
381
+ }
382
+ if (result.errors.length > 0) {
383
+ console.log(" Errors:");
384
+ for (const error of result.errors) {
385
+ console.log(` \u2717 ${error}`);
386
+ }
387
+ }
388
+ console.log("");
389
+ }
390
+ const passed = results.filter((r) => r.success && r.syntaxValid).length;
391
+ const failed = results.length - passed;
392
+ if (failed > 0) {
393
+ console.log(`Summary: ${passed} passed, ${failed} failed`);
394
+ process.exit(1);
395
+ } else {
396
+ console.log(`Summary: All ${passed} generator${passed === 1 ? "" : "s"} passed validation`);
397
+ }
398
+ }
399
+ export {
400
+ generateSampleFromSchema,
401
+ listGenerators,
402
+ validateGenerator,
403
+ validateGeneratorCommand,
404
+ validateMarkdownSyntax,
405
+ validatePythonSyntax,
406
+ validateSQLSyntax,
407
+ validateSyntax,
408
+ validateTypeScriptSyntax
409
+ };
410
+ //# sourceMappingURL=validate-generator-46H2LYYQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/validate-generator.ts"],"sourcesContent":["/**\n * Validate generator command.\n *\n * Validates imported generators by executing them with sample params\n * and checking output syntax.\n *\n * @module commands/validate-generator\n */\n\nimport { join, basename } from 'node:path';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { pathToFileURL } from 'node:url';\nimport { z } from 'zod';\nimport { toErrorMessage } from '../utils/errors.js';\n\n/**\n * Validation result for a generator.\n */\nexport interface ValidationResult {\n success: boolean;\n generatorName: string;\n generatorPath: string;\n language: string;\n sampleParams: Record<string, unknown>;\n output: string;\n syntaxValid: boolean;\n syntaxErrors: string[];\n warnings: string[];\n errors: string[];\n}\n\n/**\n * Generator module interface (what we expect from imported generators).\n */\ninterface GeneratorModule {\n paramsSchema?: z.ZodType;\n template?: (params: unknown) => string;\n generator?: {\n name: string;\n description?: string;\n params?: z.ZodType;\n template?: (params: unknown) => string;\n language?: string;\n };\n default?: {\n name: string;\n description?: string;\n params?: z.ZodType;\n template?: (params: unknown) => string;\n language?: string;\n };\n}\n\n/**\n * Generate sample data from a Zod schema.\n * Uses duck typing to detect schema types for compatibility across Zod versions.\n */\nexport function generateSampleFromSchema(schema: z.ZodType): unknown {\n // Use duck typing to detect schema types\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const schemaAny = schema as any;\n const def = schemaAny.def as Record<string, unknown> | undefined;\n // Zod 4 uses 'type' field instead of 'typeName'\n const schemaType = (def?.['type'] as string | undefined) ||\n (def?.['typeName'] as string | undefined) ||\n (schemaAny.type as string | undefined);\n\n // For object schemas\n if (schemaType === 'object' || 'shape' in schemaAny) {\n const shape = schemaAny.shape as Record<string, z.ZodType> | undefined;\n if (shape) {\n const sample: Record<string, unknown> = {};\n for (const [key, fieldSchema] of Object.entries(shape)) {\n sample[key] = generateSampleFromSchema(fieldSchema);\n }\n return sample;\n }\n }\n\n // For string schemas\n if (schemaType === 'string') {\n return 'sample_string';\n }\n\n // For number schemas\n if (schemaType === 'number') {\n return 42;\n }\n\n // For boolean schemas\n if (schemaType === 'boolean') {\n return true;\n }\n\n // For array schemas\n if (schemaType === 'array') {\n const innerType = def?.['element'] as z.ZodType | undefined;\n if (innerType) {\n return [generateSampleFromSchema(innerType)];\n }\n return ['sample'];\n }\n\n // For enum schemas\n if (schemaType === 'enum') {\n const entries = def?.['entries'] as Record<string, string> | undefined;\n if (entries) {\n const values = Object.values(entries);\n if (values.length > 0) {\n return values[0];\n }\n }\n return 'enum_value';\n }\n\n // For optional schemas - use inner type\n if (schemaType === 'optional') {\n const innerType = def?.['innerType'] as z.ZodType | undefined;\n if (innerType) {\n return generateSampleFromSchema(innerType);\n }\n }\n\n // For nullable schemas - use inner type (treat like optional)\n if (schemaType === 'nullable') {\n const innerType = def?.['innerType'] as z.ZodType | undefined;\n if (innerType) {\n return generateSampleFromSchema(innerType);\n }\n }\n\n // For default schemas - use default value\n if (schemaType === 'default') {\n const defaultValue = def?.['defaultValue'] as unknown;\n if (defaultValue !== undefined) {\n return typeof defaultValue === 'function' ? (defaultValue as () => unknown)() : defaultValue;\n }\n // Fall through to inner type\n const innerType = def?.['innerType'] as z.ZodType | undefined;\n if (innerType) {\n return generateSampleFromSchema(innerType);\n }\n }\n\n // Fallback\n return 'unknown';\n}\n\n/**\n * Validate TypeScript/JavaScript syntax.\n *\n * NOTE: This is a basic syntax check without full AST parsing.\n * Known limitations:\n * - Escaped quotes (e.g., 'it\\'s') may be flagged as unbalanced\n * - Block comments are not excluded from quote checks\n */\nexport function validateTypeScriptSyntax(code: string): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Basic syntax checks without full AST parsing\n // Check balanced braces, brackets, parentheses\n const balanceChecks: Array<[string, string, string]> = [\n ['{', '}', 'braces'],\n ['[', ']', 'brackets'],\n ['(', ')', 'parentheses'],\n ];\n\n for (const [open, close, name] of balanceChecks) {\n const openCount = (code.match(new RegExp(`\\\\${open}`, 'g')) || []).length;\n const closeCount = (code.match(new RegExp(`\\\\${close}`, 'g')) || []).length;\n if (openCount !== closeCount) {\n errors.push(`Unbalanced ${name}: ${openCount} open, ${closeCount} close`);\n }\n }\n\n // Check for unclosed strings (simple check)\n const lines = code.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n // Skip lines that are just comments\n if (line.trim().startsWith('//')) continue;\n\n // Count quotes (simplified - doesn't handle escaped quotes perfectly)\n const singleQuotes = (line.match(/'/g) || []).length;\n const doubleQuotes = (line.match(/\"/g) || []).length;\n const _backticks = (line.match(/`/g) || []).length;\n\n // Template literals can span lines, so we only check single/double in single lines\n if (singleQuotes % 2 !== 0 && !line.includes('`')) {\n // Could be a valid template string continuation\n if (!code.includes('`')) {\n errors.push(`Unclosed single quote on line ${i + 1}`);\n }\n }\n if (doubleQuotes % 2 !== 0 && !line.includes('`')) {\n if (!code.includes('`')) {\n errors.push(`Unclosed double quote on line ${i + 1}`);\n }\n }\n }\n\n // Check for common syntax errors\n if (/;\\s*;/.test(code)) {\n errors.push('Double semicolon detected');\n }\n\n if (/\\(\\s*\\)[\\s\\n]*\\{[\\s\\n]*\\}[\\s\\n]*\\(/.test(code)) {\n errors.push('Empty function followed by call - possible syntax error');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Validate Python syntax.\n */\nexport function validatePythonSyntax(code: string): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check indentation consistency\n const lines = code.split('\\n');\n let prevIndent = 0;\n let inMultilineString = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n\n // Track multiline strings\n const tripleQuotes = (line.match(/\"\"\"|'''/g) || []).length;\n if (tripleQuotes % 2 !== 0) {\n inMultilineString = !inMultilineString;\n }\n\n if (inMultilineString) continue;\n if (line.trim() === '' || line.trim().startsWith('#')) continue;\n\n const indent = line.match(/^(\\s*)/)?.[1]?.length || 0;\n\n // Check for tab/space mixing\n const hasTab = /^\\s*\\t/.test(line);\n const hasSpace = /^\\s* /.test(line);\n if (hasTab && hasSpace) {\n errors.push(`Mixed tabs and spaces on line ${i + 1}`);\n }\n\n // Check for statements that require indented blocks\n const prevLine = i > 0 ? lines[i - 1]!.trim() : '';\n if (prevLine.endsWith(':') && indent <= prevIndent && !line.trim().startsWith('#')) {\n errors.push(`Expected indented block after line ${i}`);\n }\n\n prevIndent = indent;\n }\n\n // Check balanced parentheses/brackets/braces\n const balanceChecks: Array<[string, string, string]> = [\n ['(', ')', 'parentheses'],\n ['[', ']', 'brackets'],\n ['{', '}', 'braces'],\n ];\n\n for (const [open, close, name] of balanceChecks) {\n const openCount = (code.match(new RegExp(`\\\\${open}`, 'g')) || []).length;\n const closeCount = (code.match(new RegExp(`\\\\${close}`, 'g')) || []).length;\n if (openCount !== closeCount) {\n errors.push(`Unbalanced ${name}: ${openCount} open, ${closeCount} close`);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Validate SQL syntax.\n */\nexport function validateSQLSyntax(code: string): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check for common SQL syntax patterns\n const normalizedCode = code.toUpperCase();\n\n // Check for unbalanced parentheses\n const openParens = (code.match(/\\(/g) || []).length;\n const closeParens = (code.match(/\\)/g) || []).length;\n if (openParens !== closeParens) {\n errors.push(`Unbalanced parentheses: ${openParens} open, ${closeParens} close`);\n }\n\n // Check for unclosed quotes\n const singleQuotes = (code.match(/'/g) || []).length;\n if (singleQuotes % 2 !== 0) {\n errors.push('Unclosed single quote in SQL');\n }\n\n // Check for SELECT without FROM (unless it's a simple value or function select)\n if (normalizedCode.includes('SELECT') && !normalizedCode.includes('FROM')) {\n // Allow SELECT 1, SELECT 'value', SELECT @variable, SELECT NOW(), SELECT CURRENT_DATE, etc.\n // Pattern allows: numbers, quotes, variables (@), function calls, schema.function(), and SQL constants\n if (!/SELECT\\s+(?:[\\d'\"@]|\\w+(?:\\.\\w+)?\\s*\\(|CURRENT_(?:DATE|TIME|TIMESTAMP)|TRUE|FALSE|NULL)\\b/i.test(code)) {\n errors.push('SELECT statement without FROM clause');\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Validate Markdown syntax.\n */\nexport function validateMarkdownSyntax(code: string): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n // Check for unclosed code blocks\n const codeBlockCount = (code.match(/```/g) || []).length;\n if (codeBlockCount % 2 !== 0) {\n errors.push('Unclosed code block (```)');\n }\n\n // Check for unclosed inline code\n // This is tricky as backticks in code blocks are valid\n // Just do a simple check outside code blocks\n const withoutCodeBlocks = code.replace(/```[\\s\\S]*?```/g, '');\n const inlineBackticks = (withoutCodeBlocks.match(/`/g) || []).length;\n if (inlineBackticks % 2 !== 0) {\n errors.push('Unclosed inline code (`)');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Validate output based on language.\n */\nexport function validateSyntax(\n code: string,\n language: string\n): { valid: boolean; errors: string[] } {\n switch (language.toLowerCase()) {\n case 'typescript':\n case 'javascript':\n case 'js':\n case 'ts':\n return validateTypeScriptSyntax(code);\n case 'python':\n case 'py':\n return validatePythonSyntax(code);\n case 'sql':\n return validateSQLSyntax(code);\n case 'markdown':\n case 'md':\n return validateMarkdownSyntax(code);\n default:\n // For unknown languages, just check basic balance\n return validateTypeScriptSyntax(code);\n }\n}\n\n/**\n * List available generators.\n */\nexport async function listGenerators(generatorsDir: string): Promise<string[]> {\n try {\n const entries = await readdir(generatorsDir, { withFileTypes: true });\n return entries\n .filter((e) => e.isFile() && e.name.endsWith('.ts') && !e.name.endsWith('.test.ts'))\n .map((e) => e.name.replace('.ts', ''));\n } catch (err) {\n // ENOENT is expected for missing directories; log other errors\n if (err instanceof Error && 'code' in err && (err as NodeJS.ErrnoException).code !== 'ENOENT') {\n console.warn(`Warning: Could not read generators directory: ${err.message}`);\n }\n return [];\n }\n}\n\n/**\n * Validate a generator.\n */\nexport async function validateGenerator(\n generatorPath: string\n): Promise<ValidationResult> {\n const generatorName = basename(generatorPath, '.ts');\n\n const result: ValidationResult = {\n success: false,\n generatorName,\n generatorPath,\n language: 'unknown',\n sampleParams: {},\n output: '',\n syntaxValid: false,\n syntaxErrors: [],\n warnings: [],\n errors: [],\n };\n\n // Check file exists\n let content: string;\n try {\n content = await readFile(generatorPath, 'utf-8');\n } catch (err) {\n result.errors.push(`Failed to read generator: ${toErrorMessage(err)}`);\n return result;\n }\n\n // Try to detect language from content (supports quotes, backticks, and hyphenated names)\n const languageMatch = content.match(/language:\\s*['\"`]([a-zA-Z0-9_-]+)['\"`]/);\n result.language = languageMatch?.[1]?.toLowerCase() || 'typescript';\n\n // Try to dynamically import the generator\n let module: GeneratorModule;\n try {\n const fileUrl = pathToFileURL(generatorPath).href;\n module = await import(fileUrl);\n } catch (err) {\n result.errors.push(`Failed to import generator: ${toErrorMessage(err)}`);\n return result;\n }\n\n // Get generator metadata\n const gen = module.generator || module.default;\n const paramsSchema = module.paramsSchema || gen?.params;\n const templateFn = module.template || gen?.template;\n\n // Prefer exported language over regex-detected (more reliable)\n if (gen?.language) {\n result.language = String(gen.language).toLowerCase();\n }\n\n if (!templateFn) {\n result.errors.push('Generator missing template function');\n return result;\n }\n\n // Generate sample params (expects paramsSchema to be an object schema)\n if (paramsSchema) {\n try {\n const sample = generateSampleFromSchema(paramsSchema);\n // Ensure sample is an object (generator params are typically objects)\n if (sample && typeof sample === 'object' && !Array.isArray(sample)) {\n result.sampleParams = sample as Record<string, unknown>;\n } else {\n result.warnings.push('Params schema did not produce an object - generators typically use object schemas');\n result.sampleParams = {};\n }\n } catch (err) {\n result.warnings.push(`Could not generate sample params: ${toErrorMessage(err)}`);\n result.sampleParams = {};\n }\n }\n\n // Execute template with sample params\n try {\n result.output = templateFn(result.sampleParams);\n } catch (err) {\n result.errors.push(`Template execution failed: ${toErrorMessage(err)}`);\n return result;\n }\n\n // Validate output syntax\n const syntaxResult = validateSyntax(result.output, result.language);\n result.syntaxValid = syntaxResult.valid;\n result.syntaxErrors = syntaxResult.errors;\n\n if (!syntaxResult.valid) {\n result.warnings.push('Output has syntax issues that may need review');\n }\n\n // Check for TODO markers indicating incomplete template\n if (result.output.includes('TODO')) {\n result.warnings.push('Template contains TODO markers - implementation may be incomplete');\n }\n\n result.success = result.errors.length === 0;\n\n return result;\n}\n\nexport interface ValidateGeneratorOptions {\n generator?: string;\n all?: boolean;\n json?: boolean;\n}\n\n/**\n * Execute the validate-generator command.\n */\nexport async function validateGeneratorCommand(\n options: ValidateGeneratorOptions\n): Promise<void> {\n const projectRoot = process.cwd();\n const generatorsDir = join(projectRoot, 'generators');\n\n if (!options.generator && !options.all) {\n if (options.json) {\n console.log(JSON.stringify({\n success: false,\n error: 'Must specify --generator <name> or --all',\n }));\n } else {\n console.error('Error: Must specify --generator <name> or --all');\n console.error('');\n console.error('Usage:');\n console.error(' atomic validate-generator --generator <name>');\n console.error(' atomic validate-generator --all');\n }\n process.exit(1);\n }\n\n let generators: string[];\n\n if (options.all) {\n generators = await listGenerators(generatorsDir);\n if (generators.length === 0) {\n if (options.json) {\n console.log(JSON.stringify({\n success: false,\n error: 'No generators found in generators/ directory',\n }));\n } else {\n console.error('No generators found in generators/ directory');\n }\n process.exit(1);\n }\n } else {\n generators = [options.generator!];\n }\n\n const results: ValidationResult[] = [];\n let allPassed = true;\n\n for (const generatorName of generators) {\n const generatorPath = join(generatorsDir, `${generatorName}.ts`);\n const result = await validateGenerator(generatorPath);\n results.push(result);\n\n if (!result.success || !result.syntaxValid) {\n allPassed = false;\n }\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n success: allPassed,\n results,\n }));\n if (!allPassed) {\n process.exit(1);\n }\n return;\n }\n\n // Human-readable output\n console.log(`Validated ${results.length} generator${results.length === 1 ? '' : 's'}:\\n`);\n\n for (const result of results) {\n const status = result.success && result.syntaxValid ? '✓' : '✗';\n console.log(`${status} ${result.generatorName}`);\n console.log(` Path: ${result.generatorPath}`);\n console.log(` Language: ${result.language}`);\n\n if (Object.keys(result.sampleParams).length > 0) {\n console.log(` Sample params: ${JSON.stringify(result.sampleParams)}`);\n }\n\n if (result.output) {\n const outputPreview = result.output.length > 100\n ? result.output.substring(0, 100) + '...'\n : result.output;\n console.log(` Output preview: ${outputPreview.replace(/\\n/g, '\\\\n')}`);\n }\n\n if (result.syntaxValid) {\n console.log(' Syntax: ✓ Valid');\n } else {\n console.log(' Syntax: ✗ Invalid');\n for (const error of result.syntaxErrors) {\n console.log(` - ${error}`);\n }\n }\n\n if (result.warnings.length > 0) {\n console.log(' Warnings:');\n for (const warning of result.warnings) {\n console.log(` ⚠ ${warning}`);\n }\n }\n\n if (result.errors.length > 0) {\n console.log(' Errors:');\n for (const error of result.errors) {\n console.log(` ✗ ${error}`);\n }\n }\n\n console.log('');\n }\n\n // Summary\n const passed = results.filter((r) => r.success && r.syntaxValid).length;\n const failed = results.length - passed;\n\n if (failed > 0) {\n console.log(`Summary: ${passed} passed, ${failed} failed`);\n process.exit(1);\n } else {\n console.log(`Summary: All ${passed} generator${passed === 1 ? '' : 's'} passed validation`);\n }\n}\n"],"mappings":"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","names":[]}