···11{"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}
22{"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}
33+{"id":"is-tree-interactive-picker","title":"interactive TUI picker for selecting trees","description":"## Overview\n\nAdd an interactive picker mode to is-tree that lets users select one or more trees from a searchable, navigable TUI list — then execute an action on the selection(s). This makes is-tree a launcher/hub for working with discovered trees.\n\n## What it does\n\n- New flag: `--pick` or `--interactive` launches a terminal UI picker.\n- Displays all discovered trees with key columns (status, directory, age, ahead).\n- Fuzzy search/filter to narrow the list by directory name or path.\n- Multi-select support (e.g. space to toggle, enter to confirm).\n- On selection, either:\n - Print the selected path(s) to stdout (pipe-friendly).\n - Execute a configurable command against each selection (e.g. `cd`, `jj status`, `git log`).\n- Keyboard navigation: up/down, page up/down, tab, enter, escape to cancel.\n\n## Key considerations\n\n- Should work as a composable Unix tool: `is-tree --all --pick | xargs -I{} ...`\n- Consider using a Rust TUI picker library (e.g. `gaggle`, `skim`, `dialoguer`, or custom with `crossterm`).\n- Falls back gracefully if no interactive terminal is detected (error or just print list).\n- Should respect existing `--filter`, `--sort` flags to pre-filter before picking.\n- Natural integration point for `reforrest`: `is-tree --all --pick | reforrest push`","status":"open","priority":2,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T21:32:54Z","created_by":"rektide de la faye","updated_at":"2026-04-06T21:32:54Z","labels":["interactive","picker","tui"],"dependency_count":0,"dependent_count":0,"comment_count":0}
34{"id":"is-tree-staleness-views","title":"improve staleness views across all projects","description":"## Overview\n\nCreate a cohesive \"staleness view\" for is-tree that helps answer the question: \"which of my projects are gathering dust?\" This combines and builds on the duration column and per-file stats features into a unified staleness reporting experience.\n\n## What it does\n\n- A `--stale` or `stale` subcommand that produces a staleness-oriented view of all trees.\n- Tree-level staleness: overall age since last change/commit, with color coding or indicators (e.g. `●` fresh, `◐` aging, `○` stale).\n- Configurable thresholds: `--stale-threshold 30d` marks trees older than 30 days as stale.\n- Summary statistics: count of fresh/aging/stale trees, median age, oldest tree.\n- Integration with per-file stats: `is-tree --stale --files` to drill into stale trees.\n- Sort defaults to age descending (stalest first).\n\n## Key considerations\n\n- Should work well with existing `--filter`, `--sort`, `--format`, `--json` flags.\n- Color/styling should be optional (respects `--no-color` or `TERM=dumb`).\n- Depends on is-tree-duration-column for age data.\n- Optionally depends on is-tree-per-file-stats for drill-down.\n\n## Dependencies\n\n- is-tree-duration-column\n- is-tree-per-file-stats (optional, for file-level drill-down)","status":"open","priority":2,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T21:22:01Z","created_by":"rektide de la faye","updated_at":"2026-04-06T21:22:01Z","labels":["reporting","staleness","ux"],"dependencies":[{"issue_id":"is-tree-staleness-views","depends_on_id":"is-tree-duration-column","type":"blocks","created_at":"2026-04-06T17:22:00Z","created_by":"rektide de la faye","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
45{"id":"is-tree-per-file-stats","title":"recurse into trees and report per-file stats (age, modified, size)","description":"## Overview\n\nAdd a recursive per-file stats mode to is-tree that descends into each tree and reports modification metadata for individual files — enabling granular staleness views like \"which files haven't been touched in 6 months.\"\n\n## What it does\n\n- New flag: `--files` or `--per-file` that makes is-tree recurse into each discovered tree.\n- Per-file output columns:\n - `file` — relative path within the tree\n - `modified` — last modification timestamp\n - `age` — duration since last modification (relative time)\n - `size` — file size in bytes\n- Respect `.gitignore` / `.jjignore` by default (skip ignored files).\n- Option to filter/sort by age threshold: `--older-than 30d`, `--newer-than 1w`.\n- Output formats: table (default), JSON (`--json`).\n\n## Key considerations\n\n- Could be expensive on large repos — should stream or batch results.\n- May want to limit recursion depth with `--depth`.\n- `.git` / `.jj` internal directories should be excluded.\n- Useful for identifying dead code, stale configs, abandoned files.\n- Feeds into the staleness views ticket (is-tree-staleness-views).","status":"open","priority":2,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T21:21:52Z","created_by":"rektide de la faye","updated_at":"2026-04-06T21:21:52Z","labels":["per-file","recursion","staleness"],"dependency_count":0,"dependent_count":0,"comment_count":0}
56{"id":"is-tree-duration-column","title":"add duration/age column showing time since last change","description":"## Overview\n\nAdd a `duration` or `age` column to is-tree output that shows how long since each tree's last change — e.g. `2h`, `3d`, `6w`. This gives an at-a-glance view of staleness across all trees.\n\n## What it does\n\n- New column: `age` or `duration` — human-readable relative time since `change-date`.\n- Uses the existing `change-date` data already collected per tree.\n- Format: compact relative time (`2h`, `3d`, `6w`, `1y`) with configurable granularity.\n- Available in `--format` string interpolation: `{age}`, `{duration}`.\n- Available in `--json` output.\n\n## Key considerations\n\n- Should default to time since `change-date` but could optionally show time since `commit-date`.\n- Relative time formatting should match familiar conventions (like `jj log` relative dates).\n- Useful for the staleness views (see is-tree-staleness-views).","status":"open","priority":2,"issue_type":"feature","owner":"rektide+git@voodoowarez.com","created_at":"2026-04-06T21:21:45Z","created_by":"rektide de la faye","updated_at":"2026-04-06T21:21:45Z","labels":["column","output","staleness"],"dependency_count":0,"dependent_count":1,"comment_count":0}