Repository navigation
feat(runtime): inspect and try a desktop app before it's added - #59
Merged
Merged
Conversation
- inspectDesktopApp: static checks of a picked .app (where it is, Info.plist via plutil, Electron's framework, its executable, App Sandbox, codesign); its signer kept: a developer's team, or a digest pinning an unsigned build - trialDesktopApp: a confined launch without the network beyond this machine; read as ok, a wrapper's site (named even unreached), a quit - apps allowing one copy (Slack, VS Code, Discord) launch confined: their lock's socket goes to the sandbox's temp (MAC_CHROMIUM_TMPDIR) - launch errors say why structurally; the tests' launch hooks leave the package's launch options - a macOS CI job runs the desktop-app suite
- a pinned build's digest covers the whole bundle (helpers, frameworks) - codesign that fails or times out refuses the app, never read as unsigned or unsandboxed; empty names fall back - a trial runs with the network (an updater can't touch the real app): a wrapper's offline page no longer hides its site - a main window that never loaded its own page is refused at launch, said as such (a dev server not running included); a hung attach is retried - one command helper; the macOS CI job installs ffmpeg
- a pinned build's digest covers the whole bundle and refuses a link that leads outside it; unreadable, too large or stopped: refused, said - an attach that never answers is tried again, then said as the launch's own error (runs and trials alike); a trial throws Kiframe's own faults - an error page whose address can't be read is said as an unloaded page - the docs say what a trial reaches (the network, as a run)
…igest Redesign after three review rounds on the same two seams (reviewed): - every failure ending a launch is an ElectronLaunchError with its why, by one rule (stop, not started, quit first, said, anything else in a fixed phrase, its detail on stderr only when asked); the trial maps only its why - the pinned digest: the path resolved, each entry a JSON line under a version, links resolved inside the bundle step by step (a chain leaving it refused, one leading nowhere kept), sizes checked, sockets and devices refused, a stop honoured per chunk - the unused loopback network mode and a duplicate branch removed
…ked build - what a launch already said (a site, a page never loaded) stays said if the app then quits; the attach hands its timeout to the one rule - a pinned build is held by its digest (signatureHolds compares it); a trial runs only the build that was picked - an inspection stops when asked (codesign and plutil killed) - bundle ids with underscores accepted (schema and inspection) - one quoting helper; the digest's link steps no longer block
…s such - only what the app showed (a site, a page never loaded) beats a quit - a build that can't be checked (codesign timed out, unreadable) is said as unread, never as changed; buildHolds says which - the stop honoured in the middle of one large file - one bundle id rule, shared with the schema; one quoting helper, named for the two languages it serves
What the main window embeds as it opens is read by a loading frame's src too: its first navigation uncommitted when the launch seals what's the app's own, it was stopped once it loaded (the macOS runner's flake). The single-instance test runs where its fix applies (macOS).
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
A dev build that opens DevTools after Kiframe attached showed them in a window that appears blank first (never filtered as DevTools), and the guard stopped it, failing the step (the macOS runner's failure, then reproduced every time with DevTools opened late). The guard leaves devtools: pages alone, as the window list and emulation already did.
… runner On the macOS runner a click under DevTools opened mid-run waits for stability until its timeout (a covered window's animation frames throttled); the test's property is DevTools never counted as leaving the app. Clicking with DevTools open is checked on a real app (BACKLOG, PR 5).
…failed back - a frame still loading toward what isn't the app's when the launch seals is stopped then (never landing as a stop in a run's first step) - a main window whose back failed is blanked (never left showing the site; the run says to relaunch, as with no history), the failure's detail logged - CI logs desktop-app failures' detail (KIFRAME_ELECTRON_DEBUG)
winlp4ever
added a commit
that referenced
this pull request
Oct 10, 2026
…61) * feat(desktop): launch a project's desktop app only from its approval The launch main gives the agent (PR 4a, design reviewed): the app's copy approved for this project and what it opens, inspected once by its status. An update by the same developer is tried confined first, quietly (one trial per app and project), and that build approved compare-and-set (the same copy, developer and opens, the project still open). Anything else is refused for the user to settle in the Apps panel, never for the agent to retry. - a take of a desktop app keeps its build and what it opened (appBuild: shown, never in its key, never a reason to record again) - Kif starting ends an "Add desktop app…" check in progress - BACKLOG: #60's CI flakes; what an approval doesn't cover (files/) * fix(desktop): launch only the build that was tried, and only while approved - a launch re-reads the approval and the project after looking at the app: one removed or switched meanwhile is never launched - one quiet trial per build: an update landing during a trial is never launched untried; a stopped launch stops only its own wait - a quiet trial that didn't work says why (a site, a quit, a failure); an approval that can't be written is refused for the user - Kif starting ends checks in progress only (picked cards kept); a launch's stop reaches its look at the app; the take's build shape from its schema; status tests assert the app they return * fix(desktop): one quiet trial per app, ended with the launcher, status asked again - one quiet trial per app and project (launches meanwhile wait); after it a launch asks the app's status again and must find the build just approved (an update, a move, a replacement meanwhile: refused) - the quiet trial ends with the launcher (stopAll: a project switch, a quit), never with one launch's stop; a launch already stopped starts none - the trial approves against the launch's own project; a launch checks the approved build is the one it starts - an add's check ended by Kif starting or a switch is said in words * refactor(desktop): each launch tries its own update, stopped with it Simplified after a third review round on the shared quiet trial: each launch of an updated app tries it itself (stopped by its own stop, or by the launcher's as it was when the launch began: a project switch, a quit refused in words), then approves compare-and-set (two launches that both tried it approve the same build). No trial shared, kept, or joined. - an add's check ended (Kif started, given up) always said in words - a folder in files/ gone mid-copy said as a change; the slow-copy tests budget the app's start on the slower of two * test(runtime): accept an interrupt handled before the first step that met it On a busy CI runner the page loads slower than the late dialog's 300 ms, so the dialog is up as the steps begin and is handled before "wait" instead of "go" (seen twice). Handled once, off camera, before the click it would block, either way: the click works. * test(runtime): close the interrupt test again The previous commit's edit dropped the test's closing brace (lint and format failed in CI). * test: run the desktop-app suite's files one after another Since #59 the electron project holds two files and they ran in parallel: Electron launched while the other file cloned and re-signed it (spawn ETXTBSY on Linux for the first tests, a splash slower than its wait on macOS, both in #61's CI). The suite was meant to run alone: its files now do too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR 3b-1 of the Electron targets epic (#55): the runtime half of "Add desktop app…". The desktop half (approval store, Apps panel) is 3b-2. The design was reviewed (and revised by its review and two spikes); the launch failure rule and the pinned digest were redesigned after three review rounds and reviewed again.
A fix to #58: apps that allow one copy
Slack, VS Code and Discord take Chromium's single-instance lock. Its socket goes to macOS's per-user temp (
/var/folders), which the confinement denies, so they quit at once, even alone.MAC_CHROMIUM_TMPDIR=<sandbox>/tmpputs it in the sandbox (measured: no confinement rule widened).Inspection (
electron-inspect.ts, static: only plutil and codesign run)Refused, said:
Kept: the bundle id, name, Electron version, and the signer. That's a developer (team id, checked with
codesign --verify --strict -R), or for an ad hoc or unsigned build a digest of the whole bundle:Tried read-only on the installed apps: minmux (pinned), Slack, VS Code, Figma and Notion all inspect in 0.1–0.6 s.
Trial (
electron-trial.ts)A confined launch with the network as in a run: an updater can't touch the real app, and a wrapper's offline page can't hide its site. Outcomes, read structurally:
ok;site: a wrapper's, named even when unreached, from the error page's unreachable URL over CDP;quit;failed, said as is.It runs only the build that was picked; a build that can't be checked is said as unread.
The launch's one failure rule
Every failure that ends a launch is an
ElectronLaunchErrorwith itswhy, except a stop. The order:KIFRAME_ELECTRON_DEBUG.A main window that never loaded its page is refused as such. An attach that hangs as the first page fails (measured 1 in 5, cause not found) is tried again within the launch's time.
Also
appArgs,readable,allowUnconfined) left the package's launch options.Tests
Each fix's test fails with its bug put back.