Metadata-Version: 2.4
Name: helixwright
Version: 1.0.2
Summary: Python automation SDK for Helix Browser Local API and the private Helix RPC page-control plane.
Author: Helix Browser
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://pypi.org/project/helixwright/
Project-URL: Documentation, http://66.154.125.146:8000/helixwright/
Keywords: automation,browser,fingerprint,chromium,local-api,helix
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Typing :: Typed
Classifier: Intended Audience :: Developers
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# Helixwright

Helixwright is the Python automation SDK for Helix Browser.

> **Status (2026-07-14):** `1.0.0` is a local release candidate under active
> implementation. It is not published, and this document makes no installed
> browser or cloud-validation claim.

## Contract

Helixwright `1.0.0` is a breaking, single-protocol release:

| Item | Required value |
| --- | --- |
| SDK | `1.0.0` |
| Browser RPC protocol | `6` |
| Browser RPC endpoint | `/rpc/v6` |
| Chromium core contract | `0075` |
| Browser RPC semantic hash | `40DFB6DEDAA4CD9A1F56BCEBB019A08B1F57025A28069E79605945CA1FF60BE8` |
| Trace session schema | `helixwright.trace.session` version `4` |

`helixwright.rpc_contract` is the source of truth for the endpoint, required
methods, capability versions, receipt fields, and semantic contract hash.
Admission is fail-closed: an older endpoint, missing method, boolean-only
capability, wrong core, or wrong hash is rejected.

Helix Browser Desktop owns profile, fingerprint, proxy, browser, and automation
session lifecycle. Helixwright never uses CDP, WebDriver, Playwright, Selenium,
direct Chromium launch, local profile directories, or local fingerprint
generation.

## Local candidate setup

Use the repository checkout while `1.0.0` is unreleased:

```powershell
cd "G:\Helix Browser\repos\helixwright"
python -m pip install -e .
python -c "import helixwright as hw; assert hw.__version__ == '1.0.0'"
```

Helix Browser Desktop must be running and logged in for browser-backed calls.

## Quick start

```python
import helixwright as hw

with hw.launch("https://example.com", name="example") as page:
    page.locator("body").wait(timeout_ms=10_000)
    print(page.title())

    effect = page.get_by_role("link", name="More information...").click()
    assert effect.receipt_confirmed
    assert effect.dispatch_phase == "completed"
```

A normal `Locator.click()` automatically performs frame/OOPIF and Shadow DOM
routing, target-owned scrolling/materialisation, mechanical actionability,
trusted input, and final pointer-down revalidation in one
`element.await_ready_and_act` transaction. Do not add manual scrolling or raw
coordinate fallback to an ordinary element click.

Use `reuse_profile_id` only for deliberate profile reuse:

```python
with hw.launch("https://example.com", reuse_profile_id="profile-id") as page:
    print(page.profile_id, page.session_id)
```

## Readiness and authoritative effects

Mechanical checks cannot be disabled. Add site-specific business readiness with
an immutable `ReadinessContract` discovered from Trace evidence:

```python
ready = hw.ReadinessContract(
    all_of=(
        hw.ReadinessSignal.attribute(
            "#save", "data-hydrated", equals="true"
        ),
    ),
    quiet_ms=100,
    description="Save control is hydrated in the current document epoch",
)

effect = page.locator("#save").click(ready=ready, timeout_ms=15_000)
receipt = effect.receipt.as_dict()
assert effect.ok and effect.receipt_confirmed
assert effect.dispatch_phase == "completed"
assert receipt["action_id"] == effect.action_id
assert receipt["readiness_id"]
```

The returned `RuntimeActionEffect` is the action's authority. Keep it, validate
its own receipt, and bind the outcome to its `action_id`. A timeout or transport
loss is reconciled through `action.status`, `action.cancel`, and
`action.reconcile`; an uncertain dispatch is never blindly replayed.

## Immutable scope and one-epoch reads

`Page`, `Frame`, `Locator`, and `Input` are root day-to-day APIs. The advanced
`hw.expert.ProbeController` carries the same immutable
`hw.expert.ContextScope` identity. Creating a child frame appends a frozen
frame chain; it does not mutate a process-global frame cursor:

```python
checkout = page.frame("iframe#checkout")
email = checkout.get_by_label("Email")
email.fill("buyer@example.test")
checkout.get_by_role("button", name="Pay").click()
```

Locator reads use `state.snapshot`. Every `hw.expert.StateSnapshot` belongs to
one target, frame chain, document epoch, and snapshot id. Renderer or epoch
changes fail as errors rather than degrading into false `hidden` or `detached`
results. Waits use per-subscriber `events.subscribe` plus a confirming snapshot
instead of a shared cursor or fixed busy poll.

## Production actions and diagnostic JavaScript

- Element-bound production actions use `Locator` (`click`, `fill`, `type`,
  `press`, `select`, `upload`, `drag_to`).
- Deliberate raw input uses `Input` or one balanced `hw.expert.Gesture`.
- JavaScript is diagnostic only and must go through `page.probe.evaluate(...)`.
- Never use diagnostic JavaScript to click, fill, dispatch events, or replace a
  missing production action.

```python
ready_state = page.probe.evaluate(
    "document.readyState", label="diagnostic-ready-state"
)
forms = page.probe.forms()  # private evidence retains full values
```

Balanced custom input is committed as one `input.gesture` request:

```python
gesture = page.input.gesture(timeout_ms=10_000)
gesture.move(120, 240).down().pause(60).move(360, 240).up()
effect = gesture.commit()
assert effect.receipt_confirmed
```

Every pressed button or key must be released before commit. An exception inside
a gesture context dispatches nothing; core cancellation performs compensating
release when required.

## Statecharts

Branchy or multi-state automation uses `StateMachine`. Each non-terminal
handler returns its own final effect, consumes the state's readiness contract in
that action, and has a typed `OutcomeContract`:

```python
import helixwright as hw

submit_ready = hw.ReadinessContract(
    all_of=(hw.ReadinessSignal.attribute("#submit", "disabled", absent=True),)
)

def submit(ctx):
    return ctx.scope.locator("#submit").click(ready=ctx.ready)

machine = hw.StateMachine(
    [
        hw.State(
            "form",
            match=hw.Signature(require_selectors=["#form", "#submit"]),
            ready=submit_ready,
            handler=submit,
            expect=hw.OutcomeContract(
                success_states=["done"],
                no_effect="report",
            ),
        ),
        hw.State(
            "done",
            match=hw.Signature(require_selectors=["#complete"]),
            terminal=True,
        ),
    ],
    name="submit_flow",
)

result = machine.run(page, until="done", failure_dir="evidence/failures")
```

Classification is strict: mixed-epoch, unknown, ambiguous, malformed signal,
foreign receipt, and uncertain dispatch evidence fail closed. Concurrent page
regions are explicit statechart regions; frame-like applications are immutable
frame-scoped child machines.

## Flow IR

Production delivery includes a machine-verifiable `hw.expert.FlowIR` beside
the Python flow and private evidence. It binds:

- states, signatures, immutable contexts, and terminal states;
- readiness and action kind;
- core `action_id`, final dispatch phase, and authoritative receipt;
- causal outcome and Trace window;
- matching run/trace ids with `complete=true`, `full_fidelity=true`,
  `local_only=true`, and `upload=false`.

Validate an emitted file without relying on Python AST inference:

```python
flow = hw.expert.FlowIR.load("evidence/AUTOMATION_FLOW.json").require_valid()
print(flow.run_id, flow.terminal_states)
```

## Persistent authoring and private evidence

Use one persistent authoring controller for a flow. It starts Trace before
target navigation and keeps one process, namespace, page, session, and profile:

```powershell
$run = "evidence\authoring-run"
python -m helixwright author start --url "https://target.example" --run-dir $run
python -m helixwright author exec --run-dir $run `
  --code "page.probe.forms()"
python -m helixwright author checkpoint --run-dir $run --label "form"
python -m helixwright author stop --run-dir $run
```

Trace/Authoring evidence is intentionally full-fidelity: raw passwords, proxy
credentials, cookies, authorization data, form values, storage, network
request/response headers and bodies, and action arguments are retained when
observed. No masking, redaction, or value-capture switch is applied. The
boundary is owner-only ACLs, per-run isolation/locking, atomic writes, explicit
retention, and no automatic upload. Screenshots are supplementary; selectors,
state identity, readiness, and action outcomes come from structured evidence.

Each Trace manifest is schema `helixwright.trace.session` version `4`. Its
`browser_rpc` object must identify protocol `6`, endpoint `/rpc/v6`, core
contract `0075`, the semantic hash shown above, and the exact 22-field V6
receipt evidence contract. Completed pointer receipts additionally prove the
input-sequence id, motion-policy and trajectory digests, trajectory metrics,
core-computed pointer continuity, and the target-owned scroll chain.

## Controllers

The public surface is deliberately split by responsibility:

- root `hw.*`: day-to-day launch, page, locator, input, readiness, effects, and
  state-machine APIs;
- `hw.admin.*`: Local API, profile, proxy, launch-configuration, and automation
  session administration;
- `hw.expert.*`: Flow IR, Trace/probe types, immutable context/snapshot types,
  gestures, diagnostics, and controller classes;
- `hw.signals.*`: typed outcome signals such as `DomChanged`, `Appeared`, and
  `Network`.

Controller instances remain available from a page; their classes live in
`hw.expert`:

- `page.tabs`
- `page.network`
- `page.downloads`
- `page.dialogs`
- `page.cookies`
- `page.console`
- `page.trace`
- `page.probe`

See [`examples/README.md`](examples/README.md),
[`docs/NATIVE_TRACE.md`](docs/NATIVE_TRACE.md), and
[`docs/HELIXWRIGHT_SKILL_DESIGN.md`](docs/HELIXWRIGHT_SKILL_DESIGN.md).
