Navigate a directory full of directories, identifying repos and worktrees
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

add sort/filter/date ticket, reorganize README into implemented/planned option tables

rektide d0e33890 c8301b59

+64 -33
+2 -1
.beads/issues.jsonl
··· 1 - {"id":"is-tree-scan-priority","title":"Prioritized directory scanning: stream recently-changed projects first","description":"Currently is-tree processes directories in filesystem order and sorts after all results are collected. For large directory trees, this means waiting for the full scan before seeing the most relevant results.\n\nThis ticket tracks adding **scan priority** — deciding which directories to process first based on cheap heuristics, so the most interesting projects stream to screen immediately.\n\nKey aspects:\n\n1. **Pre-scan heuristics** — Use cheap filesystem metadata (mtime of the directory itself, presence of recent changes) to order the work queue before the heavier detection/formatting runs. `change-date` (file mtime) is essentially free from `stat` and correlates well with \"what am I working on.\"\n\n2. **Streaming output** — Emit results as each directory is processed, in priority order, rather than buffering everything. Combined with pre-scan ordering, the user sees their most-recently-worked-on projects first.\n\n3. **Atuin session priority** — Integrate with atuin session data (see is-tree-atuin-session-tracking) to boost directories associated with active sessions to the top of the scan queue.\n\n4. **Pre-filtering** — Allow filtering the scan set before processing (e.g. only scan directories modified in the last N days, or only directories with active sessions). This reduces total work for large trees.\n\n5. **New sort columns** — Add any additional sortable columns needed to support priority-aware output (e.g. session recency, directory mtime as a first-class column).","acceptance_criteria":"- Add `--scan` mode that performs lightweight discovery/classification only (`git`, `jj`, `worktree-git`, `worktree-jj`) without resolving expensive inspection columns.\n- `--scan` output streams line-by-line as candidates are found; users see early results before the full scan completes.\n- Default `--scan` output is one directory path per line (pipeline-safe), suitable for pickers and downstream commands.\n- Scan priority ordering still applies (recently changed first by default), and pre-filtering can reduce scan set.\n- Selected paths can flow back into deep inspection through stdin (`is-tree --scan | ... | is-tree --stdin --format all`, or equivalent auto-detected piped stdin behavior).\n- Existing non-scan behavior and explicit `--sort` post-processing remain compatible.","status":"open","priority":1,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T22:51:14Z","created_by":"rektide de la faye","updated_at":"2026-04-06T23:06:31Z","labels":["performance","streaming"],"dependency_count":0,"dependent_count":0,"comment_count":0} 1 + {"id":"is-tree-sort-filter-date","title":"implement --sort, --filter, and --date flags","description":"## Overview\n\nis-tree needs `--sort`, `--filter`, and `--date` flags to control output ordering, filtering, and date formatting. These are currently documented in the README as aspirational features — this ticket tracks implementing them.\n\n## `--sort \u003ccolumn\u003e`\n\nSort output by one or more columns:\n- Multiple columns comma-separated\n- Suffix `+` for ascending, `-` for descending\n- Example: `--sort change-date-` (most recent first)\n- Example: `--sort status-,directory+`\n\nRequires sortable columns to be collected before output. For streaming mode (see `is-tree-scan-priority`), sort conflicts with streaming — when `--sort` is used, output must be buffered until all rows are collected. Without `--sort`, streaming is possible.\n\nColumns that should be sortable:\n- `status`, `directory`, `workparent`, `variant` (string)\n- `commit-date`, `change-date` (temporal)\n- `ahead` (numeric)\n\n## `--filter \u003ctype\u003e`\n\nFilter results by status type:\n- Comma-separated types: `git`, `jj`, `worktree`, `worktree-git`, `worktree-jj`\n- Suffix `-` for NOT: `git-` means \"not git\", `jj-` means \"not jj\"\n- Examples:\n - `--filter git` — only git repos\n - `--filter git,jj` — git or jj repos (exclude `none`)\n - `--filter worktree-` — exclude all worktrees\n\nUnlike `--sort`, filtering can happen early — skip detection work for excluded types. For scan-priority integration, pre-filtering reduces the work set.\n\n## `--date \u003cformat\u003e`\n\nDate format string using strftime-style patterns:\n- Default: ISO 8601\n- Example: `--date \"%Y-%m-%d %H:%M:%S\"`\n- Applied to `commit-date` and `change-date` columns\n- For the planned `duration`/`age` column (is-tree-duration-column), this would be ignored in favor of relative time formatting\n\n## Connection to scan priority (`is-tree-scan-priority`)\n\nSorting and scanning are deeply connected:\n\n1. **Without `--sort`**: streaming output is possible. Scan-priority determines emission order. Results appear as they're processed.\n2. **With `--sort`**: output must be buffered. But scan-priority still determines *processing order* — sort the final output after processing, but process the most relevant directories first so interactive users see early results even before sort completes.\n3. **Pre-filtering** reduces work. If `--filter jj` is set, skip git-only and bare directories during scan, not just in output.\n4. **Both at once**: `is-tree --all --filter jj --sort change-date-` should pre-filter to only jj trees during scan, process them in mtime-priority order, then output sorted by change-date descending.\n\n## Dependencies\n\n- Relates to `is-tree-scan-priority` — sort/filter/scan-priority need a unified design for how they interact during the processing pipeline.","status":"open","priority":1,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T23:11:10Z","created_by":"rektide de la faye","updated_at":"2026-04-06T23:11:10Z","labels":["date","filter","output","sort"],"dependency_count":0,"dependent_count":0,"comment_count":0} 2 + {"id":"is-tree-scan-priority","title":"Prioritized directory scanning: stream recently-changed projects first","description":"Currently is-tree processes directories in filesystem order and sorts after all results are collected. For large directory trees, this means waiting for the full scan before seeing the most relevant results.\n\nThis ticket tracks adding **scan priority** — deciding which directories to process first based on cheap heuristics, so the most interesting projects stream to screen immediately.\n\nKey aspects:\n\n1. **Pre-scan heuristics** — Use cheap filesystem metadata (mtime of the directory itself, presence of recent changes) to order the work queue before the heavier detection/formatting runs. `change-date` (file mtime) is essentially free from `stat` and correlates well with \"what am I working on.\"\n\n2. **Streaming output** — Emit results as each directory is processed, in priority order, rather than buffering everything. Combined with pre-scan ordering, the user sees their most-recently-worked-on projects first.\n\n3. **Atuin session priority** — Integrate with atuin session data (see is-tree-atuin-session-tracking) to boost directories associated with active sessions to the top of the scan queue.\n\n4. **Pre-filtering** — Allow filtering the scan set before processing (e.g. only scan directories modified in the last N days, or only directories with active sessions). This reduces total work for large trees.\n\n5. **New sort columns** — Add any additional sortable columns needed to support priority-aware output (e.g. session recency, directory mtime as a first-class column).","acceptance_criteria":"- Add `--scan` mode that performs lightweight discovery/classification only (`git`, `jj`, `worktree-git`, `worktree-jj`) without resolving expensive inspection columns.\n- `--scan` output streams line-by-line as candidates are found; users see early results before the full scan completes.\n- Default `--scan` output is one directory path per line (pipeline-safe), suitable for pickers and downstream commands.\n- Scan priority ordering still applies (recently changed first by default), and pre-filtering can reduce scan set.\n- Selected paths can flow back into deep inspection through stdin (`is-tree --scan | ... | is-tree --stdin --format all`, or equivalent auto-detected piped stdin behavior).\n- Existing non-scan behavior and explicit `--sort` post-processing remain compatible.","status":"open","priority":1,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T22:51:14Z","created_by":"rektide de la faye","updated_at":"2026-04-06T23:06:31Z","labels":["performance","streaming"],"dependencies":[{"issue_id":"is-tree-scan-priority","depends_on_id":"is-tree-sort-filter-date","type":"related","created_at":"2026-04-06T19:11:13Z","created_by":"rektide de la faye","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0} 2 3 {"id":"is-tree-reforrest-starter","title":"scaffold reforrest project with gunshi-style CLI","description":"## Overview\n\nScaffold a new Rust project for `reforrest` as a separate crate, using `gunshi`-style CLI conventions. This is a prerequisite workspace setup ticket before implementing the actual push logic.\n\n## What it does\n\n- Create a new crate (e.g. `reforrest/` directory or workspace member) in the is-tree workspace.\n- Wire up `clap` derive CLI with initial subcommand structure:\n - `reforrest push [path]` — discover and push trees\n - `reforrest status [path]` — show what would be pushed (dry-run default)\n - `reforrest ensure-remote [path]` — create missing remotes via forge CLIs\n- Depend on `is-tree` as a library crate for tree detection/classification.\n- Basic `--dry-run`, `--json`, `--verbose` flags wired but not yet functional.\n- Skeleton `main.rs` with subcommand dispatch.\n\n## Key considerations\n\n- May require splitting is-tree into a lib+bin crate so reforrest can import detection logic.\n- Follow existing workspace conventions (Cargo.toml workspace, clap derive, tokio async).\n\n## Dependencies\n\n- This is a dependency of is-tree-reforrest-cli (the epic).","status":"open","priority":1,"issue_type":"task","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T21:21:33Z","created_by":"rektide de la faye","updated_at":"2026-04-06T21:21:33Z","labels":["cli","gunshi","scaffold"],"dependency_count":0,"dependent_count":0,"comment_count":0} 3 4 {"id":"is-tree-reforrest-cli","title":"reforrest: replicate local git and jj states to remotes","description":"## Overview\n\nCreate a `reforrest` CLI tool (Rust binary in this workspace) that discovers all local git/jj trees using is-tree's detection logic and pushes their local state up to tracked remotes — effectively \"making the trees flow out to far places.\"\n\n## What it does\n\nGiven a root directory (e.g. `~/src`), `reforrest`:\n\n1. **Discovers** all git and jj repositories/worktrees beneath the given path (leveraging is-tree's existing classification logic for `git`, `jj`, `worktree-git`, `worktree-jj`).\n2. **Inspects** each tree's local state relative to its tracked remote(s):\n - For jj repos: local bookmarks ahead of remote bookmarks, unpushed changes.\n - For git repos: local branches ahead of remote tracking branches.\n3. **Replicates** (pushes) local state up to remotes:\n - `jj git push --all` for jj trees.\n - `git push --all` for git trees.\n4. **Reports** a summary of what was pushed, what was skipped (up-to-date), and what failed (e.g. no remote configured, auth issues).\n\n## Architecture\n\n- New binary target `reforrest` in the existing `is-tree` Cargo workspace.\n- Reuse is-tree's detection/classification module as a library dependency.\n- Async push operations across discovered trees using tokio (already a dep).\n\n## Key considerations\n\n- Should be idempotent — safe to run repeatedly, no-ops when already synced.\n- Must handle mixed trees (some jj, some git, some worktrees) gracefully.\n- Worktrees: push from the main tree location, skip worktrees to avoid duplicate pushes.\n- Error handling: collect per-tree results, don't let one failure stop the rest. Report aggregate at end.\n- Respect `.gitignore`-style exclusions or a config for paths to skip.\n\n## Acceptance criteria\n\n- [ ] `reforrest ~/src` discovers all trees, classifies them, and pushes ahead state to remotes\n- [ ] Summary output shows pushed / up-to-date / failed / skipped counts per tree\n- [ ] Handles jj repos, git repos, and worktrees correctly\n- [ ] Worktrees are deduplicated (push happens from main tree only)\n- [ ] Individual tree failures don't abort the batch; errors are collected and reported\n- [ ] `--dry-run` flag shows what would be pushed without actually pushing\n- [ ] `--json` flag for machine-readable output","status":"open","priority":1,"issue_type":"epic","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T21:11:32Z","created_by":"rektide de la faye","updated_at":"2026-04-06T21:11:32Z","labels":["cli","push","replication"],"dependency_count":0,"dependent_count":0,"comment_count":0} 4 5 {"id":"is-tree-atuin-session-tracking","title":"Atuin session tracking: find which sessions last cd'ed into each directory","description":"Track which atuin sessions last cd'ed into each directory, leveraging ATUIN_SESSION to correlate shell sessions with directory changes. This enables answering \"which session am I in that project from?\" and \"which session was last working here?\" across the is-tree project listing.\n\nThree integration layers:\n\n1. **Query atuin DB directly** — Read the atuin SQLite DB (~/.local/share/atuin/history.db or equivalent) to find `cd` commands grouped by session (ATUIN_SESSION). Map session IDs to the directories they last visited. This is the data foundation.\n\n2. **Shell hook / env integration** — Use ATUIN_SESSION env var at runtime to associate the current shell session with the working directory. Could be a hook that records session→directory mappings, or reads them on-demand from atuin history keyed by session.\n\n3. **New CLI subcommand** — Add an is-tree subcommand (e.g. `is-tree sessions` or integrated into `--all` output) that reports per-directory session info from atuin history. Show which session last cd'ed into each tree, when, and potentially the session's current/last-known directory.","acceptance_criteria":"- Can query atuin history DB for cd commands grouped by ATUIN_SESSION\n- Shell hook or integration surface exists to resolve current session's directory from ATUIN_SESSION\n- New subcommand or column shows session info alongside is-tree directory listings\n- Works with both git and jj trees","status":"open","priority":2,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T22:29:20Z","created_by":"rektide de la faye","updated_at":"2026-04-06T22:29:20Z","labels":["atuin","session-tracking"],"dependency_count":0,"dependent_count":0,"comment_count":0}
+62 -32
README.md
··· 11 11 # Test all directories in current path with --all/-a 12 12 is-tree --all 13 13 14 - # Filter for specific types (comma-separated, - for NOT) 15 - is-tree --all --filter git 16 - is-tree --all --filter git,jj 17 - is-tree --all --filter worktree-git,worktree-jj 18 - is-tree --all --filter worktree- 19 - is-tree --all --filter git-,jj 20 - 21 14 # Test specific directories by positional arguments 22 15 is-tree ~/src/compfuzor ~/src/niri-mcp 23 16 24 - # Sort by any column (use + for ascending, - for descending) 25 - is-tree --all --sort change-date- 26 - is-tree --all --sort commit-date+ 27 - is-tree --all --sort workparent,directory+ 28 - 29 - # Multiple sorts (comma-separated) 30 - is-tree --all --sort status-,change-date+ 31 - 32 17 # Custom output format with interpolated columns 33 - is-tree --all --format "{status} {directory} {commit-date} {change-date} {workparent}" 34 18 is-tree --all --format "{status} {directory} {ahead}" 35 19 is-tree --all --format all 36 20 21 + # Enable jj plugin columns 22 + is-tree --all --jj 23 + 37 24 # Output as JSON (respects --format for column selection) 38 25 is-tree --all --json 39 26 is-tree --all --format "{status} {directory} {ahead}" --json 40 27 28 + # Header row with custom separator 29 + is-tree --all --header --separator " | " 30 + ``` 31 + 32 + ### Planned usage (not yet implemented) 33 + 34 + ```bash 35 + # Filter for specific types (comma-separated, - for NOT) 36 + is-tree --all --filter git 37 + is-tree --all --filter git,jj 38 + is-tree --all --filter worktree- 39 + is-tree --all --filter git-,jj 40 + 41 + # Sort by any column (use + for ascending, - for descending) 42 + is-tree --all --sort change-date- 43 + is-tree --all --sort workparent,directory+ 44 + 41 45 # Custom date format 42 46 is-tree --all --date "%Y-%m-%d %H:%M:%S" 43 47 ``` 44 48 45 49 ## Options 46 50 47 - - `--all`, `-a` - Test all directories in current path 48 - - `--filter <type>` - Filter by type(s). Multiple types comma-separated. Suffix `-` for NOT. Types: `git`, `jj`, `worktree`, `worktree-git`, `worktree-jj` 49 - - `--sort <column>` - Sort by column(s). Multiple columns comma-separated. Suffix `+` for ascending, `-` for descending 50 - - `--format <string>` - Custom output format with interpolated columns 51 - - Shortcut: `--format all` includes all available columns 52 - - `--date <format>` - Date format string (default: ISO 8601) 53 - - `--json` - Output results in JSON format 54 - - Positional arguments - Test specific directories 51 + ### Implemented 52 + 53 + | Flag | Description | 54 + |------|-------------| 55 + | `--all`, `-a` | Scan all non-hidden subdirectories in current directory | 56 + | `--format <template>` | Output format with `{column}` placeholders; `all` for every column | 57 + | `--json` | Output as JSON array (respects `--format` for column selection) | 58 + | `--header` | Print a header row above text output | 59 + | `--separator <string>` | Replace spaces between columns in text output (default: single space) | 60 + | `--plugins <ids>` | Comma-separated plugin ids to run (default: all) | 61 + | `--microbatch-rows <n>` | Max row patches per streaming microbatch (default: 64) | 62 + | `--jj` | Enable jj plugin columns (equivalent to requesting all jj columns) | 63 + | `--jj-ahead` | Enable the `ahead` column | 64 + | `<directories>` | Positional paths to inspect | 65 + 66 + ### Not yet implemented 67 + 68 + | Flag | Description | Ticket | 69 + |------|-------------|--------| 70 + | `--filter <type>` | Filter by repo type: `git`, `jj`, `worktree`, `worktree-git`, `worktree-jj`. Suffix `-` for NOT | [is-tree-sort-filter-date] | 71 + | `--sort <column>` | Sort by column(s). Suffix `+` ascending, `-` descending | [is-tree-sort-filter-date] | 72 + | `--date <format>` | strftime-style date format (default: ISO 8601) | [is-tree-sort-filter-date] | 55 73 56 74 ## Output 57 75 58 76 Default format: `<status> <directory>` 59 77 60 78 ### Columns 61 - Available columns for custom format: 62 - - `status` - Repository type (git, jj, worktree-git, worktree-jj, none) 63 - - `directory` - Full directory path 64 - - `workparent` - Directory name of the workparent (without path), for worktrees only 65 - - `commit-date` - Most recent commit date 66 - - `change-date` - Most recent file change date 67 - - `ahead` - Number of local JJ commits ahead of tracked remote bookmarks 79 + 80 + Available columns for `--format`: 81 + 82 + **Implemented:** 83 + 84 + | Column | Description | Source | 85 + |--------|-------------|--------| 86 + | `status` | Repository type (git, jj, worktree-git, worktree-jj, none) | core | 87 + | `directory` | Full directory path | core | 88 + | `ahead` | Local JJ commits ahead of tracked remote bookmarks | `--jj` / `--jj-ahead` | 89 + 90 + **Not yet implemented:** 91 + 92 + | Column | Description | Ticket | 93 + |--------|-------------|--------| 94 + | `workparent` | Directory name of the workparent (worktrees only) | [is-tree-sort-filter-date] | 95 + | `commit-date` | Most recent commit date | [is-tree-sort-filter-date] | 96 + | `change-date` | Most recent file change date | [is-tree-sort-filter-date] | 68 97 69 98 ### Status values 70 99 - `git` - Git repository (not Jujutsu, not a worktree) ··· 128 157 129 158 ### Interaction & workflows 130 159 160 + - **[is-tree-sort-filter-date]** `--sort`, `--filter`, `--date` flags for controlling output ordering, type filtering, and date formatting. 161 + - **[is-tree-scan-priority]** Stream recently-changed projects first during scans. 131 162 - **[is-tree-interactive-picker]** Built-in TUI picker with fuzzy search and multi-select for choosing trees. 132 163 - **[is-tree-fuzzel-pipeline]** Documented example pipeline: `is-tree --all --format "{directory}" | fuzzel --dmenu --multi`. 133 - - **[is-tree-scan-priority]** Stream recently-changed projects first during scans. 134 164 - **[is-tree-semantic-search]** Semantic search across trees via opencode run / ACP.