Adds : an append-only JSONL ledger that
survives process restart and reconstructs queue/worker state.
- Records runs, task inbox entries, leases, lifecycle events, heartbeats,
receipts, and alert decisions.
- Replays the ledger to rebuild on startup.
- Atomic temp-file writes guard against partial writes; malformed lines
are skipped during replay.
- Provides , , , , and a
compaction helper.
- Six tests cover create/rebuild, enqueue/claim, restart survival,
partial-line tolerance, event/heartbeat reconstruction, and receipts.
Closes#3156.
* feat: build static linux x64 binaries with musl
Build codewhale-cli and codewhale-tui with x86_64-unknown-linux-musl
target in the CNB tag_push workflow to produce fully static Linux x64
binaries. Install musl-tools instead of libdbus-1-dev; keep toolchain
install and build in a single stage since CNB stages run in isolated
containers without persistent state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: gate keyring behind not(target_env = "musl") for static builds
When targeting x86_64-unknown-linux-musl, the keyring crate's
linux-native-sync-persistent feature pulls in libdbus-sys which
cannot link against musl. Gate the OS keyring dependency behind
not(target_env = "musl") so musl builds fall back to the
file-backed secret store instead.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: wavezhang <wavezhang@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
- Match actual Harbor CLI interface (no invented flags)
- Proper BaseInstalledAgent subclass for Codex
- Robust token extraction from stream JSONL + transcript parsing
- Heuristic answer_len extraction (## Final Answer markers)
- Metadata capture: versions, git commit, platform, timestamp
- --regenerate walks existing run directories
- All missing fields explicit null, never zero
- Support multiple runs per task with run_idx tracking
The harness is designed to run:
harbor run --dataset terminal-bench@2.0:<task> --agent ... --model ...
for both codex and codewhale agents, then normalize the results.
* feat(config): implement verbosity settings with normal and concise modes
* fix(config): wrap unsafe env calls in tests and fix clippy/fmt errors for CI
* perf(config): avoid verbosity prompt allocations
Split SiliconflowCN into its own [providers.siliconflow_cn] TOML section
instead of silently ignoring [providers.siliconflow-CN] config.
- ProvidersToml / ProvidersConfig: add siliconflow_cn field with serde alias
- for_provider / for_provider_mut / provider_config_for: route SiliconflowCN
to the new field
- resolve_runtime_options_with_secrets: fallback siliconflow_cn → siliconflow
for api_key / base_url / model when unset
- deepseek_api_key: add config-file fallback for SiliconflowCn
- provider_config_key: update metadata to "siliconflow_cn"
- save_api_key_for: write SiliconflowCn keys to providers.siliconflow_cn
- docs/PROVIDERS.md, config.example.toml, scripts/check-provider-registry.py
* fix(tui): normalize macOS SUPER (Cmd) to CONTROL for keyboard shortcuts (#2938)
On macOS, terminal emulators may report Cmd (SUPER) instead of Ctrl
(CONTROL) for keyboard shortcuts, depending on the terminal app and
its configuration. This caused Ctrl+B, Ctrl+Alt+2, and other shortcuts
to be inconsistent.
Fix:
- Add normalize_macos_modifiers() in composer_ui.rs
- On macOS: map SUPER to CONTROL when CONTROL is not already set
- On other platforms: no-op
- Apply normalization at the key event entry point in ui.rs
Tests:
- normalize_macos_modifiers_maps_super_to_control
- normalize_macos_modifiers_preserves_existing_control
- normalize_macos_modifiers_leaves_alt_unchanged
* fix: strip SUPER from modifiers after normalization per review
* fix: gate macOS-specific modifier tests with #[cfg(target_os = "macos")]
Adds a /plugins [name] command to list discovered script plugin tools
and inspect their metadata (description, input schema, approval level,
path). Includes localization strings and unit tests.
Co-authored-by: CodeWhale Agent <codewhale-agent@hmbown.local>
Wire hotbar key dispatch into the TUI event loop.
Bare 1-8 now fires the matching hotbar slot only when the composer is empty.
Alt+1 through Alt+8 fires the matching slot even when the composer has text.
Modal and overlay views keep ownership of those keys, and empty slots remain a
safe no-op.