Skip to content

Conversation

@feynon
Copy link
Member

@feynon feynon commented Nov 6, 2025

Note

Introduces ISO packaging with CI artifact, a revamped installer, registry-based model resolution in CLI, and updates default model to mem-agent-mlx-4bit.

  • Packaging/Installers:
    • Add scripts/make_iso.sh to build a bootable installer ISO (macOS auto-launch app, logging, README, ASCII art).
    • Overhaul scripts/install.sh with UI, dependency checks, bundle discovery (local/release), and installation steps.
    • Improve bundling via scripts/bundler.sh; add just iso and ignore dist/.
    • Include ascii-art.txt for installer branding.
  • CLI/Runner:
    • tiles run now accepts a model name by resolving to ~/.local/share/tiles/registry/<name>/Modelfile (adds get_registry_dir).
    • Update CLI description and help text; add registry/memgpt/Modelfile.
  • Server/Defaults:
    • Switch default MODEL_ID to driaforall/mem-agent-mlx-4bit in server/config.py.
  • CI:
    • Update Rust workflow to pin toolchain, install ISO tooling, build ISO, and upload ISO artifact.

Written by Cursor Bugbot for commit 92e56eb. This will update automatically on new commits. Configure here.

@coderabbitai
Copy link

coderabbitai bot commented Nov 6, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds ISO packaging and CI support plus a refactored interactive installer. New scripts: scripts/make_iso.sh (builds bundle, prepares .tiles-installer, macOS helpers, creates ISO via xorriso/genisoimage/mkisofs) and scripts/bundler.sh (minor output change). scripts/install.sh refactored to a modular, UI-driven installer with expanded dependency checks and stricter error handling. CI (.github/workflows/rust.yml) now installs ISO tooling and uploads the ISO artifact. justfile gains an iso target; dist/ added to .gitignore. Small app changes: CLI help text, MODEL_ID updated, registry Modelfile added, and a new get_registry_dir() helper.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer / CI
    participant Just as just (task runner)
    participant MakeISO as scripts/make_iso.sh
    participant Bundler as scripts/bundler.sh
    participant Installer as scripts/install.sh
    participant ISOtool as xorriso|genisoimage|mkisofs
    participant GH as GitHub Actions Artifact

    Dev->>Just: just iso (or CI triggers)
    Just->>MakeISO: execute
    MakeISO->>MakeISO: read Cargo.toml, determine VERSION, OS/ARCH
    MakeISO->>Bundler: ./scripts/bundler.sh (create bundle)
    Bundler-->>MakeISO: dist/tiles-bundle.tar
    MakeISO->>MakeISO: create .tiles-installer, copy bundle + install script (+ ASCII art)
    alt darwin
        MakeISO->>MakeISO: generate Install Tiles.command and Install Tiles.app
    end
    MakeISO->>ISOtool: build ISO with label tiles-VERSION
    ISOtool-->>MakeISO: tiles-installer-VERSION.iso
    MakeISO->>GH: upload tiles-installer-*.iso artifact
    GH-->>Dev: artifact available
Loading
sequenceDiagram
    participant User as End user
    participant Installer as scripts/install.sh
    participant Env as Host (python/uv/tooling)
    participant Bundle as tiles-bundle.tar

    User->>Installer: run install.sh (from ISO or bundle)
    Installer->>Env: check dependencies (python, uv, etc.)
    alt missing
        Installer->>Env: print instructions / attempt install (brew/apt/uv installer)
    end
    Installer->>Bundle: locate bundle (local / repo / GitHub release)
    alt found
        Installer->>Installer: extract bundle, install CLI, setup Python server (uv sync)
        Installer->>User: print PATH/setup guidance and completion
    else not found
        Installer->>User: error and abort
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay attention to:
    • scripts/install.sh — large behavioral refactor, many branches, platform-specific logic, and new helper functions.
    • scripts/make_iso.sh — temp dir/trap logic, macOS app/script generation, and fallback ISO tool selection.
    • .github/workflows/rust.yml — CI steps installing ISO tooling and artifact upload patterns.
    • Interaction between bundler.sh, make_iso.sh, and install.sh (bundle layout expectations).
    • src/commands/mod.rs and src/runner/mlx.rs — new path-resolution behavior and added public registry helper.
    • server/config.py and src/main.rs — value and documentation updates.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: bundler improvements, ISO installer support, and Modelfile folder structure.
Description check ✅ Passed The description clearly outlines all major changes across packaging, CLI, server defaults, and CI, with organized sections and specific file references.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch build-artifacts

📜 Recent review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92e56eb and 30fc8ec.

📒 Files selected for processing (2)
  • src/commands/mod.rs (2 hunks)
  • src/main.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{rs,toml}

⚙️ CodeRabbit configuration file

Review the Rust code for conformity with best practices in Rust, Systems programming. Highlight any deviations.

Files:

  • src/commands/mod.rs
🧬 Code graph analysis (1)
src/commands/mod.rs (2)
src/runner/mlx.rs (2)
  • run (12-19)
  • get_registry_dir (274-279)
src/core/modelfile.rs (1)
  • parse_from_file (246-251)

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.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +273 to +283
create_iso() {
local src_dir="$1"
local out_path="$2"
local label="$3"

if command -v xorriso >/dev/null 2>&1; then
xorriso -as mkisofs -quiet -o "${out_path}" -V "${label}" "${src_dir}"
elif command -v genisoimage >/dev/null 2>&1; then
genisoimage -quiet -V "${label}" -o "${out_path}" "${src_dir}"
elif command -v mkisofs >/dev/null 2>&1; then
mkisofs -quiet -V "${label}" -o "${out_path}" "${src_dir}"

Choose a reason for hiding this comment

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

P1 Badge Preserve long file names when generating installer ISO

The ISO is created with xorriso/genisoimage/mkisofs using only -V and -o. Without Rock Ridge or Joliet extensions the tools fall back to ISO9660 level 1, truncating file and directory names to 8.3 uppercase. The macOS bundle laid out earlier in this script (Install Tiles.app/Contents/Info.plist, .../Resources/...) relies on those exact long paths; after truncation Finder cannot treat the directory as an application and the auto‑launch installer fails to run. Add options such as -J -R (or other platform‑appropriate flags) so that long file names are preserved whenever a macOS ISO is produced.

Useful? React with 👍 / 👎.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
scripts/make_iso.sh (2)

143-221: AppleScript launcher logic is comprehensive but has multiple search paths.

The fallback mechanism that searches mounted volumes (lines 180-206) could theoretically match an incorrect volume if multiple /Volumes/tiles-* directories exist. Consider adding a more specific identifier (e.g., version number in volume name) or prompt user to select if multiple matches are found. However, this is a defensive fallback and unlikely to cause issues in normal use.


273-290: Add validation that ISO creation succeeded.

While the tool fallback logic is solid, consider verifying that the output ISO file was created before reporting success at line 292. Current code will report success even if xorriso/genisoimage/mkisofs failed silently.

Apply this diff to validate ISO creation:

 mkdir -p "${DIST_DIR}"
 create_iso "${TMPDIR}" "${ISO_PATH}" "${ISO_LABEL}"
+
+if [[ ! -f "${ISO_PATH}" ]]; then
+  err "ISO creation failed: ${ISO_PATH} not found"
+fi
 
 log "ISO created: ${ISO_PATH}"
scripts/install.sh (3)

122-125: Add defensive check for sudo availability on Linux systems.

Line 124 invokes sudo without verifying the user has sudo access. If sudo is unavailable or user lacks permissions, the installer will fail with a permission error. Consider checking sudo availability or handling the error more gracefully.

  elif [[ -f /etc/debian_version ]]; then
+   if ! sudo -n true 2>/dev/null; then
+     err "This system requires 'sudo' to install Python. Please configure sudo access."
+   fi
    print_info "Installing Python via apt..."
    sudo apt-get update -y && sudo apt-get install -y python3 python3-venv

137-141: Verify uv installation succeeded.

While the official uv installation method is used, there's no verification that uv is actually available after line 138 completes. If the installer script fails silently, line 140's success message would be misleading. Consider checking for uv command availability after PATH update.

  print_info "Installing uv..."
  curl -LsSf https://astral.sh/uv/install.sh | sh
  export PATH="$HOME/.local/bin:$PATH"
+ if ! command -v uv >/dev/null 2>&1; then
+   err "uv installation failed. Please visit https://docs.astral.sh/uv/getting-started/installation/"
+ fi
  print_success "uv installed"

1-3: Add cleanup trap for main script TMPDIR.

While rm -rf "${TMPDIR}" is called at line 213, it's not in a trap handler, so TMPDIR won't be cleaned up if the script exits early due to an error. Consider adding an early cleanup trap to ensure temp directory is always removed.

 #!/usr/bin/env bash
 set -euo pipefail
+
+TMPDIR="$(mktemp -d)"
+trap 'rm -rf "${TMPDIR}"' EXIT
 
 # Terminal setup

Then remove the manual cleanup at line 213. This ensures cleanup happens regardless of how the script exits.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67a792d and e0a5dda.

⛔ Files ignored due to path filters (1)
  • .DS_Store is excluded by !**/.DS_Store
📒 Files selected for processing (10)
  • .github/workflows/rust.yml (1 hunks)
  • .gitignore (1 hunks)
  • README.md (1 hunks)
  • ascii-art.txt (1 hunks)
  • justfile (1 hunks)
  • memgpt.modelfile (1 hunks)
  • scripts/bundler.sh (2 hunks)
  • scripts/install.sh (1 hunks)
  • scripts/make_iso.sh (1 hunks)
  • src/main.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{rs,toml}

⚙️ CodeRabbit configuration file

Review the Rust code for conformity with best practices in Rust, Systems programming. Highlight any deviations.

Files:

  • src/main.rs
🧬 Code graph analysis (2)
scripts/make_iso.sh (1)
scripts/install.sh (2)
  • log (87-89)
  • err (91-95)
scripts/install.sh (1)
scripts/make_iso.sh (1)
  • err (16-16)
🪛 LanguageTool
ascii-art.txt

[duplication] ~1-~1: Ebla mistajpaĵo: vi ripetis vorton
Context: ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~2-~2: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~4-~4: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~6-~6: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~8-~8: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~43-~43: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~45-~45: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~47-~47: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~49-~49: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~51-~51: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░...

(WORD_REPEAT_RULE)


[duplication] ~53-~53: Ebla mistajpaĵo: vi ripetis vorton
Context: ...░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

(WORD_REPEAT_RULE)

🔇 Additional comments (15)
.gitignore (1)

3-3: LGTM!

The addition of the dist/ directory to gitignore appropriately excludes build artifacts generated by the new ISO packaging workflow.

justfile (1)

23-24: LGTM!

The new iso target follows the existing pattern of shell script delegation and integrates cleanly with the packaging workflow.

ascii-art.txt (1)

1-55: LGTM!

The ASCII art asset will be included in the ISO installer as a visual element. The static analysis warnings about character repetition are false positives—the repeated block elements are intentional parts of the ASCII art design.

README.md (1)

18-21: LGTM!

The new documentation section clearly explains the packaging workflow, providing users with straightforward instructions for creating bundles and bootable ISO images.

.github/workflows/rust.yml (1)

41-54: LGTM!

The new CI steps install ISO tooling, build the installer, and upload artifacts with appropriate error handling. The use of if-no-files-found: error ensures the workflow fails if the ISO generation doesn't produce expected outputs.

scripts/bundler.sh (1)

14-29: LGTM!

The removal of emoji characters from output messages improves compatibility with various terminal environments and automated tooling while maintaining clear status reporting.

src/main.rs (1)

7-7: LGTM!

The CLI description update provides users with a clearer understanding of the tool's purpose and functionality, specifically highlighting privacy, on-device processing, and Obsidian integration.

memgpt.modelfile (1)

1-1: Based on my verification, the original review comment was based on incorrect assumptions about the file format and requires correction.

The review comment is incorrect.

The FROM instruction in an Ollama Modelfile identifies the base model and is mandatory for defining the foundation. You can use any model available in the Ollama library or even a local file path to a GGUF model file.

The file memgpt.modelfile is an Ollama Modelfile, not a Docker container definition. The original review comment incorrectly treated it as a Docker image reference by suggesting Docker Hub image verification. However, the GitHub repository references "mem-agent-mlx-4bit" and "mem-agent-mlx-8bit" as model names for use with LM Studio, and the MLX version of the mem-agent model has been quantized to 8-bit and 4-bit precisions, with the 4-bit model showing little to no loss in performance.

The change from driaforall/mem-agent to driaforall/mem-agent-mlx-4bit appears intentionally designed to reference a quantized model variant. This is a valid model configuration update, not a Docker image dependency issue.

Likely an incorrect or invalid review comment.

scripts/make_iso.sh (2)

18-23: Bundle validation and error handling look solid.

Proper file existence check with clear error message on failure.


85-99: Exit code handling is correct.

Proper use of ${PIPESTATUS[0]} to capture the exit code from install.sh before tee, with appropriate success/failure handling.

scripts/install.sh (5)

8-25: Terminal setup and ASCII art detection are well-designed.

Defensive terminal width detection and dual-path ASCII art lookup handle both local and mounted volume scenarios appropriately.


119-127: Verify macOS Python installation doesn't fail silently.

Line 121 assumes brew is available on macOS but doesn't verify it exists first. If brew isn't installed, the brew install python command fails, but because it's piped to err() via the || operator, it should exit correctly. However, clarify the intent: is this a fatal error if brew is unavailable, or should there be a fallback?

Consider checking for brew availability explicitly:

  if [[ "$OS" == "darwin" ]]; then
+   if ! command -v brew >/dev/null 2>&1; then
+     err "Homebrew not found. Please install from https://brew.sh"
+   fi
    print_info "Installing Python via Homebrew..."
    brew install python || err "Could not install Python. Please install manually from https://www.python.org"
  elif [[ -f /etc/debian_version ]]; then

149-181: Bundle resolution and extraction logic is well-structured.

Clear priority order (local → repo → GitHub) with appropriate error handling and explicit success messaging for each path.


187-209: Installation steps use appropriate commands with proper error handling.

Binary permissions (755), recursive server copy, and reproducible uv sync --frozen with failure handling are all appropriate.


228-252: PATH setup detection and help display are comprehensive.

The parameter expansion check for PATH membership (line 228) is correct, and the fallback chain for displaying help (lines 243-247) handles cases where the tiles command isn't yet available.

@feynon feynon changed the title feat: Bundler improvements, add ISO installer support feat: Bundler improvements, add ISO installer support, and Modelfile folder Nov 6, 2025
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on December 16

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

.canonicalize()
.map(|p| p.to_string_lossy().to_string())
.map_err(|e| format!("Failed to canonicalize path '{}': {}", input, e));
}
Copy link

Choose a reason for hiding this comment

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

Bug: Path-conflict: prioritize model lookup over local files

The resolve_modelfile_path function incorrectly prioritizes file existence over model name resolution. If a user runs tiles run memgpt and there happens to be a file or directory named memgpt in the current directory, it will use that local file instead of looking for the model in the registry. The function should check if the input is explicitly a path (contains /, \, or starts with . or ~) before checking existence, or at minimum check if it's a relative/absolute path pattern before treating it as a file path.

Fix in Cursor Fix in Web

@feynon
Copy link
Member Author

feynon commented Nov 6, 2025

@cursoragent fix this error in build step: https://github.com/tilesprivacy/tilekit/actions/runs/19133405090/job/54679797502#step:6:1

2025-11-06T11:03:15.8986303Z ##[debug]Evaluating condition for step: 'Run check'
2025-11-06T11:03:15.8987245Z ##[debug]Evaluating: success()
2025-11-06T11:03:15.8987572Z ##[debug]Evaluating success:
2025-11-06T11:03:15.8987896Z ##[debug]=> true
2025-11-06T11:03:15.8988217Z ##[debug]Result: true
2025-11-06T11:03:15.8988648Z ##[debug]Starting: Run check
2025-11-06T11:03:15.8996269Z ##[debug]Loading inputs
2025-11-06T11:03:15.8996990Z ##[debug]Loading env
2025-11-06T11:03:15.9000564Z ##[group]Run just check
2025-11-06T11:03:15.9000788Z �[36;1mjust check�[0m
2025-11-06T11:03:15.9029164Z shell: /usr/bin/bash -e {0}
2025-11-06T11:03:15.9029414Z env:
2025-11-06T11:03:15.9029592Z CARGO_TERM_COLOR: always
2025-11-06T11:03:15.9029822Z CARGO_HOME: /home/runner/.cargo
2025-11-06T11:03:15.9030059Z CARGO_INCREMENTAL: 0
2025-11-06T11:03:15.9030423Z ##[endgroup]
2025-11-06T11:03:15.9060910Z ##[debug]/usr/bin/bash -e /home/runner/work/_temp/8f7e98f4-cdd5-4998-b69a-ae41fe561375.sh
2025-11-06T11:03:15.9090261Z just fmt
2025-11-06T11:03:15.9106253Z cargo fmt --all -- --check
2025-11-06T11:03:16.0104218Z info: syncing channel updates for '1.90.0-x86_64-unknown-linux-gnu'
2025-11-06T11:03:16.0689334Z info: latest update on 2025-09-18, rust version 1.90.0 (1159e78c4 2025-09-14)
2025-11-06T11:03:16.0987764Z info: component 'clippy' for target 'x86_64-unknown-linux-gnu' is up to date
2025-11-06T11:03:16.0988625Z info: component 'rustfmt' for target 'x86_64-unknown-linux-gnu' is up to date
2025-11-06T11:03:16.0993295Z info: downloading component 'rust-analyzer'
2025-11-06T11:03:16.1361381Z info: installing component 'rust-analyzer'
2025-11-06T11:03:16.9574645Z Diff in /home/runner/work/tilekit/tilekit/src/commands/mod.rs:1:
2025-11-06T11:03:16.9575496Z // Module that handles CLI commands
2025-11-06T11:03:16.9575985Z
2025-11-06T11:03:16.9582466Z +use std::path::Path;
2025-11-06T11:03:16.9582840Z use tiles::{
2025-11-06T11:03:16.9583050Z core::{
2025-11-06T11:03:16.9583249Z health,
2025-11-06T11:03:16.9583565Z Diff in /home/runner/work/tilekit/tilekit/src/commands/mod.rs:7:
2025-11-06T11:03:16.9583927Z },
2025-11-06T11:03:16.9584119Z runner::mlx,
2025-11-06T11:03:16.9584316Z };
2025-11-06T11:03:16.9584501Z -use std::path::Path;
2025-11-06T11:03:16.9584733Z
2025-11-06T11:03:16.9584944Z pub async fn run(modelfile_path: &str) {
2025-11-06T11:03:16.9585350Z // Resolve the modelfile path - check if it's a model name or file path
2025-11-06T11:03:16.9585835Z Diff in /home/runner/work/tilekit/tilekit/src/commands/mod.rs:29:
2025-11-06T11:03:16.9586187Z
2025-11-06T11:03:16.9586469Z fn resolve_modelfile_path(input: &str) -> Result<String, String> {
2025-11-06T11:03:16.9586838Z let path = Path::new(input);
2025-11-06T11:03:16.9587087Z -
2025-11-06T11:03:16.9587263Z +
2025-11-06T11:03:16.9587569Z // If the input is a file path that exists, canonicalize it to get absolute path
2025-11-06T11:03:16.9588100Z // This prevents path traversal attacks and ensures consistent path handling
2025-11-06T11:03:16.9588451Z if path.exists() {
2025-11-06T11:03:16.9588725Z Diff in /home/runner/work/tilekit/tilekit/src/main.rs:13:
2025-11-06T11:03:16.9589268Z #[derive(Subcommand, Debug)]
2025-11-06T11:03:16.9589494Z enum Commands {
2025-11-06T11:03:16.9589746Z /// Runs a model by name (e.g., 'memgpt') or by Modelfile path
2025-11-06T11:03:16.9590027Z - ///
2025-11-06T11:03:16.9590191Z + ///
2025-11-06T11:03:16.9590356Z /// Examples:
2025-11-06T11:03:16.9590646Z /// tiles run memgpt # Runs registry/memgpt/Modelfile
2025-11-06T11:03:16.9591023Z /// tiles run ./path/to/my.modelfile # Runs specific file
2025-11-06T11:03:16.9600829Z error: Recipe fmt failed on line 4 with exit code 1
2025-11-06T11:03:16.9605133Z error: Recipe check failed on line 10 with exit code 1
2025-11-06T11:03:16.9620851Z ##[error]Process completed with exit code 1.
2025-11-06T11:03:16.9632444Z ##[debug]Finishing: Run check

@cursor
Copy link

cursor bot commented Nov 6, 2025

Perfect! I've fixed all the formatting issues:

Changes Made

Fixed formatting errors in two files:

  1. src/commands/mod.rs:

    • Moved use std::path::Path; before use tiles::{...} (standard library imports should come first)
    • Removed trailing whitespace after let path = Path::new(input);
  2. src/main.rs:

    • Removed trailing space after /// in the doc comment

The cargo fmt --check now passes successfully. These formatting issues were causing the CI build to fail, and the fixes ensure the code adheres to Rust's standard formatting conventions.


Open in Cursor Open in Web

Learn more about Cursor Agents

@cursor
Copy link

cursor bot commented Nov 6, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@feynon feynon merged commit 7690cb5 into main Nov 6, 2025
2 checks passed
@feynon feynon deleted the build-artifacts branch November 6, 2025 12:27
feynon added a commit that referenced this pull request Nov 6, 2025
@feynon feynon restored the build-artifacts branch November 6, 2025 12:32
@coderabbitai coderabbitai bot mentioned this pull request Nov 6, 2025
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.

3 participants