diff --git a/.changeset/vscode-lazy-historical-tool-details.md b/.changeset/vscode-lazy-historical-tool-details.md index 24b147f45c..6776f852fc 100644 --- a/.changeset/vscode-lazy-historical-tool-details.md +++ b/.changeset/vscode-lazy-historical-tool-details.md @@ -2,4 +2,4 @@ "kilo-code": patch --- -Speed up Agent Manager switching for long sessions by lazily mounting collapsed historical tool details, sharing timeline hover infrastructure across activity bars, and omitting transcript metadata that the webview does not use. +Speed up Agent Manager switching for long sessions by lazily mounting collapsed historical tool details, sharing timeline hover infrastructure across activity bars, omitting transcript metadata that the webview does not use, and avoiding shimmer markup for inactive historical labels. diff --git a/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts b/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts index e3e4161fc0..df8d576e03 100644 --- a/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts +++ b/packages/kilo-vscode/src/kilo-provider/slim-metadata.ts @@ -12,7 +12,9 @@ * * This module strips fields the webview never (or rarely) needs while keeping * everything required to render transcript summaries, tool details and - * diagnostics. + * diagnostics. It transforms outgoing webview copies only: backend session + * storage remains the source of truth for continuation, caching, forks and + * exports. * * No vscode dependency — safe to unit-test in isolation. */ diff --git a/packages/kilo-vscode/tests/unit/textshimmer-no-timer.test.ts b/packages/kilo-vscode/tests/unit/textshimmer-no-timer.test.ts index 74e45bb818..48627137d2 100644 --- a/packages/kilo-vscode/tests/unit/textshimmer-no-timer.test.ts +++ b/packages/kilo-vscode/tests/unit/textshimmer-no-timer.test.ts @@ -18,8 +18,6 @@ import { join } from "node:path" * char already handles the fade over `--text-shimmer-swap` (220ms). * * This static test fails if someone re-introduces the timer pattern. - * For the matching runtime assertion, see - * `tests/webview-reactivity/textshimmer-perf.test.ts`. */ describe("TextShimmer JS-timer regression guard", () => { const tsxPath = join(__dirname, "..", "..", "..", "ui", "src", "components", "text-shimmer.tsx") @@ -51,23 +49,9 @@ describe("TextShimmer JS-timer regression guard", () => { expect(tsx).not.toMatch(/data-run/) }) - it("text-shimmer.css gates the sweep animation on data-active, not data-run", () => { - expect(css).not.toMatch(/\[data-run="true"\]/) - expect(css).toMatch( - /\[data-component="text-shimmer"\]\[data-active="true"\]\s*\[data-slot="text-shimmer-char-shimmer"\]\s*\{[^}]*animation-name:\s*text-shimmer-sweep/, - ) - }) - - it("text-shimmer.tsx does not use clearTimeout", () => { - expect(tsx).not.toMatch(/\bclearTimeout\b/) - }) - - it("text-shimmer.tsx has no createEffect (animation is CSS-driven)", () => { - expect(tsx).not.toMatch(/\bcreateEffect\b/) - }) - - it("text-shimmer.tsx does not render a data-run attribute", () => { - expect(tsx).not.toMatch(/data-run/) + it("text-shimmer.tsx renders plain text until an instance has been active", () => { + expect(tsx).toMatch(/createMemo\(\(seen\) => seen \|\| active\(\), false\)/) + expect(tsx).toMatch(//) }) it("text-shimmer.css gates the sweep animation on data-active, not data-run", () => { diff --git a/packages/ui/src/components/text-shimmer.tsx b/packages/ui/src/components/text-shimmer.tsx index 272912d5ee..430e41c9fd 100644 --- a/packages/ui/src/components/text-shimmer.tsx +++ b/packages/ui/src/components/text-shimmer.tsx @@ -5,7 +5,7 @@ // showed ~16% of blocked main-thread time in timer operations). The // animation is now driven entirely by the `data-active` attribute via CSS — // no JS timer, no per-change work. -import { createMemo, type ValidComponent } from "solid-js" +import { createMemo, Show, type ValidComponent } from "solid-js" import { Dynamic } from "solid-js/web" export const TextShimmer = (props: { @@ -18,6 +18,9 @@ export const TextShimmer = (props: { const text = createMemo(() => props.text ?? "") const active = createMemo(() => props.active ?? true) const offset = createMemo(() => props.offset ?? 0) + // Preserve the fade-out structure after live animation, but avoid creating it + // for historical labels that mount inactive and never shimmer. + const shimmer = createMemo((seen) => seen || active(), false) const swap = 220 return ( @@ -32,14 +35,16 @@ export const TextShimmer = (props: { "--text-shimmer-index": `${offset()}`, }} > - - + ) }