app
Pup - the AI's own browser
Public Made by Adomby adom
pup gives your AI a real browser on your desktop that it drives completely, in the background, signed in as you: windows that never jump in front of your work, one shared profile that learns your logins, and every window labeled on the taskbar with its AI thread's name.
← Commit history
README.mdadded+181@@ -0,0 +1,181 @@+# Reference bridge: Puppeteer + +## Source code + contributing (2026-05) + +The Puppeteer (Chrome) bridge moved out of `adom-inc/adom-desktop`'s monorepo into its own dedicated repo so the community can extend it without coordinating with Adom Desktop's release cycle. + +### Where the source lives + +The canonical repo is **[`adom-inc/adom-bridge-puppeteer`](https://github.com/adom-inc/adom-bridge-puppeteer)** on GitHub. It's private today and will go public after a review pass. + +In the meantime, the full source — code, history, contributing guide, license — is **mirrored on this wiki page**: + +| Download | What it is | How to use | +|---|---|---| +| [`adom-bridge-puppeteer-source.tar.gz`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer-source.tar.gz) | Clean source tree, no `.git` directory. ~98 KB. | `tar xzf adom-bridge-puppeteer-source.tar.gz && cd adom-bridge-puppeteer/` | +| [`adom-bridge-puppeteer.bundle`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle) | Git bundle with full commit history. ~157 KB. | `git clone https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle adom-bridge-puppeteer && cd adom-bridge-puppeteer && git log` | + +No GitHub account needed to download either — both URLs are public. + +### How to contribute + +We accept community improvements. Most useful targets right now: + +- **macOS / Linux ports** — bridge currently Windows-only; cross-platform PRs welcome. +- **New browser-automation verbs** — Puppeteer surface is big; we wrap a useful subset. Add more if you need them. +- **Recording features** — desktop recorder is new (v1.8.x); plenty of polish room (annotations, audio, GIF export). + +Two contribution paths, depending on your access: + +**With a GitHub account (preferred):** wait until we make the repo public, then fork on GitHub and open a PR. We're aiming to flip the repo public in the next maintenance pass. + +**Without GitHub access (patch-by-email-style, available right now):** Clone the bundle, make your changes, generate a patch with `git format-patch origin/main..HEAD --stdout > my-changes.patch`, and email it to **`[email protected]`**. Adom maintainers will review and apply. + +See `CONTRIBUTING.md` inside the tarball/bundle for the full PR + ship workflow. + +### How shipping works after merge + +1. Maintainer merges your PR into `main` +2. Maintainer tags `v<X.Y.Z>` + runs `bash scripts/release-bridge.sh puppeteer` on their box +3. New zip + manifest published to this wiki page (replaces current version) +4. Every Adom Desktop install running v1.7.19+ auto-picks up your change within 4 hours OR immediately via `adom-desktop refresh_bridges` + +No NSIS installer rebuild required. Your code reaches real users in ~30s after merge. + +### License + +MIT — see the `LICENSE` file in the tarball. + +--- + + +The Puppeteer bridge is one of three reference implementations bundled with Adom Desktop. It wraps `puppeteer-core` + Chrome for Testing to give Docker-side Claude full headful browser automation on the user's desktop — multi-window, multi-tab, file uploads, network interception, video recording. + +If you're authoring a new third-party bridge, see the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges) first. Use this page when you want to see how a Node-based bridge is wired. + +## Quick facts + +| | | +|---|---| +| Name | `puppeteer` | +| Display | Puppeteer (Chrome for Testing) | +| Spawn kind | Node (`server.js`) | +| Port | 8851 | +| Verb prefixes | `browser_*`, `desktop_recorder_*`, `desktop_record_*` (22 verbs) | +| Source zip | [`puppeteer-bridge-v1.0.0.zip`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip) | +| Manifest | [`puppeteer-bridge-manifest.json`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-manifest.json) | +| User-facing skill | [`pup-SKILL.md`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/pup-SKILL.md) | + +## What it does + +- **Sessions + tabs** — `browser_open_window` spawns Chrome for Testing with a per-session profile (cookies, IndexedDB, localStorage isolated). `browser_open_tab` / `browser_close_tab` manage tabs within a session. +- **Navigation + introspection** — `browser_navigate`, `browser_back/forward/reload`, `browser_screenshot` (full-page or viewport), `browser_evaluate` (run JS, return result). +- **Input synthesis** — `browser_click`, `browser_type`, `browser_press_key`, `browser_input_dispatch` (low-level CDP `Input.dispatchKeyEvent` for cases where typing through React state handlers fails). +- **Recording** — `browser_record_start` per-tab via CDP `Page.startScreencast`, `desktop_record_start` for full-desktop via `getDisplayMedia` + `MediaRecorder` in a hidden Chrome window. +- **Network capture** — `browser_fetch_url` runs `fetch()` from inside the page context (uses session cookies); useful for endpoints that gate by SameSite/CORS. + +## `bridge.json` + +```json +{ + "manifest_version": 1, + "name": "puppeteer", + "displayName": "Puppeteer (Chrome for Testing)", + "version": "1.0.0", + "description": "Headful browser automation via puppeteer-core + Chrome for Testing. Multi-window, multi-tab, recording, file uploads, network interception.", + "homepage": "https://github.com/adom-inc/adom-desktop", + "author": "Adom Inc.", + "license": "MIT", + "spawn": { + "kind": "node", + "entrypoint": "server.js", + "port": 8851, + "healthEndpoint": "http://127.0.0.1:8851/status", + "stopMethod": "kill", + "killImageName": "node.exe" + }, + "verbPrefixes": ["browser_", "desktop_recorder_", "desktop_record_"], + "verbs": [ + "browser_open_window", "browser_open_tab", "browser_close_tab", "browser_close_window", + "browser_navigate", "browser_back", "browser_forward", "browser_reload", + "browser_click", "browser_type", "browser_press_key", + "browser_screenshot", "browser_evaluate", "browser_fetch_url", + "browser_input_dispatch", + "browser_record_start", "browser_record_stop", "browser_record_status", "browser_record_list", + "desktop_recorder_open", "desktop_record_start", "desktop_record_stop" + ], + "dependencies": { "node": ">=20", "chrome": ">=120" }, + "category": "Browser Automation", + "tags": ["puppeteer", "chrome", "headful", "recording"] +} +``` + +Note: `verbPrefixes` is an array with THREE entries (`browser_*`, `desktop_recorder_*`, `desktop_record_*`). One bridge can own multiple prefixes. + +## Architecture highlights + +``` +puppeteer/ +├── server.js ← HTTP entry point; routes /command → handler functions +├── credential_vault.js ← Per-session cookie/storage isolation +├── adom-icon.svg ← Window icon for spawned Chrome instances +└── (npm install lays down node_modules + puppeteer-core) +``` + +The bridge intentionally keeps minimal on-disk state — `puppeteer-core` does the heavy lifting and Chrome for Testing is downloaded into `~/.cache/puppeteer/` on first run. The bridge code itself is one large `server.js` (~2k lines) using `http.createServer` for the JSON-over-HTTP dispatch layer (same shape as the hello sample, just more handlers). + +## Session model + +```bash +# Open a window for session "design-review" with its own Chrome profile +adom-desktop browser_open_window '{"sessionId":"design-review","profile":"design-review","url":"https://staging.example.com"}' + +# Add a tab in the same window +adom-desktop browser_open_tab '{"sessionId":"design-review","url":"https://staging.example.com/cart"}' + +# Screenshot the active tab +adom-desktop browser_screenshot '{"sessionId":"design-review"}' + +# Evaluate JS in the page (returns the resolved value) +adom-desktop browser_evaluate '{"sessionId":"design-review","expr":"document.querySelectorAll(\"button\").length"}' + +# Close the whole window when done +adom-desktop browser_close_window '{"sessionId":"design-review"}' +``` + +The `sessionId` is the persistence key — close + reopen the same session and you get the cookies + localStorage from before. `profile` defaults to the sessionId but can be shared across sessions for IndexedDB / login state sharing. + +## Recording example + +```bash +# Per-tab recording → CDP screencast → JPEG frames → ffmpeg-mux'd tar on stop +adom-desktop browser_record_start '{"sessionId":"design-review","tabId":"tab-1","fps":30}' +# … drive the page … +adom-desktop browser_record_stop '{"recordingId":"rec-tab-…"}' + +# Full-desktop recording → hidden Chrome window with getDisplayMedia + MediaRecorder → WebM +adom-desktop desktop_recorder_open +adom-desktop desktop_record_start '{"reason":"Demoing the alignment dialog flow","monitor":"primary"}' +# … drive the desktop … +adom-desktop desktop_record_stop +``` + +Reason is required for desktop recording so the user always knows why the recorder activated — it's shown in the HUD panel that opens. + +## Reference: install the source locally to read + +```bash +curl -L https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip -o /tmp/puppeteer-bridge.zip +mkdir -p /tmp/puppeteer-bridge && cd /tmp/puppeteer-bridge && python3 -c "import zipfile; zipfile.ZipFile('/tmp/puppeteer-bridge.zip').extractall()" +ls -la +``` + +Open `server.js` to see the dispatch shape, recorder lifecycle, and per-session profile management. + +## Related + +- **[Bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges)** — `bridge.json` schema, packaging recipe, lifecycle +- **[KiCad bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-kicad-bridge)** — most complex of the three; multi-instance, reverse-bridge +- **[Fusion 360 bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-fusion-bridge)** — passthrough-to-add-in pattern +- **[adom-desktop main page](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop)** — install the parent app first +
page.jsonadded+70@@ -0,0 +1,70 @@+{+ "schema_version": 1,+ "type": "app",+ "slug": "adom-desktop-puppeteer-bridge",+ "title": "Reference bridge: Puppeteer",+ "brief": "Reference implementation of the Puppeteer bridge — Node + puppeteer-core + Chrome for Testing for headful browser automation, multi-window, per-tab CDP screencast recording.",+ "version": "1.0.0",+ "tags": [],+ "license": "MIT",+ "discovery_triggers": [+ "puppeteer bridge",+ "pup bridge",+ "puppeteer bridge source",+ "chrome automation bridge",+ "puppeteer-core",+ "chrome for testing",+ "browser_open_window",+ "browser_screenshot",+ "browser_record_start",+ "desktop_record_start",+ "pup session profile",+ "headful chrome",+ "browser bridge source",+ "fork the pup bridge",+ "node bridge example"+ ],+ "discovery_pitch": "Reference implementation of the Puppeteer bridge — Node + puppeteer-core + Chrome for Testing for headful browser automation. Multi-window, multi-tab, per-session profile isolation, per-tab CDP screencast recording, full-desktop MediaRecorder capture.",+ "sample_prompts": [+ {+ "label": "Read puppeteer bridge source",+ "prompt": "Download the puppeteer-bridge zip from the wiki and walk me through server.js"+ },+ {+ "label": "Add a browser verb",+ "prompt": "Help me add a new browser_extract_pdfs verb to the puppeteer bridge"+ },+ {+ "label": "Open a window in pup",+ "prompt": "adom-desktop browser_open_window with a test URL"+ },+ {+ "label": "Record a tab",+ "prompt": "Record a 30-second video of a pup tab via browser_record_start/stop"+ },+ {+ "label": "Understand sessions",+ "prompt": "Explain how pup session profiles isolate cookies + IndexedDB"+ }+ ],+ "install": {+ "binary_name": "adom-desktop-puppeteer-bridge",+ "install_dir": "",+ "install_hint": "",+ "version_cmd": ""+ },+ "readme": "# Reference bridge: Puppeteer\r\n\r\n## Source code + contributing (2026-05)\r\n\r\nThe Puppeteer (Chrome) bridge moved out of `adom-inc/adom-desktop`'s monorepo into its own dedicated repo so the community can extend it without coordinating with Adom Desktop's release cycle.\r\n\r\n### Where the source lives\r\n\r\nThe canonical repo is **[`adom-inc/adom-bridge-puppeteer`](https://github.com/adom-inc/adom-bridge-puppeteer)** on GitHub. It's private today and will go public after a review pass.\r\n\r\nIn the meantime, the full source — code, history, contributing guide, license — is **mirrored on this wiki page**:\r\n\r\n| Download | What it is | How to use |\r\n|---|---|---|\r\n| [`adom-bridge-puppeteer-source.tar.gz`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer-source.tar.gz) | Clean source tree, no `.git` directory. ~98 KB. | `tar xzf adom-bridge-puppeteer-source.tar.gz && cd adom-bridge-puppeteer/` |\r\n| [`adom-bridge-puppeteer.bundle`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle) | Git bundle with full commit history. ~157 KB. | `git clone https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-puppeteer-bridge/adom-bridge-puppeteer.bundle adom-bridge-puppeteer && cd adom-bridge-puppeteer && git log` |\r\n\r\nNo GitHub account needed to download either — both URLs are public.\r\n\r\n### How to contribute\r\n\r\nWe accept community improvements. Most useful targets right now:\r\n\r\n- **macOS / Linux ports** — bridge currently Windows-only; cross-platform PRs welcome.\r\n- **New browser-automation verbs** — Puppeteer surface is big; we wrap a useful subset. Add more if you need them.\r\n- **Recording features** — desktop recorder is new (v1.8.x); plenty of polish room (annotations, audio, GIF export).\r\n\r\nTwo contribution paths, depending on your access:\r\n\r\n**With a GitHub account (preferred):** wait until we make the repo public, then fork on GitHub and open a PR. We're aiming to flip the repo public in the next maintenance pass.\r\n\r\n**Without GitHub access (patch-by-email-style, available right now):** Clone the bundle, make your changes, generate a patch with `git format-patch origin/main..HEAD --stdout > my-changes.patch`, and email it to **`[email protected]`**. Adom maintainers will review and apply.\r\n\r\nSee `CONTRIBUTING.md` inside the tarball/bundle for the full PR + ship workflow.\r\n\r\n### How shipping works after merge\r\n\r\n1. Maintainer merges your PR into `main`\r\n2. Maintainer tags `v<X.Y.Z>` + runs `bash scripts/release-bridge.sh puppeteer` on their box\r\n3. New zip + manifest published to this wiki page (replaces current version)\r\n4. Every Adom Desktop install running v1.7.19+ auto-picks up your change within 4 hours OR immediately via `adom-desktop refresh_bridges`\r\n\r\nNo NSIS installer rebuild required. Your code reaches real users in ~30s after merge.\r\n\r\n### License\r\n\r\nMIT — see the `LICENSE` file in the tarball.\r\n\r\n---\r\n\r\n\r\nThe Puppeteer bridge is one of three reference implementations bundled with Adom Desktop. It wraps `puppeteer-core` + Chrome for Testing to give Docker-side Claude full headful browser automation on the user's desktop — multi-window, multi-tab, file uploads, network interception, video recording.\r\n\r\nIf you're authoring a new third-party bridge, see the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges) first. Use this page when you want to see how a Node-based bridge is wired.\r\n\r\n## Quick facts\r\n\r\n| | |\r\n|---|---|\r\n| Name | `puppeteer` |\r\n| Display | Puppeteer (Chrome for Testing) |\r\n| Spawn kind | Node (`server.js`) |\r\n| Port | 8851 |\r\n| Verb prefixes | `browser_*`, `desktop_recorder_*`, `desktop_record_*` (22 verbs) |\r\n| Source zip | [`puppeteer-bridge-v1.0.0.zip`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip) |\r\n| Manifest | [`puppeteer-bridge-manifest.json`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-manifest.json) |\r\n| User-facing skill | [`pup-SKILL.md`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/pup-SKILL.md) |\r\n\r\n## What it does\r\n\r\n- **Sessions + tabs** — `browser_open_window` spawns Chrome for Testing with a per-session profile (cookies, IndexedDB, localStorage isolated). `browser_open_tab` / `browser_close_tab` manage tabs within a session.\r\n- **Navigation + introspection** — `browser_navigate`, `browser_back/forward/reload`, `browser_screenshot` (full-page or viewport), `browser_evaluate` (run JS, return result).\r\n- **Input synthesis** — `browser_click`, `browser_type`, `browser_press_key`, `browser_input_dispatch` (low-level CDP `Input.dispatchKeyEvent` for cases where typing through React state handlers fails).\r\n- **Recording** — `browser_record_start` per-tab via CDP `Page.startScreencast`, `desktop_record_start` for full-desktop via `getDisplayMedia` + `MediaRecorder` in a hidden Chrome window.\r\n- **Network capture** — `browser_fetch_url` runs `fetch()` from inside the page context (uses session cookies); useful for endpoints that gate by SameSite/CORS.\r\n\r\n## `bridge.json`\r\n\r\n```json\r\n{\r\n \"manifest_version\": 1,\r\n \"name\": \"puppeteer\",\r\n \"displayName\": \"Puppeteer (Chrome for Testing)\",\r\n \"version\": \"1.0.0\",\r\n \"description\": \"Headful browser automation via puppeteer-core + Chrome for Testing. Multi-window, multi-tab, recording, file uploads, network interception.\",\r\n \"homepage\": \"https://github.com/adom-inc/adom-desktop\",\r\n \"author\": \"Adom Inc.\",\r\n \"license\": \"MIT\",\r\n \"spawn\": {\r\n \"kind\": \"node\",\r\n \"entrypoint\": \"server.js\",\r\n \"port\": 8851,\r\n \"healthEndpoint\": \"http://127.0.0.1:8851/status\",\r\n \"stopMethod\": \"kill\",\r\n \"killImageName\": \"node.exe\"\r\n },\r\n \"verbPrefixes\": [\"browser_\", \"desktop_recorder_\", \"desktop_record_\"],\r\n \"verbs\": [\r\n \"browser_open_window\", \"browser_open_tab\", \"browser_close_tab\", \"browser_close_window\",\r\n \"browser_navigate\", \"browser_back\", \"browser_forward\", \"browser_reload\",\r\n \"browser_click\", \"browser_type\", \"browser_press_key\",\r\n \"browser_screenshot\", \"browser_evaluate\", \"browser_fetch_url\",\r\n \"browser_input_dispatch\",\r\n \"browser_record_start\", \"browser_record_stop\", \"browser_record_status\", \"browser_record_list\",\r\n \"desktop_recorder_open\", \"desktop_record_start\", \"desktop_record_stop\"\r\n ],\r\n \"dependencies\": { \"node\": \">=20\", \"chrome\": \">=120\" },\r\n \"category\": \"Browser Automation\",\r\n \"tags\": [\"puppeteer\", \"chrome\", \"headful\", \"recording\"]\r\n}\r\n```\r\n\r\nNote: `verbPrefixes` is an array with THREE entries (`browser_*`, `desktop_recorder_*`, `desktop_record_*`). One bridge can own multiple prefixes.\r\n\r\n## Architecture highlights\r\n\r\n```\r\npuppeteer/\r\n├── server.js ← HTTP entry point; routes /command → handler functions\r\n├── credential_vault.js ← Per-session cookie/storage isolation\r\n├── adom-icon.svg ← Window icon for spawned Chrome instances\r\n└── (npm install lays down node_modules + puppeteer-core)\r\n```\r\n\r\nThe bridge intentionally keeps minimal on-disk state — `puppeteer-core` does the heavy lifting and Chrome for Testing is downloaded into `~/.cache/puppeteer/` on first run. The bridge code itself is one large `server.js` (~2k lines) using `http.createServer` for the JSON-over-HTTP dispatch layer (same shape as the hello sample, just more handlers).\r\n\r\n## Session model\r\n\r\n```bash\r\n# Open a window for session \"design-review\" with its own Chrome profile\r\nadom-desktop browser_open_window '{\"sessionId\":\"design-review\",\"profile\":\"design-review\",\"url\":\"https://staging.example.com\"}'\r\n\r\n# Add a tab in the same window\r\nadom-desktop browser_open_tab '{\"sessionId\":\"design-review\",\"url\":\"https://staging.example.com/cart\"}'\r\n\r\n# Screenshot the active tab\r\nadom-desktop browser_screenshot '{\"sessionId\":\"design-review\"}'\r\n\r\n# Evaluate JS in the page (returns the resolved value)\r\nadom-desktop browser_evaluate '{\"sessionId\":\"design-review\",\"expr\":\"document.querySelectorAll(\\\"button\\\").length\"}'\r\n\r\n# Close the whole window when done\r\nadom-desktop browser_close_window '{\"sessionId\":\"design-review\"}'\r\n```\r\n\r\nThe `sessionId` is the persistence key — close + reopen the same session and you get the cookies + localStorage from before. `profile` defaults to the sessionId but can be shared across sessions for IndexedDB / login state sharing.\r\n\r\n## Recording example\r\n\r\n```bash\r\n# Per-tab recording → CDP screencast → JPEG frames → ffmpeg-mux'd tar on stop\r\nadom-desktop browser_record_start '{\"sessionId\":\"design-review\",\"tabId\":\"tab-1\",\"fps\":30}'\r\n# … drive the page …\r\nadom-desktop browser_record_stop '{\"recordingId\":\"rec-tab-…\"}'\r\n\r\n# Full-desktop recording → hidden Chrome window with getDisplayMedia + MediaRecorder → WebM\r\nadom-desktop desktop_recorder_open\r\nadom-desktop desktop_record_start '{\"reason\":\"Demoing the alignment dialog flow\",\"monitor\":\"primary\"}'\r\n# … drive the desktop …\r\nadom-desktop desktop_record_stop\r\n```\r\n\r\nReason is required for desktop recording so the user always knows why the recorder activated — it's shown in the HUD panel that opens.\r\n\r\n## Reference: install the source locally to read\r\n\r\n```bash\r\ncurl -L https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/puppeteer-bridge-v1.0.0.zip -o /tmp/puppeteer-bridge.zip\r\nmkdir -p /tmp/puppeteer-bridge && cd /tmp/puppeteer-bridge && python3 -c \"import zipfile; zipfile.ZipFile('/tmp/puppeteer-bridge.zip').extractall()\"\r\nls -la\r\n```\r\n\r\nOpen `server.js` to see the dispatch shape, recorder lifecycle, and per-session profile management.\r\n\r\n## Related\r\n\r\n- **[Bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges)** — `bridge.json` schema, packaging recipe, lifecycle\r\n- **[KiCad bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-kicad-bridge)** — most complex of the three; multi-instance, reverse-bridge\r\n- **[Fusion 360 bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-fusion-bridge)** — passthrough-to-add-in pattern\r\n- **[adom-desktop main page](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop)** — install the parent app first\r\n\r\n",+ "author": {+ "id": "695820315b5f1e4db2fcf602",+ "name": "Kyle Bergstedt",+ "email": "[email protected]"+ },+ "visibility": {+ "public": true+ },+ "hero": null,+ "metadata": {},+ "created_at": "2026-05-28T05:28:43.991Z",+ "updated_at": "2026-05-28T05:28:43.991Z",+ "skills": []+}