Skip to content

feat: add direct worksheet map blocks - #757

Merged
ilyabo merged 8 commits into
mainfrom
codex/direct-worksheet-map-blocks
Jun 23, 2026
Merged

feat: add direct worksheet map blocks#757
ilyabo merged 8 commits into
mainfrom
codex/direct-worksheet-map-blocks

Conversation

@ilyabo

@ilyabo ilyabo commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add an experimental map stateful worksheet block in the CLI app.
  • Render Deck map panels directly inside worksheets without requiring users or agents to create a dashboard block first.
  • Add a worksheet map agent tool, map-aware block listing, and prompt guidance so worksheet map requests target the direct map block.
  • Export createDeckMapPanelFromNativeConfig for host surfaces that need the same normalized Deck map panel shape as dashboard map tooling.

Impact

Worksheet users can add or generate maps directly as worksheet blocks. Existing dashboard map panels continue to use the same renderer/config path.

Validation

  • pnpm build
  • pnpm --filter sqlrooms-cli-app typecheck
  • pnpm --filter @sqlrooms/deck test
  • pnpm --filter @sqlrooms/mosaic test -- worksheet
  • Pre-push hook: knip, turbo typecheck, turbo test

Summary by CodeRabbit

  • New Features
    • Added experimental, persistent worksheet map stateful blocks with a safe “unsupported/unconfigured” fallback, including title/caption rendering and deck-map panel auto-seeding.
    • Enhanced worksheet AI to optionally prefer direct worksheet map blocks (including reuse/update via map identifiers), with updated workflow guidance.
    • Deck maps now support embeddable block rendering, choosing geospatial tables when available and otherwise showing an empty map.
  • Bug Fixes
    • Improved deck map panel creation to always return a compatible, dashboard-ready panel shape.
  • Tests
    • Expanded AI and deck map tests to cover the new map block flow.
  • Documentation
    • Added docs for creating dashboard-compatible Deck map panels and guidance for map/table picker primitives.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 293130d9-27c8-43bd-96c7-149c4de6c26d

📥 Commits

Reviewing files that changed from the base of the PR and between 93f9be5 and 81aec14.

📒 Files selected for processing (1)
  • apps/sqlrooms-cli-ui/src/createWorksheetAgent.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/sqlrooms-cli-ui/src/createWorksheetAgent.ts

📝 Walkthrough

Walkthrough

Adds an embeddable map stateful block type for worksheets, backed by Deck.gl via the Mosaic dashboard system. Introduces DeckMapBlockRenderer and ensureDeckMapBlockState in the deck package, registers a map artifact config with lifecycle handlers, wires a worksheet renderer component, and adds an AI tool (create_worksheet_map_block) with updated agent instructions and type options.

Changes

Worksheet Map Block Feature

Layer / File(s) Summary
Deck embeddable map block component and state initialization
packages/deck/src/block.tsx
Implements ensureDeckMapBlockState to initialize/ensure a Mosaic dashboard with optional geospatial table seeding and deck-map panel creation, and DeckMapBlockRenderer component that manages dashboard lifecycle, detects/selects geospatial tables, synchronizes panel configs, and renders either the deck map panel or a DataTableSelectorEmptyState based on dataset availability.
Dashboard panel creation and empty config helpers
packages/deck/src/dashboard.tsx
Adds createEmptyDeckMapDashboardPanelConfig helper and updates deckMapDashboardAddPanelAction to remove isEnabled gating so createPanel always returns a config—selecting a table-backed map panel when geospatial columns are detected, otherwise returning an empty map config with default title.
Deck package public API exports
packages/deck/src/ai.ts, packages/deck/src/index.ts
Exports createDeckMapPanelFromNativeConfig from ai.ts and re-exports DeckMapBlockRenderer, ensureDeckMapBlockState, DeckMapBlockRendererProps type from block.tsx, plus findGeometryColumn from mapConfigUtils.
Map artifact config registration and worksheet renderer wiring
apps/sqlrooms-cli-ui/src/statefulBlockArtifactConfigs.ts, apps/sqlrooms-cli-ui/src/workspace/WorksheetMapBlockRenderer.tsx, apps/sqlrooms-cli-ui/src/workspace/WorksheetArtifact.tsx
Registers map entry in STATEFUL_BLOCK_ARTIFACT_CONFIGS with ensureDeckMapBlockState, removeDashboard, and ensureDashboard lifecycle handlers. Introduces WorksheetMapBlockRenderer component delegating to DeckMapBlockRenderer. Wires renderer into worksheet block renderer registry with ExperimentalStatefulBlockPlaceholder override for non-experimental mode.
Map block AI tool creation and integration
apps/sqlrooms-cli-ui/src/createWorksheetAgent.ts
Implements createWorksheetMapBlockTool with Zod schema validation, worksheet artifact validation, block document/dashboard/selection setup, deck map panel creation from native config, and panel update/insert logic. Wires tool into worksheetAgentTool when experimentalEnabled with mapBlocksEnabled flag and routing instructions.
Agent instruction updates and mapBlocksEnabled option
packages/mosaic/src/ai/worksheet/worksheet-types.ts, packages/mosaic/src/ai/worksheet/createWorksheetAgentTool.ts, apps/sqlrooms-cli-ui/src/store.ts
Adds mapBlocksEnabled option to CreateWorksheetAgentToolOptions. Rewrites agent instructions to branch on mapBlocksEnabled: routes direct map requests to worksheet map tool when enabled, otherwise to dashboard/embedded-dashboard flow. Conditionally structures HTML app guidance based on htmlAppBlocksEnabled. Updates top-level store AI instruction for worksheet map requests.
Block summary expansion for map blocks
packages/mosaic/src/ai/worksheet/createListWorksheetBlocksTool.ts
Adds optional mapId field to block summary type, populates mapId for blockType === 'map' blocks, and updates tool description to explicitly cover map block updates with mapId passing.
Mosaic package public exports for table selection
packages/mosaic/src/index.ts
Exports DataTableSelector, DataTableSelectorEmptyState, and DataTableSelectorProps type, enabling host surfaces to embed the searchable table picker component.
Tests and documentation updates
packages/mosaic/__tests__/worksheet-ai.test.ts, packages/deck/__tests__/dashboard-ai-map.test.ts, packages/deck/README.md, packages/mosaic/README.md
Extends worksheet AI test with new map stateful block in mock and expected results. Strengthens deck panel action test to assert createPanel returns correct empty map config. Adds README sections for createDeckMapPanelFromNativeConfig and embeddable map blocks, and documents DataTableSelector usage patterns.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant WorksheetAgent
  participant createWorksheetMapBlockTool
  participant MosaicDashboard
  participant WorksheetStore
  participant DeckMapBlockRenderer

  User->>WorksheetAgent: "Add a map of cities by population"
  WorksheetAgent->>createWorksheetMapBlockTool: execute(title, nativeConfig, mapId?)
  createWorksheetMapBlockTool->>WorksheetStore: validate artifact, ensure block document
  createWorksheetMapBlockTool->>MosaicDashboard: ensureDashboard(mapId)
  createWorksheetMapBlockTool->>MosaicDashboard: createDeckMapPanelFromNativeConfig(title, config)
  alt new map (no mapId)
    createWorksheetMapBlockTool->>MosaicDashboard: addPanel(deckMapPanel)
    createWorksheetMapBlockTool->>WorksheetStore: createStatefulBlock(map, blockInstanceId)
  else update existing (mapId provided)
    createWorksheetMapBlockTool->>MosaicDashboard: updatePanel(existing deckMapPanel)
  end
  createWorksheetMapBlockTool-->>WorksheetAgent: {success: true, mapId}
  WorksheetAgent-->>User: Map block created/updated
  User->>DeckMapBlockRenderer: view worksheet with map
  DeckMapBlockRenderer->>MosaicDashboard: ensureDeckMapBlockState(state, mapId, title)
  DeckMapBlockRenderer->>MosaicDashboard: find deck-map panel
  alt geospatial table available
    DeckMapBlockRenderer->>DataTableSelector: show table picker
    DataTableSelector-->>User: select table to populate map
  else no data
    DeckMapBlockRenderer->>DeckMapBlockRenderer: render empty map
  end
  DeckMapBlockRenderer-->>User: render Deck.gl map panel
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • sqlrooms/sqlrooms#654: Introduced the Deck map AI tooling and createDeckMapPanelFromNativeConfig, which this PR exports and reuses for the worksheet map block tool.
  • sqlrooms/sqlrooms#668: Extends worksheet stateful block infrastructure in the same files (statefulBlockArtifactConfigs.ts, WorksheetArtifact.tsx) by adding a data-table block type alongside this PR's new map block type.
  • sqlrooms/sqlrooms#711: Introduced the worksheet agent tool infrastructure in createWorksheetAgentTool.ts and createWorksheetAgent.ts that this PR extends with mapBlocksEnabled option and the new map block tool.

Suggested reviewers

  • dmitriy-kostianetskiy

Poem

🐇 A new map block blooms in the worksheet today,
Deck.gl and Mosaic now work in display,
The agent says "map!" and the panel appears,
ensureDeckMapBlockState calms all my fears,
With mapId in hand, the rabbit hops away! 🗺️✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add direct worksheet map blocks' accurately describes the main change: introducing a new feature for direct worksheet map blocks that can be rendered within worksheets.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/direct-worksheet-map-blocks

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ilyabo
ilyabo marked this pull request as ready for review June 22, 2026 19:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ced270153

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +64 to +66
const mapId = params.mapId ?? createDefaultBlockDocumentBlockId();
const title = params.title || 'Map';
state.mosaicDashboard.ensureDashboard(mapId, title, 'grid');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject stale worksheet map IDs

When mapId is supplied but is stale or not actually present as a map block in this worksheet, this call creates a backing dashboard for that arbitrary ID; because the later append is skipped whenever params.mapId is truthy, the tool can return success while no visible worksheet block exists. For update requests, verify that mapId belongs to an existing map stateful block in the target worksheet (or fail) before creating/updating dashboard state.

Useful? React with 👍 / 👎.

Comment on lines +57 to +60
const tableName = params.tableName;
if (tableName) {
state.db.findTable(tableName);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate table names before selecting them

When the optional tableName is misspelled or no longer exists, db.findTable just returns undefined, but execution continues and the same value is stored as the map dashboard's selected table. The deck map renderer gives the selected table precedence over dataset sources, so a bad tableName can make an otherwise valid map config fail at query time instead of returning a tool error.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/sqlrooms-cli-ui/src/workspace/WorksheetMapBlockRenderer.tsx (1)

4-9: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add TSDoc to the exported renderer component.

WorksheetMapBlockRenderer is exported but undocumented in a TSX file.

📝 Proposed fix
+/**
+ * Renders a worksheet `map` stateful block using the Deck embeddable map surface.
+ */
 export const WorksheetMapBlockRenderer = ({
   blockInstanceId,
   blockType,
   title,
   caption,
 }: BlockDocumentStatefulBlockRendererProps) => {

As per coding guidelines, **/*.{ts,tsx}: Add tsdoc to exported types and functions.

🤖 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 `@apps/sqlrooms-cli-ui/src/workspace/WorksheetMapBlockRenderer.tsx` around
lines 4 - 9, The exported function WorksheetMapBlockRenderer is missing TSDoc
documentation. Add a TSDoc comment block above the function export that
documents what the component does, describes the
BlockDocumentStatefulBlockRendererProps parameter including its key properties
(blockInstanceId, blockType, title, caption), and notes the return type. Use the
standard TSDoc format with `@param` and `@returns` tags to provide comprehensive
documentation for this exported component.

Source: Coding guidelines

🤖 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 `@apps/sqlrooms-cli-ui/src/createWorksheetAgent.ts`:
- Around line 64-69: When params.mapId is supplied, validate that the provided
mapId actually belongs to a blockType: 'map' block in the target worksheet
before proceeding with the mosaicDashboard.ensureDashboard and
mosaicDashboard.setSelectedTable calls. Add a validation check that confirms the
mapId ownership by querying the worksheet state to verify the block exists and
has blockType set to 'map', and only execute the dashboard mutations if
validation succeeds. This same validation pattern should also be applied to the
other locations mentioned in the comment (lines 101-114).

In `@packages/mosaic/src/ai/worksheet/createWorksheetAgentTool.ts`:
- Around line 148-152: The map routing guidance contains contradictory
instructions across multiple locations. The conditional logic for
mapBlocksEnabled in the diff (lines 148-152) correctly routes to the direct
worksheet map tool when enabled, but other instruction surfaces at line 222 and
lines 291-304 still hardcode the dashboard-map workflow path regardless of the
mapBlocksEnabled flag. Update all other map-related instruction blocks (at line
222 and the tool description sections around lines 291-304) to include the same
mapBlocksEnabled conditional logic so that when mapBlocksEnabled is true, they
all direct users to the direct worksheet map tool instead of the dashboard path,
ensuring consistent agent behavior across all instruction surfaces.

---

Nitpick comments:
In `@apps/sqlrooms-cli-ui/src/workspace/WorksheetMapBlockRenderer.tsx`:
- Around line 4-9: The exported function WorksheetMapBlockRenderer is missing
TSDoc documentation. Add a TSDoc comment block above the function export that
documents what the component does, describes the
BlockDocumentStatefulBlockRendererProps parameter including its key properties
(blockInstanceId, blockType, title, caption), and notes the return type. Use the
standard TSDoc format with `@param` and `@returns` tags to provide comprehensive
documentation for this exported component.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: e7e9159a-62bd-49ac-a472-757102597888

📥 Commits

Reviewing files that changed from the base of the PR and between 7924b5a and 7ced270.

📒 Files selected for processing (15)
  • apps/sqlrooms-cli-ui/src/createWorksheetAgent.ts
  • apps/sqlrooms-cli-ui/src/statefulBlockArtifactConfigs.ts
  • apps/sqlrooms-cli-ui/src/store.ts
  • apps/sqlrooms-cli-ui/src/workspace/WorksheetArtifact.tsx
  • apps/sqlrooms-cli-ui/src/workspace/WorksheetMapBlockRenderer.tsx
  • packages/deck/README.md
  • packages/deck/__tests__/dashboard-ai-map.test.ts
  • packages/deck/src/ai.ts
  • packages/deck/src/block.tsx
  • packages/deck/src/dashboard.tsx
  • packages/deck/src/index.ts
  • packages/mosaic/__tests__/worksheet-ai.test.ts
  • packages/mosaic/src/ai/worksheet/createListWorksheetBlocksTool.ts
  • packages/mosaic/src/ai/worksheet/createWorksheetAgentTool.ts
  • packages/mosaic/src/ai/worksheet/worksheet-types.ts

Comment thread apps/sqlrooms-cli-ui/src/createWorksheetAgent.ts
Comment thread packages/mosaic/src/ai/worksheet/createWorksheetAgentTool.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e87564a3eb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +91 to +95
if (existingPanel) {
state.mosaicDashboard.updatePanel(mapId, existingPanel.id, {
title: panel.title,
config: panel.config,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the worksheet block title on map edits

When mapId is supplied for an existing worksheet map and the caller changes the map title, this branch updates only the backing Deck panel. Newly created map blocks persist both title and caption, and DeckMapBlockRenderer displays caption || title || panel.title, so the worksheet block header continues to show the old title even though the tool reports that it updated the worksheet map. In the update path, also update the matching map stateful block attrs or stop letting the stale block caption override the panel title.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5e3125bd5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +83 to +85
if (tableName) {
state.mosaicDashboard.setSelectedTable(mapId, tableName);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Select the config table when tableName is omitted

When updating an existing worksheet map and the caller omits the optional top-level tableName, this leaves the backing dashboard's previous selectedTable in place even if params.config.datasets now points at a different table. resolveDeckMapDashboardDatasetSource gives dashboard.selectedTable precedence over dataset source.tableName, so an edit from old_table to new_table can keep querying old_table while the tool returns success. Mirror createDeckMapDashboardTool by falling back to the first dataset source table before validating/setting the selection, or require tableName for updates that change data sources.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93f9be5edf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +75 to +76
const tableName =
params.tableName ?? getFirstDatasetSourceTableName(params.config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require a table for SQL-only map updates

When updating an existing worksheet map, this fallback still returns undefined for configs whose dataset source is only sqlQuery (a supported form and common for point maps), so the backing dashboard keeps its previous selectedTable. At render time resolveDeckMapDashboardDatasetSource rewrites SQL-only sources to the dashboard's selected table when one exists, so an edit from old_table to a SQL query over new_table can silently keep querying old_table unless the agent also supplied the optional top-level tableName. The fresh evidence is that SQL-only dataset sources still bypass this fallback because getFirstDatasetSourceTableName only reads source.tableName.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant