Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
Obsidian plugin — alternative side-pane file explorer with tree/list browsing, sorting, grouping, filtering, and manual order.

- Plugin ID: `smart-explorer`
- Current version: `0.5.0`
- Current version: `0.5.4`
- Min Obsidian version: `1.7.2`

## Commands

```bash
npm run dev # esbuild watch mode
npm run build # tsc check + esbuild production
npm test # jest with ts-jest
npm run lint # eslint
npm run verify # lint + production build + all tests
npm run dev # esbuild watch mode
npm run build # tsc check + esbuild production
npm test # jest with ts-jest (node + jsdom suites)
npm run lint # eslint
npm run test:fixture # fixture-script safety tests (node --test)
npm run verify # lint + production build + all tests + fixture tests
```

## Architecture
Expand All @@ -35,6 +36,8 @@ src/explorer/sorters.ts Pure sorting functions (8 modes, path tie-br
src/explorer/groupers.ts Pure grouping functions (5 modes: none, folder, extension, modified-month, top-folder)
src/explorer/filters.ts Pure filter functions (search, extension, file kind, date range)
src/explorer/filterState.ts Clear/detect active search and filters
src/explorer/queryNormalization.ts Shared search-text normalization for filters + state
src/explorer/focusNavigation.ts Pure key → focus/expand/activate resolver for list/tree rows
src/explorer/fileRow.ts File row display formatting helpers
src/explorer/creationPath.ts Pure helpers for new note/folder target paths
src/explorer/treeFolderInfo.ts Tree folder hover metadata helpers
Expand All @@ -43,14 +46,20 @@ src/explorer/revealPath.ts Pure path-reveal helpers for active file / s
src/explorer/touchLongPress.ts Pure touch long-press threshold helpers
src/explorer/viewMode.ts Resolves effective tree/list mode + manual seed sort

src/explorer/rowHeight.ts List row-height constants (44px desktop / 52px mobile)
src/settings/settings.ts Settings type + defaults
src/settings/settings-normalization.ts Strict validation/migration of persisted settings
src/settings/settings-tab.ts PluginSettingTab UI
src/settings/settings-helpers.ts Sort/group option lists (shared by toolbar + settings)
src/test-utils/obsidianDom.ts jsdom shims (Obsidian DOM helpers, deterministic layout)

src/explorer/__tests__/*.test.ts Unit tests for pure explorer helpers and models
src/explorer/__tests__/*.test.ts Unit/DOM/integration tests for explorer helpers and models
scripts/prepare-large-vault-fixture.mjs Marker-protected synthetic fixture generator
```

**List data flow:** `FileIndex.build()` → hidden-extension filter → `buildSections(records, query)` → filter → sort → group → `VirtualList` render
**List data flow:** `FileIndex.build()` → hidden-extension filter → `buildSections(records, query)` → filter → sort → group → direct render, or keyed windowed render via `VirtualList` above 200 rows

**Keyboard model:** the list container holds the single tab stop and DOM focus; the active row is tracked via `aria-activedescendant` (pinned across windowed renders). Selection highlight follows `workspace.file-open` without auto-reveal.

**Tree data flow:** `FileIndex.build()` → hidden-extension filter → `buildTree(records, query)` → filter → folder tree sort → recursive tree render

Expand All @@ -65,6 +74,17 @@ src/explorer/__tests__/*.test.ts Unit tests for pure explorer helpers and mod
- Obsidian CSS variables for theming, prefixed with `.smart-explorer-`
- Tests use Jest with ts-jest, `__tests__` subdirectory per module

## Test vault and large-vault fixture

`/Users/Roger/my-vault` is the dedicated local development/test vault (the plugin folder symlinks to a repo checkout). For large-vault testing:

```bash
node scripts/prepare-large-vault-fixture.mjs --vault /Users/Roger/my-vault --files 5000 # create
node scripts/prepare-large-vault-fixture.mjs --vault /Users/Roger/my-vault --remove # remove
```

The script only touches `<vault>/.smart-explorer-large-vault-fixture` and refuses to delete anything without its marker file.

## Git workflow

- `main` branch: PR required, CI `verify` job must pass, no force push, no deletion
Expand Down
36 changes: 28 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
Obsidian plugin — alternative side-pane file explorer with tree/list browsing, sorting, grouping, filtering, and manual order.

- Plugin ID: `smart-explorer`
- Current version: `0.5.0`
- Current version: `0.5.4`
- Min Obsidian version: `1.7.2`

## Commands

```bash
npm run dev # esbuild watch mode
npm run build # tsc check + esbuild production
npm test # jest with ts-jest
npm run lint # eslint
npm run verify # lint + production build + all tests
npm run dev # esbuild watch mode
npm run build # tsc check + esbuild production
npm test # jest with ts-jest (node + jsdom suites)
npm run lint # eslint
npm run test:fixture # fixture-script safety tests (node --test)
npm run verify # lint + production build + all tests + fixture tests
```

## Architecture
Expand All @@ -35,6 +36,8 @@ src/explorer/sorters.ts Pure sorting functions (8 modes, path tie-br
src/explorer/groupers.ts Pure grouping functions (5 modes: none, folder, extension, modified-month, top-folder)
src/explorer/filters.ts Pure filter functions (search, extension, file kind, date range)
src/explorer/filterState.ts Clear/detect active search and filters
src/explorer/queryNormalization.ts Shared search-text normalization for filters + state
src/explorer/focusNavigation.ts Pure key → focus/expand/activate resolver for list/tree rows
src/explorer/fileRow.ts File row display formatting helpers
src/explorer/creationPath.ts Pure helpers for new note/folder target paths
src/explorer/treeFolderInfo.ts Tree folder hover metadata helpers
Expand All @@ -43,14 +46,20 @@ src/explorer/revealPath.ts Pure path-reveal helpers for active file / s
src/explorer/touchLongPress.ts Pure touch long-press threshold helpers
src/explorer/viewMode.ts Resolves effective tree/list mode + manual seed sort

src/explorer/rowHeight.ts List row-height constants (44px desktop / 52px mobile)
src/settings/settings.ts Settings type + defaults
src/settings/settings-normalization.ts Strict validation/migration of persisted settings
src/settings/settings-tab.ts PluginSettingTab UI
src/settings/settings-helpers.ts Sort/group option lists (shared by toolbar + settings)
src/test-utils/obsidianDom.ts jsdom shims (Obsidian DOM helpers, deterministic layout)

src/explorer/__tests__/*.test.ts Unit tests for pure explorer helpers and models
src/explorer/__tests__/*.test.ts Unit/DOM/integration tests for explorer helpers and models
scripts/prepare-large-vault-fixture.mjs Marker-protected synthetic fixture generator
```

**List data flow:** `FileIndex.build()` → hidden-extension filter → `buildSections(records, query)` → filter → sort → group → `VirtualList` render
**List data flow:** `FileIndex.build()` → hidden-extension filter → `buildSections(records, query)` → filter → sort → group → direct render, or keyed windowed render via `VirtualList` above 200 rows

**Keyboard model:** the list container holds the single tab stop and DOM focus; the active row is tracked via `aria-activedescendant` (pinned across windowed renders). Selection highlight follows `workspace.file-open` without auto-reveal.

**Tree data flow:** `FileIndex.build()` → hidden-extension filter → `buildTree(records, query)` → filter → folder tree sort → recursive tree render

Expand All @@ -65,6 +74,17 @@ src/explorer/__tests__/*.test.ts Unit tests for pure explorer helpers and mod
- Obsidian CSS variables for theming, prefixed with `.smart-explorer-`
- Tests use Jest with ts-jest, `__tests__` subdirectory per module

## Test vault and large-vault fixture

`/Users/Roger/my-vault` is the dedicated local development/test vault (the plugin folder symlinks to a repo checkout). For large-vault testing:

```bash
node scripts/prepare-large-vault-fixture.mjs --vault /Users/Roger/my-vault --files 5000 # create
node scripts/prepare-large-vault-fixture.mjs --vault /Users/Roger/my-vault --remove # remove
```

The script only touches `<vault>/.smart-explorer-large-vault-fixture` and refuses to delete anything without its marker file.

## Git workflow

- `main` branch: PR required, CI `verify` job must pass, no force push, no deletion
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ Built for vaults with hundreds or thousands of notes where the default file tree

| Category | Options |
|----------|---------|
| **Browse** | Folder tree by default, with folder counts and compact hover details |
| **Browse** | Folder tree by default, with folder counts and compact hover details; closed folders render lazily and long flat lists use windowed rendering, so large vaults stay fast |
| **Create** | Create notes and folders via toolbar, context menu, or command palette — with inline name editing |
| **Edit** | Rename files inline; extensions stay fixed so only the name changes |
| **Sort** | Name (A-Z / Z-A), modified date, created date, extension, file size, manual drag order |
| **Filter** | Search by name/path, extension, file kind (all / markdown / non-markdown / images), date range (1d / 7d / 30d) |
| **View** | Tree/list toggle; Manual sort automatically uses list mode for direct drag-and-drop |
| **View** | Tree/list toggle — the mode is remembered between sessions; Manual sort automatically uses list mode for direct drag-and-drop |
| **Commands** | Open, focus search, reveal active file, new note, new folder — all in the Command Palette |
| **Keyboard** | Focus search, clear search, move through rows, and open selected files |
| **Keyboard** | Full keyboard navigation: arrows move through rows, Home/End jump, arrow keys open and close folders, Enter opens files, and `Alt+Arrow` reorders files in Manual mode |
| **Settings** | Default sort/group mode, hidden extensions, reset manual order |

### Manual Drag-and-Drop Sorting

Switch to **Manual** sort mode to drag the handle beside a file and reorder it. The starting order matches whatever sort you were viewing ("what you see is what you drag"), shown in a toolbar hint. Use **Undo** to revert the last reorder. The custom order is saved per vault, keeps new files draggable, and persists across sessions. Works on both desktop and mobile.
Switch to **Manual** sort mode to drag the handle beside a file and reorder it, or keep your hands on the keyboard and use `Alt+ArrowUp` / `Alt+ArrowDown` on the selected file. The starting order matches whatever sort you were viewing ("what you see is what you drag"), shown in a toolbar hint. Use **Undo** to revert the last reorder. The custom order is saved per vault, keeps new files draggable, and persists across sessions. Works on both desktop and mobile.

## Installation

Expand Down Expand Up @@ -52,8 +52,10 @@ Switch to **Manual** sort mode to drag the handle beside a file and reorder it.

- `Cmd/Ctrl+F` focuses the search box
- `Esc` clears search text or closes the filter row
- `Arrow Up/Down` moves through file rows
- `Enter` opens the focused file
- `Arrow Up/Down` moves through rows; `Home`/`End` jump to the first/last row
- `Arrow Right/Left` opens/closes the focused folder in tree mode
- `Enter` or `Space` opens the focused file or toggles the focused folder
- `Alt+ArrowUp` / `Alt+ArrowDown` moves the selected file in Manual sort mode (announced via screen reader)
- Command Palette actions: **Smart Explorer: Open**, **Focus search**, **Reveal active file**, **New note**, **New folder**

## Compatibility
Expand Down
5 changes: 5 additions & 0 deletions docs/release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
- [ ] Changelog / release notes drafted
- [ ] No network requests in codebase (`grep -rn "fetch\|XMLHttpRequest" src/`)
- [ ] Vault writes are limited to explicit create-note/create-folder actions and plugin settings
- [ ] Large-vault check (optional but recommended before perf-touching releases):
- [ ] Create the synthetic fixture: `node scripts/prepare-large-vault-fixture.mjs --vault <test-vault> --files 5000`
- [ ] Closed tree shows folder summaries only; flat list stays smooth and bounded
- [ ] Remove the fixture afterwards: `node scripts/prepare-large-vault-fixture.mjs --vault <test-vault> --remove`; confirm the vault is otherwise untouched
- [ ] Plugin tested in Obsidian vault:
- [ ] Loads without console errors
- [ ] File list displays correctly
Expand All @@ -17,6 +21,7 @@
- [ ] New note and new folder actions create items in the expected folder
- [ ] Collapse all and reveal active file work in tree mode
- [ ] Manual drag handles and undo work in Manual sort mode
- [ ] Keyboard navigation works: Tab enters once, arrows move, ArrowRight/Left open/close folders, Enter opens files, Alt+Arrow reorders in Manual mode
- [ ] Settings persist after reload
- [ ] Vault events (create/delete/rename/modify) trigger reindex

Expand Down