Open-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
ci(buildkite): put the Linux toolchain where both users can reach it Build 1445 confirmed the re-exec works -- the suite reached uid 1000 -- and then died on `cargo: command not found`. rustup had installed into `/root/.cargo`, which mode 0700 makes unreadable the moment the job stops being root. Install the toolchain into /opt/cargo + /opt/rustup on the Linux agent and mark it a+rX, pass an explicit HOME through the re-exec, and hand CARGO_HOME and ./target to the build user so cargo can still write its registry, git checkouts and target dir. macOS is unaffected: it is not root, so it keeps the HOME-relative paths. That leg has now passed twice at 328s (builds 1443 and 1445). Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
wip(v0.8.67): fleet roster + whaleflow-js cutover checkpoint Safety checkpoint of multi-agent cutover work (fleet roster core, whaleflow-js runtime, /fleet roster view, audit fix lanes). Tree may not compile: the agent-tool profile edit in tools/subagent/mod.rs was interrupted mid-edit (credit exhaustion). Checkpoint precedes repair. | 1 个月前 | |
fix(prompts): single precedence source, facts-only turn_meta, lean prefix Closes the constitution P0 cluster and the first prefix-token cut: - #4777: delete the inverted MEMORY_GUIDANCE Tier ladder; assert precedence only in BASE_PROMPT § Whose word wins; slim Authority Recap to a pointer; reject rank-restating recap overrides; align .codewhale/constitution.json authority[] with the canonical five. - #4778: strip Tier/Statute/Article vocabulary from approval, compaction, memory, and personality overlays so layers describe behavior, not rank. - #4780: turn_meta keeps mode/posture as facts and stops re-embedding mode doctrine and permission-question essays every user message. - #4781: project context pack defaults off (opt-in via project_pack=true). - #4784: compress LANGUAGE_PROMPT while keeping English law / user-language reply, including reasoning_content and next-turn switch. Tests: only_the_constitution_states_precedence, memory hygiene, turn_meta fact-only assertions, project_pack default-off. | 1 个月前 | |
fix(ci): remove stale acid-bath test references Stop invoking deleted brittle harnesses, drop the retired PTY nextest target, and preserve Agent Mail error and redaction behavior without duplicate branches. Signed-off-by: Hunter Bown <hmbown@gmail.com> | 14 天前 | |
fix(devcontainer): support Windows development Use a dedicated development image so Cargo builds have the Rust toolchain, rustfmt, pkg-config, and DBus headers instead of inheriting the minimal release runtime.\n\nReplace the host HOME bind mount with named volumes for CodeWhale state and Cargo artifacts. This avoids invalid Windows HOME expansion, preserves non-root write access, and keeps Rust build churn off the workspace bind mount.\n\nDocument the Dev Container storage and rebuild behavior.\n\nVerification:\n- Built the Dev Container image with Docker Desktop\n- Verified non-root Cargo, Rust, Git, pkg-config, DBus discovery, and writable state/target paths\n- cargo build --locked\n- cargo test -p codewhale-config --locked (cherry picked from commit 8b1ceea7f03394246fa86b9a23b7c75fe661dd46) Signed-off-by: Hmbown <101357273+Hmbown@users.noreply.github.com> | 1 个月前 | |
chore: approve SparkofSpike for contributor CI #5793 (14 files of zh-Hans documentation, +4868/-26) had no CI at all: only Devin, GitGuardian and `gate` reported. Lint, the three Test legs and the npm smoke never started, because an unlisted author's workflow runs sit at `action_required` and never dispatch. That is the failure AGENTS.md describes -- the PR looks abandoned when in fact nobody has looked at it -- and it is worse for a translation contributor, who gets silence rather than a review. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
fix(release): promote tested v0.9.11 nonbenchmark candidate Promotes the fully gated non-benchmark candidate while preserving the benchmark tree exactly from the prior release-PR head. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 11 天前 | |
perf(web): serve one canonical host and a 61%-smaller product screenshot Two things the site was paying for on every visit. **www served the whole site.** `web/wrangler.jsonc` binds both `codewhale.net` and `www.codewhale.net` to this worker as custom domains, and nothing redirected between them — so every page had a second reachable, indexable URL and the two hosts split whatever authority they earned. `middleware.ts` now 301s `www` to the apex before the locale and static-asset branches, so a document that moves does not keep pulling subresources from the host it left. The redirect keeps path and query, leaves the apex, localhost, and preview hosts alone, and still carries the security headers. Doing it in middleware rather than moving the route to the existing `web/redirect` worker is deliberate: reassigning a custom domain between workers has a window where `www` answers with nothing, and this ships atomically with the next deploy. **The LCP element was a 440 KB PNG.** `app/[locale]/page.tsx` marks the product screenshot `priority`, so it is the largest contentful paint, and it was served raw — `next/image` is wired up but the Cloudflare transform binding is not enabled, so nothing resized or re-encoded it. Re-encoded as lossless WebP: 440,507 -> 172,380 bytes (-60.9%) Verified pixel-identical before swapping, not assumed — decoded both and compared: difference bbox `None`, max channel delta 0 across RGBA. A lossy q88 encode was 41 KB but showed a max channel delta of 67, which is visible artifacting on terminal text, so it was rejected. `docs/public-surface-facts.json` holds the README and website screenshots to one byte-identical canonical asset, so both move together — `assets/screenshot.webp` is the same file, and the 19 READMEs and their source stamps follow. That contract is why this is one commit and not two. The contract test read dimensions from the PNG IHDR; it now parses the packed 14-bit fields of the lossless VP8L header, and still accepts PNG so the asset can be swapped back without touching the test. Enabling the Cloudflare Images binding would let `next/image` negotiate AVIF and per-viewport widths on top of this, but it needs Images enabled on the zone, so it is left for a deliberate infra change rather than smuggled in here. Verified: `npx vitest run` — 31 files, 276 tests passing (5 new middleware tests, confirmed failing without the redirect); `tsc --noEmit` clean; `check-readme-translations.py` reports 18 in sync; `prepare-release.sh 0.9.10` clean. | 15 天前 | |
cloud agent: product-owned Daytona snapshot + two fixes found by running agents inside a Computer (#5745) * computer: add product-owned codewhale-cloud-agent Daytona snapshot definition Pins the released v0.9.11 Linux x64 engine (commit 96d13a0bc3f4, sha256 c02969556e51e138afa3fe9c97a1359878cd3d1986b1ce1f5fa96c93c6909416) into a debian:bookworm-slim Computer image with the agent toolchain (git, node 22, python3, ripgrep, build-essential), non-root agent user, and /workspace prepared for the cloud dispatcher (PRD 4.5). Built and probed on Daytona as snapshot codewhale-cloud-agent (4 CPU / 8 GB / 10 GB). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014aDEyM2a4pPZ9qqMDrP5YX Signed-off-by: CodeWhale Bot <bot@codewhale.net> * exec: honour dispatcher-forwarded --provider/--model on --resume/--continue The `codewhale` dispatcher rejects `--provider`/`--model` after `exec` and forwards the top-level flags as CODEWHALE_PROVIDER / CODEWHALE_MODEL. `resolve_exec_resume_route` only looked at the exec-level flags, so `codewhale --provider modelstudio-token-plan --model qwen3.8-flash exec --continue ...` silently restored the saved route (observed in the Daytona cloud-agent e2e on 2026-08-30: the resumed turn ran on deepseek-v4-pro). Fold the launch overrides into the explicit route signals for resume; a fresh session already treated them as explicit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014aDEyM2a4pPZ9qqMDrP5YX Signed-off-by: CodeWhale Bot <bot@codewhale.net> * subagent: scope session-name reservation to the live session A completed worker hydrated from a previous session's workspace ledger is invisible to status/peek/followup (`Agent not found in the active session`), yet spawn still refused its name with "already in use by agent_id ... (status: completed)". A second `codewhale exec` in the same workspace could not spawn worker-a/worker-b again and burned six turns recovering (Daytona cloud-agent e2e, 2026-08-30). Skip prior-session agents in the collision check, matching the other model-facing actions. The existing duplicate-name test now stamps the manager's own boot id so it keeps covering the live-session case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014aDEyM2a4pPZ9qqMDrP5YX Signed-off-by: CodeWhale Bot <bot@codewhale.net> * computer: disclose Daytona create-time env persistence; require post-create key injection Signed-off-by: CodeWhale Bot <bot@codewhale.net> * computer: align snapshot docs and tests with the post-create credential contract - Dockerfile/README: Daytona create-time env is server-visible; provider secrets must never be injected at create time. Post-create delivery over an execution channel (stdin, never argv) into a 0600 file, removed at teardown, is the only documented path. The provider env table is reframed as reference for a future supported bridge, and api_key_env is correctly described as holding an env-var name, not a file path. - Image/probe receipts re-labeled as manual image evidence, not launch proof; the snapshot remains an image definition, not a wired dispatcher. - tui: test-only strengthening — exec_resume route override covered end-to-end through Config::load with CODEWHALE_PROVIDER/CODEWHALE_MODEL; session-name reservation test now hard-expects same-name respawn. Local proof (RUST_MIN_STACK=33554432, --locked): subagent 676/676, exec_resume 4/4, session_name 7/7; cargo fmt --check clean. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * fix(tui): release Runtime Chat owner lock before same-process reopen Safety-gate hermetic tests failed on failed_state_writes_never_become_in_memory_authority_and_exact_retry_reopens with WouldBlock after drop-then-reopen of the same account session (#5735). Unlock on Drop, and retry only WouldBlock, so a just-closed fd is not reported as another owner. A lock that stays held is still ownership. Local proof (hermetic HOME, RUST_MIN_STACK=8388608, --locked): runtime_chat_relay 16/16; Safety-gate tui filter 344/344; execpolicy 108/108 plus authorization_order 1/1; PR exec_resume/session-name 4/4. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * docs: record Pod public-roster surface in the unreleased changelog Feature commit 84f42aefc017 (#5776) landed on main without a durable release-note receipt, so Version drift failed after merging origin/main into this branch. The gate requires #5776 in CHANGELOG.md. Signed-off-by: CodeWhale Bot <bot@codewhale.net> --------- Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 2 天前 | |
docs(computer-meter): stop the header reading as an authority claim Founder correction. The header line "Codewhale is the billing authority" is about *what is billable* -- provider-accepted active seconds rather than Daytona's provisioned wall clock -- not about which service decides. An audit read it as core-versus-control-plane and carried that into codewhale-apps, where it shaped a PR before it was caught. This session's ops backlog repeated the same misreading, so the ambiguity is demonstrably load-bearing. The actual split, now stated first: the control plane in codewhale-apps is the billing authority. It writes sandbox state intervals itself and derives receipts server-side; it never accepts a receipt from a client, correctly, because the CLI runs on the customer's machine. Anything this module issues is a local display or self-check, never billing input. Also records that the module is unwired. `cloud_dispatch::meter_cloud_job` is its only consumer and is itself called only from `#[cfg(test)] mod tests` (cloud_dispatch.rs:1210 and :1227; the module opens at :917), and no ComputerMeterReceipt is transmitted anywhere. A complete implementation that was never connected, left where it reads as authoritative, is precisely the shape that produced the drift above -- so it is flagged for a deliberate wire -or-delete rather than left silent. Comment-only; no behaviour change. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
fix(release): promote tested v0.9.11 nonbenchmark candidate Promotes the fully gated non-benchmark candidate while preserving the benchmark tree exactly from the prior release-PR head. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 11 天前 | |
chore: drop the co-author trailer gate, keep harvested credit (#5789) The Lint job ran scripts/check-coauthor-trailers.py on every commit range and rejected any Co-authored-by trailer that was not a human in .github/AUTHOR_MAP or one of two hardcoded agent identities. In practice it rejected ordinary agent commits -- the default trailer most tools append fails it -- so every contributor and every agent had to learn a rule that bought tidiness and nothing else. Removed: the 46-line "Check harvested contributor credit" step in ci.yml, the checker, its test, and its five fixtures. Also the stale mention in the light-change path filter. Kept, deliberately: harvested contributor credit. auto-close-harvested.yml is independent of the deleted script -- it reads "Harvested from PR #N by @handle" from the commit message -- so a contributor's PR still closes with credit when their work lands, and .github/AUTHOR_MAP remains the canonical human identity list. The rule that survives is "name the humans who did the work". The rule that goes is "no tool may appear in a trailer". The two skills that called the checker now read trailers with git log directly. CONTRIBUTING.md and AGENTS.md say what is true now instead of describing a gate that no longer exists. actionlint is clean on the edited workflow. Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
fix(release): promote tested v0.9.11 nonbenchmark candidate Promotes the fully gated non-benchmark candidate while preserving the benchmark tree exactly from the prior release-PR head. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 11 天前 | |
chore: delete v0867/v0868 debris and stale slop references Removes the retired v0868-stopship fleet roster, the v0867 setup QA script, and the three v0867 constitution evidence docs, none of which anything on the train references anymore (rg-verified; the only inbound link was docs/CONFIGURATION.md, updated here). Trims the dead v0868-stopship alias from the stopship role-validation guard in crates/cli/src/lib.rs, drops the retired /slop and /canzha aliases from the command-dispatch architecture doc, and removes the deleted crates/tui/src/slop_ledger.rs path from source-structure-budget.json. The v0868_ name-guard regression test stays by design. Verified: cargo fmt clean, cargo test -p codewhale-cli --lib (204 passed), source-structure-budget.json still valid JSON. | 1 个月前 | |
fix(exec): leave headless turn budgets opt-in Run headless agent loops without a finite model-step ceiling unless the caller explicitly supplies --max-turns. Keep finite values validated and preserve the separate Fleet worker budget. Remove the verifier harness's implicit 100-turn flag so long benchmark rollouts are not silently truncated. Verified with the focused TUI regression, all nine verifier harness tests, cargo fmt, targeted strict Clippy, and diff checking. | 26 天前 | |
misc: replace stdenv.isLinux with stdenv.hostPlatform.isLinux | 6 天前 | |
fix(release): promote tested v0.9.11 nonbenchmark candidate Promotes the fully gated non-benchmark candidate while preserving the benchmark tree exactly from the prior release-PR head. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 11 天前 | |
fix(packaging): preserve AUR compatibility alias Keep the existing codewhale-tui symlink when codewhale-bin upgrades while installing codew from the consolidated archive. Pin the package-layout regression and make the Omarchy documentation match the compatibility contract. | 9 天前 | |
fix(tui): measure circled digits and keycaps as 2 columns everywhere (#4479) (#5001) The v0.9.1 fix (9be600bf4) made CodeWhale's own width helpers grapheme- aware, but Ratatui's renderer still measures ambiguous-width characters through its own unicode-width dependency, whose width() reports Enclosed Alphanumerics (circled digits/letters) as 1 column while CJK terminals paint them as 2. The 1-column cell placement shifts every downstream column by one, producing the intermittent missing-characters / phantom-space glitch that mouse selection only temporarily repairs. Fix the width accounting at all three layers: 1. Patch unicode-width 0.2.2 via [patch.crates-io] so UnicodeWidthChar:: width() and UnicodeWidthStr::width() report 2 columns for Enclosed Alphanumerics (U+2460-U+24FF), Dingbat Circled Digits (U+2776-U+2793), and Circled Numbers on Black Square (U+3248-U+324F). The patch is scoped to exactly those ranges; box-drawing glyphs and ellipsis keep their 1-column non-CJK widths, so table borders and truncation do not regress. 2. Keep the explicit range override in char_display_width as a defense in depth that does not depend on the patch. 3. Keep the U+20E3 override in grapheme_display_width / markdown_grapheme_width for keycap sequences that lack an FE0F variation selector (unicode-width reports those as 1 column too). Adds regression tests asserting UnicodeWidthChar::width('\u{2460}') == Some(2) and that circled digits count as 2 columns in text_display_width, plus the existing keycap suite. 26 ui_text tests and 52 markdown_render tests pass. | 1 个月前 | |
chore: drop the co-author trailer gate, keep harvested credit (#5789) The Lint job ran scripts/check-coauthor-trailers.py on every commit range and rejected any Co-authored-by trailer that was not a human in .github/AUTHOR_MAP or one of two hardcoded agent identities. In practice it rejected ordinary agent commits -- the default trailer most tools append fails it -- so every contributor and every agent had to learn a rule that bought tidiness and nothing else. Removed: the 46-line "Check harvested contributor credit" step in ci.yml, the checker, its test, and its five fixtures. Also the stale mention in the light-change path filter. Kept, deliberately: harvested contributor credit. auto-close-harvested.yml is independent of the deleted script -- it reads "Harvested from PR #N by @handle" from the commit message -- so a contributor's PR still closes with credit when their work lands, and .github/AUTHOR_MAP remains the canonical human identity list. The rule that survives is "name the humans who did the work". The rule that goes is "no tool may appear in a trailer". The two skills that called the checker now read trailers with git log directly. CONTRIBUTING.md and AGENTS.md say what is true now instead of describing a gate that no longer exists. actionlint is clean on the edited workflow. Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
feat(telemetry): report observed active installs with trend, freshness, and caveats Operationalize the owner report around the honest metric: observed active installs = distinct rotating anonymous install ids with a session_start ingested on a UTC day. The canonical report:active-installs command prints the daily series, a complete-days 7-vs-7 trend, event freshness, and an always-printed coverage-caveat block; report:dau remains as a pure re-export compat alias. Exclusion guarantees are now pinned by tests (index1 only inside count(DISTINCT), no content/identity/network columns anywhere in the report path), and the output is forbidden from claiming DAU/unique users. Known floor semantics recorded in docs: day attribution is ingest-day (events carry no per-event timestamps), distinct counts cannot be sampling-corrected, and id rotation can double-count across a trend window — all framed as the lower-bound caveats they are. Verified: telemetry-ingest npm test (109/109), npm run typecheck, CLI smoke against fixtures. Implemented with Claude Code agent assistance. | 23 天前 | |
chore(deps): bump next from 15.5.21 to 16.3.3 in /web (#5673) Bumps [next](https://github.com/vercel/next.js) from 15.5.21 to 16.3.3. - [Release notes](https://github.com/vercel/next.js/releases) - [Commits](https://github.com/vercel/next.js/compare/v15.5.21...v16.3.3) --- updated-dependencies: - dependency-name: next dependency-version: 16.3.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> | 2 天前 | |
test(tui): pin injection sizes — child envelope, parent surface, turn_meta R6 (finish-operator 2026-08-02): the only envelope number anyone quoted was a stale fixture comment (workflows/stopship.workflow.js:1-5, 17,457–17,550 tokens from an old live run). Nothing failed when the assembled payloads grew. Three regressions now build — never send — the real payloads and pin them at measured-current +10%: - read_only_child_envelope_stays_within_measured_ceiling: scout system prompt + seed messages + child tool catalog = 80,856 bytes measured (~20k tokens — the old 17.5k figure was already low); ceiling 89,000. - parent_agent_surface_stays_within_measured_ceiling: BASE_PROMPT + full parent tool catalog = 72,679 bytes measured; ceiling 80,000. - turn_meta_block_stays_within_measured_ceiling: per-turn <turn_meta> block via the production snapshot path = 254 bytes measured (includes the new sandbox-posture line); ceiling 280. Each failure message says how to raise the ceiling honestly (re-measure in the same commit). The stopship fixture comment now points at the pinned test instead of the stale token figure. Proof the ceilings bite: a scratch diff padding BASE_PROMPT +15,000B, the child system prompt +17,000B, and turn_meta +1 line (~+20% each) failed all three tests; reverted, all green. Verification: - cargo fmt --check -p codewhale-tui: clean - cargo test -p codewhale-tui --bin codewhale-tui -- turn_meta_block_stays read_only_child_envelope parent_agent_surface: 4 passed; 0 failed | 1 个月前 | |
ci(cnb): post shadow GitHub check runs from linux rust gates (#5746) Import the codewhale-cnb-bridge GitHub App credentials from the CNB KeyStore (codewhale.net/codewhale-ci-secrets, github-bridge.yml) via the documented imports mechanism, and add an endStages bridge step to the linux rust gates pipeline that mints an installation token and posts a non-required 'linux rust gates -cnb' Check Run on the exact GitHub SHA being built, with the conclusion mapped from CNB_PIPELINE_STATUS. Per the shadow-parity protocol in the CNB-primary CI design: GitHub Actions stays canonical and required, no GitHub gate flips, and the bridge runs in endStages so a bridge outage can never fail the CNB pipeline itself. Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
fix(release): embed user-theme schema inside codewhale-tui package cargo publish and the Docker image both failed because palette/user_theme.rs include_str!'d docs/schemas/..., which is outside the crate package and excluded by .dockerignore. Copy the schema into crates/tui/src/assets and include it from there so crates.io packaging and container builds can compile codewhale-tui. Keep a .dockerignore exception for docs/schemas as belt-and-suspenders for other embeds. | 1 个月前 | |
feat: add Mistral AI as a first-class provider route Wire Mistral AI / la Plateforme into the shared provider registry, TUI provider enum, provider-scoped config/env overrides, static model registry, context-window metadata, reasoning wiring, docs, and examples. The route uses Mistral's OpenAI-compatible Chat Completions endpoint at https://api.mistral.ai/v1 with 'mistral-code-latest' as the default model (Codestral coding model, 256K context). Model IDs verified live against https://api.mistral.ai/v1/models: the static registry ships 'mistral-code-latest' (accepts 'codestral-latest' as alias for backward compatibility), 'mistral-medium-latest', 'mistral-small-latest', 'magistral-small-latest', and 'mistral-large-latest'. All models report 262144 (256K) context on /v1/models except mistral-code-latest at 256000; earlier drafts of this PR had those windows reversed. Reasoning is wired end-to-end for the three models that advertise 'reasoning: true' on /v1/models — mistral-medium-latest, mistral-small-latest, and magistral-small-latest. Codewhale sends 'reasoning_effort' (Mistral currently accepts 'none' or 'high' only; intermediate tiers return HTTP 400 code 3051), parses the polymorphic 'content: [{type: thinking, thinking: [{type: text, text: ...}], closed: bool}, {type: text, text: ...}]' shape emitted by reasoning models, and replays the thinking trace back into multi-turn history per docs.mistral.ai/capabilities/reasoning. Non-reasoning models (mistral-code-latest, mistral-large-latest) never receive the field because Mistral would reject it. FIM (/v1/fim/completions) is not wired. Provider aliases: mistral-ai, mistralai, la-plateforme. Env vars: MISTRAL_API_KEY, MISTRAL_BASE_URL, MISTRAL_MODEL. Auth via API key from https://console.mistral.ai/api-keys, config, or 'codewhale auth set'. Test env-poisoning: EnvGuard captures/removes/restores MISTRAL_* so tests stay reproducible when a user has these vars exported in their shell. Validation: - cargo fmt --all -- --check - cargo clippy --workspace --all-targets --all-features --locked (with the documented allow list) -- No issues found - cargo test --workspace --all-features --locked -- 22 pre-existing failures in crates/tui git-shell tests (worktree init failing on 'git commit' in isolated tempdirs), verified identical count on origin/main at 91bca01a9 and unrelated to this change - python3 scripts/check-provider-registry.py -- passed - codewhale --provider mistral --model mistral-medium-latest exec against api.mistral.ai returned a correct reasoning-mode response - codewhale --provider mistral --model mistral-large-latest exec succeeded without HTTP 400 code 3051 (verifies the model-aware reasoning gate) - TUI smoke previously validated: /status shows mistral + mistral-code-latest, /provider lists Mistral, tool call end-to-end Assisted by Codex CLI for implementation and multiple Oracle review passes (correctness + convention + Hunter's inline review) that surfaced the ProviderArg clap enum gap, the ModelRegistry silent fallthrough to DeepSeek, the Codestral context-window regression, the EnvGuard env-poisoning flake, and the model-ID / context-window / reasoning-support mistakes from the initial docs-slug pass now corrected against the live /v1/models catalog. | 25 天前 | |
fix(ci): keep Tideline goldens LF on Windows checkouts crates/tui/src/tui/goldens/*.txt fell through to the `* text=auto` fallback, so a Windows checkout converted all forty goldens to CRLF. golden_harness.rs::render_golden_text always joins rows with LF and assert_matches_golden compares the fs::read_to_string bytes directly, so Test (windows-latest) failed all eight golden tests with a pure \r\n diff. Same fix, same reason, as the telemetry golden JSON above. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 5 天前 | |
ci(buildkite): actually ship the step scripts The previous commit added .buildkite/pipeline.yml but not the scripts it invokes. `.gitignore` line 59 ignores `*.sh` repo-wide, with negations for `!scripts/**` and `!.github/scripts/**`; `.buildkite/**` had none, so `git add .buildkite` staged the YAML and silently dropped all three scripts. Buildkite proved it: $ .buildkite/steps/lint.sh /bin/bash: line 1: .buildkite/steps/lint.sh: No such file or directory 🚨 Error: The command exited with status 127 Add the negation in the same shape as the existing two rather than inlining the commands into YAML: kept as scripts they stay `bash -n`-checkable and shellcheck-able, which is how the `Workflow lint` job already treats `.github/workflows`. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
chore: map github web committer | 4 个月前 | |
chore: drop the co-author trailer gate, keep harvested credit (#5789) The Lint job ran scripts/check-coauthor-trailers.py on every commit range and rejected any Co-authored-by trailer that was not a human in .github/AUTHOR_MAP or one of two hardcoded agent identities. In practice it rejected ordinary agent commits -- the default trailer most tools append fails it -- so every contributor and every agent had to learn a rule that bought tidiness and nothing else. Removed: the 46-line "Check harvested contributor credit" step in ci.yml, the checker, its test, and its five fixtures. Also the stale mention in the light-change path filter. Kept, deliberately: harvested contributor credit. auto-close-harvested.yml is independent of the deleted script -- it reads "Harvested from PR #N by @handle" from the commit message -- so a contributor's PR still closes with credit when their work lands, and .github/AUTHOR_MAP remains the canonical human identity list. The rule that survives is "name the humans who did the work". The rule that goes is "no tool may appear in a trailer". The two skills that called the checker now read trailers with git log directly. CONTRIBUTING.md and AGENTS.md say what is true now instead of describing a gate that no longer exists. actionlint is clean on the edited workflow. Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
feat(compaction): publish survival contract and keep last round (#4394) (#5782) * feat(compaction): publish survival contract and keep last round (#4394) Port the missing coverage floor onto origin/main: replacement history keeps a bounded last user round (assistant + tool results) and refuses the rewrite if that round, /anchor text, or the checkpoint receipt would vanish. Failed compact still does not replace live history. Publish the language-invariant schema next to the compaction module and surface path + /anchor survival in /context. Billed parent prompt tokens survive the turn boundary so last-turn pressure can still auto-compact. Evidence: cargo test -p codewhale-tui --lib --offline --locked -- compaction context_inspector last_round -> 125 passed; 0 failed Refs: #4394 Signed-off-by: CodeWhale Bot <bot@codewhale.net> * fix(compaction): keep last tool round and unstick CI (#4394) Drop the unused validate_last_round_coverage re-export that failed Lint. Walk last_round_start back to the last tool-bearing user round instead of one hop, so two trailing toolless turns cannot drop a tool result behind the summary. Sync the TUI changelog slice with root. Add a language-invariant fixture matrix and a Node coverage validator next to the survival contract. There is no Go runtime in this repository yet. Evidence: cargo check -p codewhale-tui --locked cargo clippy -p codewhale-tui --lib --locked -- -A clippy::all -D unused-imports cargo test -p codewhale-tui --lib --offline --locked -- compaction context_inspector last_round -> 128 passed; 0 failed node crates/tui/src/compaction/validate_survival_contract.mjs -> ok 9 survival-contract fixtures Refs: #4394 Signed-off-by: CodeWhale Bot <bot@codewhale.net> * fix(compaction): make the coverage floor actually hold the last round The PR's central claim was that a rewrite cannot drop the last round. It could, three ways, and all three are now regression-tested. Reverting just the validator with the new tests in place fails all three: dropping the latest user turn must fail the coverage floor: () dropping the tool call must fail the coverage floor: () substituting a summary for the round's output must fail closed: () 1. It checked the *first* user text in the round, not every one. `last_round_start` walks back past a toolless tail to the previous tool-bearing turn, so the round routinely spans two user messages. `find_map(user_text_of)` took the earliest, so a replacement that kept "Run the suite." and dropped "Now ship it." passed -- the latest turn, the one the contract exists to keep, was exactly what could vanish. 2. It covered tool_result ids but never tool_use ids. A replacement could keep a tool_result whose tool_use had been summarized away. That orphan is not just lossy, it is a request providers reject. 3. The assistant check was existential. "The round has an assistant message, so the replacement must have an assistant message" is satisfied by the summary the rewrite itself just wrote. It now compares text, with the same truncation-tolerant prefix rule the user check uses, and keeps the existential check underneath for rounds whose only assistant turn is a text-free tool call. validate_survival_contract.mjs carried all three holes verbatim. SURVIVAL_CONTRACT.md calls it "the same coverage floor", so it is fixed in the same shape rather than left to contradict the doc; both now pass the shared fixture matrix. cargo test -p codewhale-tui --lib compaction (RUST_MIN_STACK=16777216) test result: ok. 117 passed; 0 failed; 0 ignored; 0 measured; 11559 filtered out node crates/tui/src/compaction/validate_survival_contract.mjs ok 9 survival-contract fixtures Signed-off-by: CodeWhale Bot <bot@codewhale.net> --------- Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
docs: adopt the ponytail decision ladder (#5787) Founder-directed. From dietrichgebert/ponytail -- 'the laziest senior dev in the room', 'the best code is the code you never wrote'. Encodes the ladder verbatim rather than paraphrasing it: 1. Does this need to exist? -> Skip it 2. Already in this codebase? -> Reuse it 3. Stdlib does it? -> Use it 4. Native platform feature? -> Use it 5. Installed dependency? -> Use it 6. One line? -> One line 7. Only then: the minimum that works Two parts of the source method matter as much as the rungs and are kept explicit. The ladder runs *after* understanding the problem -- lazy about solutions, never about reading the code first. And it never cuts trust-boundary validation, data-loss handling, security, or accessibility. Rung 2 is the one this repository keeps failing, so the section says so and points at the existing model_*/ *_config / provider_* grep rule rather than restating it. Two corollaries earned here are added because the ladder does not cover them: an abstraction must delete caller code, and migrate the last consumer or do not start. Carries no counts. AGENTS.md's first line says to derive changing state from the repository rather than from instructions, so the dead-code corollary points at scripts/check-dead-code-budget.py instead of freezing a number. CLAUDE.md gets a pointer, not a copy. Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
docs: add CODE_OF_CONDUCT.md Add Contributor Covenant Code of Conduct v2.1 to establish community guidelines and set clear expectations for participant behavior. | 3 个月前 | |
docs: add Indonesian documentation suite and README.id.md Add README.id.md linked to main README, CONTRIBUTING.id.md, and comprehensive Indonesian documentation suite in docs/*.id.md. Pass check-readme-translations.py validation. | 1 个月前 | |
chore: drop the co-author trailer gate, keep harvested credit (#5789) The Lint job ran scripts/check-coauthor-trailers.py on every commit range and rejected any Co-authored-by trailer that was not a human in .github/AUTHOR_MAP or one of two hardcoded agent identities. In practice it rejected ordinary agent commits -- the default trailer most tools append fails it -- so every contributor and every agent had to learn a rule that bought tidiness and nothing else. Removed: the 46-line "Check harvested contributor credit" step in ci.yml, the checker, its test, and its five fixtures. Also the stale mention in the light-change path filter. Kept, deliberately: harvested contributor credit. auto-close-harvested.yml is independent of the deleted script -- it reads "Harvested from PR #N by @handle" from the commit message -- so a contributor's PR still closes with credit when their work lands, and .github/AUTHOR_MAP remains the canonical human identity list. The rule that survives is "name the humans who did the work". The rule that goes is "no tool may appear in a trailer". The two skills that called the checker now read trailers with git log directly. CONTRIBUTING.md and AGENTS.md say what is true now instead of describing a gate that no longer exists. actionlint is clean on the edited workflow. Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
chore(deps): bump schemaui from 0.12.3 to 0.12.4 (#5695) Bumps [schemaui](https://github.com/yuniqueunic/schemaui) from 0.12.3 to 0.12.4. - [Release notes](https://github.com/yuniqueunic/schemaui/releases) - [Changelog](https://github.com/YuniqueUnic/schemaui/blob/main/CHANGELOG.md) - [Commits](https://github.com/yuniqueunic/schemaui/compare/schemaui-v0.12.3...schemaui-v0.12.4) --- updated-dependencies: - dependency-name: schemaui dependency-version: 0.12.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> | 2 天前 | |
chore: remove verified-dead code and unused dependencies Dead-code sweep over main. Every removal was verified two ways before deletion: a rustc --force-warn dead_code pass over a full --workspace --all-targets build, and a whole-word textual reference search across Rust sources, scripts, docs, web/, npm/, and integrations/, so items consumed by non-Rust tooling or reserved by documented external contracts were kept. Unused dependencies (cargo-machete): - codewhale-core: tokio-util — zero references in the crate. - codewhale-tui: ratatui-core — the direct dependency was only ever a transitive-version pin; its own comment records the pin became obsolete once ColorCompatBackend started answering get_cursor_position() from tracked state. The surviving note now documents that behavior on the ratatui entry. Cargo.lock slims accordingly (drops hashbrown 0.15.5 and the futures-io / futures-util edges tokio-util's workspace "full" features pulled in). Dead functions with no callers, no reservations, and no external consumers: - provider_lake::all_catalog_providers - voice::available_asr_providers (its doc cited a `voice --list` surface that does not exist) - features::feature_spec_by_key - tui/git_status::list_worktrees - fleet/profile::load_personal_agent_profiles_tolerant - plugins/discovery::load_plugin_for_test (test-only helper with no remaining callers) - work_graph::Runtime::reconcile_workspace_owner_bindings - work_graph::liveness::ExternalBinding::with_acceptance - tools/spec::ToolContextBuilder::with_sandbox_policy Kept despite compiler visibility: PUBLIC_SANDBOX_BACKENDS (parsed by the web facts-drift gate), palette token inventory marked #[expect(dead_code)] by design, and seams explicitly reserved for tracked follow-ups (TUI-DOG-008..011, #2186, #4651, #4407, #3217, #97). Evidence (local): cargo check --workspace --all-targets clean with zero warnings; cargo fmt --all -- --check clean; cargo-machete clean; 261 focused nextest cases across the touched modules pass; the force-warn dead_code inventory shows the nine removed items gone and no newly-dead items introduced. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 5 天前 | |
fix(release): promote tested v0.9.11 nonbenchmark candidate Promotes the fully gated non-benchmark candidate while preserving the benchmark tree exactly from the prior release-PR head. Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 11 天前 | |
feat(tui): make settings MCP recovery first-class and clickable (#5655) * feat(tui): make settings MCP recovery first-class and clickable Settings Advanced now exposes Connect/Reconnect/Diagnose and plugin rows instead of a path-only MCP section, and the category tabs are mouse-clickable. The extensions MCP tab, plugin Problems group, and /mcp manager name recovery commands that exist (/mcp login, /mcp reload, /mcp validate, /plugin validate). Stale OAuth copy no longer points at the non-existent /mcp auth. OpenRouter Hunyuan aliases (hy3, hunyuan) resolve to tencent/hy3-preview; hy4 is not added. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * docs: add TUI settings/MCP recovery lane handoff Record the isolated worktree SHA, journeys, tests actually run, PR #5643 overlap, and what remains unverified. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * test(tui): bump Extensions locale census for MCP recovery actions Connect/Reconnect/Re-auth/Diagnose add four ExtensionsAction keys. The complete-set census is 86, not 82. Signed-off-by: CodeWhale Bot <bot@codewhale.net> --------- Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 6 天前 | |
Initial release v0.1.0 DeepSeek TUI - Unofficial terminal UI + CLI for DeepSeek models. Features: - Interactive TUI with multiple modes (Normal, Plan, Agent, YOLO, RLM, Duo) - Comprehensive tool access with approval gating - File operations, shell execution, task management - Sub-agent system for parallel work - MCP integration for external tool servers - Session management and skills system - Cross-platform support (macOS, Linux, Windows) 🤖 Generated with [Claude Code](https://claude.ai/code) | 7 个月前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
Merge branch 'codex/v0911-auth-port-20260820' into codex/v0911-integration-20260820 # Conflicts: # CHANGELOG.md # crates/tui/CHANGELOG.md | 13 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
docs(public): align release facts with runtime Derive website sandbox facts from explicit runtime capability markers instead of source filenames. Document actual platform wrappers, narrow model and audit claims, and make two-package/three-command installs exact. Verify release assets under their manifest filenames before renaming them, with an executable contract test for every Unix snippet. Refresh localized README receipts and keep source-candidate toolCount at 66. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
feat(config): add one shared RFC 8628 device-code polling primitive CodeWhale had two hand-rolled device-code pollers with nothing shared between them (crates/cli/src/cloud.rs poll_device, crates/tui/src/ xai_oauth.rs poll_device_token + device_poll_backoff). The xAI one decided whether to keep polling by substring-matching its own error strings, which is why slow_down handling was stringly typed. Port pi's pollOAuthDeviceCodeFlow to Rust as codewhale_config:: device_code::DeviceCodePoll, generic over the poll result and free of I/O: the caller supplies poll and sleep. It carries pi's accumulated fixes, which CodeWhale did not all have: - RFC 8628 3.2 default of 5s when the server omits interval - slow_down that PREFERS a server-supplied interval over the client-tracked one, because a purely client-tracked interval polls early forever under WSL/VM clock drift; RFC 8628 3.5's +5s step is the fallback - a deadline from expires_in that is never slept past, including after backoff - a distinct timeout message once any slow_down was seen Also ports pi's validateVerificationUri as validate_browser_verification_uri: the URI comes off the wire and is handed to a browser opener, so it must not be able to launch file:, javascript:, or a custom app scheme. pi requires https; this allows http on a loopback host as well, matching the loopback allowance crates/cli/src/cloud.rs already makes for a self-hosted test API. The primitive never holds, formats, or logs token material: T is opaque to the module and no Debug/Display derive touches it. Ported from pi (MIT, Copyright (c) 2025 Mario Zechner), packages/ai/src/auth/oauth/device-code.ts and .../xai.ts; notice carried in THIRD_PARTY_NOTICES.md and at the top of the new module. Implemented with agent assistance. Signed-off-by: Hunter Bown <hmbown@gmail.com> | 13 天前 | |
fix(custom): wire = responses|anthropic for openai-compatible + opencode-zen muse-spark (rescue of #5716) (#5719) * ci: add Windows x64 build workflow on push to main * fix: trigger build-windows on any push to main * fix(custom): support wire = "responses" | "anthropic" | "chat" for kind="openai-compatible" Custom provider was fixed to ChatCompletions, ignoring providers.<name>.wire. Now honors per-config wire in both client::provider_wire_format_for_config and config::provider_capability, keeping Custom::wire_policy default as Chat for compat. Aliases: responses/openai-responses/responses-api -> Responses; anthropic/messages/claude -> AnthropicMessages; default -> Chat. Fixes custom muse-spark-1.2 on opencode.ai/zen/v1 needing Responses. * fix(opencode-zen): route muse-spark over Responses API Muse Spark 1.2 contributor-free on https://opencode.ai/zen/v1 only supports POST /v1/responses (Responses API) and rejects Chat Completions. Previously the bundled offering roster and ModelAware resolver treated unknown muse-spark variants as chat or failed closed to unproven, so CodeWhale sent chat payloads that 404. - Add muse-spark-1.2, -contributor, -contributor-free to OPENCODE_ZEN_RESPONSES_MODELS (bundled_offerings) - Add resolver fallback: any muse-spark* under OpencodeZen resolves to endpoint_key responses even without exact catalog match - Update config.example.toml docs (GPT/Muse Spark -> Responses) and add muse-spark-1.2-contributor-free example - Add scripts/opencode-chat2responses-proxy.mjs as zero-Rust chat->responses shim for chat-only clients Custom gateways can already use wire="responses" (ff504585a); this fix makes the first-class opencode-zen provider work without hand-written wire config. * fix(client): keep codex env-token auth working on custom endpoints PR #5716 diverted OpenaiCodex credential resolution to the generic key resolver whenever provider_uses_custom_endpoint() is true, which dropped an explicit OPENAI_CODEX_ACCESS_TOKEN for custom-base-url setups. The shared-seam wiremock test proves the regression: the mock only answers Bearer test-token, so the request came back 404 on all three CI OSes (client::responses::tests::responses_stream_open_preserves_wire_headers_ through_shared_seam). The manual if-condition formatting also failed the Lint job's cargo fmt --check. Restore the pre-PR precedence by trying codex_credentials() first: env credentials still win on custom endpoints (codex_credentials checks env before the official-endpoint consent grant), the official endpoint keeps propagating OAuth errors, and only a custom endpoint with no env token falls back to deepseek_api_key() — preserving the contributor's goal of letting a custom endpoint authenticate with its own configured key. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * refactor(tui): route wire-dialect reads through one Config helper The wire= feature read providers.<id>.wire in two places (client wire resolution and the capability reporter), and provider_capability_with_ wire was exported but never called with a real value — a parallel entry point that reported Chat for custom providers the client actually speaks Responses/Messages to. - Add Config::provider_wire_dialect() as the single trimmed, non-empty wire reader; use it in provider_wire_format_for_config and the doctor capability report (provider_capability_with_wire). - Drop the over-broad '|| normalized.contains("responses")' from wire_config_prefers_responses in both modules: every listed alias except the singular 'response'/'response-api' spellings already contains the substring, so the fallback only admitted unintended values like 'not-responses'. - Remove the vestigial 'let _ = provider_kind;' marker in the resolver arm that now genuinely uses provider_kind. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * revert(ci): drop contributor-added build-windows workflow The PR added a Build Windows x64 workflow triggering on every push to main. That build is already covered: release-artifacts.yml builds both x86_64-pc-windows-msvc and aarch64-pc-windows-msvc release binaries, nightly.yml rebuilds them nightly, and ci.yml runs the full test matrix on windows-latest. A fourth always-on Windows build only spends CI minutes on every main push and grants the job an actions:write permission it does not need. Contributor CI-workflow additions are outside this feature's scope; restoring main's tree (no such file). Signed-off-by: CodeWhale Bot <bot@codewhale.net> --------- Signed-off-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: whp233 <whp233@users.noreply.github.com> Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 2 天前 | |
build(deps): carry one jsonschema stack again (690 → 685 packages) The dependabot bump of the workspace `jsonschema` pin to 0.49 (d85be3b76) left schemaui 0.12 — which still requires ^0.46, including its latest 0.12.4 — on the old line, so the graph compiled jsonschema, jsonschema-regex, referencing, and fancy-regex twice (5.8 s + 3.2 s of the cold lib-test build for the two jsonschema units alone) and `cargo deny check bans` warned on all four. Pin the workspace back to the 0.46 line schemaui can share, with a note to move both together, and drop the stale jni/jni-sys/redox_syscall skips deny reported as unmatched or unnecessary. `cargo deny check bans` and `check advisories` are clean; `--locked` still resolves; codewhale-workflow-js and the tui schema tests pass. multiple-versions stays "warn". | 18 天前 | |
fix(nix): update flake.lock to avoid crates download 403 issue | 6 天前 | |
misc: replace stdenv.isLinux with stdenv.hostPlatform.isLinux | 6 天前 | |
release: assemble v0.9.11 non-benchmark candidate | 12 天前 | |
fix(deps): bump undici 7.28.0->7.29.0 (override), fast-uri 3.1.4->3.1.5, brace-expansion to fixed lines — clears 23 Dependabot alerts | 28 天前 | |
chore: use stable rust toolchain channel Cargo already enforces the workspace MSRV through rust-version, so let rustup select the current stable toolchain instead of pinning contributors to exactly Rust 1.88. Fixes #3570. | 2 个月前 |
Codewhale
Codewhale 是一款面向终端的开源编程智能体,使用 Rust 构建,并与用户一起在公开协作中不断改进。

English · 日本語 · Tiếng Việt · Bahasa Indonesia · 한국어 · Español · Português · Русский · Українська · Français · Deutsch · 繁體中文 · हिन्दी · Türkçe · Italiano · Polski · العربية · Català
安装
npm install -g codewhale
codewhale
首次运行会帮助你连接提供商,也可以选择保持离线。Codewhale 还支持 Cargo、Docker、Nix、Scoop、预构建压缩包、Android/Termux 和 CNB 镜像。请参阅安装指南。
每种 shell 只需一条命令即可启用 Tab 补全——codewhale completion bash|zsh|fish|powershell|elvish。请参阅 shell 补全。
使用
像与队友交流一样向 Codewhale 描述任务:
Fix the failing tests and explain what changed.
也可以不打开 TUI,直接运行任务:
codewhale exec "fix the failing tests and explain what changed"
Codewhale 可以读取你的代码仓库、编辑文件、运行命令、检查结果,并持续推进目标。由你决定授予它多少访问权限。
为什么选择 Codewhale
- 使用你想要的模型。 连接托管提供商,或通过 Ollama、vLLM、SGLang 使用本地模型。使用
/model切换提供商和模型。 - 掌控始终在你手中。 Plan 模式为只读。Ask、Auto-Review 和 Full Access 会清晰展示审批行为。
/undo可撤销上一轮操作,/restore可将工作区恢复到较早的快照。 - 让长时间任务井然有序。 保存会话、设置持久的
/goal、在工作流运行前进行审查,并协调多个智能体,同时不让其内部指令混入你的对话记录。 - 扩展你已有的智能体。 连接 MCP 服务器和技能、配置钩子,并将智能体角色作为可读文件保存在项目或个人设置中。
在 TUI 中运行 /help 可查看命令和键盘快捷键。
安全
Codewhale 在你的机器上运行,并仅拥有你授予的访问权限。审批模式和仓库规则会限制智能体的行为;在支持的平台上,可选的操作系统沙箱可提供更强的执行边界。未知的模型价格会保持显示为未知,而不会被误报为免费。
文档
加入社区
当人们使用 Codewhale、反馈不顺手之处并帮助修复问题时,它就会变得更好。如果缺少某个提供商、工作流体验不佳,或终端界面妨碍了你,请提交 issue。如果你知道如何改进,请提交 pull request。我们欢迎首次贡献,贡献者也会保留已合入工作的署名。
加入 Discord,或在微信添加 Hunter(hunterbown)并申请加入 Whale Brothers 群。
项目历史
Codewhale 起初名为 deepseek-tui,至今仍保留与其配置和会话的兼容性。如今它已不偏向任何提供商,由社区独立维护,也不隶属于任何模型提供商。
感谢每一位贡献者,以及帮助项目成长的开源社区。请参阅贡献者记录。
许可证
项目介绍
适用于 DeepSeek 模型的编码代理,可在终端运行【此简介由AI生成】