Skip to content
Open
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
21 changes: 13 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,30 @@ jobs:
- name: Run tests
run: crystal spec

- name: Build binary (Linux)
- name: Build binaries (Linux)
if: matrix.target == 'linux-x86_64'
run: |
crystal build src/amber_cli.cr -o amber --release --static

- name: Build binary (macOS)
crystal build src/amber_lsp.cr -o amber-lsp --release --static

- name: Build binaries (macOS)
if: matrix.target == 'darwin-arm64'
run: |
crystal build src/amber_cli.cr -o amber --release

- name: Test binary
crystal build src/amber_lsp.cr -o amber-lsp --release

- name: Test binaries
run: |
./amber --version
./amber --help

- name: Upload build artifact
./amber-lsp --help

- name: Upload build artifacts
uses: actions/upload-artifact@v4
if: github.event_name == 'workflow_dispatch'
with:
name: amber-cli-${{ matrix.target }}-build
path: amber
path: |
amber
amber-lsp
retention-days: 7
26 changes: 19 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,29 @@ jobs:
run: ./bin/ameba
continue-on-error: true

- name: Compile project
run: crystal build src/amber_cli.cr --no-debug
- name: Compile CLI
run: crystal build src/amber_cli.cr --no-debug -o amber

- name: Compile LSP
run: crystal build src/amber_lsp.cr --no-debug -o amber-lsp

- name: Run tests
run: crystal spec

- name: Build release binary
run: crystal build src/amber_cli.cr --release --no-debug -o amber_cli
- name: Build release binaries
if: matrix.os == 'ubuntu-latest'
run: |
crystal build src/amber_cli.cr --release --no-debug -o amber_cli
crystal build src/amber_lsp.cr --release --no-debug -o amber_lsp

- name: Upload binary artifact (Linux)
- name: Upload binary artifacts (Linux)
uses: actions/upload-artifact@v4
if: matrix.os == 'ubuntu-latest'
with:
name: amber_cli-linux
path: amber_cli
name: amber-cli-linux
path: |
amber_cli
amber_lsp

# Separate job for additional platform-specific tests
platform-specific:
Expand Down Expand Up @@ -113,6 +120,11 @@ jobs:
./amber_cli --help || true
./amber_cli --version || true

- name: Test LSP functionality
run: |
crystal build src/amber_lsp.cr -o amber_lsp
./amber_lsp --help || true

# Job to run integration tests
integration:
runs-on: ubuntu-latest
Expand Down
88 changes: 49 additions & 39 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: Build and Release Binaries

permissions:
contents: write

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: 'Tag to build (e.g., v1.0.0)'
ref:
description: 'Git ref to build (tag or branch)'
required: true
type: string

Expand All @@ -28,58 +31,65 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.event.release.tag_name || github.event.inputs.tag }}

- name: Install Crystal (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
curl -fsSL https://crystal-lang.org/install.sh | sudo bash

- name: Install Crystal (macOS)
if: matrix.os == 'macos-latest'
run: |
brew update
brew install crystal
ref: ${{ github.event.release.tag_name || github.event.inputs.ref }}

- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
crystal: latest

- name: Install dependencies
run: shards install --production
run: |
if [ -f shard.lock ]; then
shards install --production
else
shards install
fi

- name: Build binary (Linux x86_64)
- name: Build binaries (Linux x86_64)
if: matrix.target == 'linux-x86_64'
run: |
crystal build src/amber_cli.cr -o amber --release --static

- name: Build binary (macOS ARM64)
crystal build src/amber_lsp.cr -o amber-lsp --release --static

- name: Build binaries (macOS ARM64)
if: matrix.target == 'darwin-arm64'
run: |
crystal build src/amber_cli.cr -o amber --release

- name: Verify binary
crystal build src/amber_lsp.cr -o amber-lsp --release

- name: Verify binaries
run: |
file amber
./amber --version || echo "Version command may not work in cross-compiled binary"

./amber --version
file amber-lsp
test -x amber-lsp

- name: Create archive
run: |
mkdir -p dist
tar -czf dist/amber-cli-${{ matrix.target }}.tar.gz amber
tar -czf dist/amber_cli-${{ matrix.target }}.tar.gz amber amber-lsp

- name: Calculate checksum
id: checksum
run: |
cd dist
sha256sum amber-cli-${{ matrix.target }}.tar.gz > amber-cli-${{ matrix.target }}.tar.gz.sha256
echo "sha256=$(cat amber-cli-${{ matrix.target }}.tar.gz.sha256 | cut -d' ' -f1)" >> $GITHUB_OUTPUT
if command -v sha256sum >/dev/null 2>&1; then
sha256sum amber_cli-${{ matrix.target }}.tar.gz > amber_cli-${{ matrix.target }}.tar.gz.sha256
else
shasum -a 256 amber_cli-${{ matrix.target }}.tar.gz > amber_cli-${{ matrix.target }}.tar.gz.sha256
fi
echo "sha256=$(cat amber_cli-${{ matrix.target }}.tar.gz.sha256 | cut -d' ' -f1)" >> $GITHUB_OUTPUT

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: amber-cli-${{ matrix.target }}
name: amber_cli-${{ matrix.target }}
path: |
dist/amber-cli-${{ matrix.target }}.tar.gz
dist/amber-cli-${{ matrix.target }}.tar.gz.sha256
dist/amber_cli-${{ matrix.target }}.tar.gz
dist/amber_cli-${{ matrix.target }}.tar.gz.sha256

upload-assets:
name: Upload Release Assets
Expand All @@ -89,18 +99,18 @@ jobs:

steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: artifacts

- name: Upload release assets
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v3
with:
files: |
artifacts/amber-cli-darwin-arm64/dist/amber-cli-darwin-arm64.tar.gz
artifacts/amber-cli-darwin-arm64/dist/amber-cli-darwin-arm64.tar.gz.sha256
artifacts/amber-cli-linux-x86_64/dist/amber-cli-linux-x86_64.tar.gz
artifacts/amber-cli-linux-x86_64/dist/amber-cli-linux-x86_64.tar.gz.sha256
artifacts/amber_cli-darwin-arm64/dist/amber_cli-darwin-arm64.tar.gz
artifacts/amber_cli-darwin-arm64/dist/amber_cli-darwin-arm64.tar.gz.sha256
artifacts/amber_cli-linux-x86_64/dist/amber_cli-linux-x86_64.tar.gz
artifacts/amber_cli-linux-x86_64/dist/amber_cli-linux-x86_64.tar.gz.sha256
tag_name: ${{ github.event.release.tag_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -113,9 +123,9 @@ jobs:

steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v2
uses: peter-evans/repository-dispatch@v4
with:
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
repository: crimsonknight/homebrew-amber-cli
repository: amberframework/homebrew-amber_cli
event-type: release-published
client-payload: '{"version": "${{ github.event.release.tag_name }}"}'
client-payload: '{"version": "${{ github.event.release.tag_name }}"}'
67 changes: 64 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ The comprehensive documentation includes detailed guides, examples, and API refe

**macOS & Linux via Homebrew:**
```bash
brew install amber
brew tap amberframework/amber_cli
brew install amber_cli
```

**From Source:**
```bash
git clone https://github.com/amberframework/amber_cli.git
cd amber_cli
shards install
crystal build src/amber_cli.cr -o amber
sudo mv amber /usr/local/bin/
crystal build src/amber_cli.cr -o amber --release
crystal build src/amber_lsp.cr -o amber-lsp --release
sudo mv amber amber-lsp /usr/local/bin/
```

**Windows:**
Expand Down Expand Up @@ -64,6 +66,7 @@ Your application will be available at `http://localhost:3000`
| `exec` | Execute Crystal code in app context | `amber exec 'puts User.count'` |
| `encrypt` | Manage encrypted environment files | `amber encrypt production` |
| `pipelines` | Show pipeline configuration | `amber pipelines` |
| `setup:lsp` | Configure the Amber LSP for Claude Code | `amber setup:lsp` |

Run `amber --help` or `amber [command] --help` for detailed usage information.

Expand All @@ -87,6 +90,12 @@ Run `amber --help` or `amber [command] --help` for detailed usage information.
- Route analysis and pipeline inspection
- Environment file encryption for security

### **Amber LSP — AI-Assisted Development**
- Built-in Language Server Protocol (LSP) server for Claude Code integration
- 15 convention rules that catch framework mistakes as you type
- Custom YAML-based rules for project-specific conventions
- One command to set up: `amber setup:lsp`

### **Extensible Architecture**
- Plugin system for extending functionality
- Command registration system for custom commands
Expand All @@ -112,6 +121,58 @@ Run `amber --help` or `amber [command] --help` for detailed usage information.
- Conditional file generation
- Post-generation command execution

## 🤖 Amber LSP — The Default Development Workflow

Amber ships with a diagnostics-only Language Server that integrates with [Claude Code](https://claude.ai/claude-code). When you develop with Claude Code, the LSP runs in the background and automatically catches framework convention violations — wrong controller names, missing methods, bad inheritance, file naming issues, and more. Claude sees these diagnostics and self-corrects without you having to notice or intervene.

**This is the recommended way to develop with Amber.** The LSP turns Claude Code from a general-purpose coding assistant into one that understands Amber's conventions natively.

### Quick Setup

```bash
# From your Amber project directory:
amber setup:lsp
```

This creates three files:

| File | Purpose |
|------|---------|
| `.lsp.json` | Tells Claude Code where the LSP binary is and what files it handles |
| `.claude-plugin/plugin.json` | Plugin manifest so Claude Code discovers the LSP |
| `.amber-lsp.yml` | Rule configuration — customize severity, disable rules, add custom rules |

Then open Claude Code in your project. The LSP activates automatically.

### What It Checks

The LSP ships with 15 built-in rules covering controllers, jobs, channels, pipes, mailers, schemas, routing, file naming, directory structure, and more. Every rule maps to an Amber convention — if Claude generates a controller that doesn't end with `Controller`, or a job without a `perform` method, the LSP flags it immediately.

### Custom Rules

You can define project-specific rules in `.amber-lsp.yml` using regex patterns. No recompilation needed:

```yaml
custom_rules:
- id: "project/no-puts"
description: "Do not use puts in production code"
severity: warning
applies_to: ["src/**"]
pattern: "^\\s*puts\\b"
message: "Avoid 'puts' in production code. Use Log.info instead."
```

### Building the LSP Binary

If `amber-lsp` is not on your PATH, the `setup:lsp` command will offer to build it:

```bash
cd ~/open_source_coding_projects/amber_cli
crystal build src/amber_lsp.cr -o bin/amber-lsp --release
```

For full documentation on all 15 rules, configuration options, and custom rule syntax, see the [LSP Setup Guide](https://github.com/crimson-knight/amber/blob/master/docs/guides/lsp-setup.md).

## 📚 Examples

### Generate a Blog Post Resource
Expand Down
Loading
Loading