@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.
- package/dist/blockchain/deployments.d.ts +40 -0
- package/dist/blockchain/deployments.d.ts.map +1 -0
- package/dist/blockchain/deployments.js +64 -0
- package/dist/debug/DebugConsole.d.ts +22 -0
- package/dist/debug/DebugConsole.d.ts.map +1 -0
- package/dist/debug/DebugConsole.js +79 -0
- package/dist/debug/Logger.d.ts +38 -0
- package/dist/debug/Logger.d.ts.map +1 -0
- package/dist/debug/Logger.js +94 -0
- package/dist/debug/index.d.ts +6 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +4 -0
- package/dist/debug/useLogger.d.ts +14 -0
- package/dist/debug/useLogger.d.ts.map +1 -0
- package/dist/debug/useLogger.js +23 -0
- package/dist/debug/utils.d.ts +10 -0
- package/dist/debug/utils.d.ts.map +1 -0
- package/dist/debug/utils.js +53 -0
- package/dist/e2e/assertions.d.ts +5 -0
- package/dist/e2e/assertions.d.ts.map +1 -0
- package/dist/e2e/assertions.js +18 -0
- package/dist/e2e/browser.d.ts +37 -0
- package/dist/e2e/browser.d.ts.map +1 -0
- package/dist/e2e/browser.js +97 -0
- package/dist/e2e/env.d.ts +18 -0
- package/dist/e2e/env.d.ts.map +1 -0
- package/dist/e2e/env.js +57 -0
- package/dist/e2e/index.d.ts +11 -0
- package/dist/e2e/index.d.ts.map +1 -0
- package/dist/e2e/index.js +8 -0
- package/dist/e2e/navigation.d.ts +4 -0
- package/dist/e2e/navigation.d.ts.map +1 -0
- package/dist/e2e/navigation.js +32 -0
- package/dist/e2e/siwe-mock.d.ts +11 -0
- package/dist/e2e/siwe-mock.d.ts.map +1 -0
- package/dist/e2e/siwe-mock.js +112 -0
- package/dist/e2e/siwe.d.ts +15 -0
- package/dist/e2e/siwe.d.ts.map +1 -0
- package/dist/e2e/siwe.js +85 -0
- package/dist/e2e/wallet-mock.d.ts +13 -0
- package/dist/e2e/wallet-mock.d.ts.map +1 -0
- package/dist/e2e/wallet-mock.js +91 -0
- package/dist/i18n/common-cli.d.ts +11 -0
- package/dist/i18n/common-cli.d.ts.map +1 -0
- package/dist/i18n/common-cli.js +22 -0
- package/dist/i18n/createTranslator.d.ts +28 -0
- package/dist/i18n/createTranslator.d.ts.map +1 -0
- package/dist/i18n/createTranslator.js +48 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/locales/cli.d.ts +3 -0
- package/dist/i18n/locales/cli.d.ts.map +1 -0
- package/dist/i18n/locales/cli.js +180 -0
- package/dist/i18n/types.d.ts +3 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +10 -0
- package/dist/m.d.ts +2 -0
- package/dist/m.d.ts.map +1 -0
- package/dist/m.js +334 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +7 -0
- package/dist/shadcn_components/cn.d.ts +13 -0
- package/dist/shadcn_components/cn.d.ts.map +1 -0
- package/dist/shadcn_components/cn.js +15 -0
- package/dist/shadcn_components/ui/accordion.d.ts +8 -0
- package/dist/shadcn_components/ui/accordion.d.ts.map +1 -0
- package/dist/shadcn_components/ui/accordion.js +14 -0
- package/dist/shadcn_components/ui/alert-dialog.d.ts +21 -0
- package/dist/shadcn_components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/shadcn_components/ui/alert-dialog.js +27 -0
- package/dist/shadcn_components/ui/alert.d.ts +9 -0
- package/dist/shadcn_components/ui/alert.d.ts.map +1 -0
- package/dist/shadcn_components/ui/alert.js +22 -0
- package/dist/shadcn_components/ui/avatar.d.ts +7 -0
- package/dist/shadcn_components/ui/avatar.d.ts.map +1 -0
- package/dist/shadcn_components/ui/avatar.js +12 -0
- package/dist/shadcn_components/ui/badge.d.ts +10 -0
- package/dist/shadcn_components/ui/badge.d.ts.map +1 -0
- package/dist/shadcn_components/ui/badge.js +22 -0
- package/dist/shadcn_components/ui/button.d.ts +11 -0
- package/dist/shadcn_components/ui/button.d.ts.map +1 -0
- package/dist/shadcn_components/ui/button.js +31 -0
- package/dist/shadcn_components/ui/card.d.ts +10 -0
- package/dist/shadcn_components/ui/card.d.ts.map +1 -0
- package/dist/shadcn_components/ui/card.js +24 -0
- package/dist/shadcn_components/ui/checkbox.d.ts +5 -0
- package/dist/shadcn_components/ui/checkbox.d.ts.map +1 -0
- package/dist/shadcn_components/ui/checkbox.js +9 -0
- package/dist/shadcn_components/ui/dialog.d.ts +20 -0
- package/dist/shadcn_components/ui/dialog.d.ts.map +1 -0
- package/dist/shadcn_components/ui/dialog.js +23 -0
- package/dist/shadcn_components/ui/dropdown-menu.d.ts +28 -0
- package/dist/shadcn_components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/shadcn_components/ui/dropdown-menu.js +36 -0
- package/dist/shadcn_components/ui/form.d.ts +24 -0
- package/dist/shadcn_components/ui/form.d.ts.map +1 -0
- package/dist/shadcn_components/ui/form.js +63 -0
- package/dist/shadcn_components/ui/input.d.ts +4 -0
- package/dist/shadcn_components/ui/input.d.ts.map +1 -0
- package/dist/shadcn_components/ui/input.js +6 -0
- package/dist/shadcn_components/ui/label.d.ts +6 -0
- package/dist/shadcn_components/ui/label.d.ts.map +1 -0
- package/dist/shadcn_components/ui/label.js +10 -0
- package/dist/shadcn_components/ui/menubar.d.ts +29 -0
- package/dist/shadcn_components/ui/menubar.d.ts.map +1 -0
- package/dist/shadcn_components/ui/menubar.js +46 -0
- package/dist/shadcn_components/ui/popover.d.ts +7 -0
- package/dist/shadcn_components/ui/popover.d.ts.map +1 -0
- package/dist/shadcn_components/ui/popover.js +10 -0
- package/dist/shadcn_components/ui/progress.d.ts +5 -0
- package/dist/shadcn_components/ui/progress.d.ts.map +1 -0
- package/dist/shadcn_components/ui/progress.js +8 -0
- package/dist/shadcn_components/ui/radio-group.d.ts +6 -0
- package/dist/shadcn_components/ui/radio-group.d.ts.map +1 -0
- package/dist/shadcn_components/ui/radio-group.js +15 -0
- package/dist/shadcn_components/ui/scroll-area.d.ts +6 -0
- package/dist/shadcn_components/ui/scroll-area.d.ts.map +1 -0
- package/dist/shadcn_components/ui/scroll-area.js +12 -0
- package/dist/shadcn_components/ui/select.d.ts +14 -0
- package/dist/shadcn_components/ui/select.d.ts.map +1 -0
- package/dist/shadcn_components/ui/select.js +27 -0
- package/dist/shadcn_components/ui/separator.d.ts +5 -0
- package/dist/shadcn_components/ui/separator.d.ts.map +1 -0
- package/dist/shadcn_components/ui/separator.js +8 -0
- package/dist/shadcn_components/ui/sheet.d.ts +26 -0
- package/dist/shadcn_components/ui/sheet.d.ts.map +1 -0
- package/dist/shadcn_components/ui/sheet.js +37 -0
- package/dist/shadcn_components/ui/skeleton.d.ts +3 -0
- package/dist/shadcn_components/ui/skeleton.d.ts.map +1 -0
- package/dist/shadcn_components/ui/skeleton.js +6 -0
- package/dist/shadcn_components/ui/slider.d.ts +5 -0
- package/dist/shadcn_components/ui/slider.d.ts.map +1 -0
- package/dist/shadcn_components/ui/slider.js +8 -0
- package/dist/shadcn_components/ui/switch.d.ts +5 -0
- package/dist/shadcn_components/ui/switch.d.ts.map +1 -0
- package/dist/shadcn_components/ui/switch.js +8 -0
- package/dist/shadcn_components/ui/table.d.ts +11 -0
- package/dist/shadcn_components/ui/table.d.ts.map +1 -0
- package/dist/shadcn_components/ui/table.js +20 -0
- package/dist/shadcn_components/ui/tabs.d.ts +8 -0
- package/dist/shadcn_components/ui/tabs.d.ts.map +1 -0
- package/dist/shadcn_components/ui/tabs.js +13 -0
- package/dist/shadcn_components/ui/textarea.d.ts +4 -0
- package/dist/shadcn_components/ui/textarea.d.ts.map +1 -0
- package/dist/shadcn_components/ui/textarea.js +8 -0
- package/dist/shadcn_components/ui/toast.d.ts +16 -0
- package/dist/shadcn_components/ui/toast.d.ts.map +1 -0
- package/dist/shadcn_components/ui/toast.js +34 -0
- package/dist/shadcn_components/ui/toaster.d.ts +2 -0
- package/dist/shadcn_components/ui/toaster.d.ts.map +1 -0
- package/dist/shadcn_components/ui/toaster.js +10 -0
- package/dist/shadcn_components/ui/tooltip.d.ts +8 -0
- package/dist/shadcn_components/ui/tooltip.d.ts.map +1 -0
- package/dist/shadcn_components/ui/tooltip.js +11 -0
- package/dist/shadcn_components/ui/use-toast.d.ts +45 -0
- package/dist/shadcn_components/ui/use-toast.d.ts.map +1 -0
- package/dist/shadcn_components/ui/use-toast.js +126 -0
- package/dist/tasks/context.d.ts +13 -0
- package/dist/tasks/context.d.ts.map +1 -0
- package/dist/tasks/context.js +310 -0
- package/dist/tasks/create.d.ts +2 -0
- package/dist/tasks/create.d.ts.map +1 -0
- package/dist/tasks/create.js +91 -0
- package/dist/tasks/db.d.ts +19 -0
- package/dist/tasks/db.d.ts.map +1 -0
- package/dist/tasks/db.js +791 -0
- package/dist/tasks/e2e.d.ts +2 -0
- package/dist/tasks/e2e.d.ts.map +1 -0
- package/dist/tasks/e2e.js +124 -0
- package/dist/tasks/edit.d.ts +7 -0
- package/dist/tasks/edit.d.ts.map +1 -0
- package/dist/tasks/edit.js +471 -0
- package/dist/tasks/engine.d.ts +2 -0
- package/dist/tasks/engine.d.ts.map +1 -0
- package/dist/tasks/engine.js +149 -0
- package/dist/tasks/env-diff.d.ts +2 -0
- package/dist/tasks/env-diff.d.ts.map +1 -0
- package/dist/tasks/env-diff.js +140 -0
- package/dist/tasks/fuzzy.d.ts +9 -0
- package/dist/tasks/fuzzy.d.ts.map +1 -0
- package/dist/tasks/fuzzy.js +153 -0
- package/dist/tasks/glob.d.ts +5 -0
- package/dist/tasks/glob.d.ts.map +1 -0
- package/dist/tasks/glob.js +57 -0
- package/dist/tasks/grep.d.ts +9 -0
- package/dist/tasks/grep.d.ts.map +1 -0
- package/dist/tasks/grep.js +93 -0
- package/dist/tasks/readfile.d.ts +2 -0
- package/dist/tasks/readfile.d.ts.map +1 -0
- package/dist/tasks/readfile.js +177 -0
- package/dist/tasks/update.d.ts +5 -0
- package/dist/tasks/update.d.ts.map +1 -0
- package/dist/tasks/update.js +200 -0
- package/dist/tasks/util.d.ts +12 -0
- package/dist/tasks/util.d.ts.map +1 -0
- package/dist/tasks/util.js +42 -0
- package/dist/tasks/wallet.d.ts +2 -0
- package/dist/tasks/wallet.d.ts.map +1 -0
- package/dist/tasks/wallet.js +697 -0
- package/dist/tasks/writefile.d.ts +2 -0
- package/dist/tasks/writefile.d.ts.map +1 -0
- package/dist/tasks/writefile.js +66 -0
- package/dist/templates/AGENTS.md.hbs +81 -0
- package/dist/templates/ARCHITECTURE.md.hbs +146 -0
- package/dist/templates/CONTRIBUTING.md.hbs +83 -0
- package/dist/templates/LICENCIA.md +21 -0
- package/dist/templates/LICENSE.md +15 -0
- package/dist/templates/Makefile +16 -0
- package/dist/templates/README.md.hbs +111 -0
- package/dist/templates/apps/.env.example.hbs +75 -0
- package/dist/templates/apps/hardhat/.prettierrc +16 -0
- package/dist/templates/apps/hardhat/MOCK_USDT_README.md +20 -0
- package/dist/templates/apps/hardhat/Makefile +13 -0
- package/dist/templates/apps/hardhat/README.md +129 -0
- package/dist/templates/apps/hardhat/bin/MusdtVerification +4 -0
- package/dist/templates/apps/hardhat/bin/approveDepositOwner +7 -0
- package/dist/templates/apps/hardhat/bin/contractVerification +9 -0
- package/dist/templates/apps/hardhat/bin/deployMockUSDT +7 -0
- package/dist/templates/apps/hardhat/bin/prepadJ.sh +14 -0
- package/dist/templates/apps/hardhat/bin/verifyMockUSDT +7 -0
- package/dist/templates/apps/hardhat/contracts/MockUSDT.sol +47 -0
- package/dist/templates/apps/hardhat/hardhat.config.ts +102 -0
- package/dist/templates/apps/hardhat/package.json +55 -0
- package/dist/templates/apps/hardhat/scripts/approveDepositOwner.ts +22 -0
- package/dist/templates/apps/hardhat/scripts/deployMockUSDT.ts +49 -0
- package/dist/templates/apps/hardhat/scripts/verifyDeployment.ts +93 -0
- package/dist/templates/apps/hardhat/scripts/verifyMockUSDT.ts +52 -0
- package/dist/templates/apps/hardhat/sync-abis.mjs +58 -0
- package/dist/templates/apps/hardhat/test/MockUSDT.test.ts +40 -0
- package/dist/templates/apps/hardhat/tsconfig.json +27 -0
- package/dist/templates/apps/nextjs/.config/kysely.config.ts +36 -0
- package/dist/templates/apps/nextjs/Makefile +24 -0
- package/dist/templates/apps/nextjs/README.md.hbs +76 -0
- package/dist/templates/apps/nextjs/abis/IERC20.json +74 -0
- package/dist/templates/apps/nextjs/abis/MockUSDT.json +242 -0
- package/dist/templates/apps/nextjs/abis/ReentrancyGuard.json +1 -0
- package/dist/templates/apps/nextjs/app/globals.css +3 -0
- package/dist/templates/apps/nextjs/app/layout.tsx.hbs +26 -0
- package/dist/templates/apps/nextjs/app/page.tsx.hbs +225 -0
- package/dist/templates/apps/nextjs/app/testui/page.tsx +371 -0
- package/dist/templates/apps/nextjs/bin/m +8 -0
- package/dist/templates/apps/nextjs/components.json +21 -0
- package/dist/templates/apps/nextjs/next-env.d.ts +5 -0
- package/dist/templates/apps/nextjs/next.config.ts +10 -0
- package/dist/templates/apps/nextjs/package.json.hbs +48 -0
- package/dist/templates/apps/nextjs/pnpm-workspace.yaml +13 -0
- package/dist/templates/apps/nextjs/postcss.config.mjs +6 -0
- package/dist/templates/apps/nextjs/tailwind.config.js +11 -0
- package/dist/templates/apps/nextjs/tests/helpers.ts +31 -0
- package/dist/templates/apps/nextjs/tests/index.test.ts +7 -0
- package/dist/templates/apps/nextjs/tests/setup-env.ts.hbs +8 -0
- package/dist/templates/apps/nextjs/tests/test-utils.example.test.ts +168 -0
- package/dist/templates/apps/nextjs/tsconfig.json +44 -0
- package/dist/templates/apps/nextjs/tsconfig.test.json +38 -0
- package/dist/templates/apps/nextjs/vitest.config.ts +13 -0
- package/dist/test-utils/fs-mocks.d.ts +32 -0
- package/dist/test-utils/fs-mocks.d.ts.map +1 -0
- package/dist/test-utils/fs-mocks.js +63 -0
- package/dist/test-utils/i18n-mock.d.ts +21 -0
- package/dist/test-utils/i18n-mock.d.ts.map +1 -0
- package/dist/test-utils/i18n-mock.js +29 -0
- package/dist/test-utils/index.d.ts +12 -0
- package/dist/test-utils/index.d.ts.map +1 -0
- package/dist/test-utils/index.js +11 -0
- package/dist/test-utils/kysely-mocks.d.ts +298 -0
- package/dist/test-utils/kysely-mocks.d.ts.map +1 -0
- package/dist/test-utils/kysely-mocks.js +173 -0
- package/dist/test-utils/radix-mocks.d.ts +134 -0
- package/dist/test-utils/radix-mocks.d.ts.map +1 -0
- package/dist/test-utils/radix-mocks.js +175 -0
- package/dist/test-utils/rainbowkit-mocks.d.ts +80 -0
- package/dist/test-utils/rainbowkit-mocks.d.ts.map +1 -0
- package/dist/test-utils/rainbowkit-mocks.js +247 -0
- package/dist/test-utils/viem-mocks.d.ts +86 -0
- package/dist/test-utils/viem-mocks.d.ts.map +1 -0
- package/dist/test-utils/viem-mocks.js +54 -0
- package/dist/util/cli-parser.d.ts +20 -0
- package/dist/util/cli-parser.d.ts.map +1 -0
- package/dist/util/cli-parser.js +38 -0
- package/dist/util/colors.d.ts +5 -0
- package/dist/util/colors.d.ts.map +1 -0
- package/dist/util/colors.js +5 -0
- package/dist/util/locale.d.ts +3 -0
- package/dist/util/locale.d.ts.map +1 -0
- package/dist/util/locale.js +10 -0
- package/dist/wba/client.d.ts +19 -0
- package/dist/wba/client.d.ts.map +1 -0
- package/dist/wba/client.js +31 -0
- package/dist/wba/index.d.ts +4 -0
- package/dist/wba/index.d.ts.map +1 -0
- package/dist/wba/index.js +2 -0
- package/dist/wba/routes/event.d.ts +32 -0
- package/dist/wba/routes/event.d.ts.map +1 -0
- package/dist/wba/routes/event.js +42 -0
- package/dist/wba/routes/index.d.ts +3 -0
- package/dist/wba/routes/index.d.ts.map +1 -0
- package/dist/wba/routes/index.js +2 -0
- package/dist/wba/routes/summary.d.ts +44 -0
- package/dist/wba/routes/summary.d.ts.map +1 -0
- package/dist/wba/routes/summary.js +146 -0
- package/dist/wba/server.d.ts +18 -0
- package/dist/wba/server.d.ts.map +1 -0
- package/dist/wba/server.js +29 -0
- package/dist/wba/types.d.ts +68 -0
- package/dist/wba/types.d.ts.map +1 -0
- package/dist/wba/types.js +6 -0
- package/package.json +223 -0
- package/src/blockchain/README.md +80 -0
- package/src/debug/README.md +94 -0
- package/src/e2e/README.md +105 -0
- package/src/i18n/README.md +143 -0
- package/src/shadcn_components/README.md +125 -0
- package/src/tasks/README.md +69 -0
- package/src/test-utils/README.md +638 -0
- package/src/util/README.md +18 -0
- package/src/wba/README.md +175 -0
|
@@ -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 @@
|
|
|
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"}
|