Record: Status, Discovered, and Actions, and a mode that is not a failure
Outcome
The activator’s single text area is now a tabbed panel of three read-only logs, so the current state, the evidence behind it, and a record of every command that changed the system are visible at once. The conflict mode no longer calls itself blocked.
The Mode Is Not a Failure
another launcher already represents this application replaces blocked: another launcher already represents this application. The owner was right: nothing is wrong when two launchers want one identifier; the tool is simply waiting for a decision. The word was the tool’s, so it was changed in plan() where the mode is set, and every consumer followed: plan, install, explain --json’s mode, the activator’s Integrate will row, and the Status tab. tests/90-integration-conflicts.sh asserts the exact string.
Three Logs
The panel is a GtkNotebook of three pages, each a large read-only monospace text view.
| Tab | Holds | Filled by |
|---|---|---|
| Status | the current state: the mode in the tool’s own words, the launcher, the file, the already-installed notice, and, while a choice is open, the launcher list with the policy wording, and any failure note | compose_status(), refreshed whenever the state changes |
| Discovered | the evidence: the command that produced it, then detection, size, payload offset and size, compression, version and its source, signature, identifier, embedded entry, desktop id, installed path, icon, exec, window class, this run’s mode, the embedded entry text, and every existing launcher with its origin and whether its target exists | compose_discovered(), plus the full explain report appended by Inspect |
| Actions | a timestamped line per command that changes the system, with the command’s output underneath: installs, and Run once or Run now | log_action() from run_install and run_the_appimage |
The “This application is already installed.” block was removed from above the buttons; it is the first paragraph of the Status tab, which is the page the window opens on. Inspect and Integrate still switch the panel to the page that answers them: Discovered for Inspect, Actions for a command that writes something.
One Call, Not Two
The Discovered tab needs the payload offset and the signature, which explain --json did not carry, while the human explain did. Rather than running both commands, the plan now carries payload_offset and signature and explain --json emits them, so the window composes the whole log from the call it was already making.
Verifying It
A run driven by --activate now prints the three logs after performing its actions, because the logs are the only place the window’s knowledge lives and a test cannot read a screen. The test asserts that Status carries the already-installed notice, that Discovered lists the identifier and the existing launchers, and that Actions logs the install command including the typed name.
Against the real OrcaSlicer AppImage, whose file the owner moved, the window now says in Status:
State: repair the launcher (the AppImage is not where it was)
Launcher: com.orcaslicer.OrcaSlicer.desktop
...
origin: this tool (this AppImage, and its launcher is broken)
state: the same AppImage, not where this launcher expects it
appimage: ~/Applications/OrcaSlicer_...AppImage [MISSING]
Replace existing repairs that launcher: the AppImage is not where the launcher expects it, so
its Exec and TryExec are rewritten.
and in Discovered:
Detection type-2
Size 131.4 MiB (137759224 bytes)
Payload offset 944632 bytes, size 136814592 bytes
Compression zstd
Version 2.4 (from filename)
Signature (absent)
Identifier 57434599bed20bde
which is the deduction the owner asked to see.
Follow-Up: the Tool’s Report Is Status Too
The first version of the tabs left one block above the buttons: the tool’s own report, which explain --json carries in its error field — “N existing launcher(s) already represent this application:
Status therefore reads, for the real FreeCAD 1.1.3 AppImage:
State: another launcher already represents this application
Launcher: org.freecad.FreeCAD.desktop
File: ~/Downloads/Applications/FreeCAD_1.1.3-Linux-x86_64-py311.AppImage
This application is already installed.
Integrate will show details, then offer to replace or add alongside.
2 existing launcher(s) already represent this application:
~/.local/share/applications/org.freecad.FreeCAD-2.desktop (this tool)
~/.local/share/applications/org.freecad.FreeCAD.desktop (this tool (a different AppImage for the same identifier))
choose --replace to back them up and install this version in their place, or --add to install alongside them
tests/95-activator-ui.sh’s stub now reports an error alongside its conflicts, and the test asserts that both the report line and the two choices appear in the driven run’s Status output.
Verification
Verified 2026-09-23 with make test; all sixteen test scripts passed. The installed activator was run against the real AppImage on a virtual display with --activate integrate and --activate inspect, and the three logs above are its own output.
Commits
dc331a1Give the activator Status, Discovered, and Actions tabs5bc7a39Move the tool’s report into the Status tab