| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
ci(triage): stop over-labelling well-specified issues (#4792) Two auto-labellers were classifying issues from their full body text, which meant the better-specified an issue was, the more wrong labels it collected. The v0.9.2 localization issues (#4787, #4790) landed tagged `bug, question` purely because their acceptance criteria said "fails when a pack drifts" and a scope heading said "How to add a locale". triage.yml: match type labels against the title only. A title states what an issue *is*; a body just discusses it. Also drop `error` and `fail(ed|ure)` from the bug rule outright — they describe what nearly every issue mentions, not what any issue is. This trades a little recall for precision: a genuine bug whose title avoids the word "bug" now needs manual triage, which is the cheaper error. agent-task-labels.yml: `tui` required only a bare \btui\b, so any issue that referenced the terminal UI in passing was tagged as touching it. Anchor on `crates/tui`, `ratatui`, and `codewhale-tui` instead. Those signals are also the ones that survive the single-binary refactor (#4747): the crate path and the framework stay when codewhale-tui is lib-ized, while the binary name goes away. Verified against the four issues that misfired: `bug` and `question` clear on all of them, `tui` is retained where the body genuinely cites crates/tui, a synthetic "Crash on startup: panic in ratatui render loop" still classifies as bug+tui, and a passing "how the tui differs from the web UI" mention no longer fires. | 1 个月前 | |
chore(ci): bump GitHub Actions to latest majors (dependabot #3334-#3338) Batch the routine CI action version bumps proposed by dependabot: actions/checkout v4 -> v7 (21 uses) actions/github-script v7 -> v9 (5 uses) actions/upload-artifact v4 -> v7 (4 uses) actions/setup-node v4 -> v6 (4 uses) docker/metadata-action v5 -> v6 (1 use) The repo already runs actions/download-artifact@v8 and actions/stale@v10, so high majors are exercised in this CI already, and upload-artifact is already past its v3->v4 breaking change. All 13 workflow files re-parse as valid YAML. These are CI-only changes that cannot be exercised locally; the integration branch PR run must confirm them before they reach main. Refs #3334, #3335, #3336, #3337, #3338. | 2 个月前 | |
chore(ci): bump GitHub Actions to latest majors (dependabot #3334-#3338) Batch the routine CI action version bumps proposed by dependabot: actions/checkout v4 -> v7 (21 uses) actions/github-script v7 -> v9 (5 uses) actions/upload-artifact v4 -> v7 (4 uses) actions/setup-node v4 -> v6 (4 uses) docker/metadata-action v5 -> v6 (1 use) The repo already runs actions/download-artifact@v8 and actions/stale@v10, so high majors are exercised in this CI already, and upload-artifact is already past its v3->v4 breaking change. All 13 workflow files re-parse as valid YAML. These are CI-only changes that cannot be exercised locally; the integration branch PR run must confirm them before they reach main. Refs #3334, #3335, #3336, #3337, #3338. | 2 个月前 | |
chore(release): keep the v0.9.1 candidate honest Accept the explicit unreleased-candidate heading during source CI while requiring a dated heading and tag compare link at publication time. Sync the packaged TUI changelog so it carries the same candidate wording and contributor credit as the root record. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
fix(ci): repair three shared check failures blocking open PRs (#5017) * fix(ci): skip the PR-issue link gate for bot-authored PRs The `link` job fails on every dependabot PR (e.g. #5010-#5016): dependabot bodies are machine-generated dependency bumps that never contain a closing keyword, so the gate exits 1 ("This PR neither closes an issue nor says why it doesn't", run 30665868640/job 91272641294). Skip the gate step when the PR author is a GitHub-verified bot account (`pull_request.user.type == 'Bot'`, set by GitHub so it cannot be spoofed). This covers dependabot today and any other automation (renovate, etc.) without hand-editing every bot body, while keeping the gate strict for every human PR. Policy choice: all verified bots, not just dependabot[bot]. Bots cannot respond to a prompt, and their changes never close issues; the check's purpose is keeping human work linked to its issue. * fix(ci): provision the deny container's Rust toolchain explicitly cargo-deny runs inside EmbarkStudios/cargo-deny-action@v2's alpine container (host triple x86_64-unknown-linux-musl, rustup default 1.85.0-musl). The repo's rust-toolchain.toml pins `channel = "stable"` with no target, so the action's `rustup show` (entrypoint.sh) resolves it to `stable-x86_64-unknown-linux-musl` — not installed — and every run prints: error: override toolchain 'stable-x86_64-unknown-linux-musl' is not installed: the toolchain file at '/github/workspace/rust-toolchain.toml' specifies an uninstalled toolchain then auto-installs mid-run (network-dependent ~12s detour; hard failure if the download stalls; seen in run 30665967039/job 91272951661). Pass `rust-version: stable` so the entrypoint provisions the channel (`rustup default stable`, same musl host triple) before cargo-deny touches the workspace; the toolchain file then resolves to an installed toolchain. * fix(deps): bump event-listener 5.4.1 -> 5.4.2 (RUSTSEC-2026-0221) cargo-deny (advisories) fails on every dependabot PR (e.g. run 30665967039/job 91272951661) with the unsound advisory: error[unsound]: `event-listener` allows `!Send` tags to cross thread boundaries via `StackSlot` (RUSTSEC-2026-0221) event-listener 5.4.1 unconditionally implements Send/Sync for StackSlot, allowing a !Send tag to cross threads via Event::with_tag. Pulled in via codewhale-tui -> codewhale-workflow-js -> rquickjs -> rquickjs-core -> async-lock (and event-listener-strategy). Advisory solution: >=5.4.2, the latest published version. `cargo update -p event-listener` lands exactly on 5.4.2 (also drops its now unneeded concurrent-queue dependency). No deny.toml ignore needed. * fix(ci): fetch the locked graph before the offline runtime-contract check The Lint job's "Check runtime-contract budget" step fails on every dependabot PR (run 30665967040/job 91273020141, PR #5016): error: failed to download `assert-json-diff v2.0.2` Caused by: attempting to make an HTTP request, but --offline was specified subprocess.CalledProcessError: ... returned non-zero exit status 101. [runtime-contract-budget] ERROR: runtime-contract measurement failed with exit code 1 Root cause: check-runtime-contract-budget.py hardcodes CARGO_NET_OFFLINE=true and runs `cargo test --locked` on codewhale-tui, which needs the dev-dependency graph (wiremock -> assert-json-diff). Clippy above builds no test targets, and Swatinem/rust-cache keys its registry cache on Cargo.lock, so any lock-changing PR (every dependabot bump) misses the cache and the offline test cannot download the missing crate. Reproduced locally with the identical error by removing assert-json-diff from the registry cache and re-running the exact CI command. Fix: fetch the full locked graph (`cargo fetch --locked`, dev-deps included) once in the heavy path before the measurement, so the hermetic offline measurement is deterministic on every branch. The budget contract itself is unchanged and still enforced. * fix(ci): reviewed source-structure budget update for merged LaTeX module Merging #4981 (LaTeX rendering) added crates/tui/src/tui/history/ latex_render.rs (1734 lines) and grew aggregate owned Rust source to the measured merged state (644756 lines). The ratchet's contract requires an explicit reviewed update for new thousand-line modules and aggregate growth; this commit allows the merged module and raises the ceiling to the exact CI-measured value. Verified: check-source-structure-budget.py PASS on the branch; runtime-contract budget still PASS 55/55. | 1 个月前 | |
fix(vscode): make the extension's send path work, and close the security holes The extension had never successfully started a turn. `startTurn` accepted only HTTP 200/202 while the runtime's `start_thread_turn` (crates/tui/src/runtime_api.rs:4613-4632) returns `StatusCode::CREATED` as its ONLY success path, so every send failed. `git log -- src/api.ts` is a single commit: this was never a regression, it shipped that way and was never run end to end. api.ts (send path): - Status handling now tests a RANGE (`isOk`: >= 200 && < 300) through one `ensureOk` helper routed through every call site, rather than enumerating codes at eleven of them. 201 is accepted because it is 2xx, not because it is special-cased — the same shape the embedded web client already used at crates/tui/src/runtime_web/app.mjs:873, which is why that client worked against the same runtime this one choked on. - The runtime's JSON `error.message` is surfaced on every route; previously only startTurn passed it through. - 409 is typed: a second send while a turn is live is "already running", and interrupting when nothing streams is "nothing to stop", not an error. Security (extension.ts, runtime.ts, secrets.ts): - SecretStorage now wins over the settings token, matching what secrets.ts, the manifest and the README all already promised. Previously a repo-local .vscode/settings.json could supply a bearer AND retarget `runtimeHost`, and the token rode every request — opening a repo was enough. - The runtime token is passed to the terminal via environment instead of `--auth-token` in argv, which was visible in shell history and `ps`. - status.ts nonce uses a CSPRNG, matching chat.ts. Chat correctness and accessibility (chat.ts, transcript.ts): - Transcript prefers `detail` over the 280-char `summary`, so reload shows the reply instead of a stub. - `operation_key` is reused on retry, so a timeout and resend no longer creates two turns; the dead SSE stream is cleared so reconnect can fire. - The composer keeps its text until the turn is accepted. - Tool paths are parsed out of `metadata.tool_input` and treated as untrusted. The durable fix is runtime-side and is NOT taken here. - Focus styling and roles/labels added; there were none. Chrome (package.json, extension.ts): - Chat is contributed to the secondary sidebar with an activity-bar fallback, gated on `codewhale.noSecondarySidebar`, which is set at activation from `vscode.version` (>= 1.106). One ChatView instance serves both view ids and `reveal()` focuses whichever resolved. - `engines.vscode` stays `^1.96.2` and the threshold is enforced at runtime, matching the shipping Codex extension; raising the floor would have cut off 1.90-1.105 users and made the fallback unreachable for nothing. CI and dev loop (ci.yml, .gitignore, .vscode/): - CI runs the extension tests. Nothing ran them before, which is how a send path that could not work stayed green. - launch.json/tasks.json give a working F5 host. The root `.gitignore`'s bare `.vscode/` silently swallowed them, so a negation was added — without it these files exist locally and vanish on commit. Gates: cd extensions/vscode && npx tsc --noEmit -> clean cd extensions/vscode && npm test -> tests 42, pass 42, fail 0 (baseline before this was 25) manifest/provider coherence: every declared view id has a provider; no provider lacks a manifest entry; context key set at activation. Not done, deliberately: the Runtime view still exists, so this is not yet a single-view Agents panel. Removing it spans extension.ts, status.ts and two commands; a half-removal is worse than either state. Gate item 5 — a human driving one real turn in an Extension Development Host — remains unproven. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D4rk4NXwyy6wmvii9Lp84P Signed-off-by: CodeWhale Bot <bot@codewhale.net> | 1 天前 | |
ci: add advisory Claude PR review workflow (#3456) Wire Claude code review into every non-draft PR as a GitHub Action, since GitHub CODEOWNERS only accepts users/teams (not bots). @Hmbown stays the human owner; the review is advisory and posts alongside it. - claude-review.yml: anthropics/claude-code-action@v1 in review mode with track_progress; auth via CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`). No-ops with a notice until the secret is set, so it's safe to merge first. Codex/ChatGPT review is handled out-of-repo via the ChatGPT Codex cloud integration (chatgpt.com/codex), authed by the ChatGPT subscription, so no OpenAI workflow or repo secret is needed. CODEOWNERS documents the split. The review prompt also guards the v0.8.65 EPIC #2608 routing invariant (provider-prefixed model strings are wire ids/hints, not provider-selection proof). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> | 2 个月前 | |
fix(ci): surface Claude issue-worker replies via tracking comment Live verification on #4542 showed the worker session completing successfully while its reply went nowhere: agent mode with display_report/show_full_output disabled and a cargo/npm-only tool allowlist has no path that can write back to the issue. track_progress forces tag mode, whose app-token tracking comment carries progress and the final report on the triggering issue without widening the tool allowlist. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
build(deps): bump actions/create-github-app-token from 2 to 3 Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2 to 3. - [Release notes](https://github.com/actions/create-github-app-token/releases) - [Changelog](https://github.com/actions/create-github-app-token/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/create-github-app-token/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/create-github-app-token dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> | 2 天前 | |
ci(dco): add checkout repository for fork PR support - Add repository: ${{ github.event.pull_request.head.repo.full_name }} so actions/checkout works for both same-repo and fork PRs Signed-off-by: laopan <147567034@qq.com> | 2 个月前 | |
chore(ci): bump GitHub Actions to latest majors (dependabot #3334-#3338) Batch the routine CI action version bumps proposed by dependabot: actions/checkout v4 -> v7 (21 uses) actions/github-script v7 -> v9 (5 uses) actions/upload-artifact v4 -> v7 (4 uses) actions/setup-node v4 -> v6 (4 uses) docker/metadata-action v5 -> v6 (1 use) The repo already runs actions/download-artifact@v8 and actions/stale@v10, so high majors are exercised in this CI already, and upload-artifact is already past its v3->v4 breaking change. All 13 workflow files re-parse as valid YAML. These are CI-only changes that cannot be exercised locally; the integration branch PR run must confirm them before they reach main. Refs #3334, #3335, #3336, #3337, #3338. | 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> | 17 天前 | |
fix(ci): do not cancel-in-progress on main pushes (#5395) Main and schedule/dispatch runs share one concurrency group via github.ref when there is no pull_request.number. cancel-in-progress: true then killed prior main CI before it could fail, which is how v0.9.8 assertion regressions shipped (#5383). Keep cancel-in-progress only for pull_request events so superseded PR heads still cancel; apply the same fix to ohos.yml which used the identical group pattern. Agent-assisted change. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Hunter Bown <Hmbown@users.noreply.github.com> | 24 天前 | |
chore(ci): bump GitHub Actions to latest majors (dependabot #3334-#3338) Batch the routine CI action version bumps proposed by dependabot: actions/checkout v4 -> v7 (21 uses) actions/github-script v7 -> v9 (5 uses) actions/upload-artifact v4 -> v7 (4 uses) actions/setup-node v4 -> v6 (4 uses) docker/metadata-action v5 -> v6 (1 use) The repo already runs actions/download-artifact@v8 and actions/stale@v10, so high majors are exercised in this CI already, and upload-artifact is already past its v3->v4 breaking change. All 13 workflow files re-parse as valid YAML. These are CI-only changes that cannot be exercised locally; the integration branch PR run must confirm them before they reach main. Refs #3334, #3335, #3336, #3337, #3338. | 2 个月前 | |
fix(ci): repair three shared check failures blocking open PRs (#5017) * fix(ci): skip the PR-issue link gate for bot-authored PRs The `link` job fails on every dependabot PR (e.g. #5010-#5016): dependabot bodies are machine-generated dependency bumps that never contain a closing keyword, so the gate exits 1 ("This PR neither closes an issue nor says why it doesn't", run 30665868640/job 91272641294). Skip the gate step when the PR author is a GitHub-verified bot account (`pull_request.user.type == 'Bot'`, set by GitHub so it cannot be spoofed). This covers dependabot today and any other automation (renovate, etc.) without hand-editing every bot body, while keeping the gate strict for every human PR. Policy choice: all verified bots, not just dependabot[bot]. Bots cannot respond to a prompt, and their changes never close issues; the check's purpose is keeping human work linked to its issue. * fix(ci): provision the deny container's Rust toolchain explicitly cargo-deny runs inside EmbarkStudios/cargo-deny-action@v2's alpine container (host triple x86_64-unknown-linux-musl, rustup default 1.85.0-musl). The repo's rust-toolchain.toml pins `channel = "stable"` with no target, so the action's `rustup show` (entrypoint.sh) resolves it to `stable-x86_64-unknown-linux-musl` — not installed — and every run prints: error: override toolchain 'stable-x86_64-unknown-linux-musl' is not installed: the toolchain file at '/github/workspace/rust-toolchain.toml' specifies an uninstalled toolchain then auto-installs mid-run (network-dependent ~12s detour; hard failure if the download stalls; seen in run 30665967039/job 91272951661). Pass `rust-version: stable` so the entrypoint provisions the channel (`rustup default stable`, same musl host triple) before cargo-deny touches the workspace; the toolchain file then resolves to an installed toolchain. * fix(deps): bump event-listener 5.4.1 -> 5.4.2 (RUSTSEC-2026-0221) cargo-deny (advisories) fails on every dependabot PR (e.g. run 30665967039/job 91272951661) with the unsound advisory: error[unsound]: `event-listener` allows `!Send` tags to cross thread boundaries via `StackSlot` (RUSTSEC-2026-0221) event-listener 5.4.1 unconditionally implements Send/Sync for StackSlot, allowing a !Send tag to cross threads via Event::with_tag. Pulled in via codewhale-tui -> codewhale-workflow-js -> rquickjs -> rquickjs-core -> async-lock (and event-listener-strategy). Advisory solution: >=5.4.2, the latest published version. `cargo update -p event-listener` lands exactly on 5.4.2 (also drops its now unneeded concurrent-queue dependency). No deny.toml ignore needed. * fix(ci): fetch the locked graph before the offline runtime-contract check The Lint job's "Check runtime-contract budget" step fails on every dependabot PR (run 30665967040/job 91273020141, PR #5016): error: failed to download `assert-json-diff v2.0.2` Caused by: attempting to make an HTTP request, but --offline was specified subprocess.CalledProcessError: ... returned non-zero exit status 101. [runtime-contract-budget] ERROR: runtime-contract measurement failed with exit code 1 Root cause: check-runtime-contract-budget.py hardcodes CARGO_NET_OFFLINE=true and runs `cargo test --locked` on codewhale-tui, which needs the dev-dependency graph (wiremock -> assert-json-diff). Clippy above builds no test targets, and Swatinem/rust-cache keys its registry cache on Cargo.lock, so any lock-changing PR (every dependabot bump) misses the cache and the offline test cannot download the missing crate. Reproduced locally with the identical error by removing assert-json-diff from the registry cache and re-running the exact CI command. Fix: fetch the full locked graph (`cargo fetch --locked`, dev-deps included) once in the heavy path before the measurement, so the hermetic offline measurement is deterministic on every branch. The budget contract itself is unchanged and still enforced. * fix(ci): reviewed source-structure budget update for merged LaTeX module Merging #4981 (LaTeX rendering) added crates/tui/src/tui/history/ latex_render.rs (1734 lines) and grew aggregate owned Rust source to the measured merged state (644756 lines). The ratchet's contract requires an explicit reviewed update for new thousand-line modules and aggregate growth; this commit allows the merged module and raises the ceiling to the exact CI-measured value. Verified: check-source-structure-budget.py PASS on the branch; runtime-contract budget still PASS 55/55. | 1 个月前 | |
feat(packaging): add verified Omarchy AUR path Render codewhale-bin PKGBUILD and .SRCINFO metadata from the workspace version and checksum-verified x64/arm64 release archives. Preserve the Arch runtime dependency contract, reject placeholders and tampered assets, and validate package contents deterministically.\n\nWire the renderer into CI and release-candidate smoke without publishing to AUR, and document Omarchy install/update plus the separately authorized release handoff. | 14 天前 | |
ci: bound every release-lane job and guard the bound (#5496) #5495 capped `ci.yml`; the release path was left on GitHub's 360-minute default. That is not theoretical — the v0.9.9 train had an assigned-but-dead runner sit `in_progress` with 404 logs, and the operator rule (cancel/rerun after 20 minutes of 404s) only limits damage while somebody is watching. Twenty jobs were uncapped: all of `release-candidate.yml`, `release-artifacts.yml`, `release.yml`, and `release-republish.yml`. Caps use the four values agreed in the issue (candidate resolve 10, candidate web 15, artifact build 90, and 15 each for bundle / windows-installer / assemble / smoke) and size the rest against observed healthy durations with margin. Jobs that call a reusable workflow are deliberately left alone: GitHub rejects `timeout-minutes` on a `uses:` job, which is exactly why the artifact bounds belong in `release-artifacts.yml` rather than in its callers. The acceptance criterion asked for a test that fails when a new uncapped release job appears, so the guard lands with the thing it guards. It walks each workflow's job headers, skips `uses:` jobs, and requires an explicit `timeout-minutes` — and it immediately found a job the manual pass missed, `nightly.yml`'s `build`, now capped at 90 minutes alongside the artifact build. It also asserts the artifact build keeps at least 60 minutes, because a tight cap there would fail healthy Windows builds that historically run 40-45. Timeouts are containment, not recovery: the runbook keeps the 404-log cancel/rerun rule for infrastructure failures. Verified: `node .github/scripts/release-workflows.test.js` passes; re-run with an uncapped job spliced into release.yml it fails with "release.yml: every job must set timeout-minutes (#5496)". All six workflows still parse as YAML with their job counts unchanged. | 20 天前 | |
build(deps): bump docker/setup-qemu-action from 4.2.0 to 4.3.0 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/96fe6ef7f33517b61c61be40b68a1882f3264fb8...1f40c72289eff860ee54a304f1438e3cff362e0a) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: 4.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> | 2 天前 | |
build(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3 Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/3d0d9888cb7fd7b750713d6e236d1fcb99157228...efb35369e0ad2afab669f228072c1b0d510eae64) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 3.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> | 2 天前 | |
ci: add RustSec security audit and cargo-deny checks Add security audit infrastructure using RustSec advisory database: - .github/workflows/security-audit.yml: runs cargo-audit to scan Cargo.lock for known vulnerabilities - .github/workflows/cargo-deny.yml: checks advisories, dependency bans, licenses, and sources - audit.toml: cargo-audit configuration - deny.toml: cargo-deny configuration with allowed licenses - README.md: add Security audit and cargo-deny status badges | 1 个月前 | |
chore(ci): bump GitHub Actions to latest majors (dependabot #3334-#3338) Batch the routine CI action version bumps proposed by dependabot: actions/checkout v4 -> v7 (21 uses) actions/github-script v7 -> v9 (5 uses) actions/upload-artifact v4 -> v7 (4 uses) actions/setup-node v4 -> v6 (4 uses) docker/metadata-action v5 -> v6 (1 use) The repo already runs actions/download-artifact@v8 and actions/stale@v10, so high majors are exercised in this CI already, and upload-artifact is already past its v3->v4 breaking change. All 13 workflow files re-parse as valid YAML. These are CI-only changes that cannot be exercised locally; the integration branch PR run must confirm them before they reach main. Refs #3334, #3335, #3336, #3337, #3338. | 2 个月前 | |
chore(deps): bump actions/stale from 10.4.0 to 11.0.0 (#5010) Update actions/stale to 11.0.0. All substantive platform, lint, workflow, security, and source-budget checks pass. | 1 个月前 | |
chore(ci): bump GitHub Actions to latest majors (dependabot #3334-#3338) Batch the routine CI action version bumps proposed by dependabot: actions/checkout v4 -> v7 (21 uses) actions/github-script v7 -> v9 (5 uses) actions/upload-artifact v4 -> v7 (4 uses) actions/setup-node v4 -> v6 (4 uses) docker/metadata-action v5 -> v6 (1 use) The repo already runs actions/download-artifact@v8 and actions/stale@v10, so high majors are exercised in this CI already, and upload-artifact is already past its v3->v4 breaking change. All 13 workflow files re-parse as valid YAML. These are CI-only changes that cannot be exercised locally; the integration branch PR run must confirm them before they reach main. Refs #3334, #3335, #3336, #3337, #3338. | 2 个月前 | |
telemetry: add the first-party ingest Worker (not deployed) Adds `telemetry-ingest/`, a Cloudflare Worker that accepts the batches `crates/telemetry` produces and writes them to Workers Analytics Engine. Nothing is deployed and no Cloudflare resource was created; the shipped `telemetry_endpoint` default stays unset, `config.example.toml` and `docs/TELEMETRY.md` are untouched. Publishing is a separate, deliberate step. It lives at the top level rather than inside `web/` because the site is a separate deploy with its own Next.js/OpenNext build, and a telemetry change should not rebuild the marketing site. The endpoint is write-only: one POST route, every other method 405, no route that returns data, and a zero-byte body on every status. The client reads only the status class and drops the batch on anything non-2xx, so a rejection here is invisible to the user by construction — which is what lets the endpoint fail closed and refuse anything it cannot account for. Three properties are enforced by tests rather than by intent: `docs/TELEMETRY.md` says "Batches are IP-stripped at ingest. No IP is stored, logged, or joined to install_id." This Worker is the whole of what makes that true. It reads exactly two headers, never touches the request's `cf` property, logs nothing, and turns invocation logs off in the config; the row builder's input type is the validated batch body, so it cannot see the connection at all. `test/no-ip.test.ts` greps the shipped source for the header and geo names and fails the build if one appears, if the set of headers read grows, if a console call is added, or if a Response is ever built with a body. The validator is a closed field set, not a permissive parse: an unexpected key anywhere — envelope, event, counters, errors, turn_wall — rejects the whole batch with 400. A future client bug that starts attaching a path or a prompt is refused rather than quietly stored. `test/schema-doc.test.ts` parses the field names and enum spellings back out of `docs/TELEMETRY.md` and asserts set equality against the validator, and the suite posts `crates/telemetry/tests/golden/v1.json` — the client's own pinned wire form — asserting it is accepted and that deleting any key from it is rejected. Doc, client, and server cannot drift apart silently. The body cap is computed, not guessed: `parse_events` bounds a batch at 200 events and 65536 bytes, plus 199 commas and ~375 bytes of envelope, so 66110 bytes is the conforming worst case and the cap is 72 KiB. The 512-record ring is the disk cap, not the wire cap. Rate limiting is keyed on `install_id` from the validated body, never on an address. Analytics Engine layout is one data point per event, indexed on `install_id`, with the ten counters, six error classes and four turn-wall buckets filling all twenty doubles. The README documents the exact SQL for the two questions this exists to answer — installs and sessions, and which error classes and panic sites dominate — one query each. Verified locally only: 87 vitest tests, `tsc --noEmit`, `wrangler deploy --dry-run`, and `wrangler dev --local` driven with curl (204 on the golden batch, 400 on an unknown key and on an out-of-allowlist panic site, 413 oversized, 405 GET, 415 wrong content type, 404 other path, 429 after 20 POSTs from one install id). `wrangler dev` caught a real defect the dry run did not: the runtime maps every named export of the entrypoint to an entrypoint, so the route constant moved to its own module. | 1 个月前 | |
ci(triage): stop over-labelling well-specified issues (#4792) Two auto-labellers were classifying issues from their full body text, which meant the better-specified an issue was, the more wrong labels it collected. The v0.9.2 localization issues (#4787, #4790) landed tagged `bug, question` purely because their acceptance criteria said "fails when a pack drifts" and a scope heading said "How to add a locale". triage.yml: match type labels against the title only. A title states what an issue *is*; a body just discusses it. Also drop `error` and `fail(ed|ure)` from the bug rule outright — they describe what nearly every issue mentions, not what any issue is. This trades a little recall for precision: a genuine bug whose title avoids the word "bug" now needs manual triage, which is the cheaper error. agent-task-labels.yml: `tui` required only a bare \btui\b, so any issue that referenced the terminal UI in passing was tagged as touching it. Anchor on `crates/tui`, `ratatui`, and `codewhale-tui` instead. Those signals are also the ones that survive the single-binary refactor (#4747): the crate path and the framework stay when codewhale-tui is lib-ized, while the binary name goes away. Verified against the four issues that misfired: `bug` and `question` clear on all of them, `tui` is retained where the body genuinely cites crates/tui, a synthetic "Crash on startup: panic in ratatui render loop" still classifies as bug+tui, and a passing "how the tui differs from the web UI" mention no longer fires. | 1 个月前 | |
design: export the TUI whale palette instead of re-typing it (#5797) * design: export the TUI whale palette instead of re-typing it crates/tui/src/palette/tokens.rs is the whale palette. The web app repeated its hexes by hand, the desktop shell ran a separate neutral-gray palette, and the Android theme a fourth one — four palettes sharing exactly one value (#08111C). Make the Rust file the source and generate the rest. scripts/export-design-tokens.py parses the 47 WHALE_*_RGB consts (aliases included: INFO = ACTION = ACCENT_PRIMARY, SUCCESS = WORKING_GREEN, ERROR_BORDER = ERROR, ...) and emits web/app/tokens.css, plus — when a codewhale-apps checkout sits beside this repo — the desktop CSS token file and a Compose WhaleTokens object. Aliases are emitted as var()/val references, so the alias structure survives the export instead of flattening into duplicate literals. --check fails when a generated file is stale; it is wired in as `npm run check:tokens` and runs in the web workflow. globals.css keeps its own variable names (--paper, --ink, --indigo — the component rules and the docs light sheet consume them) and now binds them to --whale-* rather than re-typing the hex. Only byte-identical values were rebound; --paper-card, --indigo-deep, --stage-ambient and --stage-hint are not whale tokens and stayed literal. No rendered color changes. The two contract tests read hexes straight out of globals.css, so they now resolve one hop through the generated file (lib/whale-tokens.ts). They still catch a wrong mapping: pointing --paper at --whale-panel fails with "expected '#0e1729' to be '#03070d'". Evidence, in web/: npm test -> Test Files 42 passed (42), Tests 364 passed (364) npm run lint -> clean; npx tsc --noEmit -> clean npm run build -> succeeded; built CSS carries --whale-bg:#03070d and --paper:var(--whale-bg) npm run check:tokens -> design tokens up to date (47 tokens) check:facts, check:docs -> PASS Perturbing tokens.css makes --check exit 1 with "stale: web/app/tokens.css". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdbuqwHAXSDcikPiS6L6Qw * design tokens: the generator targets the web app only The desktop and Android targets were rendered and rejected on sight; the script now writes nothing outside this repository and has no --apps-root. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdbuqwHAXSDcikPiS6L6Qw --------- Co-authored-by: CodeWhale Bot <bot@codewhale.net> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> | 6 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 天前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 2 天前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 17 天前 | ||
| 24 天前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 14 天前 | ||
| 20 天前 | ||
| 2 天前 | ||
| 2 天前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 6 天前 |