The retry wrapper should never let CODEWHALE_OHOS_DEP_RETRIES=0 skip the cargo tree probe and pass an empty dependency graph. Reject invalid retry counts before probing so the guard fails loudly instead.
The Version drift gate can fail when Cargo registry fetches briefly drop during the OHOS dependency graph probe. The underlying check is still useful, but a transient EOF should not be indistinguishable from real dependency drift.
Retry cargo tree a few times before failing, while preserving the final nonzero status for real errors. Document the CI hardening in both changelogs.
Register OpenModel across the shared provider registry, CLI model registry, TUI config, provider picker, and docs. Default the route to deepseek-v4-flash, use Anthropic Messages wire semantics, and keep Bearer auth so /v1/messages and /v1/models share one client.
This harvest also updates the config example to use deepseek-v4-flash instead of deepseek-chat, which the original PR notes is not available through OpenModel Messages.
Harvested from PR #3585 by @noaft.
Verification:
- cargo fmt
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-config --locked openmodel
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-tui --bin codewhale-tui --locked openmodel
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target CARGO_INCREMENTAL=0 cargo test -p codewhale-agent --locked first_party_recent_provider_models_are_listed
Drain redirect responses in the npm release asset verifier before following them, and cap redirect recursion to match the existing HEAD helper.
Also clarify the 100-run workflow lookup window and add coverage for non-uploaded GitHub Release assets.
Add a release asset verification gate that compares the local and remote tag SHAs, confirms a successful Release workflow run for that SHA, and reruns the npm wrapper asset verifier against the public GitHub assets.
Strengthen npm release:check so stale or incomplete GitHub Release assets fail before publish, while local/mirror asset checks still work through explicit release-base overrides.
Document npm auth/OTP retry commands, final registry verification, and the legacy deepseek-tui no-republish rule.
Closes#2642.
Closes#2643.
Stage the codew binary in release builds, include it in platform archives and Windows installer inputs, and teach local release asset prep/checks about the shim. The Unix archive installer now installs via atomic replace so an existing executable is not overwritten in place.
Point public vulnerability reporting contact surfaces at [email protected] after the codewhale.net security mailbox bounced. Keep the release guard aligned so CI rejects stale [email protected] references in SECURITY.md.
Follow-ons surfaced by integrating #1519 + #3311:
- #1519 added the dynamic ApiProvider::Custom meta-provider. Exclude it from the
website provider facts (facts-lib.mjs + facts-drift.ts EXCLUDED, like
DeepseekCN) and from the provider-table drift check (META_PROVIDER_TABLES in
check-provider-registry.py) — it's a runtime catch-all, not a shipped provider.
- #3311 moved DEFAULT_TEXT_MODEL's definition to config/models.rs, which broke
the web facts' loose scrape (it mis-bound to an NVIDIA base URL). Read both
files and match the const definition precisely; default model is deepseek-v4-pro
again.
Extract self-contained, behavior-preserving leaves out of the
~6.7k-line crates/tui/src/config.rs into sibling modules under
crates/tui/src/config/, each re-exported behind a `pub use` facade so
every existing `crate::config::<symbol>` path resolves unchanged. No
call site outside config.rs is touched; entangled credential/provider/
default-model/normalization/route logic stays put.
Modules created (config.rs: 6739 -> 6246 lines, ~493 lines moved):
- config/models.rs (160): provider model-name + base-URL constants and
curated model lists (DEFAULT_*_MODEL/BASE_URL, RECENT_OPENROUTER_*,
COMMON/OFFICIAL_DEEPSEEK_MODELS, ...). API_KEYRING_SENTINEL stays in
config.rs with the credential logic.
- config/search.rs (135): SearchProvider, SearchProviderSource,
SearchProviderResolution, SearchConfig (self-contained [search] types).
- config/subagent_limits.rs (69): sub-agent concurrency/timeout limit
constants + their two private clamp resolvers (pulled back privately,
no new external surface).
- config/paths.rs (203): pure filesystem path helpers (config/cache/
workspace path resolution, env-var path overrides, ~ expansion);
effective_home_dir/expand_path re-exported pub(crate). Workspace-trust
and config-load logic stay in config.rs.
scripts/check-provider-registry.py now also scans config/models.rs for
the default model/base-URL constants so the registry gate follows the
split.
Verify: config suite 480 passed / 0 failed; full bin suite 5248 passed
/ 0 failed; cargo build -p codewhale-tui --locked green; clippy clean on
all changed files (the 3 remaining -D warnings errors are pre-existing
too_many_arguments lints in untouched chat.rs/engine.rs); cargo fmt
--all clean; provider registry drift check passes.
Add a release guard that rejects tag-triggered releases whose source commit is not reachable from the canonical main branch. Wire it into release.yml before asset publishing and document the merge-before-tag order in the release runbook and checklist.
Closes#2985.
Second behavior-preserving slice of the config module split: moves the
ProviderKind enum + its identity impl out of lib.rs into a provider_kind module,
re-exported `pub use provider_kind::ProviderKind` so codewhale_config::ProviderKind
and all crate::ProviderKind paths are unchanged. Also updates the provider-registry
drift check to read ProviderKind from its new module. No values/logic changed;
lib.rs shrinks ~158 lines.
cargo fmt/clippy clean; cargo test -p codewhale-config 251 passed; drift check passes.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
SECURITY.md pointed disclosures at [email protected], a domain the
project does not own (the project owns codewhale.net, and the website
footer already uses [email protected]). Reports were being sent to
a dead address. Align SECURITY.md and the check-versions.sh release
guard on [email protected].
Update the release version-drift guard to require the CodeWhale security contact now listed in SECURITY.md, matching the v0.8.64 security contact harvest.
Use refs/remotes/<remote>/main when deriving the default main ref for branch hygiene so a local branch named <remote>/main cannot shadow the intended remote-tracking branch.
This addresses Gemini Code Assist feedback on PR #3348.
Validation:
- bash scripts/release/branch-hygiene.test.sh
- bash scripts/release/branch-hygiene.sh --remote upstream --release-branch hunter/0.8.62-glm-subagents
- cargo fmt --all -- --check
(cherry picked from commit 34a3e227f9)
Add a --remote option so post-merge branch hygiene can inspect upstream release refs from fork checkouts while keeping origin as the default.
Pin the branch-hygiene shell helper and test to LF line endings, make the hermetic test independent of global git identity, and document the post-merge dry-run/prune workflow in the release runbook and checklist.
Fixes#3214
Validation:
- cargo fmt --all -- --check
- bash scripts/release/branch-hygiene.test.sh
- bash scripts/release/branch-hygiene.sh --remote upstream --release-branch hunter/0.8.62-glm-subagents --main-ref upstream/main
- cargo test --workspace --all-features --locked (local run reached codewhale_tui; session_manager temp-dir tests fail because this machine has C:\\.git, and the pandoc/sidebar failures passed when rerun in isolation)
(cherry picked from commit 6952914463)
The mobile shell is intentionally served without embedding the runtime token in the URL while /v1 routes remain bearer-protected. Update the smoke to assert that contract and verify the shell HTML does not echo the configured token.
Sanitize auth-looking identifiers and bearer/key-value forms before the provider registry checker writes drift details to stderr. This keeps the maintainer diagnostics useful while avoiding cleartext sensitive-data output patterns.
Verified with:
- python3 -m py_compile scripts/check-provider-registry.py
- python3 scripts/check-provider-registry.py
- direct redaction probe for bearer and key-value forms
- git diff --check
Remove public benchmark docs/scripts and the shipped SWE-bench CLI surface from the CodeWhale repo; benchmark work belongs outside this release repo.
Trim public docs that routed users into private maintainer runbooks, remove stale deleted-doc links, tone down release-facing copy, update CodeWhale crate descriptions, and expose the residue ledger as /debt while keeping quiet legacy dispatch compatibility.
Verification:\n- cargo fmt --all -- --check\n- git diff --check\n- ./scripts/release/check-versions.sh\n- cargo check -p codewhale-tui --bin codewhale-tui --locked\n- cargo test -p codewhale-tui --bin codewhale-tui --locked command_registry\n- cargo test -p codewhale-tui --bin codewhale-tui --locked every_command_alias_dispatches_to_a_handler\n- cargo test -p codewhale-cli --locked
Preserve the existing local benchmark drift by making Debian installs noninteractive, raising direct-agent default tool timeouts for long build/test steps, classifying more verifier/environment failures, and adding a Pier adapter for local CodeWhale artifacts.
Verified with: python3 -m py_compile scripts/benchmarks/pier_codewhale_local_agent.py scripts/benchmarks/harbor/codewhale_local_agent.py scripts/benchmarks/harbor/deepseek_direct_agent.py scripts/benchmarks/run-codewhale-terminal-bench.py scripts/benchmarks/run-deepseek-direct-terminal-bench.py
Verified with: python3 -m pytest scripts/benchmarks/test_run_codewhale_terminal_bench.py
Add local-artifact CodeWhale, thin direct DeepSeek, and stock mini-swe Terminal-Bench runners for release-candidate comparison rows.
Verified with py_compile, help output, dry-run command generation, and missing-artifact validation. Full Harbor task execution remains a separate benchmark run.
Allow the co-author credit check to ignore known bot/tool co-author trailers on true merge commits while continuing to enforce human contributor credit on harvested commits. Also reject rooted or prefixed state subdir paths so the #3240 hardening behaves consistently on Windows.
Verified: python3 scripts/check-coauthor-trailers.py --author-map .github/AUTHOR_MAP --range origin/main..HEAD --check-authors
Verified: cargo test -p codewhale-config --locked
Verified: cargo test -p codewhale-tui --bin codewhale-tui saved_default_provider_syncs_back_to_runtime_config --locked
Verified: cargo clippy --workspace --all-features --locked -- -D warnings -A clippy::uninlined_format_args -A clippy::too_many_arguments -A clippy::unnecessary_map_or -A clippy::assertions_on_constants
Verified: git diff --check; cargo fmt --all -- --check; python3 scripts/check-provider-registry.py; ./scripts/release/check-versions.sh; cargo audit
The mobile/remote smoke and verify steps could hang indefinitely when a
server accepted a connection but never responded, because the curl health
polls and assert requests had no timeout. Issue #2872 reports the CI
verify step (Smoke Tests) wedging on exactly this.
Bound every unbounded curl in the smoke harness:
- mobile-smoke.sh: --max-time 2 on the two /health readiness polls and
--max-time 10 on the assert_status/assert_body_contains request arrays.
- remote-smoke/setup-vm.sh: --max-time 3 on the final display curl after
the already-bounded readiness loop.
This matches the --max-time convention already used in doctor.sh and the
setup-vm readiness poll. Verified by running mobile-smoke.sh end to end
(9 passed, 0 failed).
Refs #2872.
Clean CI checkouts no longer track web/lib/facts.generated.ts, but check-versions.sh still validates the generated facts version. Derive the ignored facts file before reading it, and regenerate once if the version is stale.
Verified: rm -f web/lib/facts.generated.ts && ./scripts/release/check-versions.sh; git diff --check
Verified zero dependents: no workspace crate depends on codewhale-tui-core,
no `use codewhale_tui_core` exists outside the crate itself, and it is not in
default-members. The 470-line lib.rs carried #![allow(dead_code)] and served
only as an unfinished extraction/parity scaffold.
Removes the crate directory, the workspace `members` entry, the
release-crate publish line, the now-dangling "TUI snapshot parity" CI step
(the crate it tested no longer exists), and the doc/contribute-page mentions
of it. The historical note in docs/CHANGELOG_ARCHIVE.md is left intact as an
accurate record of when the crate was introduced.
Verified: cargo build --workspace, cargo build --release -p codewhale-cli -p
codewhale-tui, cargo fmt --all -- --check, and the remaining two parity
binaries (codewhale-protocol parity_protocol, codewhale-state parity_state)
all pass on the result. Cargo.lock diff is exactly the removed package block.
- Add provider-neutral /v1/chat/completions pass-through with model registry
resolution, configured-credential forwarding, and upstream URL handling.
- Delete crates/app-server/src/main.rs and set autobins=false so the crate ships
as a library consumed by codewhale-cli; no standalone app-server binary.
- Add Arcee default model to the release smoke script.
`codewhale app-server --http`/`--mobile` now serve the full HTTP/SSE runtime API
(/v1/*, SSE, sessions, threads, turns, approvals, usage, fleet, tasks) by
delegating to the same mature server reached via `serve --http`/`--mobile`, which
remain as compatibility aliases. No routes or behavior in
crates/tui/src/runtime_api.rs changed; the CLI reuses the existing sibling-TUI
delegation that `serve` already uses.
- app-server --stdio: unchanged JSON-RPC control transport.
- app-server (bare): unchanged legacy in-process HTTP on :8787.
- AppServerArgs: host/port -> Option (defaults 7878 for --http/--mobile, 8787
legacy); add --http/--mobile/--qr/--workers with clap conflicts; map
--insecure-no-auth onto serve's --insecure when delegating.
- app-server: pin the stdio capability method set with drift tests.
- docs/RUNTIME_API.md: lead with app-server; document benchmark/SDK contract.
- scripts/release/app-server-smoke.sh (+ .test.sh): pre-release headless smoke,
stdio health/capabilities probe (no tokens) plus a secret-safe provider/model
matrix discovered from `codewhale auth list`.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds scripts/release/branch-hygiene.sh: a read-only, dry-run-by-default tool
that makes the post-merge release state obvious and recommends safe branch
cleanup. It reports the current checkout, local+remote release tips, and
origin/main; flags branches whose tip is already contained in main or the
release branch as safe deletes; and lists branches with unique commits as
keep/review, naming the branch, unique-commit count, author(s), and reason.
Enforces the contributor-preservation policy: a branch is only ever a
maintainer-only safe/review item if every unique commit maps to Hunter
(via a built-in list + the canonical side of .mailmap). Any unique commit
from another contributor forces a KEEP and is never auto-deleted unless
already merged. Deletion is gated behind --prune/--prune-remote + a
confirmation (or --yes), and a diverged local/remote release tip exits
non-zero.
Adds a hermetic test (branch-hygiene.test.sh) that builds a synthetic repo
and asserts safe-delete detection, contributor preservation, mailmap
folding, the parked-checkout warning, prune behavior, and divergence
detection. Documents the exact commands as section 5b of the release
checklist.
Refs: #3214
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
#3208 was confusion, not a bug: codewhale-<platform> (bare) is what the npm wrapper
and in-app updater download; codewhale-<platform>.tar.gz bundles the same binaries +
install.sh for manual installs. Clarify both the generated GitHub release body and
INSTALL.md §6 so the Releases page is self-explanatory. Docs only; no pipeline logic.
Closes: #3208
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Harvest #2895 for the v0.8.59 release lane. SiliconFlow CN now reads its own providers.siliconflow_cn / providers.siliconflow-CN table and falls back to providers.siliconflow only when api_key, base_url, or model are unset.
Maintainer amendments wire the TUI fallback paths, provider config get/set/unset/redaction surfaces, env override routing, model normalization, tests, and changelog credit.
Fixes#2893.
Reported-by: Artenx <[email protected]>
Harvest #3009 for the v0.8.59 release lane. Adds a paired Terminal-Bench harness for CodeWhale and Codex, a Codex Harbor adapter, generated-result ignore protection, and benchmark docs.
Maintainer amendments keep explicit zero-valued metrics, regenerate parent task names, write refreshed summaries in regenerate mode, and allow transcript paths outside the repo.
Fixes#2952.
- setup-vm.sh: bump RELEASE_TAG default to v0.8.57, add gh CLI install
step (official APT repo) and 4G swapfile creation (idempotent)
- agent-session.sh: new sourceable helper that exports the provider key
from /etc/codewhale/runtime.env for interactive agent sessions
- README.md: update version refs, add agent-session.sh to layout, add
Autonomous agent loop section with full pick->PR commands
The droplet ops (binary upgrade, PAT setup, first end-to-end issue run)
are documented as the next steps for the operator.
The workflow hardcoded install boilerplate plus a contributor list that
had already drifted (v0.8.56's release thanked people 'for shaping
v0.9.0'). The body now comes from scripts/release/generate-release-body.sh:
static install/verify sections plus the tagged version's changelog section,
which already carries the per-release credits.
- scripts/release/prepare-release.sh bumps workspace + crate pins + npm
wrapper + README install tags, refreshes Cargo.lock, regenerates the
TUI changelog slice and web facts, then runs check-versions.sh
- check-versions.sh now also gates web/lib/facts.generated.ts and the
README install-tag examples (both drifted silently before)
- .cnb.yml validates the pushed tag against Cargo.toml before generating
mirror release notes
- RELEASE_CHECKLIST/RUNBOOK updated accordingly (v0.8.56 needed 9 fix
commits for exactly these sync points)
The packaged changelog is now a recent-releases slice produced by
scripts/sync-changelog.sh (which gains a --check mode); also restore the
SECURITY.md contact line the version gate guards, and finish the stale
binary-name sweep (--bin codewhale examples, qa harness doc).