@@ -14,8 +14,10 @@ import { initCommand } from '../templates/init-command.js';
1414import { DSLIntrospector } from '../dsl/introspection.js' ;
1515import { parseWorkflowFile } from '../parsing/parser.js' ;
1616import { Command } from 'commander' ;
17+ import { execFileSync } from 'child_process' ;
1718import * as path from 'path' ;
1819import * as fs from 'fs' ;
20+ import * as os from 'os' ;
1921
2022// Simple error handling - no fancy logging or correlation IDs
2123function handleError ( error : unknown , operation : string ) : never {
@@ -53,6 +55,29 @@ async function writeScriptToFile(script: string, outputFile: string): Promise<vo
5355 }
5456}
5557
58+ /**
59+ * Validate generated script for bash syntax errors.
60+ */
61+ function validateBashSyntax ( script : string ) : void {
62+ const tempDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'flowsh-syntax-check-' ) ) ;
63+ const tempFile = path . join ( tempDir , 'script.sh' ) ;
64+
65+ try {
66+ fs . writeFileSync ( tempFile , script , 'utf8' ) ;
67+ execFileSync ( 'bash' , [ '-n' , tempFile ] , { stdio : 'pipe' } ) ;
68+ } catch ( error : any ) {
69+ const errorOutput = error ?. stderr ?. toString ?. ( ) || error ?. message || 'Unknown bash error' ;
70+ throw new Error ( `Bash syntax validation failed:\n${ errorOutput } ` ) ;
71+ } finally {
72+ try {
73+ fs . unlinkSync ( tempFile ) ;
74+ fs . rmdirSync ( tempDir ) ;
75+ } catch {
76+ // Best-effort cleanup
77+ }
78+ }
79+ }
80+
5681/**
5782 * Compile command: Convert YAML workflow to shell script
5883 */
@@ -123,6 +148,16 @@ async function compileCommand(
123148 finalScript = warnings . join ( '\n' ) + '\n' + finalScript ;
124149 }
125150
151+ if ( options . verbose ) {
152+ console . error ( '🔍 Validating bash syntax...' ) ;
153+ }
154+
155+ validateBashSyntax ( finalScript ) ;
156+
157+ if ( options . verbose ) {
158+ console . error ( '✅ Bash syntax validation passed' ) ;
159+ }
160+
126161 // Dry-run mode: validate and compile but don't output
127162 if ( options . dryRun ) {
128163 const nodeCount = parseResult . workflow ?. graph ?. nodes ?. length || 0 ;
0 commit comments