Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
226 commits
Select commit Hold shift + click to select a range
5fc2876
feat: added initial configuration discovery + plan.
Blankeos Jan 31, 2026
f896f2d
feat: added basic themes dialog, got my themes from officially the
Blankeos Jan 31, 2026
f3b4b2f
feat: basic theme preview as selection goes.
Blankeos Jan 31, 2026
30cec4f
feat: complete work of art for the theme-token usage. It works.
Blankeos Jan 31, 2026
5250496
feat: proper status bar theme usage. (branch)
Blankeos Jan 31, 2026
1ce44a6
feat: perfect search UX
Blankeos Jan 31, 2026
ef06df6
fix: fixed the `esc` in the dialog to stick to the right.
Blankeos Jan 31, 2026
f6b04cc
feat: lower scroll speed so it doesn't feel janky.
Blankeos Feb 2, 2026
4c8947f
fix: 'qui' instead of 'quit' (cutoff).
Blankeos Feb 2, 2026
e8598c6
docs: added some todos.
Blankeos Feb 2, 2026
5da9604
fix: ctrl+a in /models and a few jank fixes.
Blankeos Feb 2, 2026
3b09cbf
docs: initial docs w/ gittydocs.
Blankeos Feb 2, 2026
03fc787
feat: keep focus on the currently selected item even after ctrl+f to
Blankeos Feb 2, 2026
6a09831
feat: Add accurate token counting during streaming responses
Blankeos Feb 7, 2026
d402a4f
feat: hide modal when click outside.
Blankeos Feb 7, 2026
2c6594c
feat: Add built-in sound effects for error and complete events
Blankeos Feb 13, 2026
e6c47b1
docs: Add bundled sound defaults and JSON schema for config
Blankeos Feb 13, 2026
ab208a5
docs: better docs.
Blankeos Feb 14, 2026
f20543e
feat: added npm release scripts
Blankeos Feb 14, 2026
46205ff
docs: added banner image.
Blankeos Feb 14, 2026
740dfb0
docs: more install options.
Blankeos Feb 14, 2026
12a04d3
feat: added 'notify' feature along w/ the sounds.
Blankeos Feb 14, 2026
aa083c8
feat: a lot better theme for Plan and Build agents.
Blankeos Feb 14, 2026
cc0bbe0
feat: BIG completely revamped toasts. No more ratatui_toolkit.
Blankeos Feb 14, 2026
971599f
chore: added more todos for myself.
Blankeos Feb 14, 2026
a736169
feat: better markdown color themes.
Blankeos Feb 14, 2026
c9436d2
feat: added permission-gated tool calls and agent-specific tools (Plan
Blankeos Feb 14, 2026
4ebef58
chore: fmt.
Blankeos Feb 14, 2026
b66ba3b
fix: popup padding commands.
Blankeos Feb 14, 2026
a59bf81
fix: border-l of my chat messages.
Blankeos Feb 14, 2026
aa8d671
fix: minor spacings in scrollbar stuff.
Blankeos Feb 14, 2026
20cc17c
fix: for sessions and themes dialogs. autofocus what is current.
Blankeos Feb 14, 2026
b3cb516
chore: just local dev stuff.
Blankeos Feb 14, 2026
beeb39f
chore: put plans in _plans.
Blankeos Feb 14, 2026
a55d27e
chore: used the crabcode branch for my aisdk-rs fork.
Blankeos Feb 14, 2026
7283a96
feat: openai codex oauth.
Blankeos Feb 16, 2026
23c348a
feat: Infinite steps + more consistent timeout w/ opencode.
Blankeos Feb 16, 2026
5af521b
feat: better permission dialog (not exactly a dialog anymore).
Blankeos Feb 16, 2026
e22e764
refactor: Refactor LLM client into modular components
Blankeos Feb 16, 2026
cc1dd55
Update tag_and_release.sh
Blankeos Mar 28, 2026
854791f
chore: install script for linux/macos via curl.
Blankeos Mar 28, 2026
693e534
chore: remove ralphy.
Blankeos May 9, 2026
183e38e
feat: add skills dialog and update OpenAI provider API.
Blankeos May 9, 2026
a93f624
feat: implement skills system with file-system discovery and tool int…
Blankeos May 9, 2026
38f4aff
feat: include item tips in dialog search matching.
Blankeos May 9, 2026
e8f01c8
feat: mascot done.
Blankeos May 9, 2026
07c53ff
feat: add hidden token support for command aliases.
Blankeos May 9, 2026
1a37353
feat: add session resume CLI flag, remove landing page, simplify mode…
Blankeos May 9, 2026
ee5e299
feat(session): use cuid2 identifiers instead of sequential names for …
Blankeos May 9, 2026
44094db
feat: add timeline dialog and text selection with copy-on-select.
Blankeos May 9, 2026
a648950
feat: simplify timeline dialog and fix mouse selection behavior.
Blankeos May 9, 2026
46e3234
feat: add message actions dialog with copy/fork/undo, chat-only comma…
Blankeos May 9, 2026
cf4c6dc
chore: added opencode ai plugin.
Blankeos May 9, 2026
3c7e456
feat: add print mode, session cost tracking, mascot animation, and tr…
Blankeos May 9, 2026
98260df
feat: added /rename <opt:newname> command.
Blankeos May 9, 2026
42a287f
fix(pref): cache chat rendering and adapt event loop poll rate to red…
Blankeos May 9, 2026
6288bca
feat: show token usage as percentage of model limit, fix UTF-8 trunca…
Blankeos May 9, 2026
c4a87aa
feat(ui): improve highlight styling and scrollbar consistency.
Blankeos May 9, 2026
4fe2984
feat: restore undone message content to input, make home screen layou…
Blankeos May 9, 2026
f7013c4
feat: better spacing + color for the chat input box.
Blankeos May 10, 2026
87cbe6e
fix: better spacing using a clever glyph (upper half block).
Blankeos May 10, 2026
9d6889d
feat: PERFECT spacing using clever glyphs.
Blankeos May 10, 2026
3a9ac34
fix: horizontal centering of mascot.
Blankeos May 10, 2026
a180207
feat: better chat input box background theme.
Blankeos May 10, 2026
27a9ce7
fix: layout shifts when focusing timeline dialog.
Blankeos May 10, 2026
ee42628
refactor: replace inline timeline highlight with overlay band.
Blankeos May 11, 2026
33abe04
refactor(chat): render timeline highlight as full-width background.
Blankeos May 11, 2026
51df90e
feat: opencode parity 1st run. Lots of tools added.
Blankeos May 11, 2026
fb8943d
fix: plan to build so it can call tools.
Blankeos May 11, 2026
013835a
feat(tools): expand plan mode permissions and log skipped tools.
Blankeos May 11, 2026
32df7fb
feat: working ai sdk port.
Blankeos May 11, 2026
6461a59
fix: proper table rendering.
Blankeos May 11, 2026
ce20f74
feat: replace eventsource-stream with custom SSE parser and add inlin…
Blankeos May 18, 2026
d9058d1
feat: better interactive question dialog + fixed toolcall rendering.
Blankeos May 18, 2026
4ba5b9a
feat(question): auto-generate fallback options and detect skips; fix …
Blankeos May 18, 2026
c724c77
feat(questions): make navigation mouse-driven and require explicit co…
Blankeos May 18, 2026
363f63f
feat(timeline): collapse consecutive assistant messages into one time…
Blankeos May 18, 2026
97070d5
feat: migrate data storage to XDG_STATE_HOME with private permissions.
Blankeos May 18, 2026
eb40ebf
feat(sessions): switch to session on dialog click and fix popup scroll.
Blankeos May 18, 2026
17119b9
feat: allow command submission during streaming; refactor dialog acti…
Blankeos May 18, 2026
1e41203
docs: updated docs on multiworkspace.
Blankeos May 18, 2026
3607962
feat(BIG): add multi-session management with workspace-aware streamin…
Blankeos May 18, 2026
611c8cb
fix: defer session creation until first message with pending title su…
Blankeos May 18, 2026
6ac36eb
feat: implement multi-step subagent tool loops with child session nav…
Blankeos May 18, 2026
b8bd0cd
docs: added codex parity docs (but might not use).
Blankeos May 18, 2026
5521897
feat(chat): remove vertical centering of content, render at top.
Blankeos May 18, 2026
968360b
fix: add vertical padding and background styling to user message bubb…
Blankeos May 18, 2026
26ef498
feat: bound tool output and compact read/list UI.
Blankeos May 18, 2026
13a6b0c
feat(chat): group consecutive exploration tool messages and refactor …
Blankeos May 18, 2026
0c6546d
feat: better "diff" more similar to codex when editing.
Blankeos May 18, 2026
e7fe4b1
feat: add image attachment support with clipboard paste and @-file au…
Blankeos May 19, 2026
11f5ef5
feat: handle SSE metadata lines and preserve sessions dialog on delete.
Blankeos May 19, 2026
2306d81
feat: add session compaction for reducing context token usage.
Blankeos May 19, 2026
3149008
feat: made mouse in command and file popovers.
Blankeos May 19, 2026
0cbb00b
fix: issue w/ opencodego models, replace parse_tool_calls with stream…
Blankeos May 19, 2026
78f8fcf
fix: remove compact tool panel spacing special case.
Blankeos May 19, 2026
f9a2679
feat: (better) refactor subagent UI to footer with locked input in ch…
Blankeos May 19, 2026
c7063c4
refactor(perf): performance optimizations in chat loading.
Blankeos May 19, 2026
5112686
feat(aisdk): execute same-step tool calls concurrently and deduplicat…
Blankeos May 19, 2026
e0da61a
feat: rename `todowrite` tool to `update_plan` and overhaul tool rend…
Blankeos May 19, 2026
114ae2c
refactor: extract search area height into a named constant.
Blankeos May 19, 2026
c89ee53
feat(webfetch): overhaul HTML conversion, add streaming, Cloudflare h…
Blankeos May 19, 2026
2a42856
refactor: centralize CWD resolution and embed themes at compile time.
Blankeos May 19, 2026
ececcee
chore(benchmax): add makeshift agent benchmarking script.
Blankeos May 19, 2026
1277b7d
feat: add OpenAI Responses API function call support and --dangerousl…
Blankeos May 19, 2026
bbb3c3b
docs(bench): add `--dangerously-skip-permissions` to crabcode benchma…
Blankeos May 19, 2026
5271e25
refactor: suppress tool call/result output in print mode.
Blankeos May 19, 2026
03f060e
feat(bench): add live reports, safe runner, static server, and 3 new …
Blankeos May 19, 2026
d7728fb
feat(bench): add workflow-planner-ts benchmark case with hidden test …
Blankeos May 19, 2026
55995c9
feat: show sessions from all workspaces with group reordering.
Blankeos May 19, 2026
9523f14
chore: todos
Blankeos May 20, 2026
486ddf2
feat: replace "♥︎ Favorite" tip with standalone "❤︎" and refactor tim…
Blankeos May 20, 2026
4c928d2
feat: add reasoning effort support with Ctrl+T cycling and models dia…
Blankeos May 20, 2026
aa66483
feat: persist partial messages on streaming failure.
Blankeos May 20, 2026
5211bfe
feat: implement custom slash commands.
Blankeos May 20, 2026
bfdbc91
feat(llm): preserve system message content in instructions when strip…
Blankeos May 20, 2026
66843b5
feat: normalize and expand GPT-5 model matching for OpenAI OAuth.
Blankeos May 20, 2026
ca11810
feat: compact large paste content into placeholders during input.
Blankeos May 20, 2026
9e23628
feat: emit ChunkType::End on [DONE] and finish_reason; enforce termin…
Blankeos May 20, 2026
3311acd
fix(llm): add structured stream logging with request/summary diagnost…
Blankeos May 20, 2026
7616663
feat(aisdk): add assistant message phase and response completed strea…
Blankeos May 21, 2026
896dea1
refactor(dialog): extract content padding to deduplicate layout logic.
Blankeos May 21, 2026
5167647
feat: add tool error diagnostics and non-fatal error recovery.
Blankeos May 21, 2026
72ec127
fix(chat): style image placeholders with markdown_image color.
Blankeos May 21, 2026
8577d5a
fix: keep chat pinned to bottom when new stream content arrives.
Blankeos May 21, 2026
052a623
fix: allow scroll passthrough when permission dialog is open.
Blankeos May 21, 2026
62c3ca2
feat(sessions-dialog): add esc to cancel pending delete.
Blankeos May 21, 2026
82d90a2
fix(providers): use connect timeout instead of request timeout for st…
Blankeos May 21, 2026
c500dc7
fix: premature stops.
Blankeos May 21, 2026
26c7ce0
fix: chat input box wrapping fixes.
Blankeos May 21, 2026
bec2732
feat: add terminal notification signals (BEL) for completion events.
Blankeos May 21, 2026
ecfa273
feat: add premature-completion diagnostics and relax read-tool permis…
Blankeos May 21, 2026
be7c859
fix(premature-complete): defer finish when tool messages still running.
Blankeos May 21, 2026
bcdd883
fix: premature completion 2.
Blankeos May 21, 2026
669b1f5
feat: add command palette overlay accessible via ctrl+p.
Blankeos May 21, 2026
b81cee4
feat: normalize plan status markers and add helper functions.
Blankeos May 21, 2026
206f8ae
fix(chat): preserve explicit newlines in user messages.
Blankeos May 21, 2026
8beb439
fix: address premature completion recurrence through prompt parity an…
Blankeos May 21, 2026
8884799
feat: open message actions on direct chat message click.
Blankeos May 21, 2026
eb1fb4d
feat: gate app.log logging behind `--emit-logs` flag.
Blankeos May 22, 2026
0699b39
feat(aisdk): add OpenAI Responses WebSocket transport with incrementa…
Blankeos May 25, 2026
6e6a74d
fix: handle stale websocket connections and normalize assistant messa…
Blankeos May 25, 2026
ce55ddb
feat: add configurable image opening and improve stream interruption …
Blankeos May 25, 2026
f168dc8
feat: add syntax-highlighted diffs via syntect
Blankeos May 25, 2026
63656d8
feat: add storage dialog, refactor permissions, improve syntax highli…
Blankeos May 25, 2026
eff0507
feat: group assistant turn parts into logical message blocks for clip…
Blankeos May 25, 2026
7bc2572
feat: queue messages sent while streaming and auto-submit after curre…
Blankeos May 25, 2026
6703b77
refactor(main): theme post-close logo and replace startup diagnostics…
Blankeos May 25, 2026
eb641ec
refactor: simplify post-close logo styling with single-color lines.
Blankeos May 25, 2026
fa8ed06
fix(ui): apply background color at line level for inline code rows.
Blankeos May 25, 2026
ac4b116
fix: exclude diff gutters from selection copy and highlighting.
Blankeos May 25, 2026
99f212f
feat(skills): add codex-imagegen skill (exampleonly).
Blankeos May 25, 2026
b65eac1
docs: fix config.mdx references, add remote-usage plan, enable theme …
Blankeos May 25, 2026
5f70401
chore: remove aisdk_debug.log.
Blankeos May 25, 2026
57f166c
feat: add view_image tool for local image inspection.
Blankeos May 25, 2026
c02e6d3
feat: add tool image output support and chat hyperlinks.
Blankeos May 25, 2026
3193d9e
fix: avoid false positive hyperlinks for single-segment absolute paths.
Blankeos May 25, 2026
4cee971
feat: add local Ollama provider integration with optional API keys.
Blankeos May 25, 2026
60091ed
fix: hyperlink on hover only.
Blankeos May 25, 2026
cbbb980
feat: emit terminal BEL on permission/question events, fix scroll-on-…
Blankeos May 25, 2026
55c1832
feat: add "Skills" command palette entry to open skills dialog.
Blankeos May 26, 2026
644af4d
docs: add formatting reminder to AGENTS.md.
Blankeos May 26, 2026
ad6bf93
feat: proper context compaction.
Blankeos May 26, 2026
f0f4110
fix: diff bleeding.
Blankeos May 26, 2026
d8a88dc
feat(tools): enforce at most one in_progress item in update_plan.
Blankeos May 26, 2026
5f0d6f0
refactor(config): unify sounds and notifications into single notifica…
Blankeos May 27, 2026
a22770c
chore: just progress mgmt stuff.
Blankeos May 27, 2026
a544af4
docs: add WebSocket reset bug investigation to premature complete notes.
Blankeos May 27, 2026
4b38b1e
fix(openai): add bounded retry for websocket stream disconnects.
Blankeos May 27, 2026
fb684d7
refactor: changed from 'annotate' to 'add to prompt'.
Blankeos May 27, 2026
c4cd65d
fix: outside input box not triggering tooltip for copy.
Blankeos May 27, 2026
47ced6e
fix: anthropic-style for qwen 3.7 max.
Blankeos May 27, 2026
a4dc2b2
refactor(anthropic): extract SSE stream parsing into composable helpers.
Blankeos May 27, 2026
db7b9dd
feat(ui): add edge scrolling for text selection drag.
Blankeos May 27, 2026
c9021bf
fix: more fixes on premature complete esp for other models, qwen 3.7 …
Blankeos May 27, 2026
551ab67
feat: handle text-only models when images are attached.
Blankeos May 27, 2026
2cb074c
feat(aisdk): add reasoning_content support to tool call messages.
Blankeos May 27, 2026
9bac1eb
refactor(aisdk): group adjacent tool calls into single assistant mess…
Blankeos May 28, 2026
1f07c7d
fix: kimi k2.6 fixes.
Blankeos May 28, 2026
20c088d
refactor: (annoying) prevent opening message actions when clicking as…
Blankeos May 28, 2026
4e2645a
feat(agent): add OpenCode-compatible agent registry with @mentions an…
Blankeos May 28, 2026
bb235b2
fix(ui): keep list markers inline with item text when wrapping.
Blankeos May 28, 2026
94036fa
fix(ui/markdown): preserve table line breaks in rendered markdown tab…
Blankeos May 28, 2026
2d7f5cf
feat: optimization.
Blankeos May 28, 2026
6cd4a72
fix: stdin pipe for -p mode.
Blankeos May 28, 2026
ae847d4
feat(app): restore undo attachments and update terminal title state.
Blankeos May 29, 2026
42a664f
feat(benchmark): extract bench-agents into modular benchmarking package.
Blankeos May 29, 2026
715edd4
feat(benchmarking): add issue triage pipeline benchmark task.
Blankeos May 29, 2026
92f524e
feat: add non-interactive print mode and batched file write support.
Blankeos May 30, 2026
91924db
feat(tools,benchmarking): add reasoning-effort override and apply_pat…
Blankeos May 30, 2026
5923cf6
fix(autocomplete): hide registered "skills" from autocomplete suggest…
Blankeos May 31, 2026
9a195ba
feat(commands): add /fork command with /branch alias for session clon…
Blankeos May 31, 2026
f41dc16
feat(app): queue and batch user messages during active compaction.
Blankeos May 31, 2026
d7c765a
chore: todo
Blankeos May 31, 2026
f5df7a9
feat(theme): persist theme selection as state fallback
Blankeos May 31, 2026
381befe
fix(command-palette): match hidden command tokens during search.
Blankeos May 31, 2026
191506d
feat(ui): add command palette toggle for assistant thinking visibility
Blankeos May 31, 2026
dcf2d1e
chore: remote usage plan.
Blankeos May 31, 2026
069fab5
feat(remote): BIG add remote mode support with client UI and release …
Blankeos Jun 2, 2026
742a8a3
feat(cli): add print-mode prompt size preflight.
Blankeos Jun 3, 2026
a24f604
fix(ui): keep selected `/models` item visible when it is the last row
Blankeos Jun 3, 2026
de0ebe6
feat(model): centralize model dialog description helper
Blankeos Jun 3, 2026
64e79c1
feat(session): preserve assistant tool-call lifecycle as ordered mess…
Blankeos Jun 3, 2026
28da33b
fix(remote-client): handle wrapped prompt lines in history navigation.
Blankeos Jun 3, 2026
1abba79
refactor(remote-client): split index page into modular remote client …
Blankeos Jun 3, 2026
5ae91df
docs(quickstart): remove outdated `?` command hint
Blankeos Jun 3, 2026
970fd1f
fix(remote): clarify Tailscale workflow docs and stabilize composer d…
Blankeos Jun 3, 2026
5f8ed7a
refactor: remove stale exports and stabilize dialog/model discovery t…
Blankeos Jun 3, 2026
6a774b3
chore: author
Blankeos Jun 3, 2026
5bbac03
fix: fail on remote-client missing during build
Blankeos Jun 5, 2026
f63b8b6
feat(ui): add remote host launch flow and grouped tool output
Blankeos Jun 5, 2026
c824f44
fix(sessions): focus first session item when opening workspace dialog
Blankeos Jun 5, 2026
20889a5
feat(tui): add dedicated weak text theme token for placeholders
Blankeos Jun 5, 2026
320de99
feat(permission-dialog): add vertical permission action list and keyb…
Blankeos Jun 5, 2026
1039cb9
doc: updated docs
Blankeos Jun 5, 2026
278023e
fix(ui,terminal): stabilize terminal restoration and preserve dialog …
Blankeos Jun 5, 2026
4371a21
feat(tui): show active dialog entries as markers instead of right-sid…
Blankeos Jun 6, 2026
03d71e3
feat(chat): render apply_patch tool output as diff previews
Blankeos Jun 6, 2026
aa23567
fix(input): handle kitty key events and add textarea line shortcuts
Blankeos Jun 6, 2026
775071b
feat(chat): add syntax-highlighted apply_patch and edit diff previews
Blankeos Jun 6, 2026
d64139c
chore: added a root favicon so crabcode/t3code picks it up.
Blankeos Jun 6, 2026
864d505
feat(notifications): add configurable macOS desktop notification backend
Blankeos Jun 6, 2026
7683f8e
doc: more clarity on merging.
Blankeos Jun 6, 2026
c52a601
feat(tools): add configurable websearch integration with provider ada…
Blankeos Jun 7, 2026
6f74c6c
fix(app): isolate reasoning effort overrides per instance and show wo…
Blankeos Jun 7, 2026
8af180f
feat(model): add CommandCode remote provider discovery
Blankeos Jun 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 15 additions & 0 deletions .devrefs/devrefs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# DevRefs makes cloning/updating references for agents seamless and fast.
# Edit this file directly, or use `devrefs add <id> <description>` to add entries.
references:
- id: ogulcancelik/herdr
description: "Ratatui app with good scroll"
remote: https://github.com/ogulcancelik/herdr.git
branch: master
- id: anomalyco/opencode
description: "Main reference and preferred agent harness by the author, we wanted to rewrite it in rust w/ crabcode"
remote: https://github.com/anomalyco/opencode.git
branch: dev
- id: openai/codex
description: "a ratatui agent harness that we can use as reference, especially since it's by openai"
remote: https://github.com/openai/codex.git
branch: main
11 changes: 11 additions & 0 deletions .github/dist-build-setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
- name: Install Bun
uses: oven-sh/setup-bun@v2
- name: Build remote client
shell: bash
run: |
cd remote-client
bun install --frozen-lockfile
bun run build
- name: Verify remote client assets
shell: bash
run: test -s remote-client/dist/client/index.html
307 changes: 307 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,307 @@
# This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist
#
# Copyright 2022-2024, axodotdev
# SPDX-License-Identifier: MIT or Apache-2.0
#
# CI that:
#
# * checks for a Git Tag that looks like a release
# * builds artifacts with dist (archives, installers, hashes)
# * uploads those artifacts to temporary workflow zip
# * on success, uploads the artifacts to a GitHub Release
#
# Note that the GitHub Release will be created with a generated
# title/body based on your changelogs.

name: Release
permissions:
"contents": "write"

# This task will run whenever you push a git tag that looks like a version
# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc.
# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where
# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION
# must be a Cargo-style SemVer Version (must have at least major.minor.patch).
#
# If PACKAGE_NAME is specified, then the announcement will be for that
# package (erroring out if it doesn't have the given version or isn't dist-able).
#
# If PACKAGE_NAME isn't specified, then the announcement will be for all
# (dist-able) packages in the workspace with that version (this mode is
# intended for workspaces with only one dist-able package, or with all dist-able
# packages versioned/released in lockstep).
#
# If you push multiple tags at once, separate instances of this workflow will
# spin up, creating an independent announcement for each one. However, GitHub
# will hard limit this to 3 tags per commit, as it will assume more tags is a
# mistake.
#
# If there's a prerelease-style suffix to the version, then the release(s)
# will be marked as a prerelease.
on:
pull_request:
push:
tags:
- '**[0-9]+.[0-9]+.[0-9]+*'

jobs:
# Run 'dist plan' (or host) to determine what tasks we need to do
plan:
runs-on: "ubuntu-22.04"
outputs:
val: ${{ steps.plan.outputs.manifest }}
tag: ${{ !github.event.pull_request && github.ref_name || '' }}
tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }}
publishing: ${{ !github.event.pull_request }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
submodules: recursive
- name: Install dist
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
# sure would be cool if github gave us proper conditionals...
# so here's a doubly-nested ternary-via-truthiness to try to provide the best possible
# functionality based on whether this is a pull_request, and whether it's from a fork.
# (PRs run on the *source* but secrets are usually on the *target* -- that's *good*
# but also really annoying to build CI around when it needs secrets to work right.)
- id: plan
run: |
dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json
echo "dist ran successfully"
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v4
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json

# Build and packages all the platform-specific things
build-local-artifacts:
name: build-local-artifacts (${{ join(matrix.targets, ', ') }})
# Let the initial task tell us to not run (currently very blunt)
needs:
- plan
if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }}
strategy:
fail-fast: false
# Target platforms/runners are computed by dist in create-release.
# Each member of the matrix has the following arguments:
#
# - runner: the github runner
# - dist-args: cli flags to pass to dist
# - install-dist: expression to run to install dist on the runner
#
# Typically there will be:
# - 1 "global" task that builds universal installers
# - N "local" tasks that build each platform's binaries and platform-specific installers
matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}
runs-on: ${{ matrix.runner }}
container: ${{ matrix.container && matrix.container.image || null }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json
steps:
- name: enable windows longpaths
run: |
git config --global core.longpaths true
- uses: actions/checkout@v4
with:
persist-credentials: false
submodules: recursive
- name: Install Rust non-interactively if not already installed
if: ${{ matrix.container }}
run: |
if ! command -v cargo > /dev/null 2>&1; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
fi
- name: "Install Bun"
uses: "oven-sh/setup-bun@v2"
- name: "Build remote client"
run: |
cd remote-client
bun install --frozen-lockfile
bun run build
shell: "bash"
- name: "Verify remote client assets"
run: "test -s remote-client/dist/client/index.html"
shell: "bash"
- name: Install dist
run: ${{ matrix.install_dist.run }}
# Get the dist-manifest
- name: Fetch local artifacts
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- name: Install dependencies
run: |
${{ matrix.packages_install }}
- name: Build artifacts
run: |
# Actually do builds and make zips and whatnot
dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json
echo "dist ran successfully"
- id: cargo-dist
name: Post-build
# We force bash here just because github makes it really hard to get values up
# to "real" actions without writing to env-vars, and writing to env-vars has
# inconsistent syntax between shell and powershell.
shell: bash
run: |
# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"

cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
with:
name: artifacts-build-local-${{ join(matrix.targets, '_') }}
path: |
${{ steps.cargo-dist.outputs.paths }}
${{ env.BUILD_MANIFEST_NAME }}

# Build and package all the platform-agnostic(ish) things
build-global-artifacts:
needs:
- plan
- build-local-artifacts
runs-on: "ubuntu-22.04"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- id: cargo-dist
shell: bash
run: |
dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json
echo "dist ran successfully"

# Parse out what we just built and upload it to scratch storage
echo "paths<<EOF" >> "$GITHUB_OUTPUT"
jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"

cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@v4
with:
name: artifacts-build-global
path: |
${{ steps.cargo-dist.outputs.paths }}
${{ env.BUILD_MANIFEST_NAME }}
# Determines if we should publish/announce
host:
needs:
- plan
- build-local-artifacts
- build-global-artifacts
# Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine)
if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: "ubuntu-22.04"
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@v4
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: target/distrib/
merge-multiple: true
- id: host
shell: bash
run: |
dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json
echo "artifacts uploaded and released successfully"
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@v4
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
path: dist-manifest.json
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@v4
with:
pattern: artifacts-*
path: artifacts
merge-multiple: true
- name: Cleanup
run: |
# Remove the granular manifests
rm -f artifacts/*-dist-manifest.json
- name: Create GitHub Release
env:
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
RELEASE_COMMIT: "${{ github.sha }}"
run: |
# Write and read notes from a file to avoid quoting breaking things
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt

gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*

announce:
needs:
- plan
- host
# use "always() && ..." to allow us to wait for all publish jobs while
# still allowing individual publish jobs to skip themselves (for prereleases).
# "host" however must run to completion, no skipping allowed!
if: ${{ always() && needs.host.result == 'success' }}
runs-on: "ubuntu-22.04"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
submodules: recursive
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@ src/themes/
!src/theme.json
!src/theme.json
app.log
aisdk_debug.log
sounds/complete.wav

_dev_reference1
_dev_reference2
.env
node_modules
remote-client/dist/assets.json
remote-client/dist/client/.vite/
remote-client/dist/server/
.devrefs/references
.benchmarks/
benchmark-reports/
2 changes: 2 additions & 0 deletions .ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
!_dev_reference1
!_dev_reference2
Loading
Loading