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
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.26.x"
check-latest: true
- name: Build
run: go build ./...
- name: Vet
run: go vet ./...
- name: Test
run: go test ./...
103 changes: 103 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: Release

on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Tag to (re)build and attach assets to (e.g. v2.1.0)"
required: true

permissions:
contents: write

jobs:
build:
name: Build ${{ matrix.goos }}/${{ matrix.goarch }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- goos: linux
goarch: amd64
ext: ""
- goos: linux
goarch: arm64
ext: ""
- goos: darwin
goarch: amd64
ext: ""
- goos: darwin
goarch: arm64
ext: ""
- goos: windows
goarch: amd64
ext: ".exe"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag || github.ref }}

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.26.x"
check-latest: true

- name: Resolve version
id: ver
run: |
TAG="${{ github.event.inputs.tag || github.ref_name }}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"

- name: Build
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
CGO_ENABLED: 0
run: |
OUT="cue-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.ext }}"
go build -trimpath \
-ldflags "-s -w -X main.Version=${{ steps.ver.outputs.version }} -X main.BuildDate=${{ steps.ver.outputs.build_date }}" \
-o "dist/${OUT}" .
(cd dist && sha256sum "${OUT}" > "${OUT}.sha256")

Comment on lines +59 to +70
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: cue-${{ matrix.goos }}-${{ matrix.goarch }}
path: dist/*
if-no-files-found: error

publish:
name: Publish release assets
needs: build
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true

- name: Resolve tag
id: ver
run: |
TAG="${{ github.event.inputs.tag || github.ref_name }}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"

- name: Upload to GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.ver.outputs.tag }}"
if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --title "$TAG" --generate-notes
fi
gh release upload "$TAG" --repo "$GITHUB_REPOSITORY" --clobber dist/*
82 changes: 79 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<br>

<div align="center">
<h2>📺 Welcome to v2.0</h2>
<h2>📺 Welcome to v2.2</h2>
<img src="docs/assets/onboarding_demo.gif" alt="Onboarding Demo" width="900" style="border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.5);">
<br><br>
<h3>🏪 Environment Store Management</h3>
Expand Down Expand Up @@ -56,14 +56,23 @@ Modern application development requires immense cognitive overhead. Should you u
The CLI distributes as a self-contained, statically linked fat binary. No complex Node/Python/Ruby dependencies are strictly required to run it!

<details>
<summary><b>🐧 Linux / macOS</b></summary>
<summary><b>🐧 Linux / macOS (incl. Arch Linux support)</b></summary>
<br>

**One-liner install (Ubuntu / Debian / Arch / macOS):**
```bash
curl -fsSL https://raw.githubusercontent.com/GyaneshSamanta/cue/main/scripts/install.sh | bash
```

> **Note for Arch Linux Users:** The `install.sh` script is fully compatible with Arch Linux. For optimal compatibility with future AUR packaging and dependencies, ensure you have the base development tools installed via `sudo pacman -S base-devel`.
To pin a specific version:
```bash
curl -fsSL https://raw.githubusercontent.com/GyaneshSamanta/cue/main/scripts/install.sh | CUE_VERSION=v2.1.0 bash
```

**Arch Linux specifics:** The `install.sh` script works directly on Arch. We recommend having `base-devel`, `curl`, and `sudo` ready (`sudo pacman -S --needed base-devel curl`).

> [!TIP]
> **AUR packaging:** AUR support (`cue-bin`) is currently in development. For now, the direct install is the recommended path.

</details>

Expand All @@ -75,6 +84,25 @@ curl -fsSL https://raw.githubusercontent.com/GyaneshSamanta/cue/main/scripts/ins
iwr https://raw.githubusercontent.com/GyaneshSamanta/cue/main/scripts/install.ps1 -useb | iex
```

To pin a specific version:
```powershell
$env:CUE_VERSION = 'v2.1.0'; iwr https://raw.githubusercontent.com/GyaneshSamanta/cue/main/scripts/install.ps1 -useb | iex
```

</details>

<details>
<summary><b>🛠 Build from source</b></summary>
<br>

Requires Go 1.26+.

```bash
git clone https://github.com/GyaneshSamanta/cue && cd cue
go build -o cue .
./cue --version
```

</details>

<br>
Expand Down Expand Up @@ -118,6 +146,33 @@ During installation, it offers multiple execution engines:

---

## 🧠 Local Models (Ollama, Gemma & friends)

Run open-weight models on your own machine, then point Claude Code at them. Cue takes care of pulling, switching, and benchmarking.

```bash
cue model recommend # hardware-aware suggestions for your laptop
cue model gemma # one-shot install of Google Gemma 3 (4B default)
cue model gemma 12b # bigger Gemma for stronger quality
cue model pull qwen2.5-coder:7b
cue model use gemma3:4b # set as the default for Claude Code
cue model list # see what's installed
cue model benchmark gemma3:4b # quick speed test
```

**Gemma sizes** at a glance:

| Tag | Size | Best for |
| :--- | :--- | :--- |
| `gemma3:1b` | ~0.8 GB | Tiny laptops, instant load |
| `gemma3:4b` | ~3.3 GB | Default — strong general use on 8 GB+ RAM |
| `gemma3:12b` | ~8.1 GB | High quality on 16 GB RAM / 12 GB VRAM |
| `gemma3:27b` | ~17 GB | Best local quality on 32 GB RAM / 24 GB VRAM |

> Cue requires [Ollama](https://ollama.com/download) for local models. Run `cue model gemma` and Cue will tell you exactly how to install it if it's missing.

---

## ⚡ The Ultimate Macro Glossary

Macros encapsulate best-practices and safety constraints into readable verbs. Forget raw terminal commands—use our semantic shortcuts.
Expand Down Expand Up @@ -167,6 +222,27 @@ ui.HandleError(se)

---

## 📋 Changelog

### v2.2.0 — May 2026

**New**
- **`cue model` command** — the `internal/model` package was wired up and is now a first-class CLI feature. Run `cue model --help` to see all subcommands.
- **Google Gemma 3 support** — `cue model gemma [1b|4b|12b|27b]` installs Google Gemma via Ollama in one command. Hardware-aware `cue model recommend` now includes all four Gemma sizes.
- **`cue toolkit` command** — install, upgrade, remove, and inspect developer tools with automatic version-manager bootstrapping (e.g. `cue toolkit install node`). Closes the loop from `cue doctor fix --all`, which had been suggesting `cue toolkit install <tool>` when the command didn't yet exist.
- **Release pipeline** — added `.github/workflows/release.yml` that cross-compiles for linux/darwin/windows × amd64/arm64 and uploads binaries to GitHub Releases on every version tag. **This is what was causing the broken `install.sh` / `install.ps1`** — prior releases had no binary assets.
- **CI pipeline** — added `.github/workflows/ci.yml` for build / vet / test checks on every PR.

**Fixed**
- `install.sh` and `install.ps1` now fail with a clear actionable error if no release is found, instead of silently downloading nothing.
- Both scripts accept a `CUE_VERSION=vX.Y.Z` / `$env:CUE_VERSION` env var to pin to a specific release.
- `cue model list/pull/gemma` now prints a friendly install hint (brew / curl / winget) if Ollama is missing, instead of an opaque exec error.

**Improved**
- README install section: explicit Arch Linux guidance, versioned-install snippets, build-from-source instructions.

---

<div align="center">
<p><b>Built with ❤️ by Gyanesh</b></p>
<a href="https://buymeachai.ezee.li/GyaneshOnProduct">
Expand Down
119 changes: 119 additions & 0 deletions cmd/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package cmd

import (
"github.com/spf13/cobra"

"github.com/GyaneshSamanta/cue/internal/model"
"github.com/GyaneshSamanta/cue/internal/ui"
)

var modelCmd = &cobra.Command{
Use: "model",
Short: "Manage local AI models (Ollama, Gemma, etc.)",
Long: `Manage local AI models served by Ollama, including Google Gemma.

Cue treats Ollama as the canonical local-model runtime. Use this command
to pull models, set the active model for Claude Code, benchmark inference
speed, or get hardware-aware recommendations (including Gemma sizes).`,
}

var modelListCmd = &cobra.Command{
Use: "list",
Short: "List installed local models",
RunE: func(cmd *cobra.Command, args []string) error {
return model.ListModels()
},
}

var modelPullCmd = &cobra.Command{
Use: "pull <name>",
Short: "Download a model (e.g. gemma3:4b, llama3.1:8b)",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return model.PullModel(args[0])
},
Comment on lines +28 to +34
}

var modelRemoveCmd = &cobra.Command{
Use: "remove <name>",
Short: "Remove a downloaded model",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return model.RemoveModel(args[0])
},
}

var modelUseCmd = &cobra.Command{
Use: "use <name>",
Short: "Set the default model used by Claude Code",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return model.UseModel(args[0])
},
Comment on lines +46 to +52
}

var modelRecommendCmd = &cobra.Command{
Use: "recommend",
Short: "Suggest models based on detected hardware",
RunE: func(cmd *cobra.Command, args []string) error {
return model.Recommend()
},
}

var modelBenchmarkCmd = &cobra.Command{
Use: "benchmark [name]",
Short: "Run a quick inference speed test",
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
name := ""
if len(args) == 1 {
name = args[0]
}
return model.Benchmark(name)
},
}

var modelSearchCmd = &cobra.Command{
Use: "search <query>",
Short: "Search the Ollama registry",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return model.Search(args[0])
},
}

var modelGemmaCmd = &cobra.Command{
Use: "gemma [size]",
Short: "Quick-install Google Gemma (sizes: 1b, 4b, 12b, 27b — default 4b)",
Long: `Quick-install Google Gemma 3 via Ollama.

Examples:
cue model gemma # installs gemma3:4b (good default for 16GB RAM)
cue model gemma 1b # tiny — fits low-RAM laptops
cue model gemma 12b # quality — needs ~16GB RAM or 12GB VRAM
cue model gemma 27b # best — needs ~32GB RAM or 24GB VRAM

After install, run 'cue model use gemma3:<size>' to make it the default
for Claude Code.`,
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
size := "4b"
if len(args) == 1 {
size = args[0]
}
valid := map[string]bool{"1b": true, "4b": true, "12b": true, "27b": true}
if !valid[size] {
ui.PrintWarning("Unknown Gemma size '" + size + "'. Supported: 1b, 4b, 12b, 27b. Proceeding anyway.")
}
Comment on lines +104 to +107
tag := "gemma3:" + size
if err := model.EnsureOllama(); err != nil {
return err
}
return model.PullModel(tag)
},
}

func init() {
modelCmd.AddCommand(modelListCmd, modelPullCmd, modelRemoveCmd, modelUseCmd,
modelRecommendCmd, modelBenchmarkCmd, modelSearchCmd, modelGemmaCmd)
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func init() {
rootCmd.AddCommand(updateCmd)
rootCmd.AddCommand(versionMgrCmd)
rootCmd.AddCommand(doctorCmd)
rootCmd.AddCommand(modelCmd)
}

// Execute runs the root command.
Expand Down
Loading
Loading