Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
315 commits
Select commit Hold shift + click to select a range
4640d8f
fix: enlarge preferences window
steipete May 6, 2026
59a93c2
docs: reorder unreleased changelog
steipete May 6, 2026
a2d5323
docs: finalize 0.24 changelog
steipete May 6, 2026
f09d3a9
docs: update appcast for 0.24
steipete May 6, 2026
cd37f38
ci: select modern Xcode for CLI release
steipete May 6, 2026
7783458
ci: allow CLI release reruns for tags
steipete May 6, 2026
35051a8
ci: harden CLI release packaging
steipete May 6, 2026
d019a15
ci: avoid macOS CLI execution in release smoke
steipete May 6, 2026
406ee10
chore: start 0.25 development
steipete May 6, 2026
cb9a550
ci: run macOS tests in parallel
steipete May 6, 2026
6f88f82
ci: avoid forced macOS test parallelism
steipete May 6, 2026
8e3f045
ci: isolate serial macOS test suites
steipete May 6, 2026
3f5cf40
ci: skip headless status menu test
steipete May 6, 2026
ac24106
fix: restore menu bar icon on macOS 26.4 (#805) (#849)
willytop8 May 6, 2026
dc16f9e
fix: correct Augment keepalive interval logs
steipete May 6, 2026
4155a40
fix: keep menu open when refreshing
steipete May 7, 2026
63e473f
ci: serialize dashboard cache tests
steipete May 7, 2026
1581e27
fix: remove stale split status items
steipete May 7, 2026
35283b0
feat: stop OpenRouter from replacing menu-bar meter with logo (#854)
willytop8 May 8, 2026
dd4bc9f
fix(deepseek): show balance without quota bar (#856)
jb381 May 8, 2026
98edf6e
test: split DeepSeek menu card regression
steipete May 8, 2026
dcb4706
fix: pin RelativeDateTimeFormatter to en_US to stop mixed-locale labe…
Karl-Dai May 8, 2026
824c47e
Fix Droid zero usage ratio (#864)
proxynico May 8, 2026
9aaa65c
docs: record landed locale and Droid fixes
steipete May 8, 2026
23d5c4f
ci: update Homebrew tap after CLI releases
steipete May 8, 2026
9907f74
fix(menu): route switcher clicks through parent view
Karl-Dai May 8, 2026
c727684
feat: add Crof provider
baanish May 9, 2026
c7f3866
feat: show balance metrics for API-balance providers
willytop8 May 9, 2026
35cd513
fix: avoid hidden autosaved status items
steipete May 9, 2026
e3534b9
docs: add generated llms index
steipete May 9, 2026
1acf9cf
docs: note Crof and balance display changes
steipete May 9, 2026
618b13f
feat: add Factory Droid billing limits
dantemoon1 May 9, 2026
161d983
docs: note Factory Droid billing support
steipete May 9, 2026
0d60c90
feat: generalize quota pace display
ViperThanks May 9, 2026
c6d3568
fix: add VoiceOver labels to menu UI
WadydX May 9, 2026
90134bc
docs: note pace and VoiceOver changes
steipete May 9, 2026
dac1511
refactor: move menu copy overlay
steipete May 9, 2026
df47517
fix: restrict Codex OAuth CLI fallback
ViperThanks May 10, 2026
f6b853f
docs: note Codex OAuth fallback fix
steipete May 10, 2026
c8e1382
fix: keep cost refresh incremental
steipete May 10, 2026
4aad5a5
fix: drain cost scanner autoreleases
steipete May 10, 2026
bf1472e
Add Venice API balance provider (#865)
clawSean May 10, 2026
001561a
Feat: Add models.dev pricing metadata pipeline (#863)
iam-brain May 10, 2026
18eb73d
Add quota warning controls and markers (#852)
Alekstodo May 10, 2026
256752b
Fix models.dev pricing refresh continuity (#881)
iam-brain May 10, 2026
77b7367
feat(minimax): Add multi-service usage support (#605)
XWind18 May 10, 2026
0d5714d
docs: prefer CLI-focused validation
steipete May 10, 2026
21d5067
Rename Codex Pro Lite/Pro to official name Pro 5x/Pro 20x (#882)
xiaoqianWX May 10, 2026
fbcdeb8
Fix: Align models.dev refresh guard with lookup (#883)
iam-brain May 10, 2026
1620116
Add command code support (#857)
sixhobbits May 10, 2026
c51ec0f
Add StepFun provider
tevenfeng May 10, 2026
5cf2ea4
Add session pace indicators
johnlarkin1 May 10, 2026
e98c8f5
feat(antigravity): add OAuth-backed remote usage when the IDE is clos…
abnormal749 May 10, 2026
dd54a28
Add Chinese (Simplified) localization (#819)
markhome1 May 10, 2026
6eb3699
Add Qwen and Doubao providers (#498)
LeoLin990405 May 10, 2026
f9a2918
Add Xiaomi MiMo token plan usage tracking (#651)
debpramanik May 10, 2026
ed46925
Update CNAME
steipete May 10, 2026
b4213f1
docs: refresh codex.bar with structured aurora background and matchin…
steipete May 10, 2026
7ff8148
fix: bump SweetCookieKit browser support
steipete May 10, 2026
8084eeb
fix: honor legacy OpenAI web access default
steipete May 10, 2026
145951c
test: cover browser keychain prompt cooldown
steipete May 10, 2026
1f92be3
fix: send Factory JWT subject as usage user ID
steipete May 10, 2026
d2eca29
build: time-box local widget metadata generation
steipete May 10, 2026
c66ea42
fix: trust CLI for keychain cache items
steipete May 10, 2026
197a2df
fix: clarify Alibaba INTL quota fallback
steipete May 10, 2026
23e4b69
fix: target Claude web token account organizations
steipete May 10, 2026
20690b7
fix: prefer funded DeepSeek balance currency
steipete May 10, 2026
7d16521
fix: support Vertex AI service account ADC
steipete May 10, 2026
3ca45e3
fix: defer menu rebuilds while submenus are open
steipete May 10, 2026
98a2eb8
fix: add Gemini curl timeout fallback
steipete May 10, 2026
eb867d6
feat: add Manus provider (#700)
hhh2210 May 10, 2026
03c6801
Integrate models.dev pricing flow (#884)
iam-brain May 10, 2026
28f5394
Feat/multiple accounts stack vs segmented options (#869)
ajmccall May 10, 2026
f853cee
fix: support Homebrew Gemini OAuth bundles
steipete May 10, 2026
8663d93
feat: add OpenAI API balance provider
steipete May 10, 2026
898785f
test: isolate flaky menu and Claude cache tests
steipete May 10, 2026
3f034f3
docs: update changelog for landed fixes
steipete May 10, 2026
732aaf5
Update CNAME
steipete May 10, 2026
e22d3cd
fix: preserve tiered pricing boundaries
iam-brain May 10, 2026
8e86d2d
docs: restore codexbar.app canonical domain
steipete May 10, 2026
062fb8c
docs: note tiered pricing boundary fix
steipete May 10, 2026
fe61a96
test: stabilize merged menu provider setup
steipete May 10, 2026
7cd7127
test: allow historical pace write propagation
steipete May 10, 2026
4f0ff8e
docs: remove site changelog notes
steipete May 10, 2026
74d82fd
fix: prevent account switchers widening menu
steipete May 10, 2026
da6f9ec
fix: prevent display picker crash
steipete May 10, 2026
3e2545b
docs: finalize changelog for 0.25
steipete May 10, 2026
804ba91
docs: update appcast for 0.25
steipete May 10, 2026
5d60c06
chore: start 0.26 development
steipete May 10, 2026
78e186d
fix(pi): rebuild stale session cost cache
ngutman May 10, 2026
4b507f0
Merge pull request #889 from steipete/fix/pi-cache-v2-migration
ngutman May 10, 2026
37dc641
fix(keychain): reduce dev prompt churn (#888)
ngutman May 10, 2026
da89436
fix: avoid packaged Settings localization crash
lederniermagicien May 11, 2026
c3c20b6
chore: bump CodexBar version
steipete May 11, 2026
da957fb
Fix CLI release version fallback
ThiagoCAltoe May 11, 2026
d313f07
chore: release 0.25.1
steipete May 11, 2026
1001382
style: apply release formatting
steipete May 11, 2026
a42e102
docs: update appcast for 0.25.1
steipete May 11, 2026
386f114
chore: start 0.26 development
steipete May 11, 2026
b0c18a1
ci: split macOS Swift test timeouts
steipete May 11, 2026
2f997b7
ci: serialize promotion service tests
steipete May 11, 2026
086b398
ci: run macOS Swift tests serially
steipete May 11, 2026
a1199cc
test: harden CLI version fallback test
steipete May 11, 2026
d681897
test: satisfy CLI fallback lint
steipete May 11, 2026
6f2cd9a
ci: restore split macOS test lanes
steipete May 11, 2026
4dcabe1
ci: shard macOS Swift tests by suite
steipete May 11, 2026
39034a2
ci: isolate macOS test suites
steipete May 11, 2026
b06d76d
ci: run macOS suite shards serially
steipete May 11, 2026
f5fcd0c
ci: prioritize CLI suite in Swift shards
steipete May 11, 2026
70ba7c3
ci: skip hanging mac CLI suite shard
steipete May 11, 2026
3cfd799
test: run CLI entry suite with XCTest
steipete May 11, 2026
53db57a
ci: skip mac CLI entry shard on Intel runner
steipete May 11, 2026
3356090
Fix z.ai MCP monthly window label (#904)
ThiagoCAltoe May 11, 2026
c829819
Harden ChatGPT purchase URL validation (#903)
ThiagoCAltoe May 11, 2026
a01bf8c
fix: apply selected app language
steipete May 11, 2026
22c4484
Add Brazilian Portuguese localization (#902)
ThiagoCAltoe May 11, 2026
0cb8abd
Add Moonshot / Kimi API provider support (#911)
steipete May 11, 2026
c7729cd
fix: stabilize Codex account switcher layout (#905)
arturneumann May 11, 2026
009420a
Add option to hide quota warning markers (#918)
ThiagoCAltoe May 12, 2026
2af7f55
Fix Codex menu account refresh routing (#932)
ThiagoCAltoe May 13, 2026
f5c54c1
Clarify Gemini source label (#930)
ThiagoCAltoe May 13, 2026
cd2c2c4
Add provider changelog links
ThiagoCAltoe May 13, 2026
0919805
Fix changelog menu test
ThiagoCAltoe May 13, 2026
81a420a
feat: gate provider changelog links behind setting
steipete May 13, 2026
cd2abfd
fix: repair stale managed Codex account removal
steipete May 13, 2026
34d9b18
fix: handle Claude enterprise web accounts (#941)
clintandrewhall May 14, 2026
100e32f
docs: update changelog for Claude enterprise fix
steipete May 14, 2026
36db0c6
fix: handle quota and usage edge cases
steipete May 14, 2026
ac5de84
Rebalance Kimi provider icon (#912)
giuseppebisemi May 14, 2026
6423275
Add zh-Hans translations for Claude peak hour labels (#921)
whtis May 14, 2026
e48a4bc
docs: update changelog for recent contributor fixes
steipete May 14, 2026
e6ea0ae
Add Tahoe menu bar visibility guidance
pdurlej May 14, 2026
4abfbb6
Coalesce historical pace reset buckets
zhulijin1991 May 14, 2026
2f6a31c
Add Codex priority cost pricing
iam-brain May 14, 2026
9d7a24e
fix: parse Claude web spend limits
steipete May 14, 2026
24d67e5
fix: refresh Gemini credentials without access token
steipete May 14, 2026
8c3e254
refactor: split Claude web extra usage helpers
steipete May 14, 2026
aebe1c9
fix: defer account switcher menu rebuilds
steipete May 14, 2026
6e68613
docs: fix changelog spacing
steipete May 14, 2026
32fd0ec
fix: handle unavailable Codex limits gracefully
steipete May 14, 2026
0776680
docs: update unreleased changelog
steipete May 14, 2026
837cdb9
fix: repair update and account menu paths
steipete May 14, 2026
eba4b6f
fix: handle account-scoped usage and menu login bugs
steipete May 14, 2026
a15df5c
Add Antigravity account switching (#937)
hhh2210 May 14, 2026
9902384
docs: add Antigravity account switching changelog
steipete May 14, 2026
66b8277
Improve Kiro credits and account display (#933)
solnikhil May 14, 2026
1880c90
docs: add Kiro credits changelog
steipete May 14, 2026
be9f8d5
fix: avoid stale Cursor login sessions
steipete May 14, 2026
bb78426
fix: refresh codex cost cache without roots
steipete May 14, 2026
29386fe
test(cli): cover Claude all-account source routing
steipete May 14, 2026
19671e0
fix(codex): throttle blocked CLI background launches
steipete May 14, 2026
73c8209
fix(cost): clarify local estimate labels
steipete May 14, 2026
d624297
feat(kilo): add organization usage selection
steipete May 14, 2026
629ac5f
docs: update changelog for landed fixes
steipete May 14, 2026
c42bdeb
fix(opencodego): scan browser cookies in automatic mode
steipete May 14, 2026
22a5524
feat(zai): add hourly usage chart
steipete May 14, 2026
5161462
docs: update changelog for provider fixes
steipete May 14, 2026
2905c5e
Add AWS Bedrock provider (#897)
afalk42 May 14, 2026
e508f44
fix: clarify claude cost estimates
steipete May 14, 2026
3446dbd
fix: harden upstream review scripts
steipete May 15, 2026
9d64126
fix: improve provider usage displays
steipete May 15, 2026
2203a4d
fix: name macOS release assets by arch
steipete May 15, 2026
eadf5c1
feat: add provider switcher arrow navigation
steipete May 15, 2026
a55a1bb
docs: update changelog for bug fixes
steipete May 15, 2026
ca30a9b
docs: reorder unreleased changelog
steipete May 15, 2026
7ba98d4
chore: prepare 0.26.0 release
steipete May 15, 2026
ab7b90d
docs: update appcast for 0.26.0
steipete May 15, 2026
8357490
fix: support Bedrock signing on Linux
ThiagoCAltoe May 15, 2026
e63c5fe
build: resolve swift crypto dependency
steipete May 15, 2026
9bd3c44
fix: stabilize CLI release version smoke
steipete May 15, 2026
c5a72b4
fix: harden CLI release smoke
steipete May 15, 2026
216e5a8
chore: start 0.26.1 development
steipete May 15, 2026
2e177cd
fix: isolate Codex status probes
steipete May 15, 2026
d814c22
fix: stabilize Cost submenu opening
getogrand May 15, 2026
7e53a12
fix(pt-BR): translate quota warning settings
ThiagoCAltoe May 15, 2026
74a019c
feat(cli): add localhost serve command
ThiagoCAltoe May 15, 2026
480a8d3
feat: show OpenAI API usage dashboard
steipete May 15, 2026
5a111eb
docs: finalize 0.26.1 changelog
steipete May 15, 2026
8f4bfc5
test: isolate usage store provider detection
steipete May 15, 2026
f642907
build: allow slow widget metadata builds
steipete May 15, 2026
3132250
docs: update appcast for 0.26.1
steipete May 15, 2026
3be1586
Start 0.26.2 development
steipete May 15, 2026
e3b80b1
Harden CodexBar CLI release assets
steipete May 15, 2026
0727018
test: isolate switcher refresh test from background refresh
steipete May 15, 2026
450bb8d
test: make switcher refresh test deterministic
steipete May 15, 2026
1763979
fix: preserve usage after transient timeouts
steipete May 15, 2026
cee403b
feat: reuse inline usage dashboards
steipete May 15, 2026
91cf1a3
fix: show Claude spend limit metric
steipete May 15, 2026
0a59284
test: cover Claude Team dashboard URL
steipete May 15, 2026
d16b41b
fix: fall back for Ollama browser sessions
steipete May 15, 2026
e059a78
fix: wait for Claude usage values
steipete May 15, 2026
b222db2
fix: clarify Claude session pace text
steipete May 15, 2026
a3f3e2a
test: keep Claude dashboard regression compact
steipete May 15, 2026
ffe10d5
fix: preserve Claude data across transient refresh failures
steipete May 15, 2026
ebc9ba4
feat: add ElevenLabs usage provider
steipete May 15, 2026
6304fec
fix: avoid widget metadata timeout during dev restarts
steipete May 15, 2026
38ed2aa
fix: shorten OpenAI provider label
steipete May 15, 2026
60f4a4e
Prefer Codex last token usage for cost scanning (#968)
Ifan24 May 16, 2026
bf4424b
Clarify unofficial Kimi K2 provider (#967)
mturac May 16, 2026
d5f1c58
fix: separate Claude plan utilization history
steipete May 16, 2026
aa8977e
feat: add Claude Admin API usage source
steipete May 16, 2026
0348028
feat: add Grok provider support
taibaran May 16, 2026
23a89fb
feat: add config API key CLI (#978)
steipete May 16, 2026
d93cfc9
test: include Grok in provider order expectation
steipete May 16, 2026
567ac94
fix(grok): treat expired credentials as missing in fetch (#976)
taibaran May 16, 2026
c6392ed
fix: label Claude extra usage monthly cap (#980)
steipete May 16, 2026
a80d7ba
test: stabilize status menu switcher refresh (#983)
steipete May 16, 2026
53d675f
Block OpenCode Go redirect cookie leakage (#979)
steipete May 16, 2026
be0ceed
ci: run push CI on slash branches (#981)
steipete May 16, 2026
6498d20
fix: improve managed Codex login recovery (#982)
steipete May 16, 2026
6a1eae2
feat(grok): add web billing fallback (#987)
steipete May 16, 2026
8132f7c
feat(cli): add provider config toggles
steipete May 16, 2026
a75d276
fix: recover missing menu bar status item
steipete May 16, 2026
645ca83
MiniMax: fix remains-to-used mapping and add quota-style usage cards …
Yuxin-Qiao May 16, 2026
eef4e1f
Localize provider storage setting
tanish19078 May 16, 2026
7c59f8e
docs: credit provider storage localization
steipete May 16, 2026
f6a0f70
Document ElevenLabs provider
tanish19078 May 16, 2026
8c29b3b
docs: polish ElevenLabs setup docs
steipete May 16, 2026
e5eb944
fix(cli): validate serve host headers
steipete May 16, 2026
fcbd46f
fix: recover status item after display changes
steipete May 16, 2026
f86abe2
docs: refresh landing page provider logos
steipete May 16, 2026
f934467
fix: harden provider timeout handling
steipete May 16, 2026
654c98a
chore: start 0.27.0 development
steipete May 16, 2026
f23a478
fix: accept OpenAI cost string values
steipete May 16, 2026
7b19aa1
fix: stabilize refresh menu row
steipete May 16, 2026
150c5ab
docs: point Linux users at codexbar-waybar
Marouan-chak May 16, 2026
7291084
feat: add Kiro overage menu bar modes
raflyazf May 16, 2026
ee96d84
feat: show quota warning account
raflyazf May 17, 2026
f62bb8c
feat: add shared provider HTTP transport
serezha93 May 17, 2026
ad33b32
refactor: centralize provider HTTP responses
steipete May 17, 2026
d78a770
fix: dedupe copied Claude transcript history
steipete May 17, 2026
9a369ad
feat: add Deepgram usage tracking
steipete May 17, 2026
3ce4101
fix: bound provider HTTP timeouts
steipete May 17, 2026
1e80b73
fix: fall back from blank localized strings
steipete May 17, 2026
d24664b
feat: show OpenCode Zen balance
steipete May 17, 2026
51d6c12
fix: reduce idle menu CPU
steipete May 17, 2026
9cd91d6
fix: improve overview menu responsiveness
steipete May 17, 2026
af202b4
feat: add MiniMax billing summaries
steipete May 17, 2026
52b5c0c
fix: harden subprocess timeouts
steipete May 17, 2026
2c687f8
fix: keep provider HTTP stubs testable
steipete May 17, 2026
faf0be9
test: future-proof provider order expectation
steipete May 17, 2026
e736582
fix: keep CI Linux builds portable
steipete May 17, 2026
ddfc7f5
fix: expose URLSession response helper on Linux
steipete May 17, 2026
eed34a7
fix: improve Codex account switcher state
steipete May 17, 2026
860bab6
perf: skip unchanged provider icon redraws
steipete May 17, 2026
eab99cc
build: keep release builds warning-free
steipete May 17, 2026
f30d264
docs: reorder 0.27 changelog
steipete May 17, 2026
a86b3f8
docs: refresh provider and CLI docs
steipete May 17, 2026
fce9c0d
docs: finalize 0.27.0 changelog
steipete May 17, 2026
0172cdc
Add notification delivery model
kibermaks May 17, 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
  •  
  •  
  •  
14 changes: 11 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ name: CI

on:
push:
branches: ["*"]
branches: ["**"]
pull_request:

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-build-test:
runs-on: macos-latest
runs-on: macos-15-intel
timeout-minutes: 70
steps:
- uses: actions/checkout@v6

Expand Down Expand Up @@ -36,9 +41,12 @@ jobs:
run: ./Scripts/lint.sh lint

- name: Swift Test
run: swift test --no-parallel
timeout-minutes: 60
run: |
python3 Scripts/ci_swift_test_by_suite.py --group-size 1 --timeout 120

build-linux-cli:
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
Expand Down
223 changes: 203 additions & 20 deletions .github/workflows/release-cli.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,76 @@
name: Release Linux CLI
name: Release CLI

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Release tag to upload assets to (for example, v0.24)."
required: false
type: string

permissions:
contents: write

jobs:
build-linux-cli:
build-cli:
strategy:
fail-fast: false
matrix:
include:
- name: linux-x64
runs-on: ubuntu-24.04
platform: linux
asset-arch: x86_64
build-arch: ""
static-swift-stdlib: true
- name: linux-arm64
runs-on: ubuntu-24.04-arm
platform: linux
asset-arch: aarch64
build-arch: ""
static-swift-stdlib: true
- name: macos-arm64
runs-on: macos-15
platform: macos
asset-arch: arm64
build-arch: arm64
static-swift-stdlib: false
- name: macos-x86_64
runs-on: macos-15-intel
platform: macos
asset-arch: x86_64
build-arch: x86_64
static-swift-stdlib: false
runs-on: ${{ matrix.runs-on }}
env:
RELEASE_TAG: ${{ inputs.tag || github.ref_name }}
steps:
- uses: actions/checkout@v6

- name: Select Xcode 26.1.1 (if present) or fallback to default
if: matrix.platform == 'macos'
run: |
set -euo pipefail
for candidate in /Applications/Xcode_26.1.1.app /Applications/Xcode_26.1.app /Applications/Xcode.app; do
if [[ -d "$candidate" ]]; then
sudo xcode-select -s "${candidate}/Contents/Developer"
echo "DEVELOPER_DIR=${candidate}/Contents/Developer" >> "$GITHUB_ENV"
break
fi
done
/usr/bin/xcodebuild -version

- name: Runner info
run: |
set -euo pipefail
uname -a
uname -m
swift --version

- name: Install Swift 6.2.1 via swiftly
if: matrix.platform == 'linux'
shell: bash
run: |
set -euo pipefail
Expand Down Expand Up @@ -63,55 +105,196 @@ jobs:
swift --version

- name: Build CodexBarCLI (release)
run: swift build -c release --product CodexBarCLI --static-swift-stdlib
id: build
shell: bash
run: |
set -euo pipefail

BUILD_ARGS=(swift build -c release --product CodexBarCLI)
if [[ -n "${{ matrix.build-arch }}" ]]; then
BUILD_ARGS+=(--arch "${{ matrix.build-arch }}")
fi
if [[ "${{ matrix.static-swift-stdlib }}" == "true" ]]; then
BUILD_ARGS+=(--static-swift-stdlib)
fi
"${BUILD_ARGS[@]}"

SHOW_BIN_ARGS=(swift build -c release --product CodexBarCLI --show-bin-path)
if [[ -n "${{ matrix.build-arch }}" ]]; then
SHOW_BIN_ARGS+=(--arch "${{ matrix.build-arch }}")
fi
if [[ "${{ matrix.static-swift-stdlib }}" == "true" ]]; then
SHOW_BIN_ARGS+=(--static-swift-stdlib)
fi

echo "bin_dir=$("${SHOW_BIN_ARGS[@]}")" >> "$GITHUB_OUTPUT"

- name: Smoke test CodexBarCLI
timeout-minutes: 5
shell: bash
run: |
set -euo pipefail

BIN_DIR="${{ steps.build.outputs.bin_dir }}"
BIN="$BIN_DIR/CodexBarCLI"
run_with_timeout() {
local output="$1"
shift
"$@" > "$output" &
local pid=$!
local run_status=
for _ in {1..20}; do
if ! kill -0 "$pid" 2>/dev/null; then
set +e
wait "$pid"
run_status=$?
set -e
break
fi
sleep 1
done
if [[ -z "$run_status" ]]; then
kill "$pid" 2>/dev/null || true
wait "$pid" 2>/dev/null || true
echo "$* timed out." >&2
exit 124
fi
if [[ "$run_status" -ne 0 ]]; then
cat "$output" >&2 || true
exit "$run_status"
fi
}

echo "BIN=$BIN"
file "$BIN"
if [[ "${{ matrix.platform }}" == "macos" ]]; then
lipo -archs "$BIN" | tr ' ' '\n' | grep -Fx "${{ matrix.asset-arch }}"
run_with_timeout "$RUNNER_TEMP/codexbar-cli-smoke-${{ matrix.name }}.txt" "$BIN" config validate --format json
else
run_with_timeout "$RUNNER_TEMP/codexbar-cli-help-${{ matrix.name }}.txt" "$BIN" --help
file "$BIN" | grep -q "${{ matrix.asset-arch }}"
fi
printf '%s\n' "${RELEASE_TAG#v}" > "$BIN_DIR/VERSION"
VERSION_OUTPUT="$RUNNER_TEMP/codexbar-cli-version-${{ matrix.name }}.txt"
run_with_timeout "$VERSION_OUTPUT" "$BIN" --version
grep -Fx "CodexBar ${RELEASE_TAG#v}" "$VERSION_OUTPUT"
rm "$BIN_DIR/VERSION"

- name: Package
id: pkg
shell: bash
run: |
set -euo pipefail

TAG="${GITHUB_REF_NAME}"
if [[ -z "$TAG" ]]; then
echo "Missing tag (GITHUB_REF_NAME)." >&2
REF_NAME="${RELEASE_TAG}"
if [[ -z "$REF_NAME" ]]; then
echo "Missing release tag." >&2
exit 1
fi
SAFE_REF_NAME="${REF_NAME//\//-}"

ARCH="$(uname -m)"
case "$ARCH" in
x86_64) ARCH="x86_64" ;;
aarch64|arm64) ARCH="aarch64" ;;
esac

BIN_DIR="$(swift build -c release --product CodexBarCLI --static-swift-stdlib --show-bin-path)"
BIN_DIR="${{ steps.build.outputs.bin_dir }}"
OUT_DIR="$(mktemp -d)"
install -m 0755 "$BIN_DIR/CodexBarCLI" "$OUT_DIR/CodexBarCLI"
ln -s "CodexBarCLI" "$OUT_DIR/codexbar"
printf '%s\n' "${SAFE_REF_NAME#v}" > "$OUT_DIR/VERSION"

ASSET="CodexBarCLI-${TAG}-linux-${ARCH}.tar.gz"
(cd "$OUT_DIR" && tar czf "$ASSET" CodexBarCLI codexbar)
sha256sum "$OUT_DIR/$ASSET" > "$OUT_DIR/$ASSET.sha256"
ASSET="CodexBarCLI-${SAFE_REF_NAME}-${{ matrix.platform }}-${{ matrix.asset-arch }}.tar.gz"
(cd "$OUT_DIR" && tar czf "$ASSET" CodexBarCLI codexbar VERSION)
if command -v sha256sum >/dev/null 2>&1; then
sha256sum "$OUT_DIR/$ASSET" > "$OUT_DIR/$ASSET.sha256"
else
shasum -a 256 "$OUT_DIR/$ASSET" > "$OUT_DIR/$ASSET.sha256"
fi

echo "out_dir=$OUT_DIR" >> "$GITHUB_OUTPUT"
echo "asset=$ASSET" >> "$GITHUB_OUTPUT"

- name: Upload release assets
if: github.event_name == 'release'
if: github.event_name == 'release' || inputs.tag != ''
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash
run: |
set -euo pipefail
TAG="${GITHUB_REF_NAME}"
TAG="${RELEASE_TAG}"
OUT_DIR="${{ steps.pkg.outputs.out_dir }}"
ASSET="${{ steps.pkg.outputs.asset }}"
gh release upload "$TAG" "$OUT_DIR/$ASSET" "$OUT_DIR/$ASSET.sha256" --clobber

- name: Upload workflow artifact (manual runs)
if: github.event_name != 'release'
if: github.event_name != 'release' && inputs.tag == ''
uses: actions/upload-artifact@v6
with:
name: codexbar-linux-cli-${{ matrix.name }}
name: codexbar-cli-${{ matrix.name }}
path: |
${{ steps.pkg.outputs.out_dir }}/${{ steps.pkg.outputs.asset }}
${{ steps.pkg.outputs.out_dir }}/${{ steps.pkg.outputs.asset }}.sha256

update-homebrew-tap:
runs-on: ubuntu-latest
needs: build-cli
if: github.event_name == 'release' || inputs.tag != ''
steps:
- name: Resolve release tag
id: release
shell: bash
run: |
set -euo pipefail
tag="${{ inputs.tag || github.ref_name }}"
if [[ -z "$tag" ]]; then
echo "Missing release tag." >&2
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "request_id=codexbar-${tag}-${GITHUB_RUN_ID}" >> "$GITHUB_OUTPUT"

- name: Dispatch tap update
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
shell: bash
run: |
set -euo pipefail
test -n "$GH_TOKEN"
for attempt in {1..6}; do
if gh workflow run update-formula.yml \
--repo steipete/homebrew-tap \
-f formula=codexbar \
-f tag="${{ steps.release.outputs.tag }}" \
-f repository=steipete/CodexBar \
-f artifact_template='CodexBarCLI-{tag}-{target}.tar.gz' \
-f target_aliases='darwin_arm64=macos-arm64,darwin_amd64=macos-x86_64,linux_arm64=linux-aarch64,linux_amd64=linux-x86_64' \
-f request_id="${{ steps.release.outputs.request_id }}"; then
exit 0
fi
if [[ "$attempt" -eq 6 ]]; then
echo "Failed to dispatch tap update after ${attempt} attempts." >&2
exit 1
fi
sleep $((attempt * 30))
done

- name: Wait for tap update
env:
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
shell: bash
run: |
set -euo pipefail
for _ in {1..20}; do
run_id="$(
gh run list \
--repo steipete/homebrew-tap \
--workflow update-formula.yml \
--json databaseId,displayTitle \
--jq '.[] | select(.displayTitle | contains("${{ steps.release.outputs.request_id }}")) | .databaseId' 2>/tmp/codexbar-tap-run-list.err \
| head -n1 || true
)"
if [[ -n "$run_id" ]]; then
gh run watch "$run_id" --repo steipete/homebrew-tap --exit-status
exit 0
fi
cat /tmp/codexbar-tap-run-list.err >&2 || true
sleep 5
done
echo "Timed out waiting for tap workflow to appear." >&2
exit 1
Loading