Add TanStack Charts Intent skills - #88
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
📝 WalkthroughWalkthroughAdded a TanStack Charts skill ecosystem with generated manifests, twelve independently loadable skills, ecosystem coordination references, package publication metadata, and a patch Changeset. ChangesTanStack Charts skill ecosystem
Estimated code review effort: 4 (Complex) | ~60 minutes Mergeability Score: 🟡 Moderate · up to The PR adds charting guidance whose examples currently include an accessor that can throw, a data-preparation example that renders no points, and an interaction example whose overlay does not stay selected; its Canvas accessibility wording is also imprecise. These bounded documentation correctness issues should be fixed before merge. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit 0f35d4c
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/charts-core/skills/build-chart-interactions/SKILL.md`:
- Around line 80-116: Update the chart setup around selectedId, selection, and
chart so the accepted selection value is stored in application state and used to
rebuild both the keyed selection and chart definition. Ensure whenSelected reads
the rebuilt selection after user interaction, and when the chart is mounted,
pass each rebuilt chart definition to host.update instead of retaining the
initial definition.
In `@packages/charts-core/skills/coordinate-charts-with-tanstack/SKILL.md`:
- Around line 72-83: Update the key accessor in the defineChart call to accept
the row directly as datum, using key: (datum) => ... instead of destructuring a
nonexistent datum property. Preserve the existing region/day key composition and
leave the valid color: 'region' configuration unchanged.
In `@packages/charts-core/skills/prepare-chart-data/SKILL.md`:
- Around line 44-56: Add five additional chronologically ordered West entries to
the prepareRevenue example so it contains seven rows and produces a complete
rolling window with partial: false; keep the existing rollingWindow
configuration unchanged.
In
`@packages/charts-core/skills/ship-accessible-charts/references/renderers-and-export.md`:
- Line 8: Update the Canvas row in the “renderers and export” reference to
clarify that Canvas lacks per-mark vector/accessibility descendants, while
preserving that it can provide an accessible shell with roles, ARIA attributes,
and focus/scene surfaces.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 592ce6a6-4eb2-46b2-b607-b8d62a7e98b7
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (43)
.changeset/intent-chart-skills.md_artifacts/domain_map.yaml_artifacts/skill_spec.md_artifacts/skill_tree.yamlbenchmarks/conformance/previews/manifest.jsonpackages/charts-core/package.jsonpackages/charts-core/skills/build-chart-interactions/SKILL.mdpackages/charts-core/skills/build-chart-interactions/references/interaction-state.mdpackages/charts-core/skills/compose-marks-and-views/SKILL.mdpackages/charts-core/skills/compose-marks-and-views/references/mark-selection.mdpackages/charts-core/skills/configure-scales-guides-color/SKILL.mdpackages/charts-core/skills/configure-scales-guides-color/references/scale-guide-ownership.mdpackages/charts-core/skills/coordinate-charts-with-tanstack/SKILL.mdpackages/charts-core/skills/coordinate-charts-with-tanstack/references/query-db-and-sync.mdpackages/charts-core/skills/coordinate-charts-with-tanstack/references/table-and-data-grid.mdpackages/charts-core/skills/coordinate-charts-with-tanstack/references/tanstack-application-state.mdpackages/charts-core/skills/debug-and-verify-charts/SKILL.mdpackages/charts-core/skills/design-a-chart/SKILL.mdpackages/charts-core/skills/design-a-chart/references/visual-task-matrix.mdpackages/charts-core/skills/design-responsive-charts/SKILL.mdpackages/charts-core/skills/extend-tanstack-charts/SKILL.mdpackages/charts-core/skills/extend-tanstack-charts/references/extension-protocols.mdpackages/charts-core/skills/migrate-to-tanstack-charts/SKILL.mdpackages/charts-core/skills/migrate-to-tanstack-charts/references/chart-js.mdpackages/charts-core/skills/migrate-to-tanstack-charts/references/d3.mdpackages/charts-core/skills/migrate-to-tanstack-charts/references/echarts.mdpackages/charts-core/skills/migrate-to-tanstack-charts/references/observable-plot.mdpackages/charts-core/skills/migrate-to-tanstack-charts/references/recharts.mdpackages/charts-core/skills/prepare-chart-data/SKILL.mdpackages/charts-core/skills/prepare-chart-data/references/transforms.mdpackages/charts-core/skills/ship-accessible-charts/SKILL.mdpackages/charts-core/skills/ship-accessible-charts/references/alpine.mdpackages/charts-core/skills/ship-accessible-charts/references/angular.mdpackages/charts-core/skills/ship-accessible-charts/references/lit.mdpackages/charts-core/skills/ship-accessible-charts/references/octane.mdpackages/charts-core/skills/ship-accessible-charts/references/preact.mdpackages/charts-core/skills/ship-accessible-charts/references/react-native.mdpackages/charts-core/skills/ship-accessible-charts/references/react.mdpackages/charts-core/skills/ship-accessible-charts/references/renderers-and-export.mdpackages/charts-core/skills/ship-accessible-charts/references/solid.mdpackages/charts-core/skills/ship-accessible-charts/references/svelte.mdpackages/charts-core/skills/ship-accessible-charts/references/vue.mdpackages/charts-core/skills/update-and-animate-charts/SKILL.md
| let selectedId: string | null = null | ||
|
|
||
| const selection = keyedSelection< | ||
| (typeof observations)[number], | ||
| string, | ||
| number, | ||
| number | ||
| >({ | ||
| selected: controlledSignal(selectedId, (next) => { | ||
| selectedId = next | ||
| }), | ||
| key: (datum) => datum.id, | ||
| }) | ||
|
|
||
| export const chart = defineChart({ | ||
| marks: [ | ||
| dot(observations, { | ||
| id: 'observations', | ||
| x: 'speed', | ||
| y: 'efficiency', | ||
| key: 'id', | ||
| }), | ||
| whenSelected( | ||
| dot(observations, { | ||
| id: 'selected-observation', | ||
| x: 'speed', | ||
| y: 'efficiency', | ||
| key: 'id', | ||
| r: 7, | ||
| }), | ||
| selection, | ||
| ), | ||
| ], | ||
| x: { scale: scaleLinear }, | ||
| y: { scale: scaleLinear }, | ||
| selection, | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -A8 -B2 'function controlledSignal|return \{ value, onChange \}' packages/charts-core/src/interaction-signal.tsRepository: TanStack/charts
Length of output: 494
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- skill excerpt ---'
sed -n '60,130p' packages/charts-core/skills/build-chart-interactions/SKILL.md
printf '%s\n' '--- interaction signal symbols ---'
rg -n -A30 -B8 'controlledSignal|keyedSelection|whenSelected|interface ControlledSignal|type ControlledSignal' packages/charts-core/src
printf '%s\n' '--- chart update and selection usage ---'
rg -n -A12 -B8 'host\.update|defineChart\(|\.selected\.value|selection\.selected|whenSelected\(' packages/charts-core packages/charts-react packages/charts-solid packages/charts-vue 2>/dev/null | head -n 1000Repository: TanStack/charts
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- selection implementation ---'
sed -n '1,180p' packages/charts-core/src/selection.ts
printf '%s\n' '--- controlled-selection tests ---'
sed -n '38,190p' packages/charts-core/src/selection.test.ts
printf '%s\n' '--- host update API ---'
rg -n -A25 -B10 'interface ChartHost|type ChartHost|update\(' packages/charts-core/src/dom-types.ts packages/charts-core/src/dom.ts packages/charts-core/src/scene.ts
printf '%s\n' '--- controlled-value documentation and examples ---'
rg -n -A12 -B8 'Rebuild the definition|accepted controlled value|host\.update|controlledSignal' packages/charts-core/skills packages/charts-core/src --glob '*.md' --glob '*.ts' | head -n 500Repository: TanStack/charts
Length of output: 50373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
skill = Path("packages/charts-core/skills/build-chart-interactions/SKILL.md").read_text()
signal = Path("packages/charts-core/src/interaction-signal.ts").read_text()
selection = Path("packages/charts-core/src/selection.ts").read_text()
assert "selected: controlledSignal(selectedId" in skill
assert "selectedId = next" in skill
assert "Rebuild the definition with the accepted controlled value." in skill
assert "return { value, onChange }" in signal
assert "const selected = options.selected.value" in selection
assert "options.selected.onChange(next" in selection
# Standalone behavioral probe of the relevant snapshot/callback contract.
selected_id = None
signal_value = selected_id
def on_change(next_value):
global selected_id
selected_id = next_value
on_change("a")
assert selected_id == "a"
assert signal_value is None
assert signal_value != "a"
print("callback accepts 'a', but the existing controlled signal still exposes None")
print("the overlay predicate therefore remains false until a new definition uses the accepted value")
PYRepository: TanStack/charts
Length of output: 322
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
skill = Path("packages/charts-core/skills/build-chart-interactions/SKILL.md").read_text()
signal = Path("packages/charts-core/src/interaction-signal.ts").read_text()
selection = Path("packages/charts-core/src/selection.ts").read_text()
assert "selected: controlledSignal(selectedId" in skill
assert "selectedId = next" in skill
assert "Rebuild the definition with the accepted controlled value." in skill
assert "return { value, onChange }" in signal
assert "const selected = options.selected.value" in selection
assert "options.selected.onChange(next" in selection
selected_id = None
signal_value = selected_id
def on_change(next_value):
global selected_id
selected_id = next_value
on_change("a")
assert selected_id == "a"
assert signal_value is None
assert signal_value != "a"
print("callback accepts 'a', but the existing controlled signal still exposes None")
print("the overlay predicate remains false until a new definition uses the accepted value")
PYRepository: TanStack/charts
Length of output: 312
Rebuild the definition with the accepted selection.
controlledSignal stores selectedId as the initial value; its callback does not update selection.selected.value. After selection, whenSelected still reads null and removes the overlay. Store the accepted value in application state, rebuild the selection and chart definition, and pass the new definition to host.update when mounted.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/charts-core/skills/build-chart-interactions/SKILL.md` around lines
80 - 116, Update the chart setup around selectedId, selection, and chart so the
accepted selection value is stored in application state and used to rebuild both
the keyed selection and chart definition. Ensure whenSelected reads the rebuilt
selection after user interaction, and when the chart is mounted, pass each
rebuilt chart definition to host.update instead of retaining the initial
definition.
Source: MCP tools
| const chartDefinition = defineChart({ | ||
| marks: [ | ||
| lineY(analysis.summaryRows, { | ||
| x: 'day', | ||
| y: 'revenue', | ||
| color: 'region', | ||
| key: ({ datum }) => `${datum.region}:${datum.day.toISOString()}`, | ||
| }), | ||
| ], | ||
| x: { scale: scaleUtc }, | ||
| y: { scale: scaleLinear }, | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="packages/charts-core/skills/coordinate-charts-with-tanstack/SKILL.md"
if rg -nP "^\s*color:\s*['\"]region['\"]|^\s*key:\s*\(\{\s*datum\s*\}\)" "$file"; then
echo "Outdated lineY channel syntax remains."
exit 1
fiRepository: TanStack/charts
Length of output: 293
🏁 Script executed:
set -euo pipefail
printf '%s\n' '--- skill context ---'
sed -n '35,95p' packages/charts-core/skills/coordinate-charts-with-tanstack/SKILL.md
printf '%s\n' '--- lineY and channel definitions/usages ---'
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' \
"lineY|interface.*Channel|type.*Channel|key.*datum|z:" .
printf '%s\n' '--- package metadata ---'
rg -n --glob 'package.json' --glob 'pnpm-lock.yaml' --glob 'yarn.lock' --glob 'package-lock.json' \
'"`@tanstack/charts`"|charts-core|version' .Repository: TanStack/charts
Length of output: 50374
🏁 Script executed:
set -euo pipefail
printf '%s\n' '--- public channel contract ---'
sed -n '20,80p' docs/reference/types.md
printf '%s\n' '--- line mark contract ---'
sed -n '20,75p' docs/reference/marks/line-and-area.md
sed -n '95,135p' packages/charts-core/docs/concepts/marks-and-layering.md
printf '%s\n' '--- relevant color and grouping guidance ---'
sed -n '1,55p' docs/guides/legends-and-color.md
sed -n '100,135p' docs/guides/legends-and-color.md
sed -n '140,170p' docs/reference/transforms.md
printf '%s\n' '--- implementation types and key handling ---'
rg -n -A18 -B8 \
"type ChannelAccessor|interface ChannelAccessorContext|key\??:|resolve.*key|channel.*accessor" \
packages/charts-core/src packages/charts-core/docs docs/referenceRepository: TanStack/charts
Length of output: 50374
🏁 Script executed:
set -euo pipefail
printf '%s\n' '--- public channel contract ---'
sed -n '24,75p' docs/reference/types.md
printf '%s\n' '--- line mark contract ---'
sed -n '20,70p' docs/reference/marks/line-and-area.md
printf '%s\n' '--- color and grouping guidance ---'
sed -n '15,45p' docs/guides/legends-and-color.md
sed -n '100,135p' docs/guides/legends-and-color.md
printf '%s\n' '--- source channel and key types ---'
rg -n -A12 -B4 \
"export (type|interface) (ChannelAccessor|Channel|VisualChannel)|key\??:" \
packages/charts-core/src/types.ts packages/charts-core/src/line.ts
printf '%s\n' '--- source accessor evaluation ---'
rg -n -A10 -B5 \
"options\.key|keyChannel|resolveChannel|channelAccessor|accessor\(" \
packages/charts-core/src/mark.ts packages/charts-core/src/line.ts packages/charts-core/srcRepository: TanStack/charts
Length of output: 50373
🏁 Script executed:
set -euo pipefail
printf '%s\n' '--- lineY grouping implementation ---'
sed -n '135,160p' packages/charts-core/src/line.ts
printf '%s\n' '--- current skill example ---'
sed -n '72,82p' packages/charts-core/skills/coordinate-charts-with-tanstack/SKILL.md
printf '%s\n' '--- accessor behavior probe ---'
node - <<'JS'
const row = { region: 'west', day: new Date('2026-01-01T00:00:00Z'), revenue: 10 }
const bad = ({ datum }) => `${datum.region}:${datum.day.toISOString()}`
const good = (datum) => `${datum.region}:${datum.day.toISOString()}`
try {
bad(row)
console.log('bad: unexpectedly succeeded')
} catch (error) {
console.log(`bad: ${error.constructor.name}: ${error.message}`)
}
console.log(`good: ${good(row)}`)
JS
printf '%s\n' '--- read-only source contract probe ---'
python3 - <<'PY'
from pathlib import Path
source = Path("packages/charts-core/src/line.ts").read_text()
required = (
"options.z === undefined && options.color !== undefined",
"? colorValues",
": zValues",
)
print("lineY color fallback groups:", all(part in source for part in required))
PYRepository: TanStack/charts
Length of output: 1656
Fix the key accessor.
lineY accessors receive the row as the first argument. key: ({ datum }) => ... destructures a nonexistent property and throws. Use key: (datum) => .... color: 'region' is valid and groups paths when z is omitted.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/charts-core/skills/coordinate-charts-with-tanstack/SKILL.md` around
lines 72 - 83, Update the key accessor in the defineChart call to accept the row
directly as datum, using key: (datum) => ... instead of destructuring a
nonexistent datum property. Preserve the existing region/day key composition and
leave the valid color: 'region' configuration unchanged.
Source: MCP tools
| return rollingWindow(daily, { | ||
| by: 'region', | ||
| orderBy: 'day', | ||
| size: 7, | ||
| partial: false, | ||
| outputs: { revenue7d: { value: 'revenue', reduce: 'sum' } }, | ||
| }) | ||
| } | ||
|
|
||
| const prepared = prepareRevenue([ | ||
| { day: '2026-08-01', region: 'West', amount: 120 }, | ||
| { day: '2026-08-02', region: 'West', amount: 160 }, | ||
| ]) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -A4 -B2 'partial === false|selectedWindow' packages/charts-core/src/transform-rolling-window.tsRepository: TanStack/charts
Length of output: 716
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- SKILL.md context ---'
cat -n packages/charts-core/skills/prepare-chart-data/SKILL.md | sed -n '1,100p'
printf '%s\n' '--- rolling-window implementation ---'
cat -n packages/charts-core/src/transform-rolling-window.ts | sed -n '1,150p'
printf '%s\n' '--- related symbols ---'
rg -n -A8 -B8 'revenueMark|prepareRevenue|rollingWindow|partial' packages/charts-core/skills/prepare-chart-data packages/charts-core/srcRepository: TanStack/charts
Length of output: 45978
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
source = Path("packages/charts-core/src/transform-rolling-window.ts").read_text()
skill = Path("packages/charts-core/skills/prepare-chart-data/SKILL.md").read_text()
# Model the relevant behavior directly from the implementation:
# with the default end anchor, each position uses the preceding window
# including the current position, and partial windows are discarded.
rows = [
{"day": "2026-08-01", "region": "West", "amount": 120},
{"day": "2026-08-02", "region": "West", "amount": 160},
]
size = 7
windows = [list(range(max(0, i - size + 1), i + 1)) for i in range(len(rows))]
kept = [] if any(len(window) < size for window in windows) else windows
print(f"implementation_discards_short_windows={bool(re.search(r'partial === false.*windowIndexes\\.length < size', source))}")
print(f"window_lengths={[len(window) for window in windows]}")
print(f"kept_window_count={len(kept)}")
print(f"skill_defines_revenueMark={'revenueMark' in skill}")
PYRepository: TanStack/charts
Length of output: 506
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re
source = Path("packages/charts-core/src/transform-rolling-window.ts").read_text()
skill = Path("packages/charts-core/skills/prepare-chart-data/SKILL.md").read_text()
rows = [
{"day": "2026-08-01", "region": "West", "amount": 120},
{"day": "2026-08-02", "region": "West", "amount": 160},
]
size = 7
window_lengths = [
len(list(range(max(0, position - size + 1), position + 1)))
for position in range(len(rows))
]
kept_count = sum(length == size for length in window_lengths)
pattern = r"partial === false[\s\S]*?windowIndexes\.length < size"
print(f"implementation_discards_short_windows={bool(re.search(pattern, source))}")
print(f"grouped_input_row_count={len(rows)}")
print(f"window_lengths={window_lengths}")
print(f"kept_window_count={kept_count}")
print(f"prepared_is_empty={kept_count == 0}")
print(f"revenueMark_receives_empty_data={'lineY(prepared' in skill and kept_count == 0}")
PYRepository: TanStack/charts
Length of output: 324
Provide seven rows in the same region for the partial: false example.
With size: 7 and only two West rows, rollingWindow discards both partial windows. prepared is empty, so revenueMark receives no points. Add five more ordered West rows or set partial: true.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/charts-core/skills/prepare-chart-data/SKILL.md` around lines 44 -
56, Add five additional chronologically ordered West entries to the
prepareRevenue example so it contains seven rows and produces a complete rolling
window with partial: false; keep the existing rollingWindow configuration
unchanged.
Source: MCP tools
| | Requirement | Choose | Tradeoff to verify | | ||
| | --------------------------------------------------- | ---------------------------- | -------------------------------------------------------------------- | | ||
| | Visible server geometry, vector output, DOM styling | default SVG | scene node count and DOM interaction cost | | ||
| | Large paint workload, raster-first presentation | Canvas | first pixels after client mount; no vector/accessibility descendants | |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Clarify the Canvas accessibility trade-off.
The phrase “no vector/accessibility descendants” can imply that Canvas has no accessible output. The supplied packages/react-charts/src/CanvasChart.test.tsx:74-101 shows an accessible Canvas shell with role="img", ARIA attributes, and focus/scene surfaces. State that Canvas lacks per-mark vector/accessibility descendants instead.
Proposed wording
-| Large paint workload, raster-first presentation | Canvas | first pixels after client mount; no vector/accessibility descendants |
+| Large paint workload, raster-first presentation | Canvas | first pixels after client mount; no per-mark vector/accessibility descendants |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | Large paint workload, raster-first presentation | Canvas | first pixels after client mount; no vector/accessibility descendants | | |
| | Large paint workload, raster-first presentation | Canvas | first pixels after client mount; no per-mark vector/accessibility descendants | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@packages/charts-core/skills/ship-accessible-charts/references/renderers-and-export.md`
at line 8, Update the Canvas row in the “renderers and export” reference to
clarify that Canvas lacks per-mark vector/accessibility descendants, while
preserving that it can provide an accessible shell with roles, ARIA attributes,
and focus/scene surfaces.
Summary
Validation
Summary by CodeRabbit
New Features
Documentation