@pasosdejesus/m 0.15.0

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 (324) hide show
  1. package/dist/blockchain/deployments.d.ts +40 -0
  2. package/dist/blockchain/deployments.d.ts.map +1 -0
  3. package/dist/blockchain/deployments.js +64 -0
  4. package/dist/debug/DebugConsole.d.ts +22 -0
  5. package/dist/debug/DebugConsole.d.ts.map +1 -0
  6. package/dist/debug/DebugConsole.js +79 -0
  7. package/dist/debug/Logger.d.ts +38 -0
  8. package/dist/debug/Logger.d.ts.map +1 -0
  9. package/dist/debug/Logger.js +94 -0
  10. package/dist/debug/index.d.ts +6 -0
  11. package/dist/debug/index.d.ts.map +1 -0
  12. package/dist/debug/index.js +4 -0
  13. package/dist/debug/useLogger.d.ts +14 -0
  14. package/dist/debug/useLogger.d.ts.map +1 -0
  15. package/dist/debug/useLogger.js +23 -0
  16. package/dist/debug/utils.d.ts +10 -0
  17. package/dist/debug/utils.d.ts.map +1 -0
  18. package/dist/debug/utils.js +53 -0
  19. package/dist/e2e/assertions.d.ts +5 -0
  20. package/dist/e2e/assertions.d.ts.map +1 -0
  21. package/dist/e2e/assertions.js +18 -0
  22. package/dist/e2e/browser.d.ts +37 -0
  23. package/dist/e2e/browser.d.ts.map +1 -0
  24. package/dist/e2e/browser.js +97 -0
  25. package/dist/e2e/env.d.ts +18 -0
  26. package/dist/e2e/env.d.ts.map +1 -0
  27. package/dist/e2e/env.js +57 -0
  28. package/dist/e2e/index.d.ts +11 -0
  29. package/dist/e2e/index.d.ts.map +1 -0
  30. package/dist/e2e/index.js +8 -0
  31. package/dist/e2e/navigation.d.ts +4 -0
  32. package/dist/e2e/navigation.d.ts.map +1 -0
  33. package/dist/e2e/navigation.js +32 -0
  34. package/dist/e2e/siwe-mock.d.ts +11 -0
  35. package/dist/e2e/siwe-mock.d.ts.map +1 -0
  36. package/dist/e2e/siwe-mock.js +112 -0
  37. package/dist/e2e/siwe.d.ts +15 -0
  38. package/dist/e2e/siwe.d.ts.map +1 -0
  39. package/dist/e2e/siwe.js +85 -0
  40. package/dist/e2e/wallet-mock.d.ts +13 -0
  41. package/dist/e2e/wallet-mock.d.ts.map +1 -0
  42. package/dist/e2e/wallet-mock.js +91 -0
  43. package/dist/i18n/common-cli.d.ts +11 -0
  44. package/dist/i18n/common-cli.d.ts.map +1 -0
  45. package/dist/i18n/common-cli.js +22 -0
  46. package/dist/i18n/createTranslator.d.ts +28 -0
  47. package/dist/i18n/createTranslator.d.ts.map +1 -0
  48. package/dist/i18n/createTranslator.js +48 -0
  49. package/dist/i18n/index.d.ts +4 -0
  50. package/dist/i18n/index.d.ts.map +1 -0
  51. package/dist/i18n/index.js +2 -0
  52. package/dist/i18n/locales/cli.d.ts +3 -0
  53. package/dist/i18n/locales/cli.d.ts.map +1 -0
  54. package/dist/i18n/locales/cli.js +180 -0
  55. package/dist/i18n/types.d.ts +3 -0
  56. package/dist/i18n/types.d.ts.map +1 -0
  57. package/dist/i18n/types.js +1 -0
  58. package/dist/index.d.ts +2 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +15 -0
  61. package/dist/index.test.d.ts +2 -0
  62. package/dist/index.test.d.ts.map +1 -0
  63. package/dist/index.test.js +10 -0
  64. package/dist/m.d.ts +2 -0
  65. package/dist/m.d.ts.map +1 -0
  66. package/dist/m.js +334 -0
  67. package/dist/plugin.d.ts +10 -0
  68. package/dist/plugin.d.ts.map +1 -0
  69. package/dist/plugin.js +7 -0
  70. package/dist/shadcn_components/cn.d.ts +13 -0
  71. package/dist/shadcn_components/cn.d.ts.map +1 -0
  72. package/dist/shadcn_components/cn.js +15 -0
  73. package/dist/shadcn_components/ui/accordion.d.ts +8 -0
  74. package/dist/shadcn_components/ui/accordion.d.ts.map +1 -0
  75. package/dist/shadcn_components/ui/accordion.js +14 -0
  76. package/dist/shadcn_components/ui/alert-dialog.d.ts +21 -0
  77. package/dist/shadcn_components/ui/alert-dialog.d.ts.map +1 -0
  78. package/dist/shadcn_components/ui/alert-dialog.js +27 -0
  79. package/dist/shadcn_components/ui/alert.d.ts +9 -0
  80. package/dist/shadcn_components/ui/alert.d.ts.map +1 -0
  81. package/dist/shadcn_components/ui/alert.js +22 -0
  82. package/dist/shadcn_components/ui/avatar.d.ts +7 -0
  83. package/dist/shadcn_components/ui/avatar.d.ts.map +1 -0
  84. package/dist/shadcn_components/ui/avatar.js +12 -0
  85. package/dist/shadcn_components/ui/badge.d.ts +10 -0
  86. package/dist/shadcn_components/ui/badge.d.ts.map +1 -0
  87. package/dist/shadcn_components/ui/badge.js +22 -0
  88. package/dist/shadcn_components/ui/button.d.ts +11 -0
  89. package/dist/shadcn_components/ui/button.d.ts.map +1 -0
  90. package/dist/shadcn_components/ui/button.js +31 -0
  91. package/dist/shadcn_components/ui/card.d.ts +10 -0
  92. package/dist/shadcn_components/ui/card.d.ts.map +1 -0
  93. package/dist/shadcn_components/ui/card.js +24 -0
  94. package/dist/shadcn_components/ui/checkbox.d.ts +5 -0
  95. package/dist/shadcn_components/ui/checkbox.d.ts.map +1 -0
  96. package/dist/shadcn_components/ui/checkbox.js +9 -0
  97. package/dist/shadcn_components/ui/dialog.d.ts +20 -0
  98. package/dist/shadcn_components/ui/dialog.d.ts.map +1 -0
  99. package/dist/shadcn_components/ui/dialog.js +23 -0
  100. package/dist/shadcn_components/ui/dropdown-menu.d.ts +28 -0
  101. package/dist/shadcn_components/ui/dropdown-menu.d.ts.map +1 -0
  102. package/dist/shadcn_components/ui/dropdown-menu.js +36 -0
  103. package/dist/shadcn_components/ui/form.d.ts +24 -0
  104. package/dist/shadcn_components/ui/form.d.ts.map +1 -0
  105. package/dist/shadcn_components/ui/form.js +63 -0
  106. package/dist/shadcn_components/ui/input.d.ts +4 -0
  107. package/dist/shadcn_components/ui/input.d.ts.map +1 -0
  108. package/dist/shadcn_components/ui/input.js +6 -0
  109. package/dist/shadcn_components/ui/label.d.ts +6 -0
  110. package/dist/shadcn_components/ui/label.d.ts.map +1 -0
  111. package/dist/shadcn_components/ui/label.js +10 -0
  112. package/dist/shadcn_components/ui/menubar.d.ts +29 -0
  113. package/dist/shadcn_components/ui/menubar.d.ts.map +1 -0
  114. package/dist/shadcn_components/ui/menubar.js +46 -0
  115. package/dist/shadcn_components/ui/popover.d.ts +7 -0
  116. package/dist/shadcn_components/ui/popover.d.ts.map +1 -0
  117. package/dist/shadcn_components/ui/popover.js +10 -0
  118. package/dist/shadcn_components/ui/progress.d.ts +5 -0
  119. package/dist/shadcn_components/ui/progress.d.ts.map +1 -0
  120. package/dist/shadcn_components/ui/progress.js +8 -0
  121. package/dist/shadcn_components/ui/radio-group.d.ts +6 -0
  122. package/dist/shadcn_components/ui/radio-group.d.ts.map +1 -0
  123. package/dist/shadcn_components/ui/radio-group.js +15 -0
  124. package/dist/shadcn_components/ui/scroll-area.d.ts +6 -0
  125. package/dist/shadcn_components/ui/scroll-area.d.ts.map +1 -0
  126. package/dist/shadcn_components/ui/scroll-area.js +12 -0
  127. package/dist/shadcn_components/ui/select.d.ts +14 -0
  128. package/dist/shadcn_components/ui/select.d.ts.map +1 -0
  129. package/dist/shadcn_components/ui/select.js +27 -0
  130. package/dist/shadcn_components/ui/separator.d.ts +5 -0
  131. package/dist/shadcn_components/ui/separator.d.ts.map +1 -0
  132. package/dist/shadcn_components/ui/separator.js +8 -0
  133. package/dist/shadcn_components/ui/sheet.d.ts +26 -0
  134. package/dist/shadcn_components/ui/sheet.d.ts.map +1 -0
  135. package/dist/shadcn_components/ui/sheet.js +37 -0
  136. package/dist/shadcn_components/ui/skeleton.d.ts +3 -0
  137. package/dist/shadcn_components/ui/skeleton.d.ts.map +1 -0
  138. package/dist/shadcn_components/ui/skeleton.js +6 -0
  139. package/dist/shadcn_components/ui/slider.d.ts +5 -0
  140. package/dist/shadcn_components/ui/slider.d.ts.map +1 -0
  141. package/dist/shadcn_components/ui/slider.js +8 -0
  142. package/dist/shadcn_components/ui/switch.d.ts +5 -0
  143. package/dist/shadcn_components/ui/switch.d.ts.map +1 -0
  144. package/dist/shadcn_components/ui/switch.js +8 -0
  145. package/dist/shadcn_components/ui/table.d.ts +11 -0
  146. package/dist/shadcn_components/ui/table.d.ts.map +1 -0
  147. package/dist/shadcn_components/ui/table.js +20 -0
  148. package/dist/shadcn_components/ui/tabs.d.ts +8 -0
  149. package/dist/shadcn_components/ui/tabs.d.ts.map +1 -0
  150. package/dist/shadcn_components/ui/tabs.js +13 -0
  151. package/dist/shadcn_components/ui/textarea.d.ts +4 -0
  152. package/dist/shadcn_components/ui/textarea.d.ts.map +1 -0
  153. package/dist/shadcn_components/ui/textarea.js +8 -0
  154. package/dist/shadcn_components/ui/toast.d.ts +16 -0
  155. package/dist/shadcn_components/ui/toast.d.ts.map +1 -0
  156. package/dist/shadcn_components/ui/toast.js +34 -0
  157. package/dist/shadcn_components/ui/toaster.d.ts +2 -0
  158. package/dist/shadcn_components/ui/toaster.d.ts.map +1 -0
  159. package/dist/shadcn_components/ui/toaster.js +10 -0
  160. package/dist/shadcn_components/ui/tooltip.d.ts +8 -0
  161. package/dist/shadcn_components/ui/tooltip.d.ts.map +1 -0
  162. package/dist/shadcn_components/ui/tooltip.js +11 -0
  163. package/dist/shadcn_components/ui/use-toast.d.ts +45 -0
  164. package/dist/shadcn_components/ui/use-toast.d.ts.map +1 -0
  165. package/dist/shadcn_components/ui/use-toast.js +126 -0
  166. package/dist/tasks/context.d.ts +13 -0
  167. package/dist/tasks/context.d.ts.map +1 -0
  168. package/dist/tasks/context.js +310 -0
  169. package/dist/tasks/create.d.ts +2 -0
  170. package/dist/tasks/create.d.ts.map +1 -0
  171. package/dist/tasks/create.js +91 -0
  172. package/dist/tasks/db.d.ts +19 -0
  173. package/dist/tasks/db.d.ts.map +1 -0
  174. package/dist/tasks/db.js +791 -0
  175. package/dist/tasks/e2e.d.ts +2 -0
  176. package/dist/tasks/e2e.d.ts.map +1 -0
  177. package/dist/tasks/e2e.js +124 -0
  178. package/dist/tasks/edit.d.ts +7 -0
  179. package/dist/tasks/edit.d.ts.map +1 -0
  180. package/dist/tasks/edit.js +471 -0
  181. package/dist/tasks/engine.d.ts +2 -0
  182. package/dist/tasks/engine.d.ts.map +1 -0
  183. package/dist/tasks/engine.js +149 -0
  184. package/dist/tasks/env-diff.d.ts +2 -0
  185. package/dist/tasks/env-diff.d.ts.map +1 -0
  186. package/dist/tasks/env-diff.js +140 -0
  187. package/dist/tasks/fuzzy.d.ts +9 -0
  188. package/dist/tasks/fuzzy.d.ts.map +1 -0
  189. package/dist/tasks/fuzzy.js +153 -0
  190. package/dist/tasks/glob.d.ts +5 -0
  191. package/dist/tasks/glob.d.ts.map +1 -0
  192. package/dist/tasks/glob.js +57 -0
  193. package/dist/tasks/grep.d.ts +9 -0
  194. package/dist/tasks/grep.d.ts.map +1 -0
  195. package/dist/tasks/grep.js +93 -0
  196. package/dist/tasks/readfile.d.ts +2 -0
  197. package/dist/tasks/readfile.d.ts.map +1 -0
  198. package/dist/tasks/readfile.js +177 -0
  199. package/dist/tasks/update.d.ts +5 -0
  200. package/dist/tasks/update.d.ts.map +1 -0
  201. package/dist/tasks/update.js +200 -0
  202. package/dist/tasks/util.d.ts +12 -0
  203. package/dist/tasks/util.d.ts.map +1 -0
  204. package/dist/tasks/util.js +42 -0
  205. package/dist/tasks/wallet.d.ts +2 -0
  206. package/dist/tasks/wallet.d.ts.map +1 -0
  207. package/dist/tasks/wallet.js +697 -0
  208. package/dist/tasks/writefile.d.ts +2 -0
  209. package/dist/tasks/writefile.d.ts.map +1 -0
  210. package/dist/tasks/writefile.js +66 -0
  211. package/dist/templates/AGENTS.md.hbs +81 -0
  212. package/dist/templates/ARCHITECTURE.md.hbs +146 -0
  213. package/dist/templates/CONTRIBUTING.md.hbs +83 -0
  214. package/dist/templates/LICENCIA.md +21 -0
  215. package/dist/templates/LICENSE.md +15 -0
  216. package/dist/templates/Makefile +16 -0
  217. package/dist/templates/README.md.hbs +111 -0
  218. package/dist/templates/apps/.env.example.hbs +75 -0
  219. package/dist/templates/apps/hardhat/.prettierrc +16 -0
  220. package/dist/templates/apps/hardhat/MOCK_USDT_README.md +20 -0
  221. package/dist/templates/apps/hardhat/Makefile +13 -0
  222. package/dist/templates/apps/hardhat/README.md +129 -0
  223. package/dist/templates/apps/hardhat/bin/MusdtVerification +4 -0
  224. package/dist/templates/apps/hardhat/bin/approveDepositOwner +7 -0
  225. package/dist/templates/apps/hardhat/bin/contractVerification +9 -0
  226. package/dist/templates/apps/hardhat/bin/deployMockUSDT +7 -0
  227. package/dist/templates/apps/hardhat/bin/prepadJ.sh +14 -0
  228. package/dist/templates/apps/hardhat/bin/verifyMockUSDT +7 -0
  229. package/dist/templates/apps/hardhat/contracts/MockUSDT.sol +47 -0
  230. package/dist/templates/apps/hardhat/hardhat.config.ts +102 -0
  231. package/dist/templates/apps/hardhat/package.json +55 -0
  232. package/dist/templates/apps/hardhat/scripts/approveDepositOwner.ts +22 -0
  233. package/dist/templates/apps/hardhat/scripts/deployMockUSDT.ts +49 -0
  234. package/dist/templates/apps/hardhat/scripts/verifyDeployment.ts +93 -0
  235. package/dist/templates/apps/hardhat/scripts/verifyMockUSDT.ts +52 -0
  236. package/dist/templates/apps/hardhat/sync-abis.mjs +58 -0
  237. package/dist/templates/apps/hardhat/test/MockUSDT.test.ts +40 -0
  238. package/dist/templates/apps/hardhat/tsconfig.json +27 -0
  239. package/dist/templates/apps/nextjs/.config/kysely.config.ts +36 -0
  240. package/dist/templates/apps/nextjs/Makefile +24 -0
  241. package/dist/templates/apps/nextjs/README.md.hbs +76 -0
  242. package/dist/templates/apps/nextjs/abis/IERC20.json +74 -0
  243. package/dist/templates/apps/nextjs/abis/MockUSDT.json +242 -0
  244. package/dist/templates/apps/nextjs/abis/ReentrancyGuard.json +1 -0
  245. package/dist/templates/apps/nextjs/app/globals.css +3 -0
  246. package/dist/templates/apps/nextjs/app/layout.tsx.hbs +26 -0
  247. package/dist/templates/apps/nextjs/app/page.tsx.hbs +225 -0
  248. package/dist/templates/apps/nextjs/app/testui/page.tsx +371 -0
  249. package/dist/templates/apps/nextjs/bin/m +8 -0
  250. package/dist/templates/apps/nextjs/components.json +21 -0
  251. package/dist/templates/apps/nextjs/next-env.d.ts +5 -0
  252. package/dist/templates/apps/nextjs/next.config.ts +10 -0
  253. package/dist/templates/apps/nextjs/package.json.hbs +48 -0
  254. package/dist/templates/apps/nextjs/pnpm-workspace.yaml +13 -0
  255. package/dist/templates/apps/nextjs/postcss.config.mjs +6 -0
  256. package/dist/templates/apps/nextjs/tailwind.config.js +11 -0
  257. package/dist/templates/apps/nextjs/tests/helpers.ts +31 -0
  258. package/dist/templates/apps/nextjs/tests/index.test.ts +7 -0
  259. package/dist/templates/apps/nextjs/tests/setup-env.ts.hbs +8 -0
  260. package/dist/templates/apps/nextjs/tests/test-utils.example.test.ts +168 -0
  261. package/dist/templates/apps/nextjs/tsconfig.json +44 -0
  262. package/dist/templates/apps/nextjs/tsconfig.test.json +38 -0
  263. package/dist/templates/apps/nextjs/vitest.config.ts +13 -0
  264. package/dist/test-utils/fs-mocks.d.ts +32 -0
  265. package/dist/test-utils/fs-mocks.d.ts.map +1 -0
  266. package/dist/test-utils/fs-mocks.js +63 -0
  267. package/dist/test-utils/i18n-mock.d.ts +21 -0
  268. package/dist/test-utils/i18n-mock.d.ts.map +1 -0
  269. package/dist/test-utils/i18n-mock.js +29 -0
  270. package/dist/test-utils/index.d.ts +12 -0
  271. package/dist/test-utils/index.d.ts.map +1 -0
  272. package/dist/test-utils/index.js +11 -0
  273. package/dist/test-utils/kysely-mocks.d.ts +298 -0
  274. package/dist/test-utils/kysely-mocks.d.ts.map +1 -0
  275. package/dist/test-utils/kysely-mocks.js +173 -0
  276. package/dist/test-utils/radix-mocks.d.ts +134 -0
  277. package/dist/test-utils/radix-mocks.d.ts.map +1 -0
  278. package/dist/test-utils/radix-mocks.js +175 -0
  279. package/dist/test-utils/rainbowkit-mocks.d.ts +80 -0
  280. package/dist/test-utils/rainbowkit-mocks.d.ts.map +1 -0
  281. package/dist/test-utils/rainbowkit-mocks.js +247 -0
  282. package/dist/test-utils/viem-mocks.d.ts +86 -0
  283. package/dist/test-utils/viem-mocks.d.ts.map +1 -0
  284. package/dist/test-utils/viem-mocks.js +54 -0
  285. package/dist/util/cli-parser.d.ts +20 -0
  286. package/dist/util/cli-parser.d.ts.map +1 -0
  287. package/dist/util/cli-parser.js +38 -0
  288. package/dist/util/colors.d.ts +5 -0
  289. package/dist/util/colors.d.ts.map +1 -0
  290. package/dist/util/colors.js +5 -0
  291. package/dist/util/locale.d.ts +3 -0
  292. package/dist/util/locale.d.ts.map +1 -0
  293. package/dist/util/locale.js +10 -0
  294. package/dist/wba/client.d.ts +19 -0
  295. package/dist/wba/client.d.ts.map +1 -0
  296. package/dist/wba/client.js +31 -0
  297. package/dist/wba/index.d.ts +4 -0
  298. package/dist/wba/index.d.ts.map +1 -0
  299. package/dist/wba/index.js +2 -0
  300. package/dist/wba/routes/event.d.ts +32 -0
  301. package/dist/wba/routes/event.d.ts.map +1 -0
  302. package/dist/wba/routes/event.js +42 -0
  303. package/dist/wba/routes/index.d.ts +3 -0
  304. package/dist/wba/routes/index.d.ts.map +1 -0
  305. package/dist/wba/routes/index.js +2 -0
  306. package/dist/wba/routes/summary.d.ts +44 -0
  307. package/dist/wba/routes/summary.d.ts.map +1 -0
  308. package/dist/wba/routes/summary.js +146 -0
  309. package/dist/wba/server.d.ts +18 -0
  310. package/dist/wba/server.d.ts.map +1 -0
  311. package/dist/wba/server.js +29 -0
  312. package/dist/wba/types.d.ts +68 -0
  313. package/dist/wba/types.d.ts.map +1 -0
  314. package/dist/wba/types.js +6 -0
  315. package/package.json +223 -0
  316. package/src/blockchain/README.md +80 -0
  317. package/src/debug/README.md +94 -0
  318. package/src/e2e/README.md +105 -0
  319. package/src/i18n/README.md +143 -0
  320. package/src/shadcn_components/README.md +125 -0
  321. package/src/tasks/README.md +69 -0
  322. package/src/test-utils/README.md +638 -0
  323. package/src/util/README.md +18 -0
  324. package/src/wba/README.md +175 -0
@@ -0,0 +1,2 @@
1
+ export declare function runE2e(testPattern?: string, args?: string[]): Promise<void>;
2
+ //# sourceMappingURL=e2e.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"e2e.d.ts","sourceRoot":"","sources":["../../src/tasks/e2e.ts"],"names":[],"mappings":"AA2CA,wBAAsB,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,iBA6FrE"}
@@ -0,0 +1,124 @@
1
+ // test:e2e — Run E2E tests with Puppeteer + SIWE on OpenBSD/adJ
2
+ import { spawnSync } from 'child_process';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import { globSync } from 'glob';
6
+ import { findChrome } from '../e2e/browser.js';
7
+ import { problem, success, info, warn } from '../util/colors.js';
8
+ import { createTranslator } from '../i18n/createTranslator.js';
9
+ import { detectLocale } from '../util/locale.js';
10
+ import commonCli from '../i18n/common-cli.js';
11
+ const t = createTranslator(detectLocale(), {
12
+ en: {
13
+ 'e2e.no_dir': 'No e2e/ directory found. Expected: e2e/specs/ or e2e/smoke/',
14
+ 'e2e.no_chrome': 'Chrome not found — running smoke tests only. Set CHROME_PATH for browser tests.',
15
+ 'e2e.fallback': 'No browser specs found in e2e/specs/ — falling back to smoke tests. Use --smoke to skip this warning.',
16
+ 'e2e.no_specs': 'No spec files found in {{0}} matching: {{1}}',
17
+ 'e2e.found': 'Found {{0}} spec(s)',
18
+ 'e2e.running': '▶ {{0}}',
19
+ 'e2e.failed': ' ✗ {{0}} failed (exit {{1}})',
20
+ 'e2e.all_passed': 'All {{0}} spec(s) passed.',
21
+ 'e2e.partial': '{{0}}/{{1}} spec(s) failed.',
22
+ },
23
+ es: {
24
+ 'e2e.no_dir': 'No se encontró directorio e2e/. Esperado: e2e/specs/ o e2e/smoke/',
25
+ 'e2e.no_chrome': 'Chrome no encontrado — ejecutando solo smoke tests. Define CHROME_PATH para pruebas con navegador.',
26
+ 'e2e.fallback': 'No se encontraron specs en e2e/specs/ — usando smoke tests. Usa --smoke para evitar esta advertencia.',
27
+ 'e2e.no_specs': 'No se encontraron archivos spec en {{0}} coincidiendo con: {{1}}',
28
+ 'e2e.found': '{{0}} spec(s) encontrado(s)',
29
+ 'e2e.running': '▶ {{0}}',
30
+ 'e2e.failed': ' ✗ {{0}} falló (exit {{1}})',
31
+ 'e2e.all_passed': 'Todos los {{0}} spec(s) pasaron.',
32
+ 'e2e.partial': '{{0}}/{{1}} spec(s) fallaron.',
33
+ },
34
+ }, commonCli);
35
+ function findSpecs(subDir, pattern, e2eDir) {
36
+ const specDir = path.join(e2eDir, subDir);
37
+ if (!fs.existsSync(specDir))
38
+ return [];
39
+ const files = globSync(pattern, { cwd: specDir });
40
+ return files.map(f => ({ file: f, dir: specDir }));
41
+ }
42
+ export async function runE2e(testPattern, args = []) {
43
+ const cwd = process.cwd();
44
+ // If testPattern looks like a flag, move it to args
45
+ if (testPattern && testPattern.startsWith('--')) {
46
+ args.unshift(testPattern);
47
+ testPattern = undefined;
48
+ }
49
+ const smokeOnly = args.includes('--smoke');
50
+ const grepFilter = args.includes('--grep') ? args[args.indexOf('--grep') + 1] : null;
51
+ // 1. Detect e2e directory
52
+ const e2eDir = path.join(cwd, 'e2e');
53
+ if (!fs.existsSync(e2eDir)) {
54
+ problem(t("e2e.no_dir"));
55
+ process.exit(1);
56
+ }
57
+ // 2. Chrome check (skip for smoke-only)
58
+ let chromePath = null;
59
+ if (!smokeOnly) {
60
+ try {
61
+ chromePath = findChrome();
62
+ }
63
+ catch {
64
+ warn(t("e2e.no_chrome"));
65
+ }
66
+ }
67
+ // 3. Find specs — search in both specs/ and smoke/ when no flag specified
68
+ let specFiles = [];
69
+ // If pattern doesn't contain glob chars and isn't a full filename, wrap with *...*
70
+ let pattern = testPattern || '**/*.spec.mjs';
71
+ if (testPattern && !testPattern.includes('*') && !testPattern.endsWith('.spec.mjs')) {
72
+ pattern = `*${testPattern}*.spec.mjs`;
73
+ }
74
+ if (smokeOnly) {
75
+ specFiles = findSpecs('smoke', pattern, e2eDir);
76
+ }
77
+ else {
78
+ // Try specs/ first, then smoke/
79
+ specFiles = findSpecs('specs', pattern, e2eDir);
80
+ if (specFiles.length === 0) {
81
+ specFiles = findSpecs('smoke', pattern, e2eDir);
82
+ if (specFiles.length > 0) {
83
+ warn(t("e2e.fallback"));
84
+ }
85
+ }
86
+ }
87
+ // Apply grep filter
88
+ if (grepFilter && specFiles.length > 0) {
89
+ specFiles = specFiles.filter(s => s.file.includes(grepFilter));
90
+ }
91
+ if (specFiles.length === 0) {
92
+ const dirs = smokeOnly ? 'e2e/smoke/' : 'e2e/specs/ and e2e/smoke/';
93
+ info(t("e2e.no_specs", dirs, pattern));
94
+ process.exit(0);
95
+ }
96
+ info(t("e2e.found", String(specFiles.length)));
97
+ // 4. Run each spec
98
+ let failures = 0;
99
+ for (const { file, dir } of specFiles) {
100
+ const specPath = path.join(dir, file);
101
+ info(`\n▶ ${path.relative(e2eDir, specPath)}`);
102
+ const env = { ...process.env };
103
+ if (chromePath)
104
+ env.CHROME_PATH = chromePath;
105
+ const res = spawnSync('node', [specPath], {
106
+ stdio: 'inherit',
107
+ env,
108
+ cwd,
109
+ });
110
+ if (res.status !== 0) {
111
+ failures++;
112
+ problem(t("e2e.failed", file, String(res.status)));
113
+ }
114
+ }
115
+ // 5. Summary
116
+ if (failures === 0) {
117
+ success("\n" + t("e2e.all_passed", String(specFiles.length)));
118
+ }
119
+ else {
120
+ problem("\n" + t("e2e.partial", String(failures), String(specFiles.length)));
121
+ }
122
+ // process.exit() is mandatory in m CLI commands
123
+ process.exit(failures > 0 ? 1 : 0);
124
+ }
@@ -0,0 +1,7 @@
1
+ export declare function getClipboard(): Promise<string>;
2
+ export declare function setClipboard(content: string): Promise<void>;
3
+ export declare function runAiEdit(options?: {
4
+ dryRun?: boolean;
5
+ input?: string;
6
+ }): Promise<void>;
7
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tasks/edit.ts"],"names":[],"mappings":"AAgFA,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAsBpD;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjE;AAmTD,wBAAsB,SAAS,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,iBA0FjF"}
@@ -0,0 +1,471 @@
1
+ import { readFile, writeFile, access } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+ import { execSync } from 'node:child_process';
5
+ import { info, success, problem, warn } from '../util/colors.js';
6
+ import { findBestMatch } from './fuzzy.js';
7
+ import { createTranslator } from '../i18n/createTranslator.js';
8
+ import { detectLocale } from '../util/locale.js';
9
+ import commonCli from '../i18n/common-cli.js';
10
+ const t = createTranslator(detectLocale(), {
11
+ en: {
12
+ 'edit.dry_create': ' [DRY RUN] Would create: {{0}}',
13
+ 'edit.created': ' ✅ Created: {{0}}',
14
+ 'edit.dry_replace': ' [DRY RUN] Would replace: {{0}}',
15
+ 'edit.replaced': ' ✅ Replaced: {{0}}',
16
+ 'edit.dry_update': ' [DRY RUN] Would update: {{0}}',
17
+ 'edit.updated': ' ✅ Updated: {{0}}',
18
+ 'edit.fuzzy_match': ' ⚠️ Approximate match ({{0}}%) in {{1}}',
19
+ 'edit.dry_fuzzy': ' [DRY RUN] Would update with fuzzy: {{0}}',
20
+ 'edit.fuzzy_updated': ' ✅ Updated (fuzzy {{0}}%): {{1}}',
21
+ 'edit.insufficient': ' ❌ Insufficient match ({{0}}%). Diagnostic copied to clipboard.',
22
+ 'edit.read_error': ' ❌ Error reading {{0}}: {{1}}',
23
+ 'edit.dry_delete': ' [DRY RUN] Would delete: {{0}}',
24
+ 'edit.no_delete': ' ⚠️ Delete not implemented: {{0}}',
25
+ 'edit.reading_file': '📁 Reading file: {{0}}',
26
+ 'edit.reading_clipboard': '📋 Reading clipboard...',
27
+ 'edit.empty_clipboard': '❌ Clipboard empty.',
28
+ 'edit.analyzing': '🔍 Analyzing changes...',
29
+ 'edit.no_changes': '❌ No changes found in expected format.',
30
+ 'edit.found_changes': '📝 Found {{0}} change(s):',
31
+ 'edit.dry_mode': '🏃‍♂️ DRY RUN MODE - Changes will not be applied:',
32
+ 'edit.summary_dry': '📊 Summary (dry-run): {{0}} applicable changes, {{1}} problems',
33
+ 'edit.summary_ok': '✅ Applied {{0}} change(s) successfully.',
34
+ 'edit.summary_partial': '⚠️ {{0}} change(s) applied, {{1}} failed.',
35
+ 'edit.saved': '📋 Content saved to: {{0}}',
36
+ 'edit.view': ' View with: cat {{0}}',
37
+ },
38
+ es: {
39
+ 'edit.dry_create': ' [DRY RUN] Crearía: {{0}}',
40
+ 'edit.created': ' ✅ Creado: {{0}}',
41
+ 'edit.dry_replace': ' [DRY RUN] Reemplazaría: {{0}}',
42
+ 'edit.replaced': ' ✅ Reemplazado: {{0}}',
43
+ 'edit.dry_update': ' [DRY RUN] Actualizaría: {{0}}',
44
+ 'edit.updated': ' ✅ Actualizado: {{0}}',
45
+ 'edit.fuzzy_match': ' ⚠️ Coincidencia aproximada ({{0}}%) en {{1}}',
46
+ 'edit.dry_fuzzy': ' [DRY RUN] Actualizaría con fuzzy: {{0}}',
47
+ 'edit.fuzzy_updated': ' ✅ Actualizado (fuzzy {{0}}%): {{1}}',
48
+ 'edit.insufficient': ' ❌ Coincidencia insuficiente ({{0}}%). Diagnóstico copiado al portapapeles.',
49
+ 'edit.read_error': ' ❌ Error leyendo {{0}}: {{1}}',
50
+ 'edit.dry_delete': ' [DRY RUN] Eliminaría: {{0}}',
51
+ 'edit.no_delete': ' ⚠️ Eliminación no implementada: {{0}}',
52
+ 'edit.reading_file': '📁 Leyendo archivo: {{0}}',
53
+ 'edit.reading_clipboard': '📋 Leyendo portapapeles...',
54
+ 'edit.empty_clipboard': '❌ Portapapeles vacío.',
55
+ 'edit.analyzing': '🔍 Analizando cambios...',
56
+ 'edit.no_changes': '❌ No se encontraron cambios en el formato esperado.',
57
+ 'edit.found_changes': '📝 Se encontraron {{0}} cambio(s):',
58
+ 'edit.dry_mode': '🏃‍♂️ MODO PRUEBA (dry-run) - No se aplicarán cambios:',
59
+ 'edit.summary_dry': '📊 Resumen (dry-run): {{0}} cambios aplicables, {{1}} problemas',
60
+ 'edit.summary_ok': '✅ Aplicados {{0}} cambio(s) correctamente.',
61
+ 'edit.summary_partial': '⚠️ {{0}} cambio(s) aplicados, {{1}} fallaron.',
62
+ 'edit.saved': '📋 Contenido guardado en: {{0}}',
63
+ 'edit.view': ' Puedes verlo con: cat {{0}}',
64
+ },
65
+ }, commonCli);
66
+ const TEMP_CLIPBOARD_FILE = join(tmpdir(), 'm_clipboard.txt');
67
+ function isX11Available() {
68
+ if (!process.env.DISPLAY)
69
+ return false;
70
+ try {
71
+ execSync('xclip -version', { stdio: 'ignore' });
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ export async function getClipboard() {
79
+ if (isX11Available()) {
80
+ try {
81
+ const result = execSync('xclip -selection clipboard -o', {
82
+ encoding: 'utf-8',
83
+ stdio: ['ignore', 'pipe', 'ignore']
84
+ });
85
+ if (result.trim())
86
+ return result;
87
+ }
88
+ catch (err) {
89
+ // Fallar silenciosamente
90
+ }
91
+ }
92
+ try {
93
+ await access(TEMP_CLIPBOARD_FILE);
94
+ const content = await readFile(TEMP_CLIPBOARD_FILE, 'utf-8');
95
+ if (content.trim())
96
+ return content;
97
+ }
98
+ catch {
99
+ // No existe o está vacío
100
+ }
101
+ return '';
102
+ }
103
+ export async function setClipboard(content) {
104
+ if (isX11Available()) {
105
+ try {
106
+ execSync('xclip -selection clipboard', {
107
+ input: content,
108
+ encoding: 'utf-8',
109
+ stdio: ['pipe', 'ignore', 'ignore']
110
+ });
111
+ return;
112
+ }
113
+ catch (err) {
114
+ // Fallar silenciosamente
115
+ }
116
+ }
117
+ await writeFile(TEMP_CLIPBOARD_FILE, content, 'utf-8');
118
+ info(t('edit.saved', TEMP_CLIPBOARD_FILE));
119
+ info(t('edit.view', TEMP_CLIPBOARD_FILE));
120
+ }
121
+ function parseDiffUnified(diffContent) {
122
+ const lines = diffContent.split('\n');
123
+ const original = [];
124
+ const modified = [];
125
+ let inHunk = false;
126
+ for (const line of lines) {
127
+ if (line.startsWith('@@')) {
128
+ inHunk = true;
129
+ continue;
130
+ }
131
+ if (!inHunk)
132
+ continue;
133
+ if (line.startsWith('-') && !line.startsWith('---')) {
134
+ original.push(line.substring(1));
135
+ }
136
+ else if (line.startsWith('+') && !line.startsWith('+++')) {
137
+ modified.push(line.substring(1));
138
+ }
139
+ else if (line.startsWith(' ')) {
140
+ original.push(line.substring(1));
141
+ modified.push(line.substring(1));
142
+ }
143
+ else if (line.startsWith('\\')) {
144
+ continue;
145
+ }
146
+ }
147
+ return { original, modified };
148
+ }
149
+ function parseSearchReplace(content) {
150
+ const changes = [];
151
+ const regex = /## Edit:\s*`([^`]+)`\s*\n```(?:\w*)\n___BUSCAR_(\d+[T_]\d+)___\n([\s\S]+?)\n___REMPLAZAR_\d+[T_]\d+___\n([\s\S]+?)\n___FIN_(\d+[T_]\d+)___\n```/;
152
+ const match = regex.exec(content);
153
+ if (match) {
154
+ const buscarTimestamp = match[2];
155
+ const finTimestamp = match[5];
156
+ if (buscarTimestamp !== finTimestamp) {
157
+ return null;
158
+ }
159
+ changes.push({
160
+ file: match[1],
161
+ oldString: match[3].trim(),
162
+ newString: match[4].trim()
163
+ });
164
+ }
165
+ else {
166
+ }
167
+ return changes.length > 0 ? changes : null;
168
+ }
169
+ function parseFullFile(content) {
170
+ const regex = /^## Archivo:\s*`([^`]+)`\s*\n\s*```(\w*)\n([\s\S]+?)```/;
171
+ const match = content.match(regex);
172
+ if (match) {
173
+ return {
174
+ file: match[1],
175
+ language: match[2] || '',
176
+ code: match[3].trim()
177
+ };
178
+ }
179
+ return null;
180
+ }
181
+ function parseGitDiffHeader(content) {
182
+ const regex = /```diff\n(?:--git a\/(.+?) b\/.+?\n)?([\s\S]+?)```/;
183
+ const match = content.match(regex);
184
+ if (match) {
185
+ return {
186
+ file: match[1] || '',
187
+ diff: match[2]
188
+ };
189
+ }
190
+ return null;
191
+ }
192
+ function parseInlineDiff(content) {
193
+ const changes = [];
194
+ const searchReplaceChanges = parseSearchReplace(content);
195
+ if (searchReplaceChanges) {
196
+ return searchReplaceChanges.map(c => ({ file: c.file, original: c.oldString, modified: c.newString }));
197
+ }
198
+ const sections = content.split(/(?=^## Archivo:|^## Edit:|^```diff)/m);
199
+ for (let i = 0; i < sections.length; i++) {
200
+ const section = sections[i];
201
+ const fullFile = parseFullFile(section);
202
+ if (fullFile) {
203
+ changes.push({
204
+ file: fullFile.file,
205
+ original: '',
206
+ modified: fullFile.code
207
+ });
208
+ continue;
209
+ }
210
+ const gitDiff = parseGitDiffHeader(section);
211
+ if (gitDiff && gitDiff.file) {
212
+ const { original, modified } = parseDiffUnified(gitDiff.diff);
213
+ changes.push({
214
+ file: gitDiff.file,
215
+ original: original.join('\n'),
216
+ modified: modified.join('\n')
217
+ });
218
+ continue;
219
+ }
220
+ const diffMatch = section.match(/```diff\n([\s\S]+?)```/);
221
+ if (diffMatch) {
222
+ const diffLines = diffMatch[1].split('\n');
223
+ let fileName = '';
224
+ let diffContent = '';
225
+ for (const line of diffLines) {
226
+ if (line.startsWith('--- a/')) {
227
+ fileName = line.substring(6);
228
+ }
229
+ else if (line.startsWith('+++ b/')) {
230
+ fileName = line.substring(6);
231
+ }
232
+ else if (line.startsWith('--- ')) {
233
+ // Formato: --- a/ruta.ts
234
+ const match = line.match(/--- a\/(.+)/);
235
+ if (match)
236
+ fileName = match[1];
237
+ }
238
+ else if (line.startsWith('+++ ')) {
239
+ const match = line.match(/\+\+\+ b\/(.+)/);
240
+ if (match)
241
+ fileName = match[1];
242
+ }
243
+ else {
244
+ diffContent += line + '\n';
245
+ }
246
+ }
247
+ if (fileName || sections[i - 1]) {
248
+ // Si no encontramos fileName en el diff, usar el de la sección anterior
249
+ if (!fileName && sections[i - 1]) {
250
+ const prevSection = sections[i - 1];
251
+ const fileMatch = prevSection.match(/## Archivo: `([^`]+)`/);
252
+ if (fileMatch)
253
+ fileName = fileMatch[1];
254
+ }
255
+ const { original, modified } = parseDiffUnified(diffContent);
256
+ changes.push({
257
+ file: fileName,
258
+ original: original.join('\n'),
259
+ modified: modified.join('\n')
260
+ });
261
+ }
262
+ }
263
+ }
264
+ return changes;
265
+ }
266
+ function detectChangeType(change) {
267
+ const original = change.original || '';
268
+ const modified = change.modified || '';
269
+ if (original.trim() === '' && modified.trim() !== '') {
270
+ return {
271
+ file: change.file,
272
+ type: 'create',
273
+ modified: modified
274
+ };
275
+ }
276
+ if (modified.trim() === '' && original.trim() !== '') {
277
+ return {
278
+ file: change.file,
279
+ type: 'delete',
280
+ original: original
281
+ };
282
+ }
283
+ return {
284
+ file: change.file,
285
+ type: 'update',
286
+ original: original,
287
+ modified: modified
288
+ };
289
+ }
290
+ async function applyChange(change, dryRun = false) {
291
+ const filePath = change.file.startsWith('/')
292
+ ? change.file
293
+ : join(process.cwd(), change.file);
294
+ switch (change.type) {
295
+ case 'create':
296
+ if (dryRun) {
297
+ info(t('edit.dry_create', change.file));
298
+ return true;
299
+ }
300
+ await writeFile(filePath, change.modified || '');
301
+ success(t("edit.created", change.file));
302
+ return true;
303
+ case 'update':
304
+ try {
305
+ const currentContent = await readFile(filePath, 'utf-8');
306
+ const modifiedContent = change.modified || '';
307
+ if (!change.original || change.original.trim() === '') {
308
+ if (dryRun) {
309
+ info(t("edit.dry_replace", change.file));
310
+ return true;
311
+ }
312
+ await writeFile(filePath, modifiedContent);
313
+ success(t("edit.replaced", change.file));
314
+ return true;
315
+ }
316
+ // 1. Exact match
317
+ if (currentContent.includes(change.original)) {
318
+ if (dryRun) {
319
+ info(t("edit.dry_update", change.file));
320
+ return true;
321
+ }
322
+ const newContent = currentContent.replace(change.original, modifiedContent);
323
+ await writeFile(filePath, newContent);
324
+ success(t("edit.updated", change.file));
325
+ return true;
326
+ }
327
+ // Extraer extensión del archivo
328
+ const fileExt = change.file.split('.').pop() || '';
329
+ // 2. Fuzzy match
330
+ const best = findBestMatch(change.original, currentContent, 0.85, fileExt);
331
+ if (best.found) {
332
+ const simPercent = Math.round(best.similarity * 100);
333
+ warn(t("edit.fuzzy_match", String(simPercent), change.file));
334
+ if (dryRun) {
335
+ info(t("edit.dry_fuzzy", change.file));
336
+ return true;
337
+ }
338
+ const newContent = currentContent.replace(best.text, modifiedContent);
339
+ await writeFile(filePath, newContent);
340
+ success(t("edit.fuzzy_updated", String(simPercent), change.file));
341
+ return true;
342
+ }
343
+ // 3. Generar diagnóstico
344
+ const bestAny = findBestMatch(change.original, currentContent, 0);
345
+ const diagnostic = `❌ No se encontró el bloque original en ${change.file}
346
+
347
+ Similitud máxima encontrada: ${Math.round(bestAny.similarity * 100)}% (umbral mínimo: 85%)
348
+
349
+ Bloque buscado (primeros 200 chars):
350
+ \`\`\`
351
+ ${change.original.substring(0, 200)}${change.original.length > 200 ? '...' : ''}
352
+ \`\`\`
353
+
354
+ Bloque más similar encontrado:
355
+ \`\`\`
356
+ ${bestAny.text.substring(0, 200)}${bestAny.text.length > 200 ? '...' : ''}
357
+ \`\`\`
358
+
359
+ Sugerencias para el agente:
360
+ 1. Pide al usuario ejecutar: ./bin/m ai:readfile ${change.file}
361
+ 2. Pídele que te pegue el contenido EXACTO del archivo
362
+ 3. Usa ese contenido como BUSCAR en tu SEARCH/REPLACE
363
+ 4. Si el archivo es grande (>2KB) o el bloque a reemplazar es muy extenso:
364
+ - Propón una refactorización para dividir el archivo en módulos más pequeños (ej: en lib/)
365
+ - O usa ./bin/m ai:writefile para crear un archivo nuevo simplificado
366
+ - O divide el cambio en múltiples reemplazos pequeños (uno por línea o bloque pequeño)
367
+ 5. El umbral de similitud actual es 85%; si la similitud es baja, el bloque no coincide`;
368
+ const { setClipboard } = await import('./edit.js');
369
+ await setClipboard(diagnostic);
370
+ problem(t("edit.insufficient", String(Math.round(bestAny.similarity * 100))));
371
+ return false;
372
+ }
373
+ catch (err) {
374
+ problem(t("edit.read_error", change.file, String(err)));
375
+ return false;
376
+ }
377
+ case 'delete':
378
+ if (dryRun) {
379
+ info(t("edit.dry_delete", change.file));
380
+ return true;
381
+ }
382
+ warn(t("edit.no_delete", change.file));
383
+ return false;
384
+ default:
385
+ return false;
386
+ }
387
+ }
388
+ export async function runAiEdit(options = {}) {
389
+ let content = options.input || '';
390
+ if (options.input) {
391
+ info(t("edit.reading_file", options.input));
392
+ content = await readFile(options.input, 'utf-8');
393
+ }
394
+ else {
395
+ info('📋 Leyendo portapapeles...');
396
+ content = await getClipboard();
397
+ }
398
+ if (!content) {
399
+ problem(t('edit.empty_clipboard'));
400
+ info('');
401
+ info('📋 Instrucciones:');
402
+ info(' 1. Copia la respuesta de DeepSeek Chat (Ctrl+C o Cmd+C)');
403
+ info(' 2. Ejecuta: ./bin/m ai:apply');
404
+ return;
405
+ }
406
+ info('🔍 Analizando cambios...');
407
+ const changesRaw = parseInlineDiff(content);
408
+ if (changesRaw.length === 0) {
409
+ problem('❌ No se encontraron cambios en el formato esperado.');
410
+ info('');
411
+ info('Formatos aceptados:');
412
+ info('');
413
+ info('1. SEARCH/REPLACE (recomendado):');
414
+ info(' ## Edit: `ruta/archivo.ts`');
415
+ info(' ```diff');
416
+ info(' ___BUSCAR_TIMESTAMP___');
417
+ info(' código original exacto');
418
+ info(' ___REMPLAZAR_TIMESTAMP___');
419
+ info(' código nuevo');
420
+ info(' ___FIN_TIMESTAMP___');
421
+ info(' ```');
422
+ info('');
423
+ info('2. Bloque completo:');
424
+ info(' ## Archivo: `ruta/archivo.ts`');
425
+ info(' ```typescript');
426
+ info(' // contenido completo');
427
+ info(' ```');
428
+ info('');
429
+ info('3. Diff unificado:');
430
+ info(' ```diff');
431
+ info(' - línea vieja');
432
+ info(' + línea nueva');
433
+ info(' ```');
434
+ info('');
435
+ info('💡 Si usas SEARCH/REPLACE, asegúrate de:');
436
+ info(' - El timestamp es el mismo en BUSCAR, REPLAZAR y FIN');
437
+ info(' - El código BUSCAR coincide EXACTAMENTE con el archivo');
438
+ info(' - Usa `ai:readfile` para copiar el contenido exacto');
439
+ return;
440
+ }
441
+ info(t("edit.found_changes", String(changesRaw.length)));
442
+ console.log('');
443
+ const changes = changesRaw.map(detectChangeType);
444
+ if (options.dryRun) {
445
+ info(t('edit.dry_mode'));
446
+ console.log('');
447
+ }
448
+ let successCount = 0;
449
+ let failCount = 0;
450
+ for (const change of changes) {
451
+ const ok = await applyChange(change, options.dryRun || false);
452
+ if (ok) {
453
+ successCount++;
454
+ }
455
+ else {
456
+ failCount++;
457
+ }
458
+ }
459
+ console.log('');
460
+ if (options.dryRun) {
461
+ info(t("edit.summary_dry", String(successCount), String(failCount)));
462
+ }
463
+ else {
464
+ if (failCount === 0) {
465
+ success(t("edit.summary_ok", String(successCount)));
466
+ }
467
+ else {
468
+ problem(t("edit.summary_partial", String(successCount), String(failCount)));
469
+ }
470
+ }
471
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runEngine(args: string[]): Promise<void>;
2
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/tasks/engine.ts"],"names":[],"mappings":"AA+HA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,iBA+B7C"}