recent-project-checker
v0.1.0
Published
Estimate recently used projects from shell history and show restart-ready candidates.
Downloads
17
Maintainers
Readme
recent-project-checker

Estimate recently used projects from shell history and show a ranked list to quickly resume work.
日本語版 README はこちら (README.ja.md)
Install
Try without installing:
npx recent-project-checker --root ~/projectsOr install globally:
npm install -g recent-project-checkerThe package registers two commands: recent-project-checker and the shorter alias recent-projects.
Quick Start
# Ranked list of recent projects (text output)
recent-project-checker --root ~/projects
# Sort by how many times each project was accessed
recent-project-checker --root ~/projects --sort count
# Open the local Web UI in your browser
recent-project-checker --root ~/projects --web --openFeatures
- Infers project roots under
--rootusing the<root>/<project>/...structure - Extracts candidate paths from shell commands:
cd,pushd,git -C,git clone,make -C,docker compose -f,npm/pnpm/yarn --prefix|--cwd, and editor launchers - Detects newly created projects from
mkdir <dir> -> cd <dir> -> git initflows - Ranks candidates by a combined frequency + recency score
- Supports sorting by
score,count,recent, andtimeline - Outputs text or structured JSON (
--format text|json) - Built-in local Web UI (
--web/--ui) with filtering and live re-aggregation - Filters by minimum occurrences (
--min-count) and date range (--days)
Usage
Options
| Option | Description | Default |
|---|---|---|
| --root <path> | Required. Root directory containing project directories. | — |
| --days <n> | Number of days of history to consider. | 60 |
| --limit <n> | Maximum number of results to show. | 100 |
| --max-results <n> | Alias for --limit. | 100 |
| --min-count <n> | Minimum times a candidate must appear. | 1 |
| --history <mode> | History source: auto, zsh, bash, or file. | auto |
| --file <path> | Path to history file (required when --history file). | — |
| --format <mode> | Output format: text or json. | text |
| --sort <mode> | Sort mode: score, count, recent, or timeline. | score |
| --web, --ui | Start local Web UI after analysis. | — |
| --host <host> | Host for the web server. | 127.0.0.1 |
| --port <n> | Port for the web server. | 4173 |
| --allow-remote | Allow non-loopback host (requires --token). | — |
| --token <value> | Access token for Web UI/API when remote. | — |
| --open | Open browser automatically. | — |
| --no-open | Do not open browser automatically. | (default) |
| --help, -h | Show help. | — |
Examples
# Narrow to last 90 days, show top 40
recent-project-checker --root ~/projects --days 90 --limit 40
# Read a specific history file and output JSON
recent-project-checker --root ~/projects --history file --file /path/to/.zsh_history --format json
# Only show projects accessed 2+ times
recent-project-checker --root /work/projects --min-count 2
# Web UI sorted by most recent access
recent-project-checker --root ~/projects --sort recent --web
# Expose Web UI to LAN (token required)
recent-project-checker --root ~/projects --web --host 0.0.0.0 --allow-remote --token 'your-token'
# Then enter the token in the Web UI token fieldWeb UI (--web / --ui)
recent-project-checker --root ~/projects --web- Starts a local HTTP server at
http://127.0.0.1:4173(browser is not opened by default; use--opento auto-launch). - Filter input to quickly narrow project names.
- Adjust
days,limit,min-count, andsortin the UI, then re-aggregate on the fly. - Click copy to copy
cd "<repo-path>"to the clipboard. - If the port is busy, specify another with
--port. - This feature is primarily intended for localhost use.
- For non-loopback hosts, use
--allow-remote --token <value>, then enter the token in the UI token field. - Remote mode serves plain HTTP; use only trusted networks or place it behind HTTPS/TLS.
- For API clients, send token via
x-rpc-tokenorAuthorization: Bearer <token>header.
How it works
Root structure
recent-project-checker assumes repositories live under:
<root>/<project>/...For example:
/workspace/cli-tool/src-> project root is/workspace/cli-toolmkdir my-new-app && cd my-new-app && git initalso registers the new directory as a candidate under--root.
Processing pipeline
- Load history files (
~/.zsh_historyand~/.bash_historywhen--history auto). - Parse each command and extract relevant paths.
- Keep only paths under
--rootand normalize to the project level. - Add candidates from
mkdir -> cd -> git initflows. - Aggregate
countand latest access time per project. - Calculate score and sort.
Path decision rules
- Candidate paths are extracted from path-bearing commands only:
cd,pushd,git -C,git clone,make -C,docker compose -f,npm/pnpm/yarn --prefix|--cwd, and editor launchers (code,vim,nvim,open,cursor,subl). --sort recentonly changes ordering. A directory must first pass extraction and filtering to appear in results.- Paths outside
--rootare excluded. - Normal command-derived paths are normalized to
<root>/<first-segment-under-root>. - For
mkdir <dir> -> cd <dir> -> git init, the initialized directory itself is preserved as a candidate (including nested paths under--root).
Simulated cwd tracking
For each history file, this tool tracks a simulated cwd while scanning commands in order.
- Initial
cwdis--root. cdupdates simulatedcwdwith shell-like semantics:cdorcd --->$HOMEcd --> previouscwdcd <relative|absolute>-> resolved path
pushd <path>also updates simulatedcwd.- Safety guard: the simulated
cwdis updated only when destination is an existing directory, or a directory created earlier in the same history stream (mkdirtracking).
Scoring
score = log2(1 + count) + recency
recency = max(0, 1.2 - elapsedDays / 30)zsh history timestamps are used when present.
For bash entries without timestamps, a positional fallback estimation is used so that --days filtering still works.
JSON output (--format json)
{
"generatedAt": "2026-02-13T00:00:00.000Z",
"options": {
"root": "...",
"historyFiles": ["..."],
"days": 60,
"minCount": 1,
"limit": 100,
"sort": "score",
"format": "json",
"version": "0.1.0"
},
"results": [
{
"repo": "/path/to/root/owner/repo",
"count": 3,
"last": {
"unix": 1700000000,
"iso": "2024-11-14T22:13:20.000Z"
},
"score": 4.2
}
]
}Troubleshooting
- Few or no
cdcommands are detected Increase--daysor specify another history file with--history file --file <path>. - No timestamps in
bashhistory Use the zsh history source if available, or increase--days. --rootpath structure does not follow<root>/<project>Adjust--rootor your repository layout.- Output differs between text and JSON Ranking logic is the same; only the presentation format differs.
Requirements
- Node.js >= 18
- macOS / Linux (Windows is not a primary target, but path handling degrades safely)
Development
Run from source (without installing):
node src/cli.js --root ~/projectsInstall locally from the repo:
npm install -g .Testing
npm testTest suite includes:
- Unit tests (20+ cases):
parseZshLine,extractDirsFromCmd,toRepoRoot, scoring, arg parsing - End-to-end tests (2+ cases): text output, JSON output
Lint & Format
npm run lint
npm run format--rootis always required — no default root is assumed to avoid environment-specific assumptions and accidental misdetection.- Alternative: hardcode a default like
~/workspace, but the risk of false positives is too high.
- Alternative: hardcode a default like
--max-resultsas an alias for--limit— keeps compatibility while avoiding option duplication.- Alternative: drop one of them, but that could break existing invocations.
- Positional fallback for
bashtimestamps — whenbashhistory has no timestamps, line position is used as a rough estimate.- Alternative: shell-level trace parsing for better precision, but the complexity cost is not justified at this stage.
- This is a restart-assistance tool, not a full restoration mechanism. Dependencies are intentionally minimal.
License
MIT
