-
Notifications
You must be signed in to change notification settings - Fork 26
feat(desktop): vouch review-ui AppImage for Ubuntu (stacked on #195) #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/194-review-ui
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| name: desktop | ||
|
|
||
| # Build the vouch review-ui AppImage for Ubuntu/x86_64. | ||
| # | ||
| # Triggers: | ||
| # * push to main / a release branch — builds the AppImage so we know the | ||
| # desktop recipe stays buildable (artifact retained 7 days). | ||
| # * version tag (v*) — builds the AppImage and uploads it as a release | ||
| # asset alongside the wheel/sdist that `release.yml` already publishes. | ||
| # * manual dispatch — same as push. | ||
| # | ||
| # Note: `desktop/requirements.txt` currently uses `local+vouch` so the | ||
| # AppImage bundles the working-tree source. Once vouch-kb is published on | ||
| # PyPI with the [web] extra, swap to `vouch-kb[web]==<version>` to pin the | ||
| # desktop artifact to a published release. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, release/*] | ||
| tags: ["v*"] | ||
| paths: | ||
| - "desktop/**" | ||
| - "src/vouch/**" | ||
| - ".github/workflows/desktop.yml" | ||
| pull_request: | ||
| paths: | ||
| - "desktop/**" | ||
| - "src/vouch/**" | ||
| - ".github/workflows/desktop.yml" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: write # only used by the release-upload step on tag events | ||
|
|
||
| jobs: | ||
| build-appimage: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
|
|
||
| # python-appimage shells out to appimagetool, which needs FUSE on | ||
| # most distros — but ubuntu-latest images ship libfuse2 these days, | ||
| # so we just install python-appimage itself. | ||
| - name: install python-appimage | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| python -m pip install python-appimage | ||
|
|
||
| # `local+vouch` in desktop/requirements.txt looks for an importable | ||
| # `vouch` module on the host Python — install the package editable so | ||
| # the bundler can find it. | ||
| - name: install vouch from working tree (for local+vouch) | ||
| run: python -m pip install -e . | ||
|
|
||
| - name: build AppImage | ||
| run: | | ||
| python -m python_appimage build app desktop/ \ | ||
| --python-version 3.12 \ | ||
| --linux-tag manylinux2014_x86_64 | ||
| # python-appimage names the output after the appdir basename: | ||
| mv desktop-x86_64.AppImage vouch-review-ui-x86_64.AppImage || true | ||
| ls -la *.AppImage | ||
|
|
||
| - name: smoke test (boots and serves /healthz) | ||
| run: | | ||
| ./vouch-review-ui-x86_64.AppImage --no-open-browser --bind 127.0.0.1:8851 & | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On Useful? React with 👍 / 👎. |
||
| APP_PID=$! | ||
| for i in 1 2 3 4 5 6 7 8 9 10; do | ||
| sleep 1 | ||
| if curl -sf http://127.0.0.1:8851/healthz; then | ||
| echo | ||
| echo "smoke test ok" | ||
| kill $APP_PID || true | ||
| exit 0 | ||
| fi | ||
| done | ||
| echo "smoke test failed: AppImage did not respond on /healthz" | ||
| kill $APP_PID || true | ||
| exit 1 | ||
|
|
||
| - uses: actions/upload-artifact@v7 | ||
| with: | ||
| name: vouch-review-ui-x86_64.AppImage | ||
| path: vouch-review-ui-x86_64.AppImage | ||
| retention-days: 7 | ||
|
|
||
| - name: attach to release | ||
| if: startsWith(github.ref, 'refs/tags/v') | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| files: vouch-review-ui-x86_64.AppImage | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # vouch — desktop AppImage | ||
|
|
||
| Self-contained Ubuntu (x86_64) launcher for `vouch review-ui`. One file. No | ||
| `apt install`. Double-click to start the browser-based review console. | ||
|
|
||
| ## What this directory is | ||
|
|
||
| ``` | ||
| desktop/ | ||
| requirements.txt # vouch-kb[web] (default) or local+vouch for pre-release | ||
| vouch-review-ui.desktop # Linux menu entry — Terminal=false, Categories=Development | ||
| vouch-review-ui.svg # scalable monograph icon | ||
| entrypoint.sh # auto-inits ~/.vouch/ on first run, hands off to `vouch review-ui` | ||
| ``` | ||
|
|
||
| The bundler is [`python-appimage`](https://github.com/niess/python-appimage), | ||
| which downloads a relocatable CPython, pip-installs the requirements into it, | ||
| wraps the `entrypoint.sh` in an AppRun, and emits a single `.AppImage`. | ||
|
|
||
| ## Build (release, from PyPI) | ||
|
|
||
| ```bash | ||
| pip install python-appimage | ||
| python -m python_appimage build app desktop/ \ | ||
| --python-version 3.12 \ | ||
| --linux-tag manylinux2014_x86_64 | ||
| # → desktop-x86_64.AppImage in cwd | ||
| mv desktop-x86_64.AppImage vouch-review-ui-x86_64.AppImage | ||
| chmod +x vouch-review-ui-x86_64.AppImage | ||
| ``` | ||
|
|
||
| Requires `vouch-kb[web]` to be published on PyPI — that lands once PR #195 | ||
| ships the `[web]` extra in the next vouch-kb release. | ||
|
|
||
| ## Build (pre-release, from local source tree) | ||
|
|
||
| Until the next vouch-kb release, swap the requirements entry to bundle the | ||
| working-tree source: | ||
|
|
||
| ```bash | ||
| # in desktop/requirements.txt, replace `vouch-kb[web]` with: | ||
| local+vouch | ||
| # (plus any deps the [web] extra would pull): | ||
| fastapi>=0.115,<1 | ||
| jinja2>=3,<4 | ||
| python-multipart>=0.0.9 | ||
| uvicorn>=0.30,<1 | ||
|
|
||
| # then build as above | ||
| python -m python_appimage build app desktop/ | ||
| ``` | ||
|
|
||
| ## Launch | ||
|
|
||
| ```bash | ||
| ./vouch-review-ui-x86_64.AppImage | ||
| # or double-click in the file manager | ||
| ``` | ||
|
|
||
| First launch creates `~/.vouch/` if it doesn't exist (an empty KB with the | ||
| starter claim), binds `127.0.0.1:7780`, and opens the browser to the review | ||
| queue. Override the KB location with `VOUCH_KB_PATH=/path/to/parent` in the | ||
| environment. | ||
|
|
||
| ## Stop | ||
|
|
||
| The AppImage runs a foreground uvicorn process. Close the launching | ||
| terminal, or `pkill -f vouch-review-ui`. A system-tray quit menu is a | ||
| natural follow-up but out of scope for the first release. | ||
|
|
||
| ## What's not in this release (yet) | ||
|
|
||
| - `.deb` package — the AppImage covers the Ubuntu story for now. | ||
| - Snap / Flatpak — needs separate confinement work; deferred. | ||
| - System-tray quit / auto-start on login — needs a native shell (Tauri/Electron); deferred. | ||
| - Auto-update — once the GH Actions release workflow lands, [AppImageUpdate](https://github.com/AppImage/AppImageUpdate) can sit on top. | ||
| - ARM64 / aarch64 builds — `--linux-tag manylinux2014_aarch64` once we have a runner. | ||
|
|
||
| ## How the install + run resembles `pipx install vouch-kb` | ||
|
|
||
| Same Python, same `vouch` command, same `.vouch/` layout — the AppImage is | ||
| just a bundled CPython + entry-point. Power users keep using `pipx`; the | ||
| AppImage is for users who want a single download and a menu entry. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #! /bin/bash | ||
| # vouch review-ui desktop launcher. | ||
| # | ||
| # When the AppImage is started from a .desktop entry there is no shell | ||
| # context, no project cwd, no `.vouch/` to discover — so on first launch we | ||
| # init a KB in $HOME (or VOUCH_KB_PATH if set) and then hand off to the | ||
| # normal `vouch review-ui` command, which opens the browser to the queue. | ||
|
|
||
| set -e | ||
|
|
||
| KB_ROOT="${VOUCH_KB_PATH:-$HOME}" | ||
| PYTHON="{{ python-executable }}" | ||
|
|
||
| if [ ! -d "$KB_ROOT/.vouch" ]; then | ||
| mkdir -p "$KB_ROOT" | ||
| "$PYTHON" -I -m vouch init --path "$KB_ROOT" >/dev/null | ||
| fi | ||
|
|
||
| exec "$PYTHON" -I -m vouch review-ui --kb "$KB_ROOT" "$@" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # python-appimage installs these into the bundled CPython at build time. | ||
| # | ||
| # This file currently uses the PRE-RELEASE pattern: `local+vouch` bundles | ||
| # the working-tree source so the AppImage builds even before vouch-kb cuts | ||
| # a release that ships the [web] extra (PR #195). The explicit [web] | ||
| # dependencies below match what `pip install vouch-kb[web]` would pull. | ||
| # | ||
| # Once vouch-kb is published on PyPI with the [web] extra, swap to: | ||
| # vouch-kb[web] | ||
| # and delete the explicit lines below. | ||
| # | ||
| # Note: avoid `<` in version specifiers — python-appimage runs pip via | ||
| # shell=True with unquoted args, so `<1` would be parsed as a redirect. | ||
|
|
||
| local+vouch | ||
|
|
||
| # [web] extra (explicit until vouch-kb's published version ships it) | ||
| fastapi>=0.115 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For python-appimage recipes, each requirement is passed through Useful? React with 👍 / 👎. |
||
| jinja2>=3 | ||
| python-multipart>=0.0.9 | ||
| uvicorn>=0.30 | ||
|
|
||
| # vouch core runtime deps (normally pulled by `vouch-kb`, but `local+vouch` | ||
| # bypasses the wheel metadata) | ||
| pydantic>=2.13.4 | ||
| click>=8.4.0 | ||
| pyyaml>=6 | ||
| mcp>=1.0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| [Desktop Entry] | ||
| Type=Application | ||
| Name=vouch | ||
| GenericName=Knowledge Base Review Console | ||
| Comment=Review agent-proposed claims and pages in the browser | ||
| Exec=AppRun | ||
| Icon=vouch-review-ui | ||
| Categories=Development;Office;Utility; | ||
| Keywords=knowledge-base;mcp;llm;agent;review;vouch; | ||
| Terminal=false | ||
| StartupNotify=false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| """Enable ``python -m vouch``. | ||
| The console-script entry-point (`vouch = vouch.cli:cli`) is the canonical | ||
| surface, but the desktop AppImage launcher (and any environment that | ||
| shadows entry points) needs `python -m vouch` to work too. One-liner shim. | ||
| """ | ||
|
|
||
| from .cli import cli | ||
|
|
||
| if __name__ == "__main__": | ||
| cli() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked python-appimage's build code and appimagetool behavior: when no explicit destination is supplied, the output name is derived from the bundled desktop entry's
Name=field (this recipe setsName=vouch), so this build producesvouch-x86_64.AppImage, notdesktop-x86_64.AppImage. Because thismvis allowed to fail, the following smoke test and release upload still look forvouch-review-ui-x86_64.AppImage, causing the desktop workflow/tag release to fail before publishing the artifact.Useful? React with 👍 / 👎.