@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,400 @@
1
+ import { describe, test, expect } from 'bun:test';
2
+ import {
3
+ createDebugState,
4
+ setBreakpoints,
5
+ clearBreakpoints,
6
+ shouldPauseAtLocation,
7
+ pauseExecution,
8
+ resumeExecution,
9
+ setStepMode,
10
+ getCurrentLocation,
11
+ getStackTrace,
12
+ getScopes,
13
+ getVariables,
14
+ } from '../state';
15
+ import { createInitialState } from '../../runtime/state';
16
+ import { parse } from '../../parser/parse';
17
+
18
+ describe('Debug State', () => {
19
+ describe('createDebugState', () => {
20
+ test('creates initial debug state', () => {
21
+ const state = createDebugState();
22
+
23
+ expect(state.running).toBe(false);
24
+ expect(state.paused).toBe(false);
25
+ expect(state.pausedAt).toBeNull();
26
+ expect(state.stopReason).toBeNull();
27
+ expect(state.stepMode).toBe('none');
28
+ expect(state.breakpoints.size).toBe(0);
29
+ });
30
+
31
+ test('creates debug state with stopOnEntry', () => {
32
+ const state = createDebugState({ stopOnEntry: true });
33
+
34
+ expect(state.paused).toBe(true);
35
+ expect(state.stopReason).toBe('entry');
36
+ });
37
+ });
38
+
39
+ describe('setBreakpoints', () => {
40
+ test('sets breakpoints for a file', () => {
41
+ const debugState = createDebugState();
42
+ const result = setBreakpoints(debugState, '/test/file.vibe', [5, 10, 15]);
43
+
44
+ expect(result.breakpoints).toHaveLength(3);
45
+ expect(result.breakpoints[0]).toEqual({
46
+ id: 1,
47
+ file: '/test/file.vibe',
48
+ line: 5,
49
+ verified: true,
50
+ condition: undefined,
51
+ });
52
+ expect(result.breakpoints[1].line).toBe(10);
53
+ expect(result.breakpoints[2].line).toBe(15);
54
+ });
55
+
56
+ test('sets breakpoints with conditions', () => {
57
+ const debugState = createDebugState();
58
+ const result = setBreakpoints(
59
+ debugState,
60
+ '/test/file.vibe',
61
+ [5, 10],
62
+ ['x > 5', undefined]
63
+ );
64
+
65
+ expect(result.breakpoints[0].condition).toBe('x > 5');
66
+ expect(result.breakpoints[1].condition).toBeUndefined();
67
+ });
68
+
69
+ test('replaces breakpoints for same file', () => {
70
+ let debugState = createDebugState();
71
+
72
+ const result1 = setBreakpoints(debugState, '/test/file.vibe', [5, 10]);
73
+ debugState = result1.debugState;
74
+
75
+ const result2 = setBreakpoints(debugState, '/test/file.vibe', [20]);
76
+
77
+ expect(result2.breakpoints).toHaveLength(1);
78
+ expect(result2.breakpoints[0].line).toBe(20);
79
+ });
80
+
81
+ test('handles multiple files', () => {
82
+ let debugState = createDebugState();
83
+
84
+ const result1 = setBreakpoints(debugState, '/test/a.vibe', [5]);
85
+ debugState = result1.debugState;
86
+
87
+ const result2 = setBreakpoints(debugState, '/test/b.vibe', [10]);
88
+ debugState = result2.debugState;
89
+
90
+ expect(debugState.breakpoints.size).toBe(2);
91
+ });
92
+ });
93
+
94
+ describe('clearBreakpoints', () => {
95
+ test('clears breakpoints for a file', () => {
96
+ let debugState = createDebugState();
97
+ const result = setBreakpoints(debugState, '/test/file.vibe', [5, 10]);
98
+ debugState = result.debugState;
99
+
100
+ debugState = clearBreakpoints(debugState, '/test/file.vibe');
101
+
102
+ expect(debugState.breakpoints.get('/test/file.vibe')).toBeUndefined();
103
+ });
104
+ });
105
+
106
+ describe('shouldPauseAtLocation', () => {
107
+ test('returns true when hitting a breakpoint', () => {
108
+ let debugState = createDebugState();
109
+ const result = setBreakpoints(debugState, '/test/file.vibe', [5]);
110
+ debugState = result.debugState;
111
+
112
+ const runtimeState = createInitialState(parse('let x = 1'));
113
+
114
+ const { shouldPause, reason } = shouldPauseAtLocation(
115
+ debugState,
116
+ runtimeState,
117
+ { file: '/test/file.vibe', line: 5, column: 1 }
118
+ );
119
+
120
+ expect(shouldPause).toBe(true);
121
+ expect(reason).toBe('breakpoint');
122
+ });
123
+
124
+ test('returns false when no breakpoint', () => {
125
+ let debugState = createDebugState();
126
+ const result = setBreakpoints(debugState, '/test/file.vibe', [5]);
127
+ debugState = result.debugState;
128
+
129
+ const runtimeState = createInitialState(parse('let x = 1'));
130
+
131
+ const { shouldPause } = shouldPauseAtLocation(
132
+ debugState,
133
+ runtimeState,
134
+ { file: '/test/file.vibe', line: 10, column: 1 }
135
+ );
136
+
137
+ expect(shouldPause).toBe(false);
138
+ });
139
+
140
+ test('returns true in step mode', () => {
141
+ let debugState = createDebugState();
142
+ debugState = setStepMode(debugState, 'into');
143
+
144
+ const runtimeState = createInitialState(parse('let x = 1'));
145
+
146
+ const { shouldPause, reason } = shouldPauseAtLocation(
147
+ debugState,
148
+ runtimeState,
149
+ { file: '/test/file.vibe', line: 1, column: 1 }
150
+ );
151
+
152
+ expect(shouldPause).toBe(true);
153
+ expect(reason).toBe('step');
154
+ });
155
+ });
156
+
157
+ describe('pauseExecution', () => {
158
+ test('pauses execution at location', () => {
159
+ const debugState = createDebugState();
160
+ const location = { file: '/test/file.vibe', line: 5, column: 1 };
161
+
162
+ const newState = pauseExecution(debugState, location, 'breakpoint');
163
+
164
+ expect(newState.running).toBe(false);
165
+ expect(newState.paused).toBe(true);
166
+ expect(newState.pausedAt).toEqual(location);
167
+ expect(newState.stopReason).toBe('breakpoint');
168
+ expect(newState.stepMode).toBe('none');
169
+ });
170
+ });
171
+
172
+ describe('resumeExecution', () => {
173
+ test('resumes execution', () => {
174
+ let debugState = createDebugState({ stopOnEntry: true });
175
+ debugState = pauseExecution(
176
+ debugState,
177
+ { file: '/test/file.vibe', line: 1, column: 1 },
178
+ 'entry'
179
+ );
180
+
181
+ const newState = resumeExecution(debugState);
182
+
183
+ expect(newState.running).toBe(true);
184
+ expect(newState.paused).toBe(false);
185
+ expect(newState.pausedAt).toBeNull();
186
+ expect(newState.stopReason).toBeNull();
187
+ });
188
+ });
189
+
190
+ describe('setStepMode', () => {
191
+ test('sets step into mode', () => {
192
+ const debugState = createDebugState();
193
+ const newState = setStepMode(debugState, 'into');
194
+
195
+ expect(newState.stepMode).toBe('into');
196
+ expect(newState.running).toBe(true);
197
+ expect(newState.paused).toBe(false);
198
+ });
199
+
200
+ test('sets step over mode', () => {
201
+ const debugState = createDebugState();
202
+ const newState = setStepMode(debugState, 'over');
203
+
204
+ expect(newState.stepMode).toBe('over');
205
+ });
206
+
207
+ test('sets step out mode', () => {
208
+ const debugState = createDebugState();
209
+ const newState = setStepMode(debugState, 'out');
210
+
211
+ expect(newState.stepMode).toBe('out');
212
+ });
213
+ });
214
+ });
215
+
216
+ describe('Stack Trace', () => {
217
+ test('gets stack trace from runtime state', () => {
218
+ const code = `
219
+ function foo() {
220
+ return 1
221
+ }
222
+ foo()
223
+ `;
224
+ const ast = parse(code);
225
+ const runtimeState = createInitialState(ast);
226
+
227
+ const { stackFrames, totalFrames } = getStackTrace(runtimeState);
228
+
229
+ expect(totalFrames).toBeGreaterThan(0);
230
+ expect(stackFrames.length).toBe(totalFrames);
231
+ });
232
+ });
233
+
234
+ describe('Scopes and Variables', () => {
235
+ test('gets scopes for a frame', () => {
236
+ const code = 'let x = 1';
237
+ const ast = parse(code);
238
+ const runtimeState = createInitialState(ast);
239
+ const debugState = createDebugState();
240
+
241
+ const { scopes } = getScopes(debugState, runtimeState, 0);
242
+
243
+ expect(scopes.length).toBeGreaterThan(0);
244
+ expect(scopes.some(s => s.type === 'local')).toBe(true);
245
+ });
246
+
247
+ test('gets variables from scope reference', () => {
248
+ const code = 'let x = 42';
249
+ const ast = parse(code);
250
+ let runtimeState = createInitialState(ast);
251
+
252
+ // Run one step to create the variable
253
+ const { runUntilPause } = require('../../runtime/step');
254
+ runtimeState = runUntilPause(runtimeState);
255
+
256
+ let debugState = createDebugState();
257
+ const { debugState: ds, scopes } = getScopes(debugState, runtimeState, 0);
258
+ debugState = ds;
259
+
260
+ const localScope = scopes.find(s => s.type === 'local');
261
+ if (localScope) {
262
+ const { variables } = getVariables(debugState, runtimeState, localScope.variablesReference);
263
+
264
+ // Should have variables from the runtime state
265
+ expect(Array.isArray(variables)).toBe(true);
266
+ }
267
+ });
268
+ });
269
+
270
+ describe('VibeValue Debug Display', () => {
271
+ const { createVibeValue, createVibeError } = require('../../runtime/types');
272
+
273
+ test('displays VibeValue with error indicator', () => {
274
+ const code = 'let x = 1';
275
+ const ast = parse(code);
276
+ let runtimeState = createInitialState(ast);
277
+
278
+ // Manually inject a VibeValue with error into the runtime state
279
+ const vibeValueWithError = createVibeError('Division by zero', { line: 1, column: 1, file: 'test.vibe' });
280
+ runtimeState.callStack[0].locals['errorVar'] = vibeValueWithError;
281
+
282
+ let debugState = createDebugState();
283
+ const { debugState: ds, scopes } = getScopes(debugState, runtimeState, 0);
284
+ debugState = ds;
285
+
286
+ const localScope = scopes.find(s => s.type === 'local');
287
+ expect(localScope).toBeDefined();
288
+
289
+ const { variables } = getVariables(debugState, runtimeState, localScope!.variablesReference);
290
+
291
+ const errorVar = variables.find(v => v.name === 'errorVar');
292
+ expect(errorVar).toBeDefined();
293
+ expect(errorVar!.hasError).toBe(true);
294
+ expect(errorVar!.errorMessage).toContain('Division by zero');
295
+ expect(errorVar!.value).toContain('error');
296
+ });
297
+
298
+ test('displays VibeValue with toolCalls indicator', () => {
299
+ const code = 'let x = 1';
300
+ const ast = parse(code);
301
+ let runtimeState = createInitialState(ast);
302
+
303
+ // Manually inject a VibeValue with toolCalls into the runtime state
304
+ const vibeValueWithToolCalls = createVibeValue('result', {
305
+ toolCalls: [
306
+ { toolName: 'readFile', args: { path: '/test.txt' }, result: 'content', err: false, errDetails: null, duration: 100 },
307
+ { toolName: 'writeFile', args: { path: '/out.txt' }, result: 'ok', err: false, errDetails: null, duration: 50 },
308
+ ],
309
+ });
310
+ runtimeState.callStack[0].locals['aiResult'] = vibeValueWithToolCalls;
311
+
312
+ let debugState = createDebugState();
313
+ const { debugState: ds, scopes } = getScopes(debugState, runtimeState, 0);
314
+ debugState = ds;
315
+
316
+ const localScope = scopes.find(s => s.type === 'local');
317
+ expect(localScope).toBeDefined();
318
+
319
+ const { variables } = getVariables(debugState, runtimeState, localScope!.variablesReference);
320
+
321
+ const aiResultVar = variables.find(v => v.name === 'aiResult');
322
+ expect(aiResultVar).toBeDefined();
323
+ expect(aiResultVar!.hasToolCalls).toBe(true);
324
+ expect(aiResultVar!.toolCallCount).toBe(2);
325
+ });
326
+
327
+ test('expands VibeValue to show value, err, and toolCalls', () => {
328
+ const code = 'let x = 1';
329
+ const ast = parse(code);
330
+ let runtimeState = createInitialState(ast);
331
+
332
+ // Create a VibeValue with both error and toolCalls (edge case)
333
+ const complexVibeValue = {
334
+ value: 'partial result',
335
+ err: true,
336
+ errDetails: { message: 'Partial failure', type: 'Error', location: null },
337
+ toolCalls: [
338
+ { toolName: 'fetch', args: { url: 'http://example.com' }, result: null, err: true, errDetails: { message: 'timeout' }, duration: 5000 },
339
+ ],
340
+ isConst: false,
341
+ typeAnnotation: null,
342
+ source: 'ai' as const,
343
+ };
344
+ runtimeState.callStack[0].locals['complexVar'] = complexVibeValue;
345
+
346
+ let debugState = createDebugState();
347
+ const { debugState: ds, scopes } = getScopes(debugState, runtimeState, 0);
348
+ debugState = ds;
349
+
350
+ const localScope = scopes.find(s => s.type === 'local');
351
+ const { debugState: ds2, variables } = getVariables(debugState, runtimeState, localScope!.variablesReference);
352
+
353
+ const complexVar = variables.find(v => v.name === 'complexVar');
354
+ expect(complexVar).toBeDefined();
355
+ expect(complexVar!.variablesReference).toBeGreaterThan(0); // Should be expandable
356
+
357
+ // Expand the VibeValue
358
+ const { variables: expandedVars } = getVariables(ds2, runtimeState, complexVar!.variablesReference);
359
+
360
+ expect(expandedVars.some(v => v.name === 'value')).toBe(true);
361
+ expect(expandedVars.some(v => v.name === 'err')).toBe(true);
362
+ expect(expandedVars.some(v => v.name === 'errDetails')).toBe(true); // errDetails contains the error info
363
+ expect(expandedVars.some(v => v.name === 'toolCalls')).toBe(true);
364
+
365
+ const errVar = expandedVars.find(v => v.name === 'err');
366
+ expect(errVar!.value).toBe('true'); // err is now a boolean 'true' string
367
+ expect(errVar!.type).toBe('boolean');
368
+
369
+ const errDetailsVar = expandedVars.find(v => v.name === 'errDetails');
370
+ expect(errDetailsVar!.hasError).toBe(true);
371
+ expect(errDetailsVar!.value).toContain('Partial failure');
372
+
373
+ const toolCallsVar = expandedVars.find(v => v.name === 'toolCalls');
374
+ expect(toolCallsVar!.hasToolCalls).toBe(true);
375
+ expect(toolCallsVar!.value).toContain('Array(1)');
376
+ });
377
+
378
+ test('displays regular value without error/toolCalls indicators', () => {
379
+ const code = 'let x = 1';
380
+ const ast = parse(code);
381
+ let runtimeState = createInitialState(ast);
382
+
383
+ // Manually inject a regular VibeValue
384
+ const regularValue = createVibeValue(42);
385
+ runtimeState.callStack[0].locals['num'] = regularValue;
386
+
387
+ let debugState = createDebugState();
388
+ const { debugState: ds, scopes } = getScopes(debugState, runtimeState, 0);
389
+ debugState = ds;
390
+
391
+ const localScope = scopes.find(s => s.type === 'local');
392
+ const { variables } = getVariables(debugState, runtimeState, localScope!.variablesReference);
393
+
394
+ const numVar = variables.find(v => v.name === 'num');
395
+ expect(numVar).toBeDefined();
396
+ expect(numVar!.hasError).toBe(false);
397
+ expect(numVar!.hasToolCalls).toBe(false);
398
+ expect(numVar!.value).toContain('42');
399
+ });
400
+ });