Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ jobs:
--target ${{ matrix.target }}
--config src-tauri/tauri.adhoc.conf.json

# Reuse the installer build's compiled dependencies. These tests protect
# the native URL and deep-link dispatch boundaries before artifact upload.
- name: Test native command and deep-link contracts
run: >-
cargo test --locked --release
--manifest-path src-tauri/Cargo.toml
--target ${{ matrix.target }}

- name: Smoke-test macOS DMG install, launch, and uninstall
if: runner.os == 'macOS'
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion docs/RELEASE_CANDIDATE_INSTALLERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ only the fixed `openadapt://connect` action and forwards it to the sidecar's
strict, transactional pairing flow.

The canonical compiler and governed runtime remain in `openadapt-flow`. Each
native installer freezes the exact `openadapt-flow[browser,console]==1.34.0`
native installer freezes the exact `openadapt-flow[browser,console]==1.35.1`
runtime and its `playwright==1.61.0` browser automation dependency into the
Desktop sidecar. The `console` extra is what lets an installed application
serve the attended decision console the mobile decision portal relays; the
Expand Down
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
},
"devDependencies": {
"@tauri-apps/cli": "^2",
"@testing-library/react": "^16.3.2",
"@testing-library/react": "^16.3.3",
"@types/react": "^18.3.31",
"@types/react-dom": "^18.3.7",
"@vitejs/plugin-react": "^6.1.0",
"@vitejs/plugin-react": "^6.1.1",
"jsdom": "^30.0.1",
"typescript": "^5.5.4",
"vite": "^8.2.2",
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ dependencies = [
"openadapt-privacy>=1.0.0",
# Exact cross-surface status/target contract used by the presentation
# exporter and by the generated TypeScript projection checked into src/.
# 0.10.0 carries the portable business-decision V2 contract used by the
# 0.17.0 retains the portable business-decision V2 contract used by the
# Desktop phone portal and Flow's governed runner.
"openadapt-types==0.10.0",
"openadapt-types==0.17.0",
"pydantic>=2.0",
"pydantic-settings>=2.0",
"PyYAML>=6.0,<7",
Expand Down Expand Up @@ -88,7 +88,7 @@ build = [
# purpose (see the pin below and the embedded ``-m playwright`` process
# mode). Without it the driver becomes build-only and the artifact gate
# correctly refuses the archive.
"openadapt-flow[browser,console]==1.34.0",
"openadapt-flow[browser,console]==1.35.1",
# Desktop deliberately embeds the optional browser driver so selecting a
# web workflow is one click. It does NOT bundle Chromium: that larger
# runtime is fetched only after the operator chooses the browser surface.
Expand Down
5 changes: 5 additions & 0 deletions scripts/smoke_test_frozen_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ def _verify_bundled_capture(executable: Path, root: Path, env: dict[str, str]) -

probe_env = dict(env)
probe_env["OPENADAPT_DATA_DIR"] = str(root / "capture-contract-data")
# This probe verifies the frozen capture producer, not a user's hosted
# login. A local Keychain prompt must not block the unattended smoke test.
probe_env["PYTHON_KEYRING_BACKEND"] = "keyring.backends.null.Keyring"
probe_env["OPENADAPT_CONFIG_TOML"] = str(root / "doctor-config.toml")
probe_env.pop("OPENADAPT_INGEST_TOKEN", None)
output, _ = _run([str(executable), "doctor"], env=probe_env, timeout=300)

line = next(
Expand Down
2 changes: 1 addition & 1 deletion scripts/sync_control_overlay_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
ROOT = Path(__file__).resolve().parents[1]
OUTPUT = ROOT / "src" / "overlay" / "generated" / "contract.ts"
SCHEMA_DIR = ROOT / "src" / "overlay" / "generated" / "schemas"
PINNED_TYPES_VERSION = "0.10.0"
PINNED_TYPES_VERSION = "0.17.0"
SCHEMA_NAMES = (
"control-overlay-frame-v2.json",
"control-overlay-timeline-v2.json",
Expand Down
63 changes: 48 additions & 15 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions src-tauri/src/pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ mod tests {
format!("https://connect?pairing={SECRET}&host=https://app.openadapt.ai"),
format!("openadapt://connect/run?pairing={SECRET}&host=https://app.openadapt.ai"),
format!("openadapt://connect?pairing={SECRET}&host=https://app.openadapt.ai#x"),
runner_uri(),
format!("openadapt://connect?pack={PACK}&bind={BIND}&origin=https://openadapt.ai"),
] {
assert!(action_for_url(&parse(&raw)).is_err(), "{raw}");
Expand All @@ -377,7 +376,6 @@ mod tests {
"openadapt://connect/runner?pack={PACK}&bind={BIND}&origin=https://openadapt.ai"
),
format!("{}#x", runner_uri()),
format!("openadapt://connect?pairing={SECRET}&host=https://app.openadapt.ai"),
format!("openadapt://runner?pairing={SECRET}&host=https://app.openadapt.ai"),
] {
assert!(action_for_url(&parse(&raw)).is_err(), "{raw}");
Expand Down
2 changes: 1 addition & 1 deletion src/overlay/generated/contract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated from openadapt-types 0.10.0. Do not edit by hand.
// Generated from openadapt-types 0.17.0. Do not edit by hand.

export const CONTROL_OVERLAY_FRAME_VERSION = "openadapt.control-overlay-frame/v2" as const;
export const CONTROL_OVERLAY_TIMELINE_VERSION = "openadapt.control-overlay-timeline/v2" as const;
Expand Down
8 changes: 4 additions & 4 deletions tests/test_build_frozen_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,15 +447,15 @@ def _pyproject(pin: str) -> Path:
return root

version, extras = frozen_notices.bundled_flow_pin(build.ROOT)
assert version == "1.34.0"
assert version == "1.35.1"
assert set(frozen_notices.FLOW_REQUIRED_EXTRAS) <= set(extras)

with pytest.raises(ValueError, match="console"):
frozen_notices.bundled_flow_pin(_pyproject("openadapt-flow==1.34.0"))
frozen_notices.bundled_flow_pin(_pyproject("openadapt-flow==1.35.1"))
with pytest.raises(ValueError, match="browser"):
frozen_notices.bundled_flow_pin(_pyproject("openadapt-flow[console]==1.34.0"))
frozen_notices.bundled_flow_pin(_pyproject("openadapt-flow[console]==1.35.1"))
with pytest.raises(ValueError, match="exact openadapt-flow build pin"):
frozen_notices.bundled_flow_pin(_pyproject("openadapt-flow[browser,console]>=1.34.0"))
frozen_notices.bundled_flow_pin(_pyproject("openadapt-flow[browser,console]>=1.35.1"))


def test_frozen_runtime_roots_carry_the_pinned_flow_extras() -> None:
Expand Down
14 changes: 14 additions & 0 deletions tests/test_native_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
import re
import subprocess
import tomllib
from pathlib import Path

import pytest
Expand Down Expand Up @@ -2836,3 +2837,16 @@ def test_production_workflow_keeps_normal_publication_unadmitted() -> None:
assert "write-channel" not in text
assert "unadmitted release candidate" in normal_release_text
assert "unadmitted release candidate" in native_release_text


def test_frontend_and_native_plugins_share_the_same_protocol_version() -> None:
"""A JS plugin update must ship with its matching native IPC implementation."""
root = Path(__file__).resolve().parents[1]
npm = json.loads((root / "package-lock.json").read_text(encoding="utf-8"))
cargo = tomllib.loads((root / "src-tauri/Cargo.lock").read_text(encoding="utf-8"))
native_versions = {package["name"]: package["version"] for package in cargo["package"]}
for name, package in npm["packages"].items():
prefix = "node_modules/@tauri-apps/plugin-"
if name.startswith(prefix):
native_name = "tauri-plugin-" + name.removeprefix(prefix)
assert package["version"] == native_versions[native_name], native_name
6 changes: 3 additions & 3 deletions tests/test_public_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def test_candidate_release_notes_describe_the_bundled_flow_runtime() -> None:
flow_dependencies = [
dependency for dependency in build_dependencies if dependency.startswith("openadapt-flow")
]
assert flow_dependencies == ["openadapt-flow[browser,console]==1.34.0"]
assert flow_dependencies == ["openadapt-flow[browser,console]==1.35.1"]
# At or above the floor the bundled Flow declares for its ``capture``
# extra; ``tests/test_capture_runtime_contract.py`` compares the two
# authoritatively. 1.2.1 specifically, because 1.2.0 and every release
Expand All @@ -289,8 +289,8 @@ def test_candidate_release_notes_describe_the_bundled_flow_runtime() -> None:
assert "openadapt-privacy>=1.0.0" in dependencies
assert not any(item.startswith("Development Status ::") for item in classifiers)
assert "Development Status :: 2 - Pre-Alpha" not in classifiers
assert bundled_flow_version() == "1.34.0"
assert bundled_flow_banner() == "openadapt-flow 1.34.0"
assert bundled_flow_version() == "1.35.1"
assert bundled_flow_banner() == "openadapt-flow 1.35.1"
assert 'name = "playwright"\nversion = "1.61.0"' in lock
assert flow_dependencies[0] in notes
assert "playwright==1.61.0" in notes
Expand Down
Loading