Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@ name: CI

on:
push:
branches: [main]
branches: [ main ]
pull_request:
branches: [main]
branches: [ main ]

jobs:
build:
build-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- name: 📥 Checkout code
uses: actions/checkout@v4

- name: 🧰 Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.20
- run: go mod tidy
- run: make fmt
- run: make test
- run: make cover
go-version: '1.20'

- name: 🧪 Show Go version (debug)
run: go version

- name: 🧹 Run go mod tidy
run: go mod tidy

- name: 🔧 Verify no changes after tidy
run: |
git diff --exit-code || (echo '❌ go mod tidy modified go.mod/go.sum. Please run it locally.' && exit 1)

- name: ✅ Run tests
run: make test
134 changes: 61 additions & 73 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,104 @@
# tree-ai 🧠🌲
# tree-ai

`tree-ai` is a command-line tool that enhances the `tree` output with AI-generated descriptions of each file and folder using IBM's Granite 4.0 Tiny Preview model. It works entirely offline after install, and outputs AI-enriched directory listings.
**tree-ai** is a command-line tool that augments the traditional `tree` command with **AI-generated descriptions** for files and folders. It uses IBM Granite language models to provide concise summaries of each element in your directory tree, helping you quickly understand unfamiliar projects.

---
## Features

## 🚀 Install and Run
- 🧠 AI-generated summaries of files and directories
- 🔍 Fully recursive traversal with `--max-depth`
- 🧰 Support for both local and remote IBM Granite models
- 📦 Works offline if model is cached
- 📝 Customizable prompt instructions

### 🔁 Option 1: One-liner install and run (via `curl`)
## Installation

### 🚀 For Users (via curl)

You can install the latest release directly:

```bash
curl -sSf https://raw.githubusercontent.com/ascerra/tree-ai/main/install-and-run.sh | bash -s ./my-project
curl -sSL https://raw.githubusercontent.com/ascerra/tree-ai/main/install.sh | bash
```

This will:
- Clone the repo into a temp directory
- Set up a local Python virtual environment
- Download the Granite model via Hugging Face
- Build the Go CLI and AI runner
- Run `tree-ai` on the specified directory
This will download the latest binary to your local `bin/` folder and make it executable.

---
To install dependencies for the local Python-based runner:

```bash
make deps
```

### 🛠 Option 2: Manual install for development
### 🔧 For Developers (from source)

```bash
# Step 1: Clone the repo
git clone https://github.com/ascerra/tree-ai.git

# Step 2: Move into the project directory
git clone https://github.com/your-org/tree-ai.git
cd tree-ai

# Step 3: Build and install dependencies
make install

# Step 4: Activate your Python virtual environment
source .venv/bin/activate

# Step 5: Run tree-ai on a directory
./bin/tree-ai ./my-project
make build
```

---

## 💡 What You Get
To install dependencies for the local Python-based runner:

```bash
./
├── cmd (CLI entrypoint)
├── internal/
│ ├── ai/ (AI integration using IBM Granite)
│ └── tree/ (tree display logic)
├── model/
│ ├── granite-runner.go (Go CLI wrapper around Granite model)
│ └── granite_infer.py (Python script running IBM Granite inference)
make deps
```

When you run `tree-ai`, you’ll see output like:
## Usage

```
.
├── main.go (Handles CLI setup and command execution)
├── internal (Contains logic for AI and tree display)
│ └── ai (Integrates IBM Granite model for description generation)
```bash
bin/tree-ai ./
```

---
Show up to 3 levels deep:

## 📦 Project Structure
```bash
bin/tree-ai ./ --max-depth=3
```

- `main.go` – entrypoint, calls `cmd.Execute()`
- `cmd/` – Cobra CLI setup
- `internal/` – Go logic for tree rendering and AI prompt integration
- `model/` – AI runner files (`granite-runner.go` and `granite_infer.py`)
- `.venv/` – Python virtualenv created by `make install`
Include hidden files and directories (like `tree -a`):

---
```bash
bin/tree-ai ./ --include-dotfiles
```

## 🛠 Requirements
Use a specific remote model and endpoint:

- Go 1.20+
- Python 3.8+
- Internet access for first-time model download via Hugging Face
```bash
bin/tree-ai ../incubator-devlake \
--endpoint=https://granite-8b-code-instruct-maas-apicast-production.apps.prod.rhoai.rh-aiservices-bu.com:443/v1/completions \
--model=granite-8b-code-instruct-128k
```

---
Use a custom instruction for summarization:

## 🔐 Offline by Default
```bash
bin/tree-ai ./ --prompt-instruction "Summarize what this file contributes to the project."
```

Once installed, all AI inference runs locally using the IBM Granite 4.0 Tiny Preview model. No data is sent to any server after setup.
Enable verbose output for debugging:

---
```bash
bin/tree-ai ./ --verbose
```

## 🧹 Optional Cleanup
## Output Example

```bash
make clean
rm -rf .venv/
~/development/AI/project-tree-ai/tree-ai ❯ bin/tree-ai ./ --max-depth=2
└── 📄 LICENSE This file, "LICENSE", is a legal notice that grants permission to use, modify, distribute, and sublicense the project's software, adhering to the MIT License terms, while limiting liability for any claims or damages.
└── 📄 Makefile This Makefile outlines the build, testing, and installation processes for the "tree-ai" project, including its main Go binary, Python dependencies, and the "Granite" model runner.
└── 📄 README.md The purpose of this file is to provide comprehensive documentation for installing, running, and understanding the structure and functionality of the `tree-ai` project.
└── 💼 bin This directory contains compiled binaries used for local execution and testing.
└── 💼 cmd This directory contains the Cobra-based CLI entrypoint logic.
└── 💼 internal Internal Go packages for AI integration and tree traversal logic.
└── 📄 main.go Main entry point for the tree-ai command-line interface.
```

---

## 🧪 Testing
## Testing

```bash
make test
make cover # to see test coverage
```

---

## ✨ Coming Soon
## License

- Shell completion
- Model choice via flags (e.g. --model)
- Built-in file filters and summarization toggles
MIT License
31 changes: 21 additions & 10 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// cmd/root.go
package cmd

import (
Expand All @@ -11,11 +10,14 @@ import (
)

var (
noAI bool
model string
maxDepth int
includeFiles bool
endpoint string
noAI bool
model string
maxDepth int
includeFiles bool
endpoint string
verbose bool
includeDotfiles bool
promptInstruction string
)

var rootCmd = &cobra.Command{
Expand All @@ -26,19 +28,28 @@ var rootCmd = &cobra.Command{
if len(args) > 0 {
dir = args[0]
}
paths := tree.CollectPaths(dir, maxDepth, includeFiles)

// Pass verbosity to AI layer
ai.Verbose = verbose

// Collect tree paths
paths := tree.CollectPaths(dir, maxDepth, includeFiles, includeDotfiles)
ai.SetTotalFiles(len(paths))
tree.PrintTreeWithPaths(paths, dir, "", noAI, model, maxDepth, endpoint)

// Render tree with AI summaries
tree.PrintTreeWithPaths(paths, dir, "", noAI, model, maxDepth, endpoint, promptInstruction)
},
}

func init() {
rootCmd.Flags().BoolVar(&noAI, "no-ai", false, "Disable AI-generated descriptions")
rootCmd.Flags().StringVar(&model, "model", "granite-3-1-8b-instruct-w4a16", "Model to use for AI descriptions")
rootCmd.Flags().IntVar(&maxDepth, "max-depth", -1, "Limit the depth of the directory tree (default: 0 — immediate children only; use -1 for unlimited)")
rootCmd.Flags().IntVar(&maxDepth, "max-depth", -1, "Limit the depth of the directory tree (default: -1 for unlimited)")
rootCmd.Flags().BoolVar(&includeFiles, "include-files", true, "Include files in the output (default: true)")
rootCmd.Flags().BoolVar(&ai.Verbose, "verbose", false, "Enable verbose logging (default: off)")
rootCmd.Flags().StringVar(&endpoint, "endpoint", "", "Custom model endpoint URL (overrides default Granite endpoint)")
rootCmd.Flags().BoolVar(&verbose, "verbose", false, "Enable verbose logging (default: off)")
rootCmd.Flags().BoolVar(&includeDotfiles, "include-dotfiles", false, "Include dotfiles and dotdirs like `tree -a`")
rootCmd.Flags().StringVar(&promptInstruction, "prompt-instruction", "", "Custom prompt instruction to append after the file/directory contents")
}

func Execute() {
Expand Down
2 changes: 1 addition & 1 deletion install-and-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ make install || {
}

# Run tree-ai
./bin/tree-ai "$TARGET_PATH"
#./bin/tree-ai "$TARGET_PATH"

# Optionally clean up (comment out to persist install)
# echo "🧹 Cleaning up..."
Expand Down
Loading