From c5f538c33146ee4ae56a3205ba4fa2b34191413c Mon Sep 17 00:00:00 2001 From: gefrus112 <329268472+gefrus112@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:16:21 +0000 Subject: [PATCH 1/2] Add safe app runtime and Windows EXE builder Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com> --- .github/workflows/windows-exe-smoke.yml | 49 ++ .gitignore | 4 +- .vscode/tasks.json | 16 + README.md | 50 +- docs.html | 79 ++- docs/LANGUAGE.md | 48 +- download.html | 47 +- editors/vscode/README.md | 7 +- editors/vscode/snippets/pyv2.json | 23 + examples/software/comet_notes.pyv2 | 27 + guide.html | 25 +- index.html | 6 +- install.bat | 1 + install.sh | 1 + playground.html | 1 + playground.js | 30 +- pyproject.toml | 6 +- pyv2.js | 82 +++ pyv2/__init__.py | 3 +- pyv2/assets/pyv2.js | 82 +++ pyv2/builder.py | 684 ++++++++++++++++++++++++ pyv2/cli.py | 263 +++++++-- pyv2/interpreter.py | 205 ++++++- pyv2/launcher.py | 61 ++- pyv2/runtime.py | 171 ++++++ style.css | 11 + tests/test_apps.py | 226 ++++++++ tests/test_games_site.py | 14 + tests/test_launcher.py | 9 + tests/test_parity.py | 2 + tutorial.html | 3 + 31 files changed, 2129 insertions(+), 107 deletions(-) create mode 100644 .github/workflows/windows-exe-smoke.yml create mode 100644 examples/software/comet_notes.pyv2 create mode 100644 pyv2/builder.py create mode 100644 pyv2/runtime.py create mode 100644 tests/test_apps.py diff --git a/.github/workflows/windows-exe-smoke.yml b/.github/workflows/windows-exe-smoke.yml new file mode 100644 index 0000000..b6ac8f1 --- /dev/null +++ b/.github/workflows/windows-exe-smoke.yml @@ -0,0 +1,49 @@ +name: Windows EXE builder + +on: + workflow_dispatch: + pull_request: + paths: + - "pyv2/**" + - "examples/software/**" + - "pyproject.toml" + - ".github/workflows/windows-exe-smoke.yml" + push: + branches: [main] + paths: + - "pyv2/**" + - "examples/software/**" + - "pyproject.toml" + - ".github/workflows/windows-exe-smoke.yml" + +permissions: + contents: read + +jobs: + build-and-run: + runs-on: windows-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + - name: Install Python v2 and native builder + run: python -m pip install . pyinstaller + - name: Validate the production app example + run: pyv2 check examples/software/comet_notes.pyv2 + - name: Build a real one-file Windows executable + run: pyv2 build examples/software/comet_notes.pyv2 --native --output build/windows-smoke + - name: Run the packaged executable + shell: pwsh + run: | + $output = & ".\build\windows-smoke\dist\Comet-Notes.exe" + $output | Write-Host + if ($LASTEXITCODE -ne 0) { throw "Packaged app exited with $LASTEXITCODE" } + if (($output -join "`n") -notmatch "Use --add") { throw "Packaged app smoke output was incomplete" } + - uses: actions/upload-artifact@v4 + with: + name: comet-notes-windows-exe + path: build/windows-smoke/dist/Comet-Notes.exe + if-no-files-found: error diff --git a/.gitignore b/.gitignore index 7446761..216ad3b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ __pycache__/ *.pyc .DS_Store -# Python packaging outputs +# Python packaging and local app outputs build/ dist/ *.egg-info/ +.pyv2-data/ +.builder/ diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 8d8aaaa..db071d7 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -48,6 +48,22 @@ "presentation": { "reveal": "always", "panel": "new" }, "problemMatcher": [] }, + { + "label": "Check current Python v2 app", + "type": "shell", + "command": "python3", + "args": ["-m", "pyv2", "check", "${file}"], + "options": { "cwd": "${workspaceFolder}" }, + "problemMatcher": [] + }, + { + "label": "Build current app: Windows kit", + "type": "shell", + "command": "python3", + "args": ["-m", "pyv2", "build", "${file}", "--output", "${workspaceFolder}/build/windows"], + "options": { "cwd": "${workspaceFolder}" }, + "problemMatcher": [] + }, { "label": "Run Python v2 tests", "type": "shell", diff --git a/README.md b/README.md index 84792f8..3f47ac0 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ The product is: 384 | `assert` is a keyword with moods | `assert(cond, msg)` is a function | | trailing commas *sometimes* | trailing commas & multi-line everything | | one runtime | two parity-tested runtimes — CLI **and** browser | +| ad-hoc file access | capability-based app data, atomic saves, and read-only assets | +| packaging guesswork | validated projects, reproducible kits, and real Windows `.exe` builds | ## 🚀 Quick start @@ -79,13 +81,50 @@ $ python3 -m pyhope --demo # engine demo $ python3 -m pyv2 examples/games/monster_arena.pyv2 ``` +## 🏗️ Build production Windows applications + +Python v2 now includes the **Sudbury Build Tools**: app metadata, strict JSON, +command-line arguments, sandboxed UTF-8 files, atomic saves, read-only bundled +assets, native dialogs, validation, integrity manifests, and an inspectable +Windows packaging pipeline. + +```console +# Create a complete application project +$ pyv2 new windows-app "Comet Tasks" + +# Develop and validate it +$ pyv2 Comet-Tasks/main.pyv2 --add "Ship the app" +$ pyv2 check Comet-Tasks + +# Create a reproducible Windows build kit from any operating system +$ pyv2 build Comet-Tasks + +# On Windows: build the real one-file Comet-Tasks.exe +> pyv2 build Comet-Tasks --native +``` + +Each project includes `pyv2app.json`, VS Code tasks, a readable batch builder, +a PowerShell builder, app assets, and a GitHub Actions Windows workflow. Every +build kit vendors the exact Python v2 runtime and hashes its inputs. The actual +`.exe` is produced by PyInstaller **on Windows**; macOS and Linux create +the same reviewable build kit or can use the included Windows CI workflow. +Python v2 never disguises a non-Windows binary as an `.exe`. Generated files +are not Authenticode-signed automatically; public distributors should add their +own protected signing certificate in Windows CI. + +Packaged apps store writable data under +`%LOCALAPPDATA%\\PythonV2Apps\\APP-ID`. Absolute paths, traversal, symlink +escapes, oversized text, and writes to bundled assets are blocked by default. +See [`examples/software/comet_notes.pyv2`](examples/software/comet_notes.pyv2). + ## 🖥️ Python v2 Sudbury Launcher Version 1.1 ships Python v2 as its own lightweight desktop application. The workspace provides Home, Code Studio, a path-safe atomic file service, project wizard, eight packaged CC0 assets, Games/GPU, detected editor connections, local settings, docs, a polished offline personal/portfolio/game website -starter, and a preview server—all using the Python standard library. Open it with `pyv2-launcher`, +starter, Windows app project generation, and a preview server—all using the +Python standard library. Open it with `pyv2-launcher`, `pyhope-studio`, or `pyhope --studio`. ## 🎮 PyHope game engine @@ -167,8 +206,8 @@ The short version: $ python3 -m unittest discover -s tests -t . ``` -**92 tests pass:** 63 language tests, 9 PyHope engine tests, 12 workspace/Launcher tests, -7 arcade/Playground site tests, plus a parity harness that runs 21 programs (including error paths) through both the +**108 tests pass:** 63 language tests, 9 PyHope engine tests, 14 production-app/build tests, +13 workspace/Launcher tests, 8 arcade/Playground site tests, plus a parity harness that runs 25 programs (including error paths) through both the Python and JavaScript runtimes and demands byte-identical output. ## 📦 Repo layout @@ -184,7 +223,7 @@ tutorial.html 10 runnable language lessons + browser sandbox guide.html 50 concise language/engine learning topics games.html 10-game arcade, GPU lab, animated sprites, Python v2 source arcade.js seven-game shared Canvas engine for Pocket Arcade -pyv2/ interpreter, CLI, desktop Launcher, packaged browser runtime +pyv2/ interpreter, safe app runtime, Windows builder, CLI, desktop Launcher pyhope/ engine, CLI, and packaged offline CC0 asset library pyv2.js twin language runtime in JavaScript game.js CPU sprite raycaster (monsters + weapon) @@ -196,7 +235,8 @@ install.bat Windows installer for pyv2 + PyHope install.sh macOS/Linux installer for pyv2 + PyHope editors/vscode/ VS Code syntax highlighting + snippets examples/games/ playable Python v2 game/source examples -tests/ language, parity, and PyHope engine tests +examples/software/ persistent JSON and safe app-data examples +tests/ language, app builder, parity, site, workspace, and engine tests docs/LANGUAGE.md full language reference & grammar ``` diff --git a/docs.html b/docs.html index 84147e9..b6e434f 100644 --- a/docs.html +++ b/docs.html @@ -319,7 +319,7 @@

App layout

HomeWorkspace overview and shortcuts to every main tool Code StudioOpen, edit, save, and run .pyv2; output/errors stay in the app FilesSafe local workspace service: create, read, atomically save, rename, and delete files without path traversal - New ProjectCreate Website, CLI app, or Game starters without overwriting files + New ProjectCreate Website, Windows app, CLI app, or Game starters without overwriting files AssetsBrowse and export eight packaged original CC0 PyHope SVGs offline Games & GPUOpen the 10-game arcade, animated sprites, and 9M GPU Lab Connected EditorsDetect VS Code, VSCodium, Zed, Sublime Text, and PyCharm from PATH; no account or token @@ -350,8 +350,71 @@

Build a website with Python v2

end print("GAME|Comet Circuit|Racing|Three-lap AI racing.|games.html#comet-circuit") + +

07 Production Apps & Windows EXE Builder

+

Sudbury Build Tools turn a .pyv2 program into a validated, + inspectable application project and—when the native build runs on + Windows—a real one-file .exe. Python v2 does not rename a + Linux or macOS binary and pretend it is a Windows executable.

+ +

Create, run, check, and build

+
# Complete console application with JSON persistence
+pyv2 new windows-app "Comet Tasks"
+
+# Or create a dialog-based app with no terminal window
+pyv2 new windows-app "Hello Window" --windowed
+
+pyv2 Comet-Tasks/main.pyv2 --add "Ship the EXE"
+pyv2 check Comet-Tasks
+pyv2 build Comet-Tasks
+
+# Run this final command on Windows with PyInstaller installed.
+# The generated build-windows.bat handles that installation for you.
+pyv2 build Comet-Tasks --native
+ + + + + + + + + + + + +
Generated filePurpose
main.pyv2Readable application source using arguments, strict JSON, and persistent app data
pyv2app.jsonName, stable app ID, version, publisher, console/windowed mode, icon, and assets
build-windows.batValidates and builds the real EXE on Windows without administrator access
.github/workflows/windows-exe.ymlOptional Windows CI build and downloadable executable artifact
build/windows/manifest.jsonSHA-256 source and build-input integrity record
runtime/pyv2Exact vendored language runtime used for the build—no moving runtime dependency
app.spec + launcher.pyReviewable PyInstaller recipe and embedded Python v2 host
+ +

Application APIs

+
info = app_info()                  # name, version, platform, safe data directory
+commands = args()                  # values after the .pyv2 filename / EXE
+settings = {theme: "night", zoom: 1.25}
+write_text("settings.json", json_encode(settings))
+loaded = json_decode(read_text("settings.json"))
+print(loaded.theme)
+
+# Other safe services:
+# append_text, file_exists, list_dir, make_dir, delete_file
+# read_asset, asset_exists, sleep_ms, ui_message, ui_ask
+

During development, writable data stays in .pyv2-data/ + beside the program. Packaged apps use + %LOCALAPPDATA%\PythonV2Apps\APP-ID. Paths are relative and + sandboxed; atomic writes, UTF-8 validation, an 8 MB text limit, asset + size validation, symlink-escape checks, and unmanaged-build-directory + protection are enabled by default.

+ +
Building from macOS or Linux: + pyv2 build still creates the complete Windows kit. Copy it + to Windows and run build.bat, or push the generated project + and run its GitHub Actions workflow on a Windows runner. PyInstaller + cannot cross-compile Windows PE files from another operating system.
+

Signing note: generated executables are reproducible but + not Authenticode-signed automatically. Public distributors should add + their own protected code-signing certificate in Windows CI; never commit + a certificate or password to the project.

+ -

07 PyHope Game Engine

+

08 PyHope Game Engine

PyHope is Python v2's own dependency-free game engine. It is not pygame and it installs no native libraries. The portable Python module handles game logic and terminal previews; the website adds Canvas and @@ -403,7 +466,7 @@

Your first PyHope scene

assets/sprites/.

-

07 Language Quick Reference

+

09 Language Quick Reference

The full spec (grammar, semantics, error kinds) lives in docs/LANGUAGE.md. Here is the day-to-day core.

@@ -464,12 +527,17 @@

Builtins

keys values has getMap access sort sort_by joinHelpers assert(cond, msg?)Raises AssertionError when falsy - chr ord clock inputMisc (input is CLI-only) + json_encode json_decodeStrict JSON for persistent application data + args app_infoApplication arguments, identity, platform, and capability details + read_text write_text append_textSandboxed UTF-8 files with atomic replacement + file_exists list_dir make_dir delete_fileSafe app-data management + read_asset asset_exists ui_message ui_askPackaged assets and native dialogs + chr ord clock input sleep_msCharacters, timing, and desktop input -

08 Try It Right Here

+

10 Try It Right Here

No install needed to experiment — this is the real interpreter, running in your browser. Edit and hit Run.

@@ -516,6 +584,7 @@

Documentation

Tutorial 50-topic guide Sudbury Launcher + Windows EXE builder PyHope engine Installation VS Code setup diff --git a/docs/LANGUAGE.md b/docs/LANGUAGE.md index de102c0..6f9fa8b 100644 --- a/docs/LANGUAGE.md +++ b/docs/LANGUAGE.md @@ -195,10 +195,28 @@ hero.scores.push(30) | `sort(list)` `sort_by(list, fn)` `join(list, sep)` | helpers | | `assert(cond, msg?)` | raise `AssertionError` when falsy | | `chr(n)` `ord(char)` | character codes | -| `clock()` | seconds on the wall clock | +| `clock()` | high-resolution elapsed seconds | | `input(prompt?)` | read a line (CLI only; browser raises a friendly error) | - -### 3.1 Methods +| `args()` | command-line arguments passed after the app filename | +| `app_info()` | app name, version, ID, platform, data directory, and asset capability | +| `json_encode(value)` / `json_decode(text)` | strict JSON serialization for maps and lists | +| `read_text(path)` / `write_text(path, text)` / `append_text(path, text)` | UTF-8 app-data files; writes are atomic by default | +| `file_exists(path)` / `list_dir(path?)` / `make_dir(path)` / `delete_file(path)` | sandboxed app-data management | +| `read_asset(path)` / `asset_exists(path)` | read-only files bundled with a packaged app | +| `sleep_ms(milliseconds)` | pause a desktop/CLI app for at most 60 seconds | +| `ui_message(title, text)` / `ui_ask(title, prompt, default?)` | native dialogs in packaged/desktop apps | + +### 3.1 App capability safety + +Desktop services are explicit capabilities. A CLI source file receives a +writable `.pyv2-data/` directory beside the source and optional read-only +`assets/`. A packaged Windows app stores data under +`%LOCALAPPDATA%\\PythonV2Apps\\APP-ID`. Absolute paths, `..` traversal, symlink +escapes, non-UTF-8 reads, and text larger than 8 MB are rejected with +`CapabilityError`. Browser programs keep JSON, `args()`, and `app_info()` but +cannot touch the visitor's filesystem. + +### 3.2 Methods **Strings:** `upper lower title trim chars reverse lines count slice(a, b?) to_number repeat(n) split(sep) join(list) contains starts_with ends_with @@ -217,7 +235,7 @@ Errors are `Kind: message at line N` with an optional call trace: `SyntaxError`, `NameError`, `TypeError`, `IndexError`, `KeyError`, `ZeroDivisionError`, `ValueError`, `OverflowError`, `AssertionError`, -`AttributeError`, `RuntimeError`. +`AttributeError`, `CapabilityError`, `RuntimeError`. The CLI exits with status 1 on error; the playground prints the error in red and keeps your code. @@ -269,16 +287,26 @@ fnexpr := "fn" "(" params ")" ":" block "end" ## 7. CLI ```console -$ python3 -m pyv2 script.pyv2 # run a file -$ python3 -m pyv2 -c 'print(42)' # run a snippet -$ python3 -m pyv2 # REPL (... continues blocks) -$ python3 -m pyv2 --version +$ pyv2 script.pyv2 --list # run an app with arguments +$ pyv2 -c 'print(42)' # run a snippet +$ pyv2 # REPL (... continues blocks) +$ pyv2 check MyApp # syntax + metadata + path audit +$ pyv2 new windows-app "My App" # complete EXE-ready project +$ pyv2 build MyApp # build kit on any operating system +$ pyv2 build MyApp --native # real one-file .exe on Windows +$ pyv2 doctor # show local build readiness ``` +A generated app contains readable source, `pyv2app.json`, VS Code tasks, +sandboxed-data examples, `build-windows.bat`, and a Windows GitHub Actions +workflow. PyInstaller must run on Windows to create a Windows PE executable; +macOS/Linux builds produce the honest reproducible kit rather than relabeling a +non-Windows binary. + ## 8. Parity guarantee -The suite runs **92 tests**: 63 language tests, 9 PyHope engine tests, 7 arcade/Playground site tests, -12 workspace/Launcher tests, and one parity harness that sends 21 programs (including error paths) through +The suite runs **108 tests**: 63 language tests, 9 PyHope engine tests, 14 production-app/build tests, +8 arcade/Playground site tests, 13 workspace/Launcher tests, and one parity harness that sends 25 programs (including error paths) through **both** language runtimes and compares outputs byte for byte. If the twins ever disagree, the suite fails. That's the deal. diff --git a/download.html b/download.html index cc224cd..caae905 100644 --- a/download.html +++ b/download.html @@ -61,7 +61,8 @@

Downloads & Installation

Get the Python v2 language on your machine. It is free, open source, and needs nothing but Python 3.10+. Version 1.1 “Sudbury” includes our own desktop Launcher, - offline website builder, and dependency-free PyHope game engine— + offline website builder, production app APIs, a Windows EXE + builder, and dependency-free PyHope game engine— no pygame or Electron required.

@@ -92,6 +93,7 @@

One installer. Your whole workspace.

  • Export eight original CC0 PyHope sprites offline
  • Detect and open VS Code, VSCodium, Zed, Sublime, or PyCharm
  • Create and preview complete Python v2 website projects
  • +
  • Create validated Windows apps with JSON, safe data, dialogs, and EXE workflows
  • Configure workspace, editor, font, and autosave settings
  • Open the 10-game arcade and 9M GPU tools
  • No pygame, Electron, cloud account, or paid dependency
  • @@ -143,8 +145,41 @@

    Manual / portable

    Play the games · Get free CC0 sprites

    + +

    03 Build Real Windows EXE Applications

    +

    Installed with the normal Python v2 installer. Sudbury + Build Tools create console or windowed applications with command-line + arguments, strict JSON, sandboxed persistent files, atomic saves, + bundled read-only assets, and native message/input dialogs.

    +
    +
    +

    1. Create

    +
    pyv2 new windows-app "My App"
    +# add --windowed for a dialog app
    +
    +
    +

    2. Validate

    +
    pyv2 check My-App
    +pyv2 doctor
    +
    +
    +

    3. Build

    +
    pyv2 build My-App
    +# Windows:
    +pyv2 build My-App --native
    +
    +
    +

    The project includes a readable build-windows.bat, + PowerShell script, PyInstaller recipe, SHA-256 manifest, VS Code tasks, + and Windows GitHub Actions workflow. Native .exe creation + installs PyInstaller into a build environment on Windows; normal Python + v2 apps and the language runtime remain dependency-free. Other systems + produce the complete kit rather than a mislabeled binary. + Full app and + EXE guide →

    + -

    03 Get the Language Manually

    +

    04 Get the Language Manually

    Pick your favorite flavor:

    @@ -176,12 +211,12 @@

    What's in the box

    Examplesexamples/hello, fib, fizzbuzz, terminal_raycast VS Code extensioneditors/vscode/Syntax highlighting + snippets Dev container.devcontainer/Ready environment for VS Code / Codespaces - Teststests/92 tests: language + parity + PyHope + workspace + portfolio Playground + arcade + Teststests/108 tests: language + app/EXE builder + parity + PyHope + workspace + Playground + arcade -

    04 Install on Your Machine

    +

    05 Install on Your Machine

    One requirement: Python 3.10 or newer (python.org/downloads). Python v2 itself has zero dependencies.

    @@ -229,7 +264,7 @@

    Make it your own

    -

    05 Install in Your Editor

    +

    06 Install in Your Editor

    Full step-by-step guides live in the documentation. The quick tour:

    @@ -263,7 +298,7 @@

    05 Install in Your Editor

    -

    06 Learn the Language

    +

    07 Learn the Language

    Installed? Nice. Next stop: