Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
11b062c
docs: rewrite dynamic-domains-tls.md as the full-scope final plan
codad5 Jul 11, 2026
af89ed7
feat(server): default RABA_HTTPS_PORT to 7222, not 443
codad5 Jul 11, 2026
a56ee23
docs: document install-server.sh's real flow, add proxy/systemd templ…
codad5 Jul 11, 2026
bc6ec03
feat(server): add cert metadata columns to domains table
codad5 Jul 11, 2026
ccb1112
feat(server): add Cloudflare DNS API client for ACME challenges
codad5 Jul 11, 2026
1696333
feat(server): add ACME order/challenge/finalize flow via instant-acme
codad5 Jul 11, 2026
c244c7b
feat(server): add on-disk + in-memory cert store
codad5 Jul 11, 2026
b19f004
feat(server): wire a per-domain SNI cert resolver into https_listener.rs
codad5 Jul 11, 2026
d1b1a74
feat(server): add cert renewal background task, wire ACME automation …
codad5 Jul 11, 2026
06bfb98
feat(server): add team custom domain API, close the domain-hijack gap
codad5 Jul 11, 2026
aa4a4ce
feat(server): add rate limiting on /api/auth/login
codad5 Jul 11, 2026
b014e94
feat(server): add connection/stream caps
codad5 Jul 11, 2026
9ea3a46
feat(server): add structured fire-and-forget request logging
codad5 Jul 11, 2026
95862e3
feat(server): handle SIGINT/SIGTERM with a bounded shutdown grace period
codad5 Jul 11, 2026
1a405d7
feat(server): add plain-HTTP :80 listener that redirects to https://
codad5 Jul 12, 2026
9bb8605
feat(server): add traffic stats endpoints (Phase 10, last hardening i…
codad5 Jul 12, 2026
1009815
docs: fix stale systemd comment, document :80 passthrough-proxy gap
codad5 Jul 12, 2026
e7efbe7
feat(dashboard): wire the new traffic-stats endpoints into the UI
codad5 Jul 12, 2026
a4de958
fix(client): reconcile management_api.rs with the real server API
codad5 Jul 12, 2026
c922d8a
feat(dashboard): rebrand from placeholder blue to the real logo/accent
codad5 Jul 12, 2026
d64f09a
docs: add brand assets, LICENSE (FSL-1.1-ALv2), and a real README
codad5 Jul 12, 2026
8270164
ci: add ci.yml -- test + clippy on PR for all four subprojects
codad5 Jul 12, 2026
4322800
docs: mark ci.yml done in TODO.md
codad5 Jul 12, 2026
d89fd98
feat(dashboard): add custom-domain view/set/verify UI to TeamSettings
codad5 Jul 12, 2026
048d93f
feat(server,client): default project creation to the caller's oldest …
codad5 Jul 12, 2026
e997ce3
feat(server,client): explicit --domain project creation, scoped to ca…
codad5 Jul 12, 2026
cf2d494
feat(server): warn when a project silently falls back to the instance…
codad5 Jul 12, 2026
f4e8d01
feat(client): replace name-derived default subdomain with a random one
codad5 Jul 12, 2026
fa20657
Merge pull request #1 from codad5/phase10-followups-and-clients
codad5 Jul 12, 2026
e680ac3
fix(client): remove duplicated clippy::too_many_arguments attribute
codad5 Jul 12, 2026
f55ddc0
fix(brand): add a white-background lockup variant for the README
codad5 Jul 12, 2026
0b88ecb
feat(ci,install): finish Phase 9 -- release.yml + install scripts
codad5 Jul 13, 2026
a21ee95
feat(client): add raba update -- self-update via install.sh/install.ps1
codad5 Jul 13, 2026
75c71c4
fix(install): idempotency, real template fetching, port-driven proxy …
codad5 Jul 13, 2026
eb8b395
docs: bring TODO.md's Phase 9 and Brand/Assets tables current
codad5 Jul 13, 2026
cb3a833
feat(docs-site): finish the landing site -- real homepage, drop website/
codad5 Jul 13, 2026
502a902
docs(readme): add badges, standard structure, SEO-friendly intro
codad5 Jul 13, 2026
83a95ef
fix(server): collapse nested if-let into let-chains per CI's clippy
codad5 Jul 13, 2026
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
7 changes: 7 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Shell scripts must stay LF-only regardless of the checkout platform's
# git config (e.g. Windows' common core.autocrlf=true) -- a CRLF shebang
# line ("#!/usr/bin/env sh\r") fails outright on Linux/macOS. The scripts'
# primary documented usage (curl ... | sh) always fetches the raw LF blob
# from GitHub directly and is unaffected either way, but a local
# `git clone` + run-from-checkout should be safe too.
*.sh text eol=lf
93 changes: 93 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: CI

# TECH_DOC.md §9 Phase 9. Four independent jobs, one per subproject stack --
# nothing here depends on anything else, so they run in parallel rather
# than serialized. Each job runs exactly the commands already verified by
# hand against this repo (see TODO.md's Phase 9 row for when this was
# added): no step here should ever surprise a contributor who just ran the
# same command locally.
#
# rustfmt is deliberately NOT enforced yet -- the codebase isn't
# rustfmt-clean (a `cargo fmt --all` pass is its own separate, deliberate
# change, not bundled into standing up CI). clippy IS enforced
# (-D warnings) for both Rust jobs; both were brought to a clean slate
# before this workflow was written specifically so the gate isn't red on
# day one.

on:
pull_request:
push:
branches: [master]

env:
CARGO_TERM_COLOR: always

jobs:
server:
runs-on: ubuntu-latest
defaults:
run:
working-directory: server
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: server
- run: cargo test
- run: cargo clippy --all-targets -- -D warnings

client:
runs-on: ubuntu-latest
defaults:
run:
working-directory: client
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: client
# raba-napi builds as a plain cdylib crate under a normal `cargo
# build`/`test`/`clippy` -- the napi-rs CLI (`napi build`) is only
# needed to produce a distributable native binary, which is
# release.yml's job, not this one's.
- run: cargo test --workspace
- run: cargo clippy --workspace --all-targets -- -D warnings

dashboard:
runs-on: ubuntu-latest
defaults:
run:
working-directory: dashboard
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: dashboard/package-lock.json
- run: npm ci
- run: npx tsc --noEmit
- run: npm run lint
- run: npm run build

docs-site:
runs-on: ubuntu-latest
defaults:
run:
working-directory: docs-site
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: docs-site/package-lock.json
- run: npm ci
- run: npm run typecheck
- run: npm run build
62 changes: 62 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Deploy docs-site

# Builds docs-site (TODO.md's landing-site decision: this IS the landing
# site, a Docusaurus homepage + docs, not a separate marketing site --
# website/ was dropped) and publishes it to GitHub Pages on every push to
# master that touches docs-site/. Uses GitHub's own first-party Pages
# actions (configure-pages/upload-pages-artifact/deploy-pages), not a
# third-party gh-pages-branch action -- no extra token/secret needed
# beyond the built-in GITHUB_TOKEN, and it's the currently-recommended
# approach per GitHub's own docs.
#
# docusaurus.config.ts's url/baseUrl (https://codad5.github.io/raba/)
# assume Pages is enabled for this repo with source = GitHub Actions --
# a one-time manual step in the repo's Settings > Pages, not something a
# workflow file can do on its own.

on:
push:
branches: [master]
paths:
- "docs-site/**"
- ".github/workflows/deploy-docs.yml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: docs-site
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: docs-site/package-lock.json
- run: npm ci
- run: npm run build
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: docs-site/build

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
117 changes: 117 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Release

# TECH_DOC.md §9 Phase 9. Triggered by pushing a `v*` tag -- builds and
# publishes everything install.sh/install-server.sh need to actually work:
# a Docker image (GHCR) and pre-built binaries attached to the GitHub
# Release for that tag.
#
# Scope, deliberately: `raba-cli` covers linux-x86_64, macos-x86_64,
# macos-arm64, windows-x86_64 -- all native-runner builds, no cross-compile
# toolchain needed. The `server` binary covers linux-x86_64 only for now;
# linux-arm64 would need a Docker-based cross toolchain (`cross`) that
# can't be verified end-to-end without a real CI run, so it's left as a
# known, documented gap rather than shipped untested. Hand-rolled matrix
# build rather than cargo-dist (TODO.md originally named cargo-dist, but
# its setup is semi-interactive and generates its own workflow -- this is
# simpler to author correctly and fully inspect without that extra tool).

on:
push:
tags:
- "v*"

env:
CARGO_TERM_COLOR: always

jobs:
docker:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
file: docker/Dockerfile
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ github.ref_name }}
ghcr.io/${{ github.repository }}:latest

cli-binaries:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
asset: raba-cli-linux-x86_64.tar.gz
# Intel macOS runner -- verify this label is still current
# against GitHub's runner docs before relying on it; GitHub has
# changed default macOS runner architectures before.
- os: macos-13
target: x86_64-apple-darwin
asset: raba-cli-macos-x86_64.tar.gz
# Apple Silicon (arm64) macOS runner.
- os: macos-latest
target: aarch64-apple-darwin
asset: raba-cli-macos-arm64.tar.gz
- os: windows-latest
target: x86_64-pc-windows-msvc
asset: raba-cli-windows-x86_64.zip
runs-on: ${{ matrix.os }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
workspaces: client
- name: Build
working-directory: client
run: cargo build --release -p raba-cli --target ${{ matrix.target }}

- name: Package (Unix)
if: runner.os != 'Windows'
run: |
tar czf ${{ matrix.asset }} -C client/target/${{ matrix.target }}/release raba-cli

- name: Package (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Compress-Archive -Path client/target/${{ matrix.target }}/release/raba-cli.exe -DestinationPath ${{ matrix.asset }}

- uses: softprops/action-gh-release@v2
with:
files: ${{ matrix.asset }}

server-binary:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: server
- name: Build
working-directory: server
run: cargo build --release
- name: Package
run: tar czf raba-server-linux-x86_64.tar.gz -C server/target/release server
- uses: softprops/action-gh-release@v2
with:
files: raba-server-linux-x86_64.tar.gz
54 changes: 54 additions & 0 deletions BRAND.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Brand

## Name

*raba* is Hausa for "to divide, separate, share, or distribute." Both senses map onto what
the tool does: "share/distribute" is the pitch — share your localhost with the world.
"Divide/separate" is the problem being solved — bridging a machine that's cut off from the
public internet by NAT or a firewall.

## Logo

The mark is an arch bridging two connection points: a direct read of both senses of the
name above — the arch is the connection made, the two points are what's being bridged.

<p>
<img src="docs-site/static/img/brand/mark.svg" alt="raba mark" width="80" />
</p>

- Rounded-square badge, dark neutral background (`#111827`).
- A single smooth arch, stroked in green (`#22C55E`) — the connection made across the divide.
- Two connection-point circles in orange (`#F97316`) at the arch's base — the two things
being bridged.
- Flat fills only — no gradients, shadows, or 3D effects.

## Wordmark

`raba`, always lowercase, sans-serif, medium weight. Optional tagline beneath, small and
muted: "share your localhost."

## Color palette

| Role | Hex |
|---|---|
| Badge background | `#111827` |
| Bridge arch | `#22C55E` |
| Connection points | `#F97316` |

## Assets

All variants live in [`docs-site/static/img/brand/`](docs-site/static/img/brand/):

| File | Use |
|---|---|
| `mark.svg` | Badge alone — favicon, avatar, terminal splash |
| `wordmark.svg` | Text only, no badge |
| `lockup-compact.svg` | Badge + wordmark, no tagline — app/dashboard headers |
| `lockup-full.svg` | Badge + wordmark + tagline, transparent background — marketing pages |
| `lockup-full-white-bg.svg` | Same, with padding, a rounded card corner, and a white background — used in the README, for contexts (like GitHub's dark mode) that can't guarantee a light viewing surface |

## What to avoid

Literal pipe/tube imagery, 3D effects or drop shadows, extra accent colors beyond the two
above, capitalized/stylized treatments of the wordmark ("Raba", "RABA"), and putting the
tagline inside the badge itself.
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ See `TECH_DOC.md` for the full technical spec and `TODO.md` for live task/phase

## Git workflow

- Commit **stage by stage, module by module** — not one giant scaffold commit. Each top-level folder/crate (`server/`, `client/raba-core`, `client/raba-cli`, `client/raba-napi`, `dashboard/`, `docs-site/`, `website/`, docker/CI config, etc.) gets its own commit so git history shows what was set up for each piece.
- Commit **stage by stage, module by module** — not one giant scaffold commit. Each top-level folder/crate (`server/`, `client/raba-core`, `client/raba-cli`, `client/raba-napi`, `dashboard/`, `docs-site/`, docker/CI config, etc.) gets its own commit so git history shows what was set up for each piece.
- Before committing a Rust crate, run `cargo build` (via PowerShell, since it may need to fetch deps) to confirm it actually compiles.
- Update `TODO.md` after every commit — flip the relevant status to `[x]`/`[~]` and add notes. This is a standing rule, not a one-off.

Expand All @@ -25,4 +25,4 @@ See `TECH_DOC.md` for the full technical spec and `TODO.md` for live task/phase

## Landing site

- `website/` (Astro) is the marketing/landing site — added by decision, not in the original `TECH_DOC.md`. Distinct from `docs-site/` (Docusaurus docs, also not bundled in Docker) and `dashboard/` (the product's own web UI, which the server binary embeds/serves).
- `docs-site/` (Docusaurus) is both the docs *and* the marketing/landing site — `src/pages/index.tsx` is the real homepage (hero, feature overview, install snippet), not just a docs index. A separate `website/` (Astro) existed briefly but was merged into `docs-site/` and removed 2026-07-13 (see `TODO.md`'s Landing/Marketing Site section) — one framework/deploy target instead of two. Not bundled in the Docker image. Distinct from `dashboard/` (the product's own web UI, which the server binary embeds/serves).
Loading
Loading