@vibe-lang/runtime 0.2.5

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 (250) hide show
  1. package/package.json +46 -0
  2. package/src/ast/index.ts +375 -0
  3. package/src/ast.ts +2 -0
  4. package/src/debug/advanced-features.ts +482 -0
  5. package/src/debug/bun-inspector.ts +424 -0
  6. package/src/debug/handoff-manager.ts +283 -0
  7. package/src/debug/index.ts +150 -0
  8. package/src/debug/runner.ts +365 -0
  9. package/src/debug/server.ts +565 -0
  10. package/src/debug/stack-merger.ts +267 -0
  11. package/src/debug/state.ts +581 -0
  12. package/src/debug/test/advanced-features.test.ts +300 -0
  13. package/src/debug/test/e2e.test.ts +218 -0
  14. package/src/debug/test/handoff-manager.test.ts +256 -0
  15. package/src/debug/test/runner.test.ts +256 -0
  16. package/src/debug/test/stack-merger.test.ts +163 -0
  17. package/src/debug/test/state.test.ts +400 -0
  18. package/src/debug/test/ts-debug-integration.test.ts +374 -0
  19. package/src/debug/test/ts-import-tracker.test.ts +125 -0
  20. package/src/debug/test/ts-source-map.test.ts +169 -0
  21. package/src/debug/ts-import-tracker.ts +151 -0
  22. package/src/debug/ts-source-map.ts +171 -0
  23. package/src/errors/index.ts +124 -0
  24. package/src/index.ts +358 -0
  25. package/src/lexer/index.ts +348 -0
  26. package/src/lexer.ts +2 -0
  27. package/src/parser/index.ts +792 -0
  28. package/src/parser/parse.ts +45 -0
  29. package/src/parser/test/async.test.ts +248 -0
  30. package/src/parser/test/destructuring.test.ts +167 -0
  31. package/src/parser/test/do-expression.test.ts +486 -0
  32. package/src/parser/test/errors/do-expression.test.ts +95 -0
  33. package/src/parser/test/errors/error-locations.test.ts +230 -0
  34. package/src/parser/test/errors/invalid-expressions.test.ts +144 -0
  35. package/src/parser/test/errors/missing-tokens.test.ts +126 -0
  36. package/src/parser/test/errors/model-declaration.test.ts +185 -0
  37. package/src/parser/test/errors/nested-blocks.test.ts +226 -0
  38. package/src/parser/test/errors/unclosed-delimiters.test.ts +122 -0
  39. package/src/parser/test/errors/unexpected-tokens.test.ts +120 -0
  40. package/src/parser/test/import-export.test.ts +143 -0
  41. package/src/parser/test/literals.test.ts +404 -0
  42. package/src/parser/test/model-declaration.test.ts +161 -0
  43. package/src/parser/test/nested-blocks.test.ts +402 -0
  44. package/src/parser/test/parser.test.ts +743 -0
  45. package/src/parser/test/private.test.ts +136 -0
  46. package/src/parser/test/template-literal.test.ts +127 -0
  47. package/src/parser/test/tool-declaration.test.ts +302 -0
  48. package/src/parser/test/ts-block.test.ts +252 -0
  49. package/src/parser/test/type-annotations.test.ts +254 -0
  50. package/src/parser/visitor/helpers.ts +330 -0
  51. package/src/parser/visitor.ts +794 -0
  52. package/src/parser.ts +2 -0
  53. package/src/runtime/ai/cache-chunking.test.ts +69 -0
  54. package/src/runtime/ai/cache-chunking.ts +73 -0
  55. package/src/runtime/ai/client.ts +109 -0
  56. package/src/runtime/ai/context.ts +168 -0
  57. package/src/runtime/ai/formatters.ts +316 -0
  58. package/src/runtime/ai/index.ts +38 -0
  59. package/src/runtime/ai/language-ref.ts +38 -0
  60. package/src/runtime/ai/providers/anthropic.ts +253 -0
  61. package/src/runtime/ai/providers/google.ts +201 -0
  62. package/src/runtime/ai/providers/openai.ts +156 -0
  63. package/src/runtime/ai/retry.ts +100 -0
  64. package/src/runtime/ai/return-tools.ts +301 -0
  65. package/src/runtime/ai/test/client.test.ts +83 -0
  66. package/src/runtime/ai/test/formatters.test.ts +485 -0
  67. package/src/runtime/ai/test/retry.test.ts +137 -0
  68. package/src/runtime/ai/test/return-tools.test.ts +450 -0
  69. package/src/runtime/ai/test/tool-loop.test.ts +319 -0
  70. package/src/runtime/ai/test/tool-schema.test.ts +241 -0
  71. package/src/runtime/ai/tool-loop.ts +203 -0
  72. package/src/runtime/ai/tool-schema.ts +151 -0
  73. package/src/runtime/ai/types.ts +113 -0
  74. package/src/runtime/ai-logger.ts +255 -0
  75. package/src/runtime/ai-provider.ts +347 -0
  76. package/src/runtime/async/dependencies.ts +276 -0
  77. package/src/runtime/async/executor.ts +293 -0
  78. package/src/runtime/async/index.ts +43 -0
  79. package/src/runtime/async/scheduling.ts +163 -0
  80. package/src/runtime/async/test/dependencies.test.ts +284 -0
  81. package/src/runtime/async/test/executor.test.ts +388 -0
  82. package/src/runtime/context.ts +357 -0
  83. package/src/runtime/exec/ai.ts +139 -0
  84. package/src/runtime/exec/expressions.ts +475 -0
  85. package/src/runtime/exec/frames.ts +26 -0
  86. package/src/runtime/exec/functions.ts +305 -0
  87. package/src/runtime/exec/interpolation.ts +312 -0
  88. package/src/runtime/exec/statements.ts +604 -0
  89. package/src/runtime/exec/tools.ts +129 -0
  90. package/src/runtime/exec/typescript.ts +215 -0
  91. package/src/runtime/exec/variables.ts +279 -0
  92. package/src/runtime/index.ts +975 -0
  93. package/src/runtime/modules.ts +452 -0
  94. package/src/runtime/serialize.ts +103 -0
  95. package/src/runtime/state.ts +489 -0
  96. package/src/runtime/stdlib/core.ts +45 -0
  97. package/src/runtime/stdlib/directory.test.ts +156 -0
  98. package/src/runtime/stdlib/edit.test.ts +154 -0
  99. package/src/runtime/stdlib/fastEdit.test.ts +201 -0
  100. package/src/runtime/stdlib/glob.test.ts +106 -0
  101. package/src/runtime/stdlib/grep.test.ts +144 -0
  102. package/src/runtime/stdlib/index.ts +16 -0
  103. package/src/runtime/stdlib/readFile.test.ts +123 -0
  104. package/src/runtime/stdlib/tools/index.ts +707 -0
  105. package/src/runtime/stdlib/writeFile.test.ts +157 -0
  106. package/src/runtime/step.ts +969 -0
  107. package/src/runtime/test/ai-context.test.ts +1086 -0
  108. package/src/runtime/test/ai-result-object.test.ts +419 -0
  109. package/src/runtime/test/ai-tool-flow.test.ts +859 -0
  110. package/src/runtime/test/async-execution-order.test.ts +618 -0
  111. package/src/runtime/test/async-execution.test.ts +344 -0
  112. package/src/runtime/test/async-nested.test.ts +660 -0
  113. package/src/runtime/test/async-parallel-timing.test.ts +546 -0
  114. package/src/runtime/test/basic1.test.ts +154 -0
  115. package/src/runtime/test/binary-operators.test.ts +431 -0
  116. package/src/runtime/test/break-statement.test.ts +257 -0
  117. package/src/runtime/test/context-modes.test.ts +650 -0
  118. package/src/runtime/test/context.test.ts +466 -0
  119. package/src/runtime/test/core-functions.test.ts +228 -0
  120. package/src/runtime/test/e2e.test.ts +88 -0
  121. package/src/runtime/test/error-locations/error-locations.test.ts +80 -0
  122. package/src/runtime/test/error-locations/main-error.vibe +4 -0
  123. package/src/runtime/test/error-locations/main-import-error.vibe +3 -0
  124. package/src/runtime/test/error-locations/utils/helper.vibe +5 -0
  125. package/src/runtime/test/for-in.test.ts +312 -0
  126. package/src/runtime/test/helpers.ts +69 -0
  127. package/src/runtime/test/imports.test.ts +334 -0
  128. package/src/runtime/test/json-expressions.test.ts +232 -0
  129. package/src/runtime/test/literals.test.ts +372 -0
  130. package/src/runtime/test/logical-indexing.test.ts +478 -0
  131. package/src/runtime/test/member-methods.test.ts +324 -0
  132. package/src/runtime/test/model-config.test.ts +338 -0
  133. package/src/runtime/test/null-handling.test.ts +342 -0
  134. package/src/runtime/test/private-visibility.test.ts +332 -0
  135. package/src/runtime/test/runtime-state.test.ts +514 -0
  136. package/src/runtime/test/scoping.test.ts +370 -0
  137. package/src/runtime/test/string-interpolation.test.ts +354 -0
  138. package/src/runtime/test/template-literal.test.ts +181 -0
  139. package/src/runtime/test/tool-execution.test.ts +467 -0
  140. package/src/runtime/test/tool-schema-generation.test.ts +477 -0
  141. package/src/runtime/test/tostring.test.ts +210 -0
  142. package/src/runtime/test/ts-block.test.ts +594 -0
  143. package/src/runtime/test/ts-error-location.test.ts +231 -0
  144. package/src/runtime/test/types.test.ts +732 -0
  145. package/src/runtime/test/verbose-logger.test.ts +710 -0
  146. package/src/runtime/test/vibe-expression.test.ts +54 -0
  147. package/src/runtime/test/vibe-value-errors.test.ts +541 -0
  148. package/src/runtime/test/while.test.ts +232 -0
  149. package/src/runtime/tools/builtin.ts +30 -0
  150. package/src/runtime/tools/directory-tools.ts +70 -0
  151. package/src/runtime/tools/file-tools.ts +228 -0
  152. package/src/runtime/tools/index.ts +5 -0
  153. package/src/runtime/tools/registry.ts +48 -0
  154. package/src/runtime/tools/search-tools.ts +134 -0
  155. package/src/runtime/tools/security.ts +36 -0
  156. package/src/runtime/tools/system-tools.ts +312 -0
  157. package/src/runtime/tools/test/fixtures/base-types.ts +40 -0
  158. package/src/runtime/tools/test/fixtures/test-types.ts +132 -0
  159. package/src/runtime/tools/test/registry.test.ts +713 -0
  160. package/src/runtime/tools/test/security.test.ts +86 -0
  161. package/src/runtime/tools/test/system-tools.test.ts +679 -0
  162. package/src/runtime/tools/test/ts-schema.test.ts +357 -0
  163. package/src/runtime/tools/ts-schema.ts +341 -0
  164. package/src/runtime/tools/types.ts +89 -0
  165. package/src/runtime/tools/utility-tools.ts +198 -0
  166. package/src/runtime/ts-eval.ts +126 -0
  167. package/src/runtime/types.ts +797 -0
  168. package/src/runtime/validation.ts +160 -0
  169. package/src/runtime/verbose-logger.ts +459 -0
  170. package/src/runtime.ts +2 -0
  171. package/src/semantic/analyzer-context.ts +62 -0
  172. package/src/semantic/analyzer-validators.ts +575 -0
  173. package/src/semantic/analyzer-visitors.ts +534 -0
  174. package/src/semantic/analyzer.ts +83 -0
  175. package/src/semantic/index.ts +11 -0
  176. package/src/semantic/symbol-table.ts +58 -0
  177. package/src/semantic/test/async-validation.test.ts +301 -0
  178. package/src/semantic/test/compress-validation.test.ts +179 -0
  179. package/src/semantic/test/const-reassignment.test.ts +111 -0
  180. package/src/semantic/test/control-flow.test.ts +346 -0
  181. package/src/semantic/test/destructuring.test.ts +185 -0
  182. package/src/semantic/test/duplicate-declarations.test.ts +168 -0
  183. package/src/semantic/test/export-validation.test.ts +111 -0
  184. package/src/semantic/test/fixtures/math.ts +31 -0
  185. package/src/semantic/test/imports.test.ts +148 -0
  186. package/src/semantic/test/json-type.test.ts +68 -0
  187. package/src/semantic/test/literals.test.ts +127 -0
  188. package/src/semantic/test/model-validation.test.ts +179 -0
  189. package/src/semantic/test/prompt-validation.test.ts +343 -0
  190. package/src/semantic/test/scoping.test.ts +312 -0
  191. package/src/semantic/test/tool-validation.test.ts +306 -0
  192. package/src/semantic/test/ts-type-checking.test.ts +563 -0
  193. package/src/semantic/test/type-constraints.test.ts +111 -0
  194. package/src/semantic/test/type-inference.test.ts +87 -0
  195. package/src/semantic/test/type-validation.test.ts +552 -0
  196. package/src/semantic/test/undefined-variables.test.ts +163 -0
  197. package/src/semantic/ts-block-checker.ts +204 -0
  198. package/src/semantic/ts-signatures.ts +194 -0
  199. package/src/semantic/ts-types.ts +170 -0
  200. package/src/semantic/types.ts +58 -0
  201. package/tests/fixtures/conditional-logic.vibe +14 -0
  202. package/tests/fixtures/function-call.vibe +16 -0
  203. package/tests/fixtures/imports/cycle-detection/a.vibe +6 -0
  204. package/tests/fixtures/imports/cycle-detection/b.vibe +5 -0
  205. package/tests/fixtures/imports/cycle-detection/main.vibe +3 -0
  206. package/tests/fixtures/imports/module-isolation/main-b.vibe +8 -0
  207. package/tests/fixtures/imports/module-isolation/main.vibe +9 -0
  208. package/tests/fixtures/imports/module-isolation/moduleA.vibe +6 -0
  209. package/tests/fixtures/imports/module-isolation/moduleB.vibe +6 -0
  210. package/tests/fixtures/imports/nested-import/helper.vibe +6 -0
  211. package/tests/fixtures/imports/nested-import/main.vibe +3 -0
  212. package/tests/fixtures/imports/nested-import/utils.ts +3 -0
  213. package/tests/fixtures/imports/nested-isolation/file2.vibe +15 -0
  214. package/tests/fixtures/imports/nested-isolation/file3.vibe +10 -0
  215. package/tests/fixtures/imports/nested-isolation/main.vibe +21 -0
  216. package/tests/fixtures/imports/pure-cycle/a.vibe +5 -0
  217. package/tests/fixtures/imports/pure-cycle/b.vibe +5 -0
  218. package/tests/fixtures/imports/pure-cycle/main.vibe +3 -0
  219. package/tests/fixtures/imports/ts-boolean/checks.ts +14 -0
  220. package/tests/fixtures/imports/ts-boolean/main.vibe +10 -0
  221. package/tests/fixtures/imports/ts-boolean/type-mismatch.vibe +5 -0
  222. package/tests/fixtures/imports/ts-boolean/use-constant.vibe +18 -0
  223. package/tests/fixtures/imports/ts-error-handling/helpers.ts +42 -0
  224. package/tests/fixtures/imports/ts-error-handling/main.vibe +5 -0
  225. package/tests/fixtures/imports/ts-import/main.vibe +4 -0
  226. package/tests/fixtures/imports/ts-import/math.ts +9 -0
  227. package/tests/fixtures/imports/ts-variables/call-non-function.vibe +5 -0
  228. package/tests/fixtures/imports/ts-variables/data.ts +10 -0
  229. package/tests/fixtures/imports/ts-variables/import-json.vibe +5 -0
  230. package/tests/fixtures/imports/ts-variables/import-type-mismatch.vibe +5 -0
  231. package/tests/fixtures/imports/ts-variables/import-variable.vibe +5 -0
  232. package/tests/fixtures/imports/vibe-import/greet.vibe +5 -0
  233. package/tests/fixtures/imports/vibe-import/main.vibe +3 -0
  234. package/tests/fixtures/multiple-ai-calls.vibe +10 -0
  235. package/tests/fixtures/simple-greeting.vibe +6 -0
  236. package/tests/fixtures/template-literals.vibe +11 -0
  237. package/tests/integration/basic-ai/basic-ai.integration.test.ts +166 -0
  238. package/tests/integration/basic-ai/basic-ai.vibe +12 -0
  239. package/tests/integration/bug-fix/bug-fix.integration.test.ts +201 -0
  240. package/tests/integration/bug-fix/buggy-code.ts +22 -0
  241. package/tests/integration/bug-fix/fix-bug.vibe +21 -0
  242. package/tests/integration/compress/compress.integration.test.ts +206 -0
  243. package/tests/integration/destructuring/destructuring.integration.test.ts +92 -0
  244. package/tests/integration/hello-world-translator/hello-world-translator.integration.test.ts +61 -0
  245. package/tests/integration/line-annotator/context-modes.integration.test.ts +261 -0
  246. package/tests/integration/line-annotator/line-annotator.integration.test.ts +148 -0
  247. package/tests/integration/multi-feature/cumulative-sum.integration.test.ts +75 -0
  248. package/tests/integration/multi-feature/number-analyzer.integration.test.ts +191 -0
  249. package/tests/integration/multi-feature/number-analyzer.vibe +59 -0
  250. package/tests/integration/tool-calls/tool-calls.integration.test.ts +93 -0
@@ -0,0 +1,231 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parser/parse';
3
+ import { Runtime, AIProvider, TsBlockError } from '../index';
4
+ import * as path from 'path';
5
+
6
+ // Mock AI provider for testing
7
+ function createMockProvider(): AIProvider {
8
+ return {
9
+ async execute() {
10
+ return { value: 'ai response' };
11
+ },
12
+ async generateCode() {
13
+ return { value: 'generated code' };
14
+ },
15
+ async askUser(): Promise<string> {
16
+ return 'user input';
17
+ },
18
+ };
19
+ }
20
+
21
+ describe('TypeScript Error Location Tracking', () => {
22
+ const fixtureDir = path.resolve(__dirname, '../../../tests/fixtures/imports/ts-error-handling');
23
+ const mainVibePath = path.join(fixtureDir, 'main.vibe');
24
+
25
+ describe('Imported TS function errors', () => {
26
+ test('error includes Vibe source location (line and column)', async () => {
27
+ // Parse a simple vibe file that calls a throwing function
28
+ const vibeCode = `
29
+ import { alwaysThrows } from "./helpers.ts"
30
+ let result = alwaysThrows()
31
+ `;
32
+ const ast = parse(vibeCode, { file: 'test.vibe' });
33
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
34
+
35
+ try {
36
+ await runtime.run();
37
+ expect.unreachable('should have thrown');
38
+ } catch (error) {
39
+ expect(error).toBeInstanceOf(TsBlockError);
40
+ const tsError = error as TsBlockError;
41
+
42
+ // Check Vibe location is present
43
+ expect(tsError.location).toBeDefined();
44
+ expect(tsError.location?.line).toBe(3); // Line 3: let result = alwaysThrows()
45
+ expect(tsError.location?.file).toBe('test.vibe');
46
+ }
47
+ });
48
+
49
+ test('error includes original TS stack trace with file path', async () => {
50
+ const vibeCode = `
51
+ import { alwaysThrows } from "./helpers.ts"
52
+ let result = alwaysThrows()
53
+ `;
54
+ const ast = parse(vibeCode, { file: 'test.vibe' });
55
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
56
+
57
+ try {
58
+ await runtime.run();
59
+ expect.unreachable('should have thrown');
60
+ } catch (error) {
61
+ expect(error).toBeInstanceOf(TsBlockError);
62
+ const tsError = error as TsBlockError;
63
+
64
+ // Check original error has stack trace
65
+ expect(tsError.originalError).toBeDefined();
66
+ expect(tsError.originalError.stack).toBeDefined();
67
+
68
+ // Stack trace should reference the actual .ts file
69
+ expect(tsError.originalError.stack).toContain('helpers.ts');
70
+ }
71
+ });
72
+
73
+ test('error stack trace includes TS line number', async () => {
74
+ const vibeCode = `
75
+ import { alwaysThrows } from "./helpers.ts"
76
+ let result = alwaysThrows()
77
+ `;
78
+ const ast = parse(vibeCode, { file: 'test.vibe' });
79
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
80
+
81
+ try {
82
+ await runtime.run();
83
+ expect.unreachable('should have thrown');
84
+ } catch (error) {
85
+ expect(error).toBeInstanceOf(TsBlockError);
86
+ const tsError = error as TsBlockError;
87
+
88
+ // Stack trace should include line number from helpers.ts
89
+ // The alwaysThrows function throws on line 8
90
+ const stack = tsError.originalError.stack ?? '';
91
+ // Stack trace format: "at alwaysThrows (path/helpers.ts:8:9)"
92
+ expect(stack).toMatch(/helpers\.ts:\d+/);
93
+ }
94
+ });
95
+
96
+ test('format() shows both Vibe location and TS stack trace', async () => {
97
+ const vibeCode = `
98
+ import { alwaysThrows } from "./helpers.ts"
99
+ let result = alwaysThrows()
100
+ `;
101
+ const ast = parse(vibeCode, { file: 'test.vibe' });
102
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
103
+
104
+ try {
105
+ await runtime.run();
106
+ expect.unreachable('should have thrown');
107
+ } catch (error) {
108
+ expect(error).toBeInstanceOf(TsBlockError);
109
+ const tsError = error as TsBlockError;
110
+ const formatted = tsError.format();
111
+
112
+ // Should include Vibe location
113
+ expect(formatted).toContain('[test.vibe:3:');
114
+
115
+ // Should include the error message
116
+ expect(formatted).toContain('alwaysThrows');
117
+
118
+ // Should include TS stack trace
119
+ expect(formatted).toContain('TypeScript stack trace:');
120
+ expect(formatted).toContain('helpers.ts');
121
+ }
122
+ });
123
+
124
+ test('nested TS function calls show full stack trace', async () => {
125
+ const vibeCode = `
126
+ import { outerFunction } from "./helpers.ts"
127
+ let result = outerFunction()
128
+ `;
129
+ const ast = parse(vibeCode, { file: 'test.vibe' });
130
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
131
+
132
+ try {
133
+ await runtime.run();
134
+ expect.unreachable('should have thrown');
135
+ } catch (error) {
136
+ expect(error).toBeInstanceOf(TsBlockError);
137
+ const tsError = error as TsBlockError;
138
+ const stack = tsError.originalError.stack ?? '';
139
+
140
+ // Stack should show the nested calls: deepFunction -> innerFunction -> outerFunction
141
+ expect(stack).toContain('deepFunction');
142
+ expect(stack).toContain('innerFunction');
143
+ expect(stack).toContain('outerFunction');
144
+ }
145
+ });
146
+
147
+ test('RangeError from TS preserves error type', async () => {
148
+ const vibeCode = `
149
+ import { validatePositive } from "./helpers.ts"
150
+ let result = validatePositive(-5)
151
+ `;
152
+ const ast = parse(vibeCode, { file: 'test.vibe' });
153
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
154
+
155
+ try {
156
+ await runtime.run();
157
+ expect.unreachable('should have thrown');
158
+ } catch (error) {
159
+ expect(error).toBeInstanceOf(TsBlockError);
160
+ const tsError = error as TsBlockError;
161
+
162
+ // Original error type should be preserved
163
+ expect(tsError.originalError).toBeInstanceOf(RangeError);
164
+ expect(tsError.originalError.message).toContain('-5');
165
+ }
166
+ });
167
+
168
+ test('TypeError from TS includes stack with line info', async () => {
169
+ const vibeCode = `
170
+ import { accessNullProperty } from "./helpers.ts"
171
+ let result = accessNullProperty()
172
+ `;
173
+ const ast = parse(vibeCode, { file: 'test.vibe' });
174
+ const runtime = new Runtime(ast, createMockProvider(), { basePath: mainVibePath });
175
+
176
+ try {
177
+ await runtime.run();
178
+ expect.unreachable('should have thrown');
179
+ } catch (error) {
180
+ expect(error).toBeInstanceOf(TsBlockError);
181
+ const tsError = error as TsBlockError;
182
+
183
+ // Should be a TypeError
184
+ expect(tsError.originalError).toBeInstanceOf(TypeError);
185
+ // Stack should point to helpers.ts
186
+ expect(tsError.originalError.stack).toContain('helpers.ts');
187
+ }
188
+ });
189
+ });
190
+
191
+ describe('Inline ts block errors', () => {
192
+ test('inline ts block error includes Vibe location', async () => {
193
+ const vibeCode = `let result = ts() { throw new Error("inline error") }`;
194
+ const ast = parse(vibeCode, { file: 'inline.vibe' });
195
+ const runtime = new Runtime(ast, createMockProvider());
196
+
197
+ try {
198
+ await runtime.run();
199
+ expect.unreachable('should have thrown');
200
+ } catch (error) {
201
+ expect(error).toBeInstanceOf(TsBlockError);
202
+ const tsError = error as TsBlockError;
203
+
204
+ // Should have Vibe location
205
+ expect(tsError.location).toBeDefined();
206
+ expect(tsError.location?.line).toBe(1);
207
+ expect(tsError.location?.file).toBe('inline.vibe');
208
+ }
209
+ });
210
+
211
+ test('inline ts block format() shows location and stack', async () => {
212
+ const vibeCode = `let result = ts() { throw new TypeError("type error") }`;
213
+ const ast = parse(vibeCode, { file: 'inline.vibe' });
214
+ const runtime = new Runtime(ast, createMockProvider());
215
+
216
+ try {
217
+ await runtime.run();
218
+ expect.unreachable('should have thrown');
219
+ } catch (error) {
220
+ expect(error).toBeInstanceOf(TsBlockError);
221
+ const tsError = error as TsBlockError;
222
+ const formatted = tsError.format();
223
+
224
+ // Should have location prefix
225
+ expect(formatted).toContain('[inline.vibe:1:');
226
+ // Should have stack trace section
227
+ expect(formatted).toContain('TypeScript stack trace:');
228
+ }
229
+ });
230
+ });
231
+ });