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
2 changes: 1 addition & 1 deletion .claude/rules/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ If either is wrong, stop and fix it before proceeding.
glb update <num> --claim
```

Commit semi-frequently - don't save everything for one giant commit.
Commit semi-frequently - don't save everything for one giant commit. Use **conventional commits** (`feat:`, `fix:`, `chore:`, `docs:`, `ci:`, `refactor:`, `test:`). Append `!` for breaking changes (e.g. `feat!:`). These prefixes drive automatic version bumps and changelog generation via release-please.

**Before every commit**, run `cargo fmt` (and `floe fmt` if you touched `.fl` files). Never commit unformatted code.

Expand Down
12 changes: 12 additions & 0 deletions .github/release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"packages": {
".": {
"release-type": "rust",
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": true,
"extra-files": [
"crates/floe-wasm/Cargo.toml"
]
}
}
}
3 changes: 3 additions & 0 deletions .github/release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.1.0"
}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Tests
run: cargo test

- name: Build release for LSP tests
- name: Build for integration tests
run: cargo build

- name: Setup Node.js
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Release Please

on:
push:
branches: [main]

permissions:
contents: write
pull-requests: write

jobs:
release-please:
runs-on: ubuntu-latest
outputs:
release_created: ${{ steps.release.outputs.release_created }}
tag_name: ${{ steps.release.outputs.tag_name }}
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
config-file: .github/release-please-config.json
manifest-file: .github/release-please-manifest.json
167 changes: 167 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: Release

on:
push:
tags: ["v*"]

permissions:
contents: write

env:
CARGO_TERM_COLOR: always

jobs:
build:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive: tar.gz
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
archive: tar.gz
cross: true
- target: x86_64-apple-darwin
os: macos-latest
archive: tar.gz
- target: aarch64-apple-darwin
os: macos-latest
archive: tar.gz
- target: x86_64-pc-windows-msvc
os: windows-latest
archive: zip

steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.94.0"
targets: ${{ matrix.target }}

- name: Install cross
if: matrix.cross
run: cargo install cross --locked

- name: Build
run: |
if [ "${{ matrix.cross }}" = "true" ]; then
cross build --release --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
fi
shell: bash

- name: Package (unix)
if: matrix.archive == 'tar.gz'
run: |
cd target/${{ matrix.target }}/release
tar czf ../../../floe-${{ matrix.target }}.tar.gz floe
shell: bash

- name: Package (windows)
if: matrix.archive == 'zip'
run: |
cd target/${{ matrix.target }}/release
7z a ../../../floe-${{ matrix.target }}.zip floe.exe
shell: bash

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: floe-${{ matrix.target }}
path: floe-${{ matrix.target }}.${{ matrix.archive }}

release:
name: Create Release
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: artifacts/*

publish-crate:
name: Publish to crates.io
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.94.0"

- name: Publish
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}

publish-npm:
name: Publish to npm
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: https://registry.npmjs.org

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Install dependencies
run: pnpm install

- name: Build and publish Vite plugin
working-directory: integrations/vite-plugin-floe
run: |
pnpm build
npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

publish-extension:
name: Publish to Open VSX
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22

- name: Install dependencies
working-directory: editors/vscode
run: npm install

- name: Build extension
working-directory: editors/vscode
run: npm run compile

- name: Install ovsx
run: npm install -g ovsx

- name: Publish to Open VSX
working-directory: editors/vscode
run: ovsx publish -p ${{ secrets.OVSX_TOKEN }}
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Changelog

All notable changes to Floe will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/),
and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Added
- Pipe operator (`|>`) with first-arg default and `_` placeholder
- Exhaustive pattern matching with `match` expressions
- Result (`Ok`/`Err`) and Option (`Some`/`None`) types
- `?` operator for Result/Option unwrapping
- Tagged unions with multi-depth matching
- Branded and opaque types
- Type constructors with named arguments and defaults
- Pipe lambdas (`|x| expr`) and dot shorthand (`.field`)
- JSX support with inline match and pipe expressions
- Language server with diagnostics, completions, and go-to-definition
- Code formatter (`floe fmt`)
- Vite plugin for dev/build integration
- VS Code extension with syntax highlighting and LSP
- Browser playground (WASM)
- `floe init` project scaffolding
- `floe watch` for auto-recompilation
57 changes: 55 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,62 @@

Do **not** use parser generators (pest, nom, lalrpop). The parser is handwritten recursive descent for better error recovery and LSP integration.

## Commits
## Releases & Versioning

Use **conventional commits** for all commit messages and PR titles. Prefixes: `feat:`, `fix:`, `chore:`, `test:`. This is required for automated versioning with release-please. See `.claude/rules/workflow.md` for details.
This project uses **conventional commits** + **release-please** for automated versioning and releases.

### How it works

1. **You write commits with prefixes:**

| Prefix | Version bump | Example |
|---|---|---|
| `fix:` | patch (0.1.0 -> 0.1.1) | `fix: crash on nested match` |
| `feat:` | minor (0.1.0 -> 0.2.0) | `feat: add pipe lambdas` |
| `feat!:` | major (0.1.0 -> 1.0.0) | `feat!: remove arrow functions` |
| `chore:`, `docs:`, `ci:`, `refactor:`, `test:` | no bump | `docs: update README` |

2. **release-please watches main** and auto-opens a "Release PR" that:
- Bumps the version in `Cargo.toml` based on commit prefixes
- Updates `CHANGELOG.md` with entries generated from commit messages
- Title looks like `chore(main): release 0.2.0`

3. **Merging the Release PR** creates a git tag (`v0.2.0`) and a GitHub Release.

4. **The tag triggers the release workflow** which:
- Cross-compiles binaries for macOS (arm64 + x86), Linux (x86 + arm64), Windows
- Uploads them as assets on the GitHub Release
- Publishes `floe` to crates.io
- Publishes `@floelang/vite-plugin` to npm
- Publishes the VS Code extension to Open VSX

### Package names

| Package | Registry | Name |
|---|---|---|
| Compiler CLI | crates.io | `floe` |
| Vite plugin | npm | `@floelang/vite-plugin` |
| VS Code extension | Open VSX | `floelang.floe` |

### What you need to do

- Write meaningful conventional commit messages (the CHANGELOG is generated from them)
- Periodically merge the Release PR that release-please opens
- That's it - everything else is automated

### Config files

| File | Purpose |
|---|---|
| `.github/release-please-config.json` | release-please settings (release type, extra files to bump) |
| `.github/release-please-manifest.json` | current version tracking |
| `.github/workflows/release-please.yml` | workflow that opens Release PRs |
| `.github/workflows/release.yml` | workflow that builds binaries on tag push |
| `CHANGELOG.md` | auto-maintained changelog |

### Pre-1.0 strategy

While pre-1.0, breaking changes bump minor (0.1 -> 0.2) not major. Go to 1.0.0 when the language syntax is stable and people are using it in real projects.

<!-- glb-agent-instructions -->
## Task Tracking with glb
Expand Down
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ resolver = "3"
name = "floe"
version = "0.1.0"
edition = "2024"
description = "A programming language that compiles to TypeScript + React"
license = "MIT"
repository = "https://github.com/milkyskies/floe"
homepage = "https://github.com/milkyskies/floe"
keywords = ["compiler", "typescript", "react", "programming-language"]
categories = ["compilers", "development-tools"]
readme = "README.md"

[lib]
name = "floe"
Expand Down
4 changes: 4 additions & 0 deletions crates/floe-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
name = "floe-wasm"
version = "0.1.0"
edition = "2024"
description = "WASM build of the Floe compiler for browser usage"
license = "MIT"
repository = "https://github.com/milkyskies/floe"
publish = false

[lib]
crate-type = ["cdylib", "rlib"]
Expand Down
8 changes: 4 additions & 4 deletions docs/site/src/content/docs/tooling/vite.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
title: Vite Plugin
---

The `vite-plugin-floe` package lets Vite transform `.fl` files during development and production builds.
The `@floelang/vite-plugin` package lets Vite transform `.fl` files during development and production builds.

## Installation

```bash
npm install -D vite-plugin-floe
npm install -D @floelang/vite-plugin
```

Make sure `floe` is installed and available in your PATH.
Expand All @@ -17,7 +17,7 @@ Make sure `floe` is installed and available in your PATH.
```typescript
// vite.config.ts
import { defineConfig } from "vite"
import floe from "vite-plugin-floe"
import floe from "@floelang/vite-plugin"

export default defineConfig({
plugins: [floe()],
Expand Down Expand Up @@ -46,7 +46,7 @@ floe({
// vite.config.ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import floe from "vite-plugin-floe"
import floe from "@floelang/vite-plugin"

export default defineConfig({
plugins: [
Expand Down
5 changes: 5 additions & 0 deletions editors/vscode/icons/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Extension icons needed:

- `floe-icon.png` - 128x128, used as the VS Code Marketplace icon
- `floe-light.png` - file icon for `.fl` files in light themes
- `floe-dark.png` - file icon for `.fl` files in dark themes
4 changes: 3 additions & 1 deletion editors/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"displayName": "Floe",
"description": "Language support for Floe (.fl) - syntax highlighting, diagnostics, and LSP integration",
"version": "0.1.0",
"publisher": "floe",
"license": "MIT",
"publisher": "floelang",
"icon": "icons/floe-icon.png",
"repository": {
"type": "git",
"url": "https://github.com/milkyskies/floe"
Expand Down
Loading
Loading