joshleaves13 downloadsHides AI agent instruction files from the file explorer and marks their folders with an icon that opens the active one.
Folder Agent hides AI agent instruction files from the Obsidian file explorer and marks the folders that contain them with an icon that opens the active agent file.
It is agent agnostic: nothing is special-cased for any particular tool, you only configure which file names may hold agent instructions.
The plugin keeps an ordered list of file names in
Settings → Community plugins → Folder Agent. The default is AGENTS.md,
but any file name works, for example:
MY-AGENT-CONFIG.mdAGENTS.mdGEMINI.md.COPILOT.configThe order defines precedence. If a folder contains several of them, the first
existing file in the list is that folder's active agent file, and it is the
one the folder icon opens. In the example above a folder holding AGENTS.md
and GEMINI.md shows a single icon that opens AGENTS.md, while both files
stay accessible through the context menu.
Nested folders are independent: each folder resolves its own active file.
The vault is the only source of truth. Folder Agent keeps no per-folder registry, so creating, renaming or deleting files on disk updates the file explorer immediately.
Each configured name can override the icon (any icon from
Lucide, the icon set Obsidian ships with) and its
colour. Typing in the icon field autocompletes the icon names Obsidian knows.
A folder uses the appearance of its currently active agent file, and
bot with the theme's own icon colour is the default. Changes are applied
immediately, and reordering names changes which file a folder icon opens.
Right-click a folder in the file explorer:
Folder Agent File
✓ AGENTS.md
GEMINI.md
Add…
MY-AGENT-CONFIG.md
.COPILOT.config
This project uses TypeScript with the Obsidian type definitions and esbuild.
npm install # install dependencies
npm run dev # watch build to main.js (for local development)
npm run build # type check, production build, refresh dist/
npm run lint # oxlint + eslint (eslint-plugin-obsidianmd)
npm run release # lint, then the production build
To try it out, put this repository into a vault as
<Vault>/.obsidian/plugins/folder-agent/, run npm run dev, and enable the
plugin in Settings → Community plugins.
A production build also assembles dist/, which contains exactly the three
files a plugin release consists of:
dist/
main.js # production bundle
manifest.json # copied from the repository root
styles.css # copied from the repository root
dist/ is recreated from scratch on every build, so it never contains stale
files. Nothing in it is generated: manifest.json and styles.css stay
canonical source files in the repository root, and main.js is the bundle the
build produces in the root as well (which is what npm run dev writes while
watching).
Requires Obsidian 1.13.0 or later, because the settings tab uses the
declarative settings API introduced there. The plugin works on desktop and
mobile (isDesktopOnly: false).
Obsidian has no public API for hiding files in the file explorer or for
decorating its rows. src/file-explorer.ts is therefore the only module that
touches the file explorer, and it does so as little as possible:
data-path attribute, the long standing
convention of the explorer markup, and by the .nav-file-title and
.nav-folder-title class names..folder-agent-hidden, styled in
styles.css) and appends one small element per folder icon. Both are driven
by a single MutationObserver per file explorer, because the explorer
recreates rows while scrolling and expanding.The nested Add… submenu uses MenuItem.setSubmenu(), which exists in
Obsidian but is not part of the public API. It is feature detected inside a
guarded call, and if it is missing or throws — as on an Obsidian version that
drops it — the same entries are added to the parent menu instead, so the
Folder Agent File entry itself always stays available.
Folder context menus are extended through the documented file-menu workspace
event, which the file explorer also fires for folders. Its source argument
carries undocumented values, so it is deliberately not filtered on; the entries
therefore also appear in folder context menus of other Obsidian views (search
results, quick switcher), which is harmless.
Because rows are matched by their data-path attribute, a row whose attribute
Obsidian has not updated yet (a known quirk when a folder is renamed) can keep
its previous state until the explorer re-renders that row. Collapsing and
expanding the folder, or reloading Obsidian, resolves it.
npm run release # lint + production build, leaves the artifacts in dist/
npm run release does not tag, push or change any version; those stay
explicit. To publish: bump the version with
npm version patch|minor|major (which updates manifest.json and
versions.json), tag the release with the manifest version (no v prefix) and
attach dist/main.js, dist/manifest.json and dist/styles.css. The GitHub
workflow in .github/workflows/release.yml does the tagging and uploading.
MIT