Skip to content

Releases

v0.10.3

Choose a tag to compare

@github-actions github-actions released this 03 Nov 23:46

Fixed

  • macOS Keychain items asked for authorization after every brew upgrade: sub-bot keys set created items through Security.framework (SecItemAdd) from the sub-bot binary itself. The Homebrew binary is ad-hoc/linker-signed, so the item ACL trusted only that binary's cdhash (and the partition list was cdhash:<hash>); every upgrade changed the cdhash, so the new binary triggered an authorization dialog on first read — or, under launchd with nobody to click it, timed out (no answer from macOS Keychain within 30s …) and the service sat in a restart loop. Trusting a stable path (/opt/homebrew/bin/sub-bot) does not help because both checks are cdhash-based. Keychain items are now read, written and deleted through Apple's /usr/bin/security (same approach as gh / go-keyring): items created by security add-generic-password carry the ACL identifier "com.apple.security" and anchor apple with partition apple-tool:, and security find-generic-password -w reads them without any prompt regardless of which sub-bot build spawns it. keys set deletes an existing item first (an in-place update would keep the legacy ACL), then re-adds and verifies by reading back. The secret never appears in a command line: the add goes through security -i on stdin as -X <hex> (visible in ps only as security -i); service/account names used for writing are restricted to [A-Za-z0-9._/@:-]. Exit codes of the tool are mapped to the same errors as before (44 → not found, 36 → interaction not allowed, 51 / 128 → denied); the tool's stdout never enters errors or logs. keys list still uses a Security.framework attribute search (no data read, no prompt). One-time migration needed for items saved by sub-bot <= 0.10.2 — see keys reauth.

Added

  • sub-bot keys reauth (macOS): migrates Keychain items created by older sub-bot versions (ACL tied to an old binary) to the /usr/bin/security-owned form, so later upgrades need nothing. Targets: managed items under service sub-bot (or --service) plus apiKeyKeychain entries of --config, filtered by --provider / --account, deduplicated. Each item is read once (a legacy item shows one dialog — click "Always Allow" / enter the login password; the usual keychainTimeoutSecs timeout and waiting hint apply), deleted, re-added and read back. Reports migrated / not found / FAILED: <reason> per item; non-zero exit if any failed. --from-env takes the key from OPENAI_API_KEY / ANTHROPIC_API_KEY (named accounts: their apiKeyEnv) instead of reading the old item — zero dialogs. --dry-run lists the targets without reading or changing anything; --json outputs an array like keys list. On Linux it prints that Keychain is macOS-only and exits 0. Output and logs never contain the key.
  • New KeychainError::Tool (keychain tool failed (service=…, account=…): <reason>) for /usr/bin/security not being runnable, a name that cannot be written safely, or an add that reported success but does not read back.

Changed

  • Keychain error and hint texts now point to sub-bot keys reauth (one-time migration) instead of re-running keys set after every upgrade; the keychain error <code> text may now carry the exit status of /usr/bin/security (= OSStatus & 0xff) for read/write/delete, and the OSStatus for attribute searches.

Tests

  • strip_thinking_keeps_text_and_tool_calls_and_drops_emptied_messages no longer fails intermittently (expected messages are cloned from the inputs instead of being rebuilt with a fresh timestamp).

Docs

  • README: Keychain section rewritten — since 0.10.3 upgrades need no action; one-time keys reauth (or keys reauth --from-env / keys set) after upgrading from <= 0.10.2, then launchctl kickstart -k gui/$(id -u)/com.dickwu.sub-bot; the trade-off (any process running as the same user can read the item with security find-generic-password -w without a prompt, comparable to a 0600 apiKeyFile) and how to opt out of it.

v0.10.2

Choose a tag to compare

@github-actions github-actions released this 03 Nov 21:28

Fixed

  • One HTTP request reported as two issues: an unauthenticated request (401) wrote the same issue id twice to issues.log — first count: 1, a few ms later count: 2 — and a dedup summary was delivered at the end of the window. The auth middleware's WARN unauthorized request … and the per-request access log WARN request finished status=401 both became log_warn issues from sub_bot::http with the same dedup key, so the access log was counted as a repeat of the auth failure (any other 4xx in the same window was folded in too). The access log no longer acts as an issue source on its own: 4xx request finished lines are marked issue = "none" (client errors; the caller already gets the reason, and the cases that matter — 401, 409 session rehydration failure, 429 session_limit — have their own issue), and 5xx lines are marked issue = "fallback": they are reported only when nothing more specific was reported for that request (e.g. session rehydration failed, session purge failed, list models failed, a typed run_timeout on 504). One 401 now yields exactly one issue with count: 1 and no summary.
  • MCP tool call timeout reported twice: the MCP tool call timed out WARN became a log_warn issue in addition to the session's tool_timeout issue for the same failure; it is now a typed (diagnostic-only) log line.
  • Issue redaction masked plain words: the Bearer <value> pattern matched ordinary text, turning unauthorized request (missing or unknown bearer token) into … missing or unknown [redacted]. Bearer values are now masked only when they look like a credential (>= 8 chars containing a digit or symbol such as -._~+/=, or >= 20 chars), so phrases like bearer token, api key, token expired, Authorization header missing stay readable. Still masked: Authorization: Bearer … (also Basic / Token schemes), Bearer sk-…, JWTs, sk-…, GitHub tokens (ghp_ / gho_ / ghu_ / ghs_ / ghr_ / github_pat_; arbitrary gh*_ identifiers no longer), api_key|api key|token|secret|password|authorization = <value> assignments including JSON ("api_key":"…"), and configured secret values.

Docs

  • README (Keychain / LaunchAgent): what to do after brew upgrade (re-authorize with keys check in a GUI terminal, then launchctl kickstart -k), why skipping it leaves the service in a restart loop, and a sample com.dickwu.sub-bot LaunchAgent plist.

v0.10.1

Choose a tag to compare

@github-actions github-actions released this 03 Nov 19:06

Fixed

  • Context compaction broke Anthropic extended-thinking sessions: after a compaction every following Anthropic call failed with HTTP 400 Invalid signature in thinking block … bound to a different conversation, because the kept assistant messages still carried signed thinking blocks whose signature is bound to the (now rewritten) preceding conversation. The session stayed broken, including after a restart. Kept messages created before a compaction now have their thinking / redacted_thinking blocks removed from the context sent to the model — for live auto compaction, manual compaction (HTTP / RPC / CLI) and when the context is rebuilt from the JSONL on resume. Text, tool calls and tool_use / tool_result pairing are unchanged; an assistant message left with no content is dropped (it has no tool calls). Messages produced after a compaction keep their thinking until a later compaction keeps them. The JSONL still stores the original messages, so sessions already broken by 0.10.0 heal when rehydrated with 0.10.1.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 03 Nov 18:14

Added

  • Built-in grep / find tools backed by ripgrep's library crates (grep-searcher, grep-regex, grep-matcher, ignore, globset) embedded in the binary — no rg install needed. ripgrep-like semantics: smart-case, fixed strings, multiline, context lines, binary-file skipping, max-count, glob / type filters, .gitignore aware. Included in the default, readonly and no-shell presets.
  • Session persistence & resume: sessions are saved under <dataDir>/sessions by default (sessionDir, persistSessions, --no-persist-sessions). Resume after restart via run --resume, rpc --resume, ask --resume, or simply by using the session id over HTTP. GET /v1/sessions?limit=, DELETE /v1/sessions/{id}?purge=true.
  • Context compaction: automatic (compaction.thresholdPct, keepRecentTokens, model, maxSummaryTokens, per-profile contextWindow) and manual (POST /v1/sessions/{id}/compact, RPC compact); compaction events and compaction_failed issues.
  • Tool approval: per-profile toolApproval policy (allow / ask / deny, globs, timeout + onTimeout). approval_required / approval_resolved events, GET/POST /v1/sessions/{id}/approvals[/{callId}], RPC approve, approval_required webhook event, interactive TTY prompt plus --auto-approve / --auto-deny for ask / run.
  • MCP client (official rmcp SDK): stdio and streamable HTTP servers via global / per-profile mcpServers; tools exposed as mcp__<server>__<tool>; crash detection with restart backoff; tools/list_changed refresh; GET /v1/mcp, sub-bot mcp list; MCP tools go through toolApproval.
  • Licensed under MIT OR Apache-2.0 (LICENSE-MIT, LICENSE-APACHE); THIRD-PARTY-NOTICES.md carries ripgrep's MIT/Unlicense attribution. Release archives now include these files and this changelog.

Fixed

  • session_run tracing span no longer records reasoning_effort twice (the requested value is requested_reasoning_effort).
  • Session listing sort key now equals the returned updatedAt for disk-only sessions.

v0.9.3

Choose a tag to compare

@github-actions github-actions released this 02 Nov 21:00
v0.9.3: typed WARN logs for keychain_waiting / account_unavailable / …

v0.9.2

Choose a tag to compare

@github-actions github-actions released this 02 Nov 20:18
v0.9.2: Keychain reads time out (keychainTimeoutSecs, warn + keychain…

v0.9.1

Choose a tag to compare

@github-actions github-actions released this 02 Nov 18:53
v0.9.1: profile-pinned named accounts no longer require the provider'…

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 18:29
v0.9.0

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 02 Nov 16:24
v0.8.1

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 15:47
v0.8.0: top-3 reasoning efforts (incl. max, extensible levels), dynam…