aetherius 0.2.0__tar.gz → 0.4.0__tar.gz
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.
- aetherius-0.4.0/.dockerignore +11 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/.env.example +8 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/.github/workflows/ci.yml +1 -1
- aetherius-0.4.0/.github/workflows/release.yml +92 -0
- aetherius-0.4.0/CHANGELOG.md +311 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/CONTRIBUTING.md +5 -1
- {aetherius-0.2.0 → aetherius-0.4.0}/Makefile +1 -1
- {aetherius-0.2.0 → aetherius-0.4.0}/PKG-INFO +193 -27
- {aetherius-0.2.0 → aetherius-0.4.0}/README.md +181 -23
- aetherius-0.4.0/contracts/blueprint.schema.json +247 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/contracts/events.schema.json +1 -1
- aetherius-0.4.0/contracts/openapi.yaml +345 -0
- aetherius-0.4.0/deploy/.env.example +17 -0
- aetherius-0.4.0/deploy/Dockerfile +63 -0
- aetherius-0.4.0/deploy/aetherius.service +29 -0
- aetherius-0.4.0/deploy/docker-compose.yml +28 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/pyproject.toml +19 -10
- aetherius-0.4.0/src/aetherius/_contracts/blueprint.schema.json +247 -0
- aetherius-0.4.0/src/aetherius/acts/_cognition/__init__.py +12 -0
- aetherius-0.4.0/src/aetherius/acts/_cognition/claude.py +217 -0
- aetherius-0.4.0/src/aetherius/acts/_cognition/local.py +47 -0
- aetherius-0.4.0/src/aetherius/acts/_cognition/planning.py +240 -0
- aetherius-0.4.0/src/aetherius/acts/_cognition/provider.py +61 -0
- aetherius-0.4.0/src/aetherius/acts/_perception.py +48 -0
- aetherius-0.4.0/src/aetherius/acts/_shared.py +280 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/bridge.py +6 -3
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/browser.py +103 -13
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/driver.py +20 -0
- aetherius-0.4.0/src/aetherius/acts/oracle/driver.py +220 -0
- aetherius-0.4.0/src/aetherius/acts/oracle/locator.py +62 -0
- aetherius-0.4.0/src/aetherius/acts/oracle/model.py +7 -0
- aetherius-0.4.0/src/aetherius/acts/oracle/perception.py +6 -0
- aetherius-0.4.0/src/aetherius/acts/oracle/scan.py +98 -0
- aetherius-0.4.0/src/aetherius/acts/phantom/driver.py +92 -0
- aetherius-0.4.0/src/aetherius/acts/phantom/loop.py +145 -0
- aetherius-0.4.0/src/aetherius/acts/phantom/memory.py +70 -0
- aetherius-0.4.0/src/aetherius/acts/phantom/perception.py +21 -0
- aetherius-0.4.0/src/aetherius/acts/phantom/planner.py +47 -0
- aetherius-0.4.0/src/aetherius/acts/vector/client.py +216 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/vector/driver.py +56 -5
- aetherius-0.4.0/src/aetherius/acts/vector/impersonate.py +81 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/catalog.py +4 -1
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/factory.py +6 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/validation.py +25 -13
- aetherius-0.2.0/src/aetherius/cli.py → aetherius-0.4.0/src/aetherius/cli/__init__.py +38 -32
- aetherius-0.4.0/src/aetherius/cli/_shared.py +20 -0
- aetherius-0.4.0/src/aetherius/cli/approvals.py +51 -0
- aetherius-0.4.0/src/aetherius/cli/schedule.py +245 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/config/settings.py +17 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/app.py +2 -2
- aetherius-0.4.0/src/aetherius/console/approvals.py +56 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/console.tcss +40 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/options_editor.py +8 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/home.py +5 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/library.py +17 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/runs.py +13 -1
- aetherius-0.4.0/src/aetherius/console/screens/schedules/__init__.py +12 -0
- aetherius-0.4.0/src/aetherius/console/screens/schedules/_common.py +44 -0
- aetherius-0.4.0/src/aetherius/console/screens/schedules/detail.py +269 -0
- aetherius-0.4.0/src/aetherius/console/screens/schedules/form.py +350 -0
- aetherius-0.4.0/src/aetherius/console/screens/schedules/screen.py +182 -0
- aetherius-0.4.0/src/aetherius/console/screenshots.py +324 -0
- aetherius-0.4.0/src/aetherius/console/widgets/confirm.py +58 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/form.py +6 -2
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/run_summary.py +2 -1
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/base.py +42 -10
- aetherius-0.4.0/src/aetherius/core/actions/flow.py +95 -0
- aetherius-0.4.0/src/aetherius/core/actions/human.py +67 -0
- aetherius-0.4.0/src/aetherius/core/actions/notification.py +59 -0
- aetherius-0.4.0/src/aetherius/core/actions/registry.py +117 -0
- aetherius-0.4.0/src/aetherius/core/actions/vision.py +35 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/models.py +26 -0
- aetherius-0.4.0/src/aetherius/core/blueprint/validator.py +130 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/errors.py +45 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/models.py +9 -1
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/extraction/json_extractor.py +12 -0
- aetherius-0.4.0/src/aetherius/core/runtime/approvals.py +154 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/context.py +9 -0
- aetherius-0.4.0/src/aetherius/core/runtime/drivers.py +119 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/engine.py +31 -80
- aetherius-0.4.0/src/aetherius/core/runtime/flow.py +143 -0
- aetherius-0.4.0/src/aetherius/core/runtime/healing.py +246 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/result.py +5 -0
- aetherius-0.4.0/src/aetherius/core/runtime/selector.py +77 -0
- aetherius-0.4.0/src/aetherius/core/runtime/steps.py +240 -0
- aetherius-0.4.0/src/aetherius/models/registry.py +39 -0
- aetherius-0.4.0/src/aetherius/models/store/.gitkeep +0 -0
- aetherius-0.4.0/src/aetherius/network/__init__.py +35 -0
- aetherius-0.4.0/src/aetherius/network/geo.py +63 -0
- aetherius-0.4.0/src/aetherius/network/identity.py +104 -0
- aetherius-0.4.0/src/aetherius/network/pool.py +64 -0
- aetherius-0.4.0/src/aetherius/network/proxy.py +90 -0
- aetherius-0.4.0/src/aetherius/network/transport.py +33 -0
- aetherius-0.4.0/src/aetherius/notify/__init__.py +48 -0
- aetherius-0.4.0/src/aetherius/notify/base.py +18 -0
- aetherius-0.4.0/src/aetherius/notify/channels/__init__.py +19 -0
- aetherius-0.4.0/src/aetherius/notify/channels/_http.py +31 -0
- aetherius-0.4.0/src/aetherius/notify/channels/discord.py +52 -0
- aetherius-0.4.0/src/aetherius/notify/channels/ntfy.py +105 -0
- aetherius-0.4.0/src/aetherius/notify/channels/telegram.py +48 -0
- aetherius-0.4.0/src/aetherius/notify/channels/webhook.py +32 -0
- aetherius-0.4.0/src/aetherius/notify/message.py +26 -0
- aetherius-0.4.0/src/aetherius/notify/registry.py +98 -0
- aetherius-0.4.0/src/aetherius/notify/sink.py +51 -0
- aetherius-0.4.0/src/aetherius/plugins.py +88 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_transform.py +21 -1
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/base.py +1 -1
- aetherius-0.4.0/src/aetherius/server/app.py +72 -0
- aetherius-0.4.0/src/aetherius/server/approvals.py +40 -0
- aetherius-0.4.0/src/aetherius/server/config.py +47 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/deps.py +14 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/jobs.py +109 -5
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/runs.py +24 -1
- aetherius-0.4.0/src/aetherius/server/routes/schedules.py +142 -0
- aetherius-0.4.0/src/aetherius/server/scheduler/__init__.py +32 -0
- aetherius-0.4.0/src/aetherius/server/scheduler/alerts.py +140 -0
- aetherius-0.4.0/src/aetherius/server/scheduler/manual.py +82 -0
- aetherius-0.4.0/src/aetherius/server/scheduler/misfire.py +71 -0
- aetherius-0.4.0/src/aetherius/server/scheduler/service.py +198 -0
- aetherius-0.4.0/src/aetherius/server/scheduler/triggers.py +115 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/schemas.py +55 -0
- aetherius-0.4.0/src/aetherius/stealth/fingerprint/hardening.py +193 -0
- aetherius-0.4.0/src/aetherius/stealth/fingerprint/headers.py +46 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/fingerprint/profile.py +48 -7
- aetherius-0.4.0/src/aetherius/stealth/fingerprint/webrtc.py +64 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/input.py +26 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/mouse.py +18 -3
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/timing.py +15 -8
- aetherius-0.4.0/src/aetherius/store/__init__.py +30 -0
- aetherius-0.4.0/src/aetherius/store/approvals.py +48 -0
- aetherius-0.4.0/src/aetherius/store/engine.py +77 -0
- aetherius-0.4.0/src/aetherius/store/models.py +48 -0
- aetherius-0.4.0/src/aetherius/store/runs.py +91 -0
- aetherius-0.4.0/src/aetherius/store/schedules.py +118 -0
- aetherius-0.4.0/src/aetherius/store/schema.py +96 -0
- aetherius-0.4.0/src/aetherius/store/state.py +51 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/version.py +1 -1
- aetherius-0.2.0/CHANGELOG.md +0 -39
- aetherius-0.2.0/RELEASING.md +0 -49
- aetherius-0.2.0/contracts/blueprint.schema.json +0 -144
- aetherius-0.2.0/contracts/openapi.yaml +0 -152
- aetherius-0.2.0/src/aetherius/_contracts/blueprint.schema.json +0 -144
- aetherius-0.2.0/src/aetherius/acts/_shared.py +0 -61
- aetherius-0.2.0/src/aetherius/acts/oracle/driver.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/oracle/locator.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/oracle/model.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/oracle/perception.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/phantom/driver.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/phantom/loop.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/phantom/memory.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/phantom/perception.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/phantom/planner.py +0 -1
- aetherius-0.2.0/src/aetherius/acts/vector/client.py +0 -129
- aetherius-0.2.0/src/aetherius/console/screenshots.py +0 -173
- aetherius-0.2.0/src/aetherius/core/actions/flow.py +0 -76
- aetherius-0.2.0/src/aetherius/core/actions/registry.py +0 -70
- aetherius-0.2.0/src/aetherius/core/blueprint/validator.py +0 -45
- aetherius-0.2.0/src/aetherius/core/runtime/selector.py +0 -1
- aetherius-0.2.0/src/aetherius/models/registry.py +0 -1
- aetherius-0.2.0/src/aetherius/server/app.py +0 -37
- aetherius-0.2.0/src/aetherius/server/config.py +0 -25
- {aetherius-0.2.0 → aetherius-0.4.0}/.gitignore +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/LICENSE +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/UKIT.king.blueprint.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/direct.linkaetherius.blueprint.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/github.aetherius.blueprint.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/github.github.blueprint.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/github.zeb.blueprint.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/licence.aetherius.blueprint.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/blueprints/record.aetherius.blueprint.json +0 -0
- {aetherius-0.2.0/src/aetherius/models/store → aetherius-0.4.0/deploy/blueprints}/.gitkeep +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/__main__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/_contracts/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/actions.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/debug_overlay.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/continuum/human_actions.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/oracle/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/phantom/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/vector/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/acts/vector/auth.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/builder/templates.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/config/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/config/secrets.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/daemon_control.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/run_bridge.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/_pending.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/act_picker.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/io_editor.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/preview.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/screen.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/builder/step_editor.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/catalog.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/library_scan.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/recorder.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/sessions.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/screens/settings.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/theme.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/event_log.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/console/widgets/json_preview.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/data.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/interaction.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/navigation.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/actions/spec.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/loader.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/blueprint/template.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/driver.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/bus.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/events/sinks.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/extraction/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/extraction/html_extractor.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/core/runtime/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/models/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_capture_js.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_gesture_js.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_names.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_overlay_js.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_playwright.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_selector_js.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/_vector_js.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/blueprint_recorder.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/capture.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/continuum_backend.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/gesture_recorder.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/selector_synth.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/session.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/recorder/vector_backend.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/blueprints.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/recorder.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/server/routes/stream.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/fingerprint/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/fingerprint/patch.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/data/human_library.json +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/library.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/gestures/seed.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/keyboard.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/humanizer/scroll.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/ml/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/ml/fingerprint_model.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/ml/motion_model.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/policy.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/session/__init__.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/session/store.py +0 -0
- {aetherius-0.2.0 → aetherius-0.4.0}/src/aetherius/stealth/session/warmup.py +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Contexte de build Docker (deploy/Dockerfile, contexte = racine du depot).
|
|
2
|
+
# Allowlist : seul ce que le Dockerfile copie entre dans le contexte — le reste (dont .env et
|
|
3
|
+
# tout secret local) est exclu par construction.
|
|
4
|
+
*
|
|
5
|
+
!pyproject.toml
|
|
6
|
+
!README.md
|
|
7
|
+
!LICENSE
|
|
8
|
+
!src
|
|
9
|
+
!examples
|
|
10
|
+
**/__pycache__
|
|
11
|
+
**/*.pyc
|
|
@@ -18,3 +18,11 @@ AETHERIUS_SECRET_QUOTES_PASS=demo
|
|
|
18
18
|
# Universite de Bordeaux ENT/CAS.
|
|
19
19
|
AETHERIUS_SECRET_BORDEAUX_USER=your-username
|
|
20
20
|
AETHERIUS_SECRET_BORDEAUX_PASS='your-password'
|
|
21
|
+
|
|
22
|
+
# Notification targets (see docs/notifications.md) — uncomment the channels you use.
|
|
23
|
+
# A channel address grants write (and for ntfy, read) access: keep them out of Blueprints.
|
|
24
|
+
# AETHERIUS_SECRET_WEBHOOK_URL=https://webhook.site/<your-uuid>
|
|
25
|
+
# AETHERIUS_SECRET_DISCORD_WEBHOOK=https://discord.com/api/webhooks/<id>/<token>
|
|
26
|
+
# AETHERIUS_SECRET_TELEGRAM_BOT_TOKEN=123456:bot-token
|
|
27
|
+
# AETHERIUS_SECRET_TELEGRAM_CHAT_ID=123456789
|
|
28
|
+
# AETHERIUS_SECRET_NTFY_TOPIC=my-private-topic
|
|
@@ -30,7 +30,7 @@ jobs:
|
|
|
30
30
|
cache: pip
|
|
31
31
|
cache-dependency-path: pyproject.toml
|
|
32
32
|
# Base install stays light; heavy Act extras are not needed, tests marked
|
|
33
|
-
# browser/vision
|
|
33
|
+
# browser/cognition/vision skip themselves when their dependency is absent.
|
|
34
34
|
- run: python -m pip install -e ".[dev]"
|
|
35
35
|
- run: make lint
|
|
36
36
|
- run: make typecheck
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Automated release. Publishing lives here (as infra), not in a doc to remember.
|
|
2
|
+
#
|
|
3
|
+
# To cut a release:
|
|
4
|
+
# 1. Bump the version in BOTH src/aetherius/version.py and sdks/typescript/package.json (same X.Y.Z).
|
|
5
|
+
# 2. Add a "## [X.Y.Z] - <date>" section at the top of CHANGELOG.md (becomes the release notes).
|
|
6
|
+
# 3. Commit, then: git tag vX.Y.Z && git push && git push --tags
|
|
7
|
+
#
|
|
8
|
+
# Pushing the tag triggers this workflow, which — after checking the tag matches the versions —
|
|
9
|
+
# publishes to PyPI and npm and creates the GitHub Release. Nothing else to run by hand.
|
|
10
|
+
#
|
|
11
|
+
# One-time setup (see the pinned note): a PyPI "trusted publisher" for this repo (no token), and an
|
|
12
|
+
# NPM_TOKEN repository secret (npm automation token).
|
|
13
|
+
|
|
14
|
+
name: Release
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
tags: ["v*"]
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
check-version:
|
|
25
|
+
name: Tag matches package versions
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
- name: Verify tag == version.py == package.json
|
|
30
|
+
run: |
|
|
31
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
32
|
+
py=$(python3 -c "import re,pathlib; print(re.search(r'__version__\s*=\s*\"([^\"]+)\"', pathlib.Path('src/aetherius/version.py').read_text()).group(1))")
|
|
33
|
+
ts=$(node -p "require('./sdks/typescript/package.json').version")
|
|
34
|
+
echo "tag=$tag python=$py npm=$ts"
|
|
35
|
+
test "$tag" = "$py" || { echo "::error::Tag $tag != Python version $py (bump src/aetherius/version.py)"; exit 1; }
|
|
36
|
+
test "$tag" = "$ts" || { echo "::error::Tag $tag != npm version $ts (bump sdks/typescript/package.json)"; exit 1; }
|
|
37
|
+
|
|
38
|
+
pypi:
|
|
39
|
+
name: Publish to PyPI
|
|
40
|
+
needs: check-version
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write # OIDC for PyPI trusted publishing (no token stored)
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
- uses: actions/setup-python@v5
|
|
47
|
+
with:
|
|
48
|
+
python-version: "3.12"
|
|
49
|
+
- run: python3 -m pip install build
|
|
50
|
+
- run: python3 -m build
|
|
51
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
52
|
+
|
|
53
|
+
npm:
|
|
54
|
+
name: Publish to npm
|
|
55
|
+
needs: check-version
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- uses: actions/checkout@v4
|
|
59
|
+
- uses: actions/setup-node@v4
|
|
60
|
+
with:
|
|
61
|
+
node-version: "20"
|
|
62
|
+
registry-url: "https://registry.npmjs.org"
|
|
63
|
+
- run: npm install --no-audit --no-fund
|
|
64
|
+
working-directory: sdks/typescript
|
|
65
|
+
- run: npm run build
|
|
66
|
+
working-directory: sdks/typescript
|
|
67
|
+
- run: npm publish --access public
|
|
68
|
+
working-directory: sdks/typescript
|
|
69
|
+
env:
|
|
70
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
71
|
+
|
|
72
|
+
github-release:
|
|
73
|
+
name: GitHub Release
|
|
74
|
+
needs: [pypi, npm]
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
permissions:
|
|
77
|
+
contents: write
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
- name: Extract the CHANGELOG section for this version
|
|
81
|
+
run: |
|
|
82
|
+
version="${GITHUB_REF_NAME#v}"
|
|
83
|
+
awk -v ver="$version" '
|
|
84
|
+
$0 ~ "^## \\[" ver "\\]" { f=1; next }
|
|
85
|
+
/^## \[/ { if (f) exit }
|
|
86
|
+
f { print }
|
|
87
|
+
' CHANGELOG.md > release-notes.md
|
|
88
|
+
[ -s release-notes.md ] || echo "Release ${GITHUB_REF_NAME}." > release-notes.md
|
|
89
|
+
- name: Create the release
|
|
90
|
+
env:
|
|
91
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
92
|
+
run: gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --notes-file release-notes.md
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Toutes les évolutions notables du projet sont consignées ici. Le format s'inspire de
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/fr/1.1.0/) et le versionnage suit
|
|
5
|
+
[SemVer](https://semver.org/lang/fr/). Tant que la version reste en `0.x`, l'API publique peut encore
|
|
6
|
+
évoluer entre deux versions mineures (durcissement de la Phase 1 en conditions réelles).
|
|
7
|
+
|
|
8
|
+
## [Non publié]
|
|
9
|
+
|
|
10
|
+
## [0.4.0] - 2026-07-20
|
|
11
|
+
|
|
12
|
+
Phase 2 — les Acts autonomes : **Oracle** (vision) et **Phantom** (agent) deviennent runnables, la
|
|
13
|
+
**composition multi-Act** et le **self-healing** lèvent la contrainte « un Act par Blueprint », et
|
|
14
|
+
l'**humain dans la boucle** (`confirm`) garde les actions sensibles. Phase 2 complète (A–E).
|
|
15
|
+
|
|
16
|
+
### Ajouté
|
|
17
|
+
- **Jalon 2-E — Human-in-the-loop (`confirm`)** ([docs/human-in-the-loop.md](docs/human-in-the-loop.md)) :
|
|
18
|
+
une action **orthogonale aux Acts** (héritée par tous les drivers comme `notify`) qui **gare le
|
|
19
|
+
run** jusqu'à une décision humaine puis reprend. **Attente bloquante, pas suspend/resume** : le
|
|
20
|
+
worker parqué bloque sur un rendez-vous mémoire (`core/runtime/approvals.py`,
|
|
21
|
+
`ApprovalRegistry`/`Rendezvous`), le run — navigateur compris — reste vivant ; la boucle asyncio,
|
|
22
|
+
l'UI, ne gèlent jamais. Le **statut reste `running`** (deux nouveaux events
|
|
23
|
+
`input_requested`/`input_provided` au contrat `events.schema.json`, aucun nouveau statut). **Timeout
|
|
24
|
+
obligatoire** (`timeout_ms`, défaut 5 min) + `on_timeout` `approve`/`reject`/`fail:CODE` (défaut
|
|
25
|
+
**reject**, deny-by-default : le step sensible gardé par `when` se saute) ; un run non surveillé
|
|
26
|
+
(bibliothèque, sans surface) applique le timeout **immédiatement**. **Quatre surfaces, un seul
|
|
27
|
+
rendez-vous** : Console (`ConfirmModal` via `ConsoleApprovalSink` sur `input_requested`),
|
|
28
|
+
CLI/in-process (invite stdin `questionary`, sur un thread pour respecter le timeout, no-op sans
|
|
29
|
+
TTY), **API daemon** (`POST /v1/runs/{id}/decisions`, token opaque lié au `run_id`, 404 run inconnu
|
|
30
|
+
/ 409 rien en attente ou token invalide), et **réponse de notification** (boutons ntfy
|
|
31
|
+
Approve/Reject POSTant la route, via `Notification.data["confirm"]` + `AETHERIUS_DAEMON_PUBLIC_URL`).
|
|
32
|
+
Piste d'audit `approvals` (migration store forward-only **v1→v2**) écrite par le daemon depuis le
|
|
33
|
+
flux d'événements (source unique, sans course). Nouveaux : `core/actions/human.py` (spec `confirm`),
|
|
34
|
+
`Capability.CONFIRM`, `RunContext.approvals` + `RunEngine.run(approvals=)`, `server/approvals.py`,
|
|
35
|
+
`console/approvals.py`, `cli/approvals.py`, `store/approvals.py`. Contrats : event enum + route
|
|
36
|
+
OpenAPI. Exemple zéro config : `examples/vector/confirm-before-post.blueprint.json`. **Phase 2
|
|
37
|
+
terminée (A–E).**
|
|
38
|
+
- **Jalon 2-D — Composition multi-Act & self-healing** ([docs/composition.md](docs/composition.md)) :
|
|
39
|
+
la contrainte « un Act par Blueprint » tombe. **`act` par step** — chaque step peut surcharger
|
|
40
|
+
l'act du run (hérité dans les branches `if`/`repeat`/`for_each`, validé contre l'act **effectif**) ;
|
|
41
|
+
les Acts navigateur (II/III/IV) partagent **un seul navigateur** : le moteur pré-scanne l'arbre
|
|
42
|
+
(surcharges + chaînes de fallback) et instancie une seule instance du plus haut Act atteignable,
|
|
43
|
+
par subsomption de la chaîne d'héritage des drivers (`core/runtime/drivers.py`, `DriverManager` à
|
|
44
|
+
démarrage paresseux, teardown groupé). **Self-healing** opt-in : sur échec d'un step navigateur,
|
|
45
|
+
la chaîne `options.fallback` (ou `fallback` par step, `[]` désactive) rejoue l'**intention** du
|
|
46
|
+
step (`describe`, jamais devinée) sur l'Act supérieur — escalade `oracle` = rejeu du même step en
|
|
47
|
+
ciblage vision (`fill` → `type`), escalade `phantom` = **micro-objectif** d'agent borné (6
|
|
48
|
+
actions, capable d'écarter un obstacle ; limité aux intentions exprimables par le planner).
|
|
49
|
+
L'escalade est ponctuelle (le step suivant repart sur son act) ; un step guéri est un succès
|
|
50
|
+
(`StepResult.healed_by`, durée cumulée), le récit passe par des événements `progress` de niveau
|
|
51
|
+
`warning` (aucun nouveau type d'événement) ; chaîne épuisée = l'erreur d'origine propagée
|
|
52
|
+
inchangée. Schéma : champs `step.act`/`step.describe`/`step.fallback` + `options.fallback`
|
|
53
|
+
(additifs). L'exécuteur est réorganisé (`core/runtime/steps.py` + `flow.py` extrait +
|
|
54
|
+
`healing.py`), zéro régression mono-Act. Exemples zéro config : `examples/composition/`
|
|
55
|
+
(run mixte Continuum→Oracle et sélecteur cassé rattrapé par vision, vérifiés en réel).
|
|
56
|
+
- **Jalon 2-C — Act IV Phantom** ([docs/acts/phantom.md](docs/acts/phantom.md)) : `act: "phantom"`
|
|
57
|
+
est **runnable**. Un Blueprint **sans `steps`** déclare un `goal` et des `constraints` ; le moteur
|
|
58
|
+
route vers `driver.run_goal` (seam goal-only dans `RunEngine.run`) qui lance la boucle
|
|
59
|
+
**percevoir → raisonner → agir**. Le **planner** (Claude par défaut, rôle `Planner` du substrat de
|
|
60
|
+
cognition, `acts/_cognition/planning.py`) choisit chaque action par **tool use forcé**
|
|
61
|
+
(`tool_choice: any`) sur un vocabulaire restreint — ciblage **vision uniquement**, plus les outils
|
|
62
|
+
terminaux `finish` (objectif atteint → sortie) et `abort` (impossible / contrainte violée → échec
|
|
63
|
+
propre). L'action est jouée par le ciblage vision d'Oracle à travers la discrétion.
|
|
64
|
+
`PhantomDriver` **étend** `OracleDriver` (un seul navigateur, une seule discrétion, provider et
|
|
65
|
+
dispatch hérités) — un Blueprint `phantom` avec `steps` tourne déjà en mode scripté (socle 2-D).
|
|
66
|
+
Garde-fou : budget `options.agent.max_steps` (défaut 40, nouveau modèle `AgentOptions` + schéma) ;
|
|
67
|
+
un échec d'action est une **observation** mémorisée (résilience), jamais fatal — seuls `abort`, une
|
|
68
|
+
réponse de planner inutilisable ou le budget épuisé arrêtent le run. Observabilité par réutilisation
|
|
69
|
+
de `progress`/`step_started`/`step_finished` (`step_id` `agent[N]`, un `StepResult` par action),
|
|
70
|
+
**aucun nouvel `EventType`**. Sorties : `finish` exposé sous `{{ steps.agent.* }}`, ou l'issue de
|
|
71
|
+
l'agent (`{result, steps_taken}`) renvoyée telle quelle sans `outputs` déclarés. Garde validator
|
|
72
|
+
« goal-only ⇒ act phantom ». Exemple zéro config :
|
|
73
|
+
`examples/phantom/quotes-find-author.blueprint.json`.
|
|
74
|
+
- **Jalon 2-B — Act III Oracle** ([docs/acts/oracle.md](docs/acts/oracle.md)) : `act: "oracle"` est
|
|
75
|
+
**runnable**. `OracleDriver` **étend** le driver Continuum (un seul navigateur, une seule
|
|
76
|
+
discrétion, steps à sélecteur inchangés) et route les cibles vision : `click`/`type`/`upload`/
|
|
77
|
+
`hover`/`wait_for` acceptent `target: {vision: "description"}` — capture en pixels CSS →
|
|
78
|
+
grounding (un appel par cible, seuil de confiance 0.5 ajustable par `min_confidence`) → action
|
|
79
|
+
par coordonnées off-center (bande 30–70 %) via la façade stealth (`HumanInput` gagne
|
|
80
|
+
`hover_at`). `wait_for` par vision sonde l'écran (un grounding par sonde, `on_timeout:
|
|
81
|
+
"fail:CODE"` honoré) ; `upload` alimente le file chooser ouvert par le clic. Nouvelle action
|
|
82
|
+
**`read`** (extraction sémantique, capability + spec `core/actions/vision.py`) : avec `schema`
|
|
83
|
+
les champs deviennent les sorties du step, sans schéma la valeur arrive sous `data`. Contrat
|
|
84
|
+
documenté sans changement structurel (`target`, `vision.provider`) ; le Studio accepte les steps
|
|
85
|
+
ciblés par vision. Exemple zéro config : `examples/oracle/quotes-vision-demo.blueprint.json`.
|
|
86
|
+
- **Action `wait` : plage aléatoire** — sans `ms`, `min_ms`/`max_ms` tirent une durée uniforme
|
|
87
|
+
dans l'intervalle (act-agnostique) ; le gabarit fondateur `tiktok-upload` devient exact.
|
|
88
|
+
- **Oracle : recherche par défilement (scan)** — une cible vision hors du viewport est trouvée en
|
|
89
|
+
défilant la page viewport par viewport (scroll humanisé sous discrétion, remontée en haut pour
|
|
90
|
+
un départ en milieu de page), à coût borné : 8 coups d'œil maximum, un appel de grounding
|
|
91
|
+
chacun ; `scan: false` épingle le step au viewport courant. Exemple zéro config :
|
|
92
|
+
`examples/oracle/books-scan-below-fold.blueprint.json`.
|
|
93
|
+
- **Contribution : sondes réalistes** — la « Définition de terminé » exige désormais, en plus du
|
|
94
|
+
flux nominal vérifié à la main, une ou deux sondes réalistes « dures » (dont un cas conçu pour
|
|
95
|
+
échouer), consignées dans la doc de la capacité ([docs/testing.md](docs/testing.md)).
|
|
96
|
+
- **Jalon 2-A — Substrat de perception & cognition** ([docs/cognition.md](docs/cognition.md)) : la
|
|
97
|
+
fondation partagée des Acts cognitifs. `ClaudeProvider` implémente le **grounding** (`locate` :
|
|
98
|
+
description → `Box` + confiance) et l'**extraction sémantique** (`read`, schéma optionnel) par
|
|
99
|
+
tool use forcé — réponse structurée, un appel par cible, modèle par défaut `claude-opus-4-8`
|
|
100
|
+
écrasé par `vision.model`, clé via `ANTHROPIC_API_KEY` (`.env` supporté) ; `resolve_provider`
|
|
101
|
+
résout `vision.provider` (`claude` défaut / `local`) ; `LocalGrounder` reste l'option locale
|
|
102
|
+
derrière la même interface (rôles non portés en `CognitionError` typée). Perception de page en
|
|
103
|
+
**pixels CSS** (`capture` : screenshot `scale="css"` + DOM optionnel, réduction 2576 px avec
|
|
104
|
+
remise à l'échelle des boîtes), cible unifiée `Target.from_step` (sélecteur ou
|
|
105
|
+
`target: {vision}`, ambiguïté rejetée), et **clic par coordonnées à travers le stealth**
|
|
106
|
+
(`HumanInput.click_at`/`type_at`, gestes rejoués + timing humain, intégration Chromium réelle).
|
|
107
|
+
Nouvelle erreur `CognitionError`. `import aetherius` reste léger (SDK importés paresseusement).
|
|
108
|
+
- **Phase 2 — Autonomie & Contrôle : cadrage + squelette.** Directives et **spécifications par jalon**
|
|
109
|
+
([docs/phase-2/](docs/phase-2/README.md), jalons 2-A à 2-E), plus les **stubs d'interface** du
|
|
110
|
+
substrat de cognition ([`acts/_cognition/`](src/aetherius/acts/_cognition/),
|
|
111
|
+
[`acts/_perception.py`](src/aetherius/acts/_perception.py),
|
|
112
|
+
[`core/runtime/selector.py`](src/aetherius/core/runtime/selector.py),
|
|
113
|
+
[`models/registry.py`](src/aetherius/models/registry.py)) et des Acts cognitifs (Oracle/Phantom).
|
|
114
|
+
Les Acts II/III/IV deviennent trois stratégies au-dessus d'un même substrat navigateur + stealth +
|
|
115
|
+
perception + cognition. La phase couvre aussi la composition multi-Act par step, le self-healing
|
|
116
|
+
(fallback d'Act) et le human-in-the-loop (action `confirm`). Aucun comportement runtime modifié
|
|
117
|
+
(`make check` vert, `import aetherius` reste léger).
|
|
118
|
+
|
|
119
|
+
### Modifié
|
|
120
|
+
- **Extras refondus (Jalon 2-A)** : nouvel extra `[cognition]` (`anthropic`, `pillow`) — le défaut
|
|
121
|
+
partagé Oracle+Phantom, qui **absorbe l'ancien `[agent]`** (supprimé) ; `[vision]` repositionné
|
|
122
|
+
en **grounder local optionnel** ; `[all]` et les markers pytest alignés (`cognition` remplace
|
|
123
|
+
`agent`).
|
|
124
|
+
- **Oracle (Act III) redéfini** : le ciblage se fait par **grounding VLM** (Claude par défaut, un
|
|
125
|
+
détecteur local restant une option branchable derrière la même interface) plutôt que par un modèle
|
|
126
|
+
ONNX entraîné par tâche ; l'entraînement local devient une piste **optionnelle/avancée**. Fiches
|
|
127
|
+
[docs/acts/oracle.md](docs/acts/oracle.md) et [docs/acts/phantom.md](docs/acts/phantom.md)
|
|
128
|
+
réécrites (définition cible), [training/README.md](training/README.md) requalifié, section
|
|
129
|
+
« Phase 2 » et descriptions Oracle du README harmonisées.
|
|
130
|
+
|
|
131
|
+
## [0.3.0] - 2026-07-17
|
|
132
|
+
|
|
133
|
+
Phase 1.5 : le socle devient **opérationnel** (planification, alertes, réactivité, furtivité réseau
|
|
134
|
+
et empreinte), et durcissement du socle Phase 1 avant d'entamer la Phase 2 (audit croisé de la doc).
|
|
135
|
+
|
|
136
|
+
### Ajouté
|
|
137
|
+
- **Durcissement de l'empreinte (Jalon 1.5-H)** — les signaux à forte valeur que le profil laissait à
|
|
138
|
+
découvert sont fermés **de façon cohérente avec le profil actif** (un signal masqué mais incohérent
|
|
139
|
+
est un tell pire que l'absence de masque). Côté navigateur,
|
|
140
|
+
[`stealth/fingerprint/hardening.py`](src/aetherius/stealth/fingerprint/hardening.py) injecte, après
|
|
141
|
+
le script de cohérence du profil, un init script masquant : **Canvas** (`toDataURL`/`toBlob`/
|
|
142
|
+
`getImageData`) et **AudioContext** avec un bruit **déterministe par profil** (seed calculé côté
|
|
143
|
+
Python, hachage JS — stable entre deux lectures d'un même run, différent d'un profil à l'autre, lu
|
|
144
|
+
depuis une copie offscreen pour ne pas s'accumuler), **polices** (`measureText`), **client hints**
|
|
145
|
+
(`navigator.userAgentData`), **écran** (`screen.*` + `devicePixelRatio`) et **WebGL2**
|
|
146
|
+
(`getParameter`). Côté **Vector** (Act I, sans discrétion jusqu'ici),
|
|
147
|
+
[`stealth/fingerprint/headers.py`](src/aetherius/stealth/fingerprint/headers.py) donne une identité
|
|
148
|
+
d'en-têtes par défaut (`User-Agent`, `Sec-CH-UA`/`-Mobile`/`-Platform`, `Accept`, `Accept-Language`
|
|
149
|
+
aligné sur la géo) supprimant la signature « client HTTP nu » — **opt-in** (injectée seulement quand
|
|
150
|
+
`options.stealth` nomme un profil, un run sans stealth reste inchangé), les en-têtes explicites du
|
|
151
|
+
Blueprint gardant la priorité (fusion insensible à la casse) ; l'impersonation TLS `curl_cffi` garde
|
|
152
|
+
ses propres en-têtes. Le `FingerprintProfile` gagne les champs `screen`/`device_pixel_ratio`/
|
|
153
|
+
`ua_platform`/`ua_full_version` et dérive `Sec-CH-UA` de sa propre version d'UA : la limite « UA-CH
|
|
154
|
+
drift » est **levée**. Exemples exécutables zéro config
|
|
155
|
+
`examples/continuum/fingerprint-hardening.blueprint.json` et
|
|
156
|
+
`examples/vector/http-headers-identity.blueprint.json`. Voir [docs/stealth.md](docs/stealth.md).
|
|
157
|
+
- **Identité réseau (Jalon 1.5-G)** — option `options.proxy` de premier niveau qui rend le bot
|
|
158
|
+
invisible **au niveau réseau**, pour les **deux** moteurs (la couche stealth ne touche que le
|
|
159
|
+
navigateur). Le module `aetherius.network` est activé : `parse_proxy`/`ProxySpec` (rendu httpx et
|
|
160
|
+
Playwright, credentials masqués dans les logs), `ProxyPool` (rotation `per_run`/`round_robin`/
|
|
161
|
+
`random`/`sticky` — l'IP change d'un run à l'autre, ou reste stable par clé), `geo_hint` (cohérence
|
|
162
|
+
timezone/locale/langues avec le pays de l'IP), `resolve_identity` (option du Blueprint > défaut
|
|
163
|
+
d'environnement `AETHERIUS_PROXY_*` > aucun). Vector route par `httpx.Client(proxy=...)`
|
|
164
|
+
(HTTP/HTTPS, plus SOCKS5 via l'extra `[network]` avec garde typée si absent) et peut imiter la
|
|
165
|
+
poignée de main TLS d'un vrai navigateur (JA3/JA4) via un transport `curl_cffi` isolé
|
|
166
|
+
(`acts/vector/impersonate.py`, extra `[network]`, `DependencyError` claire sinon). Continuum lie le
|
|
167
|
+
proxy au lancement du contexte, force l'anti-fuite WebRTC (flag Chromium `disable_non_proxied_udp`
|
|
168
|
+
+ init-script filtrant les candidats ICE locaux — indispensable, sinon le proxy laisse fuir l'IP
|
|
169
|
+
réelle) et dérive le profil d'empreinte pour coller à la géo (timezone/locale/`navigator.languages`
|
|
170
|
+
alignés sur l'IP, vérifiés sur Chromium réel). Identifiants **jamais** stockés dans le Blueprint
|
|
171
|
+
(`{{ secrets.x }}`). Le Studio préserve `options.proxy` verbatim (aucune régression à l'édition).
|
|
172
|
+
Exemple exécutable `examples/vector/ip-echo-proxy.blueprint.json` (nécessite un proxy via `.env`).
|
|
173
|
+
Voir [docs/network.md](docs/network.md).
|
|
174
|
+
- **Déploiement always-on (Jalon 1.5-F)** — recette 24/7 vérifiée de bout en bout pour héberger le
|
|
175
|
+
daemon (et donc le scheduler) sur un hôte toujours allumé : VPS, Raspberry Pi, NAS. Les brouillons
|
|
176
|
+
`deploy/` sont finalisés : image Docker multi-stage (wheel construit à part, image finale sans
|
|
177
|
+
sources ni outils de build), utilisateur non-root, `HEALTHCHECK` sur `/health`, exemples embarqués
|
|
178
|
+
comme sondes zéro config, variante Act II exécutable (`--build-arg BROWSER=1` : extra `[browser]` +
|
|
179
|
+
Chromium sous `PLAYWRIGHT_BROWSERS_PATH` partagé) ; `docker-compose.yml` (volume persistant unique
|
|
180
|
+
`/data`, port publié sur la loopback de l'hôte, `env_file` + `.env.example`, montage lecture seule
|
|
181
|
+
`blueprints/` — les schedules résolvent des chemins côté conteneur) ; service systemd utilisateur
|
|
182
|
+
(`enable-linger`, `EnvironmentFile` optionnel, redémarrage automatique) ; `.dockerignore` racine en
|
|
183
|
+
allowlist (l'ancien `deploy/.dockerignore` était inopérant, le contexte de build étant la racine).
|
|
184
|
+
Durcissement afférent : un `AETHERIUS_DAEMON_TOKEN` vide vaut absence de token — l'interpolation
|
|
185
|
+
compose (`${VAR:-}`) n'active plus l'auth par accident (`server/config.py`, test miroir). Doc
|
|
186
|
+
complète (recettes, persistance, sauvegarde SQLite, sécurité : loopback par défaut, exposer =
|
|
187
|
+
token + reverse proxy TLS) : voir [docs/deployment.md](docs/deployment.md).
|
|
188
|
+
- **Actions custom / plugins (Jalon 1.5-E)** — points d'extension activés : un paquet tiers ajoute
|
|
189
|
+
des actions de Blueprint et des canaux de notification sans forker le cœur. Découverte par
|
|
190
|
+
entry-points (`aetherius.actions`, `aetherius.notify_channels`) dans le nouveau module
|
|
191
|
+
`aetherius.plugins` (`load_plugins()` idempotent, appelé au démarrage par la CLI, le lifespan du
|
|
192
|
+
daemon et `RunEngine.run` ; surface d'import unique pour les auteurs de plugins). Le registre
|
|
193
|
+
d'actions dormant est activé : une action plugin embarque son `ActionSpec` (visible du Studio et
|
|
194
|
+
des validators, invariant « registre = source, catalogue = projection » préservé), est
|
|
195
|
+
**act-agnostique** (hors capability-table, validée dynamiquement) et dispatchée par les drivers
|
|
196
|
+
en repli après leur `match` built-in. Gardes de collision sur les deux registres (les built-ins
|
|
197
|
+
restent prioritaires, un conflit est un échec de chargement explicite) et pannes isolées (un
|
|
198
|
+
plugin qui lève à l'import est loggé et sauté, jamais fatal). Plugin d'exemple exécutable
|
|
199
|
+
(`examples/plugins/` : action `demo.slugify` + canal `logfile` + Blueprint zéro réseau), chargé
|
|
200
|
+
par de vrais entry-points dans les tests. Voir [docs/plugins.md](docs/plugins.md).
|
|
201
|
+
- **Écran Console « Schedules »** — l'UI du scheduler (Jalon 1.5-D) dans la Console : liste des
|
|
202
|
+
schedules (trigger, politique d'alerte, statut, prochains/derniers tirs en heure locale, sonde
|
|
203
|
+
d'honnêteté « daemon actif ou non »), pause/reprise (`p`, la reprise recale la cadence),
|
|
204
|
+
suppression confirmée (`d`, nouveau `ConfirmModal` réutilisable), **détail** avec l'historique
|
|
205
|
+
des runs du schedule et un **tir manuel** aux événements streamés en direct (même brique
|
|
206
|
+
in-process que `aetherius schedule run`, extraite dans `server/scheduler/manual.py::fire_schedule`
|
|
207
|
+
et partagée CLI/Console), et **formulaire guidé** de création/édition (inputs du Blueprint en
|
|
208
|
+
champs, secrets jamais saisis — état `.env` affiché, trigger/misfire/notify validés à la
|
|
209
|
+
sauvegarde). Raccourci `s` dans Library pour planifier le Blueprint surligné. Captures SVG
|
|
210
|
+
déterministes (fuseau épinglé, store de démo figé) et neutralisation renforcée des chemins
|
|
211
|
+
(le home ne fuit plus, même tronqué dans une colonne). Voir [docs/console.md](docs/console.md).
|
|
212
|
+
- **Scheduler intégré au daemon (Jalon 1.5-D)** — rejeu persistant d'un Blueprint à heure fixe
|
|
213
|
+
(cron à 5 champs, évalué dans le fuseau local, DST gérés via `tzlocal`), par intervalle ou en tir
|
|
214
|
+
unique (`at`). Boucle de tick dans le lifespan du daemon (30 s, `AETHERIUS_DAEMON_SCHEDULER_TICK_SECONDS`) ;
|
|
215
|
+
un run planifié passe par `RunManager.submit` — mêmes événements, même historique, plus le lien
|
|
216
|
+
`schedule_id`. Rattrapage des tirs manqués par politique `misfire` (`skip`/`run_once`/`run_all`,
|
|
217
|
+
portée par le trigger, résolue par le tick au-delà d'une fenêtre de grâce) et politique d'alerte
|
|
218
|
+
par schedule (`failure`/`success`/`always`/`change` — la dédup au changement d'état s'appuie sur
|
|
219
|
+
`state.compare_and_set`, cibles `{{ secrets.x }}` rendues au tir, jamais persistées). CLI
|
|
220
|
+
`aetherius schedule add|list|rm|pause|resume|run` (écrit directement dans le store : marche daemon
|
|
221
|
+
éteint ; `cli.py` devient le package `cli/`) et API `/v1/schedules` (CRUD + tir immédiat,
|
|
222
|
+
contrat OpenAPI à jour). Exemple zéro config : `examples/vector/quotes-watch.blueprint.json`.
|
|
223
|
+
Dépendances : `croniter` (déjà déclarée) + `tzlocal`. Voir [docs/scheduler.md](docs/scheduler.md).
|
|
224
|
+
- **Notifications natives (Jalon 1.5-C)** — couche d'alerte sans dépendance nouvelle (`notify/`) :
|
|
225
|
+
quatre canaux built-in en un POST `httpx` chacun (webhook générique, Discord, Telegram, ntfy pour
|
|
226
|
+
la push téléphone, en mode JSON publishing), action `notify` Act-agnostique (handler partagé, se
|
|
227
|
+
combine à `when`), `NotifySink` de fin de run (`failure`/`success`/`always`) et registre de canaux
|
|
228
|
+
prêt pour les plugins (Jalon E). Échec d'envoi contenu : jamais fatal au run, `delivered` exposé
|
|
229
|
+
dans les outputs du step. Exemple zéro config :
|
|
230
|
+
`examples/vector/books-restock-notify.blueprint.json`. Voir
|
|
231
|
+
[docs/notifications.md](docs/notifications.md).
|
|
232
|
+
- **Réactivité et flux conditionnel (Jalon 1.5-B)** — garde d'étape `when` universelle (évaluée
|
|
233
|
+
avant dispatch, même règle de véracité que `assert` ; step sauté = statut `skipped` + événement
|
|
234
|
+
`step_skipped`, contrats et SDK TypeScript à jour) et actions `if`/`repeat`/`for_each` exécutées
|
|
235
|
+
par un **exécuteur récursif** dans le moteur (`core/runtime/steps.py`), en amont des drivers —
|
|
236
|
+
tous les Acts en héritent sans câblage, `repeat` rejoint les capacités Vector. Variable de boucle
|
|
237
|
+
`as` (défaut `item`) exposée au template le temps de l'itération, validation sémantique récursive
|
|
238
|
+
des branches, identifiants de steps imbriqués traçables (`loop[2].fetch`), schéma des steps
|
|
239
|
+
formalisé (`when`, `then`/`else`/`steps`). Deux exemples zéro config dans `examples/vector/`.
|
|
240
|
+
Voir [docs/blueprint-schema.md](docs/blueprint-schema.md).
|
|
241
|
+
- **Persistance durable (Jalon 1.5-A)** — socle de stockage SQLite (stdlib `sqlite3`, mode WAL, zéro
|
|
242
|
+
dépendance) sous `~/.aetherius/aetherius.db`, avec migrations versionnées (`PRAGMA user_version`) et
|
|
243
|
+
trois dépôts typés : schedules, historique des runs, état clé/valeur inter-run (`compare_and_set`
|
|
244
|
+
pour la déduplication d'alertes). Le daemon persiste désormais le résultat de ses runs dans le store
|
|
245
|
+
(migration douce, sans régression). Voir [docs/store.md](docs/store.md).
|
|
246
|
+
- **Cadrage Phase 1.5** — squelette (stubs, interfaces, contrats) et spécifications par jalon pour
|
|
247
|
+
rendre le socle **récurrent, réactif et furtif** : persistance SQLite (`store/`), notifications
|
|
248
|
+
natives (`notify/`), scheduler du daemon, flux conditionnel (`when`, `if`/`repeat`/`for_each`),
|
|
249
|
+
plugins, déploiement 24/7, **identité réseau** (`network/` : proxy, rotation d'IP, anti-fuite
|
|
250
|
+
WebRTC, cohérence géo, impersonation TLS) et **durcissement de l'empreinte**
|
|
251
|
+
(`stealth/fingerprint/` : canvas/audio/UA-CH/écran/WebGL2 + identité d'en-têtes pour Vector).
|
|
252
|
+
Aucune capacité n'est encore activée (jalons en attente : l'action `notify` est déclarée mais
|
|
253
|
+
marquée `PENDING`, les modules lèvent une erreur « jalon en attente ») ; `make check` reste vert.
|
|
254
|
+
Nouvel extra optionnel `[network]` (SOCKS5 + `curl_cffi`). Voir [docs/phase-1.5/](docs/phase-1.5/README.md).
|
|
255
|
+
- **Suivi des nouveaux onglets (Act II — Continuum)** : un clic ouvrant un onglet (`target="_blank"`,
|
|
256
|
+
`window.open`) rend la nouvelle page active pour les steps suivants, avec retombée sur une page
|
|
257
|
+
survivante si l'onglet actif se referme. Auparavant les steps restaient bloqués sur l'onglet initial.
|
|
258
|
+
- **Recorder « Make input »** : le `type`/`format` de l'input produit est inféré du type HTML du champ
|
|
259
|
+
(`number`, `date`+`format`, `email`/`url`, …) au lieu d'un `string` générique.
|
|
260
|
+
|
|
261
|
+
### Sécurité
|
|
262
|
+
- **Évaluateur `where` (Act I — Vector)** : rejet explicite des attributs magiques (`__class__`,
|
|
263
|
+
`__globals__`, tout nom en `__`) dans l'AST-walk. L'allowlist de nœuds bloquait déjà l'exécution de
|
|
264
|
+
code, mais la traversée d'attributs dunder combinée à une comparaison restait un oracle booléen sur
|
|
265
|
+
le graphe d'objets Python — la garde ferme cette évasion de sandbox sans dépendre de l'absence
|
|
266
|
+
d'appels/indexation.
|
|
267
|
+
|
|
268
|
+
### Corrigé
|
|
269
|
+
- **`precise_sleep` (stealth/humanizer)** : le busy-wait pur sous 20 ms saturait un cœur CPU à 100 %
|
|
270
|
+
(chaque point de geste souris), risque de privation de ressources sur le daemon en multi-run.
|
|
271
|
+
Désormais `time.sleep` cède le CPU pour le gros du délai et le busy-wait ne couvre que la queue
|
|
272
|
+
(~1,5 ms) — précision de timing inchangée, CPU au repos (~9 %).
|
|
273
|
+
- **Debug (Act II — Continuum)** : quand les entrées sont humanisées, `slow_mo` est à 0 et les actions
|
|
274
|
+
brutes (`select`, `upload`, `navigate`, …) défilaient instantanément, illisibles en debug. Elles
|
|
275
|
+
reçoivent maintenant un délai manuel équivalent.
|
|
276
|
+
|
|
277
|
+
## [0.2.0] - 2026-07-10
|
|
278
|
+
|
|
279
|
+
Première release publique. Elle clôt la **Phase 1** : le socle d'Aetherius, utilisable comme
|
|
280
|
+
**bibliothèque** (in-process Python) et comme **service** (daemon local + SDK), avec sa Console.
|
|
281
|
+
|
|
282
|
+
### Ajouté
|
|
283
|
+
- **Daemon local (FastAPI)** — passerelle HTTP + WebSocket exposant le moteur à tout langage
|
|
284
|
+
(`aetherius serve`, bind loopback, token bearer optionnel) : `POST /v1/runs`, `GET /v1/runs/{id}`,
|
|
285
|
+
`WS /v1/runs/{id}/events` (rejeu bufferisé + flux live jusqu'à `done`), `POST /v1/blueprints/validate`,
|
|
286
|
+
`GET /v1/schema`, `GET /health`. L'enregistrement reste host-local (`POST /v1/recorder/sessions` → 501).
|
|
287
|
+
Voir [docs/daemon.md](docs/daemon.md).
|
|
288
|
+
- **SDK TypeScript** `@aetherius/client` (Node 20+) — spawn du daemon (ou `baseUrl`),
|
|
289
|
+
`client.run(blueprint, { inputs, secrets, onEvent })`, streaming d'événements typé.
|
|
290
|
+
- **Console : écran Settings** — démarrer/arrêter le daemon et voir son statut, sans quitter le terminal.
|
|
291
|
+
- **Act I — Vector** : client HTTP/API (requêtes, retries/backoff, 5 stratégies d'auth, extraction
|
|
292
|
+
JSONPath et CSS/XPath, moteur de templates Jinja2).
|
|
293
|
+
- **Act II — Continuum** : automatisation d'un vrai navigateur (Playwright, extra `[browser]`) —
|
|
294
|
+
navigation, interactions, extraction DOM, `wait_for` avec échec nommé, sessions persistantes, debug.
|
|
295
|
+
- **Système de discrétion (stealth)** : couche transverse (`options.stealth`) — souris humaine par
|
|
296
|
+
rejeu géométrique de gestes, clavier/scroll/timing humains, fingerprint, warmup de profil.
|
|
297
|
+
- **Recorder** : création de Blueprint par démonstration (Continuum et Vector) + gesture recorder.
|
|
298
|
+
- **Builder headless + Blueprint Studio** : construction guidée de Blueprints sans JSON, avec aperçu
|
|
299
|
+
validé en direct, réutilisable par la Console, le daemon et les SDKs.
|
|
300
|
+
- **Console (Textual)** : Library, Runs, Catalog, Recorder, Blueprint Studio, Settings.
|
|
301
|
+
- **Contrats** langage-agnostiques (`contracts/`) : schéma Blueprint, OpenAPI du daemon, schéma
|
|
302
|
+
d'événements — source de vérité, gardés par des tests.
|
|
303
|
+
|
|
304
|
+
### Notes
|
|
305
|
+
- SemVer `0.x` : l'API peut évoluer pendant le durcissement de la Phase 1.
|
|
306
|
+
- La **Phase 2** ajoutera Act III (Oracle, vision) et Act IV (Phantom, agent autonome).
|
|
307
|
+
|
|
308
|
+
[Non publié]: https://github.com/kln-mltre/Aetherius/compare/v0.4.0...HEAD
|
|
309
|
+
[0.4.0]: https://github.com/kln-mltre/Aetherius/releases/tag/v0.4.0
|
|
310
|
+
[0.3.0]: https://github.com/kln-mltre/Aetherius/releases/tag/v0.3.0
|
|
311
|
+
[0.2.0]: https://github.com/kln-mltre/Aetherius/releases/tag/v0.2.0
|
|
@@ -43,7 +43,11 @@ est vrai. On ne saute pas une étape en attendant qu'on la réclame :
|
|
|
43
43
|
3. **Doc à jour** dans le même changement — voir [Documentation](#documentation).
|
|
44
44
|
4. **`make check` vert.**
|
|
45
45
|
5. **Flux vérifié à la main** au moins une fois : le vrai `run`, pas seulement les tests (chaque
|
|
46
|
-
doc d'Act a une section « Tester … » pour ça).
|
|
46
|
+
doc d'Act a une section « Tester … » pour ça). En plus du chemin nominal, jouer **une ou deux
|
|
47
|
+
sondes réalistes « dures »** — un scénario réel plus exigeant que l'exemple zéro config, dont si
|
|
48
|
+
possible un cas conçu pour faire échouer la capacité. Un échec **propre et explicable** est un
|
|
49
|
+
résultat valide ; un comportement surprenant est un correctif ou une limite à documenter avant
|
|
50
|
+
de clore. Voir [docs/testing.md](docs/testing.md#sondes-réalistes).
|
|
47
51
|
6. **Prise en main UI** pour une capacité **liée à l'UI et non triviale** (nouvel écran ou
|
|
48
52
|
interaction non évidente de la Console) : un walkthrough orienté UI dans la doc **et** des captures
|
|
49
53
|
SVG générées (`make screenshots`) — voir [Documentation](#documentation). Exception : une
|
|
@@ -31,7 +31,7 @@ test: ## Run the full Python test suite with coverage
|
|
|
31
31
|
pytest --cov=aetherius --cov-report=term-missing
|
|
32
32
|
|
|
33
33
|
test-fast: ## Run only the fast tests (skip heavy extras and slow tests)
|
|
34
|
-
pytest -m "not browser and not vision and not
|
|
34
|
+
pytest -m "not browser and not vision and not cognition and not slow"
|
|
35
35
|
|
|
36
36
|
test-browser: ## Run the browser tests (Act II) against a real Chromium; needs the [browser] extra
|
|
37
37
|
pytest -m browser
|