Skip to content

Commit 8f4ee4b

Browse files
ajianazCTO Hermes
andauthored
chore: prepare v0.1.3 release — docs, website, release workflow (#63)
- Bump version 0.1.2 → 0.1.3 in Cargo.toml - CHANGELOG: add v0.1.3 section, update comparison links - Add AGENT.md for AI-assisted development onboarding - Release notes: hybrid template (dynamic changelog + static platforms/quickstart) - Website: add /docs/changelog page with CHANGELOG.md rendering - Website: fix config page — correct priority order, update YAML schema example - Website: add Changelog to docs sidebar navigation - README: cora review → cora review --staged (explicit intent) Co-authored-by: CTO Hermes <cto-hermes@users.noreply.github.com>
1 parent c607e74 commit 8f4ee4b

9 files changed

Lines changed: 293 additions & 67 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -129,55 +129,35 @@ jobs:
129129
id: version
130130
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
131131

132-
- name: Generate release notes
132+
- name: Extract changelog for this version
133+
id: changelog
133134
run: |
134-
cat > release-notes.md << 'EOF'
135-
## What's New in VERSION
136-
137-
### 🚀 Features
138-
139-
- **AI Code Review** — diff, branch comparison, full project scan
140-
- **BYOK** — bring your own API key (OpenAI, Anthropic, Groq, Ollama, Z.AI)
141-
- **Pre-commit Hooks** — `cora hook install` for automatic review on every commit
142-
- **Incremental Scan** — `cora scan --incremental` with SHA256 content hash cache
143-
- **SARIF Output** — upload findings to GitHub Code Scanning
144-
- **Streaming** — real-time review output with `--stream`
145-
- **Shell Completions** — `cora completion bash|zsh|fish|powershell`
146-
- **5 Providers** — OpenAI, Anthropic, Groq, Ollama, Z.AI with auto-detection
147-
- **Project Config** — `.cora.yaml` per-project configuration
148-
- **MIT License** — fully open source
149-
150-
### 📦 Platforms
151-
152-
| Platform | File |
153-
|----------|------|
154-
| Linux (x86_64) | `cora-x86_64-unknown-linux-gnu-VERSION.tar.gz` |
155-
| Linux (ARM64) | `cora-aarch64-unknown-linux-gnu-VERSION.tar.gz` |
156-
| macOS (Apple Silicon) | `cora-aarch64-apple-darwin-VERSION.tar.gz` |
157-
| Windows (x86_64) | `cora-x86_64-pc-windows-msvc-VERSION.zip` |
158-
159-
### 🚀 Quick Start
160-
161-
```bash
162-
# Install via cargo
163-
cargo install cora
164-
165-
# Or download binary (extracts as 'cora')
166-
curl -fsSL https://github.com/ajianaz/cora-cli/releases/latest/download/cora-x86_64-unknown-linux-gnu-VERSION.tar.gz | tar xz
167-
chmod +x cora
168-
sudo mv cora /usr/local/bin/
169-
170-
# Init project
171-
cora init
172-
173-
# Review staged changes
174-
CORA_API_KEY=your-key cora review --staged
175-
```
176-
177-
**Full changelog:** https://github.com/ajianaz/cora-cli/blob/main/CHANGELOG.md
178-
179-
EOF
180-
sed -i "s/VERSION/${{ steps.version.outputs.VERSION }}/g" release-notes.md
135+
CHANGELOG_EXCERPT=$(sed -n '/^## \['"${{ steps.version.outputs.VERSION }}"'\]/,/^## \[/p' CHANGELOG.md | sed '$d' | tail -n +2)
136+
{
137+
printf '## What'\''s New in %s\n\n' "${{ steps.version.outputs.VERSION }}"
138+
printf '%s\n\n' "$CHANGELOG_EXCERPT"
139+
printf '### 📦 Platforms\n\n'
140+
printf '| Platform | File |\n'
141+
printf '|----------|------|\n'
142+
printf '| Linux (x86_64) | `cora-x86_64-unknown-linux-gnu-%s.tar.gz` |\n' "${{ steps.version.outputs.VERSION }}"
143+
printf '| Linux (ARM64) | `cora-aarch64-unknown-linux-gnu-%s.tar.gz` |\n' "${{ steps.version.outputs.VERSION }}"
144+
printf '| macOS (Apple Silicon) | `cora-aarch64-apple-darwin-%s.tar.gz` |\n' "${{ steps.version.outputs.VERSION }}"
145+
printf '| Windows (x86_64) | `cora-x86_64-pc-windows-msvc-%s.zip` |\n\n' "${{ steps.version.outputs.VERSION }}"
146+
printf '### 🚀 Quick Start\n\n'
147+
printf '```bash\n'
148+
printf '# Install via cargo\n'
149+
printf 'cargo install cora\n\n'
150+
printf '# Or download binary (extracts as '\''cora'\'')\n'
151+
printf 'curl -fsSL https://github.com/ajianaz/cora-cli/releases/latest/download/cora-x86_64-unknown-linux-gnu-%s.tar.gz | tar xz\n' "${{ steps.version.outputs.VERSION }}"
152+
printf 'chmod +x cora\n'
153+
printf 'sudo mv cora /usr/local/bin/\n\n'
154+
printf '# Init project\n'
155+
printf 'cora init\n\n'
156+
printf '# Review staged changes\n'
157+
printf 'CORA_API_KEY=your-key cora review --staged\n'
158+
printf '```\n\n'
159+
printf '**Full changelog:** https://github.com/ajianaz/cora-cli/blob/develop/CHANGELOG.md\n'
160+
} > release-notes.md
181161
182162
- name: Create GitHub Release
183163
uses: softprops/action-gh-release@v2

‎AGENT.md‎

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# AGENT.md — AI-Assisted Development Onboarding
2+
3+
## Project Overview
4+
5+
**cora-cli** is a Rust CLI tool for AI-powered code review. Bring Your Own Keys (BYOK) —
6+
no managed API, no cloud service. Runs locally against diffs, scans, or branches.
7+
8+
- **License:** MIT
9+
- **Edition:** Rust 2024 (MSRV 1.85)
10+
- **Repo:** `ajianaz/cora-cli`
11+
- **Default branch:** `develop`
12+
13+
## Build & Development Commands
14+
15+
```bash
16+
cargo build # Build (debug)
17+
cargo build --release # Build (release)
18+
cargo test # Run all 151 tests
19+
cargo clippy # Lint
20+
cargo fmt # Format check (use -- --check for CI)
21+
```
22+
23+
## Code Structure (`src/`)
24+
25+
```
26+
src/
27+
├── main.rs # Entry point, CLI argument parsing
28+
├── commands/ # Subcommand handlers
29+
│ ├── mod.rs
30+
│ ├── review.rs # cora review (diff-based review)
31+
│ ├── scan.rs # cora scan (full-file scan)
32+
│ ├── config_cmd.rs # cora config (show/validate)
33+
│ ├── auth.rs # cora auth (API key management)
34+
│ ├── hook_cmd.rs # cora hook (pre-commit hook install/uninstall)
35+
│ ├── init.rs # cora init (project scaffolding)
36+
│ ├── upload.rs # cora upload (review upload)
37+
│ ├── completion.rs # Shell completion generation
38+
│ └── providers.rs # cora providers (list providers)
39+
├── config/
40+
│ ├── mod.rs
41+
│ ├── schema.rs # Config structs & defaults
42+
│ ├── loader.rs # Config loading & priority chain
43+
│ └── providers.rs # LLM provider definitions
44+
├── engine/
45+
│ ├── mod.rs
46+
│ ├── review.rs # Review orchestration logic
47+
│ ├── scanner.rs # File scanning engine
48+
│ ├── llm.rs # LLM API interaction
49+
│ └── types.rs # Severity, finding, and result types
50+
├── formatters/ # Output format implementations
51+
│ ├── mod.rs
52+
│ ├── pretty.rs # Human-readable terminal output
53+
│ ├── compact.rs # Compact single-line output
54+
│ ├── json_fmt.rs # JSON output
55+
│ └── sarif.rs # SARIF format (CI integration)
56+
├── git/
57+
│ ├── mod.rs
58+
│ ├── diff.rs # Git diff parsing
59+
│ └── files.rs # File listing & filtering
60+
└── hook/
61+
├── mod.rs
62+
├── install.rs # Hook install/uninstall logic
63+
└── template.rs # Hook script templates
64+
```
65+
66+
## Key Files
67+
68+
| File | Purpose |
69+
|---|---|
70+
| `commands/config_cmd.rs` | Config subcommand — display, validate, path resolution |
71+
| `config/loader.rs` | Config loading with full priority chain resolution |
72+
| `config/schema.rs` | All config structs, defaults, serde annotations |
73+
| `commands/init.rs` | Project scaffolding, `.cora.yaml` generation |
74+
75+
## Testing
76+
77+
```bash
78+
cargo test # 151 tests total
79+
# 129 unit tests
80+
# 16 CLI integration tests
81+
# 6 config tests
82+
cargo test --no-verify # Skip pre-commit hooks (avoids timeout in hooks)
83+
```
84+
85+
Use `--no-verify` when running tests through pre-commit hooks to prevent nested
86+
hook execution and timeouts.
87+
88+
## CI/CD
89+
90+
Three GitHub Actions workflows in `.github/workflows/`:
91+
92+
1. **ci.yml** — PR checks: build, test, clippy, fmt on push to `develop` and PRs
93+
2. **release.yml** — Triggered by `v*` tags; builds for 4 platforms (Linux x86_64,
94+
macOS x86_64, macOS ARM64, Windows x86_64), publishes to crates.io
95+
3. **deploy-website.yml** — Deploys project website/docs
96+
97+
## Config System
98+
99+
### Priority Chain (highest to lowest)
100+
101+
1. **CLI flags** (`--provider`, `--model`, etc.)
102+
2. **Environment variables** (`CORA_PROVIDER`, `CORA_MODEL`, etc.)
103+
3. **Project config** (`.cora.yaml` in repo root)
104+
4. **Global config** (`~/.cora/config.yaml`)
105+
5. **Built-in defaults** (defined in `config/schema.rs`)
106+
107+
### Auth Separation
108+
109+
API keys live in a separate `auth.toml` file (`~/.cora/auth.toml`), not in
110+
`.cora.yaml`. This prevents accidental key leakage via committed config files.
111+
112+
## Design Decisions
113+
114+
- **Severity comparison uses `<=` not `>=`**: Severity filtering uses `<=` because
115+
the ordinal maps info=1, warning=2, error=3 — so `--severity warning` means
116+
"include warning and below (info)", not "warning and above (error)". This is
117+
intentional; the mapping is defined in `engine/types.rs`.
118+
- **TOML → YAML migration**: Config format migrated from TOML to YAML for better
119+
readability and broader tooling support. The loader only reads YAML now.
120+
- **Auth/config separation**: API keys are deliberately stored in `auth.toml`
121+
rather than the main config to allow `.cora.yaml` to be safely committed to
122+
repositories without exposing secrets.

‎CHANGELOG.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.1.3] - 2026-06-01
11+
1012
### Added
1113

1214
- `cora config set --global` — write config to `~/.cora/config.yaml` instead of project `.cora.yaml`
@@ -86,7 +88,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8688
- **Cross-platform** — Linux (x86_64, ARM64), macOS (Apple Silicon), Windows (x86_64)
8789
- **MIT License** — fully open source
8890

89-
[Unreleased]: https://github.com/ajianaz/cora-cli/compare/v0.1.2...develop
91+
[Unreleased]: https://github.com/ajianaz/cora-cli/compare/v0.1.3...develop
92+
[0.1.3]: https://github.com/ajianaz/cora-cli/compare/v0.1.2...v0.1.3
9093
[0.1.2]: https://github.com/ajianaz/cora-cli/compare/v0.1.1...v0.1.2
9194
[0.1.1]: https://github.com/ajianaz/cora-cli/compare/v0.1.0...v0.1.1
9295
[0.1.0]: https://github.com/ajianaz/cora-cli/releases/tag/v0.1.0

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cora-cli"
3-
version = "0.1.2"
3+
version = "0.1.3"
44
edition = "2024"
55
description = "CLI-first AI code review — BYOK, diff/scan/branch, pre-commit hooks"
66
license = "MIT"

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ cora init
8888
### 3. Review Staged Changes
8989

9090
```bash
91-
cora review
91+
cora review --staged
9292
```
9393

9494
### 4. Review the Last Commit

‎website/src/app.d.ts‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,10 @@ declare global {
1010
}
1111
}
1212

13+
// Allow ?raw imports for markdown files
14+
declare module '*?raw' {
15+
const content: string;
16+
export default content;
17+
}
18+
1319
export {};

‎website/src/routes/docs/+layout.svelte‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
{ href: '/docs/providers', label: 'Providers' },
1212
{ href: '/docs/examples', label: 'Examples' },
1313
{ href: '/docs/cli-reference', label: 'CLI Reference' },
14+
{ href: '/docs/changelog', label: 'Changelog' },
1415
];
1516
</script>
1617

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<script lang="ts">
2+
import { onMount } from 'svelte';
3+
import changelogRaw from '../../../CHANGELOG.md?raw';
4+
5+
interface ChangelogSection {
6+
version: string;
7+
date: string;
8+
url: string;
9+
categories: { type: string; items: string[] }[];
10+
}
11+
12+
const REPO = 'https://github.com/ajianaz/cora-cli';
13+
14+
function parseChangelog(md: string): ChangelogSection[] {
15+
const sections: ChangelogSection[] = [];
16+
// Split into version sections at ## headers
17+
const blocks = md.split(/^## \[/m);
18+
for (const block of blocks) {
19+
const headerMatch = block.match(/^\[([^\]]+)\]\s*(?:-\s*)?(\d{4}-\d{2}-\d{2})/);
20+
if (!headerMatch) continue;
21+
const version = headerMatch[1];
22+
const date = headerMatch[2];
23+
24+
// Skip Unreleased if empty (no ### headers with content)
25+
if (version === 'Unreleased' && !block.match(/^###\s+\w+/m)) continue;
26+
27+
const categories: { type: string; items: string[] }[] = [];
28+
const catBlocks = block.split(/^###\s+/m);
29+
for (const catBlock of catBlocks) {
30+
const catMatch = catBlock.match(/^(\w[\w\s]*?)(?:\s*)\n([\s\S]*)$/);
31+
if (!catMatch) continue;
32+
const type = catMatch[1].trim();
33+
const items = catMatch[2]
34+
.split('\n')
35+
.map((l) => l.replace(/^-\s*/, '').trim())
36+
.filter(Boolean);
37+
if (items.length > 0) {
38+
categories.push({ type, items });
39+
}
40+
}
41+
42+
// Build compare URL
43+
let url: string;
44+
if (version === 'Unreleased') {
45+
url = `${REPO}/compare/v0.1.3...develop`;
46+
} else {
47+
url = `${REPO}/releases/tag/v${version}`;
48+
}
49+
50+
sections.push({ version, date, url, categories });
51+
}
52+
return sections;
53+
}
54+
55+
const releases = parseChangelog(changelogRaw);
56+
57+
onMount(() => {
58+
const observer = new IntersectionObserver(
59+
(entries) => {
60+
entries.forEach((entry) => {
61+
if (entry.isIntersecting) {
62+
entry.target.classList.add('revealed');
63+
observer.unobserve(entry.target);
64+
}
65+
});
66+
},
67+
{ threshold: 0.1 }
68+
);
69+
document.querySelectorAll('.scroll-reveal').forEach((el) => observer.observe(el));
70+
return () => observer.disconnect();
71+
});
72+
</script>
73+
74+
<svelte:head>
75+
<title>Changelog — cora docs</title>
76+
<meta name="description" content="cora-cli changelog — release history and version notes." />
77+
</svelte:head>
78+
79+
<div class="docs-content">
80+
<h1 class="scroll-reveal">Changelog</h1>
81+
<p class="scroll-reveal text-[var(--muted-foreground)]">
82+
For the full changelog, see the
83+
<a href="{REPO}/blob/develop/CHANGELOG.md" class="text-[var(--accent)] hover:underline" target="_blank" rel="noopener noreferrer">repository</a>.
84+
</p>
85+
86+
{#each releases as release, i}
87+
<section class="docs-section scroll-reveal">
88+
<h2 class="flex items-center gap-3">
89+
{#if release.version === 'Unreleased'}
90+
<span class="inline-flex items-center gap-1.5 px-2 py-0.5 text-xs font-medium rounded-full bg-[var(--accent)]/15 text-[var(--accent)] border border-[var(--accent)]/25">
91+
Unreleased
92+
</span>
93+
{:else}
94+
<a href={release.url} class="text-[var(--accent)] hover:underline no-underline" target="_blank" rel="noopener noreferrer">
95+
v{release.version}
96+
</a>
97+
{/if}
98+
<span class="text-sm font-normal text-[var(--muted-foreground)]">{release.date}</span>
99+
</h2>
100+
101+
{#each release.categories as category}
102+
<div class="mt-4">
103+
<h3 class="text-sm font-semibold uppercase tracking-wider text-[var(--muted-foreground)] mb-2">{category.type}</h3>
104+
<ul class="list-disc list-outside ml-4 flex flex-col gap-1.5">
105+
{#each category.items as item}
106+
<li class="text-[var(--foreground)] text-sm leading-relaxed pl-1">{@html item}</li>
107+
{/each}
108+
</ul>
109+
</div>
110+
{/each}
111+
</section>
112+
{/each}
113+
</div>

0 commit comments

Comments
 (0)