Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-4982GitHub issuePublicReceived

4.0.3: third-party plugins get appLibrary=null and a manifest stripped of __sourceDir, both silently

Reported by trustimagetiago · filed Sep 9, 2026Closed upstream on 2026-09-20 by bjarneo via an automated message, as a duplicate of #10661 (R-860). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
Not yet mapped to any requirement or component.
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.

Original report

4.0.3: third-party plugins get appLibrary=null and a manifest stripped of __sourceDir, both silentlyrevision 1 · captured 2026-10-04 12:10 UTC via poll

Summary

Omarchy 4.0.3 tightened the API handed to third-party plugins. Two members that plugins depend on are now unreachable, and both failures are silent — no QML warning, no error, just an empty or dead widget. First-party plugins are unaffected because they receive the real shell objects, so the stock UI looks fine while every clone/fork breaks.

Both were bisected on a machine upgraded 4.0.1 → 4.0.3; both worked on 4.0.1.


Bug 1 — shell.appLibrary is null for third-party menu plugins

A plugin with "kinds": ["menu"] gets shell.appLibrary === null, so Menu.qml's mergeAppRows() returns at its first guard and the Apps submenu renders "Nothing here yet" forever.

shell.qml:603 looks correct:

appLibrary: shell.manifestHasKind(manifest, "menu")
  ? shell.pluginAppLibraryFor(cacheKey, key) : null,

and the manifest does reach the plugin with the right kinds — logged from inside the running plugin:

DIAG manifest={... "id":"<id>", "kinds":["menu","bar-widget"] ...}
DIAG shell.pluginId=<id>
DIAG shell.appLibrary direto=null

So manifestHasKind is satisfied and pluginAppLibraryFor() still yields nothing usable by the time the plugin reads it. PluginAppLibraryApi instances are created with createObject(null, {...}) and only referenced from JS-side caches — worth checking whether they survive collection.

The app data itself is fine: DesktopEntries.applications.values holds 73 entries, and AppSearch.sortedEntries() returns all 73. Only the delivery to the plugin is broken.

Reproduce

mkdir -p ~/.config/omarchy/plugins/repro.menutest
cp /usr/share/omarchy/shell/plugins/menu/{Menu.qml,MenuModel.js} \
   ~/.config/omarchy/plugins/repro.menutest/
cat > ~/.config/omarchy/plugins/repro.menutest/manifest.json <<'JSON'
{
  "schemaVersion": 1,
  "id": "repro.menutest",
  "name": "Repro menu",
  "version": "1.0.0",
  "author": "repro",
  "description": "Unmodified copy of omarchy.menu",
  "kinds": ["menu"],
  "keepLoaded": true,
  "entryPoints": { "menu": "Menu.qml" }
}
JSON

Add {"id": "repro.menutest"} to plugins in ~/.config/omarchy/shell.json, restart the shell, then:

omarchy-shell shell toggle repro.menutest '{"menu":"apps"}'

Expected: the installed applications, as omarchy.menu shows them.
Actual: "Nothing here yet".

The files are byte-identical to the shipped plugin — only the manifest id differs. Adding one console.log to mergeAppRows() in that copy prints:

REPRO appLibrary=null shell=PluginShellApi_QMLTYPE_26(0x...)

Bug 2 — __sourceDir is stripped, so third-party plugins cannot find their own bundled files

publicPluginManifest() deletes __sourceDir for anything not first-party (shell.qml:318-322):

function publicPluginManifest(manifest) {
  if (!manifest) return null
  if (manifest.__isFirstParty) return manifest
  var copy = JSON.parse(JSON.stringify(manifest))
  delete copy.__sourceDir
  ...

Any third-party plugin shipping a helper script or asset alongside its QML uses manifest.__sourceDir to locate it. With the field gone the path resolves empty and the plugin runs bash "", which fails silently.

Concretely, the third-party Workload plugin resolves its collector as:

readonly property string sourceDir: manifest && manifest.__sourceDir
  ? String(manifest.__sourceDir).replace(/^file:\/\//, "").replace(/\/$/, "") : ""
readonly property string collector: sourceDir ? sourceDir + "/workload-collector" : ""

On 4.0.3 every reading renders as zero — 0 °C, 0 MHz, 0 threads, 0.0/0.0 GB memory, 0/0 GB disk — while running the same script by hand returns a full JSON snapshot immediately. No error is logged.

sourceDir is still put into bar-widget registry metadata (shell.qml:1410), but PluginBarWidgetRegistryApi does not expose it, so there is no supported way for a third-party plugin to find its own directory. Qt.resolvedUrl(".") works as a local workaround, but plugins that follow the documented __sourceDir contract all break on upgrade.


Suggested direction

If restricting these is deliberate, the replacements need to be reachable and the removals announced — a third-party plugin currently has no supported way to (a) list applications or (b) locate its own bundled files, and both fail without a diagnostic. If it is not deliberate, appLibrary delivery and __sourceDir (or an exposed equivalent on the registry API) should be restored for third-party plugins.

A warning when a plugin reads a stripped/nulled member would have turned hours of bisecting into one log line.

System

  • Omarchy 4.0.3-1 (regressed from 4.0.1-1)
  • omarchy-settings 4.0.3-1
  • quickshell 0.3.1-1
  • qt6-base 6.11.2-3
  • Arch Linux, Hyprland, x86_64
View raw text
## Summary

Omarchy 4.0.3 tightened the API handed to **third-party** plugins. Two members that plugins depend on are now unreachable, and both failures are silent — no QML warning, no error, just an empty or dead widget. First-party plugins are unaffected because they receive the real shell objects, so the stock UI looks fine while every clone/fork breaks.

Both were bisected on a machine upgraded 4.0.1 → 4.0.3; both worked on 4.0.1.

---

## Bug 1 — `shell.appLibrary` is `null` for third-party menu plugins

A plugin with `"kinds": ["menu"]` gets `shell.appLibrary === null`, so `Menu.qml`'s `mergeAppRows()` returns at its first guard and the **Apps** submenu renders "Nothing here yet" forever.

`shell.qml:603` looks correct:

```qml
appLibrary: shell.manifestHasKind(manifest, "menu")
  ? shell.pluginAppLibraryFor(cacheKey, key) : null,
```

and the manifest does reach the plugin with the right kinds — logged from inside the running plugin:

```
DIAG manifest={... "id":"<id>", "kinds":["menu","bar-widget"] ...}
DIAG shell.pluginId=<id>
DIAG shell.appLibrary direto=null
```

So `manifestHasKind` is satisfied and `pluginAppLibraryFor()` still yields nothing usable by the time the plugin reads it. `PluginAppLibraryApi` instances are created with `createObject(null, {...})` and only referenced from JS-side caches — worth checking whether they survive collection.

The app data itself is fine: `DesktopEntries.applications.values` holds 73 entries, and `AppSearch.sortedEntries()` returns all 73. Only the delivery to the plugin is broken.

### Reproduce

```bash
mkdir -p ~/.config/omarchy/plugins/repro.menutest
cp /usr/share/omarchy/shell/plugins/menu/{Menu.qml,MenuModel.js} \
   ~/.config/omarchy/plugins/repro.menutest/
cat > ~/.config/omarchy/plugins/repro.menutest/manifest.json <<'JSON'
{
  "schemaVersion": 1,
  "id": "repro.menutest",
  "name": "Repro menu",
  "version": "1.0.0",
  "author": "repro",
  "description": "Unmodified copy of omarchy.menu",
  "kinds": ["menu"],
  "keepLoaded": true,
  "entryPoints": { "menu": "Menu.qml" }
}
JSON
```

Add `{"id": "repro.menutest"}` to `plugins` in `~/.config/omarchy/shell.json`, restart the shell, then:

```bash
omarchy-shell shell toggle repro.menutest '{"menu":"apps"}'
```

**Expected:** the installed applications, as `omarchy.menu` shows them.
**Actual:** "Nothing here yet".

The files are byte-identical to the shipped plugin — only the manifest id differs. Adding one `console.log` to `mergeAppRows()` in that copy prints:

```
REPRO appLibrary=null shell=PluginShellApi_QMLTYPE_26(0x...)
```

---

## Bug 2 — `__sourceDir` is stripped, so third-party plugins cannot find their own bundled files

`publicPluginManifest()` deletes `__sourceDir` for anything not first-party (`shell.qml:318-322`):

```qml
function publicPluginManifest(manifest) {
  if (!manifest) return null
  if (manifest.__isFirstParty) return manifest
  var copy = JSON.parse(JSON.stringify(manifest))
  delete copy.__sourceDir
  ...
```

Any third-party plugin shipping a helper script or asset alongside its QML uses `manifest.__sourceDir` to locate it. With the field gone the path resolves empty and the plugin runs `bash ""`, which fails silently.

Concretely, the third-party Workload plugin resolves its collector as:

```qml
readonly property string sourceDir: manifest && manifest.__sourceDir
  ? String(manifest.__sourceDir).replace(/^file:\/\//, "").replace(/\/$/, "") : ""
readonly property string collector: sourceDir ? sourceDir + "/workload-collector" : ""
```

On 4.0.3 every reading renders as zero — 0 °C, 0 MHz, 0 threads, 0.0/0.0 GB memory, 0/0 GB disk — while running the same script by hand returns a full JSON snapshot immediately. No error is logged.

`sourceDir` is still put into bar-widget registry metadata (`shell.qml:1410`), but `PluginBarWidgetRegistryApi` does not expose it, so there is no supported way for a third-party plugin to find its own directory. `Qt.resolvedUrl(".")` works as a local workaround, but plugins that follow the documented `__sourceDir` contract all break on upgrade.

---

## Suggested direction

If restricting these is deliberate, the replacements need to be reachable and the removals announced — a third-party plugin currently has no supported way to (a) list applications or (b) locate its own bundled files, and both fail without a diagnostic. If it is not deliberate, `appLibrary` delivery and `__sourceDir` (or an exposed equivalent on the registry API) should be restored for third-party plugins.

A warning when a plugin reads a stripped/nulled member would have turned hours of bisecting into one log line.

## System

- Omarchy 4.0.3-1 (regressed from 4.0.1-1)
- omarchy-settings 4.0.3-1
- quickshell 0.3.1-1
- qt6-base 6.11.2-3
- Arch Linux, Hyprland, x86_64

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

Not linked to any known issue, other report or change yet.

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

No decision has been recorded yet.