@ebowwa/coder 0.2.1 → 0.7.64

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 (401) hide show
  1. package/README.md +31 -32
  2. package/dist/core/__tests__/permissions.test.d.ts +12 -0
  3. package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
  4. package/dist/core/__tests__/permissions.test.js +851 -0
  5. package/dist/core/agent-loop/__tests__/compaction.test.d.ts +5 -0
  6. package/dist/core/agent-loop/__tests__/compaction.test.d.ts.map +1 -0
  7. package/dist/core/agent-loop/__tests__/compaction.test.js +209 -0
  8. package/dist/core/agent-loop/__tests__/formatters.test.d.ts +5 -0
  9. package/dist/core/agent-loop/__tests__/formatters.test.d.ts.map +1 -0
  10. package/dist/core/agent-loop/__tests__/formatters.test.js +195 -0
  11. package/dist/core/agent-loop/__tests__/index.test.d.ts +5 -0
  12. package/dist/core/agent-loop/__tests__/index.test.d.ts.map +1 -0
  13. package/dist/core/agent-loop/__tests__/index.test.js +121 -0
  14. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts +5 -0
  15. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts.map +1 -0
  16. package/dist/core/agent-loop/__tests__/loop-state.test.js +340 -0
  17. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts +5 -0
  18. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts.map +1 -0
  19. package/dist/core/agent-loop/__tests__/message-builder.test.js +178 -0
  20. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts +5 -0
  21. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts.map +1 -0
  22. package/dist/core/agent-loop/__tests__/tool-executor.test.js +331 -0
  23. package/dist/core/agent-loop/compaction.d.ts +39 -0
  24. package/dist/core/agent-loop/compaction.d.ts.map +1 -0
  25. package/dist/core/agent-loop/compaction.js +51 -0
  26. package/dist/core/agent-loop/formatters.d.ts +21 -0
  27. package/dist/core/agent-loop/formatters.d.ts.map +1 -0
  28. package/dist/core/agent-loop/formatters.js +42 -0
  29. package/dist/core/agent-loop/index.d.ts +25 -0
  30. package/dist/core/agent-loop/index.d.ts.map +1 -0
  31. package/dist/core/agent-loop/index.js +83 -0
  32. package/dist/core/agent-loop/loop-state.d.ts +74 -0
  33. package/dist/core/agent-loop/loop-state.d.ts.map +1 -0
  34. package/dist/core/agent-loop/loop-state.js +147 -0
  35. package/dist/core/agent-loop/message-builder.d.ts +13 -0
  36. package/dist/core/agent-loop/message-builder.d.ts.map +1 -0
  37. package/dist/core/agent-loop/message-builder.js +49 -0
  38. package/dist/core/agent-loop/tool-executor.d.ts +23 -0
  39. package/dist/core/agent-loop/tool-executor.d.ts.map +1 -0
  40. package/dist/core/agent-loop/tool-executor.js +152 -0
  41. package/dist/core/agent-loop/turn-executor.d.ts +57 -0
  42. package/dist/core/agent-loop/turn-executor.d.ts.map +1 -0
  43. package/dist/core/agent-loop/turn-executor.js +124 -0
  44. package/dist/core/agent-loop/types.d.ts +141 -0
  45. package/dist/core/agent-loop/types.d.ts.map +1 -0
  46. package/dist/core/agent-loop/types.js +4 -0
  47. package/dist/core/agent-loop.d.ts +17 -0
  48. package/dist/core/agent-loop.d.ts.map +1 -0
  49. package/dist/core/agent-loop.js +16 -0
  50. package/dist/core/api-client-impl.d.ts +62 -0
  51. package/dist/core/api-client-impl.d.ts.map +1 -0
  52. package/dist/core/api-client-impl.js +479 -0
  53. package/dist/core/api-client.d.ts +6 -0
  54. package/dist/core/api-client.d.ts.map +1 -0
  55. package/dist/core/api-client.js +5 -0
  56. package/dist/core/checkpoints.d.ts +128 -0
  57. package/dist/core/checkpoints.d.ts.map +1 -0
  58. package/dist/core/checkpoints.js +438 -0
  59. package/dist/core/claude-md.d.ts +71 -0
  60. package/dist/core/claude-md.d.ts.map +1 -0
  61. package/dist/core/claude-md.js +198 -0
  62. package/dist/core/cognitive-security/hooks.d.ts +138 -0
  63. package/dist/core/cognitive-security/hooks.d.ts.map +1 -0
  64. package/dist/core/cognitive-security/hooks.js +389 -0
  65. package/dist/core/cognitive-security/index.d.ts +751 -0
  66. package/dist/core/cognitive-security/index.d.ts.map +1 -0
  67. package/dist/core/cognitive-security/index.js +1123 -0
  68. package/dist/core/cognitive-security/middleware.d.ts +136 -0
  69. package/dist/core/cognitive-security/middleware.d.ts.map +1 -0
  70. package/dist/core/cognitive-security/middleware.js +376 -0
  71. package/dist/core/config-loader.d.ts +127 -0
  72. package/dist/core/config-loader.d.ts.map +1 -0
  73. package/dist/core/config-loader.js +219 -0
  74. package/dist/core/context-compaction.d.ts +87 -0
  75. package/dist/core/context-compaction.d.ts.map +1 -0
  76. package/dist/core/context-compaction.js +428 -0
  77. package/dist/core/git-status.d.ts +25 -0
  78. package/dist/core/git-status.d.ts.map +1 -0
  79. package/dist/core/git-status.js +204 -0
  80. package/dist/core/image.d.ts +69 -0
  81. package/dist/core/image.d.ts.map +1 -0
  82. package/dist/core/image.js +290 -0
  83. package/dist/core/image.test.d.ts +2 -0
  84. package/dist/core/image.test.d.ts.map +1 -0
  85. package/dist/core/image.test.js +149 -0
  86. package/dist/core/models.d.ts +123 -0
  87. package/dist/core/models.d.ts.map +1 -0
  88. package/dist/core/models.js +325 -0
  89. package/dist/core/permissions.d.ts +81 -0
  90. package/dist/core/permissions.d.ts.map +1 -0
  91. package/dist/core/permissions.js +327 -0
  92. package/dist/core/retry.d.ts +25 -0
  93. package/dist/core/retry.d.ts.map +1 -0
  94. package/dist/core/retry.js +121 -0
  95. package/dist/core/session-store.d.ts +9 -0
  96. package/dist/core/session-store.d.ts.map +1 -0
  97. package/dist/core/session-store.js +10 -0
  98. package/dist/core/sessions/export.d.ts +47 -0
  99. package/dist/core/sessions/export.d.ts.map +1 -0
  100. package/dist/core/sessions/export.js +256 -0
  101. package/dist/core/sessions/index.d.ts +132 -0
  102. package/dist/core/sessions/index.d.ts.map +1 -0
  103. package/dist/core/sessions/index.js +442 -0
  104. package/dist/core/sessions/metadata.d.ts +77 -0
  105. package/dist/core/sessions/metadata.d.ts.map +1 -0
  106. package/dist/core/sessions/metadata.js +233 -0
  107. package/dist/core/sessions/persistence.d.ts +72 -0
  108. package/dist/core/sessions/persistence.d.ts.map +1 -0
  109. package/dist/core/sessions/persistence.js +201 -0
  110. package/dist/core/sessions/types.d.ts +110 -0
  111. package/dist/core/sessions/types.d.ts.map +1 -0
  112. package/dist/core/sessions/types.js +4 -0
  113. package/dist/core/stream-highlighter.d.ts +18 -0
  114. package/dist/core/stream-highlighter.d.ts.map +1 -0
  115. package/dist/core/stream-highlighter.js +916 -0
  116. package/dist/core/system-reminders.d.ts +89 -0
  117. package/dist/core/system-reminders.d.ts.map +1 -0
  118. package/dist/core/system-reminders.js +285 -0
  119. package/dist/ecosystem/hooks/__tests__/index.test.d.ts +5 -0
  120. package/dist/ecosystem/hooks/__tests__/index.test.d.ts.map +1 -0
  121. package/dist/ecosystem/hooks/__tests__/index.test.js +458 -0
  122. package/dist/ecosystem/hooks/index.d.ts +59 -0
  123. package/dist/ecosystem/hooks/index.d.ts.map +1 -0
  124. package/dist/ecosystem/hooks/index.js +294 -0
  125. package/dist/ecosystem/hooks/prompt-evaluator.d.ts +32 -0
  126. package/dist/ecosystem/hooks/prompt-evaluator.d.ts.map +1 -0
  127. package/dist/ecosystem/hooks/prompt-evaluator.js +229 -0
  128. package/dist/ecosystem/skills/index.d.ts +55 -0
  129. package/dist/ecosystem/skills/index.d.ts.map +1 -0
  130. package/dist/ecosystem/skills/index.js +258 -0
  131. package/dist/ecosystem/tools/__tests__/index.test.d.ts +7 -0
  132. package/dist/ecosystem/tools/__tests__/index.test.d.ts.map +1 -0
  133. package/dist/ecosystem/tools/__tests__/index.test.js +856 -0
  134. package/dist/ecosystem/tools/index.d.ts +24 -0
  135. package/dist/ecosystem/tools/index.d.ts.map +1 -0
  136. package/dist/ecosystem/tools/index.js +1709 -0
  137. package/dist/index.d.ts +24 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +32 -2
  140. package/dist/interfaces/mcp/client.d.ts +40 -0
  141. package/dist/interfaces/mcp/client.d.ts.map +1 -0
  142. package/dist/interfaces/mcp/client.js +309 -0
  143. package/dist/interfaces/ui/index.d.ts +36 -0
  144. package/dist/interfaces/ui/index.d.ts.map +1 -0
  145. package/dist/interfaces/ui/index.js +61 -0
  146. package/dist/interfaces/ui/spinner.d.ts +140 -0
  147. package/dist/interfaces/ui/spinner.d.ts.map +1 -0
  148. package/dist/interfaces/ui/spinner.js +342 -0
  149. package/dist/interfaces/ui/terminal/cli/index.d.ts +12 -0
  150. package/dist/interfaces/ui/terminal/cli/index.d.ts.map +1 -0
  151. package/dist/interfaces/ui/terminal/cli/index.js +167 -0
  152. package/dist/interfaces/ui/terminal/shared/args.d.ts +39 -0
  153. package/dist/interfaces/ui/terminal/shared/args.d.ts.map +1 -0
  154. package/dist/interfaces/ui/terminal/shared/args.js +176 -0
  155. package/dist/interfaces/ui/terminal/shared/index.d.ts +11 -0
  156. package/dist/interfaces/ui/terminal/shared/index.d.ts.map +1 -0
  157. package/dist/interfaces/ui/terminal/shared/index.js +16 -0
  158. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts +124 -0
  159. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts.map +1 -0
  160. package/dist/interfaces/ui/terminal/shared/loading-state.js +246 -0
  161. package/dist/interfaces/ui/terminal/shared/query.d.ts +22 -0
  162. package/dist/interfaces/ui/terminal/shared/query.d.ts.map +1 -0
  163. package/dist/interfaces/ui/terminal/shared/query.js +100 -0
  164. package/dist/interfaces/ui/terminal/shared/setup.d.ts +33 -0
  165. package/dist/interfaces/ui/terminal/shared/setup.d.ts.map +1 -0
  166. package/dist/interfaces/ui/terminal/shared/setup.js +226 -0
  167. package/dist/interfaces/ui/terminal/shared/status-line.d.ts +117 -0
  168. package/dist/interfaces/ui/terminal/shared/status-line.d.ts.map +1 -0
  169. package/dist/interfaces/ui/terminal/shared/status-line.js +267 -0
  170. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts +38 -0
  171. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts.map +1 -0
  172. package/dist/interfaces/ui/terminal/shared/system-prompt.js +102 -0
  173. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts +39 -0
  174. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts.map +1 -0
  175. package/dist/interfaces/ui/terminal/tui/HelpPanel.js +215 -0
  176. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts +91 -0
  177. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts.map +1 -0
  178. package/dist/interfaces/ui/terminal/tui/InputContext.js +154 -0
  179. package/dist/interfaces/ui/terminal/tui/InputField.d.ts +18 -0
  180. package/dist/interfaces/ui/terminal/tui/InputField.d.ts.map +1 -0
  181. package/dist/interfaces/ui/terminal/tui/InputField.js +41 -0
  182. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts +16 -0
  183. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts.map +1 -0
  184. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.js +451 -0
  185. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts +10 -0
  186. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts.map +1 -0
  187. package/dist/interfaces/ui/terminal/tui/MessageArea.js +91 -0
  188. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts +48 -0
  189. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts.map +1 -0
  190. package/dist/interfaces/ui/terminal/tui/MessageStore.js +151 -0
  191. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts +9 -0
  192. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts.map +1 -0
  193. package/dist/interfaces/ui/terminal/tui/StatusBar.js +36 -0
  194. package/dist/interfaces/ui/terminal/tui/commands.d.ts +21 -0
  195. package/dist/interfaces/ui/terminal/tui/commands.d.ts.map +1 -0
  196. package/dist/interfaces/ui/terminal/tui/commands.js +359 -0
  197. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts +115 -0
  198. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts.map +1 -0
  199. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.js +306 -0
  200. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts +92 -0
  201. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts.map +1 -0
  202. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.js +399 -0
  203. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts +59 -0
  204. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts.map +1 -0
  205. package/dist/interfaces/ui/terminal/tui/components/PaneManager.js +139 -0
  206. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts +68 -0
  207. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts.map +1 -0
  208. package/dist/interfaces/ui/terminal/tui/components/Sidebar.js +340 -0
  209. package/dist/interfaces/ui/terminal/tui/components/index.d.ts +23 -0
  210. package/dist/interfaces/ui/terminal/tui/components/index.d.ts.map +1 -0
  211. package/dist/interfaces/ui/terminal/tui/components/index.js +51 -0
  212. package/dist/interfaces/ui/terminal/tui/console.d.ts +20 -0
  213. package/dist/interfaces/ui/terminal/tui/console.d.ts.map +1 -0
  214. package/dist/interfaces/ui/terminal/tui/console.js +46 -0
  215. package/dist/interfaces/ui/terminal/tui/index.d.ts +20 -0
  216. package/dist/interfaces/ui/terminal/tui/index.d.ts.map +1 -0
  217. package/dist/interfaces/ui/terminal/tui/index.js +28 -0
  218. package/dist/interfaces/ui/terminal/tui/run.d.ts +13 -0
  219. package/dist/interfaces/ui/terminal/tui/run.d.ts.map +1 -0
  220. package/dist/interfaces/ui/terminal/tui/run.js +31 -0
  221. package/dist/interfaces/ui/terminal/tui/spinner.d.ts +44 -0
  222. package/dist/interfaces/ui/terminal/tui/spinner.d.ts.map +1 -0
  223. package/dist/interfaces/ui/terminal/tui/spinner.js +59 -0
  224. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts +39 -0
  225. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts.map +1 -0
  226. package/dist/interfaces/ui/terminal/tui/tui-app.js +198 -0
  227. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts +167 -0
  228. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts.map +1 -0
  229. package/dist/interfaces/ui/terminal/tui/tui-footer.js +330 -0
  230. package/dist/interfaces/ui/terminal/tui/types.d.ts +165 -0
  231. package/dist/interfaces/ui/terminal/tui/types.d.ts.map +1 -0
  232. package/dist/interfaces/ui/terminal/tui/types.js +5 -0
  233. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts +23 -0
  234. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts.map +1 -0
  235. package/dist/interfaces/ui/terminal/tui/useInputHandler.js +72 -0
  236. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts +90 -0
  237. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts.map +1 -0
  238. package/dist/interfaces/ui/terminal/tui/useNativeInput.js +188 -0
  239. package/dist/native/index.d.ts +480 -0
  240. package/dist/native/index.d.ts.map +1 -0
  241. package/dist/native/index.js +1625 -0
  242. package/dist/teammates/index.d.ts +161 -0
  243. package/dist/teammates/index.d.ts.map +1 -0
  244. package/dist/teammates/index.js +827 -0
  245. package/dist/types/index.d.ts +482 -0
  246. package/dist/types/index.d.ts.map +1 -0
  247. package/dist/types/index.js +52 -0
  248. package/native/README.md +5 -5
  249. package/native/index.darwin-arm64.node +0 -0
  250. package/native/index.node +0 -0
  251. package/native/package.json +4 -4
  252. package/package.json +33 -16
  253. package/packages/src/core/__tests__/permissions.test.ts +1091 -0
  254. package/packages/src/core/agent-loop/__tests__/compaction.test.ts +280 -0
  255. package/packages/src/core/agent-loop/__tests__/formatters.test.ts +234 -0
  256. package/packages/src/core/agent-loop/__tests__/index.test.ts +162 -0
  257. package/packages/src/core/agent-loop/__tests__/loop-state.test.ts +413 -0
  258. package/packages/src/core/agent-loop/__tests__/message-builder.test.ts +229 -0
  259. package/packages/src/core/agent-loop/__tests__/tool-executor.test.ts +457 -0
  260. package/packages/src/core/agent-loop/compaction.ts +88 -0
  261. package/packages/src/core/agent-loop/formatters.ts +50 -0
  262. package/packages/src/core/agent-loop/index.ts +135 -0
  263. package/packages/src/core/agent-loop/loop-state.ts +187 -0
  264. package/packages/src/core/agent-loop/message-builder.ts +62 -0
  265. package/packages/src/core/agent-loop/tool-executor.ts +211 -0
  266. package/packages/src/core/agent-loop/turn-executor.ts +222 -0
  267. package/packages/src/core/agent-loop/types.ts +148 -0
  268. package/packages/src/core/agent-loop.ts +18 -0
  269. package/packages/src/core/api-client-impl.ts +619 -0
  270. package/packages/src/core/api-client.ts +6 -0
  271. package/packages/src/core/checkpoints.ts +606 -0
  272. package/packages/src/core/claude-md.ts +272 -0
  273. package/packages/src/core/cognitive-security/hooks.ts +590 -0
  274. package/packages/src/core/cognitive-security/index.ts +2041 -0
  275. package/packages/src/core/cognitive-security/middleware.ts +536 -0
  276. package/packages/src/core/config-loader.ts +324 -0
  277. package/packages/src/core/context-compaction.ts +578 -0
  278. package/packages/src/core/git-status.ts +262 -0
  279. package/packages/src/core/image.test.ts +180 -0
  280. package/packages/src/core/image.ts +350 -0
  281. package/packages/src/core/lmdb.db +0 -0
  282. package/packages/src/core/lmdb.db-lock +0 -0
  283. package/packages/src/core/models.ts +430 -0
  284. package/packages/src/core/normalizers/todo +4 -0
  285. package/packages/src/core/permissions.ts +431 -0
  286. package/packages/src/core/retry.ts +170 -0
  287. package/packages/src/core/session-store.ts +36 -0
  288. package/packages/src/core/sessions/export.ts +329 -0
  289. package/packages/src/core/sessions/index.ts +587 -0
  290. package/packages/src/core/sessions/metadata.ts +309 -0
  291. package/packages/src/core/sessions/persistence.ts +244 -0
  292. package/packages/src/core/sessions/types.ts +169 -0
  293. package/packages/src/core/stream-highlighter.ts +1123 -0
  294. package/packages/src/core/system-reminders.ts +402 -0
  295. package/packages/src/core/todo +8 -0
  296. package/packages/src/ecosystem/hooks/__tests__/index.test.ts +561 -0
  297. package/packages/src/ecosystem/hooks/index.ts +341 -0
  298. package/packages/src/ecosystem/hooks/prompt-evaluator.ts +300 -0
  299. package/packages/src/ecosystem/skills/index.ts +295 -0
  300. package/packages/src/ecosystem/tools/__tests__/index.test.ts +1335 -0
  301. package/packages/src/ecosystem/tools/index.ts +1877 -0
  302. package/packages/src/index.ts +120 -0
  303. package/packages/src/interfaces/mcp/client.ts +389 -0
  304. package/packages/src/interfaces/ui/Screenshot 2026-03-02 at 9.23.10/342/200/257PM.png +0 -0
  305. package/packages/src/interfaces/ui/Screenshot 2026-03-03 at 10.55.11/342/200/257AM.png +0 -0
  306. package/packages/src/interfaces/ui/index.ts +161 -0
  307. package/packages/src/interfaces/ui/lmdb.db +0 -0
  308. package/packages/src/interfaces/ui/lmdb.db-lock +0 -0
  309. package/packages/src/interfaces/ui/spinner.ts +451 -0
  310. package/packages/src/interfaces/ui/terminal/cli/index.ts +228 -0
  311. package/packages/src/interfaces/ui/terminal/lmdb.db +0 -0
  312. package/packages/src/interfaces/ui/terminal/lmdb.db-lock +0 -0
  313. package/packages/src/interfaces/ui/terminal/shared/args.ts +222 -0
  314. package/packages/src/interfaces/ui/terminal/shared/index.ts +71 -0
  315. package/packages/src/interfaces/ui/terminal/shared/loading-state.ts +322 -0
  316. package/packages/src/interfaces/ui/terminal/shared/query.ts +146 -0
  317. package/packages/src/interfaces/ui/terminal/shared/setup.ts +295 -0
  318. package/packages/src/interfaces/ui/terminal/shared/status-line.ts +358 -0
  319. package/packages/src/interfaces/ui/terminal/shared/system-prompt.ts +146 -0
  320. package/packages/src/interfaces/ui/terminal/tui/HelpPanel.tsx +262 -0
  321. package/packages/src/interfaces/ui/terminal/tui/InputContext.tsx +232 -0
  322. package/packages/src/interfaces/ui/terminal/tui/InputField.tsx +62 -0
  323. package/packages/src/interfaces/ui/terminal/tui/InteractiveTUI.tsx +537 -0
  324. package/packages/src/interfaces/ui/terminal/tui/MessageArea.tsx +107 -0
  325. package/packages/src/interfaces/ui/terminal/tui/MessageStore.tsx +240 -0
  326. package/packages/src/interfaces/ui/terminal/tui/StatusBar.tsx +54 -0
  327. package/packages/src/interfaces/ui/terminal/tui/commands.ts +438 -0
  328. package/packages/src/interfaces/ui/terminal/tui/components/InteractiveElements.tsx +584 -0
  329. package/packages/src/interfaces/ui/terminal/tui/components/MultilineInput.tsx +614 -0
  330. package/packages/src/interfaces/ui/terminal/tui/components/PaneManager.tsx +333 -0
  331. package/packages/src/interfaces/ui/terminal/tui/components/Sidebar.tsx +604 -0
  332. package/packages/src/interfaces/ui/terminal/tui/components/index.ts +118 -0
  333. package/packages/src/interfaces/ui/terminal/tui/console.ts +49 -0
  334. package/packages/src/interfaces/ui/terminal/tui/index.ts +90 -0
  335. package/packages/src/interfaces/ui/terminal/tui/run.tsx +42 -0
  336. package/packages/src/interfaces/ui/terminal/tui/spinner.ts +69 -0
  337. package/packages/src/interfaces/ui/terminal/tui/tui-app.tsx +390 -0
  338. package/packages/src/interfaces/ui/terminal/tui/tui-footer.ts +422 -0
  339. package/packages/src/interfaces/ui/terminal/tui/types.ts +186 -0
  340. package/packages/src/interfaces/ui/terminal/tui/useInputHandler.ts +104 -0
  341. package/packages/src/interfaces/ui/terminal/tui/useNativeInput.ts +239 -0
  342. package/packages/src/lmdb.db +0 -0
  343. package/packages/src/lmdb.db-lock +0 -0
  344. package/packages/src/native/index.ts +2345 -0
  345. package/packages/src/teammates/index.ts +982 -0
  346. package/packages/src/types/index.ts +722 -0
  347. package/dist/cli.js +0 -148
  348. package/dist/index-0pkak453.js +0 -136
  349. package/dist/index-0qd0x8b4.js +0 -110
  350. package/dist/index-0x3kprq6.js +0 -240
  351. package/dist/index-1eawy937.js +0 -308
  352. package/dist/index-24m2aygy.js +0 -240
  353. package/dist/index-29xcjnne.js +0 -280
  354. package/dist/index-2avyytn5.js +0 -349
  355. package/dist/index-4ms367ey.js +0 -136
  356. package/dist/index-4w2t3b0m.js +0 -240
  357. package/dist/index-4xfgd8nz.js +0 -261
  358. package/dist/index-5acjp9gc.js +0 -157
  359. package/dist/index-5s15hr56.js +0 -136
  360. package/dist/index-6e4wf341.js +0 -349
  361. package/dist/index-6fvnkedw.js +0 -240
  362. package/dist/index-6rqpmd4g.js +0 -128
  363. package/dist/index-77ckwnbm.js +0 -280
  364. package/dist/index-9knxy49k.js +0 -128
  365. package/dist/index-9zrnw4zx.js +0 -128
  366. package/dist/index-bk21w99v.js +0 -280
  367. package/dist/index-c41n76fv.js +0 -240
  368. package/dist/index-cb4ppjdt.js +0 -255
  369. package/dist/index-cfb2edt6.js +0 -240
  370. package/dist/index-cmfa38hh.js +0 -308
  371. package/dist/index-datjz8q1.js +0 -257
  372. package/dist/index-eadf4wvn.js +0 -240
  373. package/dist/index-em5k0m3z.js +0 -345
  374. package/dist/index-gh8r333a.js +0 -110
  375. package/dist/index-gkx6k2tr.js +0 -261
  376. package/dist/index-h5cabfks.js +0 -155
  377. package/dist/index-hcrpwyy3.js +0 -261
  378. package/dist/index-hk7fwwa8.js +0 -257
  379. package/dist/index-jb8cw7f8.js +0 -136
  380. package/dist/index-kbyw4th1.js +0 -347
  381. package/dist/index-kgj5gqnm.js +0 -345
  382. package/dist/index-mdf6xp1z.js +0 -255
  383. package/dist/index-mrhv8kvc.js +0 -280
  384. package/dist/index-mt4743dd.js +0 -161
  385. package/dist/index-qnwsg97q.js +0 -240
  386. package/dist/index-qwdy6x44.js +0 -261
  387. package/dist/index-rmj77261.js +0 -157
  388. package/dist/index-sbbw1a61.js +0 -349
  389. package/dist/index-svy5bcpn.js +0 -345
  390. package/dist/index-tvmy7tm9.js +0 -261
  391. package/dist/index-tzz4vzkj.js +0 -312
  392. package/dist/index-vz80zmhe.js +0 -110
  393. package/dist/index-wed2fk67.js +0 -240
  394. package/dist/index-wksgzz8e.js +0 -280
  395. package/dist/index-wn2m4wma.js +0 -240
  396. package/dist/index-xha05vjc.js +0 -257
  397. package/dist/index-yc6eh8p8.js +0 -136
  398. package/dist/index-ycjxx9ft.js +0 -240
  399. package/dist/index-z0gzd0fc.js +0 -110
  400. package/dist/index-z8cwtf8j.js +0 -240
  401. package/dist/index-zy5mtt00.js +0 -128
@@ -0,0 +1,1625 @@
1
+ /**
2
+ * Native module loader
3
+ * Loads Rust-compiled native modules for performance-critical operations
4
+ */
5
+ import { dlopen, suffix } from "bun:ffi";
6
+ import { join, dirname } from "path";
7
+ import { fileURLToPath } from "url";
8
+ let nativeModule = null;
9
+ /**
10
+ * Load the native module
11
+ */
12
+ export function loadNative() {
13
+ if (nativeModule) {
14
+ return nativeModule;
15
+ }
16
+ // Try multiple possible locations for the native module
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const basePaths = [
19
+ join(__dirname, "..", "native"), // dist/../native (library entry)
20
+ join(__dirname, "..", "..", "native"), // dist/foo/../native
21
+ join(__dirname, "..", "..", "..", "native"), // dist/foo/bar/../native
22
+ join(__dirname, "..", "..", "..", "..", "native"), // dist/interfaces/ui/../native
23
+ join(__dirname, "..", "..", "..", "..", "..", "native"), // dist/interfaces/ui/terminal/../native
24
+ join(__dirname, "..", "..", "..", "..", "..", "..", "native"), // CLI entry: dist/interfaces/ui/terminal/cli/../native
25
+ join(__dirname, "native"), // native/ (if running from project root)
26
+ ];
27
+ // Try .node files first (NAPI modules)
28
+ const nodeFiles = ["index.darwin-arm64.node", "index.darwin-x64.node", "index.node"];
29
+ for (const basePath of basePaths) {
30
+ for (const file of nodeFiles) {
31
+ const nativePath = join(basePath, file);
32
+ try {
33
+ // Try to load NAPI module directly
34
+ const native = require(nativePath);
35
+ if (native && (native.highlightCode || native.highlight_code)) {
36
+ // Map camelCase to snake_case if needed
37
+ nativeModule = {
38
+ highlight_code: native.highlightCode || native.highlight_code,
39
+ highlight_markdown: native.highlightMarkdown || native.highlight_markdown,
40
+ highlight_diff: native.highlightDiff || native.highlight_diff,
41
+ search_files: native.searchFiles || native.search_files,
42
+ count_tokens: native.countTokens || native.count_tokens,
43
+ calculate_diff: native.calculateDiff || native.calculate_diff,
44
+ compact_content: native.compactContent || native.compact_content,
45
+ count_tool_use: native.countToolUse || native.count_tool_use,
46
+ find_tool_pairs: native.findToolPairs || native.find_tool_pairs,
47
+ find_common_patterns: native.findCommonPatterns || native.find_common_patterns,
48
+ validate_multi_edits: native.validateMultiEdits || native.validate_multi_edits,
49
+ preview_multi_edits: native.previewMultiEdits || native.preview_multi_edits,
50
+ apply_multi_edits: native.applyMultiEdits || native.apply_multi_edits,
51
+ // Cognitive Security - Action Module (NAPI exports camelCase)
52
+ classify_operation: native.classifyOperation,
53
+ get_action_types: native.getActionTypes,
54
+ get_action_risk_levels: native.getActionRiskLevels,
55
+ create_deny_all_policy: native.createDenyAllPolicy,
56
+ create_observe_only_policy: native.createObserveOnlyPolicy,
57
+ create_transfer_approval_policy: native.createTransferApprovalPolicy,
58
+ // Cognitive Security - Intent Module (NAPI exports camelCase)
59
+ cs_generate_keypair: native.generateIntentKeypair,
60
+ cs_sign_intent: native.signIntent,
61
+ cs_verify_intent: native.verifyIntentSignature,
62
+ cs_hash_intent: native.hashIntent,
63
+ cs_intents_equivalent: native.intentsEquivalent,
64
+ cs_score_alignment: native.scoreAlignment,
65
+ cs_batch_score_alignment: native.batchScoreAlignment,
66
+ cs_check_sequence_violations: native.checkSequenceViolations,
67
+ cs_load_intent: native.loadIntentFromFile,
68
+ cs_save_intent: native.saveIntentToFile,
69
+ cs_parse_intent: native.parseIntent,
70
+ cs_serialize_intent: native.serializeIntent,
71
+ cs_validate_intent: native.validateIntentStructure,
72
+ cs_create_data_collector_intent: native.createDataCollectorIntent,
73
+ cs_merge_intents: native.mergeIntents,
74
+ cs_analyze_corruption: native.analyzeCorruption,
75
+ cs_detect_drift: native.detectBehavioralDrift,
76
+ cs_create_empty_snapshot: native.createEmptySnapshot,
77
+ cs_update_snapshot: native.updateSnapshot,
78
+ // Cognitive Security - Flow Module (NAPI exports camelCase)
79
+ classify_data: native.classifyData,
80
+ contains_sensitive_data: native.containsSensitiveData,
81
+ redact_sensitive: native.redactSensitive,
82
+ get_sensitivity_levels: native.getSensitivityLevels,
83
+ get_data_categories: native.getDataCategories,
84
+ create_flow_policy_engine: native.createFlowPolicyEngine,
85
+ create_allow_all_flow_policy: native.createAllowAllFlowPolicy,
86
+ create_deny_all_flow_policy: native.createDenyAllFlowPolicy,
87
+ create_strict_flow_policy: native.createStrictFlowPolicy,
88
+ create_flow_tracker: native.createFlowTracker,
89
+ create_leak_prevention: native.createLeakPrevention,
90
+ check_for_leaks: native.checkForLeaks,
91
+ sanitize_content: native.sanitizeContent,
92
+ create_taint_tracker: native.createTaintTracker,
93
+ // Quant Functions
94
+ quant_version: native.quantVersion || native.quant_version,
95
+ quant_ohlcv_new: native.quantOhlcvNew || native.quant_ohlcv_new,
96
+ quant_amm_new: native.quantAmmNew || native.quant_amm_new,
97
+ quant_amm_calculate_cost: native.quantAmmCalculateCost || native.quant_amm_calculate_cost,
98
+ quant_amm_price_impact: native.quantAmmPriceImpact || native.quant_amm_price_impact,
99
+ quant_lmsr_price: native.quantLmsrPrice || native.quant_lmsr_price,
100
+ quant_lmsr_cost: native.quantLmsrCost || native.quant_lmsr_cost,
101
+ quant_detect_arbitrage: native.quantDetectArbitrage || native.quant_detect_arbitrage,
102
+ quant_convert_odds: native.quantConvertOdds || native.quant_convert_odds,
103
+ quant_mean: native.quantMean || native.quant_mean,
104
+ quant_std_dev: native.quantStdDev || native.quant_std_dev,
105
+ quant_variance: native.quantVariance || native.quant_variance,
106
+ quant_correlation: native.quantCorrelation || native.quant_correlation,
107
+ // Terminal Input
108
+ create_terminal: native.createTerminal || native.create_terminal,
109
+ // Native TUI
110
+ create_tui: native.createTui || native.create_tui,
111
+ is_native_tui_available: () => typeof (native.createTui || native.create_tui) === 'function',
112
+ };
113
+ return nativeModule;
114
+ }
115
+ }
116
+ catch {
117
+ // Try next path
118
+ continue;
119
+ }
120
+ }
121
+ }
122
+ // Try FFI with dylib
123
+ const dylibPaths = basePaths.map(p => join(p, `claude_code_native.${suffix}`));
124
+ for (const nativePath of dylibPaths) {
125
+ try {
126
+ const lib = dlopen(nativePath, {
127
+ highlight_code: {
128
+ args: ["cstring", "cstring"],
129
+ returns: "pointer",
130
+ },
131
+ highlight_markdown: {
132
+ args: ["cstring"],
133
+ returns: "pointer",
134
+ },
135
+ highlight_diff: {
136
+ args: ["cstring", "cstring", "pointer"],
137
+ returns: "pointer",
138
+ },
139
+ search_files: {
140
+ args: ["cstring", "cstring", "pointer"],
141
+ returns: "pointer",
142
+ },
143
+ count_tokens: {
144
+ args: ["cstring"],
145
+ returns: "u32",
146
+ },
147
+ calculate_diff: {
148
+ args: ["cstring", "cstring"],
149
+ returns: "pointer",
150
+ },
151
+ compact_content: {
152
+ args: ["cstring", "u32", "cstring"],
153
+ returns: "pointer",
154
+ },
155
+ });
156
+ nativeModule = lib.symbols;
157
+ return nativeModule;
158
+ }
159
+ catch {
160
+ continue;
161
+ }
162
+ }
163
+ // No native module found, use fallback
164
+ console.warn("Native module not available, using JS fallback");
165
+ return getFallbackModule();
166
+ }
167
+ /**
168
+ * Check if native module is available
169
+ */
170
+ export function isNativeAvailable() {
171
+ try {
172
+ loadNative();
173
+ return nativeModule !== null;
174
+ }
175
+ catch {
176
+ return false;
177
+ }
178
+ }
179
+ /**
180
+ * Fallback implementations in pure JavaScript
181
+ */
182
+ function getFallbackModule() {
183
+ return {
184
+ highlight_code: (code, language) => {
185
+ // ANSI color codes
186
+ const colors = {
187
+ reset: "\x1b[0m",
188
+ keyword: "\x1b[38;2;180;142;173m", // purple
189
+ string: "\x1b[38;2;163;190;140m", // green
190
+ number: "\x1b[38;2;208;135;112m", // orange
191
+ type: "\x1b[38;2;191;97;106m", // red
192
+ function: "\x1b[38;2;143;161;179m", // blue
193
+ comment: "\x1b[38;2;108;153;139m", // gray-green
194
+ default: "\x1b[38;2;192;197;206m", // gray
195
+ special: "\x1b[38;2;150;180;210m", // light blue
196
+ arrow: "\x1b[38;2;200;160;120m", // gold/tan
197
+ };
198
+ // Mermaid-specific highlighting
199
+ if (language.toLowerCase() === "mermaid" || language.toLowerCase() === "mmd") {
200
+ const MERMAID_KEYWORDS = new Set([
201
+ // Diagram types
202
+ "graph", "flowchart", "sequenceDiagram", "classDiagram", "stateDiagram",
203
+ "erDiagram", "journey", "gantt", "pie", "gitGraph", "mindmap", "timeline",
204
+ "quadrantChart", "requirementDiagram", "C4Context", "C4Container",
205
+ "C4Component", "C4Dynamic", "C4Deployment",
206
+ // Directions
207
+ "TB", "TD", "BT", "RL", "LR", "left", "right", "top", "bottom",
208
+ // Subgraphs/participants
209
+ "subgraph", "end", "participant", "actor", "as",
210
+ // Flowchart
211
+ "node", "click", "link", "href", "callback",
212
+ // Sequence
213
+ "Note", "over", "loop", "alt", "else", "opt", "par", "rect", "autonumber",
214
+ "activate", "deactivate",
215
+ // Class
216
+ "class", "namespace", "interface", "annotation", "service", "enum",
217
+ // State
218
+ "state", "note", "fork", "join", "choice",
219
+ // ER
220
+ "entity",
221
+ // Gantt
222
+ "dateFormat", "title", "section", "excludes", "includes", "todayMarker",
223
+ // Common
224
+ "title", "accTitle", "accDescr",
225
+ ]);
226
+ const MERMAID_ARROWS = new Set([
227
+ "-->", "---", "->", "->>", "-.", "-.-", "==>", "==", "--x", "--o",
228
+ "<--", "<-", "<<-", "<-->", "<->", "o--o", "x--x", "-x", "-o",
229
+ ]);
230
+ const MERMAID_SHAPES = [
231
+ ["[", "]"], // rect
232
+ ["(", ")"], // rounded
233
+ ["([", "])"], // stadium
234
+ ["[[", "]]"], // subroutine
235
+ ["[((", ")]"], // cylinder
236
+ [">", "]"], // asymmetric
237
+ ["{", "}"], // rhombus
238
+ ["{{", "}}"], // hexagon
239
+ ["[/", "/]"], // parallelogram
240
+ ["[\\", "\\]"], // parallelogram alt
241
+ ["[(", ")]"], // circle
242
+ ["(((", ")))"], // double circle
243
+ ];
244
+ const lines = code.split("\n");
245
+ const highlighted = lines.map(line => {
246
+ let result = line;
247
+ // Comments (%%)
248
+ if (line.trim().startsWith("%%")) {
249
+ return `${colors.comment}${line}${colors.reset}`;
250
+ }
251
+ // Arrows and connections (handle first to preserve them)
252
+ for (const arrow of MERMAID_ARROWS) {
253
+ const escaped = arrow.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
254
+ result = result.replace(new RegExp(escaped, 'g'), `${colors.arrow}${arrow}${colors.default}`);
255
+ }
256
+ // Strings (quoted)
257
+ result = result.replace(/"([^"\\]|\\.)*"/g, match => {
258
+ return `${colors.string}${match}${colors.default}`;
259
+ });
260
+ // Numbers
261
+ result = result.replace(/\b(\d+\.?\d*)\b/g, `${colors.number}$1${colors.default}`);
262
+ // Keywords
263
+ result = result.replace(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g, (match) => {
264
+ if (MERMAID_KEYWORDS.has(match)) {
265
+ return `${colors.keyword}${match}${colors.default}`;
266
+ }
267
+ return match;
268
+ });
269
+ // Special characters for shapes
270
+ for (const [open, close] of MERMAID_SHAPES) {
271
+ if (!open || !close)
272
+ continue;
273
+ const openEsc = open.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
274
+ const closeEsc = close.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
275
+ result = result.replace(new RegExp(`${openEsc}([^${closeEsc}]+)${closeEsc}`, 'g'), (_, content) => {
276
+ return `${colors.special}${open}${content}${close}${colors.default}`;
277
+ });
278
+ }
279
+ // Arrow labels
280
+ result = result.replace(/\|([^|]+)\|/g, (_, content) => {
281
+ return `${colors.special}|${content}|${colors.default}`;
282
+ });
283
+ return result;
284
+ }).join("\n");
285
+ return {
286
+ html: highlighted + colors.reset,
287
+ theme: "mermaid",
288
+ };
289
+ }
290
+ // Standard code highlighting
291
+ const KEYWORDS = new Set([
292
+ "function", "const", "let", "var", "return", "if", "else", "for", "while",
293
+ "class", "interface", "type", "import", "export", "from", "async", "await",
294
+ "try", "catch", "throw", "new", "this", "extends", "implements", "static",
295
+ "public", "private", "protected", "readonly", "abstract", "enum", "namespace",
296
+ ]);
297
+ const TYPES = new Set([
298
+ "string", "number", "boolean", "void", "null", "undefined", "any", "never",
299
+ "object", "symbol", "bigint", "true", "false",
300
+ ]);
301
+ // Simple tokenization
302
+ const lines = code.split("\n");
303
+ const highlighted = lines.map(line => {
304
+ // Comments
305
+ if (line.trim().startsWith("//") || line.trim().startsWith("#")) {
306
+ return `${colors.comment}${line}${colors.reset}`;
307
+ }
308
+ // Replace strings
309
+ let result = line.replace(/(["'`])(?:(?!\1)[^\\]|\\.)*?\1/g, match => {
310
+ return `${colors.string}${match}${colors.default}`;
311
+ });
312
+ // Replace numbers
313
+ result = result.replace(/\b(\d+\.?\d*)\b/g, `${colors.number}$1${colors.default}`);
314
+ // Replace keywords
315
+ result = result.replace(/\b([a-z]+)\b/gi, (match) => {
316
+ if (KEYWORDS.has(match)) {
317
+ return `${colors.keyword}${match}${colors.default}`;
318
+ }
319
+ if (TYPES.has(match)) {
320
+ return `${colors.type}${match}${colors.default}`;
321
+ }
322
+ return match;
323
+ });
324
+ // Function names (before parentheses)
325
+ result = result.replace(/\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/g, (_, name) => {
326
+ return `${colors.function}${name}${colors.default}(`;
327
+ });
328
+ return result;
329
+ }).join("\n");
330
+ return {
331
+ html: highlighted + colors.reset,
332
+ theme: "fallback",
333
+ };
334
+ },
335
+ highlight_markdown: (markdown) => {
336
+ // Simple markdown highlighting - just return as-is with reset
337
+ // Full nested code block highlighting requires native module
338
+ return {
339
+ html: markdown + "\x1b[0m",
340
+ theme: "fallback",
341
+ };
342
+ },
343
+ highlight_diff: (oldText, newText, options) => {
344
+ // Simple line-based diff with ANSI colors
345
+ const GREEN = "\x1b[38;2;163;190;140m";
346
+ const RED = "\x1b[38;2;191;97;106m";
347
+ const DIM = "\x1b[38;2;108;153;139m";
348
+ const CYAN = "\x1b[38;2;143;161;179m";
349
+ const RESET = "\x1b[0m";
350
+ const oldLines = oldText.split("\n");
351
+ const newLines = newText.split("\n");
352
+ let output = "";
353
+ let additions = 0;
354
+ let deletions = 0;
355
+ let hunks = 0;
356
+ // File header
357
+ if (options?.file_path) {
358
+ output += `${CYAN}${options.file_path}${RESET}\n`;
359
+ }
360
+ // Simple LCS-based diff
361
+ const lcs = [];
362
+ const dp = Array.from({ length: oldLines.length + 1 }, () => Array.from({ length: newLines.length + 1 }, () => 0));
363
+ for (let i = 0; i <= oldLines.length; i++) {
364
+ for (let j = 0; j <= newLines.length; j++) {
365
+ if (i === 0 || j === 0) {
366
+ dp[i][j] = 0;
367
+ }
368
+ else if (oldLines[i - 1] === newLines[j - 1]) {
369
+ dp[i][j] = dp[i - 1][j - 1] + 1;
370
+ }
371
+ else {
372
+ dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
373
+ }
374
+ }
375
+ }
376
+ // Backtrack for LCS
377
+ let i = oldLines.length;
378
+ let j = newLines.length;
379
+ const lcsSet = new Set();
380
+ while (i > 0 && j > 0) {
381
+ if (oldLines[i - 1] === newLines[j - 1]) {
382
+ lcsSet.add(`${i - 1}:${j - 1}`);
383
+ lcs.unshift(oldLines[i - 1]);
384
+ i--;
385
+ j--;
386
+ }
387
+ else if (dp[i - 1][j] > dp[i][j - 1]) {
388
+ i--;
389
+ }
390
+ else {
391
+ j--;
392
+ }
393
+ }
394
+ // Build diff output
395
+ let oldIdx = 0;
396
+ let newIdx = 0;
397
+ let lcsIdx = 0;
398
+ while (oldIdx < oldLines.length || newIdx < newLines.length) {
399
+ // Skip matching lines
400
+ while (lcsIdx < lcs.length &&
401
+ oldIdx < oldLines.length &&
402
+ newIdx < newLines.length &&
403
+ oldLines[oldIdx] === lcs[lcsIdx] &&
404
+ newLines[newIdx] === lcs[lcsIdx]) {
405
+ oldIdx++;
406
+ newIdx++;
407
+ lcsIdx++;
408
+ }
409
+ const oldStart = oldIdx + 1;
410
+ const newStart = newIdx + 1;
411
+ let oldCount = 0;
412
+ let newCount = 0;
413
+ const hunkLines = [];
414
+ // Collect removed lines
415
+ while (oldIdx < oldLines.length &&
416
+ (lcsIdx >= lcs.length || oldLines[oldIdx] !== lcs[lcsIdx])) {
417
+ hunkLines.push(`${RED}-${oldLines[oldIdx]}${RESET}`);
418
+ oldIdx++;
419
+ oldCount++;
420
+ deletions++;
421
+ }
422
+ // Collect added lines
423
+ while (newIdx < newLines.length &&
424
+ (lcsIdx >= lcs.length || newLines[newIdx] !== lcs[lcsIdx])) {
425
+ hunkLines.push(`${GREEN}+${newLines[newIdx]}${RESET}`);
426
+ newIdx++;
427
+ newCount++;
428
+ additions++;
429
+ }
430
+ if (oldCount > 0 || newCount > 0) {
431
+ hunks++;
432
+ output += `${DIM}@@ -${oldStart},${oldCount} +${newStart},${newCount} @@${RESET}\n`;
433
+ output += hunkLines.join("\n") + "\n";
434
+ }
435
+ }
436
+ return { output, additions, deletions, hunks };
437
+ },
438
+ search_files: (pattern, path, options) => {
439
+ // Simple grep fallback
440
+ return {
441
+ matches: [],
442
+ total_count: 0,
443
+ files_searched: 0,
444
+ };
445
+ },
446
+ count_tokens: (text) => {
447
+ // Approximate token count: ~4 chars per token
448
+ return Math.ceil(text.length / 4);
449
+ },
450
+ calculate_diff: (oldText, newText) => {
451
+ // Simple line-based diff
452
+ const oldLines = oldText.split("\n");
453
+ const newLines = newText.split("\n");
454
+ const hunks = [];
455
+ // Very simple diff - just show all changes as one hunk
456
+ if (oldText !== newText) {
457
+ hunks.push({
458
+ oldStart: 1,
459
+ oldLines: oldLines.length,
460
+ newStart: 1,
461
+ newLines: newLines.length,
462
+ content: `- ${oldLines.join("\n- ")}\n+ ${newLines.join("\n+ ")}`,
463
+ });
464
+ }
465
+ return hunks;
466
+ },
467
+ compact_content: (content, maxTokens, strategy = "truncate") => {
468
+ const charsPerToken = 4;
469
+ const maxChars = maxTokens * charsPerToken;
470
+ if (content.length <= maxChars) {
471
+ return content;
472
+ }
473
+ switch (strategy) {
474
+ case "truncate":
475
+ return (content.slice(0, maxChars / 2) +
476
+ "\n\n... [truncated] ...\n\n" +
477
+ content.slice(-maxChars / 2));
478
+ case "summarize":
479
+ // Return first and last sections
480
+ const quarter = Math.floor(maxChars / 4);
481
+ return ("=== BEGINNING ===\n" +
482
+ content.slice(0, quarter) +
483
+ "\n\n=== END ===\n" +
484
+ content.slice(-quarter));
485
+ case "extract":
486
+ // Return important lines only
487
+ const lines = content.split("\n");
488
+ const important = lines.filter((line) => line.trim().startsWith("#") ||
489
+ line.trim().startsWith("function") ||
490
+ line.trim().startsWith("const") ||
491
+ line.trim().startsWith("class") ||
492
+ line.trim().startsWith("export") ||
493
+ line.trim().startsWith("import"));
494
+ return important.slice(0, maxChars / 50).join("\n");
495
+ default:
496
+ return content.slice(0, maxChars);
497
+ }
498
+ },
499
+ // Multi-file editing fallback implementation
500
+ validate_multi_edits: (edits) => {
501
+ const errors = [];
502
+ const fileContents = new Map();
503
+ const fs = require('fs');
504
+ for (const edit of edits) {
505
+ // Check file exists
506
+ try {
507
+ if (!fs.existsSync(edit.filePath)) {
508
+ errors.push(`File not found: ${edit.filePath}`);
509
+ continue;
510
+ }
511
+ // Load file content if not already loaded
512
+ if (!fileContents.has(edit.filePath)) {
513
+ const content = fs.readFileSync(edit.filePath, 'utf-8');
514
+ fileContents.set(edit.filePath, content);
515
+ }
516
+ const content = fileContents.get(edit.filePath);
517
+ // Check oldString exists
518
+ if (!content.includes(edit.oldString)) {
519
+ errors.push(`String not found in ${edit.filePath}: "${truncateString(edit.oldString, 50)}"`);
520
+ continue;
521
+ }
522
+ // Check uniqueness if not replaceAll
523
+ if (!edit.replaceAll) {
524
+ const count = (content.match(new RegExp(escapeRegex(edit.oldString), "g")) || []).length;
525
+ if (count > 1) {
526
+ errors.push(`String appears ${count} times in ${edit.filePath}. Use replaceAll or provide more context.`);
527
+ }
528
+ }
529
+ }
530
+ catch (err) {
531
+ errors.push(`Error reading ${edit.filePath}: ${err}`);
532
+ }
533
+ }
534
+ return errors;
535
+ },
536
+ preview_multi_edits: (edits) => {
537
+ const results = [];
538
+ const fileReplacements = new Map();
539
+ const fs = require('fs');
540
+ for (const edit of edits) {
541
+ try {
542
+ if (!fs.existsSync(edit.filePath))
543
+ continue;
544
+ const content = fs.readFileSync(edit.filePath, 'utf-8');
545
+ const count = edit.replaceAll
546
+ ? (content.match(new RegExp(escapeRegex(edit.oldString), "g")) || []).length
547
+ : 1;
548
+ fileReplacements.set(edit.filePath, (fileReplacements.get(edit.filePath) || 0) + count);
549
+ }
550
+ catch {
551
+ // Skip files that can't be read
552
+ }
553
+ }
554
+ for (const [filePath, replacementCount] of fileReplacements) {
555
+ results.push({ filePath, replacementCount });
556
+ }
557
+ return results;
558
+ },
559
+ apply_multi_edits: (edits) => {
560
+ // First validate all edits
561
+ const errors = getFallbackModule().validate_multi_edits(edits);
562
+ if (errors.length > 0) {
563
+ return {
564
+ success: false,
565
+ filesModified: [],
566
+ totalReplacements: 0,
567
+ error: errors.join("\n"),
568
+ rolledBack: false,
569
+ };
570
+ }
571
+ // Create backups
572
+ const backups = new Map();
573
+ const uniqueFiles = new Set(edits.map(e => e.filePath));
574
+ const fs = require('fs');
575
+ for (const filePath of uniqueFiles) {
576
+ try {
577
+ backups.set(filePath, fs.readFileSync(filePath, 'utf-8'));
578
+ }
579
+ catch (err) {
580
+ return {
581
+ success: false,
582
+ filesModified: [],
583
+ totalReplacements: 0,
584
+ error: `Failed to backup ${filePath}: ${err}`,
585
+ rolledBack: false,
586
+ };
587
+ }
588
+ }
589
+ // Apply edits
590
+ const currentContents = new Map();
591
+ for (const [path, content] of backups) {
592
+ currentContents.set(path, content);
593
+ }
594
+ let totalReplacements = 0;
595
+ for (const edit of edits) {
596
+ const content = currentContents.get(edit.filePath);
597
+ if (!content)
598
+ continue;
599
+ if (edit.replaceAll) {
600
+ const count = (content.match(new RegExp(escapeRegex(edit.oldString), "g")) || []).length;
601
+ currentContents.set(edit.filePath, content.split(edit.oldString).join(edit.newString));
602
+ totalReplacements += count;
603
+ }
604
+ else {
605
+ currentContents.set(edit.filePath, content.replace(edit.oldString, edit.newString));
606
+ totalReplacements += 1;
607
+ }
608
+ }
609
+ // Write all files
610
+ const filesModified = [];
611
+ for (const [path, newContent] of currentContents) {
612
+ const originalContent = backups.get(path);
613
+ if (newContent !== originalContent) {
614
+ try {
615
+ Bun.write(path, newContent);
616
+ filesModified.push(path);
617
+ }
618
+ catch (err) {
619
+ // Rollback on failure
620
+ for (const [rollbackPath, rollbackContent] of backups) {
621
+ try {
622
+ Bun.write(rollbackPath, rollbackContent);
623
+ }
624
+ catch {
625
+ // Ignore rollback errors
626
+ }
627
+ }
628
+ return {
629
+ success: false,
630
+ filesModified: [],
631
+ totalReplacements: 0,
632
+ error: `Failed to write ${path}: ${err}. All changes rolled back.`,
633
+ rolledBack: true,
634
+ };
635
+ }
636
+ }
637
+ }
638
+ return {
639
+ success: true,
640
+ filesModified: filesModified,
641
+ totalReplacements: totalReplacements,
642
+ error: undefined,
643
+ rolledBack: false,
644
+ };
645
+ },
646
+ // Tool analysis fallback implementations
647
+ count_tool_use: (messages) => {
648
+ const counts = {};
649
+ for (const msg of messages) {
650
+ if (msg.tool_use) {
651
+ for (const tool of msg.tool_use) {
652
+ counts[tool.name] = (counts[tool.name] || 0) + 1;
653
+ }
654
+ }
655
+ }
656
+ return counts;
657
+ },
658
+ find_tool_pairs: (messages, _windowSize) => {
659
+ const pairs = {};
660
+ for (const msg of messages) {
661
+ if (msg.tool_use && msg.tool_use.length >= 2) {
662
+ for (let i = 0; i < msg.tool_use.length - 1; i++) {
663
+ const tool1 = msg.tool_use[i]?.name;
664
+ const tool2 = msg.tool_use[i + 1]?.name;
665
+ if (tool1 && tool2) {
666
+ if (!pairs[tool1])
667
+ pairs[tool1] = {};
668
+ pairs[tool1][tool2] = (pairs[tool1][tool2] || 0) + 1;
669
+ }
670
+ }
671
+ }
672
+ }
673
+ return pairs;
674
+ },
675
+ find_common_patterns: (messages) => {
676
+ const patterns = [];
677
+ const toolPairs = new Map();
678
+ let totalPairs = 0;
679
+ for (const msg of messages) {
680
+ if (msg.tool_use && msg.tool_use.length >= 2) {
681
+ for (let i = 0; i < msg.tool_use.length - 1; i++) {
682
+ const name1 = msg.tool_use[i]?.name;
683
+ const name2 = msg.tool_use[i + 1]?.name;
684
+ if (name1 && name2) {
685
+ const key = `${name1}|${name2}`;
686
+ toolPairs.set(key, (toolPairs.get(key) || 0) + 1);
687
+ totalPairs++;
688
+ }
689
+ }
690
+ }
691
+ }
692
+ for (const [key, count] of toolPairs) {
693
+ const [tool1, tool2] = key.split("|");
694
+ patterns.push({
695
+ tools: [tool1, tool2],
696
+ count,
697
+ percentage: totalPairs > 0 ? (count / totalPairs) * 100 : 0,
698
+ });
699
+ }
700
+ return patterns.sort((a, b) => b.count - a.count).slice(0, 10);
701
+ },
702
+ // ===== Cognitive Security Fallbacks =====
703
+ // Action Module
704
+ classify_operation: (operation, domain, target, reasoning) => {
705
+ const id = `action_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
706
+ let actionType = "observe";
707
+ let riskLevel = 1;
708
+ let hasSideEffects = false;
709
+ let requiresApproval = false;
710
+ const op = operation.toLowerCase();
711
+ if (op.includes("write") || op.includes("edit") || op.includes("create") || op.includes("delete")) {
712
+ actionType = "modify";
713
+ riskLevel = 3;
714
+ hasSideEffects = true;
715
+ requiresApproval = true;
716
+ }
717
+ else if (op.includes("execute") || op.includes("run") || op.includes("bash")) {
718
+ actionType = "execute";
719
+ riskLevel = 4;
720
+ hasSideEffects = true;
721
+ requiresApproval = true;
722
+ }
723
+ else if (op.includes("send") || op.includes("post") || op.includes("transmit")) {
724
+ actionType = "communicate";
725
+ riskLevel = 2;
726
+ hasSideEffects = true;
727
+ requiresApproval = domain === "external";
728
+ }
729
+ else if (op.includes("read") || op.includes("get") || op.includes("list") || op.includes("search")) {
730
+ actionType = "observe";
731
+ riskLevel = 1;
732
+ hasSideEffects = false;
733
+ requiresApproval = false;
734
+ }
735
+ return {
736
+ id,
737
+ actionType,
738
+ domain,
739
+ operation,
740
+ target: target || null,
741
+ flowDirection: "outbound",
742
+ riskLevel,
743
+ hasSideEffects,
744
+ requiresApproval,
745
+ reasoning: reasoning || `Classified as ${actionType} based on operation name`,
746
+ timestamp: Date.now(),
747
+ metadata: null,
748
+ };
749
+ },
750
+ get_action_types: () => ["modify", "execute", "communicate", "transfer", "observe", "create", "delete"],
751
+ get_action_risk_levels: () => [
752
+ { actionType: "observe", riskLevel: 1 },
753
+ { actionType: "communicate", riskLevel: 2 },
754
+ { actionType: "create", riskLevel: 3 },
755
+ { actionType: "modify", riskLevel: 3 },
756
+ { actionType: "transfer", riskLevel: 4 },
757
+ { actionType: "execute", riskLevel: 4 },
758
+ { actionType: "delete", riskLevel: 5 },
759
+ ],
760
+ create_deny_all_policy: () => ({
761
+ id: "deny_all",
762
+ description: "Deny all actions",
763
+ actionTypes: [],
764
+ domains: [],
765
+ operations: [],
766
+ effect: "deny",
767
+ priority: 1000,
768
+ enabled: true,
769
+ }),
770
+ create_observe_only_policy: () => ({
771
+ id: "observe_only",
772
+ description: "Allow observe actions only",
773
+ actionTypes: ["observe"],
774
+ domains: [],
775
+ operations: [],
776
+ effect: "allow",
777
+ priority: 100,
778
+ enabled: true,
779
+ }),
780
+ create_transfer_approval_policy: () => ({
781
+ id: "transfer_approval",
782
+ description: "Require approval for transfer actions",
783
+ actionTypes: ["transfer"],
784
+ domains: [],
785
+ operations: [],
786
+ effect: "require_approval",
787
+ priority: 200,
788
+ enabled: true,
789
+ }),
790
+ // Intent Module
791
+ cs_generate_keypair: () => ({
792
+ privateKey: `private_${Math.random().toString(36).slice(2)}_${Date.now()}`,
793
+ publicKey: `public_${Math.random().toString(36).slice(2)}_${Date.now()}`,
794
+ }),
795
+ cs_sign_intent: (intent, _privateKey) => {
796
+ return { ...intent, signature: `sig_${Date.now()}`, signedBy: "fallback" };
797
+ },
798
+ cs_verify_intent: (_intent) => ({
799
+ valid: true,
800
+ error: null,
801
+ signatureValid: true,
802
+ contentIntact: true,
803
+ expired: false,
804
+ }),
805
+ cs_hash_intent: (intent) => {
806
+ const str = JSON.stringify(intent);
807
+ let hash = 0;
808
+ for (let i = 0; i < str.length; i++) {
809
+ const char = str.charCodeAt(i);
810
+ hash = ((hash << 5) - hash) + char;
811
+ hash = hash & hash;
812
+ }
813
+ return Math.abs(hash).toString(16).padStart(16, '0');
814
+ },
815
+ cs_intents_equivalent: (intent1, intent2) => {
816
+ const stripSignature = (i) => {
817
+ const { signature, signedBy, ...rest } = i;
818
+ return rest;
819
+ };
820
+ return JSON.stringify(stripSignature(intent1)) === JSON.stringify(stripSignature(intent2));
821
+ },
822
+ cs_score_alignment: (_action, _intent) => ({
823
+ score: 0.8,
824
+ reasoning: "Fallback alignment score - native module not available",
825
+ servesGoals: [],
826
+ hindersGoals: [],
827
+ boundaryConcerns: [],
828
+ confidence: 0.5,
829
+ shouldBlock: false,
830
+ requiresReview: false,
831
+ }),
832
+ cs_batch_score_alignment: (actions, intent) => {
833
+ return actions.map(() => ({
834
+ score: 0.8,
835
+ reasoning: "Fallback alignment score",
836
+ servesGoals: [],
837
+ hindersGoals: [],
838
+ boundaryConcerns: [],
839
+ confidence: 0.5,
840
+ shouldBlock: false,
841
+ requiresReview: false,
842
+ }));
843
+ },
844
+ cs_check_sequence_violations: (_actions, _intent) => [],
845
+ cs_load_intent: (_path) => {
846
+ throw new Error("Native module required for cs_load_intent");
847
+ },
848
+ cs_save_intent: (_intent, _path) => {
849
+ throw new Error("Native module required for cs_save_intent");
850
+ },
851
+ cs_parse_intent: (json) => JSON.parse(json),
852
+ cs_serialize_intent: (intent) => JSON.stringify(intent, null, 2),
853
+ cs_validate_intent: (intent) => {
854
+ const errors = [];
855
+ const warnings = [];
856
+ if (!intent.id)
857
+ errors.push("Missing intent id");
858
+ if (!intent.version)
859
+ warnings.push("Missing version");
860
+ if (!intent.identity)
861
+ errors.push("Missing identity");
862
+ if (!intent.purpose)
863
+ errors.push("Missing purpose");
864
+ return {
865
+ valid: errors.length === 0,
866
+ errors,
867
+ warnings,
868
+ };
869
+ },
870
+ cs_create_data_collector_intent: (name, description) => ({
871
+ id: `intent_${Date.now()}`,
872
+ version: 1,
873
+ identity: {
874
+ name,
875
+ description,
876
+ capabilities: ["read", "list", "search"],
877
+ constraints: ["no_write", "no_execute", "no_network"],
878
+ },
879
+ purpose: {
880
+ goals: [],
881
+ nonGoals: ["modify_data", "execute_commands", "send_data"],
882
+ boundaries: [],
883
+ },
884
+ principles: {
885
+ values: ["transparency", "privacy"],
886
+ priorities: ["safety_first"],
887
+ forbidden: ["exfiltration", "modification"],
888
+ },
889
+ createdAt: Date.now(),
890
+ }),
891
+ cs_merge_intents: (base, override) => ({ ...base, ...override }),
892
+ cs_analyze_corruption: (_snapshot, _intent) => ({
893
+ riskScore: 0,
894
+ indicators: [],
895
+ recommendation: "continue",
896
+ explanation: "Fallback analysis - native module not available",
897
+ }),
898
+ cs_detect_drift: (_baseline, _current) => ({
899
+ overallDrift: 0,
900
+ driftFactors: [],
901
+ concernLevel: "none",
902
+ }),
903
+ cs_create_empty_snapshot: () => ({
904
+ timestamp: Date.now(),
905
+ actionCount: 0,
906
+ alignmentDistribution: { mean: 1, variance: 0, min: 1, max: 1, belowThresholdCount: 0 },
907
+ actionsByDomain: [],
908
+ actionsByType: [],
909
+ boundaryViolations: 0,
910
+ actionsBlocked: 0,
911
+ }),
912
+ cs_update_snapshot: (snapshot, _action, alignment) => {
913
+ const newScore = alignment?.score ?? 1;
914
+ const oldMean = snapshot.alignmentDistribution?.mean ?? 1;
915
+ const newMean = (oldMean * snapshot.actionCount + newScore) / (snapshot.actionCount + 1);
916
+ return {
917
+ ...snapshot,
918
+ timestamp: Date.now(),
919
+ actionCount: snapshot.actionCount + 1,
920
+ alignmentDistribution: {
921
+ ...snapshot.alignmentDistribution,
922
+ mean: newMean,
923
+ },
924
+ };
925
+ },
926
+ // Flow Module
927
+ classify_data: (content, source, tags) => {
928
+ let sensitivity = "internal";
929
+ let category = "generic";
930
+ if (content.includes("password") || content.includes("secret") || content.includes("key")) {
931
+ sensitivity = "secret";
932
+ category = "credentials";
933
+ }
934
+ else if (content.includes("@") && content.includes(".")) {
935
+ sensitivity = "confidential";
936
+ category = "pii";
937
+ }
938
+ return {
939
+ id: `data_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
940
+ sensitivity,
941
+ category,
942
+ source,
943
+ tags,
944
+ can_log: sensitivity !== "secret",
945
+ can_transmit: sensitivity === "public" || sensitivity === "internal",
946
+ can_store: true,
947
+ expires_at: null,
948
+ created_at: Date.now(),
949
+ };
950
+ },
951
+ contains_sensitive_data: (content) => {
952
+ const patterns = ["password", "secret", "api_key", "token", "credential"];
953
+ return patterns.some(p => content.toLowerCase().includes(p));
954
+ },
955
+ redact_sensitive: (content, replacement) => {
956
+ const repl = replacement || "[REDACTED]";
957
+ return content
958
+ .replace(/password[=:]\s*\S+/gi, `password=${repl}`)
959
+ .replace(/api[_-]?key[=:]\s*\S+/gi, `api_key=${repl}`)
960
+ .replace(/token[=:]\s*\S+/gi, `token=${repl}`)
961
+ .replace(/secret[=:]\s*\S+/gi, `secret=${repl}`);
962
+ },
963
+ get_sensitivity_levels: () => [
964
+ { name: "public", value: 1, description: "Publicly shareable" },
965
+ { name: "internal", value: 2, description: "Internal use only" },
966
+ { name: "confidential", value: 3, description: "Confidential" },
967
+ { name: "secret", value: 4, description: "Highly sensitive" },
968
+ { name: "top_secret", value: 5, description: "Maximum sensitivity" },
969
+ ],
970
+ get_data_categories: () => [
971
+ { name: "generic", description: "Generic data" },
972
+ { name: "pii", description: "Personally identifiable information" },
973
+ { name: "credentials", description: "Authentication credentials" },
974
+ { name: "financial", description: "Financial data" },
975
+ { name: "source_code", description: "Source code" },
976
+ { name: "configuration", description: "Configuration data" },
977
+ ],
978
+ // Flow Policy Engine
979
+ create_flow_policy_engine: () => ({
980
+ addPolicy: (_policy) => { },
981
+ removePolicy: (_id) => true,
982
+ evaluate: (_data, _source, _target) => ({
983
+ allowed: true,
984
+ reason: "Fallback: allowed by default",
985
+ applied_policy: null,
986
+ can_log: true,
987
+ can_transmit: true,
988
+ can_store: true,
989
+ transformations: [],
990
+ confidence: 0.5,
991
+ warnings: ["Fallback implementation - native module not available"],
992
+ }),
993
+ listPolicies: () => [],
994
+ setDefaultAction: (_action) => { },
995
+ setBlpMode: (_mode) => { },
996
+ }),
997
+ // Flow Policies
998
+ create_allow_all_flow_policy: () => ({
999
+ id: "allow_all",
1000
+ description: "Allow all flows",
1001
+ source_pattern: "*",
1002
+ target_pattern: "*",
1003
+ min_source_sensitivity: null,
1004
+ max_target_sensitivity: null,
1005
+ categories: [],
1006
+ effect: "allow",
1007
+ priority: 0,
1008
+ required_transforms: [],
1009
+ log_flow: false,
1010
+ require_approval: false,
1011
+ conditions: null,
1012
+ enabled: true,
1013
+ }),
1014
+ create_deny_all_flow_policy: () => ({
1015
+ id: "deny_all",
1016
+ description: "Deny all flows",
1017
+ source_pattern: "*",
1018
+ target_pattern: "*",
1019
+ min_source_sensitivity: null,
1020
+ max_target_sensitivity: null,
1021
+ categories: [],
1022
+ effect: "deny",
1023
+ priority: 1000,
1024
+ required_transforms: [],
1025
+ log_flow: false,
1026
+ require_approval: false,
1027
+ conditions: null,
1028
+ enabled: true,
1029
+ }),
1030
+ create_strict_flow_policy: () => ({
1031
+ id: "strict",
1032
+ description: "Strict flow policy",
1033
+ source_pattern: "*",
1034
+ target_pattern: "*",
1035
+ min_source_sensitivity: "internal",
1036
+ max_target_sensitivity: null,
1037
+ categories: [],
1038
+ effect: "transform",
1039
+ priority: 500,
1040
+ required_transforms: ["redact_sensitive"],
1041
+ log_flow: true,
1042
+ require_approval: true,
1043
+ conditions: null,
1044
+ enabled: true,
1045
+ }),
1046
+ // Flow Tracker
1047
+ create_flow_tracker: () => ({
1048
+ record: (_data, _source, _target, _direction, _validation, _sessionId, _actionId) => ({
1049
+ id: `flow_${Date.now()}`,
1050
+ data_id: _data.id,
1051
+ source_domain: _source,
1052
+ target_domain: _target,
1053
+ direction: _direction,
1054
+ allowed: _validation.allowed,
1055
+ reason: _validation.reason,
1056
+ policy_id: _validation.applied_policy || null,
1057
+ session_id: _sessionId,
1058
+ action_id: _actionId,
1059
+ timestamp: Date.now(),
1060
+ data_hash: "",
1061
+ }),
1062
+ getFlow: (_id) => null,
1063
+ getLineage: (_dataId) => [],
1064
+ bySource: (_domain) => [],
1065
+ byTarget: (_domain) => [],
1066
+ bySession: (_sessionId) => [],
1067
+ blocked: () => [],
1068
+ allowed: () => [],
1069
+ recent: (_limit) => [],
1070
+ stats: () => ({
1071
+ total_flows: 0,
1072
+ allowed_count: 0,
1073
+ blocked_count: 0,
1074
+ by_direction: [],
1075
+ by_source_domain: [],
1076
+ by_target_domain: [],
1077
+ first_timestamp: Date.now(),
1078
+ last_timestamp: Date.now(),
1079
+ }),
1080
+ domainStats: (_domain) => null,
1081
+ count: () => 0,
1082
+ clear: () => { },
1083
+ setMaxFlows: (_max) => { },
1084
+ exportJsonl: () => "",
1085
+ }),
1086
+ // Leak Prevention
1087
+ create_leak_prevention: () => ({
1088
+ check: (_content, _channel) => ({
1089
+ action: "allow",
1090
+ detections: [],
1091
+ channel_allowed: true,
1092
+ checked_at: Date.now(),
1093
+ }),
1094
+ sanitize: (content) => content
1095
+ .replace(/password[=:]\s*\S+/gi, "password=[REDACTED]")
1096
+ .replace(/api[_-]?key[=:]\s*\S+/gi, "api_key=[REDACTED]")
1097
+ .replace(/token[=:]\s*\S+/gi, "token=[REDACTED]")
1098
+ .replace(/secret[=:]\s*\S+/gi, "secret=[REDACTED]"),
1099
+ registerSensitive: (_data) => { },
1100
+ addChannel: (_channel) => { },
1101
+ removeChannel: (_channel) => { },
1102
+ setMode: (_mode) => { },
1103
+ stats: () => ({
1104
+ total_checks: 0,
1105
+ blocked_count: 0,
1106
+ alert_count: 0,
1107
+ by_leak_type: {},
1108
+ }),
1109
+ clearSensitive: () => { },
1110
+ }),
1111
+ // Leak Prevention helpers
1112
+ check_for_leaks: (content, channel) => ({
1113
+ action: "allow",
1114
+ detections: [],
1115
+ channel_allowed: true,
1116
+ checked_at: Date.now(),
1117
+ }),
1118
+ sanitize_content: (content) => content
1119
+ .replace(/password[=:]\s*\S+/gi, "password=[REDACTED]")
1120
+ .replace(/api[_-]?key[=:]\s*\S+/gi, "api_key=[REDACTED]")
1121
+ .replace(/token[=:]\s*\S+/gi, "token=[REDACTED]")
1122
+ .replace(/secret[=:]\s*\S+/gi, "secret=[REDACTED]"),
1123
+ // Taint Tracker
1124
+ create_taint_tracker: () => ({
1125
+ registerSource: (_type, _sensitivity, _tags) => `source_${Date.now()}`,
1126
+ taint: (_sourceId, _data, _locationType, _identifier) => `taint_${Date.now()}`,
1127
+ propagate: (_sourceTaintId, _newData, _locationType, _identifier, _propagationType, _operation) => `prop_${Date.now()}`,
1128
+ canFlow: (_taintId, _sink) => ({ allowed: true, reason: "Fallback", requires_sanitization: false }),
1129
+ isTainted: (_data) => false,
1130
+ getTaint: (_taintId) => null,
1131
+ stats: () => ({
1132
+ total_sources: 0,
1133
+ total_tainted: 0,
1134
+ total_propagations: 0,
1135
+ by_source_type: {},
1136
+ by_sensitivity: {},
1137
+ }),
1138
+ clear: (_taintId) => false,
1139
+ clearAll: () => { },
1140
+ }),
1141
+ // Quant Functions (stubs)
1142
+ quant_version: () => "0.1.0-fallback",
1143
+ quant_ohlcv_new: (_ts, _o, _h, _l, _c, _v) => JSON.stringify({ open: _o, high: _h, low: _l, close: _c, volume: _v }),
1144
+ quant_amm_new: (_poolYes, _poolNo, _fee) => JSON.stringify({ poolYes: _poolYes, poolNo: _poolNo, fee: _fee }),
1145
+ quant_amm_calculate_cost: (_poolYes, _poolNo, _buyYes, _shares) => JSON.stringify({ cost: 0 }),
1146
+ quant_amm_price_impact: (_poolYes, _poolNo, _buyYes, _shares) => JSON.stringify({ impact: 0 }),
1147
+ quant_lmsr_price: (_yesShares, _noShares, _b) => JSON.stringify({ price: 0.5 }),
1148
+ quant_lmsr_cost: (_yesShares, _noShares, _b, _buyYes, _shares) => JSON.stringify({ cost: 0 }),
1149
+ quant_detect_arbitrage: (_yesPrice, _noPrice) => JSON.stringify({ hasArbitrage: false }),
1150
+ quant_convert_odds: (_value, _fromType) => JSON.stringify({ decimal: 0 }),
1151
+ quant_mean: (_data) => 0,
1152
+ quant_std_dev: (_data) => 0,
1153
+ quant_variance: (_data) => 0,
1154
+ quant_correlation: (_x, _y) => 0,
1155
+ // Terminal Input (fallback - uses Node.js stdin directly)
1156
+ create_terminal: () => {
1157
+ let inRawMode = false;
1158
+ return {
1159
+ get isRawMode() { return inRawMode; },
1160
+ enterRawMode() {
1161
+ if (process.stdin.isTTY && !inRawMode) {
1162
+ process.stdin.setRawMode(true);
1163
+ process.stdin.resume();
1164
+ inRawMode = true;
1165
+ }
1166
+ },
1167
+ exitRawMode() {
1168
+ if (process.stdin.isTTY && inRawMode) {
1169
+ process.stdin.setRawMode(false);
1170
+ inRawMode = false;
1171
+ }
1172
+ },
1173
+ pollEvent(_timeoutMs) {
1174
+ // Fallback can't poll synchronously - return null
1175
+ // Use readEvent() instead for async operation
1176
+ return null;
1177
+ },
1178
+ async readEvent() {
1179
+ return new Promise((resolve) => {
1180
+ const handler = (buffer) => {
1181
+ process.stdin.off("data", handler);
1182
+ const str = buffer.toString("utf8");
1183
+ // Parse simple keypresses
1184
+ if (str === "\r" || str === "\n") {
1185
+ resolve({ code: "enter", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1186
+ }
1187
+ else if (str === "\x03") {
1188
+ // Ctrl+C
1189
+ resolve({ code: "c", is_special: false, ctrl: true, alt: false, shift: false, kind: "press" });
1190
+ }
1191
+ else if (str === "\x7f" || str === "\x08") {
1192
+ resolve({ code: "backspace", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1193
+ }
1194
+ else if (str === "\x1b") {
1195
+ resolve({ code: "escape", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1196
+ }
1197
+ else if (str === "\t") {
1198
+ resolve({ code: "tab", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1199
+ }
1200
+ else if (str.length === 1 && str >= " ") {
1201
+ // Regular printable character
1202
+ const ctrl = str.charCodeAt(0) < 32;
1203
+ const char = ctrl ? String.fromCharCode(str.charCodeAt(0) + 96) : str;
1204
+ resolve({ code: char, is_special: false, ctrl, alt: false, shift: false, kind: "press" });
1205
+ }
1206
+ else {
1207
+ // Handle escape sequences for arrows and special keys
1208
+ if (str === "\x1b[A") {
1209
+ resolve({ code: "up", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1210
+ }
1211
+ else if (str === "\x1b[B") {
1212
+ resolve({ code: "down", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1213
+ }
1214
+ else if (str === "\x1b[C") {
1215
+ resolve({ code: "right", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1216
+ }
1217
+ else if (str === "\x1b[D") {
1218
+ resolve({ code: "left", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1219
+ }
1220
+ else if (str === "\x1b[5~") {
1221
+ resolve({ code: "pageup", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1222
+ }
1223
+ else if (str === "\x1b[6~") {
1224
+ resolve({ code: "pagedown", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1225
+ }
1226
+ else if (str === "\x1b[H" || str === "\x1b[1~") {
1227
+ resolve({ code: "home", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1228
+ }
1229
+ else if (str === "\x1b[F" || str === "\x1b[4~") {
1230
+ resolve({ code: "end", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1231
+ }
1232
+ else if (str === "\x1b[3~") {
1233
+ resolve({ code: "delete", is_special: true, ctrl: false, alt: false, shift: false, kind: "press" });
1234
+ }
1235
+ else if (str === "\x1b[Z") {
1236
+ resolve({ code: "backtab", is_special: true, ctrl: false, alt: false, shift: true, kind: "press" });
1237
+ }
1238
+ else {
1239
+ // Unknown escape sequence - treat as-is
1240
+ resolve({ code: str, is_special: false, ctrl: false, alt: false, shift: false, kind: "press" });
1241
+ }
1242
+ }
1243
+ };
1244
+ process.stdin.once("data", handler);
1245
+ });
1246
+ },
1247
+ };
1248
+ },
1249
+ // Native TUI (fallback - not available in pure JS)
1250
+ create_tui: () => {
1251
+ throw new Error("Native TUI not available in fallback mode. Build the Rust native module.");
1252
+ },
1253
+ is_native_tui_available: () => false,
1254
+ };
1255
+ }
1256
+ // Export a singleton instance
1257
+ export const native = loadNative();
1258
+ /**
1259
+ * Syntax highlight code with ANSI escape codes for terminal display
1260
+ * Uses native Rust module if available, falls back to JS implementation
1261
+ */
1262
+ export function highlight_code(code, language) {
1263
+ return native.highlight_code(code, language);
1264
+ }
1265
+ /**
1266
+ * Highlight markdown with nested code block syntax highlighting
1267
+ * Parses markdown for code fences and highlights code blocks with their language
1268
+ */
1269
+ export function highlight_markdown(markdown) {
1270
+ return native.highlight_markdown(markdown);
1271
+ }
1272
+ /**
1273
+ * List all supported languages for syntax highlighting
1274
+ */
1275
+ export function list_highlight_languages() {
1276
+ return [
1277
+ // Core languages
1278
+ "typescript", "ts", "javascript", "js",
1279
+ "python", "py",
1280
+ "rust", "rs",
1281
+ "go", "golang",
1282
+ "ruby", "rb",
1283
+ "java",
1284
+ "c", "cpp", "c++", "csharp", "cs", "c#",
1285
+ "php",
1286
+ "swift",
1287
+ "kotlin", "kt",
1288
+ "scala",
1289
+ // Shell & config
1290
+ "shell", "sh", "bash", "zsh",
1291
+ "json",
1292
+ "yaml", "yml",
1293
+ "toml",
1294
+ // Markup
1295
+ "markdown", "md",
1296
+ "html", "htm",
1297
+ "css", "scss", "less",
1298
+ "xml",
1299
+ // Database
1300
+ "sql",
1301
+ // Diagrams
1302
+ "mermaid", "mmd",
1303
+ ];
1304
+ }
1305
+ /**
1306
+ * Highlight a diff with ANSI colors
1307
+ * Uses native Rust module if available, falls back to JS implementation
1308
+ */
1309
+ export function highlight_diff(oldText, newText, options) {
1310
+ return native.highlight_diff(oldText, newText, options);
1311
+ }
1312
+ /**
1313
+ * Calculate diff hunks with hunk headers for LLM context
1314
+ * Returns structured diff with @@ headers included in content
1315
+ */
1316
+ export function calculate_diff(oldText, newText) {
1317
+ return native.calculate_diff(oldText, newText);
1318
+ }
1319
+ // ===== Multi-File Edit Functions =====
1320
+ /**
1321
+ * Validate multi-file edits without applying them
1322
+ * Returns an array of error messages (empty if valid)
1323
+ */
1324
+ export function validate_multi_edits(edits) {
1325
+ return native.validate_multi_edits(edits);
1326
+ }
1327
+ /**
1328
+ * Preview what edits would be applied without making changes
1329
+ * Returns an array of { file_path, replacement_count } for each file
1330
+ */
1331
+ export function preview_multi_edits(edits) {
1332
+ return native.preview_multi_edits(edits);
1333
+ }
1334
+ /**
1335
+ * Apply multiple file edits atomically with rollback on failure
1336
+ *
1337
+ * This function:
1338
+ * 1. Validates all edits can be applied (files exist, strings found)
1339
+ * 2. Creates backups of all affected files
1340
+ * 3. Applies all edits
1341
+ * 4. Rolls back on any failure
1342
+ *
1343
+ * @param edits Array of edit operations
1344
+ * @returns Result with success status and list of modified files
1345
+ */
1346
+ export function apply_multi_edits(edits) {
1347
+ return native.apply_multi_edits(edits);
1348
+ }
1349
+ // ===== Helper Functions =====
1350
+ function truncateString(s, maxLen) {
1351
+ if (s.length <= maxLen)
1352
+ return s;
1353
+ return s.slice(0, maxLen) + "...";
1354
+ }
1355
+ function escapeRegex(string) {
1356
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1357
+ }
1358
+ let quantModule = null;
1359
+ /**
1360
+ * Load the quant native module from @ebowwa/quant-rust
1361
+ */
1362
+ function loadQuant() {
1363
+ if (quantModule)
1364
+ return quantModule;
1365
+ const __dirname = dirname(fileURLToPath(import.meta.url));
1366
+ // Try multiple paths for the quant library
1367
+ const libName = process.platform === "darwin"
1368
+ ? "libquant_rust.dylib"
1369
+ : process.platform === "linux"
1370
+ ? "libquant_rust.so"
1371
+ : "quant_rust.dll";
1372
+ const possiblePaths = [
1373
+ // From npm package
1374
+ join(__dirname, "..", "..", "node_modules", "@ebowwa", "quant-rust", "native", `${process.platform}-${process.arch}`, libName),
1375
+ // From npm package (alternate)
1376
+ join(__dirname, "..", "..", "..", "@ebowwa", "quant-rust", "native", `${process.platform}-${process.arch}`, libName),
1377
+ // Development build
1378
+ join(__dirname, "..", "..", "node_modules", "@ebowwa", "quant-rust", "target", "release", libName),
1379
+ ];
1380
+ for (const libPath of possiblePaths) {
1381
+ try {
1382
+ const { existsSync } = require("fs");
1383
+ if (!existsSync(libPath))
1384
+ continue;
1385
+ const { dlopen, FFIType, ptr } = require("bun:ffi");
1386
+ const lib = dlopen(libPath, {
1387
+ quant_version: { returns: FFIType.cstring, args: [] },
1388
+ quant_last_error: { returns: FFIType.cstring, args: [] },
1389
+ quant_clear_error: { returns: FFIType.void, args: [] },
1390
+ quant_ohlcv_new: { returns: FFIType.cstring, args: [FFIType.u64, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64, FFIType.f64] },
1391
+ quant_amm_new: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.f64, FFIType.f64] },
1392
+ quant_amm_calculate_cost: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.f64, FFIType.bool, FFIType.f64] },
1393
+ quant_amm_price_impact: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.f64, FFIType.bool, FFIType.f64] },
1394
+ quant_lmsr_price: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.f64, FFIType.f64] },
1395
+ quant_lmsr_cost: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.f64, FFIType.f64, FFIType.bool, FFIType.f64] },
1396
+ quant_detect_arbitrage: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.f64] },
1397
+ quant_convert_odds: { returns: FFIType.cstring, args: [FFIType.f64, FFIType.i32] },
1398
+ quant_mean: { returns: FFIType.f64, args: [FFIType.ptr, FFIType.usize] },
1399
+ quant_std_dev: { returns: FFIType.f64, args: [FFIType.ptr, FFIType.usize] },
1400
+ quant_variance: { returns: FFIType.f64, args: [FFIType.ptr, FFIType.usize] },
1401
+ quant_correlation: { returns: FFIType.f64, args: [FFIType.ptr, FFIType.ptr, FFIType.usize] },
1402
+ quant_free_string: { returns: FFIType.void, args: [FFIType.ptr] },
1403
+ });
1404
+ quantModule = lib.symbols;
1405
+ return quantModule;
1406
+ }
1407
+ catch {
1408
+ continue;
1409
+ }
1410
+ }
1411
+ return null;
1412
+ }
1413
+ // Load quant module
1414
+ export const quant = loadQuant();
1415
+ // ===== Quant Helper Functions =====
1416
+ function parseQuantJson(response) {
1417
+ if (!response) {
1418
+ throw new Error(quant?.quant_last_error() || "Unknown quant error");
1419
+ }
1420
+ return JSON.parse(response);
1421
+ }
1422
+ function toFloat64Ptr(data) {
1423
+ const { ptr } = require("bun:ffi");
1424
+ const buffer = new Float64Array(data);
1425
+ return { buffer, ptr: ptr(buffer) };
1426
+ }
1427
+ // ===== Quant Export Functions =====
1428
+ /** Warn once when using JS fallback */
1429
+ let quantFallbackWarned = false;
1430
+ function warnQuantFallback() {
1431
+ if (!quantFallbackWarned) {
1432
+ console.warn("\x1b[33m[quant] WARNING: Rust native module not loaded, using JS fallback\x1b[0m");
1433
+ quantFallbackWarned = true;
1434
+ }
1435
+ }
1436
+ export function quantVersion() {
1437
+ if (!quant) {
1438
+ warnQuantFallback();
1439
+ return "JS_FALLBACK (rust failed)";
1440
+ }
1441
+ return quant.quant_version();
1442
+ }
1443
+ export function isQuantAvailable() {
1444
+ return quant !== null;
1445
+ }
1446
+ // ----- OHLCV -----
1447
+ export function createOHLCV(timestamp, open, high, low, close, volume) {
1448
+ if (!quant) {
1449
+ warnQuantFallback();
1450
+ return { timestamp, open, high, low, close, volume };
1451
+ }
1452
+ const response = quant.quant_ohlcv_new(BigInt(timestamp), open, high, low, close, volume);
1453
+ return parseQuantJson(response);
1454
+ }
1455
+ // ----- AMM -----
1456
+ export function createAMM(poolYes, poolNo, fee) {
1457
+ if (!quant) {
1458
+ warnQuantFallback();
1459
+ const k = poolYes * poolNo;
1460
+ return {
1461
+ pool_yes: poolYes,
1462
+ pool_no: poolNo,
1463
+ k,
1464
+ fee,
1465
+ price_yes: poolNo / k,
1466
+ price_no: poolYes / k,
1467
+ };
1468
+ }
1469
+ const response = quant.quant_amm_new(poolYes, poolNo, fee);
1470
+ return parseQuantJson(response);
1471
+ }
1472
+ export function ammCalculateCost(poolYes, poolNo, outcome, shares) {
1473
+ if (!quant) {
1474
+ warnQuantFallback();
1475
+ const buyYes = typeof outcome === "string" ? outcome === "yes" : outcome;
1476
+ const k = poolYes * poolNo;
1477
+ if (buyYes) {
1478
+ return (k / (poolYes + shares)) - poolNo;
1479
+ }
1480
+ return (k / (poolNo + shares)) - poolYes;
1481
+ }
1482
+ const buyYes = typeof outcome === "string" ? outcome === "yes" : outcome;
1483
+ const response = quant.quant_amm_calculate_cost(poolYes, poolNo, buyYes, shares);
1484
+ const result = parseQuantJson(response);
1485
+ return Math.abs(result.cost);
1486
+ }
1487
+ export function ammPriceImpact(poolYes, poolNo, outcome, shares) {
1488
+ if (!quant) {
1489
+ warnQuantFallback();
1490
+ const buyYes = typeof outcome === "string" ? outcome === "yes" : outcome;
1491
+ const k = poolYes * poolNo;
1492
+ const priceBefore = buyYes ? poolNo / k : poolYes / k;
1493
+ const newPoolYes = buyYes ? poolYes + shares : poolYes;
1494
+ const newPoolNo = buyYes ? poolNo : poolNo + shares;
1495
+ const priceAfter = buyYes ? newPoolNo / k : newPoolYes / k;
1496
+ return {
1497
+ price_before: priceBefore,
1498
+ price_after: priceAfter,
1499
+ price_impact: Math.abs(priceAfter - priceBefore) / priceBefore,
1500
+ slippage: Math.abs(priceAfter - priceBefore),
1501
+ };
1502
+ }
1503
+ const buyYes = typeof outcome === "string" ? outcome === "yes" : outcome;
1504
+ const response = quant.quant_amm_price_impact(poolYes, poolNo, buyYes, shares);
1505
+ return parseQuantJson(response);
1506
+ }
1507
+ // ----- LMSR -----
1508
+ export function lmsrPrice(yesShares, noShares, b) {
1509
+ if (!quant) {
1510
+ warnQuantFallback();
1511
+ const expYes = Math.exp(yesShares / b);
1512
+ const expNo = Math.exp(noShares / b);
1513
+ const sum = expYes + expNo;
1514
+ return { yes_price: expYes / sum, no_price: expNo / sum, spread: Math.abs(expYes - expNo) / sum };
1515
+ }
1516
+ const response = quant.quant_lmsr_price(yesShares, noShares, b);
1517
+ return parseQuantJson(response);
1518
+ }
1519
+ export function lmsrCost(yesShares, noShares, b, outcome, shares) {
1520
+ if (!quant) {
1521
+ warnQuantFallback();
1522
+ const buyYes = typeof outcome === "string" ? outcome === "yes" : outcome;
1523
+ const costBefore = b * Math.log(Math.exp(yesShares / b) + Math.exp(noShares / b));
1524
+ const newYes = buyYes ? yesShares + shares : yesShares;
1525
+ const newNo = buyYes ? noShares : noShares + shares;
1526
+ const costAfter = b * Math.log(Math.exp(newYes / b) + Math.exp(newNo / b));
1527
+ return { cost: costAfter - costBefore, avg_price: (costAfter - costBefore) / shares };
1528
+ }
1529
+ const buyYes = typeof outcome === "string" ? outcome === "yes" : outcome;
1530
+ const response = quant.quant_lmsr_cost(yesShares, noShares, b, buyYes, shares);
1531
+ return parseQuantJson(response);
1532
+ }
1533
+ // ----- Arbitrage -----
1534
+ export function detectArbitrage(yesPrice, noPrice) {
1535
+ if (!quant) {
1536
+ warnQuantFallback();
1537
+ const total = yesPrice + noPrice;
1538
+ return {
1539
+ has_arbitrage: total < 1,
1540
+ yes_price: yesPrice,
1541
+ no_price: noPrice,
1542
+ total,
1543
+ profit_per_share: total < 1 ? 1 - total : 0,
1544
+ };
1545
+ }
1546
+ const response = quant.quant_detect_arbitrage(yesPrice, noPrice);
1547
+ return parseQuantJson(response);
1548
+ }
1549
+ // ----- Odds Conversion -----
1550
+ const ODDS_TYPE_MAP = {
1551
+ probability: 0,
1552
+ decimal: 1,
1553
+ american: 2,
1554
+ };
1555
+ export function convertOdds(value, fromType) {
1556
+ if (!quant) {
1557
+ warnQuantFallback();
1558
+ let prob;
1559
+ switch (fromType) {
1560
+ case "probability":
1561
+ prob = value;
1562
+ break;
1563
+ case "decimal":
1564
+ prob = 1 / value;
1565
+ break;
1566
+ case "american":
1567
+ prob = value > 0 ? 100 / (value + 100) : -value / (-value + 100);
1568
+ break;
1569
+ }
1570
+ const americanOdds = prob >= 0.5 ? Math.round(-100 / (prob - 1)) : Math.round((1 - prob) / prob * 100);
1571
+ return { probability: prob, decimal_odds: 1 / prob, american_odds: americanOdds };
1572
+ }
1573
+ const response = quant.quant_convert_odds(value, ODDS_TYPE_MAP[fromType] ?? 0);
1574
+ return parseQuantJson(response);
1575
+ }
1576
+ // ----- Statistics -----
1577
+ export function quantMean(data) {
1578
+ if (data.length === 0)
1579
+ return NaN;
1580
+ if (!quant) {
1581
+ warnQuantFallback();
1582
+ return data.reduce((a, b) => a + b, 0) / data.length;
1583
+ }
1584
+ const { ptr } = toFloat64Ptr(data);
1585
+ return quant.quant_mean(ptr, data.length);
1586
+ }
1587
+ export function quantStdDev(data) {
1588
+ if (data.length === 0)
1589
+ return NaN;
1590
+ if (!quant) {
1591
+ warnQuantFallback();
1592
+ const m = data.reduce((a, b) => a + b, 0) / data.length;
1593
+ return Math.sqrt(data.reduce((sum, x) => sum + (x - m) ** 2, 0) / data.length);
1594
+ }
1595
+ const { ptr } = toFloat64Ptr(data);
1596
+ return quant.quant_std_dev(ptr, data.length);
1597
+ }
1598
+ export function quantVariance(data) {
1599
+ if (data.length === 0)
1600
+ return NaN;
1601
+ if (!quant) {
1602
+ warnQuantFallback();
1603
+ const m = data.reduce((a, b) => a + b, 0) / data.length;
1604
+ return data.reduce((sum, x) => sum + (x - m) ** 2, 0) / data.length;
1605
+ }
1606
+ const { ptr } = toFloat64Ptr(data);
1607
+ return quant.quant_variance(ptr, data.length);
1608
+ }
1609
+ export function quantCorrelation(x, y) {
1610
+ if (x.length === 0 || y.length === 0 || x.length !== y.length)
1611
+ return NaN;
1612
+ if (!quant) {
1613
+ warnQuantFallback();
1614
+ const n = x.length;
1615
+ const mx = x.reduce((a, b) => a + b, 0) / n;
1616
+ const my = y.reduce((a, b) => a + b, 0) / n;
1617
+ const cov = x.reduce((s, xi, i) => s + (xi - mx) * (y[i] - my), 0) / n;
1618
+ const vx = x.reduce((s, xi) => s + (xi - mx) ** 2, 0) / n;
1619
+ const vy = y.reduce((s, yi) => s + (yi - my) ** 2, 0) / n;
1620
+ return cov / Math.sqrt(vx * vy);
1621
+ }
1622
+ const { ptr: ptrX } = toFloat64Ptr(x);
1623
+ const { ptr: ptrY } = toFloat64Ptr(y);
1624
+ return quant.quant_correlation(ptrX, ptrY, x.length);
1625
+ }