@hoilab/ada-cli 0.84.21 → 0.85.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/CHANGELOG.md +49 -2
- package/README.es.md +174 -0
- package/README.md +203 -658
- package/dist/ada-publico.d.ts +35 -0
- package/dist/ada-publico.d.ts.map +1 -0
- package/dist/ada-publico.js +40 -0
- package/dist/ada-publico.js.map +1 -0
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/audit-command.d.ts +15 -0
- package/dist/cli/audit-command.d.ts.map +1 -0
- package/dist/cli/audit-command.js +280 -0
- package/dist/cli/audit-command.js.map +1 -0
- package/dist/cli/banco-command.d.ts +15 -0
- package/dist/cli/banco-command.d.ts.map +1 -0
- package/dist/cli/banco-command.js +213 -0
- package/dist/cli/banco-command.js.map +1 -0
- package/dist/cli/cleanse-command.d.ts +11 -0
- package/dist/cli/cleanse-command.d.ts.map +1 -0
- package/dist/cli/cleanse-command.js +101 -0
- package/dist/cli/cleanse-command.js.map +1 -0
- package/dist/cli/commit-command.d.ts +31 -0
- package/dist/cli/commit-command.d.ts.map +1 -0
- package/dist/cli/commit-command.js +158 -0
- package/dist/cli/commit-command.js.map +1 -0
- package/dist/cli/computer-command.d.ts +12 -0
- package/dist/cli/computer-command.d.ts.map +1 -0
- package/dist/cli/computer-command.js +141 -0
- package/dist/cli/computer-command.js.map +1 -0
- package/dist/cli/discover-command.d.ts +18 -0
- package/dist/cli/discover-command.d.ts.map +1 -0
- package/dist/cli/discover-command.js +108 -0
- package/dist/cli/discover-command.js.map +1 -0
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/hashline-command.d.ts +11 -0
- package/dist/cli/hashline-command.d.ts.map +1 -0
- package/dist/cli/hashline-command.js +106 -0
- package/dist/cli/hashline-command.js.map +1 -0
- package/dist/cli/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +2 -2
- package/dist/cli/home-screen.js.map +1 -1
- package/dist/cli/import-command.d.ts +35 -0
- package/dist/cli/import-command.d.ts.map +1 -0
- package/dist/cli/import-command.js +164 -0
- package/dist/cli/import-command.js.map +1 -0
- package/dist/cli/politica-command.d.ts +20 -0
- package/dist/cli/politica-command.d.ts.map +1 -0
- package/dist/cli/politica-command.js +93 -0
- package/dist/cli/politica-command.js.map +1 -0
- package/dist/cli/refine-command.d.ts +18 -0
- package/dist/cli/refine-command.d.ts.map +1 -0
- package/dist/cli/refine-command.js +101 -0
- package/dist/cli/refine-command.js.map +1 -0
- package/dist/cli/review-command.d.ts +24 -0
- package/dist/cli/review-command.d.ts.map +1 -0
- package/dist/cli/review-command.js +168 -0
- package/dist/cli/review-command.js.map +1 -0
- package/dist/cli/schedule-command.d.ts +17 -0
- package/dist/cli/schedule-command.d.ts.map +1 -0
- package/dist/cli/schedule-command.js +117 -0
- package/dist/cli/schedule-command.js.map +1 -0
- package/dist/cli/serve-command.d.ts +72 -0
- package/dist/cli/serve-command.d.ts.map +1 -0
- package/dist/cli/serve-command.js +568 -0
- package/dist/cli/serve-command.js.map +1 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +9 -3
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli/telegram-command.d.ts +18 -0
- package/dist/cli/telegram-command.d.ts.map +1 -0
- package/dist/cli/telegram-command.js +137 -0
- package/dist/cli/telegram-command.js.map +1 -0
- package/dist/cli/telemetria-command.d.ts +22 -0
- package/dist/cli/telemetria-command.d.ts.map +1 -0
- package/dist/cli/telemetria-command.js +127 -0
- package/dist/cli/telemetria-command.js.map +1 -0
- package/dist/cli/undo-command.d.ts +9 -0
- package/dist/cli/undo-command.d.ts.map +1 -0
- package/dist/cli/undo-command.js +56 -0
- package/dist/cli/undo-command.js.map +1 -0
- package/dist/cli/usage-command.d.ts +10 -0
- package/dist/cli/usage-command.d.ts.map +1 -0
- package/dist/cli/usage-command.js +209 -0
- package/dist/cli/usage-command.js.map +1 -0
- package/dist/cli/wiki-command.d.ts +9 -0
- package/dist/cli/wiki-command.d.ts.map +1 -0
- package/dist/cli/wiki-command.js +76 -0
- package/dist/cli/wiki-command.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -11
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -2
- package/dist/config.js.map +1 -1
- package/dist/core/ada.d.ts +58 -0
- package/dist/core/ada.d.ts.map +1 -0
- package/dist/core/ada.js +61 -0
- package/dist/core/ada.js.map +1 -0
- package/dist/core/advisor/guarda.d.ts +66 -0
- package/dist/core/advisor/guarda.d.ts.map +1 -0
- package/dist/core/advisor/guarda.js +191 -0
- package/dist/core/advisor/guarda.js.map +1 -0
- package/dist/core/advisor/runtime.d.ts +66 -0
- package/dist/core/advisor/runtime.d.ts.map +1 -0
- package/dist/core/advisor/runtime.js +121 -0
- package/dist/core/advisor/runtime.js.map +1 -0
- package/dist/core/advisor/sesion.d.ts +109 -0
- package/dist/core/advisor/sesion.d.ts.map +1 -0
- package/dist/core/advisor/sesion.js +139 -0
- package/dist/core/advisor/sesion.js.map +1 -0
- package/dist/core/agent-session.d.ts +85 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +862 -78
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents/loader.d.ts +77 -0
- package/dist/core/agents/loader.d.ts.map +1 -0
- package/dist/core/agents/loader.js +154 -0
- package/dist/core/agents/loader.js.map +1 -0
- package/dist/core/aprobacion/generados.d.ts +37 -0
- package/dist/core/aprobacion/generados.d.ts.map +1 -0
- package/dist/core/aprobacion/generados.js +85 -0
- package/dist/core/aprobacion/generados.js.map +1 -0
- package/dist/core/aprobacion/politica-de-maquina.d.ts +90 -0
- package/dist/core/aprobacion/politica-de-maquina.d.ts.map +1 -0
- package/dist/core/aprobacion/politica-de-maquina.js +212 -0
- package/dist/core/aprobacion/politica-de-maquina.js.map +1 -0
- package/dist/core/aprobacion/politica.d.ts +90 -0
- package/dist/core/aprobacion/politica.d.ts.map +1 -0
- package/dist/core/aprobacion/politica.js +375 -0
- package/dist/core/aprobacion/politica.js.map +1 -0
- package/dist/core/arranque/atajos.d.ts +46 -0
- package/dist/core/arranque/atajos.d.ts.map +1 -0
- package/dist/core/arranque/atajos.js +113 -0
- package/dist/core/arranque/atajos.js.map +1 -0
- package/dist/core/audit/exportacion.d.ts +54 -0
- package/dist/core/audit/exportacion.d.ts.map +1 -0
- package/dist/core/audit/exportacion.js +265 -0
- package/dist/core/audit/exportacion.js.map +1 -0
- package/dist/core/audit/libro.d.ts +318 -0
- package/dist/core/audit/libro.d.ts.map +1 -0
- package/dist/core/audit/libro.js +508 -0
- package/dist/core/audit/libro.js.map +1 -0
- package/dist/core/audit/registro-sesion.d.ts +78 -0
- package/dist/core/audit/registro-sesion.d.ts.map +1 -0
- package/dist/core/audit/registro-sesion.js +202 -0
- package/dist/core/audit/registro-sesion.js.map +1 -0
- package/dist/core/audit/retencion.d.ts +82 -0
- package/dist/core/audit/retencion.d.ts.map +1 -0
- package/dist/core/audit/retencion.js +152 -0
- package/dist/core/audit/retencion.js.map +1 -0
- package/dist/core/audit/rutas.d.ts +23 -0
- package/dist/core/audit/rutas.d.ts.map +1 -0
- package/dist/core/audit/rutas.js +23 -0
- package/dist/core/audit/rutas.js.map +1 -0
- package/dist/core/auth-storage.d.ts +0 -3
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +21 -8
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/banco/almacenamiento.d.ts +18 -0
- package/dist/core/banco/almacenamiento.d.ts.map +1 -0
- package/dist/core/banco/almacenamiento.js +50 -0
- package/dist/core/banco/almacenamiento.js.map +1 -0
- package/dist/core/banco/analisis.d.ts +37 -0
- package/dist/core/banco/analisis.d.ts.map +1 -0
- package/dist/core/banco/analisis.js +164 -0
- package/dist/core/banco/analisis.js.map +1 -0
- package/dist/core/banco/bloques.d.ts +39 -0
- package/dist/core/banco/bloques.d.ts.map +1 -0
- package/dist/core/banco/bloques.js +84 -0
- package/dist/core/banco/bloques.js.map +1 -0
- package/dist/core/banco/cargas.d.ts +84 -0
- package/dist/core/banco/cargas.d.ts.map +1 -0
- package/dist/core/banco/cargas.js +520 -0
- package/dist/core/banco/cargas.js.map +1 -0
- package/dist/core/banco/comparar.d.ts +29 -0
- package/dist/core/banco/comparar.d.ts.map +1 -0
- package/dist/core/banco/comparar.js +28 -0
- package/dist/core/banco/comparar.js.map +1 -0
- package/dist/core/banco/ejecutar.d.ts +44 -0
- package/dist/core/banco/ejecutar.d.ts.map +1 -0
- package/dist/core/banco/ejecutar.js +183 -0
- package/dist/core/banco/ejecutar.js.map +1 -0
- package/dist/core/banco/generar.d.ts +24 -0
- package/dist/core/banco/generar.d.ts.map +1 -0
- package/dist/core/banco/generar.js +159 -0
- package/dist/core/banco/generar.js.map +1 -0
- package/dist/core/banco/mutaciones.d.ts +25 -0
- package/dist/core/banco/mutaciones.d.ts.map +1 -0
- package/dist/core/banco/mutaciones.js +215 -0
- package/dist/core/banco/mutaciones.js.map +1 -0
- package/dist/core/banco/tipos.d.ts +121 -0
- package/dist/core/banco/tipos.d.ts.map +1 -0
- package/dist/core/banco/tipos.js +16 -0
- package/dist/core/banco/tipos.js.map +1 -0
- package/dist/core/blobs/almacen.d.ts +81 -0
- package/dist/core/blobs/almacen.d.ts.map +1 -0
- package/dist/core/blobs/almacen.js +198 -0
- package/dist/core/blobs/almacen.js.map +1 -0
- package/dist/core/blobs/broker.d.ts +103 -0
- package/dist/core/blobs/broker.d.ts.map +1 -0
- package/dist/core/blobs/broker.js +204 -0
- package/dist/core/blobs/broker.js.map +1 -0
- package/dist/core/blobs/index.d.ts +70 -0
- package/dist/core/blobs/index.d.ts.map +1 -0
- package/dist/core/blobs/index.js +232 -0
- package/dist/core/blobs/index.js.map +1 -0
- package/dist/core/blobs/payload.d.ts +55 -0
- package/dist/core/blobs/payload.d.ts.map +1 -0
- package/dist/core/blobs/payload.js +255 -0
- package/dist/core/blobs/payload.js.map +1 -0
- package/dist/core/blobs/proveedor.d.ts +85 -0
- package/dist/core/blobs/proveedor.d.ts.map +1 -0
- package/dist/core/blobs/proveedor.js +196 -0
- package/dist/core/blobs/proveedor.js.map +1 -0
- package/dist/core/browser/cdp.d.ts +41 -0
- package/dist/core/browser/cdp.d.ts.map +1 -0
- package/dist/core/browser/cdp.js +119 -0
- package/dist/core/browser/cdp.js.map +1 -0
- package/dist/core/browser/politica.d.ts +51 -0
- package/dist/core/browser/politica.d.ts.map +1 -0
- package/dist/core/browser/politica.js +123 -0
- package/dist/core/browser/politica.js.map +1 -0
- package/dist/core/browser/sesion.d.ts +52 -0
- package/dist/core/browser/sesion.d.ts.map +1 -0
- package/dist/core/browser/sesion.js +176 -0
- package/dist/core/browser/sesion.js.map +1 -0
- package/dist/core/browser/tools.d.ts +16 -0
- package/dist/core/browser/tools.d.ts.map +1 -0
- package/dist/core/browser/tools.js +279 -0
- package/dist/core/browser/tools.js.map +1 -0
- package/dist/core/commit/diff.d.ts +56 -0
- package/dist/core/commit/diff.d.ts.map +1 -0
- package/dist/core/commit/diff.js +145 -0
- package/dist/core/commit/diff.js.map +1 -0
- package/dist/core/commit/mensaje.d.ts +80 -0
- package/dist/core/commit/mensaje.d.ts.map +1 -0
- package/dist/core/commit/mensaje.js +207 -0
- package/dist/core/commit/mensaje.js.map +1 -0
- package/dist/core/compactar/index.d.ts +52 -0
- package/dist/core/compactar/index.d.ts.map +1 -0
- package/dist/core/compactar/index.js +91 -0
- package/dist/core/compactar/index.js.map +1 -0
- package/dist/core/compactar/registro-denso.d.ts +160 -0
- package/dist/core/compactar/registro-denso.d.ts.map +1 -0
- package/dist/core/compactar/registro-denso.js +620 -0
- package/dist/core/compactar/registro-denso.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/computer/captura.d.ts +35 -0
- package/dist/core/computer/captura.d.ts.map +1 -0
- package/dist/core/computer/captura.js +140 -0
- package/dist/core/computer/captura.js.map +1 -0
- package/dist/core/computer/driver.d.ts +130 -0
- package/dist/core/computer/driver.d.ts.map +1 -0
- package/dist/core/computer/driver.js +206 -0
- package/dist/core/computer/driver.js.map +1 -0
- package/dist/core/computer/motor/actions.d.ts +109 -0
- package/dist/core/computer/motor/actions.d.ts.map +1 -0
- package/dist/core/computer/motor/actions.js +157 -0
- package/dist/core/computer/motor/actions.js.map +1 -0
- package/dist/core/computer/motor/bridge.d.ts +232 -0
- package/dist/core/computer/motor/bridge.d.ts.map +1 -0
- package/dist/core/computer/motor/bridge.js +2335 -0
- package/dist/core/computer/motor/bridge.js.map +1 -0
- package/dist/core/computer/motor/cdp.d.ts +107 -0
- package/dist/core/computer/motor/cdp.d.ts.map +1 -0
- package/dist/core/computer/motor/cdp.js +659 -0
- package/dist/core/computer/motor/cdp.js.map +1 -0
- package/dist/core/computer/motor/config.d.ts +23 -0
- package/dist/core/computer/motor/config.d.ts.map +1 -0
- package/dist/core/computer/motor/config.js +100 -0
- package/dist/core/computer/motor/config.js.map +1 -0
- package/dist/core/computer/motor/contract.d.ts +81 -0
- package/dist/core/computer/motor/contract.d.ts.map +1 -0
- package/dist/core/computer/motor/contract.js +14 -0
- package/dist/core/computer/motor/contract.js.map +1 -0
- package/dist/core/computer/motor/note.d.ts +37 -0
- package/dist/core/computer/motor/note.d.ts.map +1 -0
- package/dist/core/computer/motor/note.js +162 -0
- package/dist/core/computer/motor/note.js.map +1 -0
- package/dist/core/computer/motor/outline.d.ts +155 -0
- package/dist/core/computer/motor/outline.d.ts.map +1 -0
- package/dist/core/computer/motor/outline.js +590 -0
- package/dist/core/computer/motor/outline.js.map +1 -0
- package/dist/core/computer/motor/output.d.ts +18 -0
- package/dist/core/computer/motor/output.d.ts.map +1 -0
- package/dist/core/computer/motor/output.js +148 -0
- package/dist/core/computer/motor/output.js.map +1 -0
- package/dist/core/computer/motor/permissions.d.ts +41 -0
- package/dist/core/computer/motor/permissions.d.ts.map +1 -0
- package/dist/core/computer/motor/permissions.js +51 -0
- package/dist/core/computer/motor/permissions.js.map +1 -0
- package/dist/core/computer/motor/platform/architecture.d.ts +5 -0
- package/dist/core/computer/motor/platform/architecture.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/architecture.js +21 -0
- package/dist/core/computer/motor/platform/architecture.js.map +1 -0
- package/dist/core/computer/motor/platform/coerce.d.ts +4 -0
- package/dist/core/computer/motor/platform/coerce.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/coerce.js +17 -0
- package/dist/core/computer/motor/platform/coerce.js.map +1 -0
- package/dist/core/computer/motor/platform/index.d.ts +4 -0
- package/dist/core/computer/motor/platform/index.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/index.js +79 -0
- package/dist/core/computer/motor/platform/index.js.map +1 -0
- package/dist/core/computer/motor/platform/linux/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/linux/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/linux/backend.js +173 -0
- package/dist/core/computer/motor/platform/linux/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/linux/helper.d.ts +29 -0
- package/dist/core/computer/motor/platform/linux/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/linux/helper.js +261 -0
- package/dist/core/computer/motor/platform/linux/helper.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/macos/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/backend.js +124 -0
- package/dist/core/computer/motor/platform/macos/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/browser.d.ts +7 -0
- package/dist/core/computer/motor/platform/macos/browser.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/browser.js +101 -0
- package/dist/core/computer/motor/platform/macos/browser.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/helper-path.mjs +34 -0
- package/dist/core/computer/motor/platform/macos/helper.d.ts +32 -0
- package/dist/core/computer/motor/platform/macos/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/helper.js +277 -0
- package/dist/core/computer/motor/platform/macos/helper.js.map +1 -0
- package/dist/core/computer/motor/platform/macos/permissions.d.ts +4 -0
- package/dist/core/computer/motor/platform/macos/permissions.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/macos/permissions.js +118 -0
- package/dist/core/computer/motor/platform/macos/permissions.js.map +1 -0
- package/dist/core/computer/motor/platform/types.d.ts +263 -0
- package/dist/core/computer/motor/platform/types.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/types.js +2 -0
- package/dist/core/computer/motor/platform/types.js.map +1 -0
- package/dist/core/computer/motor/platform/windows/backend.d.ts +3 -0
- package/dist/core/computer/motor/platform/windows/backend.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/windows/backend.js +163 -0
- package/dist/core/computer/motor/platform/windows/backend.js.map +1 -0
- package/dist/core/computer/motor/platform/windows/helper.d.ts +18 -0
- package/dist/core/computer/motor/platform/windows/helper.d.ts.map +1 -0
- package/dist/core/computer/motor/platform/windows/helper.js +174 -0
- package/dist/core/computer/motor/platform/windows/helper.js.map +1 -0
- package/dist/core/computer/motor/root-selection.d.ts +6 -0
- package/dist/core/computer/motor/root-selection.d.ts.map +1 -0
- package/dist/core/computer/motor/root-selection.js +28 -0
- package/dist/core/computer/motor/root-selection.js.map +1 -0
- package/dist/core/computer/motor/runtime.d.ts +50 -0
- package/dist/core/computer/motor/runtime.d.ts.map +1 -0
- package/dist/core/computer/motor/runtime.js +119 -0
- package/dist/core/computer/motor/runtime.js.map +1 -0
- package/dist/core/computer/motor/state.d.ts +68 -0
- package/dist/core/computer/motor/state.d.ts.map +1 -0
- package/dist/core/computer/motor/state.js +100 -0
- package/dist/core/computer/motor/state.js.map +1 -0
- package/dist/core/computer/motor/view.d.ts +6 -0
- package/dist/core/computer/motor/view.d.ts.map +1 -0
- package/dist/core/computer/motor/view.js +185 -0
- package/dist/core/computer/motor/view.js.map +1 -0
- package/dist/core/computer/motor-ada.d.ts +159 -0
- package/dist/core/computer/motor-ada.d.ts.map +1 -0
- package/dist/core/computer/motor-ada.js +412 -0
- package/dist/core/computer/motor-ada.js.map +1 -0
- package/dist/core/computer/politica.d.ts +56 -0
- package/dist/core/computer/politica.d.ts.map +1 -0
- package/dist/core/computer/politica.js +163 -0
- package/dist/core/computer/politica.js.map +1 -0
- package/dist/core/computer/tools.d.ts +26 -0
- package/dist/core/computer/tools.d.ts.map +1 -0
- package/dist/core/computer/tools.js +399 -0
- package/dist/core/computer/tools.js.map +1 -0
- package/dist/core/context-breakdown.d.ts +80 -0
- package/dist/core/context-breakdown.d.ts.map +1 -0
- package/dist/core/context-breakdown.js +87 -0
- package/dist/core/context-breakdown.js.map +1 -0
- package/dist/core/credenciales/cliente.d.ts +60 -0
- package/dist/core/credenciales/cliente.d.ts.map +1 -0
- package/dist/core/credenciales/cliente.js +81 -0
- package/dist/core/credenciales/cliente.js.map +1 -0
- package/dist/core/credenciales/pool.d.ts +96 -0
- package/dist/core/credenciales/pool.d.ts.map +1 -0
- package/dist/core/credenciales/pool.js +128 -0
- package/dist/core/credenciales/pool.js.map +1 -0
- package/dist/core/credenciales/reposo.d.ts +93 -0
- package/dist/core/credenciales/reposo.d.ts.map +1 -0
- package/dist/core/credenciales/reposo.js +489 -0
- package/dist/core/credenciales/reposo.js.map +1 -0
- package/dist/core/credenciales/servidor.d.ts +55 -0
- package/dist/core/credenciales/servidor.d.ts.map +1 -0
- package/dist/core/credenciales/servidor.js +205 -0
- package/dist/core/credenciales/servidor.js.map +1 -0
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/descubrimiento/comandos.d.ts +30 -0
- package/dist/core/descubrimiento/comandos.d.ts.map +1 -0
- package/dist/core/descubrimiento/comandos.js +76 -0
- package/dist/core/descubrimiento/comandos.js.map +1 -0
- package/dist/core/descubrimiento/mcp.d.ts +42 -0
- package/dist/core/descubrimiento/mcp.d.ts.map +1 -0
- package/dist/core/descubrimiento/mcp.js +130 -0
- package/dist/core/descubrimiento/mcp.js.map +1 -0
- package/dist/core/descubrimiento/reglas.d.ts +61 -0
- package/dist/core/descubrimiento/reglas.d.ts.map +1 -0
- package/dist/core/descubrimiento/reglas.js +134 -0
- package/dist/core/descubrimiento/reglas.js.map +1 -0
- package/dist/core/descubrimiento/skills.d.ts +57 -0
- package/dist/core/descubrimiento/skills.d.ts.map +1 -0
- package/dist/core/descubrimiento/skills.js +113 -0
- package/dist/core/descubrimiento/skills.js.map +1 -0
- package/dist/core/dificultad/clasificador.d.ts +133 -0
- package/dist/core/dificultad/clasificador.d.ts.map +1 -0
- package/dist/core/dificultad/clasificador.js +288 -0
- package/dist/core/dificultad/clasificador.js.map +1 -0
- package/dist/core/edicion/diario.d.ts +37 -0
- package/dist/core/edicion/diario.d.ts.map +1 -0
- package/dist/core/edicion/diario.js +51 -0
- package/dist/core/edicion/diario.js.map +1 -0
- package/dist/core/edicion/hashline.d.ts +71 -0
- package/dist/core/edicion/hashline.d.ts.map +1 -0
- package/dist/core/edicion/hashline.js +111 -0
- package/dist/core/edicion/hashline.js.map +1 -0
- package/dist/core/edicion/hueco.d.ts +64 -0
- package/dist/core/edicion/hueco.d.ts.map +1 -0
- package/dist/core/edicion/hueco.js +162 -0
- package/dist/core/edicion/hueco.js.map +1 -0
- package/dist/core/edicion/limpiar-carga.d.ts +39 -0
- package/dist/core/edicion/limpiar-carga.d.ts.map +1 -0
- package/dist/core/edicion/limpiar-carga.js +121 -0
- package/dist/core/edicion/limpiar-carga.js.map +1 -0
- package/dist/core/edicion/observador.d.ts +80 -0
- package/dist/core/edicion/observador.d.ts.map +1 -0
- package/dist/core/edicion/observador.js +183 -0
- package/dist/core/edicion/observador.js.map +1 -0
- package/dist/core/edicion/parecido.d.ts +53 -0
- package/dist/core/edicion/parecido.d.ts.map +1 -0
- package/dist/core/edicion/parecido.js +145 -0
- package/dist/core/edicion/parecido.js.map +1 -0
- package/dist/core/edicion/parseo.d.ts +58 -0
- package/dist/core/edicion/parseo.d.ts.map +1 -0
- package/dist/core/edicion/parseo.js +124 -0
- package/dist/core/edicion/parseo.js.map +1 -0
- package/dist/core/edicion/reparacion.d.ts +67 -0
- package/dist/core/edicion/reparacion.d.ts.map +1 -0
- package/dist/core/edicion/reparacion.js +202 -0
- package/dist/core/edicion/reparacion.js.map +1 -0
- package/dist/core/edicion/sangria.d.ts +121 -0
- package/dist/core/edicion/sangria.d.ts.map +1 -0
- package/dist/core/edicion/sangria.js +341 -0
- package/dist/core/edicion/sangria.js.map +1 -0
- package/dist/core/edicion/tipos.d.ts +58 -0
- package/dist/core/edicion/tipos.d.ts.map +1 -0
- package/dist/core/edicion/tipos.js +160 -0
- package/dist/core/edicion/tipos.js.map +1 -0
- package/dist/core/engine-personality.d.ts +12 -0
- package/dist/core/engine-personality.d.ts.map +1 -0
- package/dist/core/engine-personality.js +53 -0
- package/dist/core/engine-personality.js.map +1 -0
- package/dist/core/errores/proveedor.d.ts +53 -0
- package/dist/core/errores/proveedor.d.ts.map +1 -0
- package/dist/core/errores/proveedor.js +191 -0
- package/dist/core/errores/proveedor.js.map +1 -0
- package/dist/core/estructural/buscar.d.ts +61 -0
- package/dist/core/estructural/buscar.d.ts.map +1 -0
- package/dist/core/estructural/buscar.js +261 -0
- package/dist/core/estructural/buscar.js.map +1 -0
- package/dist/core/estructural/editar.d.ts +36 -0
- package/dist/core/estructural/editar.d.ts.map +1 -0
- package/dist/core/estructural/editar.js +123 -0
- package/dist/core/estructural/editar.js.map +1 -0
- package/dist/core/estructural/tools.d.ts +11 -0
- package/dist/core/estructural/tools.d.ts.map +1 -0
- package/dist/core/estructural/tools.js +100 -0
- package/dist/core/estructural/tools.js.map +1 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +10 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensiones/suplantacion.d.ts +49 -0
- package/dist/core/extensiones/suplantacion.d.ts.map +1 -0
- package/dist/core/extensiones/suplantacion.js +61 -0
- package/dist/core/extensiones/suplantacion.js.map +1 -0
- package/dist/core/extensiones/vigilancia.d.ts +54 -0
- package/dist/core/extensiones/vigilancia.d.ts.map +1 -0
- package/dist/core/extensiones/vigilancia.js +217 -0
- package/dist/core/extensiones/vigilancia.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +21 -6
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/harness/fuentes-de-contexto.d.ts +29 -0
- package/dist/core/harness/fuentes-de-contexto.d.ts.map +1 -0
- package/dist/core/harness/fuentes-de-contexto.js +44 -0
- package/dist/core/harness/fuentes-de-contexto.js.map +1 -0
- package/dist/core/harness/refine.d.ts +40 -0
- package/dist/core/harness/refine.d.ts.map +1 -0
- package/dist/core/harness/refine.js +109 -0
- package/dist/core/harness/refine.js.map +1 -0
- package/dist/core/harness/store.d.ts +75 -0
- package/dist/core/harness/store.d.ts.map +1 -0
- package/dist/core/harness/store.js +149 -0
- package/dist/core/harness/store.js.map +1 -0
- package/dist/core/hooks/contract.d.ts +85 -0
- package/dist/core/hooks/contract.d.ts.map +1 -0
- package/dist/core/hooks/contract.js +140 -0
- package/dist/core/hooks/contract.js.map +1 -0
- package/dist/core/hooks/runner.d.ts +42 -0
- package/dist/core/hooks/runner.d.ts.map +1 -0
- package/dist/core/hooks/runner.js +85 -0
- package/dist/core/hooks/runner.js.map +1 -0
- package/dist/core/hooks/session-hooks.d.ts +62 -0
- package/dist/core/hooks/session-hooks.d.ts.map +1 -0
- package/dist/core/hooks/session-hooks.js +84 -0
- package/dist/core/hooks/session-hooks.js.map +1 -0
- package/dist/core/importar/formatos.d.ts +69 -0
- package/dist/core/importar/formatos.d.ts.map +1 -0
- package/dist/core/importar/formatos.js +235 -0
- package/dist/core/importar/formatos.js.map +1 -0
- package/dist/core/interactivo/deteccion.d.ts +44 -0
- package/dist/core/interactivo/deteccion.d.ts.map +1 -0
- package/dist/core/interactivo/deteccion.js +82 -0
- package/dist/core/interactivo/deteccion.js.map +1 -0
- package/dist/core/interactivo/sesion.d.ts +50 -0
- package/dist/core/interactivo/sesion.d.ts.map +1 -0
- package/dist/core/interactivo/sesion.js +156 -0
- package/dist/core/interactivo/sesion.js.map +1 -0
- package/dist/core/interactivo/tools.d.ts +21 -0
- package/dist/core/interactivo/tools.d.ts.map +1 -0
- package/dist/core/interactivo/tools.js +122 -0
- package/dist/core/interactivo/tools.js.map +1 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lectura/mapa.d.ts +70 -0
- package/dist/core/lectura/mapa.d.ts.map +1 -0
- package/dist/core/lectura/mapa.js +177 -0
- package/dist/core/lectura/mapa.js.map +1 -0
- package/dist/core/lectura/pdf.d.ts +49 -0
- package/dist/core/lectura/pdf.d.ts.map +1 -0
- package/dist/core/lectura/pdf.js +337 -0
- package/dist/core/lectura/pdf.js.map +1 -0
- package/dist/core/limpieza/comprobadores.d.ts +28 -0
- package/dist/core/limpieza/comprobadores.d.ts.map +1 -0
- package/dist/core/limpieza/comprobadores.js +311 -0
- package/dist/core/limpieza/comprobadores.js.map +1 -0
- package/dist/core/limpieza/parseo.d.ts +19 -0
- package/dist/core/limpieza/parseo.d.ts.map +1 -0
- package/dist/core/limpieza/parseo.js +124 -0
- package/dist/core/limpieza/parseo.js.map +1 -0
- package/dist/core/limpieza/reparacion.d.ts +77 -0
- package/dist/core/limpieza/reparacion.d.ts.map +1 -0
- package/dist/core/limpieza/reparacion.js +254 -0
- package/dist/core/limpieza/reparacion.js.map +1 -0
- package/dist/core/limpieza/tipos.d.ts +56 -0
- package/dist/core/limpieza/tipos.d.ts.map +1 -0
- package/dist/core/limpieza/tipos.js +9 -0
- package/dist/core/limpieza/tipos.js.map +1 -0
- package/dist/core/lsp/cliente.d.ts +52 -0
- package/dist/core/lsp/cliente.d.ts.map +1 -0
- package/dist/core/lsp/cliente.js +232 -0
- package/dist/core/lsp/cliente.js.map +1 -0
- package/dist/core/lsp/descubrimiento.d.ts +62 -0
- package/dist/core/lsp/descubrimiento.d.ts.map +1 -0
- package/dist/core/lsp/descubrimiento.js +152 -0
- package/dist/core/lsp/descubrimiento.js.map +1 -0
- package/dist/core/lsp/ediciones.d.ts +59 -0
- package/dist/core/lsp/ediciones.d.ts.map +1 -0
- package/dist/core/lsp/ediciones.js +89 -0
- package/dist/core/lsp/ediciones.js.map +1 -0
- package/dist/core/lsp/extension.d.ts +28 -0
- package/dist/core/lsp/extension.d.ts.map +1 -0
- package/dist/core/lsp/extension.js +34 -0
- package/dist/core/lsp/extension.js.map +1 -0
- package/dist/core/lsp/tools.d.ts +45 -0
- package/dist/core/lsp/tools.d.ts.map +1 -0
- package/dist/core/lsp/tools.js +265 -0
- package/dist/core/lsp/tools.js.map +1 -0
- package/dist/core/mcp/client.d.ts +60 -0
- package/dist/core/mcp/client.d.ts.map +1 -0
- package/dist/core/mcp/client.js +139 -0
- package/dist/core/mcp/client.js.map +1 -0
- package/dist/core/mcp/manager.d.ts +86 -0
- package/dist/core/mcp/manager.d.ts.map +1 -0
- package/dist/core/mcp/manager.js +124 -0
- package/dist/core/mcp/manager.js.map +1 -0
- package/dist/core/mcp/tools.d.ts +15 -0
- package/dist/core/mcp/tools.d.ts.map +1 -0
- package/dist/core/mcp/tools.js +84 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/memory-engine/audit-export.d.ts +56 -0
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-export.js +100 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -0
- package/dist/core/memory-engine/audit-indice.d.ts +153 -0
- package/dist/core/memory-engine/audit-indice.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-indice.js +271 -0
- package/dist/core/memory-engine/audit-indice.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts +18 -6
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +32 -50
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +21 -4
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +219 -55
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/inverted-index.d.ts.map +1 -1
- package/dist/core/memory-engine/inverted-index.js +67 -10
- package/dist/core/memory-engine/inverted-index.js.map +1 -1
- package/dist/core/memory-engine/keychain.d.ts.map +1 -1
- package/dist/core/memory-engine/keychain.js +1 -6
- package/dist/core/memory-engine/keychain.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +0 -1
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +40 -12
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/refinements.d.ts +51 -0
- package/dist/core/memory-engine/refinements.d.ts.map +1 -0
- package/dist/core/memory-engine/refinements.js +99 -0
- package/dist/core/memory-engine/refinements.js.map +1 -0
- package/dist/core/memory-engine/scanner.d.ts.map +1 -1
- package/dist/core/memory-engine/scanner.js +25 -5
- package/dist/core/memory-engine/scanner.js.map +1 -1
- package/dist/core/memory-engine/security.d.ts.map +1 -1
- package/dist/core/memory-engine/security.js +131 -23
- package/dist/core/memory-engine/security.js.map +1 -1
- package/dist/core/memory-engine/session-indexer.d.ts.map +1 -1
- package/dist/core/memory-engine/session-indexer.js +8 -2
- package/dist/core/memory-engine/session-indexer.js.map +1 -1
- package/dist/core/memory-engine/tools.d.ts +2 -2
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +41 -8
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/types.d.ts +2 -0
- package/dist/core/memory-engine/types.d.ts.map +1 -1
- package/dist/core/memory-engine/types.js.map +1 -1
- package/dist/core/memory-engine/vault.d.ts.map +1 -1
- package/dist/core/memory-engine/vault.js +2 -2
- package/dist/core/memory-engine/vault.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +19 -7
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/muestreo-restringido.d.ts +49 -0
- package/dist/core/muestreo-restringido.d.ts.map +1 -0
- package/dist/core/muestreo-restringido.js +65 -0
- package/dist/core/muestreo-restringido.js.map +1 -0
- package/dist/core/orphan-process-journal.d.ts +48 -0
- package/dist/core/orphan-process-journal.d.ts.map +1 -0
- package/dist/core/orphan-process-journal.js +116 -0
- package/dist/core/orphan-process-journal.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/privacidad/categorias-especiales.d.ts +186 -0
- package/dist/core/privacidad/categorias-especiales.d.ts.map +1 -0
- package/dist/core/privacidad/categorias-especiales.js +745 -0
- package/dist/core/privacidad/categorias-especiales.js.map +1 -0
- package/dist/core/privacidad/tapar.d.ts +48 -0
- package/dist/core/privacidad/tapar.d.ts.map +1 -0
- package/dist/core/privacidad/tapar.js +66 -0
- package/dist/core/privacidad/tapar.js.map +1 -0
- package/dist/core/prompt-cache/diagnostics.d.ts +33 -0
- package/dist/core/prompt-cache/diagnostics.d.ts.map +1 -0
- package/dist/core/prompt-cache/diagnostics.js +100 -0
- package/dist/core/prompt-cache/diagnostics.js.map +1 -0
- package/dist/core/prompt-cache/index.d.ts +33 -0
- package/dist/core/prompt-cache/index.d.ts.map +1 -0
- package/dist/core/prompt-cache/index.js +189 -0
- package/dist/core/prompt-cache/index.js.map +1 -0
- package/dist/core/prompt-cache/payload.d.ts +58 -0
- package/dist/core/prompt-cache/payload.d.ts.map +1 -0
- package/dist/core/prompt-cache/payload.js +122 -0
- package/dist/core/prompt-cache/payload.js.map +1 -0
- package/dist/core/prompt-cache/stabilize.d.ts +65 -0
- package/dist/core/prompt-cache/stabilize.d.ts.map +1 -0
- package/dist/core/prompt-cache/stabilize.js +137 -0
- package/dist/core/prompt-cache/stabilize.js.map +1 -0
- package/dist/core/prompt-cache/stats.d.ts +55 -0
- package/dist/core/prompt-cache/stats.d.ts.map +1 -0
- package/dist/core/prompt-cache/stats.js +158 -0
- package/dist/core/prompt-cache/stats.js.map +1 -0
- package/dist/core/prompt-eleccion.d.ts +38 -0
- package/dist/core/prompt-eleccion.d.ts.map +1 -0
- package/dist/core/prompt-eleccion.js +46 -0
- package/dist/core/prompt-eleccion.js.map +1 -0
- package/dist/core/prompt-optimizer.d.ts +53 -0
- package/dist/core/prompt-optimizer.d.ts.map +1 -0
- package/dist/core/prompt-optimizer.js +138 -0
- package/dist/core/prompt-optimizer.js.map +1 -0
- package/dist/core/prompts/montar.d.ts +75 -0
- package/dist/core/prompts/montar.d.ts.map +1 -0
- package/dist/core/prompts/montar.js +146 -0
- package/dist/core/prompts/montar.js.map +1 -0
- package/dist/core/prompts/plantilla.d.ts +54 -0
- package/dist/core/prompts/plantilla.d.ts.map +1 -0
- package/dist/core/prompts/plantilla.js +153 -0
- package/dist/core/prompts/plantilla.js.map +1 -0
- package/dist/core/prompts/sistema.md +134 -0
- package/dist/core/provider-attribution.d.ts +24 -2
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +24 -42
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/remoto/destino.d.ts +38 -0
- package/dist/core/remoto/destino.d.ts.map +1 -0
- package/dist/core/remoto/destino.js +105 -0
- package/dist/core/remoto/destino.js.map +1 -0
- package/dist/core/remoto/ejecutor.d.ts +59 -0
- package/dist/core/remoto/ejecutor.d.ts.map +1 -0
- package/dist/core/remoto/ejecutor.js +225 -0
- package/dist/core/remoto/ejecutor.js.map +1 -0
- package/dist/core/remoto/ficheros.d.ts +29 -0
- package/dist/core/remoto/ficheros.d.ts.map +1 -0
- package/dist/core/remoto/ficheros.js +90 -0
- package/dist/core/remoto/ficheros.js.map +1 -0
- package/dist/core/remoto/registro-extension.d.ts +15 -0
- package/dist/core/remoto/registro-extension.d.ts.map +1 -0
- package/dist/core/remoto/registro-extension.js +17 -0
- package/dist/core/remoto/registro-extension.js.map +1 -0
- package/dist/core/remoto/tools.d.ts +28 -0
- package/dist/core/remoto/tools.d.ts.map +1 -0
- package/dist/core/remoto/tools.js +31 -0
- package/dist/core/remoto/tools.js.map +1 -0
- package/dist/core/resource-loader.d.ts +58 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +326 -8
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/revision/hallazgo.d.ts +51 -0
- package/dist/core/revision/hallazgo.d.ts.map +1 -0
- package/dist/core/revision/hallazgo.js +73 -0
- package/dist/core/revision/hallazgo.js.map +1 -0
- package/dist/core/revision/revisor.d.ts +81 -0
- package/dist/core/revision/revisor.d.ts.map +1 -0
- package/dist/core/revision/revisor.js +132 -0
- package/dist/core/revision/revisor.js.map +1 -0
- package/dist/core/revision/sarif.d.ts +30 -0
- package/dist/core/revision/sarif.d.ts.map +1 -0
- package/dist/core/revision/sarif.js +83 -0
- package/dist/core/revision/sarif.js.map +1 -0
- package/dist/core/scheduler/scheduler.d.ts +87 -0
- package/dist/core/scheduler/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler/scheduler.js +178 -0
- package/dist/core/scheduler/scheduler.js.map +1 -0
- package/dist/core/sdk.d.ts +8 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/sesion/cerrar-llamadas-abiertas.d.ts +49 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.d.ts.map +1 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.js +77 -0
- package/dist/core/sesion/cerrar-llamadas-abiertas.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +156 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +255 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +17 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +13 -5
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetria/otlp.d.ts +122 -0
- package/dist/core/telemetria/otlp.d.ts.map +1 -0
- package/dist/core/telemetria/otlp.js +373 -0
- package/dist/core/telemetria/otlp.js.map +1 -0
- package/dist/core/tools/coercion-argumentos.d.ts +48 -0
- package/dist/core/tools/coercion-argumentos.d.ts.map +1 -0
- package/dist/core/tools/coercion-argumentos.js +99 -0
- package/dist/core/tools/coercion-argumentos.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +0 -12
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +234 -12
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +28 -5
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +5 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +2 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/json-tolerante.d.ts +30 -0
- package/dist/core/tools/json-tolerante.d.ts.map +1 -0
- package/dist/core/tools/json-tolerante.js +70 -0
- package/dist/core/tools/json-tolerante.js.map +1 -0
- package/dist/core/tools/project-memory-tool.d.ts.map +1 -1
- package/dist/core/tools/project-memory-tool.js +4 -1
- package/dist/core/tools/project-memory-tool.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +17 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +17 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/turno-vacio/detectar.d.ts +38 -0
- package/dist/core/turno-vacio/detectar.d.ts.map +1 -0
- package/dist/core/turno-vacio/detectar.js +66 -0
- package/dist/core/turno-vacio/detectar.js.map +1 -0
- package/dist/core/undo/journal.d.ts +57 -0
- package/dist/core/undo/journal.d.ts.map +1 -0
- package/dist/core/undo/journal.js +178 -0
- package/dist/core/undo/journal.js.map +1 -0
- package/dist/core/urls-internas/auditoria.d.ts +10 -0
- package/dist/core/urls-internas/auditoria.d.ts.map +1 -0
- package/dist/core/urls-internas/auditoria.js +42 -0
- package/dist/core/urls-internas/auditoria.js.map +1 -0
- package/dist/core/urls-internas/boveda.d.ts +13 -0
- package/dist/core/urls-internas/boveda.d.ts.map +1 -0
- package/dist/core/urls-internas/boveda.js +40 -0
- package/dist/core/urls-internas/boveda.js.map +1 -0
- package/dist/core/urls-internas/lector.d.ts +30 -0
- package/dist/core/urls-internas/lector.d.ts.map +1 -0
- package/dist/core/urls-internas/lector.js +56 -0
- package/dist/core/urls-internas/lector.js.map +1 -0
- package/dist/core/urls-internas/memoria.d.ts +11 -0
- package/dist/core/urls-internas/memoria.d.ts.map +1 -0
- package/dist/core/urls-internas/memoria.js +25 -0
- package/dist/core/urls-internas/memoria.js.map +1 -0
- package/dist/core/urls-internas/parse.d.ts +28 -0
- package/dist/core/urls-internas/parse.d.ts.map +1 -0
- package/dist/core/urls-internas/parse.js +32 -0
- package/dist/core/urls-internas/parse.js.map +1 -0
- package/dist/core/urls-internas/reglas.d.ts +10 -0
- package/dist/core/urls-internas/reglas.d.ts.map +1 -0
- package/dist/core/urls-internas/reglas.js +31 -0
- package/dist/core/urls-internas/reglas.js.map +1 -0
- package/dist/core/usage/aggregate.d.ts +68 -0
- package/dist/core/usage/aggregate.d.ts.map +1 -0
- package/dist/core/usage/aggregate.js +93 -0
- package/dist/core/usage/aggregate.js.map +1 -0
- package/dist/core/usage/cuota/anthropic.d.ts +10 -0
- package/dist/core/usage/cuota/anthropic.d.ts.map +1 -0
- package/dist/core/usage/cuota/anthropic.js +63 -0
- package/dist/core/usage/cuota/anthropic.js.map +1 -0
- package/dist/core/usage/cuota/cache.d.ts +20 -0
- package/dist/core/usage/cuota/cache.d.ts.map +1 -0
- package/dist/core/usage/cuota/cache.js +36 -0
- package/dist/core/usage/cuota/cache.js.map +1 -0
- package/dist/core/usage/cuota/github-copilot.d.ts +9 -0
- package/dist/core/usage/cuota/github-copilot.d.ts.map +1 -0
- package/dist/core/usage/cuota/github-copilot.js +67 -0
- package/dist/core/usage/cuota/github-copilot.js.map +1 -0
- package/dist/core/usage/cuota/google-gemini.d.ts +9 -0
- package/dist/core/usage/cuota/google-gemini.d.ts.map +1 -0
- package/dist/core/usage/cuota/google-gemini.js +72 -0
- package/dist/core/usage/cuota/google-gemini.js.map +1 -0
- package/dist/core/usage/cuota/index.d.ts +25 -0
- package/dist/core/usage/cuota/index.d.ts.map +1 -0
- package/dist/core/usage/cuota/index.js +50 -0
- package/dist/core/usage/cuota/index.js.map +1 -0
- package/dist/core/usage/cuota/openai-codex.d.ts +9 -0
- package/dist/core/usage/cuota/openai-codex.d.ts.map +1 -0
- package/dist/core/usage/cuota/openai-codex.js +59 -0
- package/dist/core/usage/cuota/openai-codex.js.map +1 -0
- package/dist/core/usage/cuota/openrouter.d.ts +10 -0
- package/dist/core/usage/cuota/openrouter.d.ts.map +1 -0
- package/dist/core/usage/cuota/openrouter.js +47 -0
- package/dist/core/usage/cuota/openrouter.js.map +1 -0
- package/dist/core/usage/cuota/tipos.d.ts +50 -0
- package/dist/core/usage/cuota/tipos.d.ts.map +1 -0
- package/dist/core/usage/cuota/tipos.js +25 -0
- package/dist/core/usage/cuota/tipos.js.map +1 -0
- package/dist/core/web/busqueda-nativa.d.ts +82 -0
- package/dist/core/web/busqueda-nativa.d.ts.map +1 -0
- package/dist/core/web/busqueda-nativa.js +163 -0
- package/dist/core/web/busqueda-nativa.js.map +1 -0
- package/dist/core/web/destino.d.ts +58 -0
- package/dist/core/web/destino.d.ts.map +1 -0
- package/dist/core/web/destino.js +127 -0
- package/dist/core/web/destino.js.map +1 -0
- package/dist/core/web/proveedores/brave.d.ts +6 -0
- package/dist/core/web/proveedores/brave.d.ts.map +1 -0
- package/dist/core/web/proveedores/brave.js +20 -0
- package/dist/core/web/proveedores/brave.js.map +1 -0
- package/dist/core/web/proveedores/claves.d.ts +19 -0
- package/dist/core/web/proveedores/claves.d.ts.map +1 -0
- package/dist/core/web/proveedores/claves.js +36 -0
- package/dist/core/web/proveedores/claves.js.map +1 -0
- package/dist/core/web/proveedores/duckduckgo.d.ts +3 -0
- package/dist/core/web/proveedores/duckduckgo.d.ts.map +1 -0
- package/dist/core/web/proveedores/duckduckgo.js +109 -0
- package/dist/core/web/proveedores/duckduckgo.js.map +1 -0
- package/dist/core/web/proveedores/ecosia.d.ts +3 -0
- package/dist/core/web/proveedores/ecosia.d.ts.map +1 -0
- package/dist/core/web/proveedores/ecosia.js +72 -0
- package/dist/core/web/proveedores/ecosia.js.map +1 -0
- package/dist/core/web/proveedores/exa.d.ts +6 -0
- package/dist/core/web/proveedores/exa.d.ts.map +1 -0
- package/dist/core/web/proveedores/exa.js +24 -0
- package/dist/core/web/proveedores/exa.js.map +1 -0
- package/dist/core/web/proveedores/mojeek.d.ts +3 -0
- package/dist/core/web/proveedores/mojeek.d.ts.map +1 -0
- package/dist/core/web/proveedores/mojeek.js +65 -0
- package/dist/core/web/proveedores/mojeek.js.map +1 -0
- package/dist/core/web/proveedores/navegador.d.ts +10 -0
- package/dist/core/web/proveedores/navegador.d.ts.map +1 -0
- package/dist/core/web/proveedores/navegador.js +13 -0
- package/dist/core/web/proveedores/navegador.js.map +1 -0
- package/dist/core/web/proveedores/registro.d.ts +43 -0
- package/dist/core/web/proveedores/registro.d.ts.map +1 -0
- package/dist/core/web/proveedores/registro.js +49 -0
- package/dist/core/web/proveedores/registro.js.map +1 -0
- package/dist/core/web/proveedores/searxng.d.ts +9 -0
- package/dist/core/web/proveedores/searxng.d.ts.map +1 -0
- package/dist/core/web/proveedores/searxng.js +17 -0
- package/dist/core/web/proveedores/searxng.js.map +1 -0
- package/dist/core/web/proveedores/serper.d.ts +9 -0
- package/dist/core/web/proveedores/serper.d.ts.map +1 -0
- package/dist/core/web/proveedores/serper.js +19 -0
- package/dist/core/web/proveedores/serper.js.map +1 -0
- package/dist/core/web/proveedores/tavily.d.ts +6 -0
- package/dist/core/web/proveedores/tavily.d.ts.map +1 -0
- package/dist/core/web/proveedores/tavily.js +19 -0
- package/dist/core/web/proveedores/tavily.js.map +1 -0
- package/dist/core/web/proveedores/tipos.d.ts +36 -0
- package/dist/core/web/proveedores/tipos.d.ts.map +1 -0
- package/dist/core/web/proveedores/tipos.js +10 -0
- package/dist/core/web/proveedores/tipos.js.map +1 -0
- package/dist/core/web/registro-red.d.ts +43 -0
- package/dist/core/web/registro-red.d.ts.map +1 -0
- package/dist/core/web/registro-red.js +86 -0
- package/dist/core/web/registro-red.js.map +1 -0
- package/dist/core/web/scrapers/cisa-kev.d.ts +10 -0
- package/dist/core/web/scrapers/cisa-kev.d.ts.map +1 -0
- package/dist/core/web/scrapers/cisa-kev.js +38 -0
- package/dist/core/web/scrapers/cisa-kev.js.map +1 -0
- package/dist/core/web/scrapers/crates-io.d.ts +11 -0
- package/dist/core/web/scrapers/crates-io.d.ts.map +1 -0
- package/dist/core/web/scrapers/crates-io.js +29 -0
- package/dist/core/web/scrapers/crates-io.js.map +1 -0
- package/dist/core/web/scrapers/docs-rs.d.ts +10 -0
- package/dist/core/web/scrapers/docs-rs.d.ts.map +1 -0
- package/dist/core/web/scrapers/docs-rs.js +35 -0
- package/dist/core/web/scrapers/docs-rs.js.map +1 -0
- package/dist/core/web/scrapers/github.d.ts +3 -0
- package/dist/core/web/scrapers/github.d.ts.map +1 -0
- package/dist/core/web/scrapers/github.js +72 -0
- package/dist/core/web/scrapers/github.js.map +1 -0
- package/dist/core/web/scrapers/go-pkg.d.ts +7 -0
- package/dist/core/web/scrapers/go-pkg.d.ts.map +1 -0
- package/dist/core/web/scrapers/go-pkg.js +30 -0
- package/dist/core/web/scrapers/go-pkg.js.map +1 -0
- package/dist/core/web/scrapers/hex.d.ts +6 -0
- package/dist/core/web/scrapers/hex.d.ts.map +1 -0
- package/dist/core/web/scrapers/hex.js +27 -0
- package/dist/core/web/scrapers/hex.js.map +1 -0
- package/dist/core/web/scrapers/maven.d.ts +8 -0
- package/dist/core/web/scrapers/maven.d.ts.map +1 -0
- package/dist/core/web/scrapers/maven.js +41 -0
- package/dist/core/web/scrapers/maven.js.map +1 -0
- package/dist/core/web/scrapers/mdn.d.ts +6 -0
- package/dist/core/web/scrapers/mdn.d.ts.map +1 -0
- package/dist/core/web/scrapers/mdn.js +28 -0
- package/dist/core/web/scrapers/mdn.js.map +1 -0
- package/dist/core/web/scrapers/npm.d.ts +11 -0
- package/dist/core/web/scrapers/npm.d.ts.map +1 -0
- package/dist/core/web/scrapers/npm.js +57 -0
- package/dist/core/web/scrapers/npm.js.map +1 -0
- package/dist/core/web/scrapers/nuget.d.ts +8 -0
- package/dist/core/web/scrapers/nuget.d.ts.map +1 -0
- package/dist/core/web/scrapers/nuget.js +22 -0
- package/dist/core/web/scrapers/nuget.js.map +1 -0
- package/dist/core/web/scrapers/nvd.d.ts +7 -0
- package/dist/core/web/scrapers/nvd.d.ts.map +1 -0
- package/dist/core/web/scrapers/nvd.js +37 -0
- package/dist/core/web/scrapers/nvd.js.map +1 -0
- package/dist/core/web/scrapers/pypi.d.ts +6 -0
- package/dist/core/web/scrapers/pypi.d.ts.map +1 -0
- package/dist/core/web/scrapers/pypi.js +31 -0
- package/dist/core/web/scrapers/pypi.js.map +1 -0
- package/dist/core/web/scrapers/registro.d.ts +13 -0
- package/dist/core/web/scrapers/registro.d.ts.map +1 -0
- package/dist/core/web/scrapers/registro.js +65 -0
- package/dist/core/web/scrapers/registro.js.map +1 -0
- package/dist/core/web/scrapers/rubygems.d.ts +6 -0
- package/dist/core/web/scrapers/rubygems.d.ts.map +1 -0
- package/dist/core/web/scrapers/rubygems.js +23 -0
- package/dist/core/web/scrapers/rubygems.js.map +1 -0
- package/dist/core/web/scrapers/stackoverflow.d.ts +3 -0
- package/dist/core/web/scrapers/stackoverflow.d.ts.map +1 -0
- package/dist/core/web/scrapers/stackoverflow.js +46 -0
- package/dist/core/web/scrapers/stackoverflow.js.map +1 -0
- package/dist/core/web/scrapers/tipos.d.ts +42 -0
- package/dist/core/web/scrapers/tipos.d.ts.map +1 -0
- package/dist/core/web/scrapers/tipos.js +23 -0
- package/dist/core/web/scrapers/tipos.js.map +1 -0
- package/dist/core/web/texto.d.ts +10 -0
- package/dist/core/web/texto.d.ts.map +1 -0
- package/dist/core/web/texto.js +26 -0
- package/dist/core/web/texto.js.map +1 -0
- package/dist/core/web/tools.d.ts +91 -0
- package/dist/core/web/tools.d.ts.map +1 -0
- package/dist/core/web/tools.js +304 -0
- package/dist/core/web/tools.js.map +1 -0
- package/dist/core/wiki/almacen.d.ts +33 -0
- package/dist/core/wiki/almacen.d.ts.map +1 -0
- package/dist/core/wiki/almacen.js +93 -0
- package/dist/core/wiki/almacen.js.map +1 -0
- package/dist/core/wiki/citas.d.ts +111 -0
- package/dist/core/wiki/citas.d.ts.map +1 -0
- package/dist/core/wiki/citas.js +146 -0
- package/dist/core/wiki/citas.js.map +1 -0
- package/dist/core/workflows/agent-runner.d.ts +88 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -0
- package/dist/core/workflows/agent-runner.js +312 -0
- package/dist/core/workflows/agent-runner.js.map +1 -0
- package/dist/core/workflows/builtins.d.ts +41 -0
- package/dist/core/workflows/builtins.d.ts.map +1 -0
- package/dist/core/workflows/builtins.js +283 -0
- package/dist/core/workflows/builtins.js.map +1 -0
- package/dist/core/workflows/contrato/esquema.d.ts +32 -0
- package/dist/core/workflows/contrato/esquema.d.ts.map +1 -0
- package/dist/core/workflows/contrato/esquema.js +25 -0
- package/dist/core/workflows/contrato/esquema.js.map +1 -0
- package/dist/core/workflows/contrato/reparar-argumentos.d.ts +69 -0
- package/dist/core/workflows/contrato/reparar-argumentos.d.ts.map +1 -0
- package/dist/core/workflows/contrato/reparar-argumentos.js +117 -0
- package/dist/core/workflows/contrato/reparar-argumentos.js.map +1 -0
- package/dist/core/workflows/contrato/validador.d.ts +30 -0
- package/dist/core/workflows/contrato/validador.d.ts.map +1 -0
- package/dist/core/workflows/contrato/validador.js +56 -0
- package/dist/core/workflows/contrato/validador.js.map +1 -0
- package/dist/core/workflows/contrato/yield.d.ts +65 -0
- package/dist/core/workflows/contrato/yield.d.ts.map +1 -0
- package/dist/core/workflows/contrato/yield.js +80 -0
- package/dist/core/workflows/contrato/yield.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +151 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/engine.js +503 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -0
- package/dist/core/workflows/goal-engine/errors.d.ts +7 -0
- package/dist/core/workflows/goal-engine/errors.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/errors.js +9 -0
- package/dist/core/workflows/goal-engine/errors.js.map +1 -0
- package/dist/core/workflows/goal-engine/index.d.ts +13 -0
- package/dist/core/workflows/goal-engine/index.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/index.js +8 -0
- package/dist/core/workflows/goal-engine/index.js.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts +31 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.js +145 -0
- package/dist/core/workflows/goal-engine/persistence.js.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts +37 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.js +131 -0
- package/dist/core/workflows/goal-engine/prompts.js.map +1 -0
- package/dist/core/workflows/goal-engine/state.d.ts +41 -0
- package/dist/core/workflows/goal-engine/state.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/state.js +397 -0
- package/dist/core/workflows/goal-engine/state.js.map +1 -0
- package/dist/core/workflows/goal-engine/tools.d.ts +31 -0
- package/dist/core/workflows/goal-engine/tools.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/tools.js +211 -0
- package/dist/core/workflows/goal-engine/tools.js.map +1 -0
- package/dist/core/workflows/goal-engine/types.d.ts +286 -0
- package/dist/core/workflows/goal-engine/types.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/types.js +17 -0
- package/dist/core/workflows/goal-engine/types.js.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts +23 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js +72 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js.map +1 -0
- package/dist/core/workflows/graph-sync.d.ts +67 -0
- package/dist/core/workflows/graph-sync.d.ts.map +1 -0
- package/dist/core/workflows/graph-sync.js +188 -0
- package/dist/core/workflows/graph-sync.js.map +1 -0
- package/dist/core/workflows/graph.d.ts +143 -0
- package/dist/core/workflows/graph.d.ts.map +1 -0
- package/dist/core/workflows/graph.js +319 -0
- package/dist/core/workflows/graph.js.map +1 -0
- package/dist/core/workflows/index.d.ts +26 -0
- package/dist/core/workflows/index.d.ts.map +1 -0
- package/dist/core/workflows/index.js +18 -0
- package/dist/core/workflows/index.js.map +1 -0
- package/dist/core/workflows/journal.d.ts +68 -0
- package/dist/core/workflows/journal.d.ts.map +1 -0
- package/dist/core/workflows/journal.js +83 -0
- package/dist/core/workflows/journal.js.map +1 -0
- package/dist/core/workflows/manager.d.ts +122 -0
- package/dist/core/workflows/manager.d.ts.map +1 -0
- package/dist/core/workflows/manager.js +351 -0
- package/dist/core/workflows/manager.js.map +1 -0
- package/dist/core/workflows/resolve-script.d.ts +35 -0
- package/dist/core/workflows/resolve-script.d.ts.map +1 -0
- package/dist/core/workflows/resolve-script.js +66 -0
- package/dist/core/workflows/resolve-script.js.map +1 -0
- package/dist/core/workflows/runtime.d.ts +62 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -0
- package/dist/core/workflows/runtime.js +380 -0
- package/dist/core/workflows/runtime.js.map +1 -0
- package/dist/core/workflows/save-as-skill.d.ts +27 -0
- package/dist/core/workflows/save-as-skill.d.ts.map +1 -0
- package/dist/core/workflows/save-as-skill.js +54 -0
- package/dist/core/workflows/save-as-skill.js.map +1 -0
- package/dist/core/workflows/shared-store.d.ts +31 -0
- package/dist/core/workflows/shared-store.d.ts.map +1 -0
- package/dist/core/workflows/shared-store.js +80 -0
- package/dist/core/workflows/shared-store.js.map +1 -0
- package/dist/core/workflows/subagent-host.d.ts +50 -0
- package/dist/core/workflows/subagent-host.d.ts.map +1 -0
- package/dist/core/workflows/subagent-host.js +225 -0
- package/dist/core/workflows/subagent-host.js.map +1 -0
- package/dist/core/workflows/tool-workflow.d.ts +22 -0
- package/dist/core/workflows/tool-workflow.d.ts.map +1 -0
- package/dist/core/workflows/tool-workflow.js +120 -0
- package/dist/core/workflows/tool-workflow.js.map +1 -0
- package/dist/core/workflows/types.d.ts +191 -0
- package/dist/core/workflows/types.d.ts.map +1 -0
- package/dist/core/workflows/types.js +26 -0
- package/dist/core/workflows/types.js.map +1 -0
- package/dist/core/workflows/worktree.d.ts +42 -0
- package/dist/core/workflows/worktree.d.ts.map +1 -0
- package/dist/core/workflows/worktree.js +107 -0
- package/dist/core/workflows/worktree.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/remoto/index.d.ts +22 -0
- package/dist/extensions/remoto/index.d.ts.map +1 -0
- package/dist/extensions/remoto/index.js +54 -0
- package/dist/extensions/remoto/index.js.map +1 -0
- package/dist/index.d.ts +1 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -13
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +26 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/acp/acp-mode.d.ts +42 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +190 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/acp/events.d.ts +74 -0
- package/dist/modes/acp/events.d.ts.map +1 -0
- package/dist/modes/acp/events.js +116 -0
- package/dist/modes/acp/events.js.map +1 -0
- package/dist/modes/interactive/components/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +2 -2
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +9 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +56 -12
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/prompt-optimization.d.ts +16 -0
- package/dist/modes/interactive/components/prompt-optimization.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-optimization.js +46 -0
- package/dist/modes/interactive/components/prompt-optimization.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +19 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +180 -56
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +21 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +709 -75
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +11 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +173 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +29 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +27 -5
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/server/attach.d.ts +56 -0
- package/dist/server/attach.d.ts.map +1 -0
- package/dist/server/attach.js +130 -0
- package/dist/server/attach.js.map +1 -0
- package/dist/server/extension-ops.d.ts +40 -0
- package/dist/server/extension-ops.d.ts.map +1 -0
- package/dist/server/extension-ops.js +146 -0
- package/dist/server/extension-ops.js.map +1 -0
- package/dist/server/pi-server-service.d.ts +85 -0
- package/dist/server/pi-server-service.d.ts.map +1 -0
- package/dist/server/pi-server-service.js +213 -0
- package/dist/server/pi-server-service.js.map +1 -0
- package/dist/server/scheduler-tick.d.ts +32 -0
- package/dist/server/scheduler-tick.d.ts.map +1 -0
- package/dist/server/scheduler-tick.js +47 -0
- package/dist/server/scheduler-tick.js.map +1 -0
- package/dist/server/serve.d.ts +25 -0
- package/dist/server/serve.d.ts.map +1 -0
- package/dist/server/serve.js +83 -0
- package/dist/server/serve.js.map +1 -0
- package/dist/server/transcript.d.ts +38 -0
- package/dist/server/transcript.d.ts.map +1 -0
- package/dist/server/transcript.js +176 -0
- package/dist/server/transcript.js.map +1 -0
- package/dist/skills/ada-engine/SKILL.md +153 -0
- package/dist/skills/skill-creator/SKILL.md +90 -0
- package/dist/telegram/api.d.ts +75 -0
- package/dist/telegram/api.d.ts.map +1 -0
- package/dist/telegram/api.js +104 -0
- package/dist/telegram/api.js.map +1 -0
- package/dist/telegram/bridge.d.ts +85 -0
- package/dist/telegram/bridge.d.ts.map +1 -0
- package/dist/telegram/bridge.js +182 -0
- package/dist/telegram/bridge.js.map +1 -0
- package/dist/telegram/journal.d.ts +67 -0
- package/dist/telegram/journal.d.ts.map +1 -0
- package/dist/telegram/journal.js +119 -0
- package/dist/telegram/journal.js.map +1 -0
- package/dist/telegram/servidor.d.ts +15 -0
- package/dist/telegram/servidor.d.ts.map +1 -0
- package/dist/telegram/servidor.js +74 -0
- package/dist/telegram/servidor.js.map +1 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +11 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +11 -0
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +29 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +25 -10
- package/docs/compliance.md +241 -0
- package/docs/containerization.md +24 -24
- package/docs/custom-provider.md +15 -12
- package/docs/development.md +47 -10
- package/docs/docs.json +14 -2
- package/docs/environment-variables.md +20 -17
- package/docs/extensions.md +62 -51
- package/docs/index.md +15 -21
- package/docs/json.md +10 -5
- package/docs/keybindings.md +5 -5
- package/docs/llama-cpp.md +9 -7
- package/docs/models.md +18 -12
- package/docs/packages.md +45 -45
- package/docs/prompt-templates.md +5 -5
- package/docs/providers.md +12 -12
- package/docs/quickstart.md +39 -39
- package/docs/rpc.md +21 -15
- package/docs/sdk.md +38 -38
- package/docs/security.md +26 -21
- package/docs/session-format.md +7 -7
- package/docs/sessions.md +14 -14
- package/docs/settings.md +47 -22
- package/docs/shell-aliases.md +2 -2
- package/docs/skills.md +14 -13
- package/docs/terminal-setup.md +14 -14
- package/docs/termux.md +7 -7
- package/docs/themes.md +11 -11
- package/docs/tmux.md +4 -4
- package/docs/tui.md +3 -3
- package/docs/usage.md +54 -54
- package/docs/windows.md +2 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/12-full-control.ts +9 -0
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +35 -261
- package/package.json +9 -3
|
@@ -0,0 +1,2335 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { constants as fsConstants } from "node:fs";
|
|
4
|
+
import { access } from "node:fs/promises";
|
|
5
|
+
import net from "node:net";
|
|
6
|
+
import os from "node:os";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { canRetryInForeground, outcomeAfterCheck, outcomeAfterObservedValues, prepareAction, } from "./actions.js";
|
|
9
|
+
import { cdpClickForContext, cdpDragForContext, cdpEvaluateForContext, cdpKeypressForContext, cdpMouseForContext, cdpNavigateContext, cdpScrollForContext, cdpSnapshotForContext, cdpTabForWindow, cdpTypeFocusedForContext, cdpTypeForContext, disconnectCdp, listCdpPageContexts, } from "./cdp.js";
|
|
10
|
+
import { getComputerUseConfig, isBrowserUseEnabled, isHeadlessMode, loadComputerUseConfig } from "./config.js";
|
|
11
|
+
import { AGENT_TOOL_NAMES, } from "./contract.js";
|
|
12
|
+
import { noteAfterAct, noteFromLook, noteRegionKeyForRef, renderNote } from "./note.js";
|
|
13
|
+
import { foldToBudget, graftScopedOutline, nodeByRef, outlineNodeLabel, outlineNodePath, rankedTextMatch, restoreOutline, searchOutline, searchOutlineRanked, serializeOutline, serializeOutlineNodeShallow, serializeOutlineSearchMatch, } from "./outline.js";
|
|
14
|
+
import { applyOutputEnvelope, boundToolError, clearStoredOutputs, readStoredOutput, UI_TEXT_PAGE_CHARS, } from "./output.js";
|
|
15
|
+
import { toFiniteNumber } from "./platform/coerce.js";
|
|
16
|
+
import { currentPlatformBackend } from "./platform/index.js";
|
|
17
|
+
import { scoreWindow, shouldPreferForegroundModalWindow } from "./root-selection.js";
|
|
18
|
+
import { ResourceScheduler } from "./runtime.js";
|
|
19
|
+
import { SavedStates } from "./state.js";
|
|
20
|
+
import { changesBetween, renderChanges, stabilizeRefs } from "./view.js";
|
|
21
|
+
const MISSING_TARGET_ERROR = "No current controlled window. Call observe_ui first to choose a target window.";
|
|
22
|
+
const CURRENT_TARGET_GONE_ERROR = "The current controlled window is no longer available. Call observe_ui to choose a new target window.";
|
|
23
|
+
const COMMAND_TIMEOUT_MS = 15_000;
|
|
24
|
+
const LOOK_TIMEOUT_MS = 33_000;
|
|
25
|
+
const ACTION_SETTLE_MS = 280;
|
|
26
|
+
const BROWSER_CONTEXT_PREFIX = "browser:";
|
|
27
|
+
const MANAGED_BROWSER_READY_TIMEOUT_MS = 15_000;
|
|
28
|
+
const AUTO_IMAGE_MAX_DIMENSION = 900;
|
|
29
|
+
const EXPLICIT_IMAGE_MAX_DIMENSION = 1_600;
|
|
30
|
+
const BROWSER_TRANSACTION_ACTIONS = new Set([
|
|
31
|
+
"press",
|
|
32
|
+
"click",
|
|
33
|
+
"setText",
|
|
34
|
+
"typeText",
|
|
35
|
+
"keypress",
|
|
36
|
+
"scroll",
|
|
37
|
+
"drag",
|
|
38
|
+
"moveMouse",
|
|
39
|
+
]);
|
|
40
|
+
const runtimeState = {
|
|
41
|
+
lastPermissionCheckAt: 0,
|
|
42
|
+
windowRefs: new Map(),
|
|
43
|
+
windowRefByIdentity: new Map(),
|
|
44
|
+
browserRootByContext: new Map(),
|
|
45
|
+
browserContextByRoot: new Map(),
|
|
46
|
+
nextRootRefIndex: 1,
|
|
47
|
+
};
|
|
48
|
+
const savedStates = new SavedStates();
|
|
49
|
+
let resourceScheduler = new ResourceScheduler();
|
|
50
|
+
function operationState() {
|
|
51
|
+
return savedStates.current();
|
|
52
|
+
}
|
|
53
|
+
function desktopResourceKey(target) {
|
|
54
|
+
return `desktop-pid:${target.pid}`;
|
|
55
|
+
}
|
|
56
|
+
function persistOperation(state) {
|
|
57
|
+
if (!state.currentTarget || !state.currentCapture || !state.currentLook || !state.currentOutline)
|
|
58
|
+
return;
|
|
59
|
+
const resourceKey = state.resourceKey ?? desktopResourceKey(state.currentTarget);
|
|
60
|
+
const epoch = state.epoch ?? resourceScheduler.epoch(resourceKey);
|
|
61
|
+
savedStates.saveDesktop(state, resourceKey, epoch);
|
|
62
|
+
}
|
|
63
|
+
/** Release handles and state owned by the current Pi session. */
|
|
64
|
+
export async function shutdownComputerUseSession() {
|
|
65
|
+
await resourceScheduler.close();
|
|
66
|
+
resourceScheduler = new ResourceScheduler();
|
|
67
|
+
disconnectCdp();
|
|
68
|
+
const managedBrowser = runtimeState.managedBrowser;
|
|
69
|
+
runtimeState.managedBrowser = undefined;
|
|
70
|
+
if (managedBrowser) {
|
|
71
|
+
managedBrowser.kill("SIGTERM");
|
|
72
|
+
managedBrowser.unref();
|
|
73
|
+
}
|
|
74
|
+
if (runtimeState.managedBrowserCdpPort &&
|
|
75
|
+
process.env.ADA_COMPUTER_USE_CDP_PORT === runtimeState.managedBrowserCdpPort) {
|
|
76
|
+
if (runtimeState.previousCdpPort === undefined)
|
|
77
|
+
delete process.env.ADA_COMPUTER_USE_CDP_PORT;
|
|
78
|
+
else
|
|
79
|
+
process.env.ADA_COMPUTER_USE_CDP_PORT = runtimeState.previousCdpPort;
|
|
80
|
+
}
|
|
81
|
+
runtimeState.managedBrowserCdpPort = undefined;
|
|
82
|
+
runtimeState.previousCdpPort = undefined;
|
|
83
|
+
savedStates.clear();
|
|
84
|
+
clearStoredOutputs();
|
|
85
|
+
runtimeState.windowRefs.clear();
|
|
86
|
+
runtimeState.windowRefByIdentity.clear();
|
|
87
|
+
runtimeState.browserRootByContext.clear();
|
|
88
|
+
runtimeState.browserContextByRoot.clear();
|
|
89
|
+
runtimeState.nextRootRefIndex = 1;
|
|
90
|
+
runtimeState.permissionStatus = undefined;
|
|
91
|
+
runtimeState.helperDiagnostics = undefined;
|
|
92
|
+
runtimeState.lastPermissionCheckAt = 0;
|
|
93
|
+
await currentPlatformBackend.shutdown?.();
|
|
94
|
+
}
|
|
95
|
+
function currentRuntimeMode() {
|
|
96
|
+
return isHeadlessMode() ? "stealth" : "default";
|
|
97
|
+
}
|
|
98
|
+
function currentDeliveryPolicy() {
|
|
99
|
+
if (isHeadlessMode())
|
|
100
|
+
return "background";
|
|
101
|
+
const value = (process.env.ADA_COMPUTER_USE_DELIVERY_POLICY ??
|
|
102
|
+
process.env.ADA_COMPUTER_USE_EVENT_DELIVERY ??
|
|
103
|
+
"default").toLowerCase();
|
|
104
|
+
return value === "background" || value === "pid"
|
|
105
|
+
? "background"
|
|
106
|
+
: value === "foreground" || value === "hid"
|
|
107
|
+
? "foreground"
|
|
108
|
+
: value === "ax_only" || value === "ax-only"
|
|
109
|
+
? "ax_only"
|
|
110
|
+
: "default";
|
|
111
|
+
}
|
|
112
|
+
function nativeInputDelivery(policy = currentDeliveryPolicy()) {
|
|
113
|
+
return policy === "foreground" ? "hid" : "pid";
|
|
114
|
+
}
|
|
115
|
+
function executionTrace(strategy, variant, metadata = {}) {
|
|
116
|
+
return {
|
|
117
|
+
strategy,
|
|
118
|
+
runtimeMode: currentRuntimeMode(),
|
|
119
|
+
variant,
|
|
120
|
+
stealthCompatible: variant === "stealth",
|
|
121
|
+
...metadata,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function settleMsForExecution(execution) {
|
|
125
|
+
// Any deltaSource means the helper already awaited UI quiescence; the
|
|
126
|
+
// bridge must not double-pay with its own settle sleep.
|
|
127
|
+
if (execution.performed?.deltaSource)
|
|
128
|
+
return 0;
|
|
129
|
+
if (execution.variant === "stealth") {
|
|
130
|
+
switch (execution.strategy) {
|
|
131
|
+
case "browser_open_location":
|
|
132
|
+
return 120;
|
|
133
|
+
default:
|
|
134
|
+
return 120;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return ACTION_SETTLE_MS;
|
|
138
|
+
}
|
|
139
|
+
function throwIfAborted(signal) {
|
|
140
|
+
if (signal?.aborted) {
|
|
141
|
+
throw new Error("Operation aborted.");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function sleep(ms, signal) {
|
|
145
|
+
if (ms <= 0)
|
|
146
|
+
return;
|
|
147
|
+
throwIfAborted(signal);
|
|
148
|
+
await new Promise((resolve, reject) => {
|
|
149
|
+
const timer = setTimeout(() => {
|
|
150
|
+
cleanup();
|
|
151
|
+
resolve();
|
|
152
|
+
}, ms);
|
|
153
|
+
const onAbort = () => {
|
|
154
|
+
cleanup();
|
|
155
|
+
reject(new Error("Operation aborted."));
|
|
156
|
+
};
|
|
157
|
+
const cleanup = () => {
|
|
158
|
+
clearTimeout(timer);
|
|
159
|
+
signal?.removeEventListener("abort", onAbort);
|
|
160
|
+
};
|
|
161
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
async function withWindowWriteLock(target, work) {
|
|
165
|
+
const state = operationState();
|
|
166
|
+
const key = desktopResourceKey(target);
|
|
167
|
+
const baseEpoch = state.epoch ?? resourceScheduler.epoch(key);
|
|
168
|
+
const result = await resourceScheduler.write(key, baseEpoch, async (nextEpoch) => {
|
|
169
|
+
state.resourceKey = key;
|
|
170
|
+
state.epoch = nextEpoch;
|
|
171
|
+
return await work();
|
|
172
|
+
});
|
|
173
|
+
return result.value;
|
|
174
|
+
}
|
|
175
|
+
function trimOrUndefined(value) {
|
|
176
|
+
if (typeof value !== "string")
|
|
177
|
+
return undefined;
|
|
178
|
+
const trimmed = value.trim();
|
|
179
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
180
|
+
}
|
|
181
|
+
function normalizeText(value) {
|
|
182
|
+
return (value ?? "").trim().toLowerCase();
|
|
183
|
+
}
|
|
184
|
+
function toBoolean(value) {
|
|
185
|
+
return value === true;
|
|
186
|
+
}
|
|
187
|
+
function outlineNodeCenter(node) {
|
|
188
|
+
if (!node.rect) {
|
|
189
|
+
throw new Error(`Outline ref '${node.ref}' has no full-look coordinates after scoped expansion. Re-observe for coordinates.`);
|
|
190
|
+
}
|
|
191
|
+
return { x: node.rect.x + node.rect.w / 2, y: node.rect.y + node.rect.h / 2 };
|
|
192
|
+
}
|
|
193
|
+
function validateStateId(stateId) {
|
|
194
|
+
const state = operationState();
|
|
195
|
+
if (!state.currentCapture) {
|
|
196
|
+
throw new Error("No observation state is available. Call observe_ui first.");
|
|
197
|
+
}
|
|
198
|
+
const supplied = stateId;
|
|
199
|
+
if (supplied && state.currentCapture.stateId !== supplied) {
|
|
200
|
+
throw new Error(`Stale state '${supplied}'. The active operation state is '${state.currentCapture.stateId}'. Observe the root again and retry.`);
|
|
201
|
+
}
|
|
202
|
+
const stateTarget = state.currentStateTarget;
|
|
203
|
+
if (stateTarget &&
|
|
204
|
+
state.currentTarget &&
|
|
205
|
+
(stateTarget.pid !== state.currentTarget.pid || stateTarget.windowId !== state.currentTarget.windowId)) {
|
|
206
|
+
throw new Error("The latest state belongs to a different window. Call observe_ui for the target window and retry.");
|
|
207
|
+
}
|
|
208
|
+
return state.currentCapture;
|
|
209
|
+
}
|
|
210
|
+
function formatOutlineNodeLabel(node) {
|
|
211
|
+
const label = outlineNodeLabel(node) || "(unlabeled)";
|
|
212
|
+
const identifier = node.identifier ? ` id=${JSON.stringify(node.identifier)}` : "";
|
|
213
|
+
const capabilities = [
|
|
214
|
+
node.canSetValue ? "setValue" : undefined,
|
|
215
|
+
node.canPress ? "press" : undefined,
|
|
216
|
+
node.canFocus ? "focus" : undefined,
|
|
217
|
+
node.canScroll ? "scroll" : undefined,
|
|
218
|
+
node.canIncrement || node.canDecrement ? "adjust" : undefined,
|
|
219
|
+
node.pictureOnly ? "pictureOnly" : undefined,
|
|
220
|
+
].filter((item) => Boolean(item));
|
|
221
|
+
return `${node.ref} ${node.role}${node.subrole ? `/${node.subrole}` : ""}${identifier} ${JSON.stringify(label)}${capabilities.length ? ` [${capabilities.join(",")}]` : ""}`;
|
|
222
|
+
}
|
|
223
|
+
function outlineNodeByRef(ref) {
|
|
224
|
+
const state = operationState();
|
|
225
|
+
const outline = state.currentOutline;
|
|
226
|
+
const node = outline ? nodeByRef(outline, ref) : undefined;
|
|
227
|
+
if (!node) {
|
|
228
|
+
const windowHint = state.currentTarget?.windowRef ? `({ root: "${state.currentTarget.windowRef}" })` : "";
|
|
229
|
+
throw new Error(`Outline ref '${ref}' is stale or not available for the latest state. Call observe_ui${windowHint} again and choose a current @e ref.`);
|
|
230
|
+
}
|
|
231
|
+
return node;
|
|
232
|
+
}
|
|
233
|
+
function wireRefForNode(node) {
|
|
234
|
+
if (node.pictureOnly || !node.wireRef) {
|
|
235
|
+
throw new Error(`Outline ref '${node.ref}' is pictureOnly and has no semantic element. It can be clicked by coordinates, but semantic-only actions are not available.`);
|
|
236
|
+
}
|
|
237
|
+
return node.wireRef;
|
|
238
|
+
}
|
|
239
|
+
function imageFallbackReason(tool, result, imageMode = "auto") {
|
|
240
|
+
if (imageMode === "never")
|
|
241
|
+
return undefined;
|
|
242
|
+
if (imageMode === "always")
|
|
243
|
+
return { reason: "fallback_recovery", message: "An image was requested explicitly for visual verification." };
|
|
244
|
+
const outline = result.outline;
|
|
245
|
+
const labeled = outline.nodes.filter((node) => outlineNodeLabel(node)).length;
|
|
246
|
+
if (outline.nodes.length < 3) {
|
|
247
|
+
return {
|
|
248
|
+
reason: "sparse_ax_targets",
|
|
249
|
+
message: "Only a few outline nodes were found, so the look image is attached for context.",
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
if (labeled * 3 < outline.nodes.length) {
|
|
253
|
+
return {
|
|
254
|
+
reason: "unlabeled_ax_targets",
|
|
255
|
+
message: "Most outline nodes are unlabeled, so the look image is attached for context.",
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
if (tool === "wait" && currentPlatformBackend.isBrowserApp(result.target.appName, result.target.bundleId)) {
|
|
259
|
+
return {
|
|
260
|
+
reason: "browser_wait_verification",
|
|
261
|
+
message: "Browser content may have changed visually during wait, so an image is attached for fallback.",
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
function currentTargetOrThrow() {
|
|
267
|
+
const target = operationState().currentTarget;
|
|
268
|
+
if (!target) {
|
|
269
|
+
throw new Error(MISSING_TARGET_ERROR);
|
|
270
|
+
}
|
|
271
|
+
return target;
|
|
272
|
+
}
|
|
273
|
+
function emptyActivation() {
|
|
274
|
+
return { activated: false, unminimized: false, raised: false };
|
|
275
|
+
}
|
|
276
|
+
async function ensureReady(ctx, signal) {
|
|
277
|
+
loadComputerUseConfig(ctx.cwd);
|
|
278
|
+
throwIfAborted(signal);
|
|
279
|
+
const ready = await currentPlatformBackend.ensureReady(ctx, {
|
|
280
|
+
permissionStatus: runtimeState.permissionStatus,
|
|
281
|
+
lastPermissionCheckAt: runtimeState.lastPermissionCheckAt,
|
|
282
|
+
helperDiagnostics: runtimeState.helperDiagnostics,
|
|
283
|
+
}, signal);
|
|
284
|
+
runtimeState.permissionStatus = ready.permissionStatus;
|
|
285
|
+
runtimeState.lastPermissionCheckAt = ready.lastPermissionCheckAt;
|
|
286
|
+
runtimeState.helperDiagnostics = ready.helperDiagnostics;
|
|
287
|
+
}
|
|
288
|
+
export async function ensureComputerUseSetup(ctx, signal) {
|
|
289
|
+
await ensureReady(ctx, signal);
|
|
290
|
+
}
|
|
291
|
+
async function listApps(signal) {
|
|
292
|
+
return await currentPlatformBackend.listApps(signal);
|
|
293
|
+
}
|
|
294
|
+
async function listWindows(pid, signal) {
|
|
295
|
+
return await currentPlatformBackend.listRoots({ pid }, signal);
|
|
296
|
+
}
|
|
297
|
+
function appMatchesWindowQuery(app, query) {
|
|
298
|
+
const appQuery = trimOrUndefined(query.app);
|
|
299
|
+
const bundleQuery = trimOrUndefined(query.bundleId);
|
|
300
|
+
const pidQuery = Number.isFinite(query.pid) ? Math.trunc(query.pid) : undefined;
|
|
301
|
+
if (pidQuery !== undefined && app.pid !== pidQuery)
|
|
302
|
+
return false;
|
|
303
|
+
if (bundleQuery && normalizeText(app.bundleId ?? "") !== normalizeText(bundleQuery))
|
|
304
|
+
return false;
|
|
305
|
+
if (appQuery && normalizeText(app.appName) !== normalizeText(appQuery))
|
|
306
|
+
return false;
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
function platformRootSheetCount(window) {
|
|
310
|
+
const value = window.metadata?.sheetCount;
|
|
311
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : undefined;
|
|
312
|
+
}
|
|
313
|
+
function platformRootPairing(window) {
|
|
314
|
+
const value = window.metadata?.pairing;
|
|
315
|
+
if (!value || typeof value !== "object")
|
|
316
|
+
return undefined;
|
|
317
|
+
const pairing = value;
|
|
318
|
+
if (pairing.confidence !== "exact" && pairing.confidence !== "high" && pairing.confidence !== "low")
|
|
319
|
+
return undefined;
|
|
320
|
+
return {
|
|
321
|
+
confidence: pairing.confidence,
|
|
322
|
+
score: typeof pairing.score === "number" && Number.isFinite(pairing.score) ? pairing.score : Number.NEGATIVE_INFINITY,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
function formatWindowLine(window) {
|
|
326
|
+
if (window.kind === "browser_page")
|
|
327
|
+
return `- ${window.windowRef} browser_page ${JSON.stringify(window.windowTitle)}${window.url ? ` — ${window.url}` : ""}`;
|
|
328
|
+
const flags = [
|
|
329
|
+
window.isFocused ? "focused" : undefined,
|
|
330
|
+
window.isMain ? "main" : undefined,
|
|
331
|
+
window.isModal ? "modal" : undefined,
|
|
332
|
+
window.sheetCount ? `sheets=${window.sheetCount}` : undefined,
|
|
333
|
+
window.isOnscreen ? "onscreen" : undefined,
|
|
334
|
+
window.isMinimized ? "minimized" : undefined,
|
|
335
|
+
window.browserUseAllowed ? undefined : "browser_use_disabled",
|
|
336
|
+
]
|
|
337
|
+
.filter(Boolean)
|
|
338
|
+
.join(", ");
|
|
339
|
+
const frame = `${Math.round(window.framePoints.x)},${Math.round(window.framePoints.y)} ${Math.round(window.framePoints.w)}x${Math.round(window.framePoints.h)}`;
|
|
340
|
+
const id = window.windowId
|
|
341
|
+
? `windowId ${window.windowId}`
|
|
342
|
+
: window.nativeWindowRef
|
|
343
|
+
? `nativeRootRef ${window.nativeWindowRef}`
|
|
344
|
+
: "unstable root id";
|
|
345
|
+
const pairing = window.pairing ? `, pairing ${window.pairing.confidence}/${Math.round(window.pairing.score)}` : "";
|
|
346
|
+
return `- ${window.windowRef} ${window.kind} ${window.app} pid ${window.pid} — ${window.windowTitle || "(untitled)"} (z ${window.zOrder}, ${id}, frame ${frame}${pairing}${flags ? `, ${flags}` : ""})`;
|
|
347
|
+
}
|
|
348
|
+
async function getFrontmost(signal) {
|
|
349
|
+
return await currentPlatformBackend.getFrontmost(signal);
|
|
350
|
+
}
|
|
351
|
+
function assertBrowserUseAllowed(target) {
|
|
352
|
+
if (!isBrowserUseEnabled() && currentPlatformBackend.isBrowserApp(target.appName, target.bundleId)) {
|
|
353
|
+
throw new Error(`Browser use is disabled by ada-computer-use config, so '${target.appName}' cannot be controlled. Enable browser_use in ~/.pi/agent/extensions/ada-computer-use.json or .pi/computer-use.json to allow browser windows.`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function windowRecordIdentity(record) {
|
|
357
|
+
if (record.windowId && record.windowId > 0) {
|
|
358
|
+
return `pid:${record.pid}|id:${record.windowId}`;
|
|
359
|
+
}
|
|
360
|
+
if (record.nativeWindowRef) {
|
|
361
|
+
return `pid:${record.pid}|ref:${record.nativeWindowRef}`;
|
|
362
|
+
}
|
|
363
|
+
const { x, y, w, h } = record.framePoints;
|
|
364
|
+
return `pid:${record.pid}|title:${normalizeText(record.windowTitle)}|frame:${Math.round(x)},${Math.round(y)},${Math.round(w)},${Math.round(h)}`;
|
|
365
|
+
}
|
|
366
|
+
function storeWindowRef(record) {
|
|
367
|
+
const identity = windowRecordIdentity(record);
|
|
368
|
+
const existingRef = runtimeState.windowRefByIdentity.get(identity);
|
|
369
|
+
if (existingRef) {
|
|
370
|
+
const existing = runtimeState.windowRefs.get(existingRef);
|
|
371
|
+
if (existing) {
|
|
372
|
+
const updated = { ...record, ref: existingRef };
|
|
373
|
+
runtimeState.windowRefs.set(existingRef, updated);
|
|
374
|
+
return updated;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const ref = `@r${runtimeState.nextRootRefIndex++}`;
|
|
378
|
+
const stored = { ...record, ref };
|
|
379
|
+
runtimeState.windowRefByIdentity.set(identity, ref);
|
|
380
|
+
runtimeState.windowRefs.set(ref, stored);
|
|
381
|
+
return stored;
|
|
382
|
+
}
|
|
383
|
+
function storeBrowserRootRef(contextId) {
|
|
384
|
+
const existing = runtimeState.browserRootByContext.get(contextId);
|
|
385
|
+
if (existing)
|
|
386
|
+
return existing;
|
|
387
|
+
const ref = `@r${runtimeState.nextRootRefIndex++}`;
|
|
388
|
+
runtimeState.browserRootByContext.set(contextId, ref);
|
|
389
|
+
runtimeState.browserContextByRoot.set(ref, contextId);
|
|
390
|
+
return ref;
|
|
391
|
+
}
|
|
392
|
+
function storeWindowRefForTarget(target) {
|
|
393
|
+
return storeWindowRef({
|
|
394
|
+
appName: target.appName,
|
|
395
|
+
bundleId: target.bundleId,
|
|
396
|
+
pid: target.pid,
|
|
397
|
+
windowTitle: target.windowTitle,
|
|
398
|
+
windowId: target.windowId > 0 ? target.windowId : undefined,
|
|
399
|
+
framePoints: target.framePoints,
|
|
400
|
+
scaleFactor: target.scaleFactor,
|
|
401
|
+
isMinimized: target.isMinimized,
|
|
402
|
+
isOnscreen: target.isOnscreen,
|
|
403
|
+
isMain: target.isMain,
|
|
404
|
+
isFocused: target.isFocused,
|
|
405
|
+
}).ref;
|
|
406
|
+
}
|
|
407
|
+
function storeWindowRefForAppWindow(app, window) {
|
|
408
|
+
return storeWindowRef({
|
|
409
|
+
appName: app.appName,
|
|
410
|
+
bundleId: app.bundleId,
|
|
411
|
+
pid: app.pid,
|
|
412
|
+
windowTitle: window.title || "(untitled)",
|
|
413
|
+
windowId: window.windowId,
|
|
414
|
+
nativeWindowRef: window.windowRef,
|
|
415
|
+
framePoints: window.framePoints,
|
|
416
|
+
scaleFactor: window.scaleFactor,
|
|
417
|
+
isMinimized: window.isMinimized,
|
|
418
|
+
isOnscreen: window.isOnscreen,
|
|
419
|
+
isMain: window.isMain,
|
|
420
|
+
isFocused: window.isFocused,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
function choosePreferredWindow(windows, appName) {
|
|
424
|
+
if (!windows.length) {
|
|
425
|
+
throw new Error(`No controllable root was found in app '${appName}'.`);
|
|
426
|
+
}
|
|
427
|
+
const scored = [...windows].sort((a, b) => scoreWindow(b) - scoreWindow(a));
|
|
428
|
+
return scored[0];
|
|
429
|
+
}
|
|
430
|
+
function summarizeWindowCandidate(window) {
|
|
431
|
+
const flags = [
|
|
432
|
+
window.isFocused ? "focused" : undefined,
|
|
433
|
+
window.isMain ? "main" : undefined,
|
|
434
|
+
window.isOnscreen ? "onscreen" : undefined,
|
|
435
|
+
window.isMinimized ? "minimized" : undefined,
|
|
436
|
+
]
|
|
437
|
+
.filter(Boolean)
|
|
438
|
+
.join(",");
|
|
439
|
+
return `${window.title || "(untitled)"} [score=${scoreWindow(window)}${flags ? `, ${flags}` : ""}]`;
|
|
440
|
+
}
|
|
441
|
+
function summarizeWindowCandidates(windows, limit = 6) {
|
|
442
|
+
return [...windows]
|
|
443
|
+
.sort((a, b) => scoreWindow(b) - scoreWindow(a))
|
|
444
|
+
.slice(0, limit)
|
|
445
|
+
.map(summarizeWindowCandidate)
|
|
446
|
+
.join("; ");
|
|
447
|
+
}
|
|
448
|
+
function chooseRankedWindowOrUndefined(windows) {
|
|
449
|
+
if (windows.length === 0)
|
|
450
|
+
return undefined;
|
|
451
|
+
const ranked = [...windows].sort((a, b) => scoreWindow(b) - scoreWindow(a));
|
|
452
|
+
if (ranked.length === 1)
|
|
453
|
+
return ranked[0];
|
|
454
|
+
const topScore = scoreWindow(ranked[0]);
|
|
455
|
+
const nextScore = scoreWindow(ranked[1]);
|
|
456
|
+
return topScore >= nextScore + 25 ? ranked[0] : undefined;
|
|
457
|
+
}
|
|
458
|
+
function toResolvedTarget(app, window) {
|
|
459
|
+
const baseTarget = {
|
|
460
|
+
appName: app.appName,
|
|
461
|
+
bundleId: app.bundleId,
|
|
462
|
+
pid: app.pid,
|
|
463
|
+
windowTitle: window.title || "(untitled)",
|
|
464
|
+
windowId: typeof window.windowId === "number" ? window.windowId : 0,
|
|
465
|
+
nativeWindowRef: window.windowRef,
|
|
466
|
+
framePoints: window.framePoints,
|
|
467
|
+
scaleFactor: window.scaleFactor,
|
|
468
|
+
isMinimized: window.isMinimized,
|
|
469
|
+
isOnscreen: window.isOnscreen,
|
|
470
|
+
isMain: window.isMain,
|
|
471
|
+
isFocused: window.isFocused,
|
|
472
|
+
};
|
|
473
|
+
return { ...baseTarget, windowRef: storeWindowRefForAppWindow(app, window).ref };
|
|
474
|
+
}
|
|
475
|
+
function nativeWindowRequest(target) {
|
|
476
|
+
return { pid: target.pid, windowId: target.windowId, windowRef: target.nativeWindowRef };
|
|
477
|
+
}
|
|
478
|
+
function setCurrentTarget(target) {
|
|
479
|
+
assertBrowserUseAllowed(target);
|
|
480
|
+
const windowRef = target.windowRef ?? storeWindowRefForTarget(target);
|
|
481
|
+
operationState().currentTarget = {
|
|
482
|
+
appName: target.appName,
|
|
483
|
+
bundleId: target.bundleId,
|
|
484
|
+
pid: target.pid,
|
|
485
|
+
windowTitle: target.windowTitle,
|
|
486
|
+
windowId: target.windowId,
|
|
487
|
+
windowRef,
|
|
488
|
+
nativeWindowRef: target.nativeWindowRef,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
function normalizeWindowSelector(selector) {
|
|
492
|
+
if (typeof selector === "number" && Number.isFinite(selector))
|
|
493
|
+
return String(Math.trunc(selector));
|
|
494
|
+
if (typeof selector === "string")
|
|
495
|
+
return trimOrUndefined(selector);
|
|
496
|
+
return undefined;
|
|
497
|
+
}
|
|
498
|
+
async function resolveTargetByWindowSelector(selector, signal) {
|
|
499
|
+
const normalized = normalizeWindowSelector(selector);
|
|
500
|
+
if (!normalized) {
|
|
501
|
+
throw new Error("root target must be a non-empty @r ref or numeric windowId.");
|
|
502
|
+
}
|
|
503
|
+
const current = operationState().currentTarget;
|
|
504
|
+
if (current?.windowRef === normalized) {
|
|
505
|
+
return await resolveCurrentTarget(signal);
|
|
506
|
+
}
|
|
507
|
+
const fromRef = runtimeState.windowRefs.get(normalized);
|
|
508
|
+
if (fromRef) {
|
|
509
|
+
const app = { appName: fromRef.appName, bundleId: fromRef.bundleId, pid: fromRef.pid };
|
|
510
|
+
const windows = await listWindows(fromRef.pid, signal);
|
|
511
|
+
const match = (fromRef.windowId ? windows.find((window) => window.windowId === fromRef.windowId) : undefined) ??
|
|
512
|
+
(fromRef.nativeWindowRef
|
|
513
|
+
? windows.find((window) => window.windowRef === fromRef.nativeWindowRef)
|
|
514
|
+
: undefined) ??
|
|
515
|
+
windows.find((window) => normalizeText(window.title || "(untitled)") === normalizeText(fromRef.windowTitle));
|
|
516
|
+
if (!match) {
|
|
517
|
+
throw new Error(`Root ref '${normalized}' is stale. Call find_roots again and choose a current window.`);
|
|
518
|
+
}
|
|
519
|
+
const resolved = toResolvedTarget(app, match);
|
|
520
|
+
setCurrentTarget(resolved);
|
|
521
|
+
return resolved;
|
|
522
|
+
}
|
|
523
|
+
const numericWindowId = Number(normalized);
|
|
524
|
+
if (Number.isInteger(numericWindowId) && numericWindowId > 0) {
|
|
525
|
+
const apps = await listApps(signal);
|
|
526
|
+
for (const app of apps) {
|
|
527
|
+
const windows = await listWindows(app.pid, signal);
|
|
528
|
+
const match = windows.find((window) => window.windowId === numericWindowId);
|
|
529
|
+
if (match) {
|
|
530
|
+
assertBrowserUseAllowed(app);
|
|
531
|
+
const resolved = toResolvedTarget(app, match);
|
|
532
|
+
setCurrentTarget(resolved);
|
|
533
|
+
return resolved;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
throw new Error(`Window id '${numericWindowId}' was not found. Call find_roots again and choose a current window.`);
|
|
537
|
+
}
|
|
538
|
+
if (normalized.startsWith("@r")) {
|
|
539
|
+
throw new Error(`Root ref '${normalized}' is not available in this session. Call find_roots first.`);
|
|
540
|
+
}
|
|
541
|
+
const config = getComputerUseConfig();
|
|
542
|
+
const candidates = await collectWindowDetails(await listApps(signal), config, signal);
|
|
543
|
+
const query = normalizeText(normalized);
|
|
544
|
+
const exact = candidates.filter((candidate) => normalizeText(candidate.app) === query || normalizeText(candidate.windowTitle) === query);
|
|
545
|
+
const fuzzy = exact.length > 0
|
|
546
|
+
? exact
|
|
547
|
+
: candidates.filter((candidate) => `${normalizeText(candidate.app)} ${normalizeText(candidate.windowTitle)}`.includes(query));
|
|
548
|
+
const match = fuzzy.sort((a, b) => Number(b.isFocused) - Number(a.isFocused) || a.zOrder - b.zOrder)[0];
|
|
549
|
+
if (!match)
|
|
550
|
+
throw new Error(`Root query '${normalized}' did not match any current root. Call find_roots to inspect roots.`);
|
|
551
|
+
const app = { appName: match.app, bundleId: match.bundleId, pid: match.pid };
|
|
552
|
+
const roots = await listWindows(match.pid, signal);
|
|
553
|
+
const helperRoot = roots.find((root) => root.rootRef === match.nativeWindowRef ||
|
|
554
|
+
root.windowRef === match.nativeWindowRef ||
|
|
555
|
+
root.windowId === match.windowId) ?? roots[0];
|
|
556
|
+
const resolved = toResolvedTarget(app, helperRoot);
|
|
557
|
+
setCurrentTarget(resolved);
|
|
558
|
+
return resolved;
|
|
559
|
+
}
|
|
560
|
+
async function resolveCurrentTarget(signal) {
|
|
561
|
+
const current = currentTargetOrThrow();
|
|
562
|
+
const windows = await listWindows(current.pid, signal);
|
|
563
|
+
if (!windows.length) {
|
|
564
|
+
throw new Error(CURRENT_TARGET_GONE_ERROR);
|
|
565
|
+
}
|
|
566
|
+
const hadStableWindowId = current.windowId > 0;
|
|
567
|
+
const titleQuery = normalizeText(current.windowTitle);
|
|
568
|
+
let match = current.nativeWindowRef
|
|
569
|
+
? windows.find((window) => window.windowRef === current.nativeWindowRef || window.rootRef === current.nativeWindowRef)
|
|
570
|
+
: undefined;
|
|
571
|
+
match ??= hadStableWindowId
|
|
572
|
+
? windows.find((window) => window.windowId !== undefined && window.windowId === current.windowId)
|
|
573
|
+
: undefined;
|
|
574
|
+
if (!match) {
|
|
575
|
+
const exactTitleMatches = titleQuery && titleQuery !== "(untitled)"
|
|
576
|
+
? windows.filter((window) => normalizeText(window.title) === titleQuery)
|
|
577
|
+
: [];
|
|
578
|
+
if (exactTitleMatches.length === 1) {
|
|
579
|
+
match = exactTitleMatches[0];
|
|
580
|
+
}
|
|
581
|
+
else if (exactTitleMatches.length > 1) {
|
|
582
|
+
match = chooseRankedWindowOrUndefined(exactTitleMatches);
|
|
583
|
+
if (!match) {
|
|
584
|
+
throw new Error(`${CURRENT_TARGET_GONE_ERROR} Multiple windows now match '${current.windowTitle}': ${summarizeWindowCandidates(exactTitleMatches)}.`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (!match && !hadStableWindowId) {
|
|
589
|
+
match = chooseRankedWindowOrUndefined(windows);
|
|
590
|
+
}
|
|
591
|
+
if (!match) {
|
|
592
|
+
throw new Error(CURRENT_TARGET_GONE_ERROR);
|
|
593
|
+
}
|
|
594
|
+
const modal = windows
|
|
595
|
+
.filter((window) => shouldPreferForegroundModalWindow(match, window))
|
|
596
|
+
.sort((a, b) => scoreWindow(b) - scoreWindow(a))[0];
|
|
597
|
+
if (modal)
|
|
598
|
+
match = modal;
|
|
599
|
+
const app = {
|
|
600
|
+
appName: current.appName,
|
|
601
|
+
bundleId: current.bundleId,
|
|
602
|
+
pid: current.pid,
|
|
603
|
+
};
|
|
604
|
+
const resolved = toResolvedTarget(app, match);
|
|
605
|
+
setCurrentTarget(resolved);
|
|
606
|
+
return resolved;
|
|
607
|
+
}
|
|
608
|
+
async function resolveFrontmostTarget(signal) {
|
|
609
|
+
const frontmost = await getFrontmost(signal);
|
|
610
|
+
const apps = await listApps(signal);
|
|
611
|
+
const app = apps.find((candidate) => candidate.pid === frontmost.pid) ?? {
|
|
612
|
+
appName: frontmost.appName,
|
|
613
|
+
bundleId: frontmost.bundleId,
|
|
614
|
+
pid: frontmost.pid,
|
|
615
|
+
};
|
|
616
|
+
const windows = await listWindows(frontmost.pid, signal);
|
|
617
|
+
if (!windows.length) {
|
|
618
|
+
throw new Error("No frontmost controllable root was found. Open an app window and call observe_ui again.");
|
|
619
|
+
}
|
|
620
|
+
if (currentPlatformBackend.isBrowserApp(app.appName, app.bundleId)) {
|
|
621
|
+
assertBrowserUseAllowed(app);
|
|
622
|
+
}
|
|
623
|
+
let selected = windows.find((window) => window.windowId !== undefined && window.windowId === frontmost.windowId);
|
|
624
|
+
if (!selected && frontmost.windowTitle) {
|
|
625
|
+
selected = windows.find((window) => normalizeText(window.title) === normalizeText(frontmost.windowTitle));
|
|
626
|
+
}
|
|
627
|
+
selected ??= choosePreferredWindow(windows, app.appName);
|
|
628
|
+
const resolved = toResolvedTarget(app, selected);
|
|
629
|
+
setCurrentTarget(resolved);
|
|
630
|
+
return resolved;
|
|
631
|
+
}
|
|
632
|
+
function matchesObserveSelection(target, selection) {
|
|
633
|
+
const root = normalizeWindowSelector(selection.root);
|
|
634
|
+
return !root || target.windowRef === root;
|
|
635
|
+
}
|
|
636
|
+
async function resolveTargetForObserve(signal) {
|
|
637
|
+
return operationState().currentTarget ? await resolveCurrentTarget(signal) : await resolveFrontmostTarget(signal);
|
|
638
|
+
}
|
|
639
|
+
async function ensureTargetWindowId(target, signal) {
|
|
640
|
+
if (target.windowId > 0 || target.nativeWindowRef) {
|
|
641
|
+
return target;
|
|
642
|
+
}
|
|
643
|
+
const refreshed = await resolveCurrentTarget(signal);
|
|
644
|
+
if (refreshed.windowId <= 0 && !refreshed.nativeWindowRef) {
|
|
645
|
+
throw new Error(CURRENT_TARGET_GONE_ERROR);
|
|
646
|
+
}
|
|
647
|
+
return refreshed;
|
|
648
|
+
}
|
|
649
|
+
function captureForLook(look) {
|
|
650
|
+
return {
|
|
651
|
+
stateId: randomUUID(),
|
|
652
|
+
width: look.image?.width ?? 0,
|
|
653
|
+
height: look.image?.height ?? 0,
|
|
654
|
+
scaleFactor: look.window.scaleFactor,
|
|
655
|
+
timestamp: Date.now(),
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
async function performLook(target, options, signal) {
|
|
659
|
+
if ((!Number.isFinite(target.windowId) || target.windowId <= 0) && !target.nativeWindowRef)
|
|
660
|
+
throw new Error(`Current platform requires a stable root id to observe '${target.windowTitle}'. Call find_roots and select a root with a stable id.`);
|
|
661
|
+
return await currentPlatformBackend.observe({
|
|
662
|
+
target: nativeWindowRequest(target),
|
|
663
|
+
baseLookId: options.baseLookId,
|
|
664
|
+
readText: options.readText,
|
|
665
|
+
scopeRef: options.scopeRef,
|
|
666
|
+
maxDimension: options.maxDimension,
|
|
667
|
+
includeImage: options.includeImage,
|
|
668
|
+
}, { signal, timeoutMs: LOOK_TIMEOUT_MS });
|
|
669
|
+
}
|
|
670
|
+
function noteWindowForTarget(target, look) {
|
|
671
|
+
return {
|
|
672
|
+
windowRef: target.windowRef,
|
|
673
|
+
title: target.windowTitle,
|
|
674
|
+
pairing: look?.window.metadata?.pairing && typeof look.window.metadata.pairing === "object"
|
|
675
|
+
? look.window.metadata.pairing.confidence
|
|
676
|
+
: undefined,
|
|
677
|
+
pairingScore: look?.window.metadata?.pairing && typeof look.window.metadata.pairing === "object"
|
|
678
|
+
? look.window.metadata.pairing.score
|
|
679
|
+
: undefined,
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
async function captureCurrentTarget(signal, readText = "auto", maxDimension = AUTO_IMAGE_MAX_DIMENSION, targetOverride, includeImage = true) {
|
|
683
|
+
const state = operationState();
|
|
684
|
+
const baseOutline = state.currentOutline;
|
|
685
|
+
const baseTarget = state.currentTarget;
|
|
686
|
+
let target = targetOverride ?? (await resolveCurrentTarget(signal));
|
|
687
|
+
target = await ensureTargetWindowId(target, signal);
|
|
688
|
+
const look = await performLook(target, { maxDimension, readText, includeImage }, signal);
|
|
689
|
+
const outline = stabilizeRefs(baseTarget && sameRootIdentity(baseTarget, target) ? baseOutline : undefined, look.parsedOutline);
|
|
690
|
+
look.parsedOutline = outline;
|
|
691
|
+
look.outline = outline.root;
|
|
692
|
+
const capture = captureForLook(look);
|
|
693
|
+
setCurrentTarget(target);
|
|
694
|
+
state.currentCapture = capture;
|
|
695
|
+
state.currentStateTarget = { pid: target.pid, windowId: target.windowId, windowRef: target.windowRef };
|
|
696
|
+
state.currentLook = look;
|
|
697
|
+
state.currentOutline = outline;
|
|
698
|
+
state.currentNote = noteFromLook(state.currentNote, outline, noteWindowForTarget(target, look));
|
|
699
|
+
state.resourceKey = desktopResourceKey(target);
|
|
700
|
+
state.epoch ??= resourceScheduler.epoch(state.resourceKey);
|
|
701
|
+
return {
|
|
702
|
+
target,
|
|
703
|
+
capture,
|
|
704
|
+
look,
|
|
705
|
+
outline,
|
|
706
|
+
activation: emptyActivation(),
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
async function buildToolResult(tool, summary, result, execution, _signal, imageMode = operationState().currentImageMode ?? "auto", base) {
|
|
710
|
+
const state = operationState();
|
|
711
|
+
const fallbackReason = imageFallbackReason(tool, result, imageMode);
|
|
712
|
+
const transition = base ? changesBetween(base.outline, result.outline) : undefined;
|
|
713
|
+
const useDiff = Boolean(transition && !transition.useFullView);
|
|
714
|
+
const folded = foldToBudget(result.outline);
|
|
715
|
+
const renderedNote = renderNote(state.currentNote);
|
|
716
|
+
const details = {
|
|
717
|
+
tool,
|
|
718
|
+
target: {
|
|
719
|
+
app: result.target.appName,
|
|
720
|
+
bundleId: result.target.bundleId,
|
|
721
|
+
pid: result.target.pid,
|
|
722
|
+
windowTitle: result.target.windowTitle,
|
|
723
|
+
windowId: result.target.windowId,
|
|
724
|
+
windowRef: result.target.windowRef ?? state.currentTarget?.windowRef,
|
|
725
|
+
nativeWindowRef: result.target.nativeWindowRef ?? state.currentTarget?.nativeWindowRef,
|
|
726
|
+
},
|
|
727
|
+
capture: {
|
|
728
|
+
stateId: result.capture.stateId,
|
|
729
|
+
width: result.capture.width,
|
|
730
|
+
height: result.capture.height,
|
|
731
|
+
scaleFactor: result.capture.scaleFactor,
|
|
732
|
+
timestamp: result.capture.timestamp,
|
|
733
|
+
coordinateSpace: "window-relative-screenshot-pixels",
|
|
734
|
+
},
|
|
735
|
+
lookId: result.look.lookId,
|
|
736
|
+
view: useDiff ? "diff" : "full",
|
|
737
|
+
baseStateId: transition ? base?.stateId : undefined,
|
|
738
|
+
changes: useDiff ? transition?.changes : undefined,
|
|
739
|
+
viewReason: transition?.useFullView ? transition.reason : undefined,
|
|
740
|
+
renderedOutline: folded.text,
|
|
741
|
+
outline: serializeOutline(result.outline),
|
|
742
|
+
note: state.currentNote,
|
|
743
|
+
activation: result.activation,
|
|
744
|
+
execution,
|
|
745
|
+
status: "ok",
|
|
746
|
+
config: getComputerUseConfig(),
|
|
747
|
+
helper: runtimeState.helperDiagnostics,
|
|
748
|
+
imageReason: fallbackReason?.reason,
|
|
749
|
+
};
|
|
750
|
+
// Console piggyback: when a CDP connection is active for this browser
|
|
751
|
+
// window, surface console output collected since the last tool result.
|
|
752
|
+
let consoleText = "";
|
|
753
|
+
if (currentPlatformBackend.isChromeFamilyApp(result.target.appName, result.target.bundleId)) {
|
|
754
|
+
const tab = await cdpTabForWindow(result.target.windowTitle, result.target.framePoints);
|
|
755
|
+
const entries = tab?.drainConsole() ?? [];
|
|
756
|
+
if (entries.length > 0) {
|
|
757
|
+
details.console = entries;
|
|
758
|
+
consoleText = `\n\nBrowser console since the last action:\n${entries.map((entry) => `[${entry.level}] ${entry.text}`).join("\n")}`;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
const noteText = renderedNote ? `\n\n${renderedNote}` : "";
|
|
762
|
+
// The model must echo capture.stateId into follow-up tools. Exposing only the
|
|
763
|
+
// helper-internal lookId here makes a plausible but invalid stateId easy to use.
|
|
764
|
+
const renderedChanges = useDiff ? renderChanges(transition.changes) : "";
|
|
765
|
+
const outlineText = useDiff
|
|
766
|
+
? `\n\nChanges (${transition.changedNodeCount}, ${base.stateId} → ${result.capture.stateId}):\n${renderedChanges || "(no element changes)"}\nUse stateId ${result.capture.stateId} for subsequent actions and queries.`
|
|
767
|
+
: `\n\nOutline (${folded.nodeCount} nodes, stateId ${result.capture.stateId}${transition?.reason ? `, full view: ${transition.reason}` : ""}${folded.truncated ? ", folded output truncated" : ""}):\n${folded.text}`;
|
|
768
|
+
const fallbackText = fallbackReason ? `\n\n${fallbackReason.message}` : "";
|
|
769
|
+
const deltaText = rootDeltaLines(execution).join("\n");
|
|
770
|
+
const content = [
|
|
771
|
+
{
|
|
772
|
+
type: "text",
|
|
773
|
+
text: `${summary}${deltaText ? `\n${deltaText}` : ""}${consoleText}${noteText}${outlineText}${fallbackText}`,
|
|
774
|
+
},
|
|
775
|
+
];
|
|
776
|
+
if (fallbackReason && result.look.image?.jpegBase64) {
|
|
777
|
+
content.push({
|
|
778
|
+
type: "image",
|
|
779
|
+
data: result.look.image.jpegBase64,
|
|
780
|
+
mimeType: result.look.image.mimeType ?? "image/jpeg",
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
return { content, details };
|
|
784
|
+
}
|
|
785
|
+
function currentLookOrThrow() {
|
|
786
|
+
const state = operationState();
|
|
787
|
+
if (!state.currentLook || !state.currentCapture) {
|
|
788
|
+
throw new Error("No current look. Call observe_ui first, then act using refs or coordinates from that look.");
|
|
789
|
+
}
|
|
790
|
+
return state.currentLook;
|
|
791
|
+
}
|
|
792
|
+
function ensurePointIsInLookImage(x, y, look, errorPrefix = "Coordinates") {
|
|
793
|
+
if (!look.image?.jpegBase64) {
|
|
794
|
+
throw new Error(`${errorPrefix} require an image-bearing root. This look is outline-only; use an @e ref with a semantic action or observe an image-bearing root.`);
|
|
795
|
+
}
|
|
796
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
797
|
+
throw new Error(`${errorPrefix} must be finite numbers.`);
|
|
798
|
+
}
|
|
799
|
+
if (x < 0 || y < 0 || x >= look.image.width || y >= look.image.height) {
|
|
800
|
+
throw new Error(`${errorPrefix} (${Math.round(x)},${Math.round(y)}) are outside the latest look image bounds (${look.image.width}x${look.image.height}). Call observe_ui again and retry.`);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
function modelRefForRootDelta(delta) {
|
|
804
|
+
if (!delta.ref)
|
|
805
|
+
return undefined;
|
|
806
|
+
if (delta.ref.startsWith("@r"))
|
|
807
|
+
return delta.ref;
|
|
808
|
+
for (const record of runtimeState.windowRefs.values()) {
|
|
809
|
+
if (record.nativeWindowRef === delta.ref || record.ref === delta.ref)
|
|
810
|
+
return record.ref;
|
|
811
|
+
}
|
|
812
|
+
const ref = `@r${runtimeState.nextRootRefIndex++}`;
|
|
813
|
+
const current = operationState().currentTarget;
|
|
814
|
+
const record = {
|
|
815
|
+
ref,
|
|
816
|
+
appName: current?.pid === delta.pid ? current.appName : "Unknown App",
|
|
817
|
+
bundleId: current?.pid === delta.pid ? current.bundleId : undefined,
|
|
818
|
+
pid: delta.pid,
|
|
819
|
+
windowTitle: delta.title ?? "(untitled)",
|
|
820
|
+
nativeWindowRef: delta.ref,
|
|
821
|
+
framePoints: { x: 0, y: 0, w: 1, h: 1 },
|
|
822
|
+
scaleFactor: 1,
|
|
823
|
+
isMinimized: false,
|
|
824
|
+
isOnscreen: true,
|
|
825
|
+
isMain: false,
|
|
826
|
+
isFocused: delta.change === "focused",
|
|
827
|
+
};
|
|
828
|
+
runtimeState.windowRefs.set(ref, record);
|
|
829
|
+
runtimeState.windowRefByIdentity.set(windowRecordIdentity(record), ref);
|
|
830
|
+
return ref;
|
|
831
|
+
}
|
|
832
|
+
function executionTraceFromAct(result, policy = currentDeliveryPolicy()) {
|
|
833
|
+
const rootDelta = result.rootDelta?.map((delta) => ({ ...delta, ref: modelRefForRootDelta(delta) }));
|
|
834
|
+
return executionTrace("act", result.performed?.delivery === "ax" ? "stealth" : "default", {
|
|
835
|
+
outcome: result.outcome,
|
|
836
|
+
performed: result.performed,
|
|
837
|
+
evidence: result.evidence,
|
|
838
|
+
error: result.error,
|
|
839
|
+
stoppedAt: result.stoppedAt,
|
|
840
|
+
rootDelta,
|
|
841
|
+
delivery: result.performed?.delivery,
|
|
842
|
+
deliveryPolicy: policy,
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
async function helperAct(target, action, headless, signal) {
|
|
846
|
+
const checked = (candidate) => {
|
|
847
|
+
if (!candidate || !["worked", "didnt", "unknown"].includes(candidate.outcome)) {
|
|
848
|
+
throw new Error("Helper act returned an invalid result without an outcome.");
|
|
849
|
+
}
|
|
850
|
+
return candidate;
|
|
851
|
+
};
|
|
852
|
+
const textTimeout = "text" in action.params ? action.params.text.length * 25 + 4_000 : COMMAND_TIMEOUT_MS;
|
|
853
|
+
const timeoutMs = Math.max(COMMAND_TIMEOUT_MS, textTimeout);
|
|
854
|
+
if ((action.usesCurrentFocus || action.needsForeground) && !headless) {
|
|
855
|
+
const foreground = checked(await currentPlatformBackend.act(helperActRequest(target, action, "foreground"), { signal, timeoutMs }));
|
|
856
|
+
const trace = executionTraceFromAct(foreground, "foreground");
|
|
857
|
+
trace.backgroundFirst = false;
|
|
858
|
+
return trace;
|
|
859
|
+
}
|
|
860
|
+
try {
|
|
861
|
+
const initialPolicy = headless ? "ax_only" : "background";
|
|
862
|
+
const result = checked(await currentPlatformBackend.act(helperActRequest(target, action, initialPolicy), { signal, timeoutMs }));
|
|
863
|
+
if (canRetryInForeground(action, result.outcome, headless)) {
|
|
864
|
+
const foreground = checked(await currentPlatformBackend.act(helperActRequest(target, action, "foreground"), { signal, timeoutMs }));
|
|
865
|
+
const trace = executionTraceFromAct(foreground, "foreground");
|
|
866
|
+
trace.backgroundFirst = true;
|
|
867
|
+
trace.escalatedToForeground = true;
|
|
868
|
+
trace.escalationReason = "side_effect_free_didnt";
|
|
869
|
+
trace.backgroundAttempt = {
|
|
870
|
+
outcome: "didnt",
|
|
871
|
+
reason: "Background input produced no observable value change; a foreground retry was safe.",
|
|
872
|
+
};
|
|
873
|
+
return trace;
|
|
874
|
+
}
|
|
875
|
+
const trace = executionTraceFromAct(result, "background");
|
|
876
|
+
trace.backgroundFirst = true;
|
|
877
|
+
return trace;
|
|
878
|
+
}
|
|
879
|
+
catch (error) {
|
|
880
|
+
const code = error?.code;
|
|
881
|
+
if (code !== "foreground_required" || headless)
|
|
882
|
+
throw error;
|
|
883
|
+
const foreground = checked(await currentPlatformBackend.act(helperActRequest(target, action, "foreground"), { signal, timeoutMs }));
|
|
884
|
+
const trace = executionTraceFromAct(foreground, "foreground");
|
|
885
|
+
trace.backgroundFirst = true;
|
|
886
|
+
trace.escalatedToForeground = true;
|
|
887
|
+
trace.escalationReason = code;
|
|
888
|
+
trace.backgroundAttempt = {
|
|
889
|
+
outcome: "foreground_required",
|
|
890
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
891
|
+
};
|
|
892
|
+
return trace;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
function helperActRequest(target, action, policy = currentDeliveryPolicy()) {
|
|
896
|
+
const look = currentLookOrThrow();
|
|
897
|
+
const delivery = nativeInputDelivery(policy);
|
|
898
|
+
const base = { lookId: look.lookId, pid: target.pid, target: action.target, policy };
|
|
899
|
+
return (() => {
|
|
900
|
+
switch (action.action) {
|
|
901
|
+
case "press":
|
|
902
|
+
case "click":
|
|
903
|
+
return { ...base, action: action.action, params: { ...action.params, delivery } };
|
|
904
|
+
case "setText":
|
|
905
|
+
return { ...base, action: action.action, params: { text: action.params.text, delivery } };
|
|
906
|
+
case "typeText":
|
|
907
|
+
return { ...base, action: action.action, params: { text: action.params.text, delivery } };
|
|
908
|
+
case "keypress":
|
|
909
|
+
return { ...base, action: action.action, params: { keys: action.params.keys, delivery } };
|
|
910
|
+
case "scroll":
|
|
911
|
+
return {
|
|
912
|
+
...base,
|
|
913
|
+
action: action.action,
|
|
914
|
+
params: { scrollX: action.params.scrollX, scrollY: action.params.scrollY, delivery },
|
|
915
|
+
};
|
|
916
|
+
case "drag":
|
|
917
|
+
return { ...base, action: action.action, params: { path: action.params.path, delivery } };
|
|
918
|
+
case "moveMouse":
|
|
919
|
+
return { ...base, action: action.action, params: { delivery } };
|
|
920
|
+
}
|
|
921
|
+
})();
|
|
922
|
+
}
|
|
923
|
+
function rootDeltaLines(execution) {
|
|
924
|
+
return (execution.rootDelta ?? []).map((delta) => {
|
|
925
|
+
const quotedTitle = delta.title ? ` ${JSON.stringify(delta.title)}` : "";
|
|
926
|
+
const ref = delta.ref ? ` (${delta.ref.startsWith("@") ? delta.ref : `@${delta.ref}`})` : "";
|
|
927
|
+
const sheetCount = typeof delta.metadata?.sheetCount === "number" && Number.isFinite(delta.metadata.sheetCount)
|
|
928
|
+
? Math.max(0, Math.trunc(delta.metadata.sheetCount))
|
|
929
|
+
: undefined;
|
|
930
|
+
const flags = [delta.isModal ? "modal" : undefined, sheetCount ? `sheets=${sheetCount}` : undefined]
|
|
931
|
+
.filter(Boolean)
|
|
932
|
+
.join(", ");
|
|
933
|
+
const suffix = `${quotedTitle}${flags ? ` (${flags})` : ""}${ref}`;
|
|
934
|
+
if (delta.change === "appeared")
|
|
935
|
+
return `New root: ${delta.kind}${suffix}`;
|
|
936
|
+
if (delta.change === "closed")
|
|
937
|
+
return `Root closed: ${delta.kind}${suffix}`;
|
|
938
|
+
return `Root focused: ${delta.kind}${suffix}`;
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
function windowDetails(app, window, config) {
|
|
942
|
+
const storedRef = storeWindowRefForAppWindow(app, window);
|
|
943
|
+
return {
|
|
944
|
+
app: app.appName,
|
|
945
|
+
bundleId: app.bundleId,
|
|
946
|
+
pid: app.pid,
|
|
947
|
+
kind: window.kind,
|
|
948
|
+
windowTitle: window.title || "(untitled)",
|
|
949
|
+
windowId: window.windowId,
|
|
950
|
+
windowRef: storedRef.ref,
|
|
951
|
+
nativeWindowRef: window.windowRef,
|
|
952
|
+
framePoints: window.framePoints,
|
|
953
|
+
scaleFactor: window.scaleFactor,
|
|
954
|
+
isMinimized: window.isMinimized,
|
|
955
|
+
isOnscreen: window.isOnscreen,
|
|
956
|
+
isMain: window.isMain,
|
|
957
|
+
isFocused: window.isFocused,
|
|
958
|
+
isModal: window.isModal,
|
|
959
|
+
sheetCount: platformRootSheetCount(window),
|
|
960
|
+
role: window.role,
|
|
961
|
+
subrole: window.subrole,
|
|
962
|
+
pairing: platformRootPairing(window),
|
|
963
|
+
zOrder: window.zOrder,
|
|
964
|
+
browserUseAllowed: config.browser_use || !currentPlatformBackend.isBrowserApp(app.appName, app.bundleId),
|
|
965
|
+
score: scoreWindow(window),
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
function sortWindowDetails(windows) {
|
|
969
|
+
return windows.sort((a, b) => b.score - a.score || a.app.localeCompare(b.app) || a.windowTitle.localeCompare(b.windowTitle));
|
|
970
|
+
}
|
|
971
|
+
// Side effect: stores stable @r refs for discovered windows in runtimeState.
|
|
972
|
+
async function collectWindowDetails(apps, config, signal) {
|
|
973
|
+
const perApp = await Promise.all(apps.map(async (app) => ({ app, windows: await listWindows(app.pid, signal) })));
|
|
974
|
+
return sortWindowDetails(perApp.flatMap(({ app, windows }) => windows.map((window) => windowDetails(app, window, config))));
|
|
975
|
+
}
|
|
976
|
+
function collectBroadWindowDetails(roots, config) {
|
|
977
|
+
const windows = [];
|
|
978
|
+
for (const window of roots) {
|
|
979
|
+
if (!window.pid)
|
|
980
|
+
continue;
|
|
981
|
+
windows.push(windowDetails({ appName: window.appName ?? "Unknown App", bundleId: window.bundleId, pid: window.pid }, window, config));
|
|
982
|
+
}
|
|
983
|
+
return sortWindowDetails(windows);
|
|
984
|
+
}
|
|
985
|
+
async function windowDetailsForFind(query, config, signal) {
|
|
986
|
+
if (!query.app && !query.bundleId && !Number.isFinite(query.pid)) {
|
|
987
|
+
return collectBroadWindowDetails(await currentPlatformBackend.listRoots({}, signal), config);
|
|
988
|
+
}
|
|
989
|
+
const apps = (await listApps(signal)).filter((app) => appMatchesWindowQuery(app, query));
|
|
990
|
+
return await collectWindowDetails(apps, config, signal);
|
|
991
|
+
}
|
|
992
|
+
async function performListWindows(params, signal) {
|
|
993
|
+
const rawParams = params ?? {};
|
|
994
|
+
const query = {
|
|
995
|
+
text: trimOrUndefined(rawParams.text),
|
|
996
|
+
app: trimOrUndefined(rawParams.app),
|
|
997
|
+
bundleId: trimOrUndefined(rawParams.bundleId),
|
|
998
|
+
pid: Number.isFinite(rawParams.pid) ? Math.trunc(rawParams.pid) : undefined,
|
|
999
|
+
kind: rawParams.kind,
|
|
1000
|
+
};
|
|
1001
|
+
const config = getComputerUseConfig();
|
|
1002
|
+
const desktopForest = await windowDetailsForFind(query, config, signal);
|
|
1003
|
+
const includeBrowserPages = !query.pid && !query.bundleId && (!query.app || normalizeText(query.app) === "browser") && config.browser_use;
|
|
1004
|
+
const browserForest = !includeBrowserPages
|
|
1005
|
+
? []
|
|
1006
|
+
: (await listCdpPageContexts().catch(() => [])).map((page) => ({
|
|
1007
|
+
app: "Browser",
|
|
1008
|
+
pid: 0,
|
|
1009
|
+
kind: "browser_page",
|
|
1010
|
+
windowTitle: page.title || page.url,
|
|
1011
|
+
windowRef: storeBrowserRootRef(page.contextId),
|
|
1012
|
+
framePoints: { x: 0, y: 0, w: 1, h: 1 },
|
|
1013
|
+
scaleFactor: 1,
|
|
1014
|
+
isMinimized: false,
|
|
1015
|
+
isOnscreen: true,
|
|
1016
|
+
isMain: false,
|
|
1017
|
+
isFocused: false,
|
|
1018
|
+
isModal: false,
|
|
1019
|
+
zOrder: Number.MAX_SAFE_INTEGER,
|
|
1020
|
+
browserUseAllowed: true,
|
|
1021
|
+
score: 0,
|
|
1022
|
+
url: page.url,
|
|
1023
|
+
}));
|
|
1024
|
+
const allRoots = [...desktopForest, ...browserForest];
|
|
1025
|
+
const forest = allRoots.filter((root) => !query.kind || root.kind === query.kind);
|
|
1026
|
+
const ranked = forest
|
|
1027
|
+
.map((root, order) => ({
|
|
1028
|
+
root,
|
|
1029
|
+
order,
|
|
1030
|
+
match: query.text
|
|
1031
|
+
? rankedTextMatch([root.app, root.windowTitle], query.text)
|
|
1032
|
+
: { reason: "filter", score: 1 },
|
|
1033
|
+
}))
|
|
1034
|
+
.filter((entry) => entry.match)
|
|
1035
|
+
.sort((a, b) => b.match.score - a.match.score ||
|
|
1036
|
+
Number(b.root.isFocused) - Number(a.root.isFocused) ||
|
|
1037
|
+
a.root.zOrder - b.root.zOrder ||
|
|
1038
|
+
a.order - b.order);
|
|
1039
|
+
const totalMatches = ranked.length;
|
|
1040
|
+
const windows = ranked.slice(0, 12).map((entry) => entry.root);
|
|
1041
|
+
const details = {
|
|
1042
|
+
tool: "find_roots",
|
|
1043
|
+
query,
|
|
1044
|
+
windows,
|
|
1045
|
+
totalMatches,
|
|
1046
|
+
returned: windows.length,
|
|
1047
|
+
hasMore: totalMatches > windows.length,
|
|
1048
|
+
config,
|
|
1049
|
+
};
|
|
1050
|
+
const lines = windows.map(formatWindowLine);
|
|
1051
|
+
const text = lines.length
|
|
1052
|
+
? `Found ${totalMatches} matching root${totalMatches === 1 ? "" : "s"}; returned ${windows.length}${totalMatches > windows.length ? ". Refine the filters for additional roots" : ""}. Use @r refs with observe_ui({ root: "@rN" }).\n${lines.join("\n")}`
|
|
1053
|
+
: query.text || query.app || query.bundleId || query.pid || query.kind
|
|
1054
|
+
? "No roots matched the supplied filters."
|
|
1055
|
+
: "No roots are currently visible to ada-computer-use.";
|
|
1056
|
+
return { content: [{ type: "text", text }], details };
|
|
1057
|
+
}
|
|
1058
|
+
function normalizeImageMode(value) {
|
|
1059
|
+
return value === "always" || value === "never" ? value : "auto";
|
|
1060
|
+
}
|
|
1061
|
+
function isBrowserContextId(contextId) {
|
|
1062
|
+
return Boolean(contextId?.startsWith(BROWSER_CONTEXT_PREFIX));
|
|
1063
|
+
}
|
|
1064
|
+
function browserSnapshotTarget(snapshotId, ref) {
|
|
1065
|
+
if (!snapshotId || !ref)
|
|
1066
|
+
return undefined;
|
|
1067
|
+
const record = savedStates.get(snapshotId);
|
|
1068
|
+
const snapshot = record?.value.kind === "browser" ? record.value.snapshot : undefined;
|
|
1069
|
+
const target = snapshot?.targets.find((candidate) => candidate.ref === ref);
|
|
1070
|
+
if (!snapshot || !target)
|
|
1071
|
+
return undefined;
|
|
1072
|
+
return { contextId: snapshot.contextId, backendNodeId: target.backendNodeId };
|
|
1073
|
+
}
|
|
1074
|
+
function browserContextForOperation() {
|
|
1075
|
+
const contextId = operationState().contextId;
|
|
1076
|
+
return isBrowserContextId(contextId) ? contextId : undefined;
|
|
1077
|
+
}
|
|
1078
|
+
async function withBrowserWrite(contextId, work) {
|
|
1079
|
+
const state = operationState();
|
|
1080
|
+
const targetId = contextId.slice(BROWSER_CONTEXT_PREFIX.length);
|
|
1081
|
+
const resourceKey = `cdp:${targetId}`;
|
|
1082
|
+
const baseEpoch = state.epoch ?? resourceScheduler.epoch(resourceKey);
|
|
1083
|
+
const result = await resourceScheduler.write(resourceKey, baseEpoch, async (nextEpoch) => {
|
|
1084
|
+
state.resourceKey = resourceKey;
|
|
1085
|
+
state.epoch = nextEpoch;
|
|
1086
|
+
return await work();
|
|
1087
|
+
});
|
|
1088
|
+
return result.value;
|
|
1089
|
+
}
|
|
1090
|
+
function browserObservationResult(browser, resourceKey, epoch, tool, base) {
|
|
1091
|
+
savedStates.set({
|
|
1092
|
+
stateId: browser.snapshotId,
|
|
1093
|
+
resourceKey,
|
|
1094
|
+
epoch,
|
|
1095
|
+
value: { kind: "browser", snapshot: browser, outline: browser.outline },
|
|
1096
|
+
});
|
|
1097
|
+
const currentOutline = restoreOutline(browser.outline);
|
|
1098
|
+
const transition = base ? changesBetween(restoreOutline(base.outline), currentOutline) : undefined;
|
|
1099
|
+
const useDiff = Boolean(transition && !transition.useFullView);
|
|
1100
|
+
const folded = foldToBudget(currentOutline);
|
|
1101
|
+
const root = {
|
|
1102
|
+
ref: storeBrowserRootRef(browser.contextId),
|
|
1103
|
+
kind: "browser_page",
|
|
1104
|
+
title: browser.title,
|
|
1105
|
+
url: browser.url,
|
|
1106
|
+
};
|
|
1107
|
+
const details = {
|
|
1108
|
+
tool,
|
|
1109
|
+
kind: "browser_page",
|
|
1110
|
+
stateId: browser.snapshotId,
|
|
1111
|
+
baseStateId: base?.stateId,
|
|
1112
|
+
view: useDiff ? "diff" : "full",
|
|
1113
|
+
changes: useDiff ? transition?.changes : undefined,
|
|
1114
|
+
root,
|
|
1115
|
+
outline: browser.outline,
|
|
1116
|
+
renderedOutline: folded.text,
|
|
1117
|
+
};
|
|
1118
|
+
const viewText = useDiff
|
|
1119
|
+
? `Changes (${transition.changedNodeCount}, ${base.stateId} → ${browser.snapshotId}):\n${renderChanges(transition.changes) || "(no element changes)"}\nUse stateId ${browser.snapshotId} for subsequent actions and queries.`
|
|
1120
|
+
: folded.text;
|
|
1121
|
+
return {
|
|
1122
|
+
content: [
|
|
1123
|
+
{
|
|
1124
|
+
type: "text",
|
|
1125
|
+
text: `${tool} completed for ${root.ref} ${JSON.stringify(browser.title)}. State ${browser.snapshotId}.\n${viewText}`,
|
|
1126
|
+
},
|
|
1127
|
+
],
|
|
1128
|
+
details,
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
async function refreshBrowserSnapshot(contextId, tool, base) {
|
|
1132
|
+
const browser = await cdpSnapshotForContext(contextId);
|
|
1133
|
+
if (!browser)
|
|
1134
|
+
throw new Error(`Browser root '${contextId}' is no longer available. Call find_roots and observe_ui again.`);
|
|
1135
|
+
const state = operationState();
|
|
1136
|
+
const resourceKey = state.resourceKey ?? `cdp:${browser.targetId}`;
|
|
1137
|
+
return browserObservationResult(browser, resourceKey, state.epoch ?? resourceScheduler.epoch(resourceKey), tool, base);
|
|
1138
|
+
}
|
|
1139
|
+
function sliceText(value, offsetValue, _limitValue) {
|
|
1140
|
+
const offset = Math.max(0, Math.trunc(toFiniteNumber(offsetValue, 0)));
|
|
1141
|
+
const limit = UI_TEXT_PAGE_CHARS;
|
|
1142
|
+
const characters = Array.from(value);
|
|
1143
|
+
const end = Math.min(characters.length, offset + limit);
|
|
1144
|
+
return {
|
|
1145
|
+
offset,
|
|
1146
|
+
limit,
|
|
1147
|
+
totalChars: characters.length,
|
|
1148
|
+
hasMore: end < characters.length,
|
|
1149
|
+
text: offset >= characters.length ? "" : characters.slice(offset, end).join(""),
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
async function performReadText(params, signal) {
|
|
1153
|
+
const ref = trimOrUndefined(params.ref);
|
|
1154
|
+
if (ref?.startsWith("@o")) {
|
|
1155
|
+
const page = readStoredOutput(ref, params.offset);
|
|
1156
|
+
if (!page)
|
|
1157
|
+
throw new Error(`Output ref '${ref}' is unavailable or was evicted. Rerun the focused query.`);
|
|
1158
|
+
const details = { tool: "read_text", ref, ...page };
|
|
1159
|
+
const suffix = page.hasMore
|
|
1160
|
+
? `\n\ncontinue: read_text({ ref: "${ref}", offset: ${page.offset + page.limit} })`
|
|
1161
|
+
: page.complete
|
|
1162
|
+
? ""
|
|
1163
|
+
: "\n\ncontinuation storage limit reached; rerun a more focused query for the remainder";
|
|
1164
|
+
return { content: [{ type: "text", text: `${page.text || "(empty output page)"}${suffix}` }], details };
|
|
1165
|
+
}
|
|
1166
|
+
const contextId = operationState().contextId;
|
|
1167
|
+
if (isBrowserContextId(contextId)) {
|
|
1168
|
+
const snapshot = operationState().browserSnapshot;
|
|
1169
|
+
if (!snapshot || snapshot.contextId !== contextId)
|
|
1170
|
+
throw new Error(`Browser state '${params.stateId}' is unavailable. Observe the browser root again.`);
|
|
1171
|
+
if (!ref)
|
|
1172
|
+
throw new Error("read_text requires an @e ref for browser contexts; use the outline root ref for whole-page text.");
|
|
1173
|
+
const outline = restoreOutline(snapshot.outline);
|
|
1174
|
+
const node = nodeByRef(outline, ref);
|
|
1175
|
+
if (!node)
|
|
1176
|
+
throw new Error(`Browser text ref '${ref}' is unavailable in this state.`);
|
|
1177
|
+
const collect = (current) => [
|
|
1178
|
+
outlineNodeLabel(current),
|
|
1179
|
+
...current.text.map((item) => item.string),
|
|
1180
|
+
...current.children.flatMap(collect),
|
|
1181
|
+
].filter(Boolean);
|
|
1182
|
+
const value = node === outline.root ? snapshot.text : [...new Set(collect(node))].join("\n");
|
|
1183
|
+
const sliced = sliceText(value, params.offset);
|
|
1184
|
+
const details = { tool: "read_text", ref, ...sliced };
|
|
1185
|
+
return { content: [{ type: "text", text: sliced.text || "(empty text slice)" }], details };
|
|
1186
|
+
}
|
|
1187
|
+
validateStateId(params.stateId);
|
|
1188
|
+
if (!ref)
|
|
1189
|
+
throw new Error("read_text requires ref for desktop contexts. Call observe_ui/inspect_ui and use a text-bearing outline ref.");
|
|
1190
|
+
const node = outlineNodeByRef(ref);
|
|
1191
|
+
const state = operationState();
|
|
1192
|
+
if (!state.resourceKey || state.epoch === undefined)
|
|
1193
|
+
throw new Error("The observation has no live resource identity. Observe again.");
|
|
1194
|
+
const raw = (await resourceScheduler.readAt(state.resourceKey, state.epoch, async () => await currentPlatformBackend.readText({
|
|
1195
|
+
lookId: state.currentOutline.lookId,
|
|
1196
|
+
elementRef: wireRefForNode(node),
|
|
1197
|
+
offset: Math.max(0, Math.trunc(toFiniteNumber(params.offset, 0))),
|
|
1198
|
+
limit: UI_TEXT_PAGE_CHARS,
|
|
1199
|
+
}, { signal, timeoutMs: COMMAND_TIMEOUT_MS }))).value;
|
|
1200
|
+
const text = raw.text;
|
|
1201
|
+
const details = {
|
|
1202
|
+
tool: "read_text",
|
|
1203
|
+
ref,
|
|
1204
|
+
offset: raw.offset,
|
|
1205
|
+
limit: raw.limit,
|
|
1206
|
+
totalChars: raw.totalChars,
|
|
1207
|
+
hasMore: raw.hasMore,
|
|
1208
|
+
text,
|
|
1209
|
+
};
|
|
1210
|
+
return { content: [{ type: "text", text: text || "(empty text slice)" }], details };
|
|
1211
|
+
}
|
|
1212
|
+
function normalizeWaitTimeoutMs(value) {
|
|
1213
|
+
return Math.max(100, Math.min(60_000, Math.trunc(toFiniteNumber(value, 10_000))));
|
|
1214
|
+
}
|
|
1215
|
+
function conditionScopeRef(params) {
|
|
1216
|
+
const ref = trimOrUndefined(params.ref);
|
|
1217
|
+
const scopeRef = trimOrUndefined(params.scopeRef);
|
|
1218
|
+
if (ref && scopeRef)
|
|
1219
|
+
throw new Error("A UI condition accepts ref or scopeRef, not both.");
|
|
1220
|
+
return ref ?? scopeRef;
|
|
1221
|
+
}
|
|
1222
|
+
function validateCondition(params) {
|
|
1223
|
+
const text = trimOrUndefined(params.text);
|
|
1224
|
+
const role = trimOrUndefined(params.role);
|
|
1225
|
+
const value = trimOrUndefined(params.value);
|
|
1226
|
+
const scopeRef = conditionScopeRef(params);
|
|
1227
|
+
if (!text && !role && !value)
|
|
1228
|
+
throw new Error("A UI condition requires text, role, or value.");
|
|
1229
|
+
if (role && !text && !value && !scopeRef)
|
|
1230
|
+
throw new Error("A role-only UI condition requires ref or scopeRef.");
|
|
1231
|
+
if (value && !params.ref)
|
|
1232
|
+
throw new Error("A value UI condition requires an exact ref.");
|
|
1233
|
+
return {
|
|
1234
|
+
text,
|
|
1235
|
+
role,
|
|
1236
|
+
value,
|
|
1237
|
+
scopeRef,
|
|
1238
|
+
scopeExact: Boolean(params.ref),
|
|
1239
|
+
gone: params.until === "absent",
|
|
1240
|
+
timeoutMs: normalizeWaitTimeoutMs(params.timeoutMs),
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
function nodeWithinScope(node, scopeRef, scopeExact) {
|
|
1244
|
+
if (!scopeRef)
|
|
1245
|
+
return true;
|
|
1246
|
+
if (scopeExact)
|
|
1247
|
+
return node.ref === scopeRef;
|
|
1248
|
+
let current = node;
|
|
1249
|
+
while (current) {
|
|
1250
|
+
if (current.ref === scopeRef)
|
|
1251
|
+
return true;
|
|
1252
|
+
current = current.parent;
|
|
1253
|
+
}
|
|
1254
|
+
return false;
|
|
1255
|
+
}
|
|
1256
|
+
function normalizedRole(value) {
|
|
1257
|
+
return value
|
|
1258
|
+
.toLowerCase()
|
|
1259
|
+
.replace(/^ax/, "")
|
|
1260
|
+
.replace(/[ _-]+/g, "");
|
|
1261
|
+
}
|
|
1262
|
+
function platformRole(outline, role) {
|
|
1263
|
+
if (!role)
|
|
1264
|
+
return undefined;
|
|
1265
|
+
return outline.nodes.find((node) => normalizedRole(node.role) === normalizedRole(role))?.role ?? role;
|
|
1266
|
+
}
|
|
1267
|
+
function outlineConditionPresent(outline, condition) {
|
|
1268
|
+
return searchOutline(outline, condition.text, undefined, undefined, outline.nodes.length).some((match) => (!condition.role || normalizedRole(match.node.role) === normalizedRole(condition.role)) &&
|
|
1269
|
+
nodeWithinScope(match.node, condition.scopeRef, condition.scopeExact) &&
|
|
1270
|
+
(!condition.value || normalizeText(match.node.value) === normalizeText(condition.value)));
|
|
1271
|
+
}
|
|
1272
|
+
function conditionScopeNode(outline, condition) {
|
|
1273
|
+
const scopeNode = condition.scopeRef ? nodeByRef(outline, condition.scopeRef) : undefined;
|
|
1274
|
+
if (condition.scopeRef && !scopeNode)
|
|
1275
|
+
throw new Error(`Condition scope ref '${condition.scopeRef}' is unavailable in this state.`);
|
|
1276
|
+
return scopeNode;
|
|
1277
|
+
}
|
|
1278
|
+
async function performWaitFor(params, signal) {
|
|
1279
|
+
const contextId = operationState().contextId;
|
|
1280
|
+
const condition = validateCondition(params);
|
|
1281
|
+
const { text, role, value, scopeRef, scopeExact, gone, timeoutMs } = condition;
|
|
1282
|
+
if (isBrowserContextId(contextId)) {
|
|
1283
|
+
const state = operationState();
|
|
1284
|
+
if (!state.resourceKey)
|
|
1285
|
+
throw new Error("The browser observation has no live resource identity. Observe again.");
|
|
1286
|
+
const baseSnapshot = state.browserSnapshot;
|
|
1287
|
+
if (!baseSnapshot)
|
|
1288
|
+
throw new Error("Browser wait requires a complete base observation.");
|
|
1289
|
+
conditionScopeNode(restoreOutline(baseSnapshot.outline), condition);
|
|
1290
|
+
const deadline = Date.now() + timeoutMs;
|
|
1291
|
+
let lastSnapshot;
|
|
1292
|
+
let lastEpoch = state.epoch ?? resourceScheduler.epoch(state.resourceKey);
|
|
1293
|
+
const finish = (found, timedOut) => {
|
|
1294
|
+
if (!lastSnapshot)
|
|
1295
|
+
throw new Error("Browser wait completed without an observation.");
|
|
1296
|
+
savedStates.set({
|
|
1297
|
+
stateId: lastSnapshot.snapshotId,
|
|
1298
|
+
resourceKey: state.resourceKey,
|
|
1299
|
+
epoch: lastEpoch,
|
|
1300
|
+
value: { kind: "browser", snapshot: lastSnapshot, outline: lastSnapshot.outline },
|
|
1301
|
+
});
|
|
1302
|
+
const successorOutline = restoreOutline(lastSnapshot.outline);
|
|
1303
|
+
const transition = changesBetween(restoreOutline(baseSnapshot.outline), successorOutline);
|
|
1304
|
+
const useDiff = !transition.useFullView;
|
|
1305
|
+
const renderedOutline = foldToBudget(successorOutline).text;
|
|
1306
|
+
const details = {
|
|
1307
|
+
tool: "wait_for",
|
|
1308
|
+
stateId: lastSnapshot.snapshotId,
|
|
1309
|
+
baseStateId: baseSnapshot.snapshotId,
|
|
1310
|
+
view: useDiff ? "diff" : "full",
|
|
1311
|
+
changes: useDiff ? transition.changes : undefined,
|
|
1312
|
+
found,
|
|
1313
|
+
gone: (found && gone) || undefined,
|
|
1314
|
+
timedOut,
|
|
1315
|
+
nodeCount: lastSnapshot.targets.length,
|
|
1316
|
+
text,
|
|
1317
|
+
role,
|
|
1318
|
+
value,
|
|
1319
|
+
scopeRef,
|
|
1320
|
+
outline: lastSnapshot.outline,
|
|
1321
|
+
renderedOutline,
|
|
1322
|
+
};
|
|
1323
|
+
const message = found
|
|
1324
|
+
? gone
|
|
1325
|
+
? "Condition disappeared."
|
|
1326
|
+
: "Condition appeared."
|
|
1327
|
+
: `Timed out after ${timeoutMs}ms waiting for condition.`;
|
|
1328
|
+
const viewText = useDiff
|
|
1329
|
+
? `${renderChanges(transition.changes) || "(no element changes)"}\nUse stateId ${lastSnapshot.snapshotId} for subsequent actions and queries.`
|
|
1330
|
+
: renderedOutline;
|
|
1331
|
+
return { content: [{ type: "text", text: `${message}\n${viewText}` }], details };
|
|
1332
|
+
};
|
|
1333
|
+
do {
|
|
1334
|
+
const scheduled = await resourceScheduler.read(state.resourceKey, async () => await cdpSnapshotForContext(contextId));
|
|
1335
|
+
lastSnapshot = scheduled.value;
|
|
1336
|
+
lastEpoch = scheduled.epoch;
|
|
1337
|
+
if (!lastSnapshot)
|
|
1338
|
+
throw new Error(`Browser root '${contextId}' is no longer available. Call find_roots and observe_ui again.`);
|
|
1339
|
+
const present = outlineConditionPresent(restoreOutline(lastSnapshot.outline), condition);
|
|
1340
|
+
if (present !== gone)
|
|
1341
|
+
return finish(true);
|
|
1342
|
+
await sleep(200, signal);
|
|
1343
|
+
} while (Date.now() < deadline);
|
|
1344
|
+
return finish(false, true);
|
|
1345
|
+
}
|
|
1346
|
+
const state = operationState();
|
|
1347
|
+
const baseView = { stateId: state.currentCapture.stateId, outline: state.currentOutline };
|
|
1348
|
+
let target = await resolveCurrentTarget(signal);
|
|
1349
|
+
target = await ensureTargetWindowId(target, signal);
|
|
1350
|
+
const scopeNode = conditionScopeNode(state.currentOutline, condition);
|
|
1351
|
+
const raw = await currentPlatformBackend.waitFor({
|
|
1352
|
+
...nativeWindowRequest(target),
|
|
1353
|
+
lookId: state.currentOutline.lookId,
|
|
1354
|
+
text,
|
|
1355
|
+
role: platformRole(state.currentOutline, role),
|
|
1356
|
+
value,
|
|
1357
|
+
scopeRef: scopeNode ? wireRefForNode(scopeNode) : undefined,
|
|
1358
|
+
scopeExact,
|
|
1359
|
+
gone,
|
|
1360
|
+
timeoutMs,
|
|
1361
|
+
}, { signal, timeoutMs: timeoutMs + 2_000 });
|
|
1362
|
+
if (!state.resourceKey || state.epoch === undefined)
|
|
1363
|
+
throw new Error("The observation has no live resource identity. Observe again.");
|
|
1364
|
+
const refreshed = (await resourceScheduler.readAt(state.resourceKey, state.epoch, async () => await captureCurrentTarget(signal, "auto"))).value;
|
|
1365
|
+
const transition = changesBetween(baseView.outline, refreshed.outline);
|
|
1366
|
+
const useDiff = !transition.useFullView;
|
|
1367
|
+
const matches = searchOutline(refreshed.outline, text, role, undefined, 1);
|
|
1368
|
+
const foundTarget = matches[0];
|
|
1369
|
+
const details = {
|
|
1370
|
+
tool: "wait_for",
|
|
1371
|
+
stateId: refreshed.capture.stateId,
|
|
1372
|
+
baseStateId: baseView.stateId,
|
|
1373
|
+
view: useDiff ? "diff" : "full",
|
|
1374
|
+
changes: useDiff ? transition.changes : undefined,
|
|
1375
|
+
found: raw.found,
|
|
1376
|
+
gone: raw.gone || undefined,
|
|
1377
|
+
timedOut: raw.timedOut || undefined,
|
|
1378
|
+
target: foundTarget ? serializeOutlineSearchMatch(foundTarget) : undefined,
|
|
1379
|
+
nodeCount: Number.isFinite(raw.nodeCount) ? Number(raw.nodeCount) : refreshed.outline.nodes.length,
|
|
1380
|
+
text,
|
|
1381
|
+
role,
|
|
1382
|
+
value,
|
|
1383
|
+
scopeRef,
|
|
1384
|
+
outline: serializeOutline(refreshed.outline),
|
|
1385
|
+
renderedOutline: foldToBudget(refreshed.outline).text,
|
|
1386
|
+
};
|
|
1387
|
+
const message = details.found
|
|
1388
|
+
? details.gone
|
|
1389
|
+
? "Condition disappeared."
|
|
1390
|
+
: "Condition appeared."
|
|
1391
|
+
: `Timed out after ${timeoutMs}ms waiting for condition.`;
|
|
1392
|
+
const viewText = useDiff
|
|
1393
|
+
? `${renderChanges(transition.changes) || "(no element changes)"}\nUse stateId ${refreshed.capture.stateId} for subsequent actions and queries.`
|
|
1394
|
+
: details.renderedOutline;
|
|
1395
|
+
return { content: [{ type: "text", text: `${message}\n${viewText}` }], details };
|
|
1396
|
+
}
|
|
1397
|
+
function sameRootIdentity(a, b) {
|
|
1398
|
+
if (a.pid !== b.pid)
|
|
1399
|
+
return false;
|
|
1400
|
+
if (a.windowId > 0 && b.windowId > 0)
|
|
1401
|
+
return a.windowId === b.windowId;
|
|
1402
|
+
if (a.nativeWindowRef && b.nativeWindowRef)
|
|
1403
|
+
return a.nativeWindowRef === b.nativeWindowRef;
|
|
1404
|
+
return normalizeText(a.windowTitle) === normalizeText(b.windowTitle);
|
|
1405
|
+
}
|
|
1406
|
+
/** Side effects: captures/updates current target, capture state, look, and parsed outline. */
|
|
1407
|
+
async function performObserve(params, signal) {
|
|
1408
|
+
const requestedRoot = typeof params.root === "string" ? params.root : undefined;
|
|
1409
|
+
if (requestedRoot && !/^@r\d+$/.test(requestedRoot))
|
|
1410
|
+
throw new Error("observe_ui.root must be an exact @r ref issued by find_roots.");
|
|
1411
|
+
const browserContextId = requestedRoot ? runtimeState.browserContextByRoot.get(requestedRoot) : undefined;
|
|
1412
|
+
if (isBrowserContextId(browserContextId)) {
|
|
1413
|
+
const targetId = browserContextId.slice(BROWSER_CONTEXT_PREFIX.length);
|
|
1414
|
+
const resourceKey = `cdp:${targetId}`;
|
|
1415
|
+
const scheduled = await resourceScheduler.read(resourceKey, async () => await cdpSnapshotForContext(browserContextId));
|
|
1416
|
+
const browser = scheduled.value;
|
|
1417
|
+
if (!browser)
|
|
1418
|
+
throw new Error(`Browser context '${browserContextId}' is no longer available. Call find_roots again.`);
|
|
1419
|
+
return browserObservationResult(browser, resourceKey, scheduled.epoch, "observe_ui");
|
|
1420
|
+
}
|
|
1421
|
+
const state = operationState();
|
|
1422
|
+
const mode = params.mode ?? "fused";
|
|
1423
|
+
const image = mode === "semantic" ? "never" : mode === "visual" ? "always" : "auto";
|
|
1424
|
+
const defaultReadText = mode === "semantic" ? "never" : mode === "visual" ? "always" : "auto";
|
|
1425
|
+
const readText = params.readText ?? defaultReadText;
|
|
1426
|
+
state.currentImageMode = normalizeImageMode(image);
|
|
1427
|
+
const selection = { root: normalizeWindowSelector(params.root) };
|
|
1428
|
+
const requestedTarget = selection.root
|
|
1429
|
+
? await resolveTargetByWindowSelector(params.root, signal)
|
|
1430
|
+
: await resolveTargetForObserve(signal);
|
|
1431
|
+
const imageMode = normalizeImageMode(image);
|
|
1432
|
+
const resourceKey = desktopResourceKey(requestedTarget);
|
|
1433
|
+
const scheduled = await resourceScheduler.read(resourceKey, async (epoch) => {
|
|
1434
|
+
state.resourceKey = resourceKey;
|
|
1435
|
+
state.epoch = epoch;
|
|
1436
|
+
return await captureCurrentTarget(signal, readText, imageMode === "always" ? EXPLICIT_IMAGE_MAX_DIMENSION : AUTO_IMAGE_MAX_DIMENSION, requestedTarget, imageMode !== "never");
|
|
1437
|
+
});
|
|
1438
|
+
const captureResult = scheduled.value;
|
|
1439
|
+
// Model @r refs are re-minted on re-resolution, so ref string equality
|
|
1440
|
+
// alone false-positives as drift for the same root; compare stable
|
|
1441
|
+
// identity against the resolved request too.
|
|
1442
|
+
if (!matchesObserveSelection(captureResult.target, selection) &&
|
|
1443
|
+
!sameRootIdentity(captureResult.target, requestedTarget)) {
|
|
1444
|
+
throw new Error(`Observation target drifted from the requested selection. Requested ${requestedTarget.appName} — ${requestedTarget.windowTitle}, captured ${captureResult.target.appName} — ${captureResult.target.windowTitle}. Call observe_ui again or specify a more exact window title.`);
|
|
1445
|
+
}
|
|
1446
|
+
const summary = `Observed ${mode} ${captureResult.target.windowRef ? `${captureResult.target.windowRef} ` : ""}${captureResult.target.appName} — ${captureResult.target.windowTitle}. Returned the latest outline state.`;
|
|
1447
|
+
return await buildToolResult("observe_ui", summary, captureResult, executionTrace("look", "stealth"), signal, imageMode);
|
|
1448
|
+
}
|
|
1449
|
+
function currentOutlineOrThrow(stateId) {
|
|
1450
|
+
validateStateId(stateId);
|
|
1451
|
+
const outline = operationState().currentOutline;
|
|
1452
|
+
if (!outline)
|
|
1453
|
+
throw new Error("No observation outline is available. Call observe_ui first.");
|
|
1454
|
+
return outline;
|
|
1455
|
+
}
|
|
1456
|
+
function matchIsNonActionableStatic(match) {
|
|
1457
|
+
const node = match.node;
|
|
1458
|
+
return !node.canPress && !node.canFocus && !node.canSetValue && node.actions.length === 0 && !node.pictureOnly;
|
|
1459
|
+
}
|
|
1460
|
+
function shouldEscalateSearchOCR(matches, _text) {
|
|
1461
|
+
return matches.length === 0 || matches.every(matchIsNonActionableStatic);
|
|
1462
|
+
}
|
|
1463
|
+
/** Pure outline query unless a window selector is supplied, in which case current target selection may change. */
|
|
1464
|
+
async function performSearchUi(params, signal) {
|
|
1465
|
+
const state = operationState();
|
|
1466
|
+
let outline = currentOutlineOrThrow(params.stateId);
|
|
1467
|
+
const text = trimOrUndefined(params.text);
|
|
1468
|
+
const role = trimOrUndefined(params.role);
|
|
1469
|
+
const capability = trimOrUndefined(params.capability);
|
|
1470
|
+
if (!text && !role && !capability)
|
|
1471
|
+
throw new Error("search_ui requires text, role, or capability. Use observe_ui for a bounded overview.");
|
|
1472
|
+
const limit = 12;
|
|
1473
|
+
let ranked = searchOutlineRanked(outline, text, role, capability, limit);
|
|
1474
|
+
let matches = ranked.matches;
|
|
1475
|
+
let escalatedOCR = false;
|
|
1476
|
+
const look = state.currentLook;
|
|
1477
|
+
if (shouldEscalateSearchOCR(matches, text) &&
|
|
1478
|
+
look &&
|
|
1479
|
+
look.readText?.requested !== "never" &&
|
|
1480
|
+
!look.readText?.executed &&
|
|
1481
|
+
state.lastSearchOcrEscalatedLookId !== look.lookId) {
|
|
1482
|
+
state.lastSearchOcrEscalatedLookId = look.lookId;
|
|
1483
|
+
const currentTarget = await ensureTargetWindowId(await resolveCurrentTarget(signal), signal);
|
|
1484
|
+
// captureCurrentTarget adopts the new look/outline/capture into
|
|
1485
|
+
// runtimeState, so refs in these matches stay actable. Keep the image
|
|
1486
|
+
// payload: OCR-only matches are clicked by coordinate, and coordinate
|
|
1487
|
+
// acts require the current look to be image-bearing.
|
|
1488
|
+
if (!state.resourceKey || state.epoch === undefined)
|
|
1489
|
+
throw new Error("The observation has no live resource identity. Observe again.");
|
|
1490
|
+
const captureResult = (await resourceScheduler.readAt(state.resourceKey, state.epoch, async () => await captureCurrentTarget(signal, "always", AUTO_IMAGE_MAX_DIMENSION, currentTarget))).value;
|
|
1491
|
+
outline = captureResult.outline;
|
|
1492
|
+
ranked = searchOutlineRanked(outline, text, role, capability, limit);
|
|
1493
|
+
matches = ranked.matches;
|
|
1494
|
+
escalatedOCR = true;
|
|
1495
|
+
}
|
|
1496
|
+
const detailMatches = matches.map(serializeOutlineSearchMatch);
|
|
1497
|
+
const details = {
|
|
1498
|
+
tool: "search_ui",
|
|
1499
|
+
stateId: state.currentCapture?.stateId,
|
|
1500
|
+
lookId: outline.lookId,
|
|
1501
|
+
matches: detailMatches,
|
|
1502
|
+
totalMatches: ranked.totalMatches,
|
|
1503
|
+
returned: matches.length,
|
|
1504
|
+
hasMore: ranked.totalMatches > matches.length,
|
|
1505
|
+
note: state.currentNote,
|
|
1506
|
+
};
|
|
1507
|
+
const lines = matches.map((match) => `${match.ref} ${match.role || "Unknown"} ${JSON.stringify(match.label || "(unlabeled)")} [${match.matchReason}${match.matchReason === "fuzzy" ? ` ${match.score?.toFixed(2)}` : ""}]\n path: ${match.path}`);
|
|
1508
|
+
const noteHeader = renderNote(state.currentNote);
|
|
1509
|
+
const noteText = noteHeader ? `${noteHeader}\n\n` : "";
|
|
1510
|
+
const escalationText = escalatedOCR
|
|
1511
|
+
? " OCR text was escalated for this search after the cached outline had no matches."
|
|
1512
|
+
: "";
|
|
1513
|
+
const moreText = ranked.totalMatches > matches.length
|
|
1514
|
+
? ` Refine the query to inspect ${ranked.totalMatches - matches.length} additional matches.`
|
|
1515
|
+
: "";
|
|
1516
|
+
return {
|
|
1517
|
+
content: [
|
|
1518
|
+
{
|
|
1519
|
+
type: "text",
|
|
1520
|
+
text: `${noteText}Found ${ranked.totalMatches} outline match${ranked.totalMatches === 1 ? "" : "es"}; returned ${matches.length}.${moreText}${escalationText}\n${lines.join("\n")}`,
|
|
1521
|
+
},
|
|
1522
|
+
],
|
|
1523
|
+
details,
|
|
1524
|
+
};
|
|
1525
|
+
}
|
|
1526
|
+
/** Reads cached outline; truncated refs trigger a scoped look. */
|
|
1527
|
+
async function performExpandUi(params, signal) {
|
|
1528
|
+
const state = operationState();
|
|
1529
|
+
const outline = currentOutlineOrThrow(params.stateId);
|
|
1530
|
+
const ref = trimOrUndefined(params.ref);
|
|
1531
|
+
if (!ref)
|
|
1532
|
+
throw new Error("expand_ui.ref is required.");
|
|
1533
|
+
const initialTarget = nodeByRef(outline, ref);
|
|
1534
|
+
if (!initialTarget)
|
|
1535
|
+
throw new Error(`Outline ref '${ref}' is not available in the current outline.`);
|
|
1536
|
+
let target = initialTarget;
|
|
1537
|
+
const depth = Math.max(1, Math.min(8, Math.trunc(toFiniteNumber(params.depth, 3))));
|
|
1538
|
+
const regionKey = noteRegionKeyForRef(outline, ref);
|
|
1539
|
+
const regionChanged = Boolean(regionKey && state.currentNote?.regions.some((region) => region.key === regionKey && region.status === "changed"));
|
|
1540
|
+
if (target.truncated || regionChanged) {
|
|
1541
|
+
const currentTarget = await ensureTargetWindowId(await resolveCurrentTarget(signal), signal);
|
|
1542
|
+
const targetWireRef = wireRefForNode(target);
|
|
1543
|
+
if (!state.resourceKey || state.epoch === undefined)
|
|
1544
|
+
throw new Error("The observation has no live resource identity. Observe again.");
|
|
1545
|
+
const scoped = (await resourceScheduler.readAt(state.resourceKey, state.epoch, async () => await performLook(currentTarget, {
|
|
1546
|
+
readText: "auto",
|
|
1547
|
+
baseLookId: outline.lookId,
|
|
1548
|
+
scopeRef: targetWireRef,
|
|
1549
|
+
maxDimension: 1,
|
|
1550
|
+
includeImage: false,
|
|
1551
|
+
}, signal))).value;
|
|
1552
|
+
target = graftScopedOutline(outline, target.ref, scoped.parsedOutline);
|
|
1553
|
+
outline.lookId = scoped.lookId;
|
|
1554
|
+
state.currentOutline = outline;
|
|
1555
|
+
state.currentLook = { ...scoped, image: state.currentLook?.image, outline: outline.root, parsedOutline: outline };
|
|
1556
|
+
persistOperation(state);
|
|
1557
|
+
}
|
|
1558
|
+
const folded = foldToBudget(outline, { maxDepth: depth, maxNodes: 150 }, [target.ref]);
|
|
1559
|
+
const details = {
|
|
1560
|
+
tool: "expand_ui",
|
|
1561
|
+
stateId: state.currentCapture?.stateId,
|
|
1562
|
+
lookId: outline.lookId,
|
|
1563
|
+
target: serializeOutlineNodeShallow(target),
|
|
1564
|
+
renderedOutline: folded.text,
|
|
1565
|
+
note: state.currentNote,
|
|
1566
|
+
};
|
|
1567
|
+
return {
|
|
1568
|
+
content: [
|
|
1569
|
+
{
|
|
1570
|
+
type: "text",
|
|
1571
|
+
text: `${formatOutlineNodeLabel(target)}\npath: ${outlineNodePath(target)}\n\n${folded.text}`,
|
|
1572
|
+
},
|
|
1573
|
+
],
|
|
1574
|
+
details,
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
/** Pure cached-outline inspection. */
|
|
1578
|
+
async function performInspectUi(params) {
|
|
1579
|
+
const state = operationState();
|
|
1580
|
+
const outline = currentOutlineOrThrow(params.stateId);
|
|
1581
|
+
const ref = trimOrUndefined(params.ref);
|
|
1582
|
+
if (!ref)
|
|
1583
|
+
throw new Error("inspect_ui.ref is required.");
|
|
1584
|
+
const target = nodeByRef(outline, ref);
|
|
1585
|
+
if (!target)
|
|
1586
|
+
throw new Error(`Outline ref '${ref}' is not available in the current outline.`);
|
|
1587
|
+
const details = {
|
|
1588
|
+
tool: "inspect_ui",
|
|
1589
|
+
stateId: state.currentCapture?.stateId,
|
|
1590
|
+
lookId: outline.lookId,
|
|
1591
|
+
target: serializeOutlineNodeShallow(target),
|
|
1592
|
+
note: state.currentNote,
|
|
1593
|
+
};
|
|
1594
|
+
const fields = [
|
|
1595
|
+
formatOutlineNodeLabel(target),
|
|
1596
|
+
`path: ${outlineNodePath(target)}`,
|
|
1597
|
+
`rect: ${JSON.stringify(target.rect)}`,
|
|
1598
|
+
`actions: ${target.actions.join(",") || "none"}`,
|
|
1599
|
+
`capabilities: ${[
|
|
1600
|
+
target.canPress ? "press" : undefined,
|
|
1601
|
+
target.canFocus ? "focus" : undefined,
|
|
1602
|
+
target.canSetValue ? "setValue" : undefined,
|
|
1603
|
+
target.canScroll ? "scroll" : undefined,
|
|
1604
|
+
target.canIncrement ? "increment" : undefined,
|
|
1605
|
+
target.canDecrement ? "decrement" : undefined,
|
|
1606
|
+
target.isTextInput ? "textInput" : undefined,
|
|
1607
|
+
]
|
|
1608
|
+
.filter(Boolean)
|
|
1609
|
+
.join(",") || "none"}`,
|
|
1610
|
+
`annotations: ${[
|
|
1611
|
+
target.offscreen ? "offscreen" : undefined,
|
|
1612
|
+
target.pictureOnly ? "pictureOnly" : undefined,
|
|
1613
|
+
target.truncated ? "truncated" : undefined,
|
|
1614
|
+
target.scrollExtent ? `scrollable ${target.scrollExtent.seen}/${target.scrollExtent.total}` : undefined,
|
|
1615
|
+
]
|
|
1616
|
+
.filter(Boolean)
|
|
1617
|
+
.join(",") || "none"}`,
|
|
1618
|
+
];
|
|
1619
|
+
return { content: [{ type: "text", text: fields.join("\n") }], details };
|
|
1620
|
+
}
|
|
1621
|
+
function prepareUiAction(action, state, look, headless) {
|
|
1622
|
+
return prepareAction(action, state, {
|
|
1623
|
+
headless,
|
|
1624
|
+
image: look.image,
|
|
1625
|
+
node: outlineNodeByRef,
|
|
1626
|
+
center: outlineNodeCenter,
|
|
1627
|
+
validatePoint: (x, y, label) => ensurePointIsInLookImage(x, y, look, label),
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
async function dispatchUiAction(action, target, look, headless, state, signal) {
|
|
1631
|
+
const prepared = prepareUiAction(action, state, look, headless);
|
|
1632
|
+
if (prepared.action === "wait") {
|
|
1633
|
+
await sleep(prepared.params.ms, signal);
|
|
1634
|
+
return executionTrace("wait", "stealth", { outcome: "worked" });
|
|
1635
|
+
}
|
|
1636
|
+
const trace = await helperAct(target, prepared, headless, signal);
|
|
1637
|
+
if (!headless && (prepared.establishesFocus || (prepared.action === "click" && "x" in prepared.target))) {
|
|
1638
|
+
state.currentFocus = true;
|
|
1639
|
+
}
|
|
1640
|
+
return trace;
|
|
1641
|
+
}
|
|
1642
|
+
async function dispatchUiTransaction(actions, target, look, headless, signal) {
|
|
1643
|
+
// Strict-headless batches have one immutable delivery class. When foreground
|
|
1644
|
+
// fallback is permitted, decide independently per action so a completed
|
|
1645
|
+
// background prefix is never replayed as part of a foreground batch.
|
|
1646
|
+
if (headless && currentPlatformBackend.actBatch) {
|
|
1647
|
+
const actionState = { currentFocus: false };
|
|
1648
|
+
const requests = actions.map((action) => helperActRequest(target, prepareUiAction(action, actionState, look, true), "ax_only"));
|
|
1649
|
+
const textLength = actions.reduce((sum, action) => sum + (action.text?.length ?? 0), 0);
|
|
1650
|
+
const result = await currentPlatformBackend.actBatch(requests, {
|
|
1651
|
+
signal,
|
|
1652
|
+
timeoutMs: Math.max(COMMAND_TIMEOUT_MS, textLength * 25 + 6_000),
|
|
1653
|
+
});
|
|
1654
|
+
if (!result.steps || result.steps.length === 0)
|
|
1655
|
+
throw new Error("Native action transaction returned no checked steps.");
|
|
1656
|
+
const execution = aggregateExecutions(result.steps.map((step) => executionTraceFromAct(step, "ax_only")));
|
|
1657
|
+
const batchTrace = executionTraceFromAct(result, "ax_only");
|
|
1658
|
+
execution.outcome = result.outcome;
|
|
1659
|
+
execution.performed = result.performed;
|
|
1660
|
+
execution.rootDelta = batchTrace.rootDelta;
|
|
1661
|
+
execution.stoppedAt = result.stoppedAt;
|
|
1662
|
+
return execution;
|
|
1663
|
+
}
|
|
1664
|
+
const steps = [];
|
|
1665
|
+
const actionState = { currentFocus: false };
|
|
1666
|
+
for (const action of actions) {
|
|
1667
|
+
const step = await dispatchUiAction(action, target, look, headless, actionState, signal);
|
|
1668
|
+
steps.push(step);
|
|
1669
|
+
if (step.outcome === "didnt")
|
|
1670
|
+
break;
|
|
1671
|
+
}
|
|
1672
|
+
return aggregateExecutions(steps);
|
|
1673
|
+
}
|
|
1674
|
+
function aggregateExecutions(steps) {
|
|
1675
|
+
const outcomes = steps.map((step) => step.outcome);
|
|
1676
|
+
const outcome = outcomes.includes("didnt")
|
|
1677
|
+
? "didnt"
|
|
1678
|
+
: outcomes.includes("unknown")
|
|
1679
|
+
? "unknown"
|
|
1680
|
+
: "worked";
|
|
1681
|
+
const fallback = steps.find((step) => step.escalatedToForeground);
|
|
1682
|
+
return executionTrace("act", steps.every((step) => step.variant === "stealth") ? "stealth" : "default", {
|
|
1683
|
+
outcome,
|
|
1684
|
+
steps,
|
|
1685
|
+
actionCount: steps.length,
|
|
1686
|
+
rootDelta: steps.flatMap((step) => step.rootDelta ?? []),
|
|
1687
|
+
backgroundFirst: true,
|
|
1688
|
+
escalatedToForeground: Boolean(fallback),
|
|
1689
|
+
escalationReason: fallback?.escalationReason,
|
|
1690
|
+
backgroundAttempt: fallback?.backgroundAttempt,
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
function exactPlatformRootMatchesTarget(root, target) {
|
|
1694
|
+
if (root.pid !== target.pid)
|
|
1695
|
+
return false;
|
|
1696
|
+
const nativeRefMatches = Boolean(target.nativeWindowRef && (root.rootRef === target.nativeWindowRef || root.windowRef === target.nativeWindowRef));
|
|
1697
|
+
const windowIdMatches = target.windowId > 0 && root.windowId === target.windowId;
|
|
1698
|
+
return nativeRefMatches || windowIdMatches;
|
|
1699
|
+
}
|
|
1700
|
+
function clearDesktopOperationState(state) {
|
|
1701
|
+
state.currentTarget = undefined;
|
|
1702
|
+
state.currentCapture = undefined;
|
|
1703
|
+
state.currentStateTarget = undefined;
|
|
1704
|
+
state.currentLook = undefined;
|
|
1705
|
+
state.currentOutline = undefined;
|
|
1706
|
+
state.currentNote = undefined;
|
|
1707
|
+
}
|
|
1708
|
+
async function terminalDesktopActionResult(target, baseStateId, execution, error, condition) {
|
|
1709
|
+
let exactRootAvailable;
|
|
1710
|
+
try {
|
|
1711
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1712
|
+
const roots = await currentPlatformBackend.listRoots({ pid: target.pid });
|
|
1713
|
+
exactRootAvailable = roots.some((root) => exactPlatformRootMatchesTarget(root, target));
|
|
1714
|
+
if (exactRootAvailable)
|
|
1715
|
+
break;
|
|
1716
|
+
if (attempt < 2)
|
|
1717
|
+
await sleep(75);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
catch {
|
|
1721
|
+
// A failed identity probe cannot prove that the root closed.
|
|
1722
|
+
}
|
|
1723
|
+
const targetClosed = exactRootAvailable === false;
|
|
1724
|
+
if (targetClosed &&
|
|
1725
|
+
!(execution.rootDelta ?? []).some((delta) => delta.change === "closed" &&
|
|
1726
|
+
delta.pid === target.pid &&
|
|
1727
|
+
(delta.ref === target.windowRef || delta.ref === target.nativeWindowRef))) {
|
|
1728
|
+
execution.rootDelta = [
|
|
1729
|
+
...(execution.rootDelta ?? []),
|
|
1730
|
+
{
|
|
1731
|
+
change: "closed",
|
|
1732
|
+
kind: "window",
|
|
1733
|
+
ref: target.windowRef,
|
|
1734
|
+
title: target.windowTitle,
|
|
1735
|
+
pid: target.pid,
|
|
1736
|
+
metadata: { source: "post_action_identity_probe" },
|
|
1737
|
+
},
|
|
1738
|
+
];
|
|
1739
|
+
}
|
|
1740
|
+
if (targetClosed && condition) {
|
|
1741
|
+
const verificationStatus = condition.gone ? "verified" : "failed";
|
|
1742
|
+
execution.verification = {
|
|
1743
|
+
status: verificationStatus,
|
|
1744
|
+
text: condition.text,
|
|
1745
|
+
role: condition.role,
|
|
1746
|
+
value: condition.value,
|
|
1747
|
+
gone: condition.gone || undefined,
|
|
1748
|
+
timeoutMs: condition.timeoutMs,
|
|
1749
|
+
};
|
|
1750
|
+
execution.outcome = outcomeAfterCheck(execution.outcome ?? "unknown", verificationStatus);
|
|
1751
|
+
if (verificationStatus === "failed") {
|
|
1752
|
+
execution.error = {
|
|
1753
|
+
code: "postcondition_failed",
|
|
1754
|
+
message: "The source root closed before the requested presence or value postcondition could be verified.",
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
const status = targetClosed ? "target_closed" : "post_action_observation_failed";
|
|
1759
|
+
const code = targetClosed ? "target_closed" : "post_action_observation_failed";
|
|
1760
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1761
|
+
clearDesktopOperationState(operationState());
|
|
1762
|
+
const details = {
|
|
1763
|
+
tool: "act_ui",
|
|
1764
|
+
status,
|
|
1765
|
+
baseStateId,
|
|
1766
|
+
target: {
|
|
1767
|
+
app: target.appName,
|
|
1768
|
+
bundleId: target.bundleId,
|
|
1769
|
+
pid: target.pid,
|
|
1770
|
+
windowTitle: target.windowTitle,
|
|
1771
|
+
windowId: target.windowId,
|
|
1772
|
+
windowRef: target.windowRef,
|
|
1773
|
+
nativeWindowRef: target.nativeWindowRef,
|
|
1774
|
+
},
|
|
1775
|
+
execution,
|
|
1776
|
+
error: { code, message },
|
|
1777
|
+
};
|
|
1778
|
+
const result = targetClosed
|
|
1779
|
+
? `The action was delivered, and its source root ${target.appName} — ${target.windowTitle} closed before a successor observation could be captured.`
|
|
1780
|
+
: `The action was delivered, but its source root ${target.appName} — ${target.windowTitle} could not be observed afterward: ${message}`;
|
|
1781
|
+
return {
|
|
1782
|
+
content: [
|
|
1783
|
+
{
|
|
1784
|
+
type: "text",
|
|
1785
|
+
text: `${result}\nNo successor state was created. Call find_roots, then observe_ui to continue.`,
|
|
1786
|
+
},
|
|
1787
|
+
],
|
|
1788
|
+
details,
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
async function performDesktopTransaction(params, actions, signal) {
|
|
1792
|
+
const state = operationState();
|
|
1793
|
+
state.currentImageMode = "auto";
|
|
1794
|
+
validateStateId(params.stateId);
|
|
1795
|
+
const look = currentLookOrThrow();
|
|
1796
|
+
const baseView = { stateId: state.currentCapture.stateId, outline: state.currentOutline };
|
|
1797
|
+
const condition = params.expect ? validateCondition(params.expect) : undefined;
|
|
1798
|
+
const scopeNode = condition ? conditionScopeNode(look.parsedOutline, condition) : undefined;
|
|
1799
|
+
const target = await ensureTargetWindowId(await resolveCurrentTarget(signal), signal);
|
|
1800
|
+
const noteBefore = state.currentNote;
|
|
1801
|
+
return await withWindowWriteLock(target, async () => {
|
|
1802
|
+
const headless = getComputerUseConfig().headless;
|
|
1803
|
+
const execution = await dispatchUiTransaction(actions, target, look, headless, signal);
|
|
1804
|
+
const executedActions = actions.slice(0, execution.actionCount ?? actions.length);
|
|
1805
|
+
try {
|
|
1806
|
+
if (condition) {
|
|
1807
|
+
const { text: expectedText, role: expectedRole, value: expectedValue, scopeExact, gone, timeoutMs, } = condition;
|
|
1808
|
+
const beforePresent = outlineConditionPresent(look.parsedOutline, condition);
|
|
1809
|
+
const desiredWasPreexisting = beforePresent !== gone;
|
|
1810
|
+
const verification = await currentPlatformBackend.waitFor({
|
|
1811
|
+
...nativeWindowRequest(target),
|
|
1812
|
+
lookId: look.parsedOutline.lookId,
|
|
1813
|
+
text: expectedText,
|
|
1814
|
+
role: platformRole(look.parsedOutline, expectedRole),
|
|
1815
|
+
value: expectedValue,
|
|
1816
|
+
scopeRef: scopeNode ? wireRefForNode(scopeNode) : undefined,
|
|
1817
|
+
scopeExact,
|
|
1818
|
+
gone,
|
|
1819
|
+
timeoutMs,
|
|
1820
|
+
}, { signal, timeoutMs: timeoutMs + 2_000 });
|
|
1821
|
+
execution.verification = {
|
|
1822
|
+
status: verification.found ? (desiredWasPreexisting ? "preexisting" : "verified") : "failed",
|
|
1823
|
+
text: expectedText,
|
|
1824
|
+
role: expectedRole,
|
|
1825
|
+
value: expectedValue,
|
|
1826
|
+
gone: gone || undefined,
|
|
1827
|
+
timeoutMs,
|
|
1828
|
+
};
|
|
1829
|
+
execution.outcome = outcomeAfterCheck(execution.outcome ?? "unknown", execution.verification.status);
|
|
1830
|
+
if (!verification.found) {
|
|
1831
|
+
execution.error = {
|
|
1832
|
+
code: "postcondition_failed",
|
|
1833
|
+
message: `The action was delivered but its postcondition was not satisfied within ${timeoutMs}ms.`,
|
|
1834
|
+
};
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
await sleep(settleMsForExecution(execution), signal);
|
|
1839
|
+
}
|
|
1840
|
+
const capture = await captureCurrentTarget(signal, "auto", AUTO_IMAGE_MAX_DIMENSION, target);
|
|
1841
|
+
execution.outcome = outcomeAfterObservedValues(execution.outcome ?? "unknown", executedActions, (ref) => nodeByRef(capture.outline, ref)?.value);
|
|
1842
|
+
for (const action of executedActions) {
|
|
1843
|
+
state.currentNote = noteAfterAct(state.currentNote ?? noteBefore, action.ref, capture.outline, {
|
|
1844
|
+
window: noteWindowForTarget(capture.target, capture.look),
|
|
1845
|
+
rootDelta: execution.rootDelta,
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
return await buildToolResult("act_ui", `Executed ${executedActions.length} checked UI action${executedActions.length === 1 ? "" : "s"} in ${target.appName} — ${target.windowTitle}. Returned state ${capture.capture.stateId}.`, capture, execution, signal, state.currentImageMode, baseView);
|
|
1849
|
+
}
|
|
1850
|
+
catch (error) {
|
|
1851
|
+
if (signal?.aborted) {
|
|
1852
|
+
clearDesktopOperationState(state);
|
|
1853
|
+
throw error;
|
|
1854
|
+
}
|
|
1855
|
+
return await terminalDesktopActionResult(target, baseView.stateId, execution, error, condition);
|
|
1856
|
+
}
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
async function performBrowserTransaction(params, actions, signal) {
|
|
1860
|
+
const contextId = browserContextForOperation();
|
|
1861
|
+
if (!contextId)
|
|
1862
|
+
throw new Error("Browser transaction requires a browser observation state.");
|
|
1863
|
+
const baseSnapshot = operationState().browserSnapshot;
|
|
1864
|
+
if (!baseSnapshot)
|
|
1865
|
+
throw new Error("Browser transaction requires a complete base observation.");
|
|
1866
|
+
const baseView = { stateId: baseSnapshot.snapshotId, outline: baseSnapshot.outline };
|
|
1867
|
+
const condition = params.expect ? validateCondition(params.expect) : undefined;
|
|
1868
|
+
if (condition)
|
|
1869
|
+
conditionScopeNode(restoreOutline(baseSnapshot.outline), condition);
|
|
1870
|
+
const prepared = actions.map((action) => {
|
|
1871
|
+
if (!BROWSER_TRANSACTION_ACTIONS.has(action.action))
|
|
1872
|
+
throw new Error(`Browser transactions do not support '${action.action}'.`);
|
|
1873
|
+
if (action.action === "click" && action.ref && action.button && action.button !== "left")
|
|
1874
|
+
throw new Error("Browser ref clicks support only the left button; use coordinate clicks for right or middle buttons.");
|
|
1875
|
+
const target = browserSnapshotTarget(params.stateId, trimOrUndefined(action.ref));
|
|
1876
|
+
if ((action.action === "press" ||
|
|
1877
|
+
action.action === "setText" ||
|
|
1878
|
+
(action.action === "click" && action.ref) ||
|
|
1879
|
+
(action.action === "typeText" && action.ref)) &&
|
|
1880
|
+
!Number.isFinite(target?.backendNodeId)) {
|
|
1881
|
+
throw new Error(`Browser ${action.action} requires an actionable @e ref owned by ${params.stateId}.`);
|
|
1882
|
+
}
|
|
1883
|
+
if (action.ref && (!target || target.contextId !== contextId))
|
|
1884
|
+
throw new Error(`Browser ${action.action} ref must be owned by ${params.stateId}.`);
|
|
1885
|
+
return { action, target };
|
|
1886
|
+
});
|
|
1887
|
+
return await withBrowserWrite(contextId, async () => {
|
|
1888
|
+
for (const { action, target } of prepared) {
|
|
1889
|
+
let worked = false;
|
|
1890
|
+
if (action.action === "press" || (action.action === "click" && action.ref)) {
|
|
1891
|
+
worked = true;
|
|
1892
|
+
for (let count = 0; count < (action.clickCount ?? 1); count += 1)
|
|
1893
|
+
worked = (await cdpClickForContext(contextId, target.backendNodeId)) && worked;
|
|
1894
|
+
}
|
|
1895
|
+
else if (action.action === "click") {
|
|
1896
|
+
worked =
|
|
1897
|
+
(await cdpMouseForContext(contextId, action.x, action.y, "mousePressed", action.button ?? "left", action.clickCount ?? 1)) &&
|
|
1898
|
+
(await cdpMouseForContext(contextId, action.x, action.y, "mouseReleased", action.button ?? "left", action.clickCount ?? 1));
|
|
1899
|
+
}
|
|
1900
|
+
else if (action.action === "setText")
|
|
1901
|
+
worked = await cdpTypeForContext(contextId, target.backendNodeId, action.text ?? "", true);
|
|
1902
|
+
else if (action.action === "typeText")
|
|
1903
|
+
worked = target?.backendNodeId
|
|
1904
|
+
? await cdpTypeForContext(contextId, target.backendNodeId, action.text ?? "", false)
|
|
1905
|
+
: await cdpTypeFocusedForContext(contextId, action.text ?? "");
|
|
1906
|
+
else if (action.action === "keypress")
|
|
1907
|
+
worked = await cdpKeypressForContext(contextId, action.keys ?? []);
|
|
1908
|
+
else if (action.action === "scroll")
|
|
1909
|
+
worked = await cdpScrollForContext(contextId, toFiniteNumber(action.scrollX, 0), toFiniteNumber(action.scrollY, 0), target?.backendNodeId);
|
|
1910
|
+
else if (action.action === "drag")
|
|
1911
|
+
worked = await cdpDragForContext(contextId, normalizeActionPath(action.path));
|
|
1912
|
+
else if (action.action === "moveMouse")
|
|
1913
|
+
worked = await cdpMouseForContext(contextId, action.x, action.y, "mouseMoved");
|
|
1914
|
+
if (!worked)
|
|
1915
|
+
throw new Error("The browser root became unavailable during the action transaction. Observe it again.");
|
|
1916
|
+
}
|
|
1917
|
+
if (condition) {
|
|
1918
|
+
const deadline = Date.now() + condition.timeoutMs;
|
|
1919
|
+
let satisfied = false;
|
|
1920
|
+
do {
|
|
1921
|
+
const snapshot = await cdpSnapshotForContext(contextId);
|
|
1922
|
+
if (!snapshot)
|
|
1923
|
+
throw new Error(`Browser root '${contextId}' is no longer available. Observe it again.`);
|
|
1924
|
+
const present = outlineConditionPresent(restoreOutline(snapshot.outline), condition);
|
|
1925
|
+
satisfied = present !== condition.gone;
|
|
1926
|
+
if (!satisfied)
|
|
1927
|
+
await sleep(100, signal);
|
|
1928
|
+
} while (!satisfied && Date.now() < deadline);
|
|
1929
|
+
if (!satisfied)
|
|
1930
|
+
throw new Error(`The browser action was delivered but its postcondition was not satisfied within ${condition.timeoutMs}ms.`);
|
|
1931
|
+
}
|
|
1932
|
+
return await refreshBrowserSnapshot(contextId, "act_ui", baseView);
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
function normalizeActionPath(path) {
|
|
1936
|
+
return (path ?? []).map((point) => Array.isArray(point)
|
|
1937
|
+
? { x: toFiniteNumber(point[0], 0), y: toFiniteNumber(point[1], 0) }
|
|
1938
|
+
: { x: toFiniteNumber(point.x, 0), y: toFiniteNumber(point.y, 0) });
|
|
1939
|
+
}
|
|
1940
|
+
function validateActionTarget(action) {
|
|
1941
|
+
const hasRef = Boolean(trimOrUndefined(action.ref));
|
|
1942
|
+
const hasX = Number.isFinite(action.x);
|
|
1943
|
+
const hasY = Number.isFinite(action.y);
|
|
1944
|
+
if (hasX !== hasY)
|
|
1945
|
+
throw new Error(`${action.action} coordinates require both x and y.`);
|
|
1946
|
+
const hasPoint = hasX && hasY;
|
|
1947
|
+
if ((action.action === "click" || action.action === "moveMouse") && hasRef === hasPoint) {
|
|
1948
|
+
throw new Error(`${action.action} requires exactly one target: ref or x/y coordinates.`);
|
|
1949
|
+
}
|
|
1950
|
+
if (action.action === "press" && !hasRef)
|
|
1951
|
+
throw new Error("press requires an actionable ref.");
|
|
1952
|
+
if (action.action === "scroll" && toFiniteNumber(action.scrollX, 0) === 0 && toFiniteNumber(action.scrollY, 0) === 0)
|
|
1953
|
+
throw new Error("scroll requires a non-zero scrollX or scrollY delta.");
|
|
1954
|
+
if (action.clickCount !== undefined &&
|
|
1955
|
+
(!Number.isInteger(action.clickCount) || action.clickCount < 1 || action.clickCount > 3))
|
|
1956
|
+
throw new Error("clickCount must be an integer from 1 to 3.");
|
|
1957
|
+
}
|
|
1958
|
+
async function performAct(params, signal) {
|
|
1959
|
+
const actions = Array.isArray(params.actions) ? params.actions : [];
|
|
1960
|
+
if (actions.length === 0)
|
|
1961
|
+
throw new Error("act_ui.actions must contain at least one action.");
|
|
1962
|
+
if (actions.length > 20)
|
|
1963
|
+
throw new Error("act_ui supports at most 20 actions per transaction.");
|
|
1964
|
+
for (const action of actions)
|
|
1965
|
+
validateActionTarget(action);
|
|
1966
|
+
if (operationState().contextId)
|
|
1967
|
+
return await performBrowserTransaction(params, actions, signal);
|
|
1968
|
+
return await performDesktopTransaction(params, actions, signal);
|
|
1969
|
+
}
|
|
1970
|
+
function managedBrowserExecutableCandidates(browser) {
|
|
1971
|
+
const overrideName = browser === "helium" ? "ADA_COMPUTER_USE_HELIUM_EXECUTABLE" : "ADA_COMPUTER_USE_CHROME_EXECUTABLE";
|
|
1972
|
+
const override = trimOrUndefined(process.env[overrideName]);
|
|
1973
|
+
if (override)
|
|
1974
|
+
return [path.resolve(override)];
|
|
1975
|
+
const platformCandidates = process.platform === "darwin"
|
|
1976
|
+
? browser === "helium"
|
|
1977
|
+
? [
|
|
1978
|
+
"/Applications/Helium.app/Contents/MacOS/Helium",
|
|
1979
|
+
path.join(os.homedir(), "Applications", "Helium.app", "Contents", "MacOS", "Helium"),
|
|
1980
|
+
]
|
|
1981
|
+
: [
|
|
1982
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
1983
|
+
path.join(os.homedir(), "Applications", "Google Chrome.app", "Contents", "MacOS", "Google Chrome"),
|
|
1984
|
+
]
|
|
1985
|
+
: process.platform === "win32"
|
|
1986
|
+
? browser === "helium"
|
|
1987
|
+
? [
|
|
1988
|
+
process.env.LOCALAPPDATA &&
|
|
1989
|
+
path.join(process.env.LOCALAPPDATA, "Helium", "Application", "helium.exe"),
|
|
1990
|
+
process.env.PROGRAMFILES &&
|
|
1991
|
+
path.join(process.env.PROGRAMFILES, "Helium", "Application", "helium.exe"),
|
|
1992
|
+
]
|
|
1993
|
+
: [
|
|
1994
|
+
process.env.LOCALAPPDATA &&
|
|
1995
|
+
path.join(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe"),
|
|
1996
|
+
process.env.PROGRAMFILES &&
|
|
1997
|
+
path.join(process.env.PROGRAMFILES, "Google", "Chrome", "Application", "chrome.exe"),
|
|
1998
|
+
process.env["PROGRAMFILES(X86)"] &&
|
|
1999
|
+
path.join(process.env["PROGRAMFILES(X86)"], "Google", "Chrome", "Application", "chrome.exe"),
|
|
2000
|
+
]
|
|
2001
|
+
: browser === "helium"
|
|
2002
|
+
? [
|
|
2003
|
+
"/usr/bin/helium",
|
|
2004
|
+
"/usr/bin/helium-browser",
|
|
2005
|
+
"/opt/helium/chrome",
|
|
2006
|
+
path.join(os.homedir(), ".local", "helium", "chrome"),
|
|
2007
|
+
]
|
|
2008
|
+
: [
|
|
2009
|
+
"/usr/bin/google-chrome",
|
|
2010
|
+
"/usr/bin/google-chrome-stable",
|
|
2011
|
+
"/usr/bin/chromium",
|
|
2012
|
+
"/usr/bin/chromium-browser",
|
|
2013
|
+
"/snap/bin/chromium",
|
|
2014
|
+
];
|
|
2015
|
+
const pathNames = browser === "helium"
|
|
2016
|
+
? process.platform === "win32"
|
|
2017
|
+
? ["helium.exe"]
|
|
2018
|
+
: ["helium", "helium-browser"]
|
|
2019
|
+
: process.platform === "win32"
|
|
2020
|
+
? ["chrome.exe"]
|
|
2021
|
+
: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"];
|
|
2022
|
+
const pathCandidates = (process.env.PATH ?? "")
|
|
2023
|
+
.split(path.delimiter)
|
|
2024
|
+
.filter(Boolean)
|
|
2025
|
+
.flatMap((directory) => pathNames.map((name) => path.join(directory, name)));
|
|
2026
|
+
return [
|
|
2027
|
+
...new Set([
|
|
2028
|
+
...platformCandidates.filter((candidate) => Boolean(candidate)),
|
|
2029
|
+
...pathCandidates,
|
|
2030
|
+
]),
|
|
2031
|
+
];
|
|
2032
|
+
}
|
|
2033
|
+
async function managedBrowserExecutable(browser) {
|
|
2034
|
+
const candidates = managedBrowserExecutableCandidates(browser);
|
|
2035
|
+
for (const candidate of candidates) {
|
|
2036
|
+
try {
|
|
2037
|
+
await access(candidate, fsConstants.X_OK);
|
|
2038
|
+
return candidate;
|
|
2039
|
+
}
|
|
2040
|
+
catch {
|
|
2041
|
+
// Try the next platform-appropriate installation location.
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
const overrideName = browser === "helium" ? "ADA_COMPUTER_USE_HELIUM_EXECUTABLE" : "ADA_COMPUTER_USE_CHROME_EXECUTABLE";
|
|
2045
|
+
if (trimOrUndefined(process.env[overrideName])) {
|
|
2046
|
+
throw new Error(`${browser} executable from ${overrideName} was not found or is not executable: ${candidates[0]}.`);
|
|
2047
|
+
}
|
|
2048
|
+
throw new Error(`${browser} executable was not found. Set ${overrideName} to its absolute path.`);
|
|
2049
|
+
}
|
|
2050
|
+
function freeTcpPort() {
|
|
2051
|
+
return new Promise((resolve, reject) => {
|
|
2052
|
+
const server = net.createServer();
|
|
2053
|
+
server.on("error", reject);
|
|
2054
|
+
server.listen(0, "127.0.0.1", () => {
|
|
2055
|
+
const address = server.address();
|
|
2056
|
+
const port = typeof address === "object" && address ? address.port : 0;
|
|
2057
|
+
server.close(() => (port > 0 ? resolve(port) : reject(new Error("Could not allocate a local CDP port."))));
|
|
2058
|
+
});
|
|
2059
|
+
});
|
|
2060
|
+
}
|
|
2061
|
+
async function waitForCdpPort(port, signal) {
|
|
2062
|
+
const deadline = Date.now() + MANAGED_BROWSER_READY_TIMEOUT_MS;
|
|
2063
|
+
while (Date.now() < deadline) {
|
|
2064
|
+
if (signal?.aborted)
|
|
2065
|
+
throw new Error("Browser launch was aborted.");
|
|
2066
|
+
try {
|
|
2067
|
+
const response = await fetch(`http://127.0.0.1:${port}/json/version`, { signal: AbortSignal.timeout(500) });
|
|
2068
|
+
if (response.ok)
|
|
2069
|
+
return;
|
|
2070
|
+
}
|
|
2071
|
+
catch {
|
|
2072
|
+
// Browser is still starting.
|
|
2073
|
+
}
|
|
2074
|
+
await sleep(200, signal);
|
|
2075
|
+
}
|
|
2076
|
+
throw new Error(`Managed browser did not expose CDP on port ${port} within ${MANAGED_BROWSER_READY_TIMEOUT_MS}ms.`);
|
|
2077
|
+
}
|
|
2078
|
+
// Side effects: starts a Pi-managed browser process, replaces any previous managed browser,
|
|
2079
|
+
// and sets ADA_COMPUTER_USE_CDP_PORT for subsequent CDP context discovery.
|
|
2080
|
+
async function performLaunchBrowser(params, signal) {
|
|
2081
|
+
const browser = getComputerUseConfig().managed_browser;
|
|
2082
|
+
const executable = await managedBrowserExecutable(browser);
|
|
2083
|
+
const port = await freeTcpPort();
|
|
2084
|
+
const requestedUrl = trimOrUndefined(params.url);
|
|
2085
|
+
if (requestedUrl && !/^https?:\/\//i.test(requestedUrl))
|
|
2086
|
+
throw new Error("launch_browser.url must be an absolute HTTP(S) URL.");
|
|
2087
|
+
const url = requestedUrl ?? "about:blank";
|
|
2088
|
+
const profileDir = path.join(os.tmpdir(), `pi-${browser}-cdp-${port}`);
|
|
2089
|
+
disconnectCdp();
|
|
2090
|
+
runtimeState.managedBrowser?.kill("SIGTERM");
|
|
2091
|
+
const args = [
|
|
2092
|
+
`--remote-debugging-port=${port}`,
|
|
2093
|
+
`--user-data-dir=${profileDir}`,
|
|
2094
|
+
"--no-first-run",
|
|
2095
|
+
"--no-default-browser-check",
|
|
2096
|
+
url,
|
|
2097
|
+
];
|
|
2098
|
+
if (runtimeState.previousCdpPort === undefined && runtimeState.managedBrowserCdpPort === undefined) {
|
|
2099
|
+
runtimeState.previousCdpPort = process.env.ADA_COMPUTER_USE_CDP_PORT;
|
|
2100
|
+
}
|
|
2101
|
+
const managedBrowser = spawn(executable, args, { stdio: "ignore", detached: false });
|
|
2102
|
+
managedBrowser.unref();
|
|
2103
|
+
runtimeState.managedBrowser = managedBrowser;
|
|
2104
|
+
runtimeState.managedBrowserCdpPort = String(port);
|
|
2105
|
+
process.env.ADA_COMPUTER_USE_CDP_PORT = String(port);
|
|
2106
|
+
try {
|
|
2107
|
+
await waitForCdpPort(port, signal);
|
|
2108
|
+
}
|
|
2109
|
+
catch (error) {
|
|
2110
|
+
if (runtimeState.managedBrowser === managedBrowser) {
|
|
2111
|
+
runtimeState.managedBrowser = undefined;
|
|
2112
|
+
managedBrowser.kill("SIGTERM");
|
|
2113
|
+
if (runtimeState.previousCdpPort === undefined)
|
|
2114
|
+
delete process.env.ADA_COMPUTER_USE_CDP_PORT;
|
|
2115
|
+
else
|
|
2116
|
+
process.env.ADA_COMPUTER_USE_CDP_PORT = runtimeState.previousCdpPort;
|
|
2117
|
+
runtimeState.managedBrowserCdpPort = undefined;
|
|
2118
|
+
runtimeState.previousCdpPort = undefined;
|
|
2119
|
+
}
|
|
2120
|
+
throw error;
|
|
2121
|
+
}
|
|
2122
|
+
const page = (await listCdpPageContexts())[0];
|
|
2123
|
+
if (!page)
|
|
2124
|
+
throw new Error("Managed browser launched without a CDP page context.");
|
|
2125
|
+
const resourceKey = `cdp:${page.targetId}`;
|
|
2126
|
+
const scheduled = await resourceScheduler.read(resourceKey, async () => await cdpSnapshotForContext(page.contextId));
|
|
2127
|
+
if (!scheduled.value)
|
|
2128
|
+
throw new Error("Managed browser page could not be observed after launch.");
|
|
2129
|
+
return browserObservationResult(scheduled.value, resourceKey, scheduled.epoch, "launch_browser");
|
|
2130
|
+
}
|
|
2131
|
+
async function performNavigateBrowser(params) {
|
|
2132
|
+
const contextId = browserContextForOperation();
|
|
2133
|
+
const url = trimOrUndefined(params.url);
|
|
2134
|
+
if (!contextId)
|
|
2135
|
+
throw new Error("navigate_browser.stateId must belong to a CDP browser-page observation. Native browser windows use act_ui.");
|
|
2136
|
+
if (!url || !/^https?:\/\//i.test(url))
|
|
2137
|
+
throw new Error("navigate_browser.url must be an absolute HTTP(S) URL.");
|
|
2138
|
+
const baseSnapshot = operationState().browserSnapshot;
|
|
2139
|
+
if (!baseSnapshot)
|
|
2140
|
+
throw new Error("Browser navigation requires a complete base observation.");
|
|
2141
|
+
return await withBrowserWrite(contextId, async () => {
|
|
2142
|
+
const ok = await cdpNavigateContext(contextId, url);
|
|
2143
|
+
if (!ok)
|
|
2144
|
+
throw new Error(`Browser context '${contextId}' is no longer available. Observe it again.`);
|
|
2145
|
+
return await refreshBrowserSnapshot(contextId, "navigate_browser", {
|
|
2146
|
+
stateId: baseSnapshot.snapshotId,
|
|
2147
|
+
outline: baseSnapshot.outline,
|
|
2148
|
+
});
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
async function performEvaluateBrowser(params) {
|
|
2152
|
+
const contextId = browserContextForOperation();
|
|
2153
|
+
const expression = typeof params.expression === "string" ? params.expression : "";
|
|
2154
|
+
if (!contextId)
|
|
2155
|
+
throw new Error("evaluate_browser.stateId must belong to a browser observation.");
|
|
2156
|
+
if (!expression.trim())
|
|
2157
|
+
throw new Error("evaluate_browser.expression must be non-empty JavaScript.");
|
|
2158
|
+
const baseSnapshot = operationState().browserSnapshot;
|
|
2159
|
+
if (!baseSnapshot)
|
|
2160
|
+
throw new Error("Browser evaluation requires a complete base observation.");
|
|
2161
|
+
return await withBrowserWrite(contextId, async () => {
|
|
2162
|
+
const result = await cdpEvaluateForContext(contextId, expression);
|
|
2163
|
+
if (!result)
|
|
2164
|
+
throw new Error(`Browser context '${contextId}' is no longer available. Observe it again.`);
|
|
2165
|
+
const successor = await refreshBrowserSnapshot(contextId, "evaluate_browser", {
|
|
2166
|
+
stateId: baseSnapshot.snapshotId,
|
|
2167
|
+
outline: baseSnapshot.outline,
|
|
2168
|
+
});
|
|
2169
|
+
const details = {
|
|
2170
|
+
tool: "evaluate_browser",
|
|
2171
|
+
baseStateId: baseSnapshot.snapshotId,
|
|
2172
|
+
stateId: successor.details.stateId,
|
|
2173
|
+
view: successor.details.view,
|
|
2174
|
+
changes: successor.details.changes,
|
|
2175
|
+
outline: successor.details.outline,
|
|
2176
|
+
renderedOutline: successor.details.renderedOutline,
|
|
2177
|
+
};
|
|
2178
|
+
return {
|
|
2179
|
+
content: [...successor.content, { type: "text", text: `Evaluation value: ${JSON.stringify(result.value)}` }],
|
|
2180
|
+
details,
|
|
2181
|
+
};
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
async function executeTool(ctx, params, signal, run) {
|
|
2185
|
+
const outputRef = trimOrUndefined(params?.ref)?.startsWith("@o") === true;
|
|
2186
|
+
const requestedStateId = outputRef
|
|
2187
|
+
? undefined
|
|
2188
|
+
: trimOrUndefined(params?.stateId);
|
|
2189
|
+
const stateRecord = requestedStateId ? savedStates.get(requestedStateId) : undefined;
|
|
2190
|
+
if (requestedStateId && !stateRecord) {
|
|
2191
|
+
throw new Error(`State '${requestedStateId}' is unavailable or was evicted. Observe the root again.`);
|
|
2192
|
+
}
|
|
2193
|
+
const operation = savedStates.hydrate(stateRecord);
|
|
2194
|
+
return await savedStates.operations.run(operation, async () => {
|
|
2195
|
+
await resourceScheduler.read("session-lifecycle", async () => await ensureReady(ctx, signal));
|
|
2196
|
+
throwIfAborted(signal);
|
|
2197
|
+
const result = await run();
|
|
2198
|
+
persistOperation(operation);
|
|
2199
|
+
return result;
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
function makeToolExecutor(tool, perform) {
|
|
2203
|
+
return async (_toolCallId, params, signal, _onUpdate, ctx) => {
|
|
2204
|
+
try {
|
|
2205
|
+
return applyOutputEnvelope(tool, await executeTool(ctx, params, signal, () => perform(params, signal)));
|
|
2206
|
+
}
|
|
2207
|
+
catch (error) {
|
|
2208
|
+
throw boundToolError(tool, error);
|
|
2209
|
+
}
|
|
2210
|
+
};
|
|
2211
|
+
}
|
|
2212
|
+
export const executeFind = makeToolExecutor("find_roots", performListWindows);
|
|
2213
|
+
export const executeReadText = makeToolExecutor("read_text", performReadText);
|
|
2214
|
+
export const executeWaitFor = makeToolExecutor("wait_for", performWaitFor);
|
|
2215
|
+
export const executeObserve = makeToolExecutor("observe_ui", performObserve);
|
|
2216
|
+
export const executeSearchUi = makeToolExecutor("search_ui", performSearchUi);
|
|
2217
|
+
export const executeExpandUi = makeToolExecutor("expand_ui", performExpandUi);
|
|
2218
|
+
export const executeInspectUi = makeToolExecutor("inspect_ui", performInspectUi);
|
|
2219
|
+
export const executeAct = makeToolExecutor("act_ui", performAct);
|
|
2220
|
+
export const executeNavigateBrowser = makeToolExecutor("navigate_browser", performNavigateBrowser);
|
|
2221
|
+
export const executeEvaluateBrowser = makeToolExecutor("evaluate_browser", performEvaluateBrowser);
|
|
2222
|
+
export const executeLaunchBrowser = makeToolExecutor("launch_browser", performLaunchBrowser);
|
|
2223
|
+
export function reconstructStateFromBranch(ctx) {
|
|
2224
|
+
savedStates.clear();
|
|
2225
|
+
clearStoredOutputs();
|
|
2226
|
+
runtimeState.windowRefs.clear();
|
|
2227
|
+
runtimeState.windowRefByIdentity.clear();
|
|
2228
|
+
runtimeState.nextRootRefIndex = 1;
|
|
2229
|
+
const restoredResources = new Set();
|
|
2230
|
+
for (const entry of [...ctx.sessionManager.getBranch()].reverse()) {
|
|
2231
|
+
if (entry?.type !== "message")
|
|
2232
|
+
continue;
|
|
2233
|
+
const message = entry.message;
|
|
2234
|
+
if (!message || message.role !== "toolResult")
|
|
2235
|
+
continue;
|
|
2236
|
+
if (!AGENT_TOOL_NAMES.has(message.toolName))
|
|
2237
|
+
continue;
|
|
2238
|
+
const rawDetails = message.details;
|
|
2239
|
+
if (rawDetails?.tool === "find_roots" && Array.isArray(rawDetails.windows)) {
|
|
2240
|
+
for (const window of rawDetails.windows) {
|
|
2241
|
+
if (typeof window?.windowRef !== "string" || !Number.isFinite(window?.pid))
|
|
2242
|
+
continue;
|
|
2243
|
+
const record = {
|
|
2244
|
+
ref: window.windowRef,
|
|
2245
|
+
appName: typeof window.app === "string" ? window.app : "Unknown App",
|
|
2246
|
+
bundleId: typeof window.bundleId === "string" ? window.bundleId : undefined,
|
|
2247
|
+
pid: Math.trunc(window.pid),
|
|
2248
|
+
windowTitle: typeof window.windowTitle === "string" ? window.windowTitle : "(untitled)",
|
|
2249
|
+
windowId: Number.isFinite(window.windowId) ? Math.trunc(window.windowId) : undefined,
|
|
2250
|
+
nativeWindowRef: typeof window.nativeWindowRef === "string" ? window.nativeWindowRef : undefined,
|
|
2251
|
+
framePoints: {
|
|
2252
|
+
x: toFiniteNumber(window.framePoints?.x, 0),
|
|
2253
|
+
y: toFiniteNumber(window.framePoints?.y, 0),
|
|
2254
|
+
w: Math.max(1, toFiniteNumber(window.framePoints?.w, 1)),
|
|
2255
|
+
h: Math.max(1, toFiniteNumber(window.framePoints?.h, 1)),
|
|
2256
|
+
},
|
|
2257
|
+
scaleFactor: Math.max(1, toFiniteNumber(window.scaleFactor, 1)),
|
|
2258
|
+
isMinimized: toBoolean(window.isMinimized),
|
|
2259
|
+
isOnscreen: toBoolean(window.isOnscreen),
|
|
2260
|
+
isMain: toBoolean(window.isMain),
|
|
2261
|
+
isFocused: toBoolean(window.isFocused),
|
|
2262
|
+
};
|
|
2263
|
+
runtimeState.windowRefs.set(record.ref, record);
|
|
2264
|
+
runtimeState.windowRefByIdentity.set(windowRecordIdentity(record), record.ref);
|
|
2265
|
+
const match = /^@r(\d+)$/.exec(record.ref);
|
|
2266
|
+
if (match)
|
|
2267
|
+
runtimeState.nextRootRefIndex = Math.max(runtimeState.nextRootRefIndex, Number(match[1]) + 1);
|
|
2268
|
+
}
|
|
2269
|
+
continue;
|
|
2270
|
+
}
|
|
2271
|
+
const details = rawDetails;
|
|
2272
|
+
if (!details?.target || !details?.capture)
|
|
2273
|
+
continue;
|
|
2274
|
+
const app = typeof details.target.app === "string" ? details.target.app : undefined;
|
|
2275
|
+
if (!app)
|
|
2276
|
+
continue;
|
|
2277
|
+
if (!Number.isFinite(details.target.pid) || !Number.isFinite(details.target.windowId))
|
|
2278
|
+
continue;
|
|
2279
|
+
if (typeof details.capture.stateId !== "string")
|
|
2280
|
+
continue;
|
|
2281
|
+
const target = {
|
|
2282
|
+
appName: app,
|
|
2283
|
+
bundleId: details.target.bundleId,
|
|
2284
|
+
pid: Math.trunc(details.target.pid),
|
|
2285
|
+
windowTitle: details.target.windowTitle ?? "(untitled)",
|
|
2286
|
+
windowId: Math.trunc(details.target.windowId),
|
|
2287
|
+
windowRef: typeof details.target.windowRef === "string" ? details.target.windowRef : undefined,
|
|
2288
|
+
nativeWindowRef: typeof details.target.nativeWindowRef === "string"
|
|
2289
|
+
? details.target.nativeWindowRef
|
|
2290
|
+
: undefined,
|
|
2291
|
+
};
|
|
2292
|
+
const resourceKey = desktopResourceKey(target);
|
|
2293
|
+
if (restoredResources.has(resourceKey))
|
|
2294
|
+
continue;
|
|
2295
|
+
const capture = {
|
|
2296
|
+
stateId: details.capture.stateId,
|
|
2297
|
+
width: Math.max(1, Math.trunc(toFiniteNumber(details.capture.width, 1))),
|
|
2298
|
+
height: Math.max(1, Math.trunc(toFiniteNumber(details.capture.height, 1))),
|
|
2299
|
+
scaleFactor: Math.max(1, toFiniteNumber(details.capture.scaleFactor, 1)),
|
|
2300
|
+
timestamp: Number.isFinite(details.capture.timestamp) ? details.capture.timestamp : Date.now(),
|
|
2301
|
+
};
|
|
2302
|
+
if (details.outline?.root && typeof details.outline.lookId === "string") {
|
|
2303
|
+
const epoch = 0;
|
|
2304
|
+
resourceScheduler.restoreEpoch(resourceKey, epoch);
|
|
2305
|
+
savedStates.set({
|
|
2306
|
+
stateId: capture.stateId,
|
|
2307
|
+
resourceKey,
|
|
2308
|
+
epoch,
|
|
2309
|
+
value: {
|
|
2310
|
+
kind: "desktop",
|
|
2311
|
+
target,
|
|
2312
|
+
capture,
|
|
2313
|
+
outline: details.outline,
|
|
2314
|
+
look: {
|
|
2315
|
+
lookId: details.outline.lookId,
|
|
2316
|
+
capturedAt: details.capture.timestamp / 1000,
|
|
2317
|
+
window: {
|
|
2318
|
+
windowId: Math.trunc(details.target.windowId),
|
|
2319
|
+
framePoints: { x: 0, y: 0, w: details.capture.width, h: details.capture.height },
|
|
2320
|
+
scaleFactor: details.capture.scaleFactor,
|
|
2321
|
+
isModal: false,
|
|
2322
|
+
role: "",
|
|
2323
|
+
subrole: "",
|
|
2324
|
+
},
|
|
2325
|
+
image: { jpegBase64: "", width: details.capture.width, height: details.capture.height },
|
|
2326
|
+
timings: {},
|
|
2327
|
+
},
|
|
2328
|
+
note: details.note,
|
|
2329
|
+
},
|
|
2330
|
+
});
|
|
2331
|
+
restoredResources.add(resourceKey);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
//# sourceMappingURL=bridge.js.map
|