Skip to content

feat(cli): skillforge tree <dir> — pre-pack file preview - #16

Merged
adityachilka1 merged 1 commit into
mainfrom
feat/tree
May 25, 2026
Merged

feat(cli): skillforge tree <dir> — pre-pack file preview#16
adityachilka1 merged 1 commit into
mainfrom
feat/tree

Conversation

@adityachilka1

Copy link
Copy Markdown
Owner

What

skillforge tree <dir> — preview the file inventory a pack would produce, without actually building the archive. Tenth piece of the authoring workflow after init, validate, lint, pack, install, update, format, inspect, and diff. Where pack builds and inspect reads a single skill end-to-end, tree is a one-shot pre-flight: walk the directory using the same exclusion logic pack uses, return a tidy file listing with sizes.

# Human-readable mode
skillforge tree ./code-review
# /…/code-review
# ├──   312 B  SKILL.md
# ├──            templates/
# │   └──   24 B  letter.md
# └──   12 B  tool.py
#
# 3 files · 348 B

# Machine-readable mode for CI
skillforge tree ./code-review --sort size --json

Why

When authoring a skill, users often want a sanity-check of "what would pack include?" without actually building the archive. Today they have to either run pack and unzip the result, or eyeball ls -R and hope the exclusion rules don't bite them. tree is a one-shot preview: same walk, same exclusions, with byte sizes and a totals line — no archive churn.

Result shape

interface TreeResult {
  srcDir: string;
  entries: Array<{ path: string; size: number; isDir: boolean }>;
  totalFiles: number;
  totalBytes: number;
}

Semantics

Aspect Behaviour
Input A directory. Errors if the path is missing or is a file.
Exclusions Reuses shouldExcludeEntry exported from pack.ts.git, node_modules, .DS_Store, hidden files, *.log. Zero duplicated logic, no chance of drift between tree and pack.
Paths Relative to srcDir, POSIX separators (/), never backslashes — same convention as inspect.attachedFiles.
Sort: path (default) Stable byte-order sort; siblings stay grouped under their parent directory. Deterministic across machines (no locale dependence).
Sort: size Files only, descending by byte size. Directory entries drop out — their reported "size" is filesystem bookkeeping, not skill content.
totalFiles / totalBytes Counts and sums file entries only, even under path sort where directories appear in the listing.
Symlinks / sockets / FIFOs Skipped, same as pack.
Side effects None — tree never writes.

CLI output taste

  • Bold directory header — quiet anchor.
  • Box-drawing tree (├── / └──, 2-space indent per level, continuation lines) for unambiguous hierarchy.
  • Right-aligned size column (bytes under 1 KB, KB with one decimal otherwise) — tabular-nums alignment in spirit.
  • Cyan directories with a trailing / so the eye can distinguish "this is a folder" at a glance.
  • One-line totals footer: N files · X.Y KB, dim — matches the inspect summary aesthetic.
  • --json emits the full TreeResult for CI / scripted reviewers.

Surface

  • src/tree.tstreeSkill() plus internal walker. ~120 LOC. No new runtime deps; the walker is the same shape as inspect.ts's, just collecting size + isDir instead of path-only.
  • src/tree.test.ts — 8 tests: happy path with exclusions matching pack (.git, node_modules, .DS_Store, debug.log all excluded), empty-ish dir → 1 entry, both sort modes verified, total-bytes accuracy, path-not-found and non-directory error paths, entry-shape contract (POSIX paths, correct isDir). macOS /tmp trap handled with realpathSync(await mkdtemp(...)) in beforeEach.
  • src/cli.ts — new tree subcommand with --json and --sort <path|size> flags, plus the printTreeReport() formatter.
  • src/index.ts — re-exports the new public types.
  • README.md — new tree section; status line updated.
  • CHANGELOG.mdUnreleased entry.
  • No changes to pack.ts. shouldExcludeEntry was already exported (PR feat(cli): skillforge inspect <path> — one-shot validation + lint + summary #14 added the export for inspect); tree reuses it as-is.

Gates

Check Status
pnpm install no drift
tsc --noEmit clean
biome check src (--fix --unsafe) clean
vitest run 136/136 pass (8 new + 128 existing)
tsup build ESM + DTS build success
Smoke: scaffold a dir with templates/, tool.py, .DS_Store, debug.log, node_modules/, run ./dist/cli.js tree … excludes correctly, prints tidy tree with sizes
Smoke: same dir with --sort size --json well-formed JSON, files only, descending by size

On tree vs pack / inspect

pack builds the archive. inspect reads a single skill (validation + lint + body + file list). tree previews what pack would do, with byte sizes. The three compose: tree to spot heavy fixtures, inspect to read the skill, pack to ship it. Each does one thing.

Don't refactor

No changes to pack.ts / inspect.ts / format.ts / lint.ts. No new runtime deps. shouldExcludeEntry reused as-is.

Declaration of AI-Tools / LLMs usage

  • Claude (Opus) for design, implementation, tests, commit message, this PR body — reviewed by @adityachilka1 before push.

@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@adityachilka1, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 51 minutes and 39 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1ceaeb10-e6b7-48d9-bbfa-2bc71059781a

📥 Commits

Reviewing files that changed from the base of the PR and between aea7423 and 4013946.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • README.md
  • src/cli.ts
  • src/index.ts
  • src/tree.test.ts
  • src/tree.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tree

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adityachilka1
adityachilka1 merged commit 5db74b7 into main May 25, 2026
4 checks passed
@adityachilka1
adityachilka1 deleted the feat/tree branch May 25, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants