Skip to content

Release/v0.8.17#56

Merged
Szowesgad merged 25 commits into
mainfrom
release/v0.8.17
Apr 25, 2026
Merged

Release/v0.8.17#56
Szowesgad merged 25 commits into
mainfrom
release/v0.8.17

Conversation

@Szowesgad

Copy link
Copy Markdown
Contributor

This pull request introduces several improvements and refactors to the Makefile, CLI help system, file scanning logic, and documentation for the loctree project. The most notable changes are the restructuring of installation targets, enhancements to cache management commands, improved symlink handling during file scans, and updates to documentation and tests.

Build and Installation Improvements

  • The Makefile installation targets are now split into install, install-cli, and install-mcp, allowing for more granular installation of CLI tools and MCP server. The main install target now also installs git hooks. [1] [2] [3]
  • The quality gate check is enhanced to include a Semgrep security scan, and the previous check target is renamed to precheck.

CLI Help and Cache Management

  • Added a dedicated cache management command to the CLI, including detailed help text and subcommands for listing and cleaning cached project snapshots. [1] [2] [3]

File Scanning and Symlink Handling

  • Improved file scanning logic to prevent following symlinks that escape the scan root, ensuring scans remain within the intended project boundaries. This is achieved by tracking the top-level scan root and comparing symlink targets against it. [1] [2] [3]
  • Root directory normalization now canonicalizes paths, ensuring consistent snapshot caching and analysis. [1] [2]

Documentation Updates

  • The README.md is updated to clarify installation options, highlight loctree's advantages over other tools, and expand the list of available tools. [1] [2] [3]

Test Adjustments

  • Tests are updated to reflect the removal of the audit --stdout flag, now recommending the --json flag for stdout output and verifying its contract.
  • Removed redundant snapshot refresh in tests to avoid stale cache state issues.

Szowesgad and others added 6 commits March 20, 2026 16:24
gather_files() followed symlinks without boundary checking. A symlink
like packaging/dmg/stage/Applications -> /Applications caused the
walker to recurse into the entire macOS Applications directory,
spawning thousands of git check-ignore subprocesses.

Fix: compute scan_root (canonical) once at entry, pass through
recursion via gather_files_inner(). Skip any symlink whose canonical
target falls outside scan_root. Intra-repo symlinks still work.

Fixes #55

Co-Authored-By: Klaudiusz <the1st@whoai.am>
Commands like `loct health` and `loct dead` that trigger auto-rescan
constructed ParsedArgs with Default::default(), which has empty
ignore_patterns. The explicit `loct scan` path loads .loctignore
via detect.rs but auto-rescan did not. Also canonicalizes root path
in load_or_create_snapshot to prevent relative/absolute mismatch.

Part of #55

Co-Authored-By: Klaudiusz <the1st@whoai.am>
normalize_root_dir('.') returned PathBuf('.') without resolving to
absolute path. This caused snapshot root mismatches when comparing
requested roots (relative) against cached roots (absolute).

Part of #55

Co-Authored-By: Klaudiusz <the1st@whoai.am>
loct cache --help returned 'Unknown command' because the help
dispatcher had no entry for 'cache'. Add CACHE_HELP text and
register it in both help lookup and command listing.

Co-Authored-By: Klaudiusz <the1st@whoai.am>
Remove stale snapshot refresh workaround from analyzes_impact test
(no longer needed after auto-rescan fix). Update audit_stdout_flag
test comments to reflect current --json contract.

Co-Authored-By: Klaudiusz <the1st@whoai.am>
Restructure installation and CI checks, and update docs. Makefile: break the monolithic install into install-cli and install-mcp (and call git-hooks from the new install), remove install-all, add clearer install output, and rename/simplify check targets (precheck -> fast cargo check, check -> full quality gate). The full quality gate now runs fmt, clippy, cargo check and an optional semgrep security scan. .gitignore: ignore /reports directory. README: simplify install instructions (one-liner, combined cargo installs, npm option), add a "Why loctree" comparison table and list the new tool `follow`, and clarify tool usage.
@Szowesgad Szowesgad requested a review from m-szymanska March 20, 2026 17:34
@Szowesgad Szowesgad linked an issue Mar 20, 2026 that may be closed by this pull request
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the loctree project by refining its build processes, improving CLI usability, and strengthening file scanning robustness. Users will benefit from more flexible installation options, better control over cached data, and safer, more accurate file scanning. Additionally, developers gain from an improved quality gate that now includes security scanning, ensuring a more robust and secure codebase.

Highlights

  • Build and Installation Refactoring: The Makefile now offers granular installation targets (install-cli, install-mcp) and the main install target includes git hooks, providing more flexible deployment options.
  • Enhanced Quality Gate: The check target was renamed to precheck, and a new check target now performs a full quality gate, including a Semgrep security scan, improving code quality and security checks.
  • New CLI Cache Management: A dedicated cache command has been added to the CLI, providing subcommands for listing and cleaning cached project snapshots with detailed help, enhancing user control over cached data.
  • Improved Symlink Handling: File scanning logic was updated to prevent following symlinks that escape the defined scan root, ensuring scans stay within intended project boundaries and preventing unintended data exposure.
  • Consistent Root Directory Normalization: Root directory paths are now canonicalized for more consistent snapshot caching and analysis, leading to more reliable project state management.
  • Documentation Updates: The README.md was updated with clearer installation instructions, a comparison table ('Why loctree'), and an expanded list of available tools, improving user onboarding and understanding.
  • Test Suite Adjustments: Tests were modified to reflect the removal of the audit --stdout flag, recommending --json instead, and redundant snapshot refreshes were removed, streamlining the test suite.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new loct cache command for managing snapshot caches, complete with list and clean subcommands and detailed help. The Makefile has been refactored to modularize installation targets (install-cli, install-mcp) and enhance the check target with a Semgrep security scan. Additionally, the README.md has been updated with streamlined installation instructions and a new feature comparison table. Code changes also include canonicalizing root paths for snapshot loading and refactoring gather_files to prevent symlinks from escaping the scan root, though an efficiency improvement was noted for redundant canonicalize() calls within the recursive gather_files_inner function. A further improvement opportunity was identified in the Makefile to prevent semgrep execution if the tool is not installed.

Comment thread Makefile
Comment on lines +91 to +97
@if command -v semgrep >/dev/null 2>&1 || command -v pipx >/dev/null 2>&1; then \
SEMGREP=$$(command -v semgrep || echo "pipx run semgrep"); \
$$SEMGREP scan --config auto --error --quiet . 2>/dev/null || \
echo "[!] Semgrep found issues (see above)"; \
else \
echo "[!] Semgrep not available, skipping (install: pipx install semgrep)"; \
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The semgrep command is executed even if it's not installed, leading to an error message in the output. It would be better to skip the execution entirely if semgrep is not available.

if command -v semgrep >/dev/null 2>&1 || command -v pipx >/dev/null 2>&1; then \
		SEMGREP=$$(command -v semgrep || echo "pipx run semgrep"); \
		$$SEMGREP scan --config auto --error --quiet . 2>/dev/null || \
			 echo "[!] Semgrep found issues (see above)"; \
	else \
		 echo "[!] Semgrep not available, skipping (install: pipx install semgrep)"; \
	fi

Comment on lines +393 to +413
// Don't follow symlinks that escape the scan root (e.g. DMG staging
// dirs with /Applications symlink). Compares against the top-level
// scan root, not the current recursion dir, so intra-repo symlinks
// like src/data -> ../shared/data still work.
if !target.starts_with(scan_root) {
continue;
}
let meta = match fs::metadata(&path) {
Ok(m) => m,
Err(_) => continue,
};
if meta.is_dir() && options.max_depth.is_none_or(|max| depth < max) {
gather_files(&target, options, depth + 1, git_checker, visited, files)?;
gather_files_inner(
&target,
scan_root,
options,
depth + 1,
git_checker,
visited,
files,
)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The gather_files_inner function is recursively called within the symlink handling logic. It would be more efficient to pass the scan_root to the gather_files_inner function directly instead of calling dir.canonicalize() again, as it's already canonicalized in the gather_files function.

gather_files_inner(
					&target,
					scan_root,
					options,
					depth + 1,
					git_checker,
					visited,
					files,
				)?;

Szowesgad and others added 19 commits March 20, 2026 20:05
Add .github/FUNDING.yml to configure project funding links. This file registers the GitHub Sponsors account 'Loctree' and a Polar funding handle 'loctree' so the repository displays sponsor/donation options.
Rework release and Homebrew distribution workflows to separate distribution from the monorepo.

- Publish pipeline now builds per-platform CLI (loct) and MCP (loctree-mcp) artifacts, uploads them as artifacts, and publishes thin releases into Loctree/loct and Loctree/loctree-mcp. A monorepo release is created after thin releases and npm publish.
- homebrew-release workflow now downloads the published tarballs, computes SHA256 checksums, renders formulas via scripts/render-homebrew-formula.sh, and commits updates directly into two tap repos: Loctree/homebrew-cli and Loctree/homebrew-mcp (requires HOMEBREW_GITHUB_API_TOKEN).
- Removed legacy Homebrew formula files and helper scripts for homebrew-core, deleted placeholder npm bin shims, and updated docs/README/.github guidance to reflect new tap names and the new bootstrap/runtime contract.

This change centralizes binary distribution in narrow "thin" repos and automates tapping/updating of Homebrew formulae in the two custom taps.
loctree=0.8.17 report-leptos=0.8.17 loctree-mcp=0.8.17

VibeCrafted with AI Agents (c)2024-2026 VetCoders
Refactor the `loct cache list` handler to aggregate cache buckets by repo and project path and surface richer scan metadata. Introduces CacheBucketRow, CacheBucketStats and CacheSnapshotRecord along with helpers to read snapshot.json, compute bucket sizes, select project roots, resolve owner/repo labels, and format schema/branch/scan info; output now shows MB sizes and a summary meta column. Adds parsing of git owner/repo (parse_owner_repo and parse_repo_name), a new git_owner_repo field in SnapshotMetadata and GitContext, and updates get_git_info/git_context_for to populate it. Updates CLI help text, adds end-to-end and unit tests for the new behavior, and minor test adjustments. Also adds .vibecrafted to .gitignore.
Add a macOS smoke-releaseability script to verify release binaries do not link against non-system dylibs and to run a quick --version check. Integrate the smoke check into GitHub Actions and Makefile (new smoke-release-macos-arm64 target), include packaged release assets in the monorepo GH release, and update release messaging/docs. Make installer changes: tools/install.sh now supports INSTALL_MCP (install MCP server optionally) and uses cargo install --locked; README, distribution docs, npm docs, and dev install docs updated to reflect CLI-only npm channel and reproducible installs. Vendor libgit2 in loctree_rs Cargo.toml to keep macOS release binaries portable. Also add a small clippy allow and other minor packaging/CI tweaks.
Strip every #[allow(clippy::..., dead_code, unused_imports, ...)] attribute
from the codebase and fix the underlying issues so clippy passes clean
without any suppression:

- Delete 7 dead functions/structs in dist.rs (source-map pipeline, -255 LOC)
- Bundle too_many_arguments into context structs across 6 functions:
  tree.rs WalkContext, scan.rs AnalyzeContext, output.rs GlobalContext,
  findings.rs SummaryInput, py/mod.rs FromImportContext,
  refactor_plan/mod.rs TarjanState
- Add ComponentResult type alias in graph.rs for type_complexity
- Remove unused_imports in analyzer/mod.rs
- Remove stale non_snake_case/dead_code/unused_unsafe suppressions in
  regexes.rs, snapshot.rs, cache.rs

Also add 3 cache clean e2e tests covering the previously untested
destructive cache clean command (--force, --older-than, confirmation UX).

Co-Authored-By: Klaudiusz <the1st@whoai.am>
Standardize copyright/branding across the repo: replace (c) markers with ⓒ and extend year ranges to 2025-2026, unify the "VibeCrafted" styling (𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍.). Changes touch many docs, CI/workflow files, ai-hooks, scripts, examples, and source headers. Also adjust a Cargo.toml comment (rmcp-memex → rust-memex).
Replace numerous manual descending sort closures with sort_by_key(...Reverse(...)) across the codebase for clarity and consistency (loctree-mcp, analyzer modules, CLI handlers, snapshot, tree). Also simplify a match arm in the Python usage parser to use a guarded pattern, and add two docs: BUG_symlink_escape_traversal.md (symlink traversal bug report/fix notes) and ROADMAP_0.8.16_to_0.10.1.md (product roadmap/research notes). These are refactors and documentation additions only.
@Szowesgad Szowesgad merged commit 22678da into main Apr 25, 2026
11 checks passed
@Szowesgad Szowesgad deleted the release/v0.8.17 branch April 25, 2026 14:11
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.

Symlink escape causes filesystem traversal hang

2 participants