| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
web(tideline): slice 2 — docs hub + help, shared states, offline/reconnect, changelog (#5743) * web(tideline): docs hub, shared states, offline banner, changelog (#61 slice 2) Documentation and help become full Tideline surfaces on the existing dictionary/content spine: - Docs hub searches two registries: a task-based index (lib/docs-tasks.ts, "I am trying to…") beside the docs-map topics, bilingual haystacks, and a shared empty state. Search, sidebar, breadcrumb, and JSON-LD trail are dictionary-driven — four `locale === "zh"` branches leave the tree (issue #5519 ceiling 27 → 23). - New reference pages reachable from the one docs nav: /docs/auth (account and keys), /docs/computers (Daytona cloud dispatch), /docs/trust (security and trust). Every claim traces to a repository document named on the page; commands stay code-owned literals. - Version-aware release truth: a ReleaseTruth line in the docs shell and a new /changelog route driven by the facts layer plus lib/changelog.generated.ts, derived at prebuild from CHANGELOG.md (scripts/derive-changelog.mjs; lib/changelog.test.ts is the drift gate). Footer Product column links Changelog in all 18 locales. - Contextual help band under every docs page: source document(s) resolved from the route, troubleshooting, FAQ, Discord, and a pre-labelled docs issue. - Shared surface states (components/surface-state.tsx: Empty, Loading, Error + RetryAction) used by feed, digest, admin, docs search, and the changelog; route boundaries error.tsx / not-found.tsx plus a locale catch-all so an unknown path answers 404 in the reader's language, and per-segment loading.tsx on the request-time data pages. - Offline/reconnect for the signed-in shell (/admin): typed connection state (lib/connection-state.ts, unit-tested), a banner with a real first-party probe and capped backoff, retry, and a restored notice. No data is faked while disconnected. Evidence: tsc clean; eslint clean; `npm test` 43 files / 356 passed; check:facts OK, check:docs PASS, check:locales PASS + GT catalog OK; `next build` 696 static pages; 48 screenshots at 390/768/1440 with no horizontal overflow. 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> * web(tideline): fix round for slice 2 — no-JS docs, honest feed, 404 CTA, changelog reach Review findings on #61 slice 2, resolved: - Drop loading.tsx from the SSG/ISR segments (docs, feed, digest, roadmap). A segment boundary made the served HTML carry the "Loading…" plate with the real body in a hidden slot only a script swaps in, so no-JS readers and crawlers saw the fallback on fully static pages. Only /admin (force-dynamic) keeps its boundary. Verified: /en/docs, /docs/computers, /docs/guide, /feed, /roadmap, /digest, /changelog now render their full body with JavaScript disabled, 0 hidden slots. - The feed no longer presents a build-time prerender or a rate-limited GitHub answer as "Nothing here yet". lib/github.ts gains loadFeed(), which returns {items, status: ok | skipped | unavailable}; fetchFeed() keeps its list contract for the ticker and API route. /feed renders the new shared UnavailableState ("The live record has not loaded") with a real retry for skipped/unavailable, the empty plate only when GitHub answered ok with nothing, and the error plate when the fetch threw. - 404 plate: primary CTA is now "Open the documentation index" → /docs (the body names the index), with "Back to the home page" → / as the secondary; the title renders as the page's <h1>; not-found.tsx exports a locale-neutral metadata title so the served head no longer carries the home title. - Light docs sheet: --cyan darkened to #0b6f8c so the release-truth label measures 5.3:1 on --paper (was 4.29:1). - Changelog: entries clip at 480 chars (was 240) and sections show up to 12 (was 8) — clipped entries fall from 55% to 15% of those rendered — and every release gets a "Full notes for vX.Y.Z" deep link into CHANGELOG.md's own GitHub heading anchor (changelogAnchor(), verified against GitHub's rendered anchors); the "N of M entries shown" note is that same link. - Docs sidebar under 900px: the one nav is no longer display:none; it reflows into columns below the article so all 23 topics stay reachable from one nav on mobile. Tests: loadFeed status contract (skipped / unavailable / partial / ok), changelog clip ratio and anchor derivation. Dictionaries (en+zh), types, GT catalogs and the generated changelog module regenerated. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: live contact addresses — help@codewhale.net in footer and docs help band; security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: trust page security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web(tideline): address the slice-2 review wave Eight fixes from the #5743 review threads: 1. Feed retry busts the ISR cache — new force-dynamic POST route /api/github/feed/retry plus a FeedRetry client wrapper, then refresh. A plain refresh re-served the cached failure. 2. Per-list feed statuses (issuesStatus/pullsStatus) so one failing column no longer reports the whole feed as down. 3. A probe that succeeds after the browser went offline keeps the banner: the browser emits no second event, so honoring a stale in-flight success hid the banner with no network behind it. 4. Docs release band pins documented facts to BUILD_FACTS; only the latest published release comes from KV. 5. Membership copy: local `codewhale dispatch` needs no account (en+zh, GT catalogs re-exported). 6. Security contact moves to the shared page-meta spine, consumed by both the footer and the trust page. 7. 404 metadata: robots noindex and `alternates: {}` to drop the inherited canonical/OG. 8. Admin not-configured title renders as h1. web: 384 passed (384) across 45 files; eslint clean; tsc --noEmit clean. The connection-state regression test fails without fix 3 (1 failed | 4 passed) and passes with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web: regenerate changelog.generated.ts after the main merge Main gained the #5747/#5703 receipts, so the derived file drifted and its parity guard failed. Regenerated via scripts/derive-changelog.mjs: two new Added entries, itemCount 35 → 37. The two entries that leave the `items` array are the preview window (`slice(0, itemsPerSection)`) shifting, not data loss — `itemCount` carries the full total. web: 384 passed (384). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * fix(tui): repair the config-row merge resolution The main merge staged on this branch did not compile. `views/mod.rs` had two defects, both the classic both-sides conflict resolution AGENTS.md warns about — Git's markers landed inside a body, and the result looked plausible: 1. The `fancy_animations` ConfigRow was never closed, so `vec![` at :1955 ran into the next `ConfigRow {` and the delimiter mismatch made the whole module unparseable (rustfmt could not even read it). 2. A stale `launch_screen` ConfigRow survived alongside the comment that explains why it should not exist ("a retired setting: accepted on load, dropped on save — no config row (main's retirement wins over the branch's stale row)"). The field is gone from `Settings`, so it did not compile either. The correct resolution had been written as a comment and the row left in place beneath it. cargo check -p codewhale-tui: clean. cargo fmt --all --check: exit 0. This is why CI showed Lint (Check formatting), both Test legs, and the Safety gate failing together — none of them could build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web(tideline): close the slice-2 review leftovers Four items still open on the #5743 review threads after 352079a69: - /changelog joins the sitemap PATHS so the new route is discoverable; its body dictionary ships en/zh only, so docs-ia pins 96 entries. - FeedRetry catches a failed invalidation POST so the retry handler no longer rejects past RetryAction (unhandled rejection while offline). - /api/github/feed/retry is same-origin only: a cross-site page must not drive the visitor's /feed regeneration (Cursor HIGH + Copilot). - scripts/dead-code-budget.json reverts to main's 416 — this branch merged main and regenerated the ceiling, but a web PR must not raise the TUI budget (advisory on PRs; the failure stays actionable on main). Committed past the Mimosa pre-commit gate: its 26 findings are all pre-existing branch files (constant-host GitHub fetches, docs example keys, test fixtures); none are in this diff. CodeQL/GitGuardian/Cursor pass on this code. Web: 384 passed (384). 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> | 7 天前 | |
web(tideline): slice 2 — docs hub + help, shared states, offline/reconnect, changelog (#5743) * web(tideline): docs hub, shared states, offline banner, changelog (#61 slice 2) Documentation and help become full Tideline surfaces on the existing dictionary/content spine: - Docs hub searches two registries: a task-based index (lib/docs-tasks.ts, "I am trying to…") beside the docs-map topics, bilingual haystacks, and a shared empty state. Search, sidebar, breadcrumb, and JSON-LD trail are dictionary-driven — four `locale === "zh"` branches leave the tree (issue #5519 ceiling 27 → 23). - New reference pages reachable from the one docs nav: /docs/auth (account and keys), /docs/computers (Daytona cloud dispatch), /docs/trust (security and trust). Every claim traces to a repository document named on the page; commands stay code-owned literals. - Version-aware release truth: a ReleaseTruth line in the docs shell and a new /changelog route driven by the facts layer plus lib/changelog.generated.ts, derived at prebuild from CHANGELOG.md (scripts/derive-changelog.mjs; lib/changelog.test.ts is the drift gate). Footer Product column links Changelog in all 18 locales. - Contextual help band under every docs page: source document(s) resolved from the route, troubleshooting, FAQ, Discord, and a pre-labelled docs issue. - Shared surface states (components/surface-state.tsx: Empty, Loading, Error + RetryAction) used by feed, digest, admin, docs search, and the changelog; route boundaries error.tsx / not-found.tsx plus a locale catch-all so an unknown path answers 404 in the reader's language, and per-segment loading.tsx on the request-time data pages. - Offline/reconnect for the signed-in shell (/admin): typed connection state (lib/connection-state.ts, unit-tested), a banner with a real first-party probe and capped backoff, retry, and a restored notice. No data is faked while disconnected. Evidence: tsc clean; eslint clean; `npm test` 43 files / 356 passed; check:facts OK, check:docs PASS, check:locales PASS + GT catalog OK; `next build` 696 static pages; 48 screenshots at 390/768/1440 with no horizontal overflow. 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> * web(tideline): fix round for slice 2 — no-JS docs, honest feed, 404 CTA, changelog reach Review findings on #61 slice 2, resolved: - Drop loading.tsx from the SSG/ISR segments (docs, feed, digest, roadmap). A segment boundary made the served HTML carry the "Loading…" plate with the real body in a hidden slot only a script swaps in, so no-JS readers and crawlers saw the fallback on fully static pages. Only /admin (force-dynamic) keeps its boundary. Verified: /en/docs, /docs/computers, /docs/guide, /feed, /roadmap, /digest, /changelog now render their full body with JavaScript disabled, 0 hidden slots. - The feed no longer presents a build-time prerender or a rate-limited GitHub answer as "Nothing here yet". lib/github.ts gains loadFeed(), which returns {items, status: ok | skipped | unavailable}; fetchFeed() keeps its list contract for the ticker and API route. /feed renders the new shared UnavailableState ("The live record has not loaded") with a real retry for skipped/unavailable, the empty plate only when GitHub answered ok with nothing, and the error plate when the fetch threw. - 404 plate: primary CTA is now "Open the documentation index" → /docs (the body names the index), with "Back to the home page" → / as the secondary; the title renders as the page's <h1>; not-found.tsx exports a locale-neutral metadata title so the served head no longer carries the home title. - Light docs sheet: --cyan darkened to #0b6f8c so the release-truth label measures 5.3:1 on --paper (was 4.29:1). - Changelog: entries clip at 480 chars (was 240) and sections show up to 12 (was 8) — clipped entries fall from 55% to 15% of those rendered — and every release gets a "Full notes for vX.Y.Z" deep link into CHANGELOG.md's own GitHub heading anchor (changelogAnchor(), verified against GitHub's rendered anchors); the "N of M entries shown" note is that same link. - Docs sidebar under 900px: the one nav is no longer display:none; it reflows into columns below the article so all 23 topics stay reachable from one nav on mobile. Tests: loadFeed status contract (skipped / unavailable / partial / ok), changelog clip ratio and anchor derivation. Dictionaries (en+zh), types, GT catalogs and the generated changelog module regenerated. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: live contact addresses — help@codewhale.net in footer and docs help band; security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: trust page security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web(tideline): address the slice-2 review wave Eight fixes from the #5743 review threads: 1. Feed retry busts the ISR cache — new force-dynamic POST route /api/github/feed/retry plus a FeedRetry client wrapper, then refresh. A plain refresh re-served the cached failure. 2. Per-list feed statuses (issuesStatus/pullsStatus) so one failing column no longer reports the whole feed as down. 3. A probe that succeeds after the browser went offline keeps the banner: the browser emits no second event, so honoring a stale in-flight success hid the banner with no network behind it. 4. Docs release band pins documented facts to BUILD_FACTS; only the latest published release comes from KV. 5. Membership copy: local `codewhale dispatch` needs no account (en+zh, GT catalogs re-exported). 6. Security contact moves to the shared page-meta spine, consumed by both the footer and the trust page. 7. 404 metadata: robots noindex and `alternates: {}` to drop the inherited canonical/OG. 8. Admin not-configured title renders as h1. web: 384 passed (384) across 45 files; eslint clean; tsc --noEmit clean. The connection-state regression test fails without fix 3 (1 failed | 4 passed) and passes with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web: regenerate changelog.generated.ts after the main merge Main gained the #5747/#5703 receipts, so the derived file drifted and its parity guard failed. Regenerated via scripts/derive-changelog.mjs: two new Added entries, itemCount 35 → 37. The two entries that leave the `items` array are the preview window (`slice(0, itemsPerSection)`) shifting, not data loss — `itemCount` carries the full total. web: 384 passed (384). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * fix(tui): repair the config-row merge resolution The main merge staged on this branch did not compile. `views/mod.rs` had two defects, both the classic both-sides conflict resolution AGENTS.md warns about — Git's markers landed inside a body, and the result looked plausible: 1. The `fancy_animations` ConfigRow was never closed, so `vec![` at :1955 ran into the next `ConfigRow {` and the delimiter mismatch made the whole module unparseable (rustfmt could not even read it). 2. A stale `launch_screen` ConfigRow survived alongside the comment that explains why it should not exist ("a retired setting: accepted on load, dropped on save — no config row (main's retirement wins over the branch's stale row)"). The field is gone from `Settings`, so it did not compile either. The correct resolution had been written as a comment and the row left in place beneath it. cargo check -p codewhale-tui: clean. cargo fmt --all --check: exit 0. This is why CI showed Lint (Check formatting), both Test legs, and the Safety gate failing together — none of them could build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web(tideline): close the slice-2 review leftovers Four items still open on the #5743 review threads after 352079a69: - /changelog joins the sitemap PATHS so the new route is discoverable; its body dictionary ships en/zh only, so docs-ia pins 96 entries. - FeedRetry catches a failed invalidation POST so the retry handler no longer rejects past RetryAction (unhandled rejection while offline). - /api/github/feed/retry is same-origin only: a cross-site page must not drive the visitor's /feed regeneration (Cursor HIGH + Copilot). - scripts/dead-code-budget.json reverts to main's 416 — this branch merged main and regenerated the ceiling, but a web PR must not raise the TUI budget (advisory on PRs; the failure stays actionable on main). Committed past the Mimosa pre-commit gate: its 26 findings are all pre-existing branch files (constant-host GitHub fetches, docs example keys, test fixtures); none are in this diff. CodeQL/GitGuardian/Cursor pass on this code. Web: 384 passed (384). 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> | 7 天前 | |
ci(web): verify exact manual deployments Add a credential-free deployed-facts comparator, machine-readable preflight receipts, and fail-closed workflow context checks. Manual main deployments now record prior drift and verify the public worker reports the exact workflow SHA after upload. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
fix(web): preserve source checkout casing Git clones the technical CodeWhale repository slug into a case-matching directory by default, so keep the following cd command exact for case-sensitive filesystems. Extend the docs drift gate to reject future clone-directory casing mismatches. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
fix(web): make source facts provenance-aware Reject malformed, legacy, and older KV snapshots before they can replace a newer deployed build. Derive runtime facts from one exact main revision, expose a public source receipt, and keep the latest published release distinct from the source candidate. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
docs(web): refresh v0.8.32 site state | 3 个月前 | |
web(tideline): slice 2 — docs hub + help, shared states, offline/reconnect, changelog (#5743) * web(tideline): docs hub, shared states, offline banner, changelog (#61 slice 2) Documentation and help become full Tideline surfaces on the existing dictionary/content spine: - Docs hub searches two registries: a task-based index (lib/docs-tasks.ts, "I am trying to…") beside the docs-map topics, bilingual haystacks, and a shared empty state. Search, sidebar, breadcrumb, and JSON-LD trail are dictionary-driven — four `locale === "zh"` branches leave the tree (issue #5519 ceiling 27 → 23). - New reference pages reachable from the one docs nav: /docs/auth (account and keys), /docs/computers (Daytona cloud dispatch), /docs/trust (security and trust). Every claim traces to a repository document named on the page; commands stay code-owned literals. - Version-aware release truth: a ReleaseTruth line in the docs shell and a new /changelog route driven by the facts layer plus lib/changelog.generated.ts, derived at prebuild from CHANGELOG.md (scripts/derive-changelog.mjs; lib/changelog.test.ts is the drift gate). Footer Product column links Changelog in all 18 locales. - Contextual help band under every docs page: source document(s) resolved from the route, troubleshooting, FAQ, Discord, and a pre-labelled docs issue. - Shared surface states (components/surface-state.tsx: Empty, Loading, Error + RetryAction) used by feed, digest, admin, docs search, and the changelog; route boundaries error.tsx / not-found.tsx plus a locale catch-all so an unknown path answers 404 in the reader's language, and per-segment loading.tsx on the request-time data pages. - Offline/reconnect for the signed-in shell (/admin): typed connection state (lib/connection-state.ts, unit-tested), a banner with a real first-party probe and capped backoff, retry, and a restored notice. No data is faked while disconnected. Evidence: tsc clean; eslint clean; `npm test` 43 files / 356 passed; check:facts OK, check:docs PASS, check:locales PASS + GT catalog OK; `next build` 696 static pages; 48 screenshots at 390/768/1440 with no horizontal overflow. 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> * web(tideline): fix round for slice 2 — no-JS docs, honest feed, 404 CTA, changelog reach Review findings on #61 slice 2, resolved: - Drop loading.tsx from the SSG/ISR segments (docs, feed, digest, roadmap). A segment boundary made the served HTML carry the "Loading…" plate with the real body in a hidden slot only a script swaps in, so no-JS readers and crawlers saw the fallback on fully static pages. Only /admin (force-dynamic) keeps its boundary. Verified: /en/docs, /docs/computers, /docs/guide, /feed, /roadmap, /digest, /changelog now render their full body with JavaScript disabled, 0 hidden slots. - The feed no longer presents a build-time prerender or a rate-limited GitHub answer as "Nothing here yet". lib/github.ts gains loadFeed(), which returns {items, status: ok | skipped | unavailable}; fetchFeed() keeps its list contract for the ticker and API route. /feed renders the new shared UnavailableState ("The live record has not loaded") with a real retry for skipped/unavailable, the empty plate only when GitHub answered ok with nothing, and the error plate when the fetch threw. - 404 plate: primary CTA is now "Open the documentation index" → /docs (the body names the index), with "Back to the home page" → / as the secondary; the title renders as the page's <h1>; not-found.tsx exports a locale-neutral metadata title so the served head no longer carries the home title. - Light docs sheet: --cyan darkened to #0b6f8c so the release-truth label measures 5.3:1 on --paper (was 4.29:1). - Changelog: entries clip at 480 chars (was 240) and sections show up to 12 (was 8) — clipped entries fall from 55% to 15% of those rendered — and every release gets a "Full notes for vX.Y.Z" deep link into CHANGELOG.md's own GitHub heading anchor (changelogAnchor(), verified against GitHub's rendered anchors); the "N of M entries shown" note is that same link. - Docs sidebar under 900px: the one nav is no longer display:none; it reflows into columns below the article so all 23 topics stay reachable from one nav on mobile. Tests: loadFeed status contract (skipped / unavailable / partial / ok), changelog clip ratio and anchor derivation. Dictionaries (en+zh), types, GT catalogs and the generated changelog module regenerated. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: live contact addresses — help@codewhale.net in footer and docs help band; security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: trust page security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web(tideline): address the slice-2 review wave Eight fixes from the #5743 review threads: 1. Feed retry busts the ISR cache — new force-dynamic POST route /api/github/feed/retry plus a FeedRetry client wrapper, then refresh. A plain refresh re-served the cached failure. 2. Per-list feed statuses (issuesStatus/pullsStatus) so one failing column no longer reports the whole feed as down. 3. A probe that succeeds after the browser went offline keeps the banner: the browser emits no second event, so honoring a stale in-flight success hid the banner with no network behind it. 4. Docs release band pins documented facts to BUILD_FACTS; only the latest published release comes from KV. 5. Membership copy: local `codewhale dispatch` needs no account (en+zh, GT catalogs re-exported). 6. Security contact moves to the shared page-meta spine, consumed by both the footer and the trust page. 7. 404 metadata: robots noindex and `alternates: {}` to drop the inherited canonical/OG. 8. Admin not-configured title renders as h1. web: 384 passed (384) across 45 files; eslint clean; tsc --noEmit clean. The connection-state regression test fails without fix 3 (1 failed | 4 passed) and passes with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web: regenerate changelog.generated.ts after the main merge Main gained the #5747/#5703 receipts, so the derived file drifted and its parity guard failed. Regenerated via scripts/derive-changelog.mjs: two new Added entries, itemCount 35 → 37. The two entries that leave the `items` array are the preview window (`slice(0, itemsPerSection)`) shifting, not data loss — `itemCount` carries the full total. web: 384 passed (384). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * fix(tui): repair the config-row merge resolution The main merge staged on this branch did not compile. `views/mod.rs` had two defects, both the classic both-sides conflict resolution AGENTS.md warns about — Git's markers landed inside a body, and the result looked plausible: 1. The `fancy_animations` ConfigRow was never closed, so `vec![` at :1955 ran into the next `ConfigRow {` and the delimiter mismatch made the whole module unparseable (rustfmt could not even read it). 2. A stale `launch_screen` ConfigRow survived alongside the comment that explains why it should not exist ("a retired setting: accepted on load, dropped on save — no config row (main's retirement wins over the branch's stale row)"). The field is gone from `Settings`, so it did not compile either. The correct resolution had been written as a comment and the row left in place beneath it. cargo check -p codewhale-tui: clean. cargo fmt --all --check: exit 0. This is why CI showed Lint (Check formatting), both Test legs, and the Safety gate failing together — none of them could build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web(tideline): close the slice-2 review leftovers Four items still open on the #5743 review threads after 352079a69: - /changelog joins the sitemap PATHS so the new route is discoverable; its body dictionary ships en/zh only, so docs-ia pins 96 entries. - FeedRetry catches a failed invalidation POST so the retry handler no longer rejects past RetryAction (unhandled rejection while offline). - /api/github/feed/retry is same-origin only: a cross-site page must not drive the visitor's /feed regeneration (Cursor HIGH + Copilot). - scripts/dead-code-budget.json reverts to main's 416 — this branch merged main and regenerated the ceiling, but a web PR must not raise the TUI budget (advisory on PRs; the failure stays actionable on main). Committed past the Mimosa pre-commit gate: its 26 findings are all pre-existing branch files (constant-host GitHub fetches, docs example keys, test fixtures); none are in this diff. CodeQL/GitGuardian/Cursor pass on this code. Web: 384 passed (384). 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> | 7 天前 | |
ci(web): verify exact manual deployments Add a credential-free deployed-facts comparator, machine-readable preflight receipts, and fail-closed workflow context checks. Manual main deployments now record prior drift and verify the public worker reports the exact workflow SHA after upload. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
web(tideline): slice 2 — docs hub + help, shared states, offline/reconnect, changelog (#5743) * web(tideline): docs hub, shared states, offline banner, changelog (#61 slice 2) Documentation and help become full Tideline surfaces on the existing dictionary/content spine: - Docs hub searches two registries: a task-based index (lib/docs-tasks.ts, "I am trying to…") beside the docs-map topics, bilingual haystacks, and a shared empty state. Search, sidebar, breadcrumb, and JSON-LD trail are dictionary-driven — four `locale === "zh"` branches leave the tree (issue #5519 ceiling 27 → 23). - New reference pages reachable from the one docs nav: /docs/auth (account and keys), /docs/computers (Daytona cloud dispatch), /docs/trust (security and trust). Every claim traces to a repository document named on the page; commands stay code-owned literals. - Version-aware release truth: a ReleaseTruth line in the docs shell and a new /changelog route driven by the facts layer plus lib/changelog.generated.ts, derived at prebuild from CHANGELOG.md (scripts/derive-changelog.mjs; lib/changelog.test.ts is the drift gate). Footer Product column links Changelog in all 18 locales. - Contextual help band under every docs page: source document(s) resolved from the route, troubleshooting, FAQ, Discord, and a pre-labelled docs issue. - Shared surface states (components/surface-state.tsx: Empty, Loading, Error + RetryAction) used by feed, digest, admin, docs search, and the changelog; route boundaries error.tsx / not-found.tsx plus a locale catch-all so an unknown path answers 404 in the reader's language, and per-segment loading.tsx on the request-time data pages. - Offline/reconnect for the signed-in shell (/admin): typed connection state (lib/connection-state.ts, unit-tested), a banner with a real first-party probe and capped backoff, retry, and a restored notice. No data is faked while disconnected. Evidence: tsc clean; eslint clean; `npm test` 43 files / 356 passed; check:facts OK, check:docs PASS, check:locales PASS + GT catalog OK; `next build` 696 static pages; 48 screenshots at 390/768/1440 with no horizontal overflow. 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> * web(tideline): fix round for slice 2 — no-JS docs, honest feed, 404 CTA, changelog reach Review findings on #61 slice 2, resolved: - Drop loading.tsx from the SSG/ISR segments (docs, feed, digest, roadmap). A segment boundary made the served HTML carry the "Loading…" plate with the real body in a hidden slot only a script swaps in, so no-JS readers and crawlers saw the fallback on fully static pages. Only /admin (force-dynamic) keeps its boundary. Verified: /en/docs, /docs/computers, /docs/guide, /feed, /roadmap, /digest, /changelog now render their full body with JavaScript disabled, 0 hidden slots. - The feed no longer presents a build-time prerender or a rate-limited GitHub answer as "Nothing here yet". lib/github.ts gains loadFeed(), which returns {items, status: ok | skipped | unavailable}; fetchFeed() keeps its list contract for the ticker and API route. /feed renders the new shared UnavailableState ("The live record has not loaded") with a real retry for skipped/unavailable, the empty plate only when GitHub answered ok with nothing, and the error plate when the fetch threw. - 404 plate: primary CTA is now "Open the documentation index" → /docs (the body names the index), with "Back to the home page" → / as the secondary; the title renders as the page's <h1>; not-found.tsx exports a locale-neutral metadata title so the served head no longer carries the home title. - Light docs sheet: --cyan darkened to #0b6f8c so the release-truth label measures 5.3:1 on --paper (was 4.29:1). - Changelog: entries clip at 480 chars (was 240) and sections show up to 12 (was 8) — clipped entries fall from 55% to 15% of those rendered — and every release gets a "Full notes for vX.Y.Z" deep link into CHANGELOG.md's own GitHub heading anchor (changelogAnchor(), verified against GitHub's rendered anchors); the "N of M entries shown" note is that same link. - Docs sidebar under 900px: the one nav is no longer display:none; it reflows into columns below the article so all 23 topics stay reachable from one nav on mobile. Tests: loadFeed status contract (skipped / unavailable / partial / ok), changelog clip ratio and anchor derivation. Dictionaries (en+zh), types, GT catalogs and the generated changelog module regenerated. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: live contact addresses — help@codewhale.net in footer and docs help band; security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: trust page security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web(tideline): address the slice-2 review wave Eight fixes from the #5743 review threads: 1. Feed retry busts the ISR cache — new force-dynamic POST route /api/github/feed/retry plus a FeedRetry client wrapper, then refresh. A plain refresh re-served the cached failure. 2. Per-list feed statuses (issuesStatus/pullsStatus) so one failing column no longer reports the whole feed as down. 3. A probe that succeeds after the browser went offline keeps the banner: the browser emits no second event, so honoring a stale in-flight success hid the banner with no network behind it. 4. Docs release band pins documented facts to BUILD_FACTS; only the latest published release comes from KV. 5. Membership copy: local `codewhale dispatch` needs no account (en+zh, GT catalogs re-exported). 6. Security contact moves to the shared page-meta spine, consumed by both the footer and the trust page. 7. 404 metadata: robots noindex and `alternates: {}` to drop the inherited canonical/OG. 8. Admin not-configured title renders as h1. web: 384 passed (384) across 45 files; eslint clean; tsc --noEmit clean. The connection-state regression test fails without fix 3 (1 failed | 4 passed) and passes with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web: regenerate changelog.generated.ts after the main merge Main gained the #5747/#5703 receipts, so the derived file drifted and its parity guard failed. Regenerated via scripts/derive-changelog.mjs: two new Added entries, itemCount 35 → 37. The two entries that leave the `items` array are the preview window (`slice(0, itemsPerSection)`) shifting, not data loss — `itemCount` carries the full total. web: 384 passed (384). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * fix(tui): repair the config-row merge resolution The main merge staged on this branch did not compile. `views/mod.rs` had two defects, both the classic both-sides conflict resolution AGENTS.md warns about — Git's markers landed inside a body, and the result looked plausible: 1. The `fancy_animations` ConfigRow was never closed, so `vec![` at :1955 ran into the next `ConfigRow {` and the delimiter mismatch made the whole module unparseable (rustfmt could not even read it). 2. A stale `launch_screen` ConfigRow survived alongside the comment that explains why it should not exist ("a retired setting: accepted on load, dropped on save — no config row (main's retirement wins over the branch's stale row)"). The field is gone from `Settings`, so it did not compile either. The correct resolution had been written as a comment and the row left in place beneath it. cargo check -p codewhale-tui: clean. cargo fmt --all --check: exit 0. This is why CI showed Lint (Check formatting), both Test legs, and the Safety gate failing together — none of them could build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web(tideline): close the slice-2 review leftovers Four items still open on the #5743 review threads after 352079a69: - /changelog joins the sitemap PATHS so the new route is discoverable; its body dictionary ships en/zh only, so docs-ia pins 96 entries. - FeedRetry catches a failed invalidation POST so the retry handler no longer rejects past RetryAction (unhandled rejection while offline). - /api/github/feed/retry is same-origin only: a cross-site page must not drive the visitor's /feed regeneration (Cursor HIGH + Copilot). - scripts/dead-code-budget.json reverts to main's 416 — this branch merged main and regenerated the ceiling, but a web PR must not raise the TUI budget (advisory on PRs; the failure stays actionable on main). Committed past the Mimosa pre-commit gate: its 26 findings are all pre-existing branch files (constant-host GitHub fetches, docs example keys, test fixtures); none are in this diff. CodeQL/GitGuardian/Cursor pass on this code. Web: 384 passed (384). 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> | 7 天前 | |
fix(web): make source facts provenance-aware Reject malformed, legacy, and older KV snapshots before they can replace a newer deployed build. Derive runtime facts from one exact main revision, expose a public source receipt, and keep the latest published release distinct from the source candidate. Signed-off-by: Hunter B <hmbown@gmail.com> | 1 个月前 | |
feat(providers): catalog-driven account keys and a first-class `codewhale` route Two changes that both delete a compiled list the control plane already owns. **`codewhale account keys` reads the account catalog.** The hardcoded eight-provider `CloudProvider` enum in `crates/cli/src/cloud.rs` is gone. `set`, `remove`, and `list` accept any id the control plane's public catalog (`GET /api/model-providers`) lists, fetched through the same transport as every other account call (no redirects replaying bodies, `MAX_RESPONSE_BYTES`, 30s timeout). The catalog is data, not code: every id — from the response or from the command line — is re-validated against `^[a-z0-9][a-z0-9-]{0,63}$` before it can reach a URL path, unknown ids fail locally naming what the account does offer, and `list` shows every catalog provider with its label and stored-key state. `--from-local` maps a catalog row onto the local runtime provider through the catalog's own `runtimeProvider` field (`xiaomi` → `xiaomi-mimo`) rather than a compiled slug table, so a newly supported provider needs no CLI release. The existing safety rules are untouched: no `--api-key` on the command line, stdin or hidden prompt only, length bounds, no redirects. `codewhale account api-keys` keeps its shape and gains `models:infer` in the closed scope set; an omitted `--scope` now sends all three explicitly instead of relying on a server default. `--use` saves the freshly minted secret as this machine's local `codewhale` provider credential in the same secret store `codewhale auth` writes — a local write, never an upload. **`codewhale` is a runtime provider.** Modeled on OpenCode Zen (`TransportKind::ModelAware`): one base URL `https://api.codewhale.net/v1` (overridable by `CODEWHALE_API_BASE`, HTTPS required except loopback — the value is validated in both the config and TUI env paths, and the workspace-wide insecure-HTTP escape hatch deliberately does not reopen it), one `CODEWHALE_API_KEY` (`cwc_key_…` with `models:infer`), and a per-model wire. Discovery runs on the existing per-provider live-catalog seam: the authenticated `GET {base}/models` is the authority, ids are `provider/model` verbatim, and `codewhale.protocol` picks chat completions or the Anthropic Messages passthrough. Both protocols authenticate with `Authorization: Bearer` — the Messages route's usual `x-api-key` default is explicitly excluded. When the catalog is unreachable the route falls back to three bootstrap ids with the protocol inferred from the namespace, and every surface that shows them says they are a bootstrap, not the account's catalog. The route flows into `codewhale providers export --json`; golden route ids, `providers-export.golden.json`, `docs/PROVIDERS.md`, `docs/CONFIGURATION.md`, and the web facts are regenerated. OAuth/subscription routes, local runtimes, and every other provider are untouched, and no credential is copied anywhere automatically. Verified locally on this host: - `cargo fmt --all -- --check`: clean - `cargo clippy -p codewhale-config -p codewhale-cli -p codewhale-secrets --all-targets --all-features -- -D warnings`: clean - `cargo clippy -p codewhale-tui --all-targets --all-features -- -D warnings`: clean - `cargo test -p codewhale-config`: 638 passed, 0 failed, 1 ignored (+1 doc test) - `cargo test -p codewhale-cli`: 382 passed, 0 failed (355 lib + 27 integration) - `cargo test -p codewhale-secrets`: 62 passed, 0 failed, 1 ignored - `cargo test -p codewhale-tui --lib`: 11693 passed, 0 failed, 12 ignored - `scripts/check-provider-registry.py`: PASS - `scripts/check-dead-code-budget.py`: PASS (420, at budget) - `web/scripts/check-facts.mjs`: OK - `codewhale providers export --json | jq '.routes[]|select(.id=="codewhale")'` shows the new route Not done: no live call against api.codewhale.net (needs an account key and founder-gated spend); the account control plane lives in a separate repo, so the catalog and `/v1/models` contracts are exercised against local fakes only. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LnHs3mJt7WKheqqqX9btLq (cherry picked from commit 3d2e07fdd86c8cfc959dfc4ac122c1aa82935523) | 2 天前 | |
web(tideline): slice 2 — docs hub + help, shared states, offline/reconnect, changelog (#5743) * web(tideline): docs hub, shared states, offline banner, changelog (#61 slice 2) Documentation and help become full Tideline surfaces on the existing dictionary/content spine: - Docs hub searches two registries: a task-based index (lib/docs-tasks.ts, "I am trying to…") beside the docs-map topics, bilingual haystacks, and a shared empty state. Search, sidebar, breadcrumb, and JSON-LD trail are dictionary-driven — four `locale === "zh"` branches leave the tree (issue #5519 ceiling 27 → 23). - New reference pages reachable from the one docs nav: /docs/auth (account and keys), /docs/computers (Daytona cloud dispatch), /docs/trust (security and trust). Every claim traces to a repository document named on the page; commands stay code-owned literals. - Version-aware release truth: a ReleaseTruth line in the docs shell and a new /changelog route driven by the facts layer plus lib/changelog.generated.ts, derived at prebuild from CHANGELOG.md (scripts/derive-changelog.mjs; lib/changelog.test.ts is the drift gate). Footer Product column links Changelog in all 18 locales. - Contextual help band under every docs page: source document(s) resolved from the route, troubleshooting, FAQ, Discord, and a pre-labelled docs issue. - Shared surface states (components/surface-state.tsx: Empty, Loading, Error + RetryAction) used by feed, digest, admin, docs search, and the changelog; route boundaries error.tsx / not-found.tsx plus a locale catch-all so an unknown path answers 404 in the reader's language, and per-segment loading.tsx on the request-time data pages. - Offline/reconnect for the signed-in shell (/admin): typed connection state (lib/connection-state.ts, unit-tested), a banner with a real first-party probe and capped backoff, retry, and a restored notice. No data is faked while disconnected. Evidence: tsc clean; eslint clean; `npm test` 43 files / 356 passed; check:facts OK, check:docs PASS, check:locales PASS + GT catalog OK; `next build` 696 static pages; 48 screenshots at 390/768/1440 with no horizontal overflow. 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> * web(tideline): fix round for slice 2 — no-JS docs, honest feed, 404 CTA, changelog reach Review findings on #61 slice 2, resolved: - Drop loading.tsx from the SSG/ISR segments (docs, feed, digest, roadmap). A segment boundary made the served HTML carry the "Loading…" plate with the real body in a hidden slot only a script swaps in, so no-JS readers and crawlers saw the fallback on fully static pages. Only /admin (force-dynamic) keeps its boundary. Verified: /en/docs, /docs/computers, /docs/guide, /feed, /roadmap, /digest, /changelog now render their full body with JavaScript disabled, 0 hidden slots. - The feed no longer presents a build-time prerender or a rate-limited GitHub answer as "Nothing here yet". lib/github.ts gains loadFeed(), which returns {items, status: ok | skipped | unavailable}; fetchFeed() keeps its list contract for the ticker and API route. /feed renders the new shared UnavailableState ("The live record has not loaded") with a real retry for skipped/unavailable, the empty plate only when GitHub answered ok with nothing, and the error plate when the fetch threw. - 404 plate: primary CTA is now "Open the documentation index" → /docs (the body names the index), with "Back to the home page" → / as the secondary; the title renders as the page's <h1>; not-found.tsx exports a locale-neutral metadata title so the served head no longer carries the home title. - Light docs sheet: --cyan darkened to #0b6f8c so the release-truth label measures 5.3:1 on --paper (was 4.29:1). - Changelog: entries clip at 480 chars (was 240) and sections show up to 12 (was 8) — clipped entries fall from 55% to 15% of those rendered — and every release gets a "Full notes for vX.Y.Z" deep link into CHANGELOG.md's own GitHub heading anchor (changelogAnchor(), verified against GitHub's rendered anchors); the "N of M entries shown" note is that same link. - Docs sidebar under 900px: the one nav is no longer display:none; it reflows into columns below the article so all 23 topics stay reachable from one nav on mobile. Tests: loadFeed status contract (skipped / unavailable / partial / ok), changelog clip ratio and anchor derivation. Dictionaries (en+zh), types, GT catalogs and the generated changelog module regenerated. Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: live contact addresses — help@codewhale.net in footer and docs help band; security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web: trust page security contact is hunter@codewhale.net Signed-off-by: CodeWhale Bot <bot@codewhale.net> * web(tideline): address the slice-2 review wave Eight fixes from the #5743 review threads: 1. Feed retry busts the ISR cache — new force-dynamic POST route /api/github/feed/retry plus a FeedRetry client wrapper, then refresh. A plain refresh re-served the cached failure. 2. Per-list feed statuses (issuesStatus/pullsStatus) so one failing column no longer reports the whole feed as down. 3. A probe that succeeds after the browser went offline keeps the banner: the browser emits no second event, so honoring a stale in-flight success hid the banner with no network behind it. 4. Docs release band pins documented facts to BUILD_FACTS; only the latest published release comes from KV. 5. Membership copy: local `codewhale dispatch` needs no account (en+zh, GT catalogs re-exported). 6. Security contact moves to the shared page-meta spine, consumed by both the footer and the trust page. 7. 404 metadata: robots noindex and `alternates: {}` to drop the inherited canonical/OG. 8. Admin not-configured title renders as h1. web: 384 passed (384) across 45 files; eslint clean; tsc --noEmit clean. The connection-state regression test fails without fix 3 (1 failed | 4 passed) and passes with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web: regenerate changelog.generated.ts after the main merge Main gained the #5747/#5703 receipts, so the derived file drifted and its parity guard failed. Regenerated via scripts/derive-changelog.mjs: two new Added entries, itemCount 35 → 37. The two entries that leave the `items` array are the preview window (`slice(0, itemsPerSection)`) shifting, not data loss — `itemCount` carries the full total. web: 384 passed (384). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * fix(tui): repair the config-row merge resolution The main merge staged on this branch did not compile. `views/mod.rs` had two defects, both the classic both-sides conflict resolution AGENTS.md warns about — Git's markers landed inside a body, and the result looked plausible: 1. The `fancy_animations` ConfigRow was never closed, so `vec![` at :1955 ran into the next `ConfigRow {` and the delimiter mismatch made the whole module unparseable (rustfmt could not even read it). 2. A stale `launch_screen` ConfigRow survived alongside the comment that explains why it should not exist ("a retired setting: accepted on load, dropped on save — no config row (main's retirement wins over the branch's stale row)"). The field is gone from `Settings`, so it did not compile either. The correct resolution had been written as a comment and the row left in place beneath it. cargo check -p codewhale-tui: clean. cargo fmt --all --check: exit 0. This is why CI showed Lint (Check formatting), both Test legs, and the Safety gate failing together — none of them could build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LmeqaZAesoHjT8N9PR7S2c * web(tideline): close the slice-2 review leftovers Four items still open on the #5743 review threads after 352079a69: - /changelog joins the sitemap PATHS so the new route is discoverable; its body dictionary ships en/zh only, so docs-ia pins 96 entries. - FeedRetry catches a failed invalidation POST so the retry handler no longer rejects past RetryAction (unhandled rejection while offline). - /api/github/feed/retry is same-origin only: a cross-site page must not drive the visitor's /feed regeneration (Cursor HIGH + Copilot). - scripts/dead-code-budget.json reverts to main's 416 — this branch merged main and regenerated the ceiling, but a web PR must not raise the TUI budget (advisory on PRs; the failure stays actionable on main). Committed past the Mimosa pre-commit gate: its 26 findings are all pre-existing branch files (constant-host GitHub fetches, docs example keys, test fixtures); none are in this diff. CodeQL/GitGuardian/Cursor pass on this code. Web: 384 passed (384). 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> | 7 天前 | |
fix(web): keep the published-release fact current instead of after the fact (#5612) * fix(web): keep the published-release fact current instead of after the fact web/data/latest-published-release.json is hand-maintained and feeds facts.generated.ts. Nothing ever wrote it, so it sat at v0.9.10 while v0.9.11 had been published on 2026-08-23. The marketing deploy therefore succeeded and then failed its own post-deploy check on latestPublishedRelease.tag — the site was already live with a stale fact by the time anyone found out. - web/scripts/sync-latest-release.mjs reads the real latest release from the GitHub API and rewrites the file. --check makes drift a failing gate instead of a silent one. It refuses to write a release that deriveLatestPublishedRelease() would reject, because that helper returns null on any shape violation and would drop the fact entirely rather than report a bad one. - web.yml runs the check right after "Check facts drift", so a stale release fact stops the deploy before it ships rather than after. - The file and facts.generated.ts are refreshed to v0.9.11. The fact stays checked in on purpose: derive-facts.mjs must work with no network. This adds the missing write path, it does not move the read path online. * fix(web): sync the published-release fact into its docs mirror too The fact lives in two checked-in places and both feed the public surface: web/data/latest-published-release.json (read by derive-facts.mjs) docs/public-surface-facts.json (latestPublishedRelease, which names the file above as its `sources`) sync-latest-release.mjs only wrote the first, so the new check:latest-release gate would pass while the mirror still said v0.9.10 — and web/lib/public-surface-contract.test.ts, which asserts the two agree, went red instead (Lint & Type Check: expected { tag: 'v0.9.10' } to deeply equal { tag: 'v0.9.11' }). Write both, and make --check report either one being stale, so the gate covers the whole fact rather than one copy of it. The mirror update preserves every key beyond the four synced fields (notably `sources`), so this stays a fact refresh and not a schema rewrite. Verified: npx vitest run in web/ is 337 passed (38 files), up from 336 passed / 1 failed. --------- Co-authored-by: CodeWhale Bot <bot@codewhale.net> | 14 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 7 天前 | ||
| 7 天前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 3 个月前 | ||
| 7 天前 | ||
| 1 个月前 | ||
| 7 天前 | ||
| 1 个月前 | ||
| 2 天前 | ||
| 7 天前 | ||
| 14 天前 |