Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 10 additions & 7 deletions .mise/config.coverage.toml
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,22 @@ goawk -f "$keep" "$covdir/wasi.lcov" >> lcov.info
shell = "bash -euo pipefail -c"

[tasks.pytest-cov]
description = "Combined Python coverage (pyface1 pytest + web-runner Pyodide runs) -> Cobertura for Codecov/DeepSource"
# One Python report is combined from three data sources: pyface1's pytest run plus the web-runner Pyodide runs.
# The web-runner integration test drops pydata1's and pyface1's .coverage files into target/pycov/ when
# ET_TEST_COVERAGE is set; `coverage combine` then merges all three via config/coverage.toml's `[paths]` remap into
# a single Cobertura file. pytest-cov is a plugin, so it rides in pyface1's uv `dev` group -- the same venv as
# pytest -- and `uv run` (a mise-managed tool) installs both into the one project venv. UV_PYTHON mirrors
# test-pyface1's mise-CPython pin.
description = "Combined Python coverage (pytest + web-runner Pyodide runs) -> Cobertura for Codecov/DeepSource"
# One Python report is combined from several data sources: the pytest runs plus the web-runner Pyodide runs.
# The pyface1 + pyeye1 pytest runs and the web-runner integration test (which drops the modules' .coverage files
# into target/pycov/ when ET_TEST_COVERAGE is set) all feed `coverage combine`, which merges them via
# config/coverage.toml's `[paths]` remap into a single Cobertura file. pytest-cov is a plugin, so it rides in
# each module's uv `dev` group -- the same venv as pytest -- and `uv run` (a mise-managed tool) installs both
# into the one project venv. UV_PYTHON mirrors test-pyface1's mise-CPython pin.
run = """
pyface=services/ws-modules/pyface1
pyeye=services/ws-modules/pyeye1
pycov=target/pycov
mkdir -p "$pycov"
uv run --directory "$pyface" pytest --cov=pyface1 --cov-report=
cp "$pyface/.coverage" "$pycov/.coverage.pyface1_pytest"
uv run --directory "$pyeye" pytest --cov=pyeye1 --cov-report=
cp "$pyeye/.coverage" "$pycov/.coverage.pyeye1_pytest"
uv run --project "$pyface" coverage combine "$pycov"
uv run --project "$pyface" coverage xml -o coverage-python.xml
"""
Expand Down
4 changes: 4 additions & 0 deletions .mise/config.js.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
# there's no value in installing them when `js` isn't loaded.

[tools]
# MediaPipe tasks-vision runtime for pyeye1.
# pyeye1 loads @mediapipe/tasks-vision (FaceLandmarker) at runtime via /modules/@mediapipe/tasks-vision, the
# same npm-package-served-as-a-module pattern as onnxruntime-web (resolved in libs/edge-toolkit/src/config.rs).
"npm:@mediapipe/tasks-vision" = "latest"
"npm:onnxruntime-web" = "latest"
# oxlint-tsgolint is oxlint's type-aware engine.
# It's a typescript-go type checker oxlint shells out to under `--type-aware`. npm-only: it ships no GitHub
Expand Down
37 changes: 37 additions & 0 deletions .mise/config.maint.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#
# - publish-face1-to-hf-cache: refreshes the Hugging Face asset mirror in
# edge-toolkit/core's hf-cache-v<N> release.
# - publish-eye1-to-hf-cache: mirrors Google's face_landmarker.task
# (MediaPipe FaceLandmarker, used as-is) to the same hf-cache-v<N> release
# as the pyeye1 model.
# - publish-rp-wasm-to-release: builds upstream RustPython main with
# wasm-pack + freeze-stdlib, tars the pkg/ output, and uploads to
# edge-toolkit/core's rp-v<N> release (same release that holds the
Expand All @@ -13,6 +16,7 @@
# Not in ALL_LANGS (maint isn't a language); invoked manually:
#
# MISE_ENV=maint mise run publish-face1-to-hf-cache
# MISE_ENV=maint mise run publish-eye1-to-hf-cache
# MISE_ENV=maint mise run publish-rp-wasm-to-release

[tools]
Expand Down Expand Up @@ -131,6 +135,39 @@ echo "updated config/upstream-cache/data.toml + .mise/config.toml; conftest will
"""
shell = "bash -euo pipefail -c"

[tasks.publish-eye1-to-hf-cache]
depends = ["bootstrap-hf-cache-release"]
description = "Refresh eye1 (MediaPipe FaceLandmarker) mirror in hf-cache-v<N> release (manual / on bump)"
# Refresh the eye1 MediaPipe FaceLandmarker model mirror in the hf-cache release.
# Downloads Google's Apache-2.0 face_landmarker.task from the mediapipe-models bucket (used as-is, no
# conversion), computes the SHA256, uploads the .task + .task.sha256 sidecar to the release, then augtool-sets
# data.toml's eye1 sha256 so the in-repo manifest stays in sync (checksums.rego catches drift on next
# `mise run check`). eye1_asset has a stable name, so config.toml needs no edit.
run = """
work="$HF_CACHE_WORK/eye1"
src="https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task"
asset="{{ vars.eye1_asset }}"

coreutils rm -rf "$work"
coreutils mkdir -p "$work"
cd "$work"

rclone copyurl "$src" "$asset"
coreutils sha256sum "$asset" > "${asset}.sha256"
actual=$(coreutils cut -c1-64 "${asset}.sha256")

gh release upload "{{ vars.a_hf_cache_tag }}" --clobber --repo "$GH_REPO" "$asset" "${asset}.sha256"

cksum_path="{{ config_root }}/config/upstream-cache/data.toml"
augtool --transform="Toml incl $cksum_path" --autosave <<EOF
set "/files$cksum_path/table[. = 'asset.\"$asset\"']/entry[. = 'sha256']/string" "$actual"
EOF

echo "uploaded $asset to {{ vars.a_hf_cache_tag }}"
echo "updated config/upstream-cache/data.toml sha256; conftest will catch any drift"
"""
shell = "bash -euo pipefail -c"

[tasks.build-rp-wasm]
description = "Build rustpython_wasm via wasm-pack from a local RustPython checkout"
# Linux/macOS only (config.maint.toml is).
Expand Down
23 changes: 22 additions & 1 deletion .mise/config.python.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,15 @@ depends = ["ruff-fix"]
description = "Apply Python lint-fix passes"

[tasks."test:python"]
depends = ["test-pyface1"]
depends = ["test-pyeye1", "test-pyface1"]
description = "Run Python tests"

[tasks.test-pyeye1]
dir = "services/ws-modules/pyeye1"
# Same uv-interpreter pin as `[tasks."prefetch:python".env]`; see there.
env = { UV_PYTHON = "{% if os() == 'windows' %}{{ vars.py3_win }}{% else %}{{ vars.py3_unix }}{% endif %}" }
run = "uv run pytest"

[tasks.test-pyface1]
dir = "services/ws-modules/pyface1"
# Same uv-interpreter pin as `[tasks."prefetch:python".env]`; see there.
Expand Down Expand Up @@ -123,6 +129,20 @@ uv build --wheel --out-dir pkg
"""
shell = "bash -euo pipefail -c"

[tasks.build-ws-pyeye1-module]
depends = ["build-et-ws-wheel"]
description = "Build the pyeye1 Python MediaPipe eye detection workflow module"
dir = "services/ws-modules/pyeye1"
# et-ws is its own ws-module mounted at /modules/et-ws/, loaded at runtime, so only pyeye1's wheel builds here.
# pyeye1 loads the et-ws wheel at runtime from that mount. The MediaPipe FaceLandmarker runtime
# (@mediapipe/tasks-vision) and the model bundle (et-model-eye1) are served separately -- not part of this build.
run = """
rm -f pkg/*.whl
uv build --wheel --out-dir pkg
{{ vars.et_cli }} module-package-json
"""
shell = "bash -euo pipefail -c"

[tasks.build-ws-wasi-graphics-info-module]
depends = ["build-et-cli"]
description = "Build the WASI graphics-info Python module as a WASI Preview 2 component"
Expand Down Expand Up @@ -153,6 +173,7 @@ description = "Prefetch Python (uv) dependencies"
env = { UV_PYTHON = "{% if os() == 'windows' %}{{ vars.py3_win }}{% else %}{{ vars.py3_unix }}{% endif %}" }
run = """
uv sync --directory services/ws-modules/pydata1
uv sync --directory services/ws-modules/pyeye1
uv sync --directory services/ws-modules/pyface1
"""
shell = "bash -euo pipefail -c"
Expand Down
37 changes: 32 additions & 5 deletions .mise/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,13 @@ ort_loc_unix = "{{ vars.a_home }}/.local/share/mise/installs/github-microsoft-on
face1_asset = "RetinaFace_int-7b69507.onnx"
face1_dst = "data/model-modules/model-face1/pkg/video_cv.onnx"
face1_src = ":http:edge-toolkit/core/releases/download/{{ vars.a_hf_cache_tag }}/{{ vars.face1_asset }}"
# eye1 is pyeye1's MediaPipe FaceLandmarker model bundle (Apache-2.0), used as-is (no conversion).
# It is Google's face_landmarker.task, mirrored from the mediapipe-models bucket to the same hf-cache-v<N>
# release by publish-eye1-to-hf-cache in config.maint.toml. data.toml records the SHA256; checksums.rego
# cross-checks both sides.
eye1_asset = "face_landmarker.task"
eye1_dst = "data/model-modules/model-eye1/pkg/face_landmarker.task"
eye1_src = ":http:edge-toolkit/core/releases/download/{{ vars.a_hf_cache_tag }}/{{ vars.eye1_asset }}"
har_dst = "data/model-modules/model-har-motion1/pkg/har-motion1.onnx"
har_repo = ":http:acd17sk/MET-Metabolic-Equivalent-of-Task-AI-Android-APP"
har_src = "{{ vars.har_repo }}/raw/refs/heads/main/Models/onnx/hybrid_met.onnx"
Expand Down Expand Up @@ -1002,9 +1009,16 @@ description = "Flag dependencies whose upstream repo is archived or unmaintained
# cargo-unmaintained is deliberately NOT a mise [tool].
# It has no prebuilt and a from-source `cargo install` is too heavy to pay on every `mise install`. The
# `dependencies` workflow installs it via taiki-e/install-action; this task just runs the binary so the
# audit command lives beside the others. A GITHUB_TOKEN in the env lets it check each upstream repo's
# archival status.
run = "cargo unmaintained"
# audit command lives beside the others. cargo-unmaintained needs a GitHub token to check each upstream
# repo's archival status: the CI workflow already sets GITHUB_TOKEN, so the `:=` default is a no-op there;
# locally (where the env var is unset) it falls back to `gh auth token`, so a dev never has to export one by
# hand. `set -u` is satisfied because `${VAR:=...}` assigns before the reference.
run = """
: "${GITHUB_TOKEN:=$(gh auth token)}"
export GITHUB_TOKEN
cargo unmaintained
"""
shell = "bash -euo pipefail -c"

[tasks."gen:dockerignore"]
description = "Regenerate .dockerignore from .gitignore + Docker-only excludes"
Expand Down Expand Up @@ -1058,7 +1072,7 @@ description = "Pre-download CI-required dependencies + the MNIST model"

[tasks.prefetch]
# "dprint-check" is here to trigger download of the dprint plugin WASM files.
depends = ["dprint-check", "fetch-face1-rclone", "fetch-har-motion1-rclone", "prefetch-ci"]
depends = ["dprint-check", "fetch-eye1-rclone", "fetch-face1-rclone", "fetch-har-motion1-rclone", "prefetch-ci"]
description = "Pre-download all dependencies and models (superset of prefetch-ci)"

[tasks."prefetch:rust"]
Expand Down Expand Up @@ -1389,6 +1403,19 @@ actual=$(mise exec -- coreutils sha256sum -b "{{ vars.face1_dst }}" | mise exec
"""
shell = "bash -euo pipefail -c"

[tasks.fetch-eye1-rclone]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Remove duplicated TOML table headers. Each repeated standard table declaration makes its file invalid TOML and blocks the associated mise or upstream-cache workflow.

  • .mise/config.toml#L1406-L1406: retain only one [tasks.fetch-eye1-rclone] header.
  • config/upstream-cache/data.toml#L30-L30: retain only one [asset."face_landmarker.task"] header.
📍 Affects 2 files
  • .mise/config.toml#L1406-L1406 (this comment)
  • config/upstream-cache/data.toml#L30-L30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.mise/config.toml at line 1406, Remove the duplicated TOML table headers,
retaining only one [tasks.fetch-eye1-rclone] declaration in .mise/config.toml
and one [asset."face_landmarker.task"] declaration in
config/upstream-cache/data.toml; preserve the settings under each table.

# Same shape as fetch-face1-rclone (rclone copy + Windows-safe SHA256 verify against data.toml).
# The FaceMesh .task is mirrored to the hf-cache-v<N> release by `MISE_ENV=maint mise run
# publish-eye1-to-hf-cache`; refresh it there on an upstream bump.
run = """
rclone copyto {{ vars.eye1_src }} {{ vars.eye1_dst }} {{ vars.gh_http }}
export asset='{{ vars.eye1_asset }}'
sha=$(mise exec -- yq -p toml -oy '.asset[strenv(asset)].sha256' config/upstream-cache/data.toml)
actual=$(mise exec -- coreutils sha256sum -b "{{ vars.eye1_dst }}" | mise exec -- coreutils cut -c1-64)
[ "$actual" = "$sha" ] || { echo "eye1 checksum mismatch: expected=$sha actual=$actual" >&2; exit 1; }
"""
shell = "bash -euo pipefail -c"

[tasks.fetch-har-motion1-rclone]
run = "rclone copyto {{ vars.har_src }} {{ vars.har_dst }} {{ vars.gh_http }}"
shell = "bash -euo pipefail -c"
Expand All @@ -1401,7 +1428,7 @@ run = "rclone copyto {{ vars.mnist_src }} {{ vars.mnist_dst }} {{ vars.gh_http }
shell = "bash -euo pipefail -c"

[tasks.download-models]
depends = ["fetch-face1-rclone", "fetch-har-motion1-rclone", "fetch-mnist-rclone"]
depends = ["fetch-eye1-rclone", "fetch-face1-rclone", "fetch-har-motion1-rclone", "fetch-mnist-rclone"]

[tasks.cargo-test]
description = "Run every Rust test via nextest (web-runner excluded on gnullvm)"
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ Languages:
- **Rust -> WASM** (wasm-pack): audio1, bluetooth, comm1, data1, face-detection, geolocation, graphics-info, har1, nfc,
sensor1, speech-recognition, video1
- **Dart -> JS**: dart-comm1
- **Python (Pyodide)**: pydata1, pyface1
- **Python (Pyodide)**: pydata1, pyeye1, pyface1
- **C# (.NET WASM)**: dotnet-data1
- **Java (TeaVM -> JS)**: java-data1
- **Zig -> WASM**: zig-data1
Expand Down
44 changes: 24 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -324,52 +324,52 @@ ignore = [
# Upstream contain-rs/bit-set is unmaintained; the newer 0.9.1 is flagged too.
# Pulled by the Deno stack (deno_core, and naga/wgpu-core via deno_webgpu).
"bit-set",
# 1153 days since last update at bitvecto-rs/bitvec.
# Unmaintained upstream at bitvecto-rs/bitvec.
# Pulled by sourcemap (via swc tooling under deno_ast).
"bitvec",
# 536 days since last update at dsherret/capacity_builder.
# Unmaintained upstream at dsherret/capacity_builder.
# Pulled by deno_ast.
"capacity_builder",
# 1702 days since last update at jethrogb/rust-cexpr.
# Unmaintained upstream at jethrogb/rust-cexpr.
# Pulled by bindgen (build-time only via aws-lc-sys / ort-sys).
"cexpr",
# 577 days since last update at dajoha/color-print.
# Unmaintained upstream at dajoha/color-print.
# Pulled by deno_node via color-print.
"color-print-proc-macro",
# Archived upstream at matklad/countme.
"countme",
# 676 days since last update at denoland/deno_native_certs.
# Unmaintained upstream at denoland/deno_native_certs.
# Pulled by deno_node + deno_tls.
"deno_native_certs",
# No `repository` declared. Pulled by deno_node for `os.userInfo()`.
"deno_whoami",
# 1853 days since last update at xdg-rs/dirs.
# Unmaintained upstream at xdg-rs/dirs.
"dirs-sys-next",
# 3182 days since last update at faradayio/exec-rs.
# Unmaintained upstream at faradayio/exec-rs.
# Pulled by Deno's `node_shim` (process re-exec on Node compatibility shim).
"exec",
# cargo-unmaintained can't find a crate of this name in the denoland/deno monorepo its `repository` field names.
# It is a workspace member there, so the "not in <repo>" heuristic misfires. Pulled by the Deno registry stack.
"fast-registry-json",
# 933 days since last update at HdrHistogram/HdrHistogram_rust.
# Unmaintained upstream at HdrHistogram/HdrHistogram_rust.
# Pulled by deno_node (perf hooks).
"hdrhistogram",
# 460 days since last update at xacrimon/dashmap.
# Unmaintained upstream at xacrimon/dashmap.
# Pulled by deno_maybe_sync. (Marked stable / feature-complete by upstream.)
"dashmap",
# jni-sys requirement ^0.3.0 (used 0.3.1, latest 0.4.1); pulled by ndk-sys, an Android-only dep.
# Reached via wgpu-hal (deno_webgpu -> wgpu); never compiled on our target platforms.
"jni-sys",
# 495 days since last update at rust-lang-nursery/lazy-static.rs.
# Unmaintained upstream at rust-lang-nursery/lazy-static.rs.
# Pulled by actix-web-thiserror-derive (build proc-macro).
"lazy_static",
# ndk-sys last updated ~365 days ago; Android-only, reached via wgpu-hal (deno_webgpu -> wgpu).
# ndk-sys unmaintained upstream; Android-only, reached via wgpu-hal (deno_webgpu -> wgpu).
# Never compiled on our target platforms.
"ndk-sys",
# 391 days since last update at rust-num/num-complex.
# Unmaintained upstream at rust-num/num-complex.
# Pulled by nalgebra (via wgpu / naga). Stable foundational math crate.
"num-complex",
# 2215 days since last update at SSheldon/rust-objc.
# Unmaintained upstream at SSheldon/rust-objc.
# Pulled by `metal` (macOS GPU bindings via wgpu).
"objc",
# Not in declared repo (RustCrypto/utils).
Expand All @@ -378,7 +378,7 @@ ignore = [
"opaque-debug",
# cargo-unmaintained doesn't follow `hg` repositories.
"oorandom",
# 1052 days since last update at hjiayz/p12.
# Unmaintained upstream at hjiayz/p12.
# Pulled by deno_node_crypto for PKCS#12 cert bundles.
"p12",
# Archived upstream at dtolnay/paste.
Expand All @@ -389,7 +389,7 @@ ignore = [
# Pulled by getset via neli via local-ip-address. Compile-time only.
"proc-macro-error-attr2",
"proc-macro-error2",
# 603 days since last update at timvisee/qr2term-rs.
# Unmaintained upstream at timvisee/qr2term-rs.
"qr2term",
# False positive.
# rand_chacha lives in rust-random/rand as a workspace subdir (rand_chacha/).
Expand All @@ -398,20 +398,24 @@ ignore = [
# Archived upstream at rustls/pemfile. Pulled by deno_native_certs.
# rustls itself has moved to inline pemfile parsing.
"rustls-pemfile",
# 2154 days since last update at arcnmx/serde-value.
# Unmaintained upstream at denoland/rustls-tokio-stream.
# Its derive-io (=0.4.1) and socket2 (^0.5) requirements lag latest; pulled by the Deno net/TLS stack
# (deno_net -> deno_runtime).
"rustls-tokio-stream",
# Unmaintained upstream at arcnmx/serde-value.
# Pulled by deno_ffi.
"serde-value",
# 732 days since last update at TedDriggs/serde_default; its `darling` requirement lags the latest release.
# Unmaintained upstream at TedDriggs/serde_default; its `darling` requirement lags the latest release.
# A direct dependency of edge-toolkit for the serde-attribute `Default` derive.
"serde_default",
# Archived upstream at bodil/smartstring.
# Pulled by swc_ecma_lexer via deno_ast.
"smartstring",
# https://github.com/rustsec/advisory-db/issues/2132
"serde_yaml",
# 700 days since last update at dalek-cryptography/subtle.
# Unmaintained upstream at dalek-cryptography/subtle.
"subtle",
# 1400 days since last update at hucsmn/suffix_array; its `bincode` requirement lags the latest release.
# Unmaintained upstream at hucsmn/suffix_array; its `bincode` requirement lags the latest release.
# Pulled by qbsdiff (binary diffing) via deno_runtime.
"suffix_array",
# Archived upstream at rust-analyzer/text-size.
Expand All @@ -426,7 +430,7 @@ ignore = [
# Declared repository alacritty/vte is a single-crate repo with no `utf8parse` member.
# The crate is effectively orphaned upstream.
"utf8parse",
# 517 days since last update at daxpedda/web-time.
# Unmaintained upstream at daxpedda/web-time.
"web-time",
# Not in declared repo (gfx-rs/wgpu): a per-platform helper crate from the wgpu monorepo.
# cargo-unmaintained can't find the individual member at the repo root -- false positive; pulled by wgpu-core.
Expand Down
3 changes: 2 additions & 1 deletion config/coverage.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# coverage.py config for the combined Python report (referenced via COVERAGE_RCFILE by the pytest-cov task).
# Three data sources feed one report: pyface1's pytest run, and the web-runner Pyodide runs of pydata1 + pyface1
# Data sources feed one report: the pytest runs, and the web-runner Pyodide runs of pydata1 + pyface1 + pyeye1
# (whose .coverage files the web-runner integration test drops into target/pycov/). `[tool.coverage.paths]` remaps
# each source's recorded path to the repo-relative one so `coverage combine` merges them into a single file entry:
# pytest records relative paths (pyface1/...); the Pyodide runs record absolute in-interpreter paths
Expand All @@ -11,4 +11,5 @@ relative_files = true

[tool.coverage.paths]
pydata1 = ["services/ws-modules/pydata1/pydata1", "pydata1", "**/pydata1"]
pyeye1 = ["services/ws-modules/pyeye1/pyeye1", "pyeye1", "**/pyeye1"]
pyface1 = ["services/ws-modules/pyface1/pyface1", "pyface1", "**/pyface1"]
7 changes: 6 additions & 1 deletion config/pyrefly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ project-excludes = [
]

# Package roots so intra-package imports (`pyface1.face_detection`) resolve as real modules, not `__unknown__.*`.
search-path = ["../services/ws-modules/pydata1", "../services/ws-modules/pyface1", "../services/ws-pyo3-runner/python"]
search-path = [
"../services/ws-modules/pydata1",
"../services/ws-modules/pyeye1",
"../services/ws-modules/pyface1",
"../services/ws-pyo3-runner/python",
]

# Third-party deps and generated packages that are absent from (or opaque to) the lint environment.
# `replace-imports-with-any` (rather than a blanket ignore) keeps import resolution deterministic across every OS
Expand Down
Loading
Loading