File size: 2,902 Bytes
391c43e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
 * Compile Error Accumulator
 *
 * Module-level store for compilation errors (Handlebars and esbuild) detected by VirtualServer.
 * VirtualServer pushes errors during compileProject(); the `build` shell command drains them
 * to give the AI explicit compilation feedback.
 *
 * Errors are collated per compilation: each compileProject() call replaces the
 * previous set so `build` always sees the latest state.
 */

export interface CompileError {
  file: string;
  error: string;
}

let pendingErrors: CompileError[] = [];
let stagingErrors: CompileError[] = [];

/**
 * Called at the start of compileProject() to begin a fresh error collection.
 */
export function beginCompilation(): void {
  stagingErrors = [];
}

/**
 * Called during compilation when an error is caught.
 * Errors accumulate in staging during a single compilation.
 */
export function pushCompileError(file: string, error: string): void {
  stagingErrors.push({ file, error });
}

/**
 * Called at the end of compileProject() to commit staged errors.
 * Replaces any previous pending errors (only latest compilation matters).
 */
export function commitCompilation(): void {
  pendingErrors = stagingErrors;
  stagingErrors = [];

  // Notify listeners (console panel, orchestrator sync) about compilation result
  if (typeof window !== 'undefined') {
    window.dispatchEvent(new CustomEvent('compilationComplete', {
      detail: {
        errors: [...pendingErrors],
        success: pendingErrors.length === 0,
        timestamp: Date.now(),
      },
    }));
  }
}

/**
 * Called by the `build` shell command to consume accumulated errors.
 * Returns all errors and clears the buffer.
 */
export function drainCompileErrors(): CompileError[] {
  const errors = pendingErrors;
  pendingErrors = [];
  return errors;
}

/**
 * Format drained errors into a message suitable for the LLM.
 */
export function formatCompileErrors(errors: CompileError[]): string {
  const grouped = new Map<string, string[]>();
  for (const { file, error } of errors) {
    const list = grouped.get(file) || [];
    list.push(error);
    grouped.set(file, list);
  }

  const parts: string[] = [];
  for (const [file, errs] of grouped) {
    parts.push(`${file}:\n${errs.map(e => `  - ${e}`).join('\n')}`);
  }

  const hasEsbuildErrors = errors.some(e => e.error.startsWith('[esbuild]'));
  const hasScriptErrors = errors.some(e => e.file === 'script' || e.file.endsWith('.py') || e.file.endsWith('.lua'));
  const prefix = hasScriptErrors
    ? 'Runtime errors detected during script execution. Fix these issues:\n\n'
    : hasEsbuildErrors
      ? 'Build errors detected during compilation. Fix these issues:\n\n'
      : 'The preview detected possible Handlebars template issues after compilation. Verify whether these are still present — they may already be resolved by recent edits:\n\n';

  return `${prefix}${parts.join('\n\n')}`;
}