Skip to content

Commit 58d847a

Browse files
Merge pull request #89 from NerioVillalobos/codex/add-optional-ai-stabilization-to-task-play
feat(task play): add optional AI hardening (--ai) with Gemini and bump version to 0.11.1
2 parents 4fa54bd + 00d8aab commit 58d847a

10 files changed

Lines changed: 1892 additions & 36 deletions

File tree

README.md

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
> **Last update / Última actualización:** 2026-03-25`@nervill/metadelta` 0.11.0
1+
> **Last update / Última actualización:** 2026-04-16`@nervill/metadelta` 0.11.1
22
33
# Metadelta Salesforce CLI Plugin
44

@@ -48,7 +48,7 @@ Created by **Nerio Villalobos** (<nervill@gmail.com>).
4848
```bash
4949
sf plugins install github:NerioVillalobos/plugin-metadelta.git
5050
```
51-
Confirm installation with `sf plugins`, which should list `@nervill/metadelta 0.11.0`.
51+
Confirm installation with `sf plugins`, which should list `@nervill/metadelta 0.11.1`.
5252

5353
3. (Optional, for local development) Clone this repository and install dependencies:
5454
```bash
@@ -61,7 +61,7 @@ Created by **Nerio Villalobos** (<nervill@gmail.com>).
6161
npm run build
6262
sf plugins link .
6363
```
64-
Confirm installation with `sf plugins`, which should list `@nervill/metadelta 0.11.0 (link)`.
64+
Confirm installation with `sf plugins`, which should list `@nervill/metadelta 0.11.1 (link)`.
6565

6666
### Usage
6767

@@ -365,7 +365,7 @@ What the command creates:
365365

366366
`initspace` is idempotent for directories (safe to re-run) and rewrites the three root files so they stay aligned with the plugin defaults.
367367

368-
> **Linked ESM note:** When `sf` prints `@nervill/metadelta is a linked ESM module and cannot be auto-transpiled`, always run `npm run build` before testing commands. If your CLI still does not resolve `sf metadelta task record`, use `sf metadelta:task:record` and relink the plugin. Task diagnostics are saved in `.metadelta/metadelta-task-orchestrator.json`.
368+
> **Linked ESM note:** When `sf` prints `@nervill/metadelta is a linked ESM module and cannot be auto-transpiled`, always run `npm run build` before testing commands. If your CLI still does not resolve `sf metadelta task record`, use `sf metadelta:task:record` and relink the plugin. Task diagnostics are saved in `.metadelta/metadelta-task-orchestrator.json`. This is mandatory after local code changes; otherwise `sf` may run stale compiled `lib/` output.
369369
> **Task play hardening:** `sf metadelta task play` now includes automatic stabilizers for frontdoor/base URL separation, initial Setup popup recovery, popup rebinds, App Launcher fallbacks, dynamic Permission Set Assignment selectors, and Action Library scroll selection + Finish enablement checks in the temporary `.metadelta.*` test file.
370370
> **Task orchestrator diagnostics:** The orchestrator now stores the most relevant Playwright failure excerpt (not only the exit code), making solution matching and future triage more accurate in `.metadelta/metadelta-task-orchestrator.json`.
371371
> **Report a task-play issue:** If playback fails, please open a public GitHub Issue at <https://github.com/NerioVillalobos/plugin-metadelta/issues> and include: (1) command executed, (2) full error text, (3) screenshot captured while running with `--header`, and (4) sanitized `.metadelta.*` snippet around the failing step.
@@ -376,14 +376,36 @@ Use `task record` to capture a Playwright flow and `task play` to replay it in a
376376

377377
```bash
378378
sf metadelta task record --org <alias>
379-
sf metadelta task play --org <alias> --tstname tests/<recorded-file>.ts [--header]
379+
sf metadelta task play --org <alias> --tstname tests/<recorded-file>.ts [--header] [--ai --ai-provider gemini --ai-model <model> --ai-key <key>]
380380
```
381381

382382
Supported coverage for `sf metadelta task play` (scope and limits):
383383

384384
* `task play` creates a temporary patched file (`tests/.metadelta.*`) to stabilize recurring Salesforce UI differences.
385+
* Optional AI hardening (`--ai`) runs **after** deterministic patching, uses a constrained AI fragility-analysis plan (targeted hardening, not full-file free rewrite), creates a second derived file (`tests/.metadelta.<name>.ai.ts`) when safe, supports model override with `--ai-model`/`METADELTA_AI_MODEL`, and falls back to the deterministic file if AI is unavailable/invalid.
386+
* Playback now also includes conservative idempotent guards for supported patterns (checkbox state, toggle state, and safe fill-value matches): when target state is already satisfied the step is skipped; otherwise it runs normally.
385387
* The command aims to auto-mitigate known recurrent failures first; if mitigation is not possible, it surfaces orchestrator-backed actionable errors instead of generic failures.
386388

389+
AI and idempotency options (quick reference):
390+
391+
| Option | Purpose | Required |
392+
|---|---|---|
393+
| `--ai` | Enables optional AI hardening stage over deterministic patched file. | No |
394+
| `--ai-provider` | AI provider selector (current supported value: `gemini`). | No (defaults to `gemini` when `--ai` is used) |
395+
| `--ai-model` | Overrides Gemini model (e.g. `gemini-2.5-flash`). | No |
396+
| `--ai-key` | API key passed inline (pipeline-friendly but prefer env secrets). | No (required only when `--ai` is enabled and no env key exists) |
397+
398+
Environment variables recognized by AI mode:
399+
400+
* `GEMINI_API_KEY` or `METADELTA_AI_KEY` for credentials.
401+
* `METADELTA_AI_MODEL` or `GEMINI_MODEL` for model override.
402+
403+
How idempotent playback behaves:
404+
405+
* Supported patterns (checkbox/switch/fill and specific toggle flows) are checked before acting.
406+
* If target state is confidently already satisfied, the step is skipped with concise log (`⏭️ action skipped: already satisfied ...`).
407+
* If state is uncertain, playback does **not** skip blindly; it keeps conservative execution.
408+
387409
Automatic mitigations currently covered:
388410

389411
* frontdoor URL vs base origin separation to avoid malformed navigation URLs.
@@ -936,7 +958,7 @@ Qué crea el comando:
936958
937959
`initspace` es idempotente para carpetas (puedes ejecutarlo varias veces) y reescribe los tres archivos raíz para mantenerlos alineados con la configuración por defecto del plugin.
938960
939-
> **Nota para ESM enlazado:** Si `sf` muestra `@nervill/metadelta is a linked ESM module and cannot be auto-transpiled`, ejecuta `npm run build` antes de probar comandos. Si la CLI no resuelve `sf metadelta task record`, usa `sf metadelta:task:record` y vuelve a enlazar el plugin. El diagnóstico de tareas se guarda en `.metadelta/metadelta-task-orchestrator.json`.
961+
> **Nota para ESM enlazado:** Si `sf` muestra `@nervill/metadelta is a linked ESM module and cannot be auto-transpiled`, ejecuta `npm run build` antes de probar comandos. Si la CLI no resuelve `sf metadelta task record`, usa `sf metadelta:task:record` y vuelve a enlazar el plugin. El diagnóstico de tareas se guarda en `.metadelta/metadelta-task-orchestrator.json`. Esto es obligatorio tras cambios locales de código; de lo contrario `sf` puede ejecutar un `lib/` compilado desactualizado.
940962
> **Robustez en task play:** `sf metadelta task play` incluye estabilizadores automáticos para separar frontdoor/base URL, recuperar la apertura inicial del popup de Setup, reabrir popups, aplicar fallback en App Launcher, normalizar selectores dinámicos de Permission Set Assignment y resolver selección con scroll + validación de botón Finish en Action Library dentro del archivo temporal `.metadelta.*`.
941963
> **Diagnóstico del orquestador:** El orquestador ahora guarda el fragmento más relevante del fallo de Playwright (no solo el código de salida), mejorando el match de soluciones y el triage futuro dentro de `.metadelta/metadelta-task-orchestrator.json`.
942964
> **Reportar incidencias de task play:** Si la reproducción falla, abre un Issue público en GitHub: <https://github.com/NerioVillalobos/plugin-metadelta/issues> e incluye: (1) comando ejecutado, (2) texto completo del error, (3) captura ejecutando con `--header`, y (4) fragmento saneado del archivo `.metadelta.*` en el paso donde falla.
@@ -947,14 +969,36 @@ Usa `task record` para grabar un flujo en Playwright y `task play` para reproduc
947969
948970
```bash
949971
sf metadelta task record --org <alias>
950-
sf metadelta task play --org <alias> --tstname tests/<archivo-grabado>.ts [--header]
972+
sf metadelta task play --org <alias> --tstname tests/<archivo-grabado>.ts [--header] [--ai --ai-provider gemini --ai-model <model> --ai-key <key>]
951973
```
952974
953975
Cobertura soportada de `sf metadelta task play` (alcance y límites):
954976
955977
* `task play` crea un archivo temporal parcheado (`tests/.metadelta.*`) para estabilizar diferencias recurrentes de UI en Salesforce.
978+
* El hardening con IA (`--ai`) es opcional, corre **después** del parcheo determinista, usa un plan interno acotado de análisis de fragilidad (no reescritura libre del archivo completo), crea un segundo archivo derivado (`tests/.metadelta.<nombre>.ai.ts`) cuando es seguro, permite forzar modelo con `--ai-model`/`METADELTA_AI_MODEL` y vuelve al archivo determinista si la IA falla o responde inválido.
979+
* La reproducción ahora incluye guardas idempotentes conservadoras para patrones soportados (estado de checkbox, estado de toggles y fills comparables): si el estado objetivo ya está cumplido se omite el paso; si no, se ejecuta normalmente.
956980
* El comando intenta primero mitigar automáticamente los fallos recurrentes conocidos; si no puede resolverlos, devuelve errores accionables respaldados por el orquestador (en vez de fallos genéricos).
957981
982+
Opciones de IA e idempotencia (resumen rápido):
983+
984+
| Opción | Propósito | Requerido |
985+
|---|---|---|
986+
| `--ai` | Activa la capa opcional de hardening con IA sobre el parche determinista. | No |
987+
| `--ai-provider` | Selector de proveedor IA (valor soportado actualmente: `gemini`). | No (por defecto `gemini` al usar `--ai`) |
988+
| `--ai-model` | Permite forzar modelo Gemini (ejemplo: `gemini-2.5-flash`). | No |
989+
| `--ai-key` | API key inline (útil en pipeline, aunque se recomienda secret por variable de entorno). | No (solo requerida si usas `--ai` y no hay key por entorno) |
990+
991+
Variables de entorno reconocidas por modo IA:
992+
993+
* `GEMINI_API_KEY` o `METADELTA_AI_KEY` para credenciales.
994+
* `METADELTA_AI_MODEL` o `GEMINI_MODEL` para override de modelo.
995+
996+
Comportamiento de reproducción idempotente:
997+
998+
* Patrones soportados (checkbox/switch/fill y ciertos toggles específicos) se validan antes de actuar.
999+
* Si el estado objetivo ya está satisfecho con alta confianza, se omite el paso y se registra (`⏭️ action skipped: already satisfied ...`).
1000+
* Si el estado es incierto, no se omite de forma especulativa; se mantiene ejecución conservadora.
1001+
9581002
Mitigaciones automáticas cubiertas actualmente:
9591003
9601004
* Separación de frontdoor URL vs base origin para evitar navegación con URLs mal concatenadas.

0 commit comments

Comments
 (0)