Skip to content

fix(cockpit-examples): use CSS sidebar widths#779

Merged
blove merged 1 commit into
mainfrom
blove/examples-latent-bug-sweep
Jul 8, 2026
Merged

fix(cockpit-examples): use CSS sidebar widths#779
blove merged 1 commit into
mainfrom
blove/examples-latent-bug-sweep

Conversation

@blove

@blove blove commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace Tailwind width class strings passed to example-chat-layout sidebarWidth with CSS length values across chat and deep-agents cockpit examples.
  • Add static sweep guards for render directive drift and sidebarWidth dead-prop regressions.
  • Add a render-project streaming harness that seeks each render example fixture to 100% and checks for [object Object]/blank render regressions plus numeric display text.

Findings

  • P1: cockpit/chat/threads/angular/src/app/threads.component.ts passed sidebarWidth="w-64" to an input consumed as a CSS custom property, so the width was a silent no-op. Fixed to 16rem.
  • P2: 13 more cockpit chat/deep-agents examples passed w-72 or w-80 into the same CSS-length input. Fixed to 18rem and 20rem respectively.
  • No remaining render fixture directive drift found against the installed @json-render/core expression set.
  • No remaining render example display-coercion or mid-stream object-flash issue found; added component coverage to keep that true.

Verification

  • npx vitest run cockpit/render/shared/render-examples-latent-bugs.spec.ts cockpit/render/shared/render-examples-display-coercion.spec.ts cockpit/render/shared/to-display-text.spec.ts
  • npx vitest run src/lib/render-examples-streaming-harness.spec.ts --config vite.config.mts from libs/render
  • npx nx test render --skip-nx-cache
  • npx nx affected -t build --configuration=production --skip-nx-cache

The affected build completed for 46 projects plus dependency tasks. It emitted existing budget/CommonJS/unused-import warnings, but exited successfully.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
threadplane Ready Ready Preview, Comment Jul 8, 2026 5:23am

Request Review

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 2m 59s —— View job


PR Review

  • Gather context and read CLAUDE.md
  • Read PR diff and changed files
  • Review for correctness, security, TypeScript, Angular pitfalls, test coverage
  • Post findings

Summary

The core fix is correct and well-executed. All 14 sidebarWidth props were passing Tailwind class names (w-64/w-72/w-80) to ExampleChatLayoutComponent, which binds the value as [style.--example-layout-sidebar-width]="sidebarWidth()" — a CSS custom property, not a class attribute. Tailwind class strings are a silent no-op there. The conversions (64→16rem, 72→18rem, 80→20rem) are exact. The new regression guards are a good addition.

Two issues worth addressing before merge:


Medium — Hardcoded spec indices in streaming harness

libs/render/src/lib/render-examples-streaming-harness.spec.ts:82,88

STATE_MANAGEMENT_SPECS[1] and COMPUTED_FUNCTIONS_SPECS[1] couple the test to spec ordering. If either array is reordered, the test silently validates a fixture that may not exercise numeric/computed values, making the coverage guarantee hollow. Inline suggestion posted. The same block also skips await fixture.whenStable() that the loop-based tests above use — low risk today (signals are sync) but an asymmetry worth closing. Fix this →


Low — Function() / eval in latent-bug sweep guard

cockpit/render/shared/render-examples-latent-bugs.spec.ts:57-63

parseJsonRenderSpecs uses Function("use strict"; return (...)) — functionally eval() — over spec source files. The practical risk is low (static repo files), but any spec that happens to contain a JS expression with side-effects would execute at test time. Inline suggestion posted with a safer alternative (static imports). Fix this →


Info / no action needed

  • ANGULAR_EXAMPLE_DIRS = ['cockpit', 'examples'] — both directories exist at workspace root, so no ENOENT risk.
  • sidebarWidth default in ExampleChatLayoutComponent is already '18rem', consistent with the new values.
  • Comment fixes ($fn$computed) in to-display-text.ts and render-examples-display-coercion.spec.ts are accurate.

Comment on lines +80 to +93
const stateFixture = TestBed.createComponent(StateManagementComponent);
const stateComponent = stateFixture.componentInstance as unknown as RenderExampleHarness;
stateComponent.simulator.setSource(STATE_MANAGEMENT_SPECS[1].json);
stateComponent.simulator.seek(STATE_MANAGEMENT_SPECS[1].json.length);
stateFixture.detectChanges();

const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
computedComponent.simulator.setSource(COMPUTED_FUNCTIONS_SPECS[1].json);
computedComponent.simulator.seek(COMPUTED_FUNCTIONS_SPECS[1].json.length);
computedFixture.detectChanges();

expect((stateFixture.nativeElement as HTMLElement).textContent).toContain('30');
expect((computedFixture.nativeElement as HTMLElement).textContent).toContain('42');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic indices make this test silently validate the wrong fixture if STATE_MANAGEMENT_SPECS or COMPUTED_FUNCTIONS_SPECS are ever reordered or a spec is inserted before index 1.

Suggested change
const stateFixture = TestBed.createComponent(StateManagementComponent);
const stateComponent = stateFixture.componentInstance as unknown as RenderExampleHarness;
stateComponent.simulator.setSource(STATE_MANAGEMENT_SPECS[1].json);
stateComponent.simulator.seek(STATE_MANAGEMENT_SPECS[1].json.length);
stateFixture.detectChanges();
const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
computedComponent.simulator.setSource(COMPUTED_FUNCTIONS_SPECS[1].json);
computedComponent.simulator.seek(COMPUTED_FUNCTIONS_SPECS[1].json.length);
computedFixture.detectChanges();
expect((stateFixture.nativeElement as HTMLElement).textContent).toContain('30');
expect((computedFixture.nativeElement as HTMLElement).textContent).toContain('42');
const statePrimSpec = STATE_MANAGEMENT_SPECS.find((s) => s.label === 'Nested Paths')!;
stateComponent.simulator.setSource(statePrimSpec.json);
stateComponent.simulator.seek(statePrimSpec.json.length);
stateFixture.detectChanges();
const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
const computedPrimSpec = COMPUTED_FUNCTIONS_SPECS.find((s) => s.label === 'Data Display')!;
computedComponent.simulator.setSource(computedPrimSpec.json);
computedComponent.simulator.seek(computedPrimSpec.json.length);
computedFixture.detectChanges();

Also note this test doesn't call await fixture.whenStable() after detectChanges(), unlike the loop-based tests above (line 62). Works today because signal propagation is synchronous, but it's an asymmetry worth closing to avoid latent flakiness if an async effect is added.

Comment on lines +57 to +63
function parseJsonRenderSpecs(source: string): unknown[] {
const specs: unknown[] = [];
const pattern = /json:\s*JSON\.stringify\(([\s\S]*?),\s*null,\s*2\)/g;
for (const match of source.matchAll(pattern)) {
specs.push(Function(`"use strict"; return (${match[1]});`)());
}
return specs;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function() is effectively eval() over spec source text. For version-controlled fixtures the practical risk is low, but any spec file that happens to contain a JavaScript expression with side-effects (e.g. a computed initializer calling process.exit) will execute at test time. Consider statically importing the spec arrays instead of parsing their source:

// In each specs.ts, export a named constant the test can import directly.
// Then collectDirectiveNames() can run on the imported value without eval.
import { STATE_MANAGEMENT_SPECS } from '../state-management/angular/src/app/specs';
// …and so on for the other render examples.

If the regex-parse approach must stay, at minimum validate that the captured expression only looks like an object/array literal before passing it to Function.

@blove blove force-pushed the blove/examples-latent-bug-sweep branch from 466a271 to 92f3bd6 Compare July 8, 2026 05:12
@blove blove marked this pull request as ready for review July 8, 2026 05:12
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 2m 34s —— View job


PR Review & Fixes

  • Gather context and read CLAUDE.md
  • Read changed files
  • Fix medium: replace hardcoded spec indices with .find() in streaming harness
  • Fix low: replace Function() eval with static imports in latent-bug spec
  • Push fixes (blocked — push approval needed)

Both issues from the prior review have been implemented locally and committed. The commit is staged but requires push approval to land on the branch.

Changes made

libs/render/src/lib/render-examples-streaming-harness.spec.ts (lines 81–91)

Replaced STATE_MANAGEMENT_SPECS[1] / COMPUTED_FUNCTIONS_SPECS[1] with label-based lookups that are stable across reorderings, and added await whenStable() calls for symmetry with the loop-based tests above:

const statePrimSpec = STATE_MANAGEMENT_SPECS.find((s) => s.label === 'Nested Paths')!;
stateComponent.simulator.setSource(statePrimSpec.json);
stateComponent.simulator.seek(statePrimSpec.json.length);
stateFixture.detectChanges();
await stateFixture.whenStable();

const computedPrimSpec = COMPUTED_FUNCTIONS_SPECS.find((s) => s.label === 'Data Display')!;
computedComponent.simulator.setSource(computedPrimSpec.json);
computedComponent.simulator.seek(computedPrimSpec.json.length);
computedFixture.detectChanges();
await computedFixture.whenStable();

cockpit/render/shared/render-examples-latent-bugs.spec.ts (full rewrite of the directive test)

Removed renderSpecFiles(), parseJsonRenderSpecs(), and all Function() usage. Instead, statically import all six spec arrays and call JSON.parse(spec.json) to feed collectDirectiveNames():

import { REGISTRY_SPECS } from '../registry/angular/src/app/specs';
import { SPEC_RENDERING_SPECS } from '../spec-rendering/angular/src/app/specs';
// … four more …

const ALL_RENDER_SPECS = [
  ...REGISTRY_SPECS, ...SPEC_RENDERING_SPECS, ...ELEMENT_RENDERING_SPECS,
  ...STATE_MANAGEMENT_SPECS, ...REPEAT_LOOPS_SPECS, ...COMPUTED_FUNCTIONS_SPECS,
];

// in the test:
for (const spec of ALL_RENDER_SPECS) {
  for (const directive of collectDirectiveNames(JSON.parse(spec.json))) {
    if (!SUPPORTED_RENDER_DIRECTIVES.has(directive)) {
      unsupported.push(`${spec.label}: ${directive}`);
    }
  }
}

The angularSourceFiles / readFileSync path for the sidebarWidth CSS-class guard is unchanged.


Note: The commit is ready locally but push to blove/examples-latent-bug-sweep needs approval. Once approved the changes will land.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 3m 41s —— View job


PR Review

  • Gather context and read CLAUDE.md
  • Read PR diff and changed files
  • Review for correctness, security, TypeScript, Angular pitfalls, test coverage
  • Post findings

Summary

Core fix is correct. All 14 sidebarWidth props were passing Tailwind class strings (w-64/w-72/w-80) to ExampleChatLayoutComponent, which binds the value as [style.--example-layout-sidebar-width] — a CSS custom property that ignores class names. The conversions (16rem / 18rem / 20rem) are exact. The previous automated review flagged the main issues; I've confirmed them by reading the actual spec arrays and component state initialization.

Two issues worth fixing before merge:


Medium — Magic indices + missing whenStable in streaming harness

libs/render/src/lib/render-examples-streaming-harness.spec.ts:83–91

STATE_MANAGEMENT_SPECS[1] is confirmed to be "Nested Paths" and COMPUTED_FUNCTIONS_SPECS[1] is confirmed to be "Data Display" — both assertions ('30' from age: 30 initial state, '42' from multiply(7,6)) are currently correct. But index coupling means a spec reorder silently validates the wrong fixture. Additionally, the standalone test calls detectChanges() without await fixture.whenStable(), unlike the loop-based tests above (lines 62–63) which call both. Inline suggestion posted.

Fix this →


Low — Function() / eval in latent-bug sweep guard

cockpit/render/shared/render-examples-latent-bugs.spec.ts:61

parseJsonRenderSpecs uses Function("use strict"; return (...)) — eval — over spec source files. A simpler fix is available since each spec file already exports a named *_SPECS array with spec.json = JSON.stringify(obj, null, 2): import the arrays statically, call JSON.parse(spec.json), and pass that to collectDirectiveNames. No eval needed. The tradeoff is the import list needs updating when new render examples are added, but that's a smaller surface than implicit eval. Inline suggestion posted.

Fix this →


Info / no action needed

  • STATE_MANAGEMENT_SPECS[1] default state has age: 30 (verified in StateManagementComponent line 420: signalStateStore({ user: { name: 'Alice', age: 30 }, ... })); COMPUTED_FUNCTIONS_SPECS[1] has multiply(7, 6) = 42. Both expect assertions are factually correct today.
  • ANGULAR_EXAMPLE_DIRS = ['cockpit', 'examples'] — both directories confirmed at workspace root; no ENOENT risk.
  • sidebarWidth default in ExampleChatLayoutComponent is '18rem', consistent with the new w-72 → 18rem values.

Comment on lines +83 to +91
stateComponent.simulator.setSource(STATE_MANAGEMENT_SPECS[1].json);
stateComponent.simulator.seek(STATE_MANAGEMENT_SPECS[1].json.length);
stateFixture.detectChanges();

const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
computedComponent.simulator.setSource(COMPUTED_FUNCTIONS_SPECS[1].json);
computedComponent.simulator.seek(COMPUTED_FUNCTIONS_SPECS[1].json.length);
computedFixture.detectChanges();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues here, both confirmed after reading the actual spec arrays:

Magic indicesSTATE_MANAGEMENT_SPECS[1] is "Nested Paths" and COMPUTED_FUNCTIONS_SPECS[1] is "Data Display" right now, so the '30' / '42' assertions are correct. But if either array is reordered, this test silently validates the wrong fixture. The previous review's inline suggestion is the right fix.

Missing await fixture.whenStable() — the loop-based tests above (lines 62–63) call detectChanges() then await fixture.whenStable() then detectChanges() again. This standalone test calls detectChanges() only once per fixture and skips whenStable(). Works today because signal propagation is synchronous, but it's an asymmetry that will bite if an async effect is added to either component.

Suggested change
stateComponent.simulator.setSource(STATE_MANAGEMENT_SPECS[1].json);
stateComponent.simulator.seek(STATE_MANAGEMENT_SPECS[1].json.length);
stateFixture.detectChanges();
const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
computedComponent.simulator.setSource(COMPUTED_FUNCTIONS_SPECS[1].json);
computedComponent.simulator.seek(COMPUTED_FUNCTIONS_SPECS[1].json.length);
computedFixture.detectChanges();
const statePrimSpec = STATE_MANAGEMENT_SPECS.find((s) => s.label === 'Nested Paths')!;
stateComponent.simulator.setSource(statePrimSpec.json);
stateComponent.simulator.seek(statePrimSpec.json.length);
stateFixture.detectChanges();
await stateFixture.whenStable();
const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
const computedPrimSpec = COMPUTED_FUNCTIONS_SPECS.find((s) => s.label === 'Data Display')!;
computedComponent.simulator.setSource(computedPrimSpec.json);
computedComponent.simulator.seek(computedPrimSpec.json.length);
computedFixture.detectChanges();
await computedFixture.whenStable();

const specs: unknown[] = [];
const pattern = /json:\s*JSON\.stringify\(([\s\S]*?),\s*null,\s*2\)/g;
for (const match of source.matchAll(pattern)) {
specs.push(Function(`"use strict"; return (${match[1]});`)());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function() is effectively eval(). The practical risk for version-controlled fixtures is low, but there's a simpler fix available: each spec file already exports a named *_SPECS array where spec.json is the result of JSON.stringify(obj, null, 2). You can import those arrays statically and round-trip with JSON.parse instead of evaluating source text:

// Replace parseJsonRenderSpecs + this loop with static imports:
import { STATE_MANAGEMENT_SPECS } from '../state-management/angular/src/app/specs';
import { ELEMENT_RENDERING_SPECS } from '../element-rendering/angular/src/app/specs';
// ... other spec arrays

const ALL_SPECS = [
  ...STATE_MANAGEMENT_SPECS,
  ...ELEMENT_RENDERING_SPECS,
  // ...
];
for (const spec of ALL_SPECS) {
  const obj = JSON.parse(spec.json);
  for (const directive of collectDirectiveNames(obj)) { ... }
}

Tradeoff: the static list needs to be updated when new render examples are added, unlike the current dynamic scan. If you want to keep dynamic discovery, dynamic import() over renderSpecFiles() paths avoids Function() while preserving the automation.

@blove blove force-pushed the blove/examples-latent-bug-sweep branch from 92f3bd6 to a2633a3 Compare July 8, 2026 05:20
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 2m 50s —— View job


PR Review & Fixes

  • Gather context and read CLAUDE.md
  • Read PR diff and changed files
  • Review for correctness, security, TypeScript, Angular pitfalls, test coverage
  • Fix medium: replace hardcoded spec indices with .find() + add whenStable() in streaming harness
  • Fix low: replace Function() eval with static imports in latent-bug spec
  • Push fixes (blocked — github-actions[bot] lacks push permission to this repo)
  • Post inline findings

Summary

The core fix (14 sidebarWidth props changed from Tailwind class strings to CSS length values) is correct and well-executed. Two issues from prior reviews remain unresolved on the branch — both have been implemented locally in this run but could not be pushed (HTTP 403).


Medium — Magic indices in streaming harness

cockpit/render/shared/render-examples-streaming-harness.spec.ts:82–90

STATE_MANAGEMENT_SPECS[1] ("Nested Paths") and COMPUTED_FUNCTIONS_SPECS[1] ("Data Display") are correct today, but index coupling means a spec reorder silently validates the wrong fixture. The test also skips await fixture.whenStable() after detectChanges(), unlike the loop-based tests above. Inline suggestion posted.


Low — Function() / eval in latent-bug sweep guard

cockpit/render/shared/render-examples-latent-bugs.spec.ts:57–63

parseJsonRenderSpecs uses Function(...) — effectively eval() — over spec source files. The streaming harness already statically imports all six *_SPECS arrays; the same pattern can replace the eval here, removing the risk entirely and producing more readable failure messages (spec.label: $directive vs. a file path). Inline suggestion posted.


Info / no action needed

  • ANGULAR_EXAMPLE_DIRS = ['cockpit', 'examples'] — both directories exist at workspace root; no ENOENT risk.
  • sidebarWidth default in ExampleChatLayoutComponent is '18rem', consistent with the new w-72 → 18rem values.
  • Comment fixes ($fn$computed) in to-display-text.ts and the display-coercion spec are accurate.

Note: Both fixes were committed locally but the push was blocked (HTTP 403 — github-actions[bot] lacks write access to this repository). To land the fixes, either grant the bot push permission or apply the inline suggestions directly.

computedFixture.detectChanges();

expect((stateFixture.nativeElement as HTMLElement).textContent).toContain('30');
expect((computedFixture.nativeElement as HTMLElement).textContent).toContain('42');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium — Magic indices + missing whenStable

STATE_MANAGEMENT_SPECS[1] is "Nested Paths" and COMPUTED_FUNCTIONS_SPECS[1] is "Data Display" today — the '30' / '42' assertions are factually correct. But index coupling means a spec reorder silently validates the wrong fixture, and both detectChanges() calls skip the await whenStable() that the loop tests above use (lines 61–63).

Suggested change
expect((computedFixture.nativeElement as HTMLElement).textContent).toContain('42');
const stateFixture = TestBed.createComponent(StateManagementComponent);
const stateComponent = stateFixture.componentInstance as unknown as RenderExampleHarness;
const statePrimSpec = STATE_MANAGEMENT_SPECS.find((s) => s.label === 'Nested Paths')!;
stateComponent.simulator.setSource(statePrimSpec.json);
stateComponent.simulator.seek(statePrimSpec.json.length);
stateFixture.detectChanges();
await stateFixture.whenStable();
const computedFixture = TestBed.createComponent(ComputedFunctionsComponent);
const computedComponent = computedFixture.componentInstance as unknown as RenderExampleHarness;
const computedPrimSpec = COMPUTED_FUNCTIONS_SPECS.find((s) => s.label === 'Data Display')!;
computedComponent.simulator.setSource(computedPrimSpec.json);
computedComponent.simulator.seek(computedPrimSpec.json.length);
computedFixture.detectChanges();
await computedFixture.whenStable();

const specs: unknown[] = [];
const pattern = /json:\s*JSON\.stringify\(([\s\S]*?),\s*null,\s*2\)/g;
for (const match of source.matchAll(pattern)) {
specs.push(Function(`"use strict"; return (${match[1]});`)());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low — Function() is effectively eval()

The streaming harness file already statically imports all six *_SPECS arrays. Use the same pattern here — import them, concatenate into ALL_RENDER_SPECS, and round-trip with JSON.parse(spec.json). This removes the eval surface entirely and the error message on failure becomes ${spec.label}: ${directive} instead of a file path, which is more readable.

Suggested change
specs.push(Function(`"use strict"; return (${match[1]});`)());
function parseJsonRenderSpecs(source: string): unknown[] {

Replace renderSpecFiles(), parseJsonRenderSpecs(), and the eval-based loop with:

import { COMPUTED_FUNCTIONS_SPECS } from '../computed-functions/angular/src/app/specs';
import { ELEMENT_RENDERING_SPECS } from '../element-rendering/angular/src/app/specs';
import { REGISTRY_SPECS } from '../registry/angular/src/app/specs';
import { REPEAT_LOOPS_SPECS } from '../repeat-loops/angular/src/app/specs';
import { SPEC_RENDERING_SPECS } from '../spec-rendering/angular/src/app/specs';
import { STATE_MANAGEMENT_SPECS } from '../state-management/angular/src/app/specs';

const ALL_RENDER_SPECS = [
  ...REGISTRY_SPECS, ...SPEC_RENDERING_SPECS, ...ELEMENT_RENDERING_SPECS,
  ...STATE_MANAGEMENT_SPECS, ...REPEAT_LOOPS_SPECS, ...COMPUTED_FUNCTIONS_SPECS,
];

// in the test:
for (const spec of ALL_RENDER_SPECS) {
  for (const directive of collectDirectiveNames(JSON.parse(spec.json))) {
    if (!SUPPORTED_RENDER_DIRECTIVES.has(directive)) {
      unsupported.push(`${spec.label}: ${directive}`);
    }
  }
}

@blove blove merged commit 496db8e into main Jul 8, 2026
41 checks passed
@blove blove deleted the blove/examples-latent-bug-sweep branch July 8, 2026 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant