feat(widgets): widget editor UX — double-click, auto-preview, templates, help text - #347
feat(widgets): widget editor UX — double-click, auto-preview, templates, help text#347alfredo1996 wants to merge 24 commits into
Conversation
…ry are set (#315) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…or parameters..." (#316) When a widget has no connectionId, the query is disabled and TanStack Query returns isPending + idle. Previously this always showed "Waiting for parameters..." which was misleading. Now the idle state distinguishes three cases: missing connection, missing query, and genuine unresolved parameters. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…313) Two root causes addressed: 1. NVL layout timeout — When the graph chart mounts inside a CSS-animated dialog (fullscreen expand), the container starts at ~0 size during the zoom-in-95 animation. NVL's force layout can fail to converge in this state and never fire onLayoutDone, leaving the loading spinner visible indefinitely. Added a safety timeout (800ms) that forces layoutReady if onLayoutDone hasn't fired, then calls fitGraph to re-center. 2. Zustand store conflict — The fullscreen dialog renders a second CardContainer for the same widget, creating two GraphExplorationWrapper instances that both read/write the same graph widget store slot. Added a widgetIdSuffix prop so the fullscreen instance uses a distinct store key (widget.id--fullscreen), preventing re-render cascades between the normal and fullscreen views. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…right testing agents Restored from git history (deleted in e8ce8f8): - CLAUDE.md — project conventions and architecture guide - .claude/agents/ — code-reviewer, code-simplifier, codebase-search, lint-fix, pr-check, pr-reviewer, project-architect, test-runner - .claude/skills/ — 16 skills (code, commit, components, drill, review, etc.) - .claude/hooks/ — 6 pre/post hooks (boundaries, coverage, credentials, etc.) - .claude/settings.json — permissions and hook configuration New additions: - .claude/agents/feature-reviewer.md — Playwright CLI-powered feature testing agent - .claude/agents/ux-crawler.md — Playwright CLI-powered full-app UX audit agent - .gitignore updated to track .claude/ (except worktrees, plans, image-cache) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…date CLAUDE.md Removed (redundant with new Playwright agents or built-in Claude Code features): - code-simplifier agent (covered by /polish skill → also removed) - codebase-search agent (built-in Explore agent) - pr-check agent (covered by code-reviewer) - pr-reviewer agent (merged into code-reviewer) - screenshot-review skill (replaced by feature-reviewer agent) - ui-audit skill (replaced by ux-crawler agent) - polish skill (code-reviewer covers simplification) Updated: - code-reviewer: now runs tests, recommends feature-reviewer for UI changes - CLAUDE.md: added Agent Pipeline section documenting the develop→review→assess flow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…gate Cover the 800ms safety timeout in GraphChart that prevents infinite loading when onLayoutDone never fires, and the widgetIdSuffix prop in CardContainer that prevents graph store conflicts between normal and fullscreen views. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…/1.0-integration-test
…1.0-integration-test
…-integration-test
…rough The "Loading…" text placeholder was briefly visible behind the rendered chart in the fullscreen dialog. Replace with a subtle spinner that doesn't compete visually with the chart content. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- user-sim-admin: power user session (dashboards, connections, users, settings, dark mode) - user-sim-creator: first-time user onboarding (learnability, guidance gaps, confusion points) Both produce structured UX friction reports with screenshots, severity ratings, and improvement suggestions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two agent personas tested the live app via Playwright CLI: - Admin power user (Alex): full feature session, 55 screenshots - First-time creator (Jordan): onboarding experience, 58 steps Combined findings: 5 P0 issues, 6 P1 issues, 7 P2 issues, 3 P3 items. Key gaps: login page context, sign-up loop, query persistence on connection switch, connection edit blank fields, missing onboarding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…342, #343) - #329: Double-click widget in edit mode opens editor modal - #330: Query preview auto-runs 800ms after query text changes - #331: Remove column mapping overlay from dashboard cards (keep in widget editor only) — reduces visual clutter in edit mode - #341: Style tab resets when chart type changes via resetKey prop - #342: Transform tab empty state shows descriptions for each transform type (filter, sort, groupBy, calculatedColumn, limit) - #343: Query templates dropdown (Top N, Time series, Full scan, Relationships) adapts to connection type (Cypher vs SQL) Closes #329 Closes #330 Closes #331 Closes #341 Closes #342 Closes #343 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WalkthroughDashboard and widget-editor behavior changes: double-click opens widget editor, dashboard no longer forwards widget-settings change handler, widget editor auto-previews queries with debounced logic and templates, ChartSettingsPanel gains a Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DashboardContainer
participant CardContainer
participant WidgetEditorModal
User->>DashboardContainer: double-click widget
DashboardContainer->>CardContainer: delegate dblclick
CardContainer->>WidgetEditorModal: open editor (widget)
WidgetEditorModal-->>User: show editor modal
sequenceDiagram
participant User
participant WidgetEditorModal
participant PreviewScheduler
participant QueryRunner
participant ChartRenderer
User->>WidgetEditorModal: types/changes query
WidgetEditorModal->>PreviewScheduler: schedule preview (debounced)
PreviewScheduler-->>QueryRunner: run preview (after debounce)
QueryRunner-->>ChartRenderer: return preview data
ChartRenderer-->>WidgetEditorModal: render preview
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
app/src/components/dashboard-container.tsx (1)
60-63: Consider removing unusedonWidgetSettingsChangefrom the interface.With the column-mapping overlay removed from dashboard cards (
#331),onWidgetSettingsChangeis no longer destructured or forwarded toCardContainer. The interface member and call-site callback are now dead code.♻️ Suggested cleanup
export interface WidgetActions { onRemoveWidget?: (widgetId: string) => void; onEditWidget?: (widget: DashboardWidget) => void; onDuplicateWidget?: (widgetId: string) => void; onLayoutChange?: (gridLayout: GridLayoutItem[]) => void; - onWidgetSettingsChange?: ( - widgetId: string, - settings: Record<string, unknown>, - ) => void; /** Called when a click action navigates to a different page. Optionally scrolls to a widget. */ onNavigateToPage?: (pageId: string, scrollToWidgetId?: string) => void;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/dashboard-container.tsx` around lines 60 - 63, Remove the now-unused onWidgetSettingsChange prop from the DashboardContainerProps interface and any related prop forwarding; specifically delete the onWidgetSettingsChange declaration in the dashboard-container.tsx props interface and remove any destructuring/prop passing of onWidgetSettingsChange to CardContainer (or other children) so the interface matches actual usage and eliminates dead code.app/src/components/widget-editor/query-editor-panel.tsx (1)
95-99: Fallback behavior may show SQL templates for non-SQL connectors.The
getTemplatesfunction falls back to SQL templates for any connector type other thanneo4jorpostgresql. If other connectors (e.g., MySQL, MongoDB) are added later, they'll get SQL templates which might have wrong syntax. Consider extending the mapping or hiding templates for unsupported connectors.This isn't a bug for current connectors but worth noting for future-proofing.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/widget-editor/query-editor-panel.tsx` around lines 95 - 99, getTemplates currently maps lang to a key and then falls back to QUERY_TEMPLATES.sql, which will incorrectly serve SQL templates for non-SQL connectors; update getTemplates (and its key mapping logic) to either extend the mapping to include other connector keys in QUERY_TEMPLATES or change the fallback to return an empty array for unsupported connectors (i.e., remove the "?? QUERY_TEMPLATES.sql" fallback), so that QUERY_TEMPLATES[key] is used when present and unsupported lang values return [] (or add a clear whitelist of supported keys) to avoid showing wrong templates.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/components/widget-editor/transform-editor.tsx`:
- Around line 465-481: The empty-state help text in transform-editor.tsx is
missing the "Rename Columns" transform listed in TRANSFORM_TYPES; update the
unordered list in the empty-state JSX (the <ul> showing Filter, Sort, Group By,
Calculated Column, Limit) to include a new list item for "Rename Columns" so the
UI matches the TRANSFORM_TYPES constant and informs users of the renameColumns
option.
---
Nitpick comments:
In `@app/src/components/dashboard-container.tsx`:
- Around line 60-63: Remove the now-unused onWidgetSettingsChange prop from the
DashboardContainerProps interface and any related prop forwarding; specifically
delete the onWidgetSettingsChange declaration in the dashboard-container.tsx
props interface and remove any destructuring/prop passing of
onWidgetSettingsChange to CardContainer (or other children) so the interface
matches actual usage and eliminates dead code.
In `@app/src/components/widget-editor/query-editor-panel.tsx`:
- Around line 95-99: getTemplates currently maps lang to a key and then falls
back to QUERY_TEMPLATES.sql, which will incorrectly serve SQL templates for
non-SQL connectors; update getTemplates (and its key mapping logic) to either
extend the mapping to include other connector keys in QUERY_TEMPLATES or change
the fallback to return an empty array for unsupported connectors (i.e., remove
the "?? QUERY_TEMPLATES.sql" fallback), so that QUERY_TEMPLATES[key] is used
when present and unsupported lang values return [] (or add a clear whitelist of
supported keys) to avoid showing wrong templates.
🪄 Autofix (Beta)
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5338a5e2-31af-4e64-acd3-76bf15ad27cb
📒 Files selected for processing (6)
app/e2e/charts.spec.tsapp/src/components/dashboard-container.tsxapp/src/components/widget-editor-modal.tsxapp/src/components/widget-editor/query-editor-panel.tsxapp/src/components/widget-editor/transform-editor.tsxcomponent/src/components/composed/chart-settings-panel.tsx
| <ul className="list-disc pl-4 space-y-0.5"> | ||
| <li> | ||
| <strong>Filter</strong> — keep rows matching a condition | ||
| </li> | ||
| <li> | ||
| <strong>Sort</strong> — order rows by a column | ||
| </li> | ||
| <li> | ||
| <strong>Group By</strong> — aggregate rows (sum, count, avg) | ||
| </li> | ||
| <li> | ||
| <strong>Calculated Column</strong> — add a computed column | ||
| </li> | ||
| <li> | ||
| <strong>Limit</strong> — cap the number of rows shown | ||
| </li> | ||
| </ul> |
There was a problem hiding this comment.
Missing "Rename Columns" transform in help text.
The TRANSFORM_TYPES constant (line 35) includes renameColumns, but the empty-state help text omits it. Consider adding it for completeness:
<li>
<strong>Limit</strong> — cap the number of rows shown
</li>
+ <li>
+ <strong>Rename Columns</strong> — change column names in output
+ </li>
</ul>📝 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.
| <ul className="list-disc pl-4 space-y-0.5"> | |
| <li> | |
| <strong>Filter</strong> — keep rows matching a condition | |
| </li> | |
| <li> | |
| <strong>Sort</strong> — order rows by a column | |
| </li> | |
| <li> | |
| <strong>Group By</strong> — aggregate rows (sum, count, avg) | |
| </li> | |
| <li> | |
| <strong>Calculated Column</strong> — add a computed column | |
| </li> | |
| <li> | |
| <strong>Limit</strong> — cap the number of rows shown | |
| </li> | |
| </ul> | |
| <ul className="list-disc pl-4 space-y-0.5"> | |
| <li> | |
| <strong>Filter</strong> — keep rows matching a condition | |
| </li> | |
| <li> | |
| <strong>Sort</strong> — order rows by a column | |
| </li> | |
| <li> | |
| <strong>Group By</strong> — aggregate rows (sum, count, avg) | |
| </li> | |
| <li> | |
| <strong>Calculated Column</strong> — add a computed column | |
| </li> | |
| <li> | |
| <strong>Limit</strong> — cap the number of rows shown | |
| </li> | |
| <li> | |
| <strong>Rename Columns</strong> — change column names in output | |
| </li> | |
| </ul> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/components/widget-editor/transform-editor.tsx` around lines 465 -
481, The empty-state help text in transform-editor.tsx is missing the "Rename
Columns" transform listed in TRANSFORM_TYPES; update the unordered list in the
empty-state JSX (the <ul> showing Filter, Sort, Group By, Calculated Column,
Limit) to include a new list item for "Rename Columns" so the UI matches the
TRANSFORM_TYPES constant and informs users of the renameColumns option.
- api-keys.spec.ts: navigate to API Keys tab after Settings (sidebar now defaults to Profile tab) - connections.spec.ts: use seeded error connection instead of creating one, scope alert locator to card wrapper to avoid matching toast alerts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- QueryEditorPanel: test templates dropdown visibility, language mapping (neo4j->cypher, postgresql->sql, unknown->fallback), template click setting query, query hints for chart types, refresh schema button - DashboardContainer: test double-click to edit widget, verify it only fires when editable=true AND onEditWidget is provided, multi-widget targeting, empty state - QUERY_HINTS: verify all chart types have hints with examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
There was a problem hiding this comment.
Actionable comments posted: 20
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/components/card-container.tsx (1)
332-336:⚠️ Potential issue | 🟠 MajorChartRenderer SSR handling is correct, but fix ECharts imports in chart implementations.
ChartRenderer properly uses
next/dynamicwithssr: falsefor all chart components. However, the chart implementations incomponent/src/charts/violate the guideline by usingimport * as echarts from "echarts/core". Replace with specific named imports: import only the required modules (e.g.,{ init }fromecharts/core, specific chart types fromecharts/charts, etc.) to avoid bundling unused chart functionality.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/card-container.tsx` around lines 332 - 336, Several chart implementation files under component/src/charts/ use a wildcard import (import * as echarts from "echarts/core"); replace those with tree-shakable named imports: import { init } from "echarts/core" (and other specific APIs you call), import only the chart types you use from "echarts/charts" (e.g., LineChart, BarChart), import needed components from "echarts/components" (e.g., TitleComponent, TooltipComponent), and import the renderer you use from "echarts/renderers" (e.g., CanvasRenderer). Update call sites so uses like echarts.init(...) become init(...), and ensure any registration calls use the named symbols you imported; do this for all files in component/src/charts/ that currently import * as echarts from "echarts/core".
🧹 Nitpick comments (14)
.claude/skills/release-plan/SKILL.md (1)
49-51: Make milestone creation idempotent to avoid duplicate milestones.This command always creates a new milestone; reruns can duplicate
v0.1/v0.2and break issue assignment consistency.Suggested update
-```bash -gh api repos/{owner}/{repo}/milestones -f title='v0.1 — Core Foundation' -f description='...' -``` +```bash +# Create milestone only if it doesn't already exist +MILESTONE_TITLE='v0.1 — Core Foundation' +EXISTING_NUMBER=$(gh api "repos/{owner}/{repo}/milestones?state=all" \ + --jq ".[] | select(.title == \"$MILESTONE_TITLE\") | .number" | head -n1) + +if [ -z "$EXISTING_NUMBER" ]; then + gh api repos/{owner}/{repo}/milestones \ + -f title="$MILESTONE_TITLE" \ + -f description='...' +fi +```🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/release-plan/SKILL.md around lines 49 - 51, The milestone creation command is not idempotent; change the snippet to first set MILESTONE_TITLE, query existing milestones (e.g., via gh api repos/{owner}/{repo}/milestones?state=all and capture a matching .number into EXISTING_NUMBER), and only call gh api repos/{owner}/{repo}/milestones to create the milestone if EXISTING_NUMBER is empty; preserve the original title/description values and ensure the conditional prevents duplicate milestones on reruns.component/src/components/composed/__tests__/dashboard-mini-preview.test.tsx (1)
79-90: Consider extracting a sharedthumbnailWidgetfixture.The same thumbnail widget object is repeated across multiple tests; a shared constant/helper would reduce churn when the fixture shape changes.
♻️ Optional cleanup
+const thumbnailWidget: MiniPreviewWidget = { + x: 0, + y: 0, + w: 6, + h: 2, + chartType: "bar", + thumbnailUrl: "data:image/jpeg;base64,abc", +}; - widgets={[{ x: 0, y: 0, w: 6, h: 2, chartType: "bar", thumbnailUrl: "data:image/jpeg;base64,abc" }]} + widgets={[thumbnailWidget]}Also applies to: 103-111, 125-132, 144-151
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@component/src/components/composed/__tests__/dashboard-mini-preview.test.tsx` around lines 79 - 90, Extract a shared fixture object for the repeated thumbnail widget and use it across tests; create a constant (e.g., thumbnailWidget) containing the widget shape (x, y, w, h, chartType, thumbnailUrl) and replace the inline widget literals used in the DashboardMiniPreview tests (the widget arrays in the "renders <img> when thumbnailUrl is present" test and the other tests around lines referenced) with references to that constant so future shape changes require updating only the single fixture..claude/skills/harden/SKILL.md (1)
46-50: Minor style nit: repeated sentence beginnings and missing hyphen.Consider varying the bullet structure to avoid three consecutive "Long" beginnings, and use "Long-form values" (hyphenated) for grammatical correctness.
### 4. Text Overflow & Layout - **Long dashboard names**: 100+ character title — truncated with ellipsis? -- **Long connector names**: Overflow in sidebar, connection cards, dropdowns? -- **Long query text**: In widget header subtitle, tooltips? -- **Long form values**: In field-picker selections, parameter display? +- **Connector name overflow**: Sidebar, connection cards, dropdowns? +- **Query text overflow**: Widget header subtitle, tooltips? +- **Long-form values**: Field-picker selections, parameter display?🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/harden/SKILL.md around lines 46 - 50, Edit the listed bullets so they don't all start with the word "Long" and correct the hyphenation for "Long-form values": update the bullet text items "Long dashboard names", "Long connector names", "Long query text", "Long form values", and "Narrow viewports" to use varied sentence openings (e.g., "Dashboard names exceeding 100 characters", "Connector names that overflow", "Query text in widget headers", "Long-form values in field-picker selections") and replace "Long form values" with the hyphenated "Long-form values" wherever it appears (locate the exact bullet strings such as "Long dashboard names" and "Long form values" to change).app/e2e/connections.spec.ts (1)
167-172: Usedata-testidselector instead of fragile CSS class selector.The selector
[class*='cursor-pointer']depends on CSS implementation and will break if Tailwind classes change. NeoBoard E2E tests consistently usedata-testidselectors (as seen throughoutcharts.spec.ts). Adddata-testid="connection-card"to theConnectionCardcomponent and update the selector:Suggested diff
- const firstCard = page.locator("[class*='cursor-pointer']").first(); + const firstCard = page.getByTestId("connection-card").first();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/e2e/connections.spec.ts` around lines 167 - 172, The test uses a fragile CSS selector; add a stable data-testid to the ConnectionCard component (add data-testid="connection-card" on the component's root/top-level element inside the ConnectionCard render function) and update the test in connections.spec.ts to select the card via page.locator('[data-testid="connection-card"]').first() (replace the current [class*="cursor-pointer"] locator and keep the subsequent expect call for the "Error" text). Ensure the attribute name exactly matches "connection-card" so other E2E tests can reuse it..claude/skills/pr/SKILL.md (2)
17-17: Rebase operation rewrites history.The
git rebase origin/devcommand is destructive and will rewrite local commit history. While this is standard PR workflow practice, consider documenting that users should ensure their work is backed up or they're comfortable with rebase before running pre-flight.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/pr/SKILL.md at line 17, The documented pre-flight step using the command `git fetch origin && git rebase origin/dev` can rewrite local commit history; update the SKILL.md line containing that command to warn users that rebase is destructive, advise they should back up or be comfortable with rebasing before running it, and optionally suggest alternatives (e.g., use `git pull --rebase` cautiously or `git merge origin/dev`) so readers know safer options.
6-6: Wildcard tool permissions match repository patterns but consider more granular alternatives.The
allowed-toolspattern (gh *,git *,npm *) is consistent with other skills in this repository (e.g.,code,next,fix-pr-reviews). However, some skills use more specific permissions—for example,plan/SKILL.mdrestricts togit log *rather than all git subcommands, andprioritize/SKILL.mdlimits togh issue *andgh api *. Consider whether this PR skill needs the full breadth of these commands, or if more granular permissions (e.g.,Bash(gh pr *),Bash(git push),Bash(npm install *)) would better align with its actual needs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/skills/pr/SKILL.md at line 6, The allowed-tools entry currently uses broad wildcards ("Bash(gh *)", "Bash(git *)", "Bash(npm *)"); narrow these to the exact subcommands the PR skill uses (e.g., replace "Bash(gh *)" with "Bash(gh pr *)" or "Bash(gh issue *)" as appropriate, restrict "Bash(git *)" to only needed commands like "Bash(git push)" or "Bash(git log *)", and limit "Bash(npm *)" to "Bash(npm install *)" if only install is required) so the permission list is least-privilege while keeping the same behavior for functions that call the gh/git/npm commands referenced in this SKILL.md..claude/hooks/format-and-lint.sh (1)
20-26: Inconsistent path usage for eslint.Line 21 correctly uses the relative path
${REL_PATH#app/}, but lines 23 and 25 pass the absolute$FILE_PATHto eslint. This works but is inconsistent.Proposed fix for consistency
if [[ "$REL_PATH" == app/* ]]; then cd "$PROJECT_DIR/app" && npx next lint --fix --file "${REL_PATH#app/}" 2>/dev/null || true elif [[ "$REL_PATH" == component/* ]]; then - cd "$PROJECT_DIR/component" && npx eslint --fix "$FILE_PATH" 2>/dev/null || true + cd "$PROJECT_DIR/component" && npx eslint --fix "${REL_PATH#component/}" 2>/dev/null || true elif [[ "$REL_PATH" == connection/* ]]; then - cd "$PROJECT_DIR/connection" && npx eslint --fix "$FILE_PATH" 2>/dev/null || true + cd "$PROJECT_DIR/connection" && npx eslint --fix "${REL_PATH#connection/}" 2>/dev/null || true fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks/format-and-lint.sh around lines 20 - 26, The script uses ${REL_PATH#app/} for the app branch but passes absolute $FILE_PATH for component and connection, causing inconsistent path usage; update the component and connection branches to pass the relative paths by replacing $FILE_PATH with ${REL_PATH#component/} in the component branch and ${REL_PATH#connection/} in the connection branch (within the if/elif blocks that call npx eslint) so all branches consistently use REL_PATH-derived relative file paths..claude/hooks/session-context.sh (2)
45-55: Prefer direct exit-code check over$?.Per Shellcheck SC2181, checking the exit code directly is cleaner and less error-prone.
Proposed fix
-PR_INFO=$(gh pr view --json number,title,state,url 2>/dev/null) -if [ $? -eq 0 ] && [ -n "$PR_INFO" ]; then +if PR_INFO=$(gh pr view --json number,title,state,url 2>/dev/null) && [ -n "$PR_INFO" ]; then PR_NUM=$(echo "$PR_INFO" | jq -r '.number')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks/session-context.sh around lines 45 - 55, Replace the separate "$?" check by testing the command substitution directly: capture PR_INFO with PR_INFO=$(gh pr view --json number,title,state,url 2>/dev/null) and use a combined conditional if PR_INFO assignment succeeds and PR_INFO is non-empty (e.g., if PR_INFO=$(gh pr view ... 2>/dev/null) && [ -n "$PR_INFO" ]; then) so the script checks the exit status of gh pr view and the content of PR_INFO in one step; update the if that currently references $? to use this direct check around the PR_INFO variable instead.
57-61: Variable name mismatch:NEOBOARD_PROJECT_DIRwritten butCLAUDE_PROJECT_DIRread elsewhere.This hook writes
NEOBOARD_PROJECT_DIRto the env file, butformat-and-lint.shandenforce-e2e.shreadCLAUDE_PROJECT_DIR. The cached value won't be reused. IfCLAUDE_PROJECT_DIRis Claude-provided, this is fine (git fallback works), but worth noting for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks/session-context.sh around lines 57 - 61, The hook currently writes NEOBOARD_PROJECT_DIR into the env file but other hooks (format-and-lint.sh, enforce-e2e.sh) read CLAUDE_PROJECT_DIR, causing a mismatch; update the .claude/hooks/session-context.sh logic to write CLAUDE_PROJECT_DIR instead of NEOBOARD_PROJECT_DIR (or write both keys for backward compatibility), i.e., replace the echo that outputs "NEOBOARD_PROJECT_DIR=$PROJECT_DIR" with one that outputs "CLAUDE_PROJECT_DIR=$PROJECT_DIR" (and optionally keep/also add NEOBOARD_PROJECT_DIR) so the downstream readers find the expected variable..claude/agents/ux-crawler.md (1)
151-151: Optional: Add language specifier to fenced code block.The report template code block at line 151 lacks a language identifier. Consider adding
markdownortextto silence the MD040 linter warning.-``` +```markdown ## NeoBoard UX Audit ReportBased on learnings, markdownlint warnings in internal reference documents under
.claude/are typically accepted as-is, so this is purely optional.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/agents/ux-crawler.md at line 151, The fenced code block starting before the "## NeoBoard UX Audit Report" heading lacks a language specifier; update the opening fence from ``` to a language-tagged fence such as ```markdown (or ```text) so the block that contains "## NeoBoard UX Audit Report" is annotated and the MD040 linter warning is silenced..claude/agents/feature-reviewer.md (1)
104-104: Optional: Add language specifier to fenced code block.Same as in
ux-crawler.md— the report template block lacks a language identifier. Addmarkdownto silence MD040.-``` +```markdown ## Feature Review: [Feature Name]Based on learnings, markdownlint warnings in internal reference documents are intentionally accepted as-is.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/agents/feature-reviewer.md at line 104, Update the fenced code block in the Feature Review template by adding the Markdown language specifier; locate the triple-backtick code fence that opens the report template (the block starting with "```") in feature-reviewer.md and change it to "```markdown" so the block begins with ```markdown followed by "## Feature Review: [Feature Name]" to silence the MD040 warning..claude/hooks/check-credential-logging.sh (1)
25-28: Minor: Potential false positives from comments or string literals.The grep chain checks if any line containing
console.(log|warn|error|debug|info)also contains a credential-related identifier anywhere on that line. This could flag benign cases like:console.log("Enter your password below"); // triggers on "password" console.log(user.name); // hasPassword check <- triggers if line has "password" in commentConsider using a more targeted regex that matches identifier usage in the argument list, or accept this as an intentional strictness trade-off.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.claude/hooks/check-credential-logging.sh around lines 25 - 28, The current grep chain on NEW_CONTENT with CRED_PATTERN can produce false positives from comments or string literals; update the check to either preprocess NEW_CONTENT to remove/ignore JS/TS comments and quoted strings before grepping, or tighten the regex to match console\.(log|warn|error|debug|info)\s*\([^)]*\b${CRED_PATTERN}\b[^)]*\) so the credential token is matched as an identifier inside the call arguments (use word boundaries) rather than anywhere on the line; apply this change where NEW_CONTENT and CRED_PATTERN are used in the grep chain to reduce false positives.app/src/components/__tests__/dashboard-container-dblclick.test.tsx (1)
213-224: Consider adding an explicit assertion.The test relies on "no error means the handler was properly set to undefined." While valid, an explicit assertion would make the test more self-documenting:
// Should not throw — onDoubleClick is undefined so nothing happens await user.dblClick(widgetDiv); - // No error means the handler was properly set to undefined + // Verify no error occurred and component still renders + expect(widgetDiv).toBeInTheDocument();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/__tests__/dashboard-container-dblclick.test.tsx` around lines 213 - 224, The test "does NOT call onEditWidget on double-click when onEditWidget is not provided" relies on absence of errors but should assert explicitly that the dblClick action doesn't throw; replace the bare await user.dblClick(widgetDiv) with an explicit assertion such as awaiting expect(user.dblClick(widgetDiv)).resolves.not.toThrow() (referencing the user.dblClick call and the widgetDiv element in the DashboardContainer test) so the test is self-documenting and fails if the handler unexpectedly throws.app/src/components/widget-editor/query-editor-panel.tsx (1)
63-95: Use the shared query-template helper instead of maintaining a second copy.
app/src/lib/query-templates.tsalready defines these templates and the same resolver logic. Keeping another copy here lets the editor UI drift from the shared helper and its tests. Import the shared module and delete this local duplicate.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/widget-editor/query-editor-panel.tsx` around lines 63 - 95, Replace the duplicated local constant QUERY_TEMPLATES with the shared helper from the library: delete the local const QUERY_TEMPLATES and import the shared query-templates helper (e.g., getQueryTemplates or exported QUERY_TEMPLATES) from lib/query-templates, then update any code that referenced QUERY_TEMPLATES[...] to call the shared helper (for example getQueryTemplates(language) or using the imported QUERY_TEMPLATES) so the editor uses the single canonical source.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/agents/code-reviewer.md:
- Around line 14-15: Current diff collection only runs "git diff" and "git diff
--cached" and therefore misses committed PR branch changes; update the
diff-gathering logic (where you assemble diffs for PR review) to first generate
a PR diff between HEAD and the target branch/merge base using "git merge-base"
and "git diff $(git merge-base HEAD <target_branch>)..HEAD" (or equivalent), and
then fall back to the existing working-tree diffs ("git diff" and "git diff
--cached") for pre-push/local use; ensure the new PR-path is used when a target
branch/merge-base is available and retain the original commands as a fallback.
- Around line 17-18: The workflow runs Vitest but never actually runs the
repository type-check, yet the output includes a "Type check: PASS/FAIL" result;
update the workflow step (near the Vitest steps that run `npx vitest run`) to
execute the repo's type-check command (for example add a step that runs your
project's type-check script such as `npm run type-check` or `pnpm -w run
typecheck`) and only set the "Type check" output after that step completes, or
alternatively remove the "Type check: PASS/FAIL" output entirely so the workflow
does not report a status it didn't collect.
In @.claude/agents/user-sim-admin.md:
- Line 36: Remove the hardcoded admin credentials string ("Login as admin:
`admin@neoboard.local` / `admin123`") from .claude/agents/user-sim-admin.md and
replace it with a non-secret placeholder or reference to a secret source (e.g.,
mention ADMIN_EMAIL and ADMIN_PASSWORD or instructions to retrieve from a
secrets manager/CI variable). Update the prompt text to instruct maintainers to
populate those placeholders from environment variables or a secure vault and add
a short note explaining where to set the real credentials (no actual secrets in
the repo).
In @.claude/agents/user-sim-creator.md:
- Line 36: The file contains hardcoded creator credentials ("bob@example.com" /
"password123") in the user-sim-creator.md instruction; replace that literal with
env-backed placeholders and update any test fixtures or docs to read from
environment variables (e.g., CREATOR_EMAIL, CREATOR_PASSWORD) or a secure test
fixture loader rather than committing secrets; update references to the login
example in user-sim-creator.md and any test harness that uses the string so they
pull values from the environment/fixtures (and rotate/remove the real
credentials from the repo/history if they were ever live).
- Around line 19-31: The docs include an invalid command "resize 1280 720" for
`@playwright/cli` and duplicate/conflicting command lists across
.claude/agents/user-sim-creator.md, .claude/agents/user-sim-admin.md,
.claude/agents/ux-crawler.md and .claude/agents/feature-reviewer.md; remove all
occurrences of the unsupported "resize" command and consolidate the four files
to a single authoritative command reference that only lists supported
`@playwright/cli` commands (e.g., open, goto, click, fill, screenshot, snapshot,
console, network, etc.), and add a note to use viewport configuration via
.playwright/cli.config.json or the Playwright API instead of a "resize" CLI
command to set viewport size.
In @.claude/hooks/enforce-e2e.sh:
- Around line 42-47: The hook currently removes the .e2e-needed marker based
only on the command text in the clear-on-test block; change it so the hook
actually runs the captured CMD and checks its exit status before deleting
MARKER: in the clear-on-test branch (where CMD is set) execute CMD (or spawn it)
and only if its exit code is 0 then remove MARKER; otherwise leave the file and
propagate a non-zero exit (do not remove MARKER). Ensure you reference the CMD
variable and MARKER in your change and preserve existing input parsing logic.
- Around line 17-23: The case pattern only matches paths with a leading slash so
repo-relative paths like "app/src/..." are skipped; update the case arms that
reference FILE_PATH and MARKER (the lines matching
"*/app/src/components/*|*/app/src/app/*") to also include the repo-relative
forms (e.g., add "app/src/components/*" and "app/src/app/*" alternatives or make
the leading slash optional) so both absolute and relative tool_input.file_path
values will hit the touch "$MARKER" and append logic.
In @.claude/hooks/format-and-lint.sh:
- Line 18: The parameter expansion REL_PATH="${FILE_PATH#$PROJECT_DIR/}" can
misinterpret glob characters in PROJECT_DIR; update the expansion to quote the
pattern so the shell treats PROJECT_DIR literally (i.e., use
REL_PATH="${FILE_PATH#${PROJECT_DIR}/}" with PROJECT_DIR quoted in the
expansion) to prevent globbing when computing REL_PATH from FILE_PATH and
PROJECT_DIR.
In @.claude/hooks/session-context.sh:
- Line 7: The script currently runs cd "$PROJECT_DIR" without checking success,
so subsequent git commands may run in the wrong directory; update
session-context.sh to validate the directory change by checking the exit status
of cd (or use a conditional/guard) and bail out with a clear error message if cd
"$PROJECT_DIR" fails (e.g., use cd "$PROJECT_DIR" || { echo "Failed to change to
PROJECT_DIR: $PROJECT_DIR"; exit 1; }) so that later commands only run when the
working directory is correct.
In @.claude/skills/commit/SKILL.md:
- Line 5: The allowlist line currently permits all git commands via
"allowed-tools: Bash(git *)", which allows destructive operations like git push;
update that line to only permit safe, non-mutating git commands (for example
list explicit commands such as git status, git log, git diff, git rev-parse, git
show) and—if commit actions are required—explicitly include only git commit (and
not push) or alternatively keep the wildcard but add an explicit exclusion for
push; locate the "allowed-tools: Bash(git *)" entry and replace it with an
explicit, restricted command list (or add a deny for push) to enforce the Do NOT
push safety rule.
In @.claude/skills/design-review/skill.md:
- Around line 88-97: The CSS custom property declarations for the chart colors
(e.g., --chart-1, --chart-2, ... --chart-10) are written on shared lines and
lack semicolons; split each custom property into its own line, terminate each
with a semicolon, and keep the inline comments (e.g., /* Blue */) next to the
corresponding property so the group of declarations parses correctly.
In @.claude/skills/fix-pr-reviews/SKILL.md:
- Around line 73-75: Update the policy text that currently instructs "For
CodeRabbit suggestions that include a diff/code block, apply the provided change
directly." to require explicit rule/context validation before applying any
suggested patch: replace the unconditional "apply the provided change directly"
behavior with a step that mandates reviewing the suggested diff, verifying its
context, running tests or static checks, and obtaining a human approval before
merge; also adjust the SonarCloud line ("For SonarCloud issues, fix at the
reported file:line per the rule description.") to clarify it is only an
instruction when the fix has been validated and reviewed, ensuring both the
"Apply bot diff directly" phrase and the SonarCloud instruction are updated to
enforce validation and prevent blind auto-application of diffs.
- Line 5: The allowed-tools list grants overly broad git privileges via
"Bash(git *)"; update that entry to least-privilege, read/apply/status-only git
commands by replacing "Bash(git *)" with a constrained set (for example
"Bash(git status)", "Bash(git diff)", "Bash(git apply)", "Bash(git checkout)" or
a minimal subset your policy allows) in the allowed-tools line so the skill can
only perform harmless review/apply operations; modify the same "allowed-tools"
line in SKILL.md where "Bash(git *)" appears.
- Around line 81-84: Phase 3 runs checks in inconsistent directories: move into
the app workspace before running all verification steps so TypeScript, linting,
and tests operate in the same scope; modify the step that currently runs "npx
tsc --noEmit" and "npm run lint" (and the test invocation) to execute from the
app directory (e.g., run a single "cd app" once and then run the commands, or
prefix each command with "cd app &&") so all checks use the same workspace and
tooling.
- Around line 40-50: The commands (e.g., gh api
repos/{owner}/{repo}/pulls/$ARGUMENTS/comments, gh pr view $ARGUMENTS --comments
--json comments, and gh api repos/{owner}/{repo}/pulls/$ARGUMENTS/reviews)
contain unresolved placeholders like {owner}, {repo}, <project-key>, and
<THREAD_NODE_ID>; update these invocations to accept real values by using shell
variables or positional parameters (e.g., OWNER, REPO, PROJECT_KEY,
THREAD_NODE_ID) or by expanding them from environment vars/arguments before
calling the gh commands, validate/escape the values, and update any
documentation or call sites so every occurrence of those placeholders is
substituted at runtime.
- Around line 28-30: The curl invocation currently exposes the secret via -u
"$SONAR_TOKEN:"; update the SKILL.md example to avoid putting SONAR_TOKEN in
argv by (a) checking/aborting early if SONAR_TOKEN is empty, and (b) replacing
-u "$SONAR_TOKEN:" with a safe alternative such as using an HTTP header (-H
"Authorization: Bearer $SONAR_TOKEN") or using curl's stdin/netrc options (e.g.,
--netrc-file or the password-stdin variant) and document each option; reference
the existing curl line and the SONAR_TOKEN variable so readers can find and
replace the insecure -u usage.
In @.claude/skills/pr/SKILL.md:
- Around line 32-42: The opening fenced code block in .claude/skills/pr/SKILL.md
lacks a language specifier causing MD040; update the triple-backtick fence to
include "markdown" (i.e., replace ``` with ```markdown) so the template block is
explicitly marked as markdown; locate the top-level fenced block containing the
"## Summary" / "## Changes" lines and change its opening fence accordingly.
In @.claude/skills/release-plan/SKILL.md:
- Line 62: The fenced code block in SKILL.md is missing a language specifier
which triggers MD040; update the opening triple-backtick to include a language
(e.g., "```md" or "```markdown") so the block becomes a language-tagged fenced
code block; locate the code block around the Release Plan section (the fenced
block containing "# Release Plan" and the v0.1/v0.2 headings) and change the
fence token accordingly to restore proper Markdown highlighting.
In `@app/src/components/widget-editor/query-editor-panel.tsx`:
- Around line 97-100: The component normalizes languages for templates inside
getTemplates but other places (like the placeholder text rendering) still use
the raw editorLanguage, causing mismatches for "postgresql"; extract the
normalization logic into a small helper (e.g., normalizeLanguage or reuse
getTemplates' key mapping) and use that normalized value everywhere: pass it to
getTemplates and use the same normalized key when selecting placeholder text and
any other language-branching logic (replace direct checks of editorLanguage with
normalizeLanguage(editorLanguage) and use that result consistently).
In `@docs/ux-friction-report.md`:
- Around line 3-4: Update the generation metadata on the report header line that
currently reads "Generated via automated user simulation agents against the live
app (release/1.0)." — append an ISO 8601 generation timestamp and a unique code
reference (commit SHA or PR number and/or CI build id) so the line becomes
self-contained (e.g., include "generated: 2026-04-03T12:00:00Z, commit: abc1234,
PR: `#42`"); ensure the template used for future reports (the same header string)
is updated to always emit these three fields (release tag, generation date/time,
and commit/PR or build id).
---
Outside diff comments:
In `@app/src/components/card-container.tsx`:
- Around line 332-336: Several chart implementation files under
component/src/charts/ use a wildcard import (import * as echarts from
"echarts/core"); replace those with tree-shakable named imports: import { init }
from "echarts/core" (and other specific APIs you call), import only the chart
types you use from "echarts/charts" (e.g., LineChart, BarChart), import needed
components from "echarts/components" (e.g., TitleComponent, TooltipComponent),
and import the renderer you use from "echarts/renderers" (e.g., CanvasRenderer).
Update call sites so uses like echarts.init(...) become init(...), and ensure
any registration calls use the named symbols you imported; do this for all files
in component/src/charts/ that currently import * as echarts from "echarts/core".
---
Nitpick comments:
In @.claude/agents/feature-reviewer.md:
- Line 104: Update the fenced code block in the Feature Review template by
adding the Markdown language specifier; locate the triple-backtick code fence
that opens the report template (the block starting with "```") in
feature-reviewer.md and change it to "```markdown" so the block begins with
```markdown followed by "## Feature Review: [Feature Name]" to silence the MD040
warning.
In @.claude/agents/ux-crawler.md:
- Line 151: The fenced code block starting before the "## NeoBoard UX Audit
Report" heading lacks a language specifier; update the opening fence from ``` to
a language-tagged fence such as ```markdown (or ```text) so the block that
contains "## NeoBoard UX Audit Report" is annotated and the MD040 linter warning
is silenced.
In @.claude/hooks/check-credential-logging.sh:
- Around line 25-28: The current grep chain on NEW_CONTENT with CRED_PATTERN can
produce false positives from comments or string literals; update the check to
either preprocess NEW_CONTENT to remove/ignore JS/TS comments and quoted strings
before grepping, or tighten the regex to match
console\.(log|warn|error|debug|info)\s*\([^)]*\b${CRED_PATTERN}\b[^)]*\) so the
credential token is matched as an identifier inside the call arguments (use word
boundaries) rather than anywhere on the line; apply this change where
NEW_CONTENT and CRED_PATTERN are used in the grep chain to reduce false
positives.
In @.claude/hooks/format-and-lint.sh:
- Around line 20-26: The script uses ${REL_PATH#app/} for the app branch but
passes absolute $FILE_PATH for component and connection, causing inconsistent
path usage; update the component and connection branches to pass the relative
paths by replacing $FILE_PATH with ${REL_PATH#component/} in the component
branch and ${REL_PATH#connection/} in the connection branch (within the if/elif
blocks that call npx eslint) so all branches consistently use REL_PATH-derived
relative file paths.
In @.claude/hooks/session-context.sh:
- Around line 45-55: Replace the separate "$?" check by testing the command
substitution directly: capture PR_INFO with PR_INFO=$(gh pr view --json
number,title,state,url 2>/dev/null) and use a combined conditional if PR_INFO
assignment succeeds and PR_INFO is non-empty (e.g., if PR_INFO=$(gh pr view ...
2>/dev/null) && [ -n "$PR_INFO" ]; then) so the script checks the exit status of
gh pr view and the content of PR_INFO in one step; update the if that currently
references $? to use this direct check around the PR_INFO variable instead.
- Around line 57-61: The hook currently writes NEOBOARD_PROJECT_DIR into the env
file but other hooks (format-and-lint.sh, enforce-e2e.sh) read
CLAUDE_PROJECT_DIR, causing a mismatch; update the
.claude/hooks/session-context.sh logic to write CLAUDE_PROJECT_DIR instead of
NEOBOARD_PROJECT_DIR (or write both keys for backward compatibility), i.e.,
replace the echo that outputs "NEOBOARD_PROJECT_DIR=$PROJECT_DIR" with one that
outputs "CLAUDE_PROJECT_DIR=$PROJECT_DIR" (and optionally keep/also add
NEOBOARD_PROJECT_DIR) so the downstream readers find the expected variable.
In @.claude/skills/harden/SKILL.md:
- Around line 46-50: Edit the listed bullets so they don't all start with the
word "Long" and correct the hyphenation for "Long-form values": update the
bullet text items "Long dashboard names", "Long connector names", "Long query
text", "Long form values", and "Narrow viewports" to use varied sentence
openings (e.g., "Dashboard names exceeding 100 characters", "Connector names
that overflow", "Query text in widget headers", "Long-form values in
field-picker selections") and replace "Long form values" with the hyphenated
"Long-form values" wherever it appears (locate the exact bullet strings such as
"Long dashboard names" and "Long form values" to change).
In @.claude/skills/pr/SKILL.md:
- Line 17: The documented pre-flight step using the command `git fetch origin &&
git rebase origin/dev` can rewrite local commit history; update the SKILL.md
line containing that command to warn users that rebase is destructive, advise
they should back up or be comfortable with rebasing before running it, and
optionally suggest alternatives (e.g., use `git pull --rebase` cautiously or
`git merge origin/dev`) so readers know safer options.
- Line 6: The allowed-tools entry currently uses broad wildcards ("Bash(gh *)",
"Bash(git *)", "Bash(npm *)"); narrow these to the exact subcommands the PR
skill uses (e.g., replace "Bash(gh *)" with "Bash(gh pr *)" or "Bash(gh issue
*)" as appropriate, restrict "Bash(git *)" to only needed commands like
"Bash(git push)" or "Bash(git log *)", and limit "Bash(npm *)" to "Bash(npm
install *)" if only install is required) so the permission list is
least-privilege while keeping the same behavior for functions that call the
gh/git/npm commands referenced in this SKILL.md.
In @.claude/skills/release-plan/SKILL.md:
- Around line 49-51: The milestone creation command is not idempotent; change
the snippet to first set MILESTONE_TITLE, query existing milestones (e.g., via
gh api repos/{owner}/{repo}/milestones?state=all and capture a matching .number
into EXISTING_NUMBER), and only call gh api repos/{owner}/{repo}/milestones to
create the milestone if EXISTING_NUMBER is empty; preserve the original
title/description values and ensure the conditional prevents duplicate
milestones on reruns.
In `@app/e2e/connections.spec.ts`:
- Around line 167-172: The test uses a fragile CSS selector; add a stable
data-testid to the ConnectionCard component (add data-testid="connection-card"
on the component's root/top-level element inside the ConnectionCard render
function) and update the test in connections.spec.ts to select the card via
page.locator('[data-testid="connection-card"]').first() (replace the current
[class*="cursor-pointer"] locator and keep the subsequent expect call for the
"Error" text). Ensure the attribute name exactly matches "connection-card" so
other E2E tests can reuse it.
In `@app/src/components/__tests__/dashboard-container-dblclick.test.tsx`:
- Around line 213-224: The test "does NOT call onEditWidget on double-click when
onEditWidget is not provided" relies on absence of errors but should assert
explicitly that the dblClick action doesn't throw; replace the bare await
user.dblClick(widgetDiv) with an explicit assertion such as awaiting
expect(user.dblClick(widgetDiv)).resolves.not.toThrow() (referencing the
user.dblClick call and the widgetDiv element in the DashboardContainer test) so
the test is self-documenting and fails if the handler unexpectedly throws.
In `@app/src/components/widget-editor/query-editor-panel.tsx`:
- Around line 63-95: Replace the duplicated local constant QUERY_TEMPLATES with
the shared helper from the library: delete the local const QUERY_TEMPLATES and
import the shared query-templates helper (e.g., getQueryTemplates or exported
QUERY_TEMPLATES) from lib/query-templates, then update any code that referenced
QUERY_TEMPLATES[...] to call the shared helper (for example
getQueryTemplates(language) or using the imported QUERY_TEMPLATES) so the editor
uses the single canonical source.
In `@component/src/components/composed/__tests__/dashboard-mini-preview.test.tsx`:
- Around line 79-90: Extract a shared fixture object for the repeated thumbnail
widget and use it across tests; create a constant (e.g., thumbnailWidget)
containing the widget shape (x, y, w, h, chartType, thumbnailUrl) and replace
the inline widget literals used in the DashboardMiniPreview tests (the widget
arrays in the "renders <img> when thumbnailUrl is present" test and the other
tests around lines referenced) with references to that constant so future shape
changes require updating only the single fixture.
🪄 Autofix (Beta)
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 1fabd641-e520-49e3-b38c-40f03a93dcaa
📒 Files selected for processing (54)
.claude/.gitignore.claude/agents/code-reviewer.md.claude/agents/feature-reviewer.md.claude/agents/lint-fix.md.claude/agents/project-architect.md.claude/agents/test-runner.md.claude/agents/user-sim-admin.md.claude/agents/user-sim-creator.md.claude/agents/ux-crawler.md.claude/hooks/check-boundaries.sh.claude/hooks/check-coverage.sh.claude/hooks/check-credential-logging.sh.claude/hooks/check-query-safety.sh.claude/hooks/enforce-e2e.sh.claude/hooks/format-and-lint.sh.claude/hooks/session-context.sh.claude/settings.json.claude/skills/code/SKILL.md.claude/skills/commit/SKILL.md.claude/skills/components/SKILL.md.claude/skills/design-review/skill.md.claude/skills/drill/SKILL.md.claude/skills/fix-pr-reviews/SKILL.md.claude/skills/github-workflow/SKILL.md.claude/skills/harden/SKILL.md.claude/skills/issue/SKILL.md.claude/skills/next/SKILL.md.claude/skills/plan/SKILL.md.claude/skills/pr/SKILL.md.claude/skills/prioritize/SKILL.md.claude/skills/release-plan/SKILL.md.claude/skills/review/SKILL.md.claude/skills/test/SKILL.md.gitignoreCLAUDE.mdapp/e2e/api-keys.spec.tsapp/e2e/connections.spec.tsapp/src/components/__tests__/card-container-states.test.tsxapp/src/components/__tests__/card-container.test.tsxapp/src/components/__tests__/dashboard-container-dblclick.test.tsxapp/src/components/card-container.tsxapp/src/components/dashboard-container.tsxapp/src/components/widget-editor-modal.tsxapp/src/components/widget-editor/__tests__/query-editor-panel.test.tsxapp/src/components/widget-editor/__tests__/transform-editor.test.tsxapp/src/components/widget-editor/query-editor-panel.tsxapp/src/lib/query-templates.tscomponent/src/charts/__tests__/graph-chart.test.tsxcomponent/src/charts/graph-chart.tsxcomponent/src/components/composed/__tests__/chart-settings-panel.test.tsxcomponent/src/components/composed/__tests__/dashboard-mini-preview.test.tsxcomponent/src/components/composed/app-shell.tsxcomponent/src/components/composed/dashboard-mini-preview.tsxdocs/ux-friction-report.md
✅ Files skipped from review due to trivial changes (14)
- .claude/.gitignore
- component/src/components/composed/app-shell.tsx
- .gitignore
- component/src/components/composed/dashboard-mini-preview.tsx
- .claude/skills/github-workflow/SKILL.md
- .claude/agents/project-architect.md
- .claude/skills/components/SKILL.md
- .claude/agents/test-runner.md
- .claude/skills/issue/SKILL.md
- .claude/skills/review/SKILL.md
- .claude/skills/code/SKILL.md
- .claude/skills/test/SKILL.md
- .claude/skills/prioritize/SKILL.md
- .claude/skills/plan/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (1)
- app/src/components/widget-editor-modal.tsx
| 1. Run `git diff` and `git diff --cached` to get all changes. | ||
| 2. Read each changed file to understand full context. |
There was a problem hiding this comment.
PR review mode will miss committed branch changes.
git diff and git diff --cached only cover local dirty state. On a clean PR branch, this agent will inspect nothing even though the PR already has committed changes. Add a PR path that diffs HEAD against the merge base / target branch, then fall back to working-tree diffs for pre-push use.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/agents/code-reviewer.md around lines 14 - 15, Current diff
collection only runs "git diff" and "git diff --cached" and therefore misses
committed PR branch changes; update the diff-gathering logic (where you assemble
diffs for PR review) to first generate a PR diff between HEAD and the target
branch/merge base using "git merge-base" and "git diff $(git merge-base HEAD
<target_branch>)..HEAD" (or equivalent), and then fall back to the existing
working-tree diffs ("git diff" and "git diff --cached") for pre-push/local use;
ensure the new PR-path is used when a target branch/merge-base is available and
retain the original commands as a fallback.
| 4. After code review, run `cd app && npx vitest run` and `cd component && npx vitest run` to verify tests pass. | ||
| 5. If any UI files changed (`*.tsx` in pages, components, or settings), recommend running `@feature-reviewer` on the affected feature. |
There was a problem hiding this comment.
The required type-check result is never actually verified.
This workflow only runs Vitest, but the output contract still asks for Type check: PASS/FAIL. Either execute the repo’s type-check command here or remove that field; otherwise the agent is forced to report a status it did not collect.
Also applies to: 70-72
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/agents/code-reviewer.md around lines 17 - 18, The workflow runs
Vitest but never actually runs the repository type-check, yet the output
includes a "Type check: PASS/FAIL" result; update the workflow step (near the
Vitest steps that run `npx vitest run`) to execute the repo's type-check command
(for example add a step that runs your project's type-check script such as `npm
run type-check` or `pnpm -w run typecheck`) and only set the "Type check" output
after that step completes, or alternatively remove the "Type check: PASS/FAIL"
output entirely so the workflow does not report a status it didn't collect.
|
|
||
| ## Your Session | ||
|
|
||
| Login as admin: `admin@neoboard.local` / `admin123` |
There was a problem hiding this comment.
Remove hardcoded admin credentials from the agent prompt.
Line 36 embeds credentials directly in versioned config. Even if test-only, this normalizes secret-in-repo patterns and increases accidental reuse risk.
🔐 Suggested patch
-Login as admin: `admin@neoboard.local` / `admin123`
+Login as admin using seeded test credentials from your local `.env`/test fixture.
+Example:
+- `NEOBOARD_E2E_ADMIN_EMAIL`
+- `NEOBOARD_E2E_ADMIN_PASSWORD`📝 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.
| Login as admin: `admin@neoboard.local` / `admin123` | |
| Login as admin using seeded test credentials from your local `.env`/test fixture. | |
| Example: | |
| - `NEOBOARD_E2E_ADMIN_EMAIL` | |
| - `NEOBOARD_E2E_ADMIN_PASSWORD` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/agents/user-sim-admin.md at line 36, Remove the hardcoded admin
credentials string ("Login as admin: `admin@neoboard.local` / `admin123`") from
.claude/agents/user-sim-admin.md and replace it with a non-secret placeholder or
reference to a secret source (e.g., mention ADMIN_EMAIL and ADMIN_PASSWORD or
instructions to retrieve from a secrets manager/CI variable). Update the prompt
text to instruct maintainers to populate those placeholders from environment
variables or a secure vault and add a short note explaining where to set the
real credentials (no actual secrets in the repo).
| Use ONLY `npx @playwright/cli` commands via Bash. Do NOT use MCP tools. | ||
|
|
||
| ```bash | ||
| npx @playwright/cli open <url> | ||
| npx @playwright/cli goto <url> | ||
| npx @playwright/cli click '<selector>' | ||
| npx @playwright/cli fill '<selector>' '<text>' | ||
| npx @playwright/cli type '<text>' | ||
| npx @playwright/cli select '<selector>' '<value>' | ||
| npx @playwright/cli screenshot | ||
| npx @playwright/cli snapshot | ||
| npx @playwright/cli console | ||
| npx @playwright/cli resize 1280 720 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
npm view `@playwright/cli` name version bin dist-tags.latest || true
npm view playwright name version bin dist-tags.latestRepository: alfredo1996/neoboard
Length of output: 279
🌐 Web query:
@playwright/cli npm package documentation commands
💡 Result:
The @playwright/cli npm package provides playwright-cli, a command-line interface for browser automation designed for coding agents like Claude Code or GitHub Copilot. It offers token-efficient control via concise commands and installable skills. This is distinct from the standard Playwright CLI (npx playwright) used for running tests. Installation: npm install -g @playwright/cli@latest or npx playwright-cli --help (local) Key commands (from official docs and repo): Core: playwright-cli open [url] # open browser, optionally navigate to url playwright-cli close # close the page/browser playwright-cli goto # navigate to a url playwright-cli type # type text into editable element playwright-cli click [button] # click element by ref (e.g. e15 from snapshot) playwright-cli dblclick # double click playwright-cli fill # fill input playwright-cli check # check checkbox playwright-cli select # select dropdown option playwright-cli press # press key (e.g. Enter) playwright-cli drag # drag and drop playwright-cli upload # upload file playwright-cli go-back # navigate back playwright-cli reload # reload page Page state: playwright-cli snapshot # capture YAML snapshot with element refs (e.g. e1, t1 for text) playwright-cli screenshot # take screenshot DevTools/Network: playwright-cli eval [ref] # evaluate JS playwright-cli console [level] # console messages playwright-cli network # network requests playwright-cli tracing-start/stop # trace recording playwright-cli video-start/stop # video recording playwright-cli route # mock network Management: playwright-cli show # dashboard for sessions playwright-cli kill-all # kill all processes playwright-cli install --skills # install skills for agents Options: --headed, --browser=chrome/firefox/webkit, --config=file.json, -s=name (session) After commands, it outputs page snapshot with URL, title, elements for refs. Configuration: .playwright/cli.config.json for browser, context, etc. Repo: https://github.com/microsoft/playwright-cli (latest 0.1.4 as of Apr 2026). For full/up-to-date list: playwright-cli --help
Citations:
- 1: https://www.npmjs.com/package/@playwright/cli
- 2: https://registry.npmjs.org/%40playwright%2Fcli
- 3: https://playwright.dev/docs/getting-started-cli
- 4: https://github.com/microsoft/playwright-cli
🏁 Script executed:
#!/bin/bash
# Find other files referencing `@playwright/cli`
rg '@playwright/cli' --type md --type js --type json -lRepository: alfredo1996/neoboard
Length of output: 46
🏁 Script executed:
#!/bin/bash
# Find files in .claude/agents directory
find .claude/agents -type f -name "*.md" 2>/dev/null | head -20Repository: alfredo1996/neoboard
Length of output: 320
🏁 Script executed:
#!/bin/bash
# Search for mentions of `@playwright/cli` or npx playwright in markdown files
rg 'playwright.*cli|npx.*playwright' --type markdownRepository: alfredo1996/neoboard
Length of output: 46
🏁 Script executed:
#!/bin/bash
# Broader search for playwright mentions
rg 'playwright' .claude/agents/ -lRepository: alfredo1996/neoboard
Length of output: 225
🏁 Script executed:
#!/bin/bash
# Check user-sim-admin.md specifically
cat .claude/agents/user-sim-admin.md | grep -A 15 'playwright\|npx' || trueRepository: alfredo1996/neoboard
Length of output: 1079
🏁 Script executed:
#!/bin/bash
# Check all agent files for resize command
rg 'resize' .claude/agents/Repository: alfredo1996/neoboard
Length of output: 368
🏁 Script executed:
#!/bin/bash
# Check ux-crawler.md and others for playwright commands
for file in .claude/agents/ux-crawler.md .claude/agents/test-runner.md .claude/agents/feature-reviewer.md; do
echo "=== $file ==="
grep -A 12 '@playwright/cli' "$file" 2>/dev/null | head -20 || echo "No match"
doneRepository: alfredo1996/neoboard
Length of output: 2037
resize 1280 720 is not a valid @playwright/cli command and appears in 4 agent files.
The @playwright/cli package (v0.1.4) does not support the resize command. Official commands are: open, close, goto, click, dblclick, fill, check, select, press, drag, upload, go-back, reload, snapshot, screenshot, eval, console, network, and others—but not resize.
This command block is duplicated across .claude/agents/user-sim-creator.md, .claude/agents/user-sim-admin.md, .claude/agents/ux-crawler.md, and .claude/agents/feature-reviewer.md. Additionally, these files have conflicting command references (e.g., hover, uncheck, network are documented differently or missing in some files).
Consolidate to a single, authoritative command reference using only documented @playwright/cli commands. Remove resize or replace with the correct viewport configuration approach (likely via .playwright/cli.config.json).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/agents/user-sim-creator.md around lines 19 - 31, The docs include an
invalid command "resize 1280 720" for `@playwright/cli` and duplicate/conflicting
command lists across .claude/agents/user-sim-creator.md,
.claude/agents/user-sim-admin.md, .claude/agents/ux-crawler.md and
.claude/agents/feature-reviewer.md; remove all occurrences of the unsupported
"resize" command and consolidate the four files to a single authoritative
command reference that only lists supported `@playwright/cli` commands (e.g.,
open, goto, click, fill, screenshot, snapshot, console, network, etc.), and add
a note to use viewport configuration via .playwright/cli.config.json or the
Playwright API instead of a "resize" CLI command to set viewport size.
|
|
||
| ## Your Session | ||
|
|
||
| Login as creator: `bob@example.com` / `password123` |
There was a problem hiding this comment.
Avoid committing creator login credentials in agent instructions.
Line 36 hardcodes account credentials in repo docs/config. Please move to env-backed test fixtures/placeholders.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/agents/user-sim-creator.md at line 36, The file contains hardcoded
creator credentials ("bob@example.com" / "password123") in the
user-sim-creator.md instruction; replace that literal with env-backed
placeholders and update any test fixtures or docs to read from environment
variables (e.g., CREATOR_EMAIL, CREATOR_PASSWORD) or a secure test fixture
loader rather than committing secrets; update references to the login example in
user-sim-creator.md and any test harness that uses the string so they pull
values from the environment/fixtures (and rotate/remove the real credentials
from the repo/history if they were ever live).
| npx tsc --noEmit | ||
| npm run lint | ||
| cd app && npm test | ||
| ``` |
There was a problem hiding this comment.
Phase 3 runs checks in inconsistent directories.
tsc and lint run before entering app, while tests run inside app. If workspace tooling is app-scoped, this breaks verification reliability.
Suggested fix
-npx tsc --noEmit
-npm run lint
-cd app && npm test
+cd app
+npx tsc --noEmit
+npm run lint
+npm test📝 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.
| npx tsc --noEmit | |
| npm run lint | |
| cd app && npm test | |
| ``` | |
| cd app | |
| npx tsc --noEmit | |
| npm run lint | |
| npm test |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/skills/fix-pr-reviews/SKILL.md around lines 81 - 84, Phase 3 runs
checks in inconsistent directories: move into the app workspace before running
all verification steps so TypeScript, linting, and tests operate in the same
scope; modify the step that currently runs "npx tsc --noEmit" and "npm run lint"
(and the test invocation) to execute from the app directory (e.g., run a single
"cd app" once and then run the commands, or prefix each command with "cd app
&&") so all checks use the same workspace and tooling.
| ``` | ||
| ## Summary | ||
| [1-2 sentences] | ||
| ## Changes | ||
| - [bullets] | ||
| ## Testing | ||
| - [ ] Unit tests added/updated | ||
| - [ ] E2E tests pass | ||
| ## Related Issues | ||
| Closes #[number] | ||
| ``` |
There was a problem hiding this comment.
Add language specifier to fenced code block.
The fenced code block is missing a language identifier, which triggers the MD040 linter warning. Since this is a markdown template, specify markdown as the language.
📝 Proposed fix
-```
+```markdown
## Summary
[1-2 sentences]
## Changes📝 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.
| ``` | |
| ## Summary | |
| [1-2 sentences] | |
| ## Changes | |
| - [bullets] | |
| ## Testing | |
| - [ ] Unit tests added/updated | |
| - [ ] E2E tests pass | |
| ## Related Issues | |
| Closes #[number] | |
| ``` |
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 32-32: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/skills/pr/SKILL.md around lines 32 - 42, The opening fenced code
block in .claude/skills/pr/SKILL.md lacks a language specifier causing MD040;
update the triple-backtick fence to include "markdown" (i.e., replace ``` with
```markdown) so the template block is explicitly marked as markdown; locate the
top-level fenced block containing the "## Summary" / "## Changes" lines and
change its opening fence accordingly.
|
|
||
| Output a markdown summary: | ||
|
|
||
| ``` |
There was a problem hiding this comment.
Add a language to the fenced code block.
The fence at Line 62 has no language, which triggers MD040 and reduces editor highlighting quality.
Suggested update
-```
+```md
# Release Plan
## v0.1 — Core Foundation
Goal: ...
Issues: `#1`, `#2`, `#3`, `#4`
Estimated effort: ...
## v0.2 — Dashboard Experience
Goal: ...
Issues: `#5`, `#6`, `#7`, `#8`
Depends on: v0.1
...</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **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.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 62-62: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.claude/skills/release-plan/SKILL.md at line 62, The fenced code block in
SKILL.md is missing a language specifier which triggers MD040; update the
opening triple-backtick to include a language (e.g., "```md" or "```markdown")
so the block becomes a language-tagged fenced code block; locate the code block
around the Release Plan section (the fenced block containing "# Release Plan"
and the v0.1/v0.2 headings) and change the fence token accordingly to restore
proper Markdown highlighting.
| function getTemplates(lang: string) { | ||
| const key = | ||
| lang === "neo4j" ? "cypher" : lang === "postgresql" ? "sql" : lang; | ||
| return QUERY_TEMPLATES[key] ?? QUERY_TEMPLATES.sql ?? []; |
There was a problem hiding this comment.
Reuse the normalized language everywhere in this panel.
These mappings make postgresql resolve to SQL templates, but the rest of the component still branches on raw editorLanguage, so PostgreSQL connections keep the Cypher placeholder at Line 215. Normalize once and use the same key for templates and placeholder text.
Suggested fix
+function normalizeEditorLanguage(lang: string) {
+ return lang === "neo4j" ? "cypher" : lang === "postgresql" ? "sql" : lang;
+}
+
function getTemplates(lang: string) {
- const key =
- lang === "neo4j" ? "cypher" : lang === "postgresql" ? "sql" : lang;
+ const key = normalizeEditorLanguage(lang);
return QUERY_TEMPLATES[key] ?? QUERY_TEMPLATES.sql ?? [];
}
export function QueryEditorPanel({
onRun,
editorLanguage,
running,
}: QueryEditorPanelProps) {
+ const normalizedLanguage = normalizeEditorLanguage(editorLanguage);
const chartType = useWidgetEditorStore((s) => s.chartType);
const query = useWidgetEditorStore((s) => s.query);
const onQueryChange = useWidgetEditorStore((s) => s.setQuery);
const connectionId = useWidgetEditorStore((s) => s.connectionId);
@@
- {getTemplates(editorLanguage).map((t) => (
+ {getTemplates(normalizedLanguage).map((t) => (
<DropdownMenuItem
key={t.label}
onSelect={() => onQueryChange(t.query)}
>
@@
placeholder={
- editorLanguage === "sql"
+ normalizedLanguage === "sql"
? "SELECT * FROM users LIMIT 10"
: "MATCH (n) RETURN n.name AS name, n.born AS value LIMIT 10"
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/src/components/widget-editor/query-editor-panel.tsx` around lines 97 -
100, The component normalizes languages for templates inside getTemplates but
other places (like the placeholder text rendering) still use the raw
editorLanguage, causing mismatches for "postgresql"; extract the normalization
logic into a small helper (e.g., normalizeLanguage or reuse getTemplates' key
mapping) and use that normalized value everywhere: pass it to getTemplates and
use the same normalized key when selecting placeholder text and any other
language-branching logic (replace direct checks of editorLanguage with
normalizeLanguage(editorLanguage) and use that result consistently).
| Generated via automated user simulation agents against the live app (release/1.0). | ||
|
|
There was a problem hiding this comment.
Add generation metadata to keep this report actionable over time.
Line 3 includes release/1.0, but without a generation date and commit/PR reference this report will age quickly and can be misread as current UX status.
💡 Suggested doc patch
# NeoBoard UX Friction Report
-Generated via automated user simulation agents against the live app (release/1.0).
+Generated via automated user simulation agents against the live app (release/1.0).
+Baseline date: YYYY-MM-DD
+Baseline commit: <git-sha>
+Related PR: `#347`📝 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.
| Generated via automated user simulation agents against the live app (release/1.0). | |
| Generated via automated user simulation agents against the live app (release/1.0). | |
| Baseline date: YYYY-MM-DD | |
| Baseline commit: <git-sha> | |
| Related PR: `#347` | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/ux-friction-report.md` around lines 3 - 4, Update the generation
metadata on the report header line that currently reads "Generated via automated
user simulation agents against the live app (release/1.0)." — append an ISO 8601
generation timestamp and a unique code reference (commit SHA or PR number and/or
CI build id) so the line becomes self-contained (e.g., include "generated:
2026-04-03T12:00:00Z, commit: abc1234, PR: `#42`"); ensure the template used for
future reports (the same header string) is updated to always emit these three
fields (release tag, generation date/time, and commit/PR or build id).
|
Merged into aggregated PR #349 (release/1.0-all-fixes) |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- QueryEditorPanel: test templates dropdown visibility, language mapping (neo4j->cypher, postgresql->sql, unknown->fallback), template click setting query, query hints for chart types, refresh schema button - DashboardContainer: test double-click to edit widget, verify it only fires when editable=true AND onEditWidget is provided, multi-widget targeting, empty state - QUERY_HINTS: verify all chart types have hints with examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>


Summary
resetKeyprop onChartSettingsPanelCloses #329
Closes #330
Closes #331
Closes #341
Closes #342
Closes #343
Changes
dashboard-container.tsx—onDoubleClickhandler, removedonWidgetSettingsChangefrom CardContainerwidget-editor-modal.tsx— debounced auto-preview effect,resetKey={chartType}on ChartSettingsPanelchart-settings-panel.tsx— newresetKeyprop forces tab remountquery-editor-panel.tsx— query templates dropdown with Cypher/SQL variantstransform-editor.tsx— detailed help text for each transform typecharts.spec.ts— updated E2E for overlay removalTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation