Skip to main content

pinned-folders

❖ Communityv0.1.2★ 1

A Pinned tab in the Desktop sidebar that files your pinned chats into nested folders: drag to order and nest, folder colors, right-click menus (including Unpin), unread/working badges on collapsed folders, a filter box, open-folder-as-tabs, and layout export/import via the clipboard. Layout stays local to the app; pins belong to the backend. SDK-only build (desktop/plugin.js); no network.

Open in Hermes Desktop
hermes plugins install pinned-folders

Screenshots

README

From the reviewed commit 7ab24e1 ↗; it updates when the author re-pins.

Pinned folders

A Pinned tab in the Hermes Desktop sidebar that files your pinned chats into folders, nested as deep as you like.

Pinned folders tab next to an open chat

Hermes shows pinned chats as one flat list. This plugin gives them their own tab next to Sessions and sorts them into folders you arrange yourself.

Right-click a folder Right-click a chat (full build) Filter
Folder menu with colors Chat menu Filter box narrowing to one chat

The screenshots use demo chats in a separate test copy of the app. The collapsed Research folder shows the activity badge: an accent dot while an agent works inside, and a green count of unread chats.

Features

  • Folders, nested to any depth. Create, rename (double-click), color, and delete. Deleting a folder moves its contents up one level, so no chat is lost.

  • Drag and drop.

    • Drop a folder on the top or bottom edge of another folder to place it above or below. Drop it in the middle to nest it.
    • Drop a chat on a folder to file it, or on another chat to place it just above that chat.
    • Folder order is whatever you set. Nothing is sorted automatically.
  • Right-click menus. Every chat and folder has the same actions as its ⋯ menu. Right-click empty space for New folder and the layout tools.

  • Chat actions like the Sessions list: Open, Open in new tab, Open in new window, Copy session ID, Unpin, and Delete (asks first). The full build adds Rename (also by double-clicking), Mark as read/unread, and Archive. On older Desktop releases without host.sessions.pin, the catalog menu instead explains that you must update Desktop or unpin in Sessions.

  • Activity on collapsed folders. A closed folder shows a green count of unread chats inside it and an accent dot while an agent is working inside. This includes chats in subfolders.

  • Shift-click a chat to unpin, the same gesture core Sessions uses to pin. A plain click opens the chat and ⌘-click or Ctrl-click opens it in a new tab. Archive (⌥⇧-click) and new window (⌘⇧-click) stay in core Sessions. The ⋯ and right-click Unpin item does the same thing.

  • Filter box. Type to narrow down to matching chats, and to folders whose names match.

  • Filter menu (the funnel button in the pane header):

    • Order: Manual (your drag order, the default) or Most recent.
    • Unread only, and Status: All, Unread or Working (the same green and accent dots as the badges).
    • Profile: All profiles or Current profile.
    • Collapse all folders. While a filter is set, matching folders stay open to show the matches, so the item is disabled and reads Clear filters to collapse.
    • Reset view sets filters and order back to their defaults. It never changes folders, colors or layout.

    The menu has no Mark all as read: the plugin SDK has no supported way to do it.

  • Open all as tabs. Opens every chat the folder shows, including its subfolders, as workspace tabs. With a filter set, only the chats you can see open. ⌘-click or Ctrl-click a single chat to open it in a new tab.

  • Export and import layout. Copies your folder layout as JSON so you can paste it on another machine. Importing replaces the folders only; pins are never changed.

  • New pins land in Unsorted.

  • The folder layout is stored in the app, separately for each connection.

Two builds

Catalog build desktop/plugin.js Full build full/plugin.js
Everything above ✓ ✓
Unpin from the folder tab, by menu or Shift-click ✓ (SDK host.sessions.pin on supported Desktop) ✓ (backend PATCH)
Filter menu (order, unread, status, profile, collapse all, reset view) ✓ ✓
Rename, Mark as read/unread, Archive a chat – ✓
Auto-pin chats you start (not agent, cron, or workflow sessions), with an optional "New chats land here" folder – ✓
Hide core's flat Pinned list in Sessions – ✓

If a new chat cannot be resolved or pinned within 60 seconds, the full build shows a notification. Pin it manually from Sessions, or check the connection and send another message to retry; a failed pin request does not mark the chat as already handled.

The catalog build uses only the Hermes Desktop plugin SDK, which the plugin catalog requires.

The catalog build unpins only through the supported host.sessions.pin(id, false) SDK method: core updates its pin store and syncs the durable flag to the owning backend. If that method is missing in an older Desktop, the action is disabled with an update/"use Sessions" explanation; it does not touch core internals or merely remove a chat from the folder layout. Because core writes the backend pin in the background, the catalog build keeps the chat's folder placement until a fresh read of the pinned list shows it gone; if the backend keeps it pinned, the chat stays in its original folder and order.

Known limitation: catalog Unpin of a chat whose id exists in more than one profile follows core's active-profile resolution; the full build targets the row's own profile.

The SDK still has no supported door for rename, archive, read state, detecting new chats for auto-pin, or hiding a core sidebar section. The full build reaches past it for those features and retains its direct backend unpin path:

  • It sends chat changes through the app's API bridge, using the same request the Sessions menu sends.
  • For direct unpin it also scrubs core's saved pin list so core cannot re-pin the backend row.
  • It hides the core Pinned section by changing the page directly.

These internals could break when the app updates. If one does, only that feature stops working. New SDK capabilities can replace full-only paths after verification.

Both builds come from full/plugin.js. node scripts/build.mjs writes the catalog build by deleting every // #full … // #end block.

Install

From the catalog (catalog build, once listed):

hermes plugins install pinned-folders

Local full Desktop build (clone this repo on the machine running the Desktop app):

node scripts/install-local.mjs --variant full

The installer requires an explicit --variant full|catalog, copies that build from this checkout into ~/.hermes/desktop-plugins/pinned-folders/plugin.js (or $HERMES_HOME/desktop-plugins/...), and prints the verified destination SHA-256. Use --variant catalog only when you deliberately want the SDK-only build. An existing different local file needs --replace; a detectable Hermes-managed package is never overwritten, even with --replace. To use a different home for testing, pass --home PATH. Do not use this local installer to update a catalog-managed install; update it with Hermes instead.

The app loads new plugins within a few seconds. If the tab doesn't appear, press ⌘K and run Reload desktop plugins.

Develop

node scripts/build.mjs          # full/plugin.js -> desktop/plugin.js
node tests/ops.test.mjs         # catalog build
node tests/ops.test.mjs full    # full build
hermes plugins validate .       # catalog admission checks

The plugin is plain ESM with jsx() calls and no build step, so the app loads the file as-is.

See CONTRIBUTING.md to send a change. Coding agents should start at AGENTS.md.

License

MIT

hermes-beads❖ Community★ 0

Native Beads (bd) work-graph plugin: fixed-argv adapter, scoped ready frontier, claim with read-back, guarded writes. Six tools over an explicit store path + actor; honest exit-code map incl. stale-13; plain bd stays fully sufficient (escape hatch). No desktop pane ships yet.

Tools
hermes-rich-ui❖ Community★ 0

Rich, evidence-backed answer cards — tables, charts, metrics, timelines, sources — rendered inline in the desktop transcript Disclosure — Image and ImageGallery cards load agent-supplied https image URLs (up to 8 per gallery) from any host when the card renders in Desktop

Desktop
hermes-workflows❖ Community★ 0

Agent-owned workflow graphs for Hermes — a background runner executes a JSON DAG of agent nodes, fan-outs (quorum) and human/machine gates with fingerprint replay-skip resume, cooperative steer, typed failure events and compact status payloads; ships a desktop DAG view, an inline transcript card and the authoring skill with measured budget recipes. Stock Hermes; no patched core required. Disclosure — every workflow run spawns a detached background runner (wf.py run <id>) that survives session end, gateway restart and plugin disable until the graph reaches a boundary or workflow stop; each agent node is a child hermes chat --query-file … --oneshot -Q … inheriting the runner's environment, and a node with profile set runs as that named profile (with its own credentials) only if the target's workflow_team.json lists the launcher; a gate's wait.until_argv runs an agent-authored argv directly from the runner, outside Hermes' tool-approval gate (the engine uses no shell, but the shipped machine-watch and incident-response templates use it to run a shell line read from a /tmp handoff file); run and amend send a one-token ping through Hermes' configured providers to check pinned model routes; the runner reads state.db read-only; state lives under $HERMES_HOME/workflows/ (or a configured runs_root). No scheduler, credential-store access or network of its own.

Automation

← Back to the catalog · catalog built Oct 3, 2026