Skip to content

Add web UI with pair and serve, Docker image, CI fix, unsigned MSIX docs - #38

Merged
linghengqian merged 8 commits into
mainfrom
clever-raccoon
Oct 25, 2026
Merged

linghengqian merged 8 commits into
mainfrom
clever-raccoon

Conversation

@linghengqian

Copy link
Copy Markdown
Member

Fix the flaky CI test

Sandboxes / mygo failed in TestModelHandsVfoxACopyOfALocalLuaPluginAndDeletesItAfterwards with a 5 s timeout waiting for the plugin copy to be deleted.

Root cause: AddPluginFromSource enqueued the task first and registered the temp .lua copy afterwards. A task that finishes immediately (the fake runner completes in microseconds) could finish before the registration, so onTaskFinished never found the copy and the test timed out. More likely to hit under -race in a loaded sandbox container.

Fix: TaskQueue.EnqueueWithFinalizer binds the cleanup to the task atomically at creation, runs it exactly once at announce time (normal finish, failure, queued cancel) and for queued tasks on Dispose. AppModel drops the racy map. Three deterministic regression tests cover finish, dedup and dispose.

Unsigned MSIX docs

Docs no longer ask users to self-sign. Windows 11 installs the unsigned .msixbundle with Add-AppxPackage -AllowUnsigned; the docs state the bundle is currently unsigned and an officially signed bundle will ship later. Sign-Msix.ps1 stays as a maintainer helper.

vfox-plus pair, vfox-plus serve, Docker image

New mygo/pair package (stdlib only):

  • pair: loopback-only pairing server printing a one-time link in the style of opencode pair (5 min TTL, session cookie, bilingual page).
  • serve: persistent server for containers and remote instances, expiring sessions (default 24 h), mintable links via GET /api/token (uses the request Host, so it works behind port mappings), non-loopback warning.
  • mygo/Dockerfile: multi-stage build, minimal Ubuntu runtime (ca-certificates + vfox + vfox-plus, non-root user, data volumes), default serve --bind 0.0.0.0 --port 8080. Verified in a container: pair, /app, inventory, link reuse rejection, minted links.

Full web interface

A paired browser gets /app (single embedded page, zero external requests): installed SDKs with install/use/uninstall, plugin registry with add/update/remove (URL or file upload), tasks with live progress and logs over SSE, settings and vfox config keys. State-changing routes need a session plus same-origin; use offers the global scope only. Verified against real vfox locally and in Docker; go test -race, vet, gofmt and docs-check pass.

- Fix the flaky plugin-copy test: bind the temp copy cleanup to the
  task atomically with TaskQueue.EnqueueWithFinalizer so an
  immediately-finishing task cannot outrun its registration.
- Docs no longer ask users to self-sign MSIX; install the unsigned
  bundle with Add-AppxPackage -AllowUnsigned until an officially
  signed bundle ships.
- Add vfox-plus pair (loopback, one-time links) and vfox-plus serve
  (persistent, expiring sessions, mintable links), plus a minimal
  published Docker image running serve.
- Add the full web interface at /app: SDKs, registry, tasks with
  live logs over SSE, settings and vfox config.
@linghengqian
linghengqian marked this pull request as draft October 25, 2026 15:35
@linghengqian linghengqian added bug Something isn't working enhancement New feature or request documentation Improvements or additions to documentation labels Oct 25, 2026
Comment thread mygo/pair/pair.go Fixed
skywalking-eyes requires it for HTML sources.
@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Memory use at 6fb5c71

  • No change from main beyond the noise of CI in mygo.
Implementation Technology Processes Home PSS Home RSS Versions PSS Versions RSS The list adds (PSS)
mygo mygo 0.6.3, Go 1.27.3, GTK 3 (purego), CPU renderer 1 45 (+3) 59 54 (+4) 69 +9

In MB, for the application and all of its child processes, sorted by the PSS of the Home page; "Versions" is the SDKs page with the available versions of Node.js listed. A number in parentheses is the difference from main, in bold when it is more than the noise of CI. "(main)" marks an implementation that this pull request did not rebuild: its numbers are those of main.

Details
  • Measured by vfxtool measure in the workflow of the implementation, on a GitHub-hosted runner with Xvfb and no GPU. These are not the numbers of docs/memory.md, which come from another machine: compare the rows of one comment.
  • The same code does not use the same memory in every CI run, so a difference counts as a change only when it is more than 5 MB and more than 5% of the number on main.
  • Runs of this pull request: mygo.
  • Latest runs on main: mygo (a21080b).

CodeQL go/cookie-secure-not-set flags it, but Secure would stop
browsers from sending the cookie back over plain HTTP outside
localhost and break pairing. Loopback traffic never leaves the
machine; beyond it, serve warns to prefer an encrypted tunnel.
errcheck: check Close errors. errorlint: errors.Is for flag.ErrHelp. gosec G114: ReadHeaderTimeout on the server. gosec G120/G124: bound the upload, document why Secure stays off. revive/unparam: comment and signature cleanups.
Comment thread mygo/pair/pair.go Fixed
Non-loopback serve now always speaks HTTPS: it uses --tls-cert/--tls-key when given and generates a self-signed certificate next to the settings otherwise, printing the SHA-256 fingerprint for comparison in the browser. The session cookie sets Secure exactly when TLS is on; loopback pair stays plain HTTP. This answers go/cookie-secure-not-set: suppressing the alert was wrong, the transport is now really encrypted.
Loopback origins (localhost, 127.0.0.1) are trustworthy, so browsers send Secure cookies back over plain HTTP there; every non-loopback bind already serves HTTPS. This satisfies go/cookie-secure-not-set and gosec G124 with the literal instead of suppressions.
CodeQL go/path-injection flagged os.ReadFile receiving an HTTP-supplied path via AddPluginFromSource. Local filesystem paths are now rejected in the web API (the desktop keeps accepting them); uploads sanitize dot names.
CodeQL go/path-injection kept flagging PreparePluginSource even with a URL guard it cannot see through. The web API now builds vfox add directly for URLs and server-side uploads instead of going through AddPluginFromSource, so no request-controlled string reaches the filesystem reads. This also fixes early deletion of uploads: cleanup runs in the task finalizer, not on handler return.
@linghengqian
linghengqian marked this pull request as ready for review October 25, 2026 16:48
@linghengqian
linghengqian merged commit b8e6c2a into main Oct 25, 2026
8 checks passed
@linghengqian
linghengqian deleted the clever-raccoon branch October 25, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants