echoui 0.9.1__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.
- echoui-0.9.1/.github/workflows/ci.yml +38 -0
- echoui-0.9.1/.github/workflows/ios-build.yml +42 -0
- echoui-0.9.1/.gitignore +64 -0
- echoui-0.9.1/AGENTS.md +24 -0
- echoui-0.9.1/CHANGELOG.md +27 -0
- echoui-0.9.1/DELIVERY_PLAN.md +34 -0
- echoui-0.9.1/LICENSE +21 -0
- echoui-0.9.1/PKG-INFO +137 -0
- echoui-0.9.1/PROGRESS.md +47 -0
- echoui-0.9.1/README.md +71 -0
- echoui-0.9.1/achecker.py +1598 -0
- echoui-0.9.1/docs/README.md +14 -0
- echoui-0.9.1/docs/api/INDEX.md +16 -0
- echoui-0.9.1/docs/api/getting-started.md +41 -0
- echoui-0.9.1/docs/api/non-goals.md +11 -0
- echoui-0.9.1/docs/api/roles.md +27 -0
- echoui-0.9.1/docs/api/targets.md +18 -0
- echoui-0.9.1/docs-src/INDEX.md +25 -0
- echoui-0.9.1/docs-src/docs-src-guide.md +74 -0
- echoui-0.9.1/docs-src/echoui/INDEX.md +28 -0
- echoui-0.9.1/docs-src/echoui/api/core/app-screen-sprite.md +29 -0
- echoui-0.9.1/docs-src/echoui/api/events/on-cli.md +22 -0
- echoui-0.9.1/docs-src/echoui/api/layout/row-col.md +20 -0
- echoui-0.9.1/docs-src/echoui/api/reactive/signal.md +48 -0
- echoui-0.9.1/docs-src/echoui/api/roles/text-button.md +25 -0
- echoui-0.9.1/docs-src/echoui/api/v0.1-index.md +11 -0
- echoui-0.9.1/docs-src/examples/INDEX.md +17 -0
- echoui-0.9.1/docs-src/guide-references/API_/345/233/276/351/211/264/346/250/241/346/235/277.md +88 -0
- echoui-0.9.1/docs-src/guide-references/DOC_/350/247/204/350/214/203.md +39 -0
- echoui-0.9.1/docs-src/guide-references/code-guide.md +57 -0
- echoui-0.9.1/docs-src/guide-references/docs-tests-guide.md +19 -0
- echoui-0.9.1/docs-src/guide-references/troubleshooting.md +61 -0
- echoui-0.9.1/docs-src/guide-references//346/230/223/346/267/267/346/267/206/345/257/271/347/205/247.md +76 -0
- echoui-0.9.1/docs-src/tests/INDEX.md +26 -0
- echoui-0.9.1/docs-src/tests-guide.md +59 -0
- echoui-0.9.1/echoui/__init__.py +31 -0
- echoui-0.9.1/echoui/__main__.py +3 -0
- echoui-0.9.1/echoui/a11y/__init__.py +58 -0
- echoui-0.9.1/echoui/animation.py +95 -0
- echoui-0.9.1/echoui/api/__init__.py +82 -0
- echoui-0.9.1/echoui/app.py +50 -0
- echoui-0.9.1/echoui/async_.py +17 -0
- echoui-0.9.1/echoui/audio/__init__.py +1 -0
- echoui-0.9.1/echoui/bridge/__init__.py +45 -0
- echoui-0.9.1/echoui/camera.py +56 -0
- echoui-0.9.1/echoui/canvas.py +31 -0
- echoui-0.9.1/echoui/chain.py +43 -0
- echoui-0.9.1/echoui/cli.py +148 -0
- echoui-0.9.1/echoui/clone.py +42 -0
- echoui-0.9.1/echoui/collab/__init__.py +47 -0
- echoui-0.9.1/echoui/compiler/__init__.py +1 -0
- echoui-0.9.1/echoui/compiler/analyzer.py +21 -0
- echoui-0.9.1/echoui/compiler/bundler.py +69 -0
- echoui-0.9.1/echoui/compiler/emit_web.py +162 -0
- echoui-0.9.1/echoui/compiler/lower.py +28 -0
- echoui-0.9.1/echoui/compiler/optimizer.py +9 -0
- echoui-0.9.1/echoui/compiler/parser.py +44 -0
- echoui-0.9.1/echoui/compiler/ssr.py +24 -0
- echoui-0.9.1/echoui/contrib/__init__.py +3 -0
- echoui-0.9.1/echoui/contrib/devtools.py +37 -0
- echoui-0.9.1/echoui/desktop/__init__.py +1 -0
- echoui-0.9.1/echoui/events.py +50 -0
- echoui-0.9.1/echoui/exceptions.py +9 -0
- echoui-0.9.1/echoui/forms/__init__.py +149 -0
- echoui-0.9.1/echoui/gestures.py +102 -0
- echoui-0.9.1/echoui/graphql/__init__.py +1 -0
- echoui-0.9.1/echoui/i18n/__init__.py +35 -0
- echoui-0.9.1/echoui/input.py +49 -0
- echoui-0.9.1/echoui/layout.py +103 -0
- echoui-0.9.1/echoui/media/__init__.py +1 -0
- echoui-0.9.1/echoui/mobile/__init__.py +1 -0
- echoui-0.9.1/echoui/monitor.py +17 -0
- echoui-0.9.1/echoui/overlay.py +80 -0
- echoui-0.9.1/echoui/pathfind.py +47 -0
- echoui-0.9.1/echoui/pen.py +40 -0
- echoui-0.9.1/echoui/physics.py +79 -0
- echoui-0.9.1/echoui/platform/__init__.py +37 -0
- echoui-0.9.1/echoui/plugin.py +26 -0
- echoui-0.9.1/echoui/print/__init__.py +23 -0
- echoui-0.9.1/echoui/query/__init__.py +127 -0
- echoui-0.9.1/echoui/raw.py +61 -0
- echoui-0.9.1/echoui/reactive.py +181 -0
- echoui-0.9.1/echoui/roles.py +36 -0
- echoui-0.9.1/echoui/router/__init__.py +82 -0
- echoui-0.9.1/echoui/rpc/__init__.py +1 -0
- echoui-0.9.1/echoui/rtc/__init__.py +1 -0
- echoui-0.9.1/echoui/runtime/__init__.py +1 -0
- echoui-0.9.1/echoui/screen.py +36 -0
- echoui-0.9.1/echoui/signals.py +37 -0
- echoui-0.9.1/echoui/sprite.py +140 -0
- echoui-0.9.1/echoui/stage.py +38 -0
- echoui-0.9.1/echoui/state.py +70 -0
- echoui-0.9.1/echoui/storage/__init__.py +116 -0
- echoui-0.9.1/echoui/style.py +56 -0
- echoui-0.9.1/echoui/svg.py +26 -0
- echoui-0.9.1/echoui/targets/__init__.py +3 -0
- echoui-0.9.1/echoui/targets/desktop.py +55 -0
- echoui-0.9.1/echoui/targets/gui.py +40 -0
- echoui-0.9.1/echoui/targets/mobile_android.py +34 -0
- echoui-0.9.1/echoui/targets/static.py +31 -0
- echoui-0.9.1/echoui/targets/tui.py +52 -0
- echoui-0.9.1/echoui/tasks.py +20 -0
- echoui-0.9.1/echoui/testing/__init__.py +121 -0
- echoui-0.9.1/echoui/three/__init__.py +1 -0
- echoui-0.9.1/echoui/tiles.py +33 -0
- echoui-0.9.1/echoui/time.py +20 -0
- echoui-0.9.1/echoui/wasm.py +15 -0
- echoui-0.9.1/echoui/workers.py +19 -0
- echoui-0.9.1/examples/01_hello_web/main.py +12 -0
- echoui-0.9.1/examples/02_counter/main.py +16 -0
- echoui-0.9.1/examples/03_game_free_mode/main.py +35 -0
- echoui-0.9.1/examples/04_multi_screen_game/main.py +46 -0
- echoui-0.9.1/examples/05_escape_layer/main.py +29 -0
- echoui-0.9.1/pyproject.toml +70 -0
- echoui-0.9.1/requirements.txt +12 -0
- echoui-0.9.1/scripts/benchmark_reactive.py +51 -0
- echoui-0.9.1/scripts/bootstrap_skeleton.py +72 -0
- echoui-0.9.1/scripts/check_banned_terms.py +43 -0
- echoui-0.9.1/tests/a11y/test_a11y_audit.py +33 -0
- echoui-0.9.1/tests/conftest.py +14 -0
- echoui-0.9.1/tests/integration/test_build_tui.py +28 -0
- echoui-0.9.1/tests/integration/test_build_web.py +39 -0
- echoui-0.9.1/tests/unit/test_compiler.py +56 -0
- echoui-0.9.1/tests/unit/test_counter.py +45 -0
- echoui-0.9.1/tests/unit/test_escape.py +51 -0
- echoui-0.9.1/tests/unit/test_forms.py +45 -0
- echoui-0.9.1/tests/unit/test_layout.py +33 -0
- echoui-0.9.1/tests/unit/test_reactive.py +51 -0
- echoui-0.9.1/tests/unit/test_router.py +50 -0
- echoui-0.9.1/tests/visual/test_snapshot.py +29 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: pip install -e ".[web,dev]" tree-sitter tree-sitter-language-pack echotools
|
|
23
|
+
- name: Prefetch tree-sitter parsers
|
|
24
|
+
run: python -c "from tree_sitter_language_pack import download; download(['python','javascript','typescript','tsx','json','yaml','toml','html','css','bash','markdown','vue'])"
|
|
25
|
+
- name: check_banned_terms
|
|
26
|
+
run: python scripts/check_banned_terms.py
|
|
27
|
+
- name: ruff
|
|
28
|
+
run: ruff check .
|
|
29
|
+
- name: mypy
|
|
30
|
+
run: mypy echoui
|
|
31
|
+
- name: pytest
|
|
32
|
+
run: pytest -q
|
|
33
|
+
- name: achecker
|
|
34
|
+
run: python achecker.py
|
|
35
|
+
- name: build
|
|
36
|
+
run: python -m build
|
|
37
|
+
- name: twine check
|
|
38
|
+
run: twine check dist/*
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: iOS Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- "v*"
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build-ios:
|
|
11
|
+
runs-on: macos-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
- name: Install EchoUI
|
|
19
|
+
run: pip install -e ".[web,dev]"
|
|
20
|
+
- name: Build web bundle for mobile shell
|
|
21
|
+
run: |
|
|
22
|
+
python - <<'PY'
|
|
23
|
+
import importlib.util
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
spec = importlib.util.spec_from_file_location("demo", "examples/01_hello_web/main.py")
|
|
26
|
+
mod = importlib.util.module_from_spec(spec)
|
|
27
|
+
spec.loader.exec_module(mod)
|
|
28
|
+
out = Path("dist/ios-web")
|
|
29
|
+
mod.app.compile(target="web", out_dir=str(out))
|
|
30
|
+
assert (out / "index.html").exists()
|
|
31
|
+
print("web bundle ready for iOS WebView shell")
|
|
32
|
+
PY
|
|
33
|
+
- name: Package placeholder IPA metadata
|
|
34
|
+
run: |
|
|
35
|
+
mkdir -p dist/ios
|
|
36
|
+
echo "EchoUI iOS shell uses web bundle + WKWebView template" > dist/ios/README.txt
|
|
37
|
+
tar -czf dist/echoui-ios-web-bundle.tar.gz dist/ios-web dist/ios
|
|
38
|
+
- name: Upload artifact
|
|
39
|
+
uses: actions/upload-artifact@v4
|
|
40
|
+
with:
|
|
41
|
+
name: echoui-ios-bundle
|
|
42
|
+
path: dist/echoui-ios-web-bundle.tar.gz
|
echoui-0.9.1/.gitignore
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Directories
|
|
2
|
+
.qoder
|
|
3
|
+
.claude
|
|
4
|
+
.codebuddy
|
|
5
|
+
.env
|
|
6
|
+
.git
|
|
7
|
+
.idea
|
|
8
|
+
.pytest_cache
|
|
9
|
+
.scripts
|
|
10
|
+
.svn
|
|
11
|
+
.vscode
|
|
12
|
+
.zed
|
|
13
|
+
.opencode
|
|
14
|
+
__pycache__
|
|
15
|
+
data
|
|
16
|
+
env
|
|
17
|
+
node_modules
|
|
18
|
+
persist
|
|
19
|
+
venv
|
|
20
|
+
agent_log
|
|
21
|
+
config/
|
|
22
|
+
.agents/
|
|
23
|
+
/plugins/
|
|
24
|
+
|
|
25
|
+
# Extensions
|
|
26
|
+
*.dll
|
|
27
|
+
*.dylib
|
|
28
|
+
*.json
|
|
29
|
+
!_manifest.json
|
|
30
|
+
!**/_manifest.json
|
|
31
|
+
*.pyc
|
|
32
|
+
*.pyd
|
|
33
|
+
*.pyo
|
|
34
|
+
*.so
|
|
35
|
+
*.srt
|
|
36
|
+
config.toml
|
|
37
|
+
*.wasm
|
|
38
|
+
*.zip
|
|
39
|
+
|
|
40
|
+
# File names
|
|
41
|
+
.DS_Store
|
|
42
|
+
Thumbs.db
|
|
43
|
+
desktop.ini
|
|
44
|
+
abnormis.txt
|
|
45
|
+
CLAUDE.local.md
|
|
46
|
+
CLAUDE.md
|
|
47
|
+
nul
|
|
48
|
+
|
|
49
|
+
# plugins
|
|
50
|
+
/plugins/
|
|
51
|
+
|
|
52
|
+
# Build artifacts
|
|
53
|
+
dist/
|
|
54
|
+
*.egg-info/
|
|
55
|
+
_scan_out.txt
|
|
56
|
+
|
|
57
|
+
!template/
|
|
58
|
+
|
|
59
|
+
# Config manager backups
|
|
60
|
+
template/old/
|
|
61
|
+
.backup/
|
|
62
|
+
|
|
63
|
+
logs/
|
|
64
|
+
.htaccess
|
echoui-0.9.1/AGENTS.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Task Completion Requirements
|
|
2
|
+
|
|
3
|
+
- Environment/configuration health check and static type checking must pass before considering tasks completed.
|
|
4
|
+
- Run code style/lint checks (`ruff check .`) — must pass.
|
|
5
|
+
- Run `python achecker.py` — must pass with 0 violations.
|
|
6
|
+
- Run `pytest -q`, `mypy echoui`, `python -m build`, `twine check dist/*` for release-ready changes.
|
|
7
|
+
|
|
8
|
+
## Project Snapshot
|
|
9
|
+
|
|
10
|
+
EchoUI is a Python-first UI framework using the **Screen → Stage → Sprite** paradigm. It compiles to web, static, TUI, desktop, and GUI targets.
|
|
11
|
+
|
|
12
|
+
Package: `echoui` · Version line: **0.9.0** · License: MIT
|
|
13
|
+
|
|
14
|
+
## Core Priorities
|
|
15
|
+
|
|
16
|
+
1. Reactive correctness (Signal / Computed / Store).
|
|
17
|
+
2. Compiler + runtime parity across documented targets.
|
|
18
|
+
3. Honest capability matrix — mark `done-degraded` or `interface-only` instead of silent stubs.
|
|
19
|
+
|
|
20
|
+
## Documentation
|
|
21
|
+
|
|
22
|
+
- User docs: `docs/api/`
|
|
23
|
+
- Spec mirror: `docs-src/`
|
|
24
|
+
- Phase matrix: `.claude/docs/08_全量追踪矩阵.md` (sync with `PROGRESS.md`)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
- Fix TUI build JSON serialization for reactive lambdas
|
|
6
|
+
- Add `python -m echoui` entry via `__main__.py`
|
|
7
|
+
- Bootstrap modules, examples `01_hello_web` / `03_game_free_mode`, visual/a11y tests
|
|
8
|
+
- docs-src API catalog entries; iOS CI workflow; reactive benchmark script
|
|
9
|
+
|
|
10
|
+
## 0.9.0
|
|
11
|
+
|
|
12
|
+
- Release-ready packaging: version aligned across pyproject, package, docs, and CHANGELOG
|
|
13
|
+
- Quality gate: ruff, mypy, pytest; wheel build + twine check
|
|
14
|
+
- Marks v0.1–v0.9 feature set as the first public-ready cut (see PROGRESS.md)
|
|
15
|
+
|
|
16
|
+
## 0.1.0
|
|
17
|
+
|
|
18
|
+
- Reactive core: Signal, Computed, Effect, batch, Store
|
|
19
|
+
- Screen–Stage–Sprite paradigm with flow and free layout
|
|
20
|
+
- Web compiler pipeline: parser → analyzer → optimizer → lower → emit → bundler
|
|
21
|
+
- CLI: new, dev, build, check, version
|
|
22
|
+
- Testing harness: mount, fire, tick, snapshot
|
|
23
|
+
- Router with guards and middleware
|
|
24
|
+
- Forms, storage, query, animation, gestures, overlay
|
|
25
|
+
- Escape layer (raw.js/html/css) and bridge.web_api
|
|
26
|
+
- Static, TUI, desktop, GUI, Android template targets
|
|
27
|
+
- Collab CRDT, data tables, i18n, a11y, print, platform, plugins
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# EchoUI Delivery Plan
|
|
2
|
+
|
|
3
|
+
## DoD (v0.9 全量)
|
|
4
|
+
- [x] Version 0.9.0 aligned in pyproject / package / CHANGELOG / docs-src
|
|
5
|
+
- [x] Local CI equivalent green: ruff, mypy, pytest
|
|
6
|
+
- [x] `python -m build` + `twine check dist/*` pass
|
|
7
|
+
- [x] `py achecker.py` → 0 violations
|
|
8
|
+
- [x] User docs under `docs/api/` (getting-started, targets, non-goals, roles)
|
|
9
|
+
- [x] `08_全量追踪矩阵.md` synced with PROGRESS (no blank `not-started` on shipped scope)
|
|
10
|
+
- [x] Initial git commit on `main` (no push unless requested)
|
|
11
|
+
|
|
12
|
+
## Non-goals
|
|
13
|
+
- Do not require `twine upload` without credentials
|
|
14
|
+
- Do not change completed API semantics without documenting degradation
|
|
15
|
+
|
|
16
|
+
## Work items
|
|
17
|
+
1. [x] Bump to 0.9.0; fix docs still marked 待实现
|
|
18
|
+
2. [x] Quality gate: ruff → mypy → pytest
|
|
19
|
+
3. [x] Build wheel + twine check
|
|
20
|
+
4. [x] achecker EchoUI layout exemptions + docs/api fill
|
|
21
|
+
5. [x] AGENTS.md / README / PROGRESS / matrix sync
|
|
22
|
+
6. [x] CI workflow includes achecker + build smoke
|
|
23
|
+
|
|
24
|
+
## Verify
|
|
25
|
+
```powershell
|
|
26
|
+
cd X:\Project\Public\EchoUI
|
|
27
|
+
pip install -e ".[web,dev]"
|
|
28
|
+
ruff check .
|
|
29
|
+
mypy echoui
|
|
30
|
+
pytest -q
|
|
31
|
+
py achecker.py
|
|
32
|
+
python -m build
|
|
33
|
+
twine check dist/*
|
|
34
|
+
```
|
echoui-0.9.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 nichengfuben
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
echoui-0.9.1/PKG-INFO
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: echoui
|
|
3
|
+
Version: 0.9.1
|
|
4
|
+
Summary: Universal Python-first UI framework — one Screen-Stage-Sprite paradigm compiles to Web, desktop, mobile, TUI, and GUI.
|
|
5
|
+
Project-URL: Homepage, https://github.com/nichengfuben/echoui
|
|
6
|
+
Project-URL: Documentation, https://echoui.dev
|
|
7
|
+
Author-email: nichengfuben <nichengfuben@outlook.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: compiler,desktop,framework,fullstack,gui,mobile,tui,ui,web
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
|
+
Requires-Dist: csscompressor>=0.9.5
|
|
13
|
+
Requires-Dist: rjsmin>=1.2.2
|
|
14
|
+
Requires-Dist: watchfiles>=0.21.0
|
|
15
|
+
Provides-Extra: all
|
|
16
|
+
Requires-Dist: aiohttp>=3.9.5; extra == 'all'
|
|
17
|
+
Requires-Dist: box2d-py>=2.3.10; extra == 'all'
|
|
18
|
+
Requires-Dist: build>=1.2.1; extra == 'all'
|
|
19
|
+
Requires-Dist: fastapi>=0.110.0; extra == 'all'
|
|
20
|
+
Requires-Dist: hatchling; extra == 'all'
|
|
21
|
+
Requires-Dist: msgpack>=1.0.8; extra == 'all'
|
|
22
|
+
Requires-Dist: mypy>=1.9.0; extra == 'all'
|
|
23
|
+
Requires-Dist: playwright>=1.43.0; extra == 'all'
|
|
24
|
+
Requires-Dist: pyarrow>=15.0.2; extra == 'all'
|
|
25
|
+
Requires-Dist: pyinstaller>=6.6.0; extra == 'all'
|
|
26
|
+
Requires-Dist: pyside6>=6.7.0; extra == 'all'
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.23.6; extra == 'all'
|
|
28
|
+
Requires-Dist: pytest-qt>=4.4.0; extra == 'all'
|
|
29
|
+
Requires-Dist: pytest>=8.1.1; extra == 'all'
|
|
30
|
+
Requires-Dist: rich>=13.7.1; extra == 'all'
|
|
31
|
+
Requires-Dist: ruff>=0.4.1; extra == 'all'
|
|
32
|
+
Requires-Dist: textual>=0.58.0; extra == 'all'
|
|
33
|
+
Requires-Dist: twine>=5.1.1; extra == 'all'
|
|
34
|
+
Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'all'
|
|
35
|
+
Provides-Extra: data
|
|
36
|
+
Requires-Dist: pyarrow>=15.0.2; extra == 'data'
|
|
37
|
+
Provides-Extra: desktop
|
|
38
|
+
Requires-Dist: pyinstaller>=6.6.0; extra == 'desktop'
|
|
39
|
+
Requires-Dist: pyside6>=6.7.0; extra == 'desktop'
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: build>=1.2.1; extra == 'dev'
|
|
42
|
+
Requires-Dist: hatchling; extra == 'dev'
|
|
43
|
+
Requires-Dist: mypy>=1.9.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest-asyncio>=0.23.6; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest>=8.1.1; extra == 'dev'
|
|
46
|
+
Requires-Dist: ruff>=0.4.1; extra == 'dev'
|
|
47
|
+
Requires-Dist: twine>=5.1.1; extra == 'dev'
|
|
48
|
+
Provides-Extra: dev-extended
|
|
49
|
+
Requires-Dist: playwright>=1.43.0; extra == 'dev-extended'
|
|
50
|
+
Requires-Dist: pytest-qt>=4.4.0; extra == 'dev-extended'
|
|
51
|
+
Provides-Extra: fastapi
|
|
52
|
+
Requires-Dist: fastapi>=0.110.0; extra == 'fastapi'
|
|
53
|
+
Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'fastapi'
|
|
54
|
+
Provides-Extra: gui
|
|
55
|
+
Requires-Dist: pyside6>=6.7.0; extra == 'gui'
|
|
56
|
+
Provides-Extra: mobile
|
|
57
|
+
Provides-Extra: physics
|
|
58
|
+
Requires-Dist: box2d-py>=2.3.10; extra == 'physics'
|
|
59
|
+
Provides-Extra: tui
|
|
60
|
+
Requires-Dist: rich>=13.7.1; extra == 'tui'
|
|
61
|
+
Requires-Dist: textual>=0.58.0; extra == 'tui'
|
|
62
|
+
Provides-Extra: web
|
|
63
|
+
Requires-Dist: aiohttp>=3.9.5; extra == 'web'
|
|
64
|
+
Requires-Dist: msgpack>=1.0.8; extra == 'web'
|
|
65
|
+
Description-Content-Type: text/markdown
|
|
66
|
+
|
|
67
|
+
# EchoUI — Universal Python-first UI framework
|
|
68
|
+
|
|
69
|
+
One **Screen–Stage–Sprite** paradigm compiles to Web, desktop, mobile, TUI, and GUI.
|
|
70
|
+
|
|
71
|
+
**Version:** 0.9.0 · **License:** MIT · **Docs:** [docs/api/INDEX.md](docs/api/INDEX.md)
|
|
72
|
+
|
|
73
|
+
## Quick Start
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install -e ".[web,dev]"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Create `main.py`:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from echoui import App, Screen, Store, col, text, button
|
|
83
|
+
|
|
84
|
+
class CounterStore(Store):
|
|
85
|
+
count: int = 0
|
|
86
|
+
|
|
87
|
+
store = CounterStore()
|
|
88
|
+
|
|
89
|
+
class Counter(Screen):
|
|
90
|
+
def build(self):
|
|
91
|
+
return col(
|
|
92
|
+
text(lambda: f"Count: {store.count}"),
|
|
93
|
+
button("+1", on_click=lambda: setattr(store, "count", store.count + 1)),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
app = App(screens=[Counter], initial="Counter")
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Build and run:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
echoui build --target web
|
|
103
|
+
echoui dev --target web --port 7999
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Open http://127.0.0.1:7999 — click **+1** and the count increments.
|
|
107
|
+
|
|
108
|
+
## CLI
|
|
109
|
+
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---------|-------------|
|
|
112
|
+
| `echoui new [name]` | Scaffold a counter project |
|
|
113
|
+
| `echoui dev --target web` | Dev server with hot reload |
|
|
114
|
+
| `echoui build --target web\|static\|tui\|desktop\|gui` | Compile for target |
|
|
115
|
+
| `echoui check` | Validate project |
|
|
116
|
+
| `echoui version` | Print version |
|
|
117
|
+
|
|
118
|
+
## Quality Gate
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
ruff check .
|
|
122
|
+
mypy echoui
|
|
123
|
+
pytest -q
|
|
124
|
+
python achecker.py
|
|
125
|
+
python -m build
|
|
126
|
+
twine check dist/*
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Testing
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
pytest -q
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT — see [LICENSE](LICENSE).
|
echoui-0.9.1/PROGRESS.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# EchoUI Progress
|
|
2
|
+
|
|
3
|
+
## 当前阶段
|
|
4
|
+
|
|
5
|
+
v0.9 生态与发布 — 收尾中(对照 `.claude/docs/09_验收与闭环协议.md`)
|
|
6
|
+
|
|
7
|
+
## 已闭环(可验证)
|
|
8
|
+
|
|
9
|
+
- [x] 核心引擎 v0.1–v0.4:reactive / compiler / web+SSR / 逃生层
|
|
10
|
+
- [x] 多端 target v0.5–v0.8:web / static / tui / desktop / gui / android(代码+测试)
|
|
11
|
+
- [x] v0.9 生态:collab / data / i18n / a11y / plugin / devtools
|
|
12
|
+
- [x] `ruff` / `mypy` / `pytest`(36 passed)/ `achecker` 0 违规
|
|
13
|
+
- [x] examples:`01_hello_web` `02_counter` `03_game_free_mode` `04_multi_screen_game` `05_escape_layer`
|
|
14
|
+
- [x] tests:`unit` / `integration` / `visual` / `a11y`
|
|
15
|
+
- [x] docs-src API 图鉴(v0.1 P0 条目 + 四件套)
|
|
16
|
+
- [x] `scripts/benchmark_reactive.py`(§3 细粒度更新)
|
|
17
|
+
- [x] `.github/workflows/ios-build.yml`(macOS CI 绕行,产出 web bundle artifact)
|
|
18
|
+
- [x] `python -m build` + `twine check` 本地通过
|
|
19
|
+
|
|
20
|
+
## 本阶段 TODO(09 协议机器检查项)
|
|
21
|
+
|
|
22
|
+
- [ ] `pip install --no-cache-dir echoui` 从 PyPI 安装成功
|
|
23
|
+
- [ ] `gh repo view` + `gh release list`(需创建远程仓库并打 tag)
|
|
24
|
+
- [ ] CLI 链:`echoui new demo && build web/tui` 端到端
|
|
25
|
+
- [ ] Desktop `.exe` / Android `.apk` 本机产出验证(A 类,需 PySide6 / Android SDK)
|
|
26
|
+
- [ ] iOS CI workflow 首次跑通并下载 artifact
|
|
27
|
+
|
|
28
|
+
## 已知降级/占位(诚实标注)
|
|
29
|
+
|
|
30
|
+
| 项 | 类别 | 说明 |
|
|
31
|
+
|----|------|------|
|
|
32
|
+
| iOS 本地构建 | B | Windows 无法跑 Xcode;已配 `ios-build.yml` macOS runner |
|
|
33
|
+
| 应用商店签名/上架 | C | 流程就绪,需用户提供开发者账号 |
|
|
34
|
+
| Web sqlite / os_api / gpu | interface-only | 见 `docs/api/targets.md` |
|
|
35
|
+
| v0.1 编译器 | 简化 | 运行时内省 IR,静态分析为后续目标 |
|
|
36
|
+
| WCAG 认证 | done-degraded | `a11y_audit` 规则检查,非完整 WCAG |
|
|
37
|
+
|
|
38
|
+
## 阻塞项
|
|
39
|
+
|
|
40
|
+
- GitHub 远程仓库 `nichengfuben/echoui` 尚未创建(本地仅有 `main` 分支)
|
|
41
|
+
- PyPI 尚无 `echoui` 包(待 `twine upload`)
|
|
42
|
+
|
|
43
|
+
## 环境记录
|
|
44
|
+
|
|
45
|
+
- Python 3.14.6(`py`)
|
|
46
|
+
- Git:`E:\Program Files\Git\cmd\git.exe`
|
|
47
|
+
- `PYPI_TOKEN` / `GH_TOKEN`:已配置
|
echoui-0.9.1/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# EchoUI — Universal Python-first UI framework
|
|
2
|
+
|
|
3
|
+
One **Screen–Stage–Sprite** paradigm compiles to Web, desktop, mobile, TUI, and GUI.
|
|
4
|
+
|
|
5
|
+
**Version:** 0.9.0 · **License:** MIT · **Docs:** [docs/api/INDEX.md](docs/api/INDEX.md)
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install -e ".[web,dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Create `main.py`:
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from echoui import App, Screen, Store, col, text, button
|
|
17
|
+
|
|
18
|
+
class CounterStore(Store):
|
|
19
|
+
count: int = 0
|
|
20
|
+
|
|
21
|
+
store = CounterStore()
|
|
22
|
+
|
|
23
|
+
class Counter(Screen):
|
|
24
|
+
def build(self):
|
|
25
|
+
return col(
|
|
26
|
+
text(lambda: f"Count: {store.count}"),
|
|
27
|
+
button("+1", on_click=lambda: setattr(store, "count", store.count + 1)),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
app = App(screens=[Counter], initial="Counter")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Build and run:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
echoui build --target web
|
|
37
|
+
echoui dev --target web --port 7999
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Open http://127.0.0.1:7999 — click **+1** and the count increments.
|
|
41
|
+
|
|
42
|
+
## CLI
|
|
43
|
+
|
|
44
|
+
| Command | Description |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| `echoui new [name]` | Scaffold a counter project |
|
|
47
|
+
| `echoui dev --target web` | Dev server with hot reload |
|
|
48
|
+
| `echoui build --target web\|static\|tui\|desktop\|gui` | Compile for target |
|
|
49
|
+
| `echoui check` | Validate project |
|
|
50
|
+
| `echoui version` | Print version |
|
|
51
|
+
|
|
52
|
+
## Quality Gate
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
ruff check .
|
|
56
|
+
mypy echoui
|
|
57
|
+
pytest -q
|
|
58
|
+
python achecker.py
|
|
59
|
+
python -m build
|
|
60
|
+
twine check dist/*
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Testing
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pytest -q
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
MIT — see [LICENSE](LICENSE).
|